PageRenderTime 43ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/include/nusoap/nusoapmime.php

https://bitbucket.org/cviolette/sugarcrm
PHP | 611 lines | 215 code | 50 blank | 346 comment | 30 complexity | 03ad5f19e5f8ca40b6ecc8bb5ff7d06d MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. <?php
  2. /*
  3. Modification information for LGPL compliance
  4. r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
  5. r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
  6. r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
  7. r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3 tags and updated the build system
  8. r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
  9. r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
  10. r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
  11. r39619 - 2008-09-09 13:41:34 -0700 (Tue, 09 Sep 2008) - jmertic - Bug 24827 - Remove all instances where we return a new object and assign it by reference, since this is deprecated in PHP 5 and emits E_DEPRECATED errors in PHP 5.3.
  12. Touched:
  13. - data/SugarBean.php
  14. - include/domit/php_http_client_generic.php
  15. - include/domit/php_http_connector.php
  16. - include/domit/testing_domit.php
  17. - include/domit/xml_domit_getelementsbypath.php
  18. - include/domit/xml_domit_lite_parser.php
  19. - include/domit/xml_domit_nodemaps.php
  20. - include/domit/xml_domit_parser.php
  21. - include/domit/xml_domit_shared.php
  22. - include/generic/SugarWidgets/SugarWidgetField.php
  23. - include/generic/SugarWidgets/SugarWidgetReportField.php
  24. - include/ListView/ProcessView.php
  25. - include/nusoap/class.soapclient.php
  26. - include/nusoap/nusoap.php
  27. - include/nusoap/nusoapmime.php
  28. - include/Pear/HTML_Safe/Safe.php
  29. - include/Pear/XML_HTMLSax3/HTMLSax3.php
  30. - modules/Administration/RebuildWorkFlow.php
  31. - modules/Expressions/RelateSelector.php
  32. - modules/Reports/templates/templates_reports.php
  33. - modules/WorkFlow/Delete.php
  34. - modules/WorkFlow/Save.php
  35. - modules/WorkFlow/SaveSequence.php
  36. - modules/WorkFlow/WorkFlow.php
  37. - modules/WorkFlowActionShells/CreateStep1.php
  38. - modules/WorkFlowActionShells/CreateStep2.php
  39. - modules/WorkFlowActionShells/Save.php
  40. - modules/WorkFlowActionShells/WorkFlowActionShell.php
  41. - modules/WorkFlowAlerts/Save.php
  42. - modules/WorkFlowAlerts/WorkFlowAlert.php
  43. - modules/WorkFlowAlertShells/DetailView.php
  44. - modules/WorkFlowAlertShells/WorkFlowAlertShell.php
  45. - modules/WorkFlowTriggerShells/CreateStep1.php
  46. - modules/WorkFlowTriggerShells/CreateStepFilter.php
  47. - modules/WorkFlowTriggerShells/SaveFilter.php
  48. - modules/WorkFlowTriggerShells/WorkFlowTriggerShell.php
  49. - soap/SoapHelperFunctions.php
  50. - test/modules/DynamicFields/DynamicFields_Bug24095_test.php
  51. - test/simpletest/browser.php
  52. - test/simpletest/default_reporter.php
  53. - test/simpletest/detached.php
  54. - test/simpletest/eclipse.php
  55. - test/simpletest/expectation.php
  56. - test/simpletest/extensions/pear_test_case.php
  57. - test/simpletest/form.php
  58. - test/simpletest/http.php
  59. - test/simpletest/mock_objects.php
  60. - test/simpletest/page.php
  61. - test/simpletest/parser.php
  62. - test/simpletest/remote.php
  63. - test/simpletest/shell_tester.php
  64. - test/simpletest/simple_test.php
  65. - test/simpletest/simpletest.php
  66. - test/simpletest/test/acceptance_test.php
  67. - test/simpletest/test/adapter_test.php
  68. - test/simpletest/test/authentication_test.php
  69. - test/simpletest/test/browser_test.php
  70. - test/simpletest/test/collector_test.php
  71. - test/simpletest/test/compatibility_test.php
  72. - test/simpletest/test/detached_test.php
  73. - test/simpletest/test/eclipse_test.php
  74. - test/simpletest/test/encoding_test.php
  75. - test/simpletest/test/errors_test.php
  76. - test/simpletest/test/expectation_test.php
  77. - test/simpletest/test/form_test.php
  78. - test/simpletest/test/frames_test.php
  79. - test/simpletest/test/http_test.php
  80. - test/simpletest/test/live_test.php
  81. - test/simpletest/test/mock_objects_test.php
  82. - test/simpletest/test/page_test.php
  83. - test/simpletest/test/parse_error_test.php
  84. - test/simpletest/test/parser_test.php
  85. - test/simpletest/test/remote_test.php
  86. - test/simpletest/test/shell_test.php
  87. - test/simpletest/test/shell_tester_test.php
  88. - test/simpletest/test/simpletest_test.php
  89. - test/simpletest/test/site/page_request.php
  90. - test/simpletest/test/tag_test.php
  91. - test/simpletest/test/unit_tester_test.php
  92. - test/simpletest/test/user_agent_test.php
  93. - test/simpletest/test/visual_test.php
  94. - test/simpletest/test/xml_test.php
  95. - test/simpletest/test_case.php
  96. - test/simpletest/ui/array_reporter/test.php
  97. - test/simpletest/ui/recorder/test.php
  98. - test/simpletest/unit_tester.php
  99. - test/simpletest/url.php
  100. - test/simpletest/user_agent.php
  101. - test/simpletest/web_tester.php
  102. - test/spikephpcoverage/src/PEAR.php
  103. - test/spikephpcoverage/src/util/Utility.php
  104. - test/spikephpcoverage/src/XML/Parser.php
  105. - test/spikephpcoverage/src/XML/Parser/Simple.php
  106. - test/test_utilities/SugarTest_SimpleBrowser.php
  107. r13782 - 2006-06-06 10:58:55 -0700 (Tue, 06 Jun 2006) - majed - changes entry point code
  108. r11115 - 2006-01-17 14:54:45 -0800 (Tue, 17 Jan 2006) - majed - add entry point validation
  109. r8991 - 2005-11-03 19:07:25 -0800 (Thu, 03 Nov 2005) - majed - fixes nusoap issue
  110. r8846 - 2005-10-31 11:01:12 -0800 (Mon, 31 Oct 2005) - majed - new version of nusoap
  111. r7905 - 2005-09-21 19:12:57 -0700 (Wed, 21 Sep 2005) - majed - restores old nusoap pre & with a few fixes
  112. r7861 - 2005-09-20 15:40:25 -0700 (Tue, 20 Sep 2005) - majed - & fix for 3.5.1
  113. r7452 - 2005-08-17 11:32:34 -0700 (Wed, 17 Aug 2005) - majed - changes soap to nusoap
  114. r5462 - 2005-05-25 13:50:11 -0700 (Wed, 25 May 2005) - majed - upgraded nusoap to .6.9
  115. r573 - 2004-09-04 13:03:32 -0700 (Sat, 04 Sep 2004) - sugarclint - undoing copyrights added in inadvertantly. --clint
  116. r546 - 2004-09-03 11:49:38 -0700 (Fri, 03 Sep 2004) - sugarmsi - removed echo count
  117. r354 - 2004-08-02 23:00:37 -0700 (Mon, 02 Aug 2004) - sugarjacob - Adding Soap
  118. */
  119. if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
  120. /*
  121. $Id: nusoapmime.php 39619 2008-09-09 20:41:34Z jmertic $
  122. NuSOAP - Web Services Toolkit for PHP
  123. Copyright (c) 2002 NuSphere Corporation
  124. This library is free software; you can redistribute it and/or
  125. modify it under the terms of the GNU Lesser General Public
  126. License as published by the Free Software Foundation; either
  127. version 2.1 of the License, or (at your option) any later version.
  128. This library is distributed in the hope that it will be useful,
  129. but WITHOUT ANY WARRANTY; without even the implied warranty of
  130. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  131. Lesser General Public License for more details.
  132. You should have received a copy of the GNU Lesser General Public
  133. License along with this library; if not, write to the Free Software
  134. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  135. If you have any questions or comments, please email:
  136. Dietrich Ayala
  137. dietrich@ganx4.com
  138. http://dietrich.ganx4.com/nusoap
  139. NuSphere Corporation
  140. http://www.nusphere.com
  141. */
  142. /*require_once('nusoap.php');*/
  143. /* PEAR Mail_MIME library */
  144. require_once('Mail/mimeDecode.php');
  145. require_once('Mail/mimePart.php');
  146. /**
  147. * nusoapclientmime client supporting MIME attachments defined at
  148. * http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
  149. *
  150. * @author Scott Nichol <snichol@sourceforge.net>
  151. * @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
  152. * @access public
  153. */
  154. class nusoapclientmime extends nusoapclient {
  155. /**
  156. * @var array Each array element in the return is an associative array with keys
  157. * data, filename, contenttype, cid
  158. * @access private
  159. */
  160. var $requestAttachments = array();
  161. /**
  162. * @var array Each array element in the return is an associative array with keys
  163. * data, filename, contenttype, cid
  164. * @access private
  165. */
  166. var $responseAttachments;
  167. /**
  168. * @var string
  169. * @access private
  170. */
  171. var $mimeContentType;
  172. /**
  173. * adds a MIME attachment to the current request.
  174. *
  175. * If the $data parameter contains an empty string, this method will read
  176. * the contents of the file named by the $filename parameter.
  177. *
  178. * If the $cid parameter is false, this method will generate the cid.
  179. *
  180. * @param string $data The data of the attachment
  181. * @param string $filename The filename of the attachment (default is empty string)
  182. * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
  183. * @param string $cid The content-id (cid) of the attachment (default is false)
  184. * @return string The content-id (cid) of the attachment
  185. * @access public
  186. */
  187. function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
  188. if (! $cid) {
  189. $cid = md5(uniqid(time()));
  190. }
  191. $info['data'] = $data;
  192. $info['filename'] = $filename;
  193. $info['contenttype'] = $contenttype;
  194. $info['cid'] = $cid;
  195. $this->requestAttachments[] = $info;
  196. return $cid;
  197. }
  198. /**
  199. * clears the MIME attachments for the current request.
  200. *
  201. * @access public
  202. */
  203. function clearAttachments() {
  204. $this->requestAttachments = array();
  205. }
  206. /**
  207. * gets the MIME attachments from the current response.
  208. *
  209. * Each array element in the return is an associative array with keys
  210. * data, filename, contenttype, cid. These keys correspond to the parameters
  211. * for addAttachment.
  212. *
  213. * @return array The attachments.
  214. * @access public
  215. */
  216. function getAttachments() {
  217. return $this->responseAttachments;
  218. }
  219. /**
  220. * gets the HTTP body for the current request.
  221. *
  222. * @param string $soapmsg The SOAP payload
  223. * @return string The HTTP body, which includes the SOAP payload
  224. * @access private
  225. */
  226. function getHTTPBody($soapmsg) {
  227. if (count($this->requestAttachments) > 0) {
  228. $params['content_type'] = 'multipart/related; type=text/xml';
  229. $mimeMessage = new Mail_mimePart('', $params);
  230. unset($params);
  231. $params['content_type'] = 'text/xml';
  232. $params['encoding'] = '8bit';
  233. $params['charset'] = $this->soap_defencoding;
  234. $mimeMessage->addSubpart($soapmsg, $params);
  235. foreach ($this->requestAttachments as $att) {
  236. unset($params);
  237. $params['content_type'] = $att['contenttype'];
  238. $params['encoding'] = 'base64';
  239. $params['disposition'] = 'attachment';
  240. $params['dfilename'] = $att['filename'];
  241. $params['cid'] = $att['cid'];
  242. if ($att['data'] == '' && $att['filename'] <> '') {
  243. $data = file_get_contents($att['filename']);
  244. $mimeMessage->addSubpart($data, $params);
  245. } else {
  246. $mimeMessage->addSubpart($att['data'], $params);
  247. }
  248. }
  249. $output = $mimeMessage->encode();
  250. $mimeHeaders = $output['headers'];
  251. foreach ($mimeHeaders as $k => $v) {
  252. $this->debug("MIME header $k: $v");
  253. if (strtolower($k) == 'content-type') {
  254. // PHP header() seems to strip leading whitespace starting
  255. // the second line, so force everything to one line
  256. $this->mimeContentType = str_replace("\r\n", " ", $v);
  257. }
  258. }
  259. return $output['body'];
  260. }
  261. return parent::getHTTPBody($soapmsg);
  262. }
  263. /**
  264. * gets the HTTP content type for the current request.
  265. *
  266. * Note: getHTTPBody must be called before this.
  267. *
  268. * @return string the HTTP content type for the current request.
  269. * @access private
  270. */
  271. function getHTTPContentType() {
  272. if (count($this->requestAttachments) > 0) {
  273. return $this->mimeContentType;
  274. }
  275. return parent::getHTTPContentType();
  276. }
  277. /**
  278. * gets the HTTP content type charset for the current request.
  279. * returns false for non-text content types.
  280. *
  281. * Note: getHTTPBody must be called before this.
  282. *
  283. * @return string the HTTP content type charset for the current request.
  284. * @access private
  285. */
  286. function getHTTPContentTypeCharset() {
  287. if (count($this->requestAttachments) > 0) {
  288. return false;
  289. }
  290. return parent::getHTTPContentTypeCharset();
  291. }
  292. /**
  293. * processes SOAP message returned from server
  294. *
  295. * @param array $headers The HTTP headers
  296. * @param string $data unprocessed response data from server
  297. * @return mixed value of the message, decoded into a PHP type
  298. * @access private
  299. */
  300. function parseResponse($headers, $data) {
  301. $this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
  302. $this->responseAttachments = array();
  303. if (strstr($headers['content-type'], 'multipart/related')) {
  304. $this->debug('Decode multipart/related');
  305. $input = '';
  306. foreach ($headers as $k => $v) {
  307. $input .= "$k: $v\r\n";
  308. }
  309. $params['input'] = $input . "\r\n" . $data;
  310. $params['include_bodies'] = true;
  311. $params['decode_bodies'] = true;
  312. $params['decode_headers'] = true;
  313. $structure = Mail_mimeDecode::decode($params);
  314. foreach ($structure->parts as $part) {
  315. if (!isset($part->disposition)) {
  316. $this->debug('Have root part of type ' . $part->headers['content-type']);
  317. $return = parent::parseResponse($part->headers, $part->body);
  318. } else {
  319. $this->debug('Have an attachment of type ' . $part->headers['content-type']);
  320. $info['data'] = $part->body;
  321. $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
  322. $info['contenttype'] = $part->headers['content-type'];
  323. $info['cid'] = $part->headers['content-id'];
  324. $this->responseAttachments[] = $info;
  325. }
  326. }
  327. if (isset($return)) {
  328. return $return;
  329. }
  330. $this->setError('No root part found in multipart/related content');
  331. return;
  332. }
  333. $this->debug('Not multipart/related');
  334. return parent::parseResponse($headers, $data);
  335. }
  336. }
  337. /**
  338. * nusoapservermime server supporting MIME attachments defined at
  339. * http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
  340. *
  341. * @author Scott Nichol <snichol@sourceforge.net>
  342. * @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
  343. * @access public
  344. */
  345. class nusoapservermime extends soap_server {
  346. /**
  347. * @var array Each array element in the return is an associative array with keys
  348. * data, filename, contenttype, cid
  349. * @access private
  350. */
  351. var $requestAttachments = array();
  352. /**
  353. * @var array Each array element in the return is an associative array with keys
  354. * data, filename, contenttype, cid
  355. * @access private
  356. */
  357. var $responseAttachments;
  358. /**
  359. * @var string
  360. * @access private
  361. */
  362. var $mimeContentType;
  363. /**
  364. * adds a MIME attachment to the current response.
  365. *
  366. * If the $data parameter contains an empty string, this method will read
  367. * the contents of the file named by the $filename parameter.
  368. *
  369. * If the $cid parameter is false, this method will generate the cid.
  370. *
  371. * @param string $data The data of the attachment
  372. * @param string $filename The filename of the attachment (default is empty string)
  373. * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
  374. * @param string $cid The content-id (cid) of the attachment (default is false)
  375. * @return string The content-id (cid) of the attachment
  376. * @access public
  377. */
  378. function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
  379. if (! $cid) {
  380. $cid = md5(uniqid(time()));
  381. }
  382. $info['data'] = $data;
  383. $info['filename'] = $filename;
  384. $info['contenttype'] = $contenttype;
  385. $info['cid'] = $cid;
  386. $this->responseAttachments[] = $info;
  387. return $cid;
  388. }
  389. /**
  390. * clears the MIME attachments for the current response.
  391. *
  392. * @access public
  393. */
  394. function clearAttachments() {
  395. $this->responseAttachments = array();
  396. }
  397. /**
  398. * gets the MIME attachments from the current request.
  399. *
  400. * Each array element in the return is an associative array with keys
  401. * data, filename, contenttype, cid. These keys correspond to the parameters
  402. * for addAttachment.
  403. *
  404. * @return array The attachments.
  405. * @access public
  406. */
  407. function getAttachments() {
  408. return $this->requestAttachments;
  409. }
  410. /**
  411. * gets the HTTP body for the current response.
  412. *
  413. * @param string $soapmsg The SOAP payload
  414. * @return string The HTTP body, which includes the SOAP payload
  415. * @access private
  416. */
  417. function getHTTPBody($soapmsg) {
  418. if (count($this->responseAttachments) > 0) {
  419. $params['content_type'] = 'multipart/related; type=text/xml';
  420. $mimeMessage = new Mail_mimePart('', $params);
  421. unset($params);
  422. $params['content_type'] = 'text/xml';
  423. $params['encoding'] = '8bit';
  424. $params['charset'] = $this->soap_defencoding;
  425. $mimeMessage->addSubpart($soapmsg, $params);
  426. foreach ($this->responseAttachments as $att) {
  427. unset($params);
  428. $params['content_type'] = $att['contenttype'];
  429. $params['encoding'] = 'base64';
  430. $params['disposition'] = 'attachment';
  431. $params['dfilename'] = $att['filename'];
  432. $params['cid'] = $att['cid'];
  433. if ($att['data'] == '' && $att['filename'] <> '') {
  434. $data = file_get_contents($att['filename']);
  435. $mimeMessage->addSubpart($data, $params);
  436. } else {
  437. $mimeMessage->addSubpart($att['data'], $params);
  438. }
  439. }
  440. $output = $mimeMessage->encode();
  441. $mimeHeaders = $output['headers'];
  442. foreach ($mimeHeaders as $k => $v) {
  443. $this->debug("MIME header $k: $v");
  444. if (strtolower($k) == 'content-type') {
  445. // PHP header() seems to strip leading whitespace starting
  446. // the second line, so force everything to one line
  447. $this->mimeContentType = str_replace("\r\n", " ", $v);
  448. }
  449. }
  450. return $output['body'];
  451. }
  452. return parent::getHTTPBody($soapmsg);
  453. }
  454. /**
  455. * gets the HTTP content type for the current response.
  456. *
  457. * Note: getHTTPBody must be called before this.
  458. *
  459. * @return string the HTTP content type for the current response.
  460. * @access private
  461. */
  462. function getHTTPContentType() {
  463. if (count($this->responseAttachments) > 0) {
  464. return $this->mimeContentType;
  465. }
  466. return parent::getHTTPContentType();
  467. }
  468. /**
  469. * gets the HTTP content type charset for the current response.
  470. * returns false for non-text content types.
  471. *
  472. * Note: getHTTPBody must be called before this.
  473. *
  474. * @return string the HTTP content type charset for the current response.
  475. * @access private
  476. */
  477. function getHTTPContentTypeCharset() {
  478. if (count($this->responseAttachments) > 0) {
  479. return false;
  480. }
  481. return parent::getHTTPContentTypeCharset();
  482. }
  483. /**
  484. * processes SOAP message received from client
  485. *
  486. * @param array $headers The HTTP headers
  487. * @param string $data unprocessed request data from client
  488. * @return mixed value of the message, decoded into a PHP type
  489. * @access private
  490. */
  491. function parseRequest($headers, $data) {
  492. $this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
  493. $this->requestAttachments = array();
  494. if (strstr($headers['content-type'], 'multipart/related')) {
  495. $this->debug('Decode multipart/related');
  496. $input = '';
  497. foreach ($headers as $k => $v) {
  498. $input .= "$k: $v\r\n";
  499. }
  500. $params['input'] = $input . "\r\n" . $data;
  501. $params['include_bodies'] = true;
  502. $params['decode_bodies'] = true;
  503. $params['decode_headers'] = true;
  504. $structure = Mail_mimeDecode::decode($params);
  505. foreach ($structure->parts as $part) {
  506. if (!isset($part->disposition)) {
  507. $this->debug('Have root part of type ' . $part->headers['content-type']);
  508. $return = parent::parseRequest($part->headers, $part->body);
  509. } else {
  510. $this->debug('Have an attachment of type ' . $part->headers['content-type']);
  511. $info['data'] = $part->body;
  512. $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
  513. $info['contenttype'] = $part->headers['content-type'];
  514. $info['cid'] = $part->headers['content-id'];
  515. $this->requestAttachments[] = $info;
  516. }
  517. }
  518. if (isset($return)) {
  519. return $return;
  520. }
  521. $this->setError('No root part found in multipart/related content');
  522. return;
  523. }
  524. $this->debug('Not multipart/related');
  525. return parent::parseRequest($headers, $data);
  526. }
  527. }
  528. ?>