PrintIPP.php 73 KB

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