PageRenderTime 44ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/nethesis/nethserver-cups
PHP | 1889 lines | 1440 code | 291 blank | 158 comment | 196 complexity | f70451dd4bfd9bc3819c847471a49681 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/PrintIPP.php,v 1.3 2010/09/06 22:41:41 harding Exp $
  4. *
  5. * Class PrintIPP - Send IPP requests, Get and parses IPP Responses.
  6. *
  7. * Copyright (C) 2005-2006 Thomas HARDING
  8. * Parts Copyright (C) 2005-2006 Manuel Lemos
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Library General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2 of the License, or (at your option) any later version.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Library General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Library General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. *
  24. * mailto:thomas.harding@laposte.net
  25. * Thomas Harding, 56 rue de la bourie rouge, 45 000 ORLEANS -- FRANCE
  26. *
  27. */
  28. /*
  29. This class is intended to implement Internet Printing Protocol on client side.
  30. References needed to debug / add functionnalities:
  31. - RFC 2910
  32. - RFC 2911
  33. - RFC 3380
  34. - RFC 3382
  35. */
  36. /*
  37. TODO: beta tests on other servers than Cups
  38. */
  39. // {{{ required and included files
  40. require_once("BasicIPP.php");
  41. // }}}
  42. class PrintIPP extends BasicIPP {
  43. // {{{ constructor
  44. public function __construct() {
  45. parent::__construct();
  46. }
  47. // }}}
  48. /*****************
  49. *
  50. * PUBLIC FUNCTIONS
  51. *
  52. *******************/
  53. // SETTINGS
  54. // OPERATIONS
  55. // {{{ printJob()
  56. public function printJob(){
  57. self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
  58. if (!$this->_stringJob())
  59. return FALSE;
  60. if (is_readable($this->data)){
  61. self::_putDebug( _("Printing a FILE\n"),3);
  62. $this->output = $this->stringjob;
  63. if ($this->setup->datatype == "TEXT")
  64. $this->output .= chr(0x16);
  65. $post_values = array( "Content-Type" => "application/ipp",
  66. "Data" => $this->output,
  67. "File" => $this->data);
  68. if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed))
  69. $post_values = array_merge($post_values,array("Filetype"=>"TEXT"));
  70. } else {
  71. self::_putDebug( _("Printing DATA\n"),3);
  72. $this->output = $this->stringjob;
  73. $this->output .= $this->datahead;
  74. $this->output .= $this->data;
  75. $this->output .= $this->datatail;
  76. $post_values = array( "Content-Type" => "application/ipp",
  77. "Data" => $this->output);
  78. }
  79. if (self::_sendHttp ($post_values,$this->paths['printers'])) {
  80. if(self::_parseServerOutput()) {
  81. $this->_getJobId();
  82. $this->_getJobUri();
  83. $this->_parseJobAttributes();
  84. } else {
  85. $this->jobs = array_merge($this->jobs,array(''));
  86. $this->jobs_uri = array_merge($this->jobs_uri,array(''));
  87. }
  88. }
  89. if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
  90. $this->status = array_merge($this->status,array($this->serveroutput->status));
  91. if ($this->serveroutput->status == "successfull-ok")
  92. {
  93. self::_errorLog(sprintf("printing job %s: ",$this->last_job) .$this->serveroutput->status,3);
  94. }
  95. else
  96. {
  97. $this->jobs = array_merge($this->jobs,array(""));
  98. $this->jobs_uri = array_merge($this->jobs_uri,array(""));
  99. self::_errorLog(sprintf("printing job: ",$this->last_job) .$this->serveroutput->status,1);
  100. if ($this->with_exceptions)
  101. {
  102. throw new ippException(sprintf("job status: %s",
  103. $this->serveroutput->status));
  104. }
  105. }
  106. return $this->serveroutput->status;
  107. }
  108. $this->status = array_merge($this->status,array("OPERATION FAILED"));
  109. $this->jobs = array_merge($this->jobs,array(""));
  110. $this->jobs_uri = array_merge($this->jobs_uri,array(""));
  111. self::_errorLog("printing job : OPERATION FAILED",1);
  112. return false;
  113. }
  114. // }}}
  115. // {{{ cancelJob ($job_uri)
  116. public function cancelJob ($job_uri) {
  117. $this->jobs = array_merge($this->jobs,array(""));
  118. $this->jobs_uri = array_merge($this->jobs_uri,array(""));
  119. self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
  120. if (!$this->_stringCancel($job_uri))
  121. return FALSE;
  122. self::_putDebug( _("Cancelling Job $job_uri\n"),3);
  123. $this->output = $this->stringjob;
  124. $post_values = array( "Content-Type"=>"application/ipp",
  125. "Data"=>$this->output);
  126. if (self::_sendHttp ($post_values,$this->paths['jobs']))
  127. self::_parseServerOutput();
  128. if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
  129. $this->status = array_merge($this->status,array($this->serveroutput->status));
  130. if ($this->serveroutput->status == "successfull-ok")
  131. self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,3);
  132. else
  133. self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,1);
  134. return $this->serveroutput->status;
  135. }
  136. $this->status = array_merge($this->status,array("OPERATION FAILED"));
  137. self::_errorLog("cancelling job : OPERATION FAILED",3);
  138. return false;
  139. }
  140. // }}}
  141. // {{{ validateJob ()
  142. public function validateJob () {
  143. $this->jobs = array_merge($this->jobs,array(""));
  144. $this->jobs_uri = array_merge($this->jobs_uri,array(""));
  145. $this->serveroutput->response = '';
  146. self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
  147. self::_putDebug( _("Validate Job\n"),2);
  148. if (!isset($this->setup->charset))
  149. self::setCharset('us-ascii');
  150. if (!isset($this->setup->datatype))
  151. self::setBinary();
  152. if (!isset($this->setup->uri)) {
  153. $this->getPrinters();
  154. unset($this->jobs[count($this->jobs) - 1]);
  155. unset($this->jobs_uri[count($this->jobs_uri) - 1]);
  156. unset($this->status[count($this->status) - 1]);
  157. if (array_key_exists(0,$this->available_printers))
  158. self::setPrinterURI($this->available_printers[0]);
  159. else {
  160. trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING);
  161. self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
  162. self::_errorLog(" Printer URI is not set, die",2);
  163. return FALSE;
  164. }
  165. }
  166. if (!isset($this->meta->copies))
  167. self::setCopies(1);
  168. if (!isset($this->setup->copies))
  169. self::setCopies(1);
  170. if (!isset($this->setup->language))
  171. self::setLanguage('en_us');
  172. if (!isset($this->setup->mime_media_type))
  173. self::setMimeMediaType();
  174. if ($this->setup->datatype != "TEXT")
  175. unset ($this->setup->mime_media_type);
  176. if (!isset($this->setup->jobname))
  177. if (is_readable($this->data))
  178. self::setJobName(basename($this->data),true);
  179. else
  180. self::setJobName();
  181. unset($this->setup->jobname);
  182. if (!isset($this->meta->username))
  183. self::setUserName();
  184. if (!isset($this->meta->fidelity))
  185. $this->meta->fidelity = '';
  186. if (!isset($this->meta->document_name))
  187. $this->meta->document_name = '';
  188. if (!isset($this->meta->sides))
  189. $this->meta->sides = '';
  190. if (!isset($this->meta->page_ranges))
  191. $this->meta->page_ranges = '';
  192. $jobattributes = '';
  193. $operationattributes = '';
  194. $printerattributes = '';
  195. self::_buildValues ($operationattributes,$jobattributes,$printerattributes);
  196. self::_setOperationId();
  197. $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
  198. . chr(0x00) . chr (0x04) // Validate-Job | operation-id
  199. . $this->meta->operation_id // request-id
  200. . chr(0x01) // start operation-attributes | operation-attributes-tag
  201. . $this->meta->charset
  202. . $this->meta->language
  203. . $this->meta->printer_uri
  204. . $this->meta->username
  205. . $this->meta->jobname
  206. . $this->meta->fidelity
  207. . $this->meta->document_name
  208. . $this->meta->mime_media_type
  209. . $operationattributes
  210. . chr(0x02) // start job-attributes | job-attributes-tag
  211. . $this->meta->copies
  212. . $this->meta->sides
  213. . $this->meta->page_ranges
  214. . $jobattributes
  215. . chr(0x03); // end-of-attributes | end-of-attributes-tag
  216. self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
  217. $this->output = $this->stringjob;
  218. $post_values = array( "Content-Type"=>"application/ipp",
  219. "Data"=>$this->output);
  220. if (self::_sendHttp ($post_values,$this->paths['printers']))
  221. if(self::_parseServerOutput())
  222. self::_parseAttributes();
  223. if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
  224. $this->status = array_merge($this->status,array($this->serveroutput->status));
  225. if ($this->serveroutput->status == "successfull-ok")
  226. self::_errorLog("validate job: ".$this->serveroutput->status,3);
  227. else
  228. self::_errorLog("validate job: ".$this->serveroutput->status,1);
  229. return $this->serveroutput->status;
  230. }
  231. $this->status = array_merge($this->status,array("OPERATION FAILED"));
  232. self::_errorLog("validate job : OPERATION FAILED",3);
  233. return false;
  234. }
  235. // }}}
  236. // {{{ getPrinterAttributes()
  237. public function getPrinterAttributes() {
  238. $this->jobs = array_merge($this->jobs,array(""));
  239. $this->jobs_uri = array_merge($this->jobs_uri,array(""));
  240. $jobattributes = '';
  241. $operationattributes = '';
  242. self::_buildValues($operationattributes,$jobattributes,$printerattributes);
  243. self::_setOperationId();
  244. $this->parsed = array();
  245. unset($this->printer_attributes);
  246. if (!isset($this->setup->uri)) {
  247. $this->getPrinters();
  248. unset($this->jobs[count($this->jobs) - 1]);
  249. unset($this->jobs_uri[count($this->jobs_uri) - 1]);
  250. unset($this->status[count($this->status) - 1]);
  251. if (array_key_exists(0,$this->available_printers))
  252. self::setPrinterURI($this->available_printers[0]);
  253. else {
  254. trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING);
  255. self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
  256. self::_errorLog(" Printer URI is not set, die",2);
  257. return FALSE;
  258. }
  259. }
  260. if (!isset($this->setup->charset))
  261. self::setCharset('us-ascii');
  262. if (!isset($this->setup->language))
  263. self::setLanguage('en_us');
  264. if (!isset($this->meta->username))
  265. self::setUserName();
  266. $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
  267. . chr(0x00) . chr (0x0b) // Print-URI | operation-id
  268. . $this->meta->operation_id // request-id
  269. . chr(0x01) // start operation-attributes | operation-attributes-tag
  270. . $this->meta->charset
  271. . $this->meta->language
  272. . $this->meta->printer_uri
  273. . $this->meta->username
  274. . $printerattributes
  275. . chr(0x03); // end-of-attributes | end-of-attributes-tag
  276. self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
  277. self::_putDebug(sprintf(_("Getting printer attributes of %s\n"),$this->printer_uri),2);
  278. $this->output = $this->stringjob;
  279. $post_values = array( "Content-Type"=>"application/ipp",
  280. "Data"=>$this->output);
  281. if (self::_sendHttp ($post_values,$this->paths['root']))
  282. if (self::_parseServerOutput())
  283. self::_parsePrinterAttributes();
  284. $this->attributes = &$this->printer_attributes;
  285. if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
  286. $this->status = array_merge($this->status,array($this->serveroutput->status));
  287. if ($this->serveroutput->status == "successfull-ok")
  288. self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri,
  289. $this->serveroutput->status),3);
  290. else
  291. self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri,
  292. $this->serveroutput->status),1);
  293. return $this->serveroutput->status;
  294. }
  295. $this->status = array_merge($this->status,array("OPERATION FAILED"));
  296. self::_errorLog(date("Y-m-d H:i:s : ")
  297. .basename($_SERVER['PHP_SELF'])
  298. .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"),
  299. $this->printer_uri),3);
  300. return false;
  301. }
  302. // }}}
  303. // {{{ getJobs ($my_jobs=true,$limit=0,$which_jobs="");
  304. public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false) {
  305. $this->jobs = array_merge($this->jobs,array(""));
  306. $this->jobs_uri = array_merge($this->jobs_uri,array(""));
  307. self::_setOperationId();
  308. $this->parsed = array();
  309. unset($this->printer_attributes);
  310. if (!isset($this->setup->uri)) {
  311. $this->getPrinters();
  312. unset($this->jobs[count($this->jobs) - 1]);
  313. unset($this->jobs_uri[count($this->jobs_uri) - 1]);
  314. unset($this->status[count($this->status) - 1]);
  315. if (array_key_exists(0,$this->available_printers))
  316. self::setPrinterURI($this->available_printers[0]);
  317. else {
  318. trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING);
  319. self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
  320. self::_errorLog("getJobs: Printer URI is not set, die",2);
  321. return FALSE;
  322. }
  323. }
  324. if (!isset($this->setup->charset))
  325. self::setCharset('us-ascii');
  326. if (!isset($this->setup->language))
  327. self::setLanguage('en_us');
  328. if (!isset($this->meta->username))
  329. self::setUserName();
  330. if ($limit) {
  331. $limit = self::_integerBuild($limit);
  332. $this->meta->limit = chr(0x21) // integer
  333. . self::_giveMeStringLength('limit')
  334. . 'limit'
  335. . self::_giveMeStringLength($limit)
  336. . $limit;
  337. } else
  338. $this->meta->limit = '';
  339. if ($which_jobs == 'completed')
  340. $this->meta->which_jobs = chr(0x44) // keyword
  341. . self::_giveMeStringLength('which-jobs')
  342. . 'which-jobs'
  343. . self::_giveMeStringLength($which_jobs)
  344. . $which_jobs;
  345. else
  346. $this->meta->which_jobs = "";
  347. if ($my_jobs)
  348. $this->meta->my_jobs = chr(0x22) // boolean
  349. . self::_giveMeStringLength('my-jobs')
  350. . 'my-jobs'
  351. . self::_giveMeStringLength(chr(0x01))
  352. . chr(0x01);
  353. else
  354. $this->meta->my_jobs = '';
  355. $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
  356. . chr(0x00) . chr (0x0A) // Get-Jobs | operation-id
  357. . $this->meta->operation_id // request-id
  358. . chr(0x01) // start operation-attributes | operation-attributes-tag
  359. . $this->meta->charset
  360. . $this->meta->language
  361. . $this->meta->printer_uri
  362. . $this->meta->username
  363. . $this->meta->limit
  364. . $this->meta->which_jobs
  365. . $this->meta->my_jobs
  366. ;
  367. if ($subset) {
  368. $this->stringjob .=
  369. chr(0x44) // keyword
  370. . self::_giveMeStringLength('requested-attributes')
  371. . 'requested-attributes'
  372. . self::_giveMeStringLength('job-uri')
  373. . 'job-uri'
  374. . chr(0x44) // keyword
  375. . self::_giveMeStringLength('')
  376. . ''
  377. . self::_giveMeStringLength('job-name')
  378. . 'job-name'
  379. . chr(0x44) // keyword
  380. . self::_giveMeStringLength('')
  381. . ''
  382. . self::_giveMeStringLength('job-state')
  383. . 'job-state'
  384. . chr(0x44) // keyword
  385. . self::_giveMeStringLength('')
  386. . ''
  387. . self::_giveMeStringLength('job-state-reason')
  388. . 'job-state-reason'
  389. ;
  390. }
  391. else { # cups 1.4.4 doesn't return much of anything without this
  392. $this->stringjob .=
  393. chr(0x44) // keyword
  394. . self::_giveMeStringLength('requested-attributes')
  395. . 'requested-attributes'
  396. . self::_giveMeStringLength('all')
  397. . 'all'
  398. ;
  399. }
  400. $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag
  401. self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
  402. self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2);
  403. $this->output = $this->stringjob;
  404. $post_values = array( "Content-Type"=>"application/ipp",
  405. "Data"=>$this->output);
  406. if (self::_sendHttp ($post_values,$this->paths['jobs']))
  407. if (self::_parseServerOutput())
  408. self::_parseJobsAttributes();
  409. $this->attributes = &$this->jobs_attributes;
  410. if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
  411. $this->status = array_merge($this->status,array($this->serveroutput->status));
  412. if ($this->serveroutput->status == "successfull-ok")
  413. self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri)
  414. .$this->serveroutput->status,3);
  415. else
  416. self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri)
  417. .$this->serveroutput->status,1);
  418. return $this->serveroutput->status;
  419. }
  420. $this->status = array_merge($this->status,array("OPERATION FAILED"));
  421. self::_errorLog(date("Y-m-d H:i:s : ")
  422. .basename($_SERVER['PHP_SELF'])
  423. .sprintf(_("getting jobs of %s : OPERATION FAILED"),
  424. $this->printer_uri),3);
  425. return false;
  426. }
  427. // }}}
  428. // {{{ getJobAttributes ($job_uri,subset="false",$attributes_group="all");
  429. public function getJobAttributes($job_uri,$subset=false,$attributes_group="all") {
  430. $this->jobs = array_merge($this->jobs,array(""));
  431. $this->jobs_uri = array_merge($this->jobs_uri,array(""));
  432. if (!$job_uri) {
  433. trigger_error(_("getJobAttributes: Job URI is not set, die."));
  434. return FALSE;
  435. }
  436. self::_setOperationId();
  437. $this->parsed = array();
  438. unset($this->printer_attributes);
  439. if (!isset($this->setup->uri)) {
  440. $this->getPrinters();
  441. unset($this->jobs[count($this->jobs) - 1]);
  442. unset($this->jobs_uri[count($this->jobs_uri) - 1]);
  443. unset($this->status[count($this->status) - 1]);
  444. if (array_key_exists(0,$this->available_printers))
  445. self::setPrinterURI($this->available_printers[0]);
  446. else {
  447. trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING);
  448. self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
  449. self::_errorLog("getJobs: Printer URI is not set, die",2);
  450. return FALSE;
  451. }
  452. }
  453. if (!isset($this->setup->charset))
  454. self::setCharset('us-ascii');
  455. if (!isset($this->setup->language))
  456. self::setLanguage('en_us');
  457. if (!isset($this->meta->username))
  458. self::setUserName();
  459. $this->meta->job_uri = chr(0x45) // URI
  460. . self::_giveMeStringLength('job-uri')
  461. . 'job-uri'
  462. . self::_giveMeStringLength($job_uri)
  463. . $job_uri;
  464. $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
  465. . chr(0x00) . chr (0x09) // Get-Job-Attributes | operation-id
  466. . $this->meta->operation_id // request-id
  467. . chr(0x01) // start operation-attributes | operation-attributes-tag
  468. . $this->meta->charset
  469. . $this->meta->language
  470. . $this->meta->job_uri
  471. . $this->meta->username
  472. ;
  473. if ($subset)
  474. $this->stringjob .=
  475. chr(0x44) // keyword
  476. . self::_giveMeStringLength('requested-attributes')
  477. . 'requested-attributes'
  478. . self::_giveMeStringLength('job-uri')
  479. . 'job-uri'
  480. . chr(0x44) // keyword
  481. . self::_giveMeStringLength('')
  482. . ''
  483. . self::_giveMeStringLength('job-name')
  484. . 'job-name'
  485. . chr(0x44) // keyword
  486. . self::_giveMeStringLength('')
  487. . ''
  488. . self::_giveMeStringLength('job-state')
  489. . 'job-state'
  490. . chr(0x44) // keyword
  491. . self::_giveMeStringLength('')
  492. . ''
  493. . self::_giveMeStringLength('job-state-reason')
  494. . 'job-state-reason'
  495. ;
  496. elseif($attributes_group) {
  497. switch($attributes_group) {
  498. case 'job-template':
  499. break;
  500. case 'job-description':
  501. break;
  502. case 'all':
  503. break;
  504. default:
  505. trigger_error(_('not a valid attribute group: ').$attributes_group,E_USER_NOTICE);
  506. $attributes_group = '';
  507. break;
  508. }
  509. $this->stringjob .=
  510. chr(0x44) // keyword
  511. . self::_giveMeStringLength('requested-attributes')
  512. . 'requested-attributes'
  513. . self::_giveMeStringLength($attributes_group)
  514. . $attributes_group;
  515. }
  516. $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag
  517. self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
  518. self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2);
  519. $this->output = $this->stringjob;
  520. $post_values = array( "Content-Type"=>"application/ipp",
  521. "Data"=>$this->output);
  522. if (self::_sendHttp ($post_values,$this->paths['jobs']))
  523. if (self::_parseServerOutput())
  524. self::_parseJobAttributes();
  525. $this->attributes = &$this->job_attributes;
  526. if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
  527. $this->status = array_merge($this->status,array($this->serveroutput->status));
  528. if ($this->serveroutput->status == "successfull-ok")
  529. self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri)
  530. .$this->serveroutput->status,3);
  531. else
  532. self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri)
  533. .$this->serveroutput->status,1);
  534. return $this->serveroutput->status;
  535. }
  536. $this->status = array_merge($this->status,array("OPERATION FAILED"));
  537. self::_errorLog(date("Y-m-d H:i:s : ")
  538. .basename($_SERVER['PHP_SELF'])
  539. .sprintf(_("getting jobs attributes of %s : OPERATION FAILED"),
  540. $job_uri),3);
  541. return false;
  542. }
  543. // }}}
  544. // {{{ getPrinters();
  545. public function getPrinters() {
  546. // placeholder for vendor extension operation (getAvailablePrinters for CUPS)
  547. $this->jobs = array_merge($this->jobs,array(''));
  548. $this->jobs_uri = array_merge($this->jobs_uri,array(''));
  549. $this->status = array_merge($this->status,array(''));
  550. }
  551. // }}}
  552. /******************
  553. *
  554. * DEVELOPPEMENT FUNCTIONS
  555. *
  556. *******************/
  557. // {{{ generateError($error)
  558. public function generateError ($error) {
  559. switch ($error) {
  560. case "request_body_malformed":
  561. $this->error_generation->request_body_malformed = chr(0xFF);
  562. break;
  563. default:
  564. true;
  565. break;
  566. }
  567. // }}}
  568. // {{{ resetError ($error)
  569. trigger_error(sprintf(_('Setting Error %s'),$error),E_USER_NOTICE);
  570. }
  571. public function resetError ($error) {
  572. unset ($this->error_generation->$error);
  573. trigger_error(sprintf(_('Reset Error %s'),$error),E_USER_NOTICE);
  574. }
  575. // }}}
  576. /******************
  577. *
  578. * PROTECTED FUNCTIONS
  579. *
  580. *******************/
  581. // SETUP
  582. // {{{ _setOperationId ()
  583. protected function _setOperationId () {
  584. $prepend = '';
  585. $this->operation_id += 1;
  586. $this->meta->operation_id = self::_integerBuild($this->operation_id);
  587. self::_putDebug( "operation id is: ".$this->operation_id."\n",2);
  588. }
  589. // }}}
  590. // {{{ _setJobId()
  591. protected function _setJobId() {
  592. $this->meta->jobid +=1;
  593. $prepend = '';
  594. $prepend_length = 4 - strlen($this->meta->jobid);
  595. for ($i = 0; $i < $prepend_length ; $i++ )
  596. $prepend .= '0';
  597. return $prepend.$this->meta->jobid;
  598. }
  599. // }}}
  600. // {{{ _setJobUri ($job_uri)
  601. protected function _setJobUri ($job_uri) {
  602. $this->meta->job_uri = chr(0x45) // type uri
  603. . chr(0x00).chr(0x07) // name-length
  604. . "job-uri"
  605. //. chr(0x00).chr(strlen($job_uri))
  606. . self::_giveMeStringLength($job_uri)
  607. . $job_uri;
  608. self::_putDebug( "job-uri is: ".$job_uri."\n",2);
  609. }
  610. // }}}
  611. // RESPONSE PARSING
  612. // {{{ _parsePrinterAttributes()
  613. protected function _parsePrinterAttributes() {
  614. //if (!preg_match('#successful#',$this->serveroutput->status))
  615. // return false;
  616. $k = -1;
  617. for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
  618. for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
  619. if (!empty($this->serveroutput->response[$i][$j]['name'])) {
  620. $k++;
  621. $l = 0;
  622. $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
  623. $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
  624. $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
  625. $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  626. } else {
  627. $l ++;
  628. $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  629. }
  630. $this->serveroutput->response = array();
  631. $this->printer_attributes = new stdClass();
  632. for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
  633. $name = $this->parsed[$i]['name'];
  634. $php_name = str_replace('-','_',$name);
  635. $type = $this->parsed[$i]['type'];
  636. $range = $this->parsed[$i]['range'];
  637. $this->printer_attributes->$php_name = new stdClass();
  638. $this->printer_attributes->$php_name->_type = $type;
  639. $this->printer_attributes->$php_name->_range = $range;
  640. for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
  641. $value = $this->parsed[$i][$j];
  642. $index = '_value'.$j;
  643. $this->printer_attributes->$php_name->$index = $value;
  644. }
  645. }
  646. $this->parsed = array();
  647. }
  648. // }}}
  649. // {{{ _parseJobsAttributes()
  650. protected function _parseJobsAttributes() {
  651. //if ($this->serveroutput->status != "successfull-ok")
  652. // return false;
  653. $job = -1;
  654. for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) {
  655. if ($this->serveroutput->response[$i]['attributes'] == "job-attributes")
  656. $job ++;
  657. $k = -1;
  658. for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
  659. if (!empty($this->serveroutput->response[$i][$j]['name'])) {
  660. $k++;
  661. $l = 0;
  662. $this->parsed[$job][$k]['range'] = $this->serveroutput->response[$i]['attributes'];
  663. $this->parsed[$job][$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
  664. $this->parsed[$job][$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
  665. $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  666. } else {
  667. $l ++;
  668. $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  669. }
  670. }
  671. $this->serveroutput->response = array();
  672. $this->jobs_attributes = new stdClass();
  673. for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++) {
  674. $job_index = "job_".$job_nbr;
  675. $this->jobs_attributes->$job_index = new stdClass();
  676. for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++) {
  677. $name = $this->parsed[$job_nbr][$i]['name'];
  678. $php_name = str_replace('-','_',$name);
  679. $type = $this->parsed[$job_nbr][$i]['type'];
  680. $range = $this->parsed[$job_nbr][$i]['range'];
  681. $this->jobs_attributes->$job_index->$php_name = new stdClass();
  682. $this->jobs_attributes->$job_index->$php_name->_type = $type;
  683. $this->jobs_attributes->$job_index->$php_name->_range = $range;
  684. for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++) {
  685. # This causes incorrect parsing of integer job attributes.
  686. # 2010-08-16
  687. # bpkroth
  688. #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]);
  689. $value = $this->parsed[$job_nbr][$i][$j];
  690. $index = '_value'.$j;
  691. $this->jobs_attributes->$job_index->$php_name->$index = $value;
  692. }
  693. }
  694. }
  695. $this->parsed = array();
  696. }
  697. // }}}
  698. // {{{ _readAttribute($attributes_type,$ji,&$collection=false)
  699. protected function _readAttribute($attributes_type) {
  700. $tag = ord($this->serveroutput->body[$this->_parsing->offset]);
  701. $this->_parsing->offset += 1;
  702. $j = $this->index;
  703. $tag = self::_readTag($tag);
  704. switch ($tag) {
  705. case "begCollection": //RFC3382 (BLIND CODE)
  706. if ($this->end_collection)
  707. $this->index --;
  708. $this->end_collection = false;
  709. $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
  710. self::_putDebug( "tag is: begCollection\n");
  711. self::_readAttributeName ($attributes_type,$j);
  712. if (!$this->serveroutput->response[$attributes_type][$j]['name']) { // it is a multi-valued collection
  713. $this->collection_depth ++;
  714. $this->index --;
  715. $this->collection_nbr[$this->collection_depth] ++;
  716. } else {
  717. $this->collection_depth ++;
  718. if ($this->collection_depth == 0)
  719. $this->collection = (object) 'collection';
  720. if (array_key_exists($this->collection_depth,$this->collection_nbr))
  721. $this->collection_nbr[$this->collection_depth] ++;
  722. else
  723. $this->collection_nbr[$this->collection_depth] = 0;
  724. unset($this->end_collection);
  725. }
  726. self::_readValue ("begCollection",$attributes_type,$j);
  727. break;
  728. case "endCollection": //RFC3382 (BLIND CODE)
  729. $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
  730. self::_putDebug( "tag is: endCollection\n");
  731. self::_readAttributeName ($attributes_type,$j,0);
  732. self::_readValue ('name',$attributes_type,$j,0);
  733. $this->collection_depth --;
  734. $this->collection_key[$this->collection_depth] = 0;
  735. $this->end_collection = true;
  736. break;
  737. case "memberAttrName": // RFC3382 (BLIND CODE)
  738. $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName";
  739. $this->index -- ;
  740. self::_putDebug( "tag is: memberAttrName\n");
  741. self::_readCollection ($attributes_type,$j);
  742. break;
  743. default:
  744. $this->collection_depth = -1;
  745. $this->collection_key = array();
  746. $this->collection_nbr = array();
  747. $this->serveroutput->response[$attributes_type][$j]['type'] = $tag;
  748. self::_putDebug( "tag is: $tag\n");
  749. $attribute_name = self::_readAttributeName ($attributes_type,$j);
  750. if (!$attribute_name)
  751. $attribute_name = $this->attribute_name;
  752. else
  753. $this->attribute_name = $attribute_name;
  754. $value = self::_readValue ($tag,$attributes_type,$j);
  755. $this->serveroutput->response[$attributes_type][$j]['value'] =
  756. self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']);
  757. break;
  758. }
  759. return;
  760. }
  761. // }}}
  762. // {{{ _readTag($tag)
  763. protected function _readTag($tag) {
  764. switch ($tag) {
  765. case 0x10:
  766. $tag = "unsupported";
  767. break;
  768. case 0x11:
  769. $tag = "reserved for 'default'";
  770. break;
  771. case 0x12:
  772. $tag = "unknown";
  773. break;
  774. case 0x13:
  775. $tag = "no-value";
  776. break;
  777. case 0x15: // RFC 3380
  778. $tag = "not-settable";
  779. break;
  780. case 0x16: // RFC 3380
  781. $tag = "delete-attribute";
  782. break;
  783. case 0x17: // RFC 3380
  784. $tag = "admin-define";
  785. break;
  786. case 0x20:
  787. $tag = "IETF reserved (generic integer)";
  788. break;
  789. case 0x21:
  790. $tag = "integer";
  791. break;
  792. case 0x22:
  793. $tag = "boolean";
  794. break;
  795. case 0x23:
  796. $tag = "enum";
  797. break;
  798. case 0x30:
  799. $tag = "octetString";
  800. break;
  801. case 0x31:
  802. $tag = "datetime";
  803. break;
  804. case 0x32:
  805. $tag = "resolution";
  806. break;
  807. case 0x33:
  808. $tag = "rangeOfInteger";
  809. break;
  810. case 0x34: //RFC3382 (BLIND CODE)
  811. $tag = "begCollection";
  812. break;
  813. case 0x35:
  814. $tag = "textWithLanguage";
  815. break;
  816. case 0x36:
  817. $tag = "nameWithLanguage";
  818. break;
  819. case 0x37: //RFC3382 (BLIND CODE)
  820. $tag = "endCollection";
  821. break;
  822. case 0x40:
  823. $tag = "IETF reserved text string";
  824. break;
  825. case 0x41:
  826. $tag = "textWithoutLanguage";
  827. break;
  828. case 0x42:
  829. $tag = "nameWithoutLanguage";
  830. break;
  831. case 0x43:
  832. $tag = "IETF reserved for future";
  833. break;
  834. case 0x44:
  835. $tag = "keyword";
  836. break;
  837. case 0x45:
  838. $tag = "uri";
  839. break;
  840. case 0x46:
  841. $tag = "uriScheme";
  842. break;
  843. case 0x47:
  844. $tag = "charset";
  845. break;
  846. case 0x48:
  847. $tag = "naturalLanguage";
  848. break;
  849. case 0x49:
  850. $tag = "mimeMediaType";
  851. break;
  852. case 0x4A: // RFC3382 (BLIND CODE)
  853. $tag = "memberAttrName";
  854. break;
  855. case 0x7F:
  856. $tag = "extended type";
  857. break;
  858. default:
  859. if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f)
  860. $tag = "out-of-band";
  861. elseif (0x24 <= $tag && $tag <= 0x2f)
  862. $tag = "new integer type";
  863. elseif (0x38 <= $tag && $tag <= 0x3F)
  864. $tag = "new octet-stream type";
  865. elseif (0x4B <= $tag && $tag <= 0x5F)
  866. $tag = "new character string type";
  867. elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 )
  868. $tag = "IETF reserved for future";
  869. else
  870. $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag);
  871. break;
  872. }
  873. return $tag;
  874. }
  875. // }}}
  876. // {{{ _readCollection($attributes_type,$j,&$collection)
  877. protected function _readCollection($attributes_type,$j) {
  878. $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
  879. + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
  880. $this->_parsing->offset += 2;
  881. self::_putDebug( "Collection name_length ". $name_length ."\n");
  882. $name = '';
  883. for ($i = 0; $i < $name_length; $i++) {
  884. $name .= $this->serveroutput->body[$this->_parsing->offset];
  885. $this->_parsing->offset += 1;
  886. if ($this->_parsing->offset > strlen($this->serveroutput->body))
  887. return;
  888. }
  889. $collection_name = $name;
  890. $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
  891. + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
  892. $this->_parsing->offset += 2;
  893. self::_putDebug( "Attribute name_length ". $name_length ."\n");
  894. $name = '';
  895. for ($i = 0; $i < $name_length; $i++) {
  896. $name .= $this->serveroutput->body[$this->_parsing->offset];
  897. $this->_parsing->offset += 1;
  898. if ($this->_parsing->offset > strlen($this->serveroutput->body))
  899. return;
  900. }
  901. $attribute_name = $name;
  902. if ($attribute_name == "") {
  903. $attribute_name = $this->last_attribute_name;
  904. $this->collection_key[$this->collection_depth] ++;
  905. } else {
  906. $this->collection_key[$this->collection_depth] = 0;
  907. }
  908. $this->last_attribute_name = $attribute_name;
  909. self::_putDebug( "Attribute name ".$name."\n");
  910. $tag = self::_readTag(ord($this->serveroutput->body[$this->_parsing->offset]));
  911. $this->_parsing->offset ++;
  912. $type = $tag;
  913. $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
  914. + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
  915. $this->_parsing->offset += 2;
  916. self::_putDebug( "Collection2 name_length ". $name_length ."\n");
  917. $name = '';
  918. for ($i = 0; $i < $name_length; $i++) {
  919. $name .= $this->serveroutput->body[$this->_parsing->offset];
  920. $this->_parsing->offset += 1;
  921. if ($this->_parsing->offset > strlen($this->serveroutput->body))
  922. return;
  923. }
  924. $collection_value = $name;
  925. $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
  926. + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
  927. self::_putDebug( "Collection value_length ".$this->serveroutput->body[ $this->_parsing->offset]
  928. . $this->serveroutput->body[$this->_parsing->offset + 1]
  929. .": "
  930. . $value_length
  931. . " ");
  932. $this->_parsing->offset += 2;
  933. $value = '';
  934. for ($i = 0; $i < $value_length; $i++) {
  935. if ($this->_parsing->offset >= strlen($this->serveroutput->body))
  936. return;
  937. $value .= $this->serveroutput->body[$this->_parsing->offset];
  938. $this->_parsing->offset += 1;
  939. }
  940. $object = &$this->collection;
  941. for ($i = 0 ; $i <= $this->collection_depth ; $i ++) {
  942. $indice = "_indice".$this->collection_nbr[$i];
  943. if (!isset($object->$indice))
  944. $object->$indice = (object) 'indice';
  945. $object = &$object->$indice;
  946. }
  947. $value_key = "_value".$this->collection_key[$this->collection_depth];
  948. $col_name_key = "_collection_name".$this->collection_key[$this->collection_depth];
  949. $col_val_key = "_collection_value".$this->collection_key[$this->collection_depth];
  950. $attribute_value = self::_interpretAttribute($attribute_name,$tag,$value);
  951. $attribute_name = str_replace('-','_',$attribute_name);
  952. self::_putDebug( sprintf("Value: %s\n",$value));
  953. $object->$attribute_name->_type = $type;
  954. $object->$attribute_name->$value_key = $attribute_value;
  955. $object->$attribute_name->$col_name_key = $collection_name;
  956. $object->$attribute_name->$col_val_key = $collection_value;
  957. $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection;
  958. }
  959. // }}}
  960. // {{{ _readAttributeName ($attributes_type,$j)
  961. protected function _readAttributeName ($attributes_type,$j,$write=1) {
  962. $name_length = ord($this->serveroutput->body[ $this->_parsing->offset]) * 256
  963. + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
  964. $this->_parsing->offset += 2;
  965. self::_putDebug( "name_length ". $name_length ."\n");
  966. $name = '';
  967. for ($i = 0; $i < $name_length; $i++) {
  968. if ($this->_parsing->offset >= strlen($this->serveroutput->body))
  969. return;
  970. $name .= $this->serveroutput->body[$this->_parsing->offset];
  971. $this->_parsing->offset += 1;
  972. }
  973. if($write)
  974. $this->serveroutput->response[$attributes_type][$j]['name'] = $name;
  975. self::_putDebug( "name " . $name . "\n");
  976. return $name;
  977. }
  978. // }}}
  979. // {{{ _readValue ($type,$attributes_type,$j)
  980. protected function _readValue ($type,$attributes_type,$j,$write=1) {
  981. $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
  982. + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
  983. self::_putDebug( "value_length ".$this->serveroutput->body[ $this->_parsing->offset]
  984. . $this->serveroutput->body[$this->_parsing->offset + 1]
  985. .": "
  986. . $value_length
  987. . " ");
  988. $this->_parsing->offset += 2;
  989. $value = '';
  990. for ($i = 0; $i < $value_length; $i++) {
  991. if ($this->_parsing->offset >= strlen($this->serveroutput->body))
  992. return;
  993. $value .= $this->serveroutput->body[$this->_parsing->offset];
  994. $this->_parsing->offset += 1;
  995. }
  996. self::_putDebug( sprintf("Value: %s\n",$value));
  997. if ($write)
  998. $this->serveroutput->response[$attributes_type][$j]['value'] = $value;
  999. return $value;
  1000. }
  1001. // }}}
  1002. // {{{ _parseAttributes()
  1003. protected function _parseAttributes() {
  1004. $k = -1;
  1005. for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
  1006. for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
  1007. if (!empty($this->serveroutput->response[$i][$j]['name'])) {
  1008. $k++;
  1009. $l = 0;
  1010. $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
  1011. $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
  1012. $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
  1013. $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  1014. } else {
  1015. $l ++;
  1016. $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  1017. }
  1018. $this->serveroutput->response = array();
  1019. $this->attributes = new stdClass();
  1020. for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
  1021. $name = $this->parsed[$i]['name'];
  1022. $php_name = str_replace('-','_',$name);
  1023. $type = $this->parsed[$i]['type'];
  1024. $range = $this->parsed[$i]['range'];
  1025. $this->attributes->$php_name = new stdClass();
  1026. $this->attributes->$php_name->_type = $type;
  1027. $this->attributes->$php_name->_range = $range;
  1028. for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
  1029. $value = $this->parsed[$i][$j];
  1030. $index = '_value'.$j;
  1031. $this->attributes->$php_name->$index = $value;
  1032. }
  1033. }
  1034. $this->parsed = array();
  1035. }
  1036. // }}}
  1037. // {{{ _parseJobAttributes()
  1038. protected function _parseJobAttributes() {
  1039. //if (!preg_match('#successful#',$this->serveroutput->status))
  1040. // return false;
  1041. $k = -1;
  1042. for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
  1043. for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
  1044. if (!empty($this->serveroutput->response[$i][$j]['name'])) {
  1045. $k++;
  1046. $l = 0;
  1047. $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
  1048. $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
  1049. $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
  1050. $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  1051. } else {
  1052. $l ++;
  1053. $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
  1054. }
  1055. $this->serveroutput->response = array();
  1056. $this->job_attributes = new stdClass();
  1057. for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
  1058. $name = $this->parsed[$i]['name'];
  1059. $php_name = str_replace('-','_',$name);
  1060. $type = $this->parsed[$i]['type'];
  1061. $range = $this->parsed[$i]['range'];
  1062. $this->job_attributes->$php_name = new stdClass();
  1063. $this->job_attributes->$php_name->_type = $type;
  1064. $this->job_attributes->$php_name->_range = $range;
  1065. for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
  1066. $value = $this->parsed[$i][$j];
  1067. $index = '_value'.$j;
  1068. $this->job_attributes->$php_name->$index = $value;
  1069. }
  1070. }
  1071. $this->parsed = array();
  1072. }
  1073. // }}}
  1074. // {{{ _interpretAttribute($attribute_name,$type,$value)
  1075. protected function _interpretAttribute($attribute_name,$type,$value) {
  1076. switch ($type) {
  1077. case "integer":
  1078. $value = self::_interpretInteger($value);
  1079. break;
  1080. case "rangeOfInteger":
  1081. $value = self::_interpretRangeOfInteger($value);
  1082. break;
  1083. case 'boolean':
  1084. $value = ord($value);
  1085. if ($value == 0x00)
  1086. $value = 'false';
  1087. else
  1088. $value = 'true';
  1089. break;
  1090. case 'datetime':
  1091. $value = self::_interpretDateTime($value);
  1092. break;
  1093. case 'enum':
  1094. $value = $this->_interpretEnum($attribute_name,$value); // must be overwritten by children
  1095. break;
  1096. case 'resolution':
  1097. $unit = $value[8];
  1098. $value = self::_interpretRangeOfInteger(substr($value,0,8));
  1099. switch($unit) {
  1100. case chr(0x03):
  1101. $unit = "dpi";
  1102. break;
  1103. case chr(0x04):
  1104. $unit = "dpc";
  1105. break;
  1106. }
  1107. $value = $value." ".$unit;
  1108. break;
  1109. default:
  1110. break;
  1111. }
  1112. return $value;
  1113. }
  1114. // }}}
  1115. // {{{ _interpretRangeOfInteger($value)
  1116. protected function _interpretRangeOfInteger($value) {
  1117. $value_parsed = 0;
  1118. $integer1 = $integer2 = 0;
  1119. $halfsize = strlen($value) / 2;
  1120. $integer1 = self::_interpretInteger(substr($value,0,$halfsize));
  1121. $integer2 = self::_interpretInteger(substr($value,$halfsize,$halfsize));
  1122. $value_parsed = sprintf('%s-%s',$integer1,$integer2);
  1123. return $value_parsed;
  1124. }
  1125. // }}}
  1126. // {{{ _interpretDateTime($date) {
  1127. protected function _interpretDateTime($date) {
  1128. $year = self::_interpretInteger(substr($date,0,2));
  1129. $month = self::_interpretInteger(substr($date,2,1));
  1130. $day = self::_interpretInteger(substr($date,3,1));
  1131. $hour = self::_interpretInteger(substr($date,4,1));
  1132. $minute = self::_interpretInteger(substr($date,5,1));
  1133. $second = self::_interpretInteger(substr($date,6,1));
  1134. $direction = substr($date,8,1);
  1135. $hours_from_utc = self::_interpretInteger(substr($date,9,1));
  1136. $minutes_from_utc = self::_interpretInteger(substr($date,10,1));
  1137. $date = sprintf('%s-%s-%s %s:%s:%s %s%s:%s',$year,$month,$day,$hour,$minute,$second,$direction,$hours_from_utc,$minutes_from_utc);
  1138. return $date;
  1139. }
  1140. // }}}
  1141. // {{{ _interpretEnum()
  1142. protected function _interpretEnum($attribute_name,$value) {
  1143. $value_parsed = self::_interpretInteger($value);
  1144. switch ($attribute_name) {
  1145. case 'job-state':
  1146. switch ($value_parsed) {
  1147. case 0x03:
  1148. $value = 'pending';
  1149. break;
  1150. case 0x04:
  1151. $value = 'pending-held';
  1152. break;
  1153. case 0x05:
  1154. $value = 'processing';
  1155. break;
  1156. case 0x06:
  1157. $value = 'processing-stopped';
  1158. break;
  1159. case 0x07:
  1160. $value = 'canceled';
  1161. break;
  1162. case 0x08:
  1163. $value = 'aborted';
  1164. break;
  1165. case 0x09:
  1166. $value = 'completed';
  1167. break;
  1168. }
  1169. if ($value_parsed > 0x09)
  1170. $value = sprintf('Unknown(IETF standards track "job-state" reserved): 0x%x',$value_parsed);
  1171. break;
  1172. case 'print-quality':
  1173. case 'print-quality-supported':
  1174. case 'print-quality-default':
  1175. switch ($value_parsed) {
  1176. case 0x03:
  1177. $value = 'draft';
  1178. break;
  1179. case 0x04:
  1180. $value = 'normal';
  1181. break;
  1182. case 0x05:
  1183. $value = 'high';
  1184. break;
  1185. }
  1186. break;
  1187. case 'printer-state':
  1188. switch ($value_parsed) {
  1189. case 0x03:
  1190. $value = 'idle';
  1191. break;
  1192. case 0x04:
  1193. $value = 'processing';
  1194. break;
  1195. case 0x05:
  1196. $value = 'stopped';
  1197. break;
  1198. }
  1199. if ($value_parsed > 0x05)
  1200. $value = sprintf('Unknown(IETF standards track "printer-state" reserved): 0x%x',$value_parsed);
  1201. break;
  1202. case 'operations-supported':
  1203. switch($value_parsed) {
  1204. case 0x0000:
  1205. case 0x0001:
  1206. $value = sprintf('Unknown(reserved) : %s',ord($value));
  1207. break;
  1208. case 0x0002:
  1209. $value = 'Print-Job';
  1210. break;
  1211. case 0x0003:
  1212. $value = 'Print-URI';
  1213. break;
  1214. case 0x0004:
  1215. $value = 'Validate-Job';
  1216. break;
  1217. case 0x0005:
  1218. $value = 'Create-Job';
  1219. break;
  1220. case 0x0006:
  1221. $value = 'Send-Document';
  1222. break;
  1223. case 0x0007:
  1224. $value = 'Send-URI';
  1225. break;
  1226. case 0x0008:
  1227. $value = 'Cancel-Job';
  1228. break;
  1229. case 0x0009:
  1230. $value = 'Get-Job-Attributes';
  1231. break;
  1232. case 0x000A:
  1233. $value = 'Get-Jobs';
  1234. break;
  1235. case 0x000B:
  1236. $value = 'Get-Printer-Attributes';
  1237. break;
  1238. case 0x000C:
  1239. $value = 'Hold-Job';
  1240. break;
  1241. case 0x000D:
  1242. $value = 'Release-Job';
  1243. break;
  1244. case 0x000E:
  1245. $value = 'Restart-Job';
  1246. break;
  1247. case 0x000F:
  1248. $value = 'Unknown(reserved for a future operation)';
  1249. break;
  1250. case 0x0010:
  1251. $value = 'Pause-Printer';
  1252. break;
  1253. case 0x0011:
  1254. $value = 'Resume-Printer';
  1255. break;
  1256. case 0x0012:
  1257. $value = 'Purge-Jobs';
  1258. break;
  1259. case 0x0013:
  1260. $value = 'Set-Printer-Attributes'; // RFC3380
  1261. break;
  1262. case 0x0014:
  1263. $value = 'Set-Job-Attributes'; // RFC3380
  1264. break;
  1265. case 0x0015:
  1266. $value = 'Get-Printer-Supported-Values'; // RFC3380
  1267. break;
  1268. case 0x0016:
  1269. $value = 'Create-Printer-Subscriptions';
  1270. break;
  1271. case 0x0017:
  1272. $value = 'Create-Job-Subscriptions';
  1273. break;
  1274. case 0x0018:
  1275. $value = 'Get-Subscription-Attributes';
  1276. break;
  1277. case 0x0019:
  1278. $value = 'Get-Subscriptions';
  1279. break;
  1280. case 0x001A:
  1281. $value = 'Renew-Subscription';
  1282. break;
  1283. case 0x001B:
  1284. $value = 'Cancel-Subscription';
  1285. break;
  1286. case 0x001C:
  1287. $value = 'Get-Notifications';
  1288. break;
  1289. case 0x001D:
  1290. $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
  1291. break;
  1292. case 0x001E:
  1293. $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
  1294. break;
  1295. case 0x001F:
  1296. $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
  1297. break;
  1298. case 0x0020:
  1299. $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
  1300. break;
  1301. case 0x0021:
  1302. $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
  1303. break;
  1304. case 0x0022:
  1305. $value = 'Enable-Printer';
  1306. break;
  1307. case 0x0023:
  1308. $value = 'Disable-Printer';
  1309. break;
  1310. case 0x0024:
  1311. $value = 'Pause-Printer-After-Current-Job';
  1312. break;
  1313. case 0x0025:
  1314. $value = 'Hold-New-Jobs';
  1315. break;
  1316. case 0x0026:
  1317. $value = 'Release-Held-New-Jobs';
  1318. break;
  1319. case 0x0027:
  1320. $value = 'Deactivate-Printer';
  1321. break;
  1322. case 0x0028:
  1323. $value = 'Activate-Printer';
  1324. break;
  1325. case 0x0029:
  1326. $value = 'Restart-Printer';
  1327. break;
  1328. case 0x002A:
  1329. $value = 'Shutdown-Printer';
  1330. break;
  1331. case 0x002B:
  1332. $value = 'Startup-Printer';
  1333. break;
  1334. }
  1335. if ($value_parsed > 0x002B && $value_parsed <= 0x3FFF)
  1336. $value = sprintf('Unknown(IETF standards track operations reserved): 0x%x',$value_parsed);
  1337. elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) {
  1338. if (method_exists($this,'_getEnumVendorExtensions')) {
  1339. $value = $this->_getEnumVendorExtensions($value_parsed);
  1340. } else
  1341. $value = sprintf('Unknown(Vendor extension for operations): 0x%x',$value_parsed);
  1342. } elseif ($value_parsed > 0x8FFF)
  1343. $value = sprintf('Unknown operation (should not exists): 0x%x',$value_parsed);
  1344. break;
  1345. case 'finishings':
  1346. case 'finishings-default':
  1347. case 'finishings-supported':
  1348. switch ($value_parsed) {
  1349. case 3:
  1350. $value = 'none';
  1351. break;
  1352. case 4:
  1353. $value = 'staple';
  1354. break;
  1355. case 5:
  1356. $value = 'punch';
  1357. break;
  1358. case 6:
  1359. $value = 'cover';
  1360. break;
  1361. case 7:
  1362. $value = 'bind';
  1363. break;
  1364. case 8:
  1365. $value = 'saddle-stitch';
  1366. break;
  1367. case 9:
  1368. $value = 'edge-stitch';
  1369. break;
  1370. case 20:
  1371. $value = 'staple-top-left';
  1372. break;
  1373. case 21:
  1374. $value = 'staple-bottom-left';
  1375. break;
  1376. case 22:
  1377. $value = 'staple-top-right';
  1378. break;
  1379. case 23:
  1380. $value = 'staple-bottom-right';
  1381. break;
  1382. case 24:
  1383. $value = 'edge-stitch-left';
  1384. break;
  1385. case 25:
  1386. $value = 'edge-stitch-top';
  1387. break;
  1388. case 26:
  1389. $value = 'edge-stitch-right';
  1390. break;
  1391. case 27:
  1392. $value = 'edge-stitch-bottom';
  1393. break;
  1394. case 28:
  1395. $value = 'staple-dual-left';
  1396. break;
  1397. case 29:
  1398. $value = 'staple-dual-top';
  1399. break;
  1400. case 30:
  1401. $value = 'staple-dual-right';
  1402. break;
  1403. case 31:
  1404. $value = 'staple-dual-bottom';
  1405. break;
  1406. }
  1407. if ($value_parsed > 31)
  1408. $value = sprintf('Unknown(IETF standards track "finishing" reserved): 0x%x',$value_parsed);
  1409. break;
  1410. case 'orientation-requested':
  1411. case 'orientation-requested-supported':
  1412. case 'orientation-requested-default':
  1413. switch ($value_parsed) {
  1414. case 0x03:
  1415. $value = 'portrait';
  1416. break;
  1417. case 0x04:
  1418. $value = 'landscape';
  1419. break;
  1420. case 0x05:
  1421. $value = 'reverse-landscape';
  1422. break;
  1423. case 0x06:
  1424. $value = 'reverse-portrait';
  1425. break;
  1426. }
  1427. if ($value_parsed > 0x06)
  1428. $value = sprintf('Unknown(IETF standards track "orientation" reserved): 0x%x',$value_parsed);
  1429. break;
  1430. default:
  1431. break;
  1432. }
  1433. return $value;
  1434. }
  1435. // }}}
  1436. // {{{ _getJobId ()
  1437. protected function _getJobId () {
  1438. if (!isset($this->serveroutput->response))
  1439. $this->jobs = array_merge($this->jobs,array('NO JOB'));
  1440. $jobfinded = false;
  1441. for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++)
  1442. if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
  1443. for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
  1444. if ($this->serveroutput->response[$i][$j]['name'] == "job-id") {
  1445. $this->last_job = $this->serveroutput->response[$i][$j]['value'];
  1446. $this->jobs = array_merge($this->jobs,array($this->serveroutput->response[$i][$j]['value']));
  1447. return;
  1448. }
  1449. }
  1450. // }}}
  1451. // {{{ _getJobUri ()
  1452. protected function _getJobUri () {
  1453. if (!isset($this->jobs_uri))
  1454. $this->jobs_uri = array();
  1455. $jobfinded = false;
  1456. for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++)
  1457. if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
  1458. for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
  1459. if ($this->serveroutput->response[$i][$j]['name'] == "job-uri") {
  1460. $this->last_job = $this->serveroutput->response[$i][$j]['value'];
  1461. $this->jobs_uri = array_merge($this->jobs_uri,array($this->last_job));
  1462. return;
  1463. }
  1464. $this->last_job = '';
  1465. }
  1466. // }}}
  1467. // {{{ _parseResponse ()
  1468. protected function _parseResponse () {
  1469. $j = -1;
  1470. $this->index = 0;
  1471. for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) {
  1472. $tag = ord($this->serveroutput->body[$this->_parsing->offset]);
  1473. if ($tag > 0x0F) {
  1474. self::_readAttribute($j);
  1475. $this->index ++;
  1476. continue;
  1477. }
  1478. switch ($tag) {
  1479. case 0x01:
  1480. $j += 1;
  1481. $this->serveroutput->response[$j]['attributes'] = "operation-attributes";
  1482. $this->index = 0;
  1483. $this->_parsing->offset += 1;
  1484. break;
  1485. case 0x02:
  1486. $j += 1;
  1487. $this->serveroutput->response[$j]['attributes'] = "job-attributes";
  1488. $this->index = 0;
  1489. $this->_parsing->offset += 1;
  1490. break;
  1491. case 0x03:
  1492. $j +=1;
  1493. $this->serveroutput->response[$j]['attributes'] = "end-of-attributes";
  1494. self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n");
  1495. if ($this->alert_on_end_tag === 1)
  1496. echo "END tag OK<br />";
  1497. $this->response_completed[(count($this->response_completed) -1)] = "completed";
  1498. return;
  1499. case 0x04:
  1500. $j += 1;
  1501. $this->serveroutput->response[$j]['attributes'] = "printer-attributes";
  1502. $this->index = 0;
  1503. $this->_parsing->offset += 1;
  1504. break;
  1505. case 0x05:
  1506. $j += 1;
  1507. $this->serveroutput->response[$j]['attributes'] = "unsupported-attributes";
  1508. $this->index = 0;
  1509. $this->_parsing->offset += 1;
  1510. break;
  1511. default:
  1512. $j += 1;
  1513. $this->serveroutput->response[$j]['attributes'] = sprintf(_("0x%x (%u) : attributes tag Unknown (reserved for future versions of IPP"),$tag,$tag);
  1514. $this->index = 0;
  1515. $this->_parsing->offset += 1;
  1516. break;
  1517. }
  1518. self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n");
  1519. }
  1520. return;
  1521. }
  1522. // }}}
  1523. /*
  1524. // NOTICE : HAVE TO READ AGAIN RFC 2911 TO SEE IF IT IS PART OF SERVER'S RESPONSE (CUPS DO NOT)
  1525. // {{{ _getPrinterUri ()
  1526. protected function _getPrinterUri () {
  1527. for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++)
  1528. if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
  1529. for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
  1530. if ($this->serveroutput->response[$i][$j]['name'] == "printer-uri") {
  1531. $this->printers_uri = array_merge($this->printers_uri,array($this->serveroutput->response[$i][$j]['value']));
  1532. return;
  1533. }
  1534. $this->printers_uri = array_merge($this->printers_uri,array(''));
  1535. }
  1536. // }}}
  1537. */
  1538. // REQUEST BUILDING
  1539. // {{{ _stringCancel ()
  1540. protected function _stringCancel ($job_uri) {
  1541. if (!isset($this->setup->charset))
  1542. self::setCharset('us-ascii');
  1543. if (!isset($this->setup->datatype))
  1544. self::setBinary();
  1545. if (!isset($this->setup->language))
  1546. self::setLanguage('en_us');
  1547. if (!$this->requesting_user)
  1548. self::setUserName();
  1549. if (!isset($this->meta->message))
  1550. $this->meta->message = '';
  1551. self::_setOperationId();
  1552. self::_setJobUri($job_uri);
  1553. if (!isset($this->error_generation->request_body_malformed))
  1554. $this->error_generation->request_body_malformed = "";
  1555. $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
  1556. . chr(0x00) . chr (0x08) // cancel-Job | operation-id
  1557. . $this->meta->operation_id // request-id
  1558. . $this->error_generation->request_body_malformed
  1559. . chr(0x01) // start operation-attributes | operation-attributes-tag
  1560. . $this->meta->charset
  1561. . $this->meta->language
  1562. . $this->meta->job_uri
  1563. . $this->meta->username
  1564. . $this->meta->message
  1565. . chr(0x03); // end-of-attributes | end-of-attributes-tag
  1566. self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
  1567. return TRUE;
  1568. }
  1569. // }}}
  1570. };
  1571. /*
  1572. * Local variables:
  1573. * mode: php
  1574. * tab-width: 4
  1575. * c-basic-offset: 4
  1576. * End:
  1577. */
  1578. ?>