PageRenderTime 50ms CodeModel.GetById 17ms 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

Large files files are truncated, but you can click here to view the full file

  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;

Large files files are truncated, but you can click here to view the full file