source: pmb4.2/trunk/fuentes/pmb/classes/nusoap/nusoapmime.php @ 815

Last change on this file since 815 was 815, checked in by jrpelegrina, 4 years ago

Initial release of pmb 4.2

  • Property svn:executable set to *
File size: 14.5 KB
Line 
1<?php
2/*
3$Id: nusoapmime.php,v 1.2 2013-04-11 08:14:12 mbertin Exp $
4
5NuSOAP - Web Services Toolkit for PHP
6
7Copyright (c) 2002 NuSphere Corporation
8
9This library is free software; you can redistribute it and/or
10modify it under the terms of the GNU Lesser General Public
11License as published by the Free Software Foundation; either
12version 2.1 of the License, or (at your option) any later version.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public
20License along with this library; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
23If you have any questions or comments, please email:
24
25Dietrich Ayala
26dietrich@ganx4.com
27http://dietrich.ganx4.com/nusoap
28
29NuSphere Corporation
30http://www.nusphere.com
31
32*/
33
34/*require_once('nusoap.php');*/
35/* PEAR Mail_MIME library */
36require_once('Mail/mimeDecode.php');
37require_once('Mail/mimePart.php');
38
39/**
40* soapclientmime client supporting MIME attachments defined at
41* http://www.w3.org/TR/SOAP-attachments.  It depends on the PEAR Mail_MIME library.
42*
43* @author   Scott Nichol <snichol@sourceforge.net>
44* @author       Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
45* @version  $Id: nusoapmime.php,v 1.2 2013-04-11 08:14:12 mbertin Exp $
46* @access   public
47*/
48class soapclientmime extends soapclient {
49        /**
50         * @var array Each array element in the return is an associative array with keys
51         * data, filename, contenttype, cid
52         * @access private
53         */
54        var $requestAttachments = array();
55        /**
56         * @var array Each array element in the return is an associative array with keys
57         * data, filename, contenttype, cid
58         * @access private
59         */
60        var $responseAttachments;
61        /**
62         * @var string
63         * @access private
64         */
65        var $mimeContentType;
66       
67        /**
68        * adds a MIME attachment to the current request.
69        *
70        * If the $data parameter contains an empty string, this method will read
71        * the contents of the file named by the $filename parameter.
72        *
73        * If the $cid parameter is false, this method will generate the cid.
74        *
75        * @param string $data The data of the attachment
76        * @param string $filename The filename of the attachment (default is empty string)
77        * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
78        * @param string $cid The content-id (cid) of the attachment (default is false)
79        * @return string The content-id (cid) of the attachment
80        * @access public
81        */
82        function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
83                if (! $cid) {
84                        $cid = md5(uniqid(time()));
85                }
86
87                $info['data'] = $data;
88                $info['filename'] = $filename;
89                $info['contenttype'] = $contenttype;
90                $info['cid'] = $cid;
91               
92                $this->requestAttachments[] = $info;
93
94                return $cid;
95        }
96
97        /**
98        * clears the MIME attachments for the current request.
99        *
100        * @access public
101        */
102        function clearAttachments() {
103                $this->requestAttachments = array();
104        }
105
106        /**
107        * gets the MIME attachments from the current response.
108        *
109        * Each array element in the return is an associative array with keys
110        * data, filename, contenttype, cid.  These keys correspond to the parameters
111        * for addAttachment.
112        *
113        * @return array The attachments.
114        * @access public
115        */
116        function getAttachments() {
117                return $this->responseAttachments;
118        }
119
120        /**
121        * gets the HTTP body for the current request.
122        *
123        * @param string $soapmsg The SOAP payload
124        * @return string The HTTP body, which includes the SOAP payload
125        * @access private
126        */
127        function getHTTPBody($soapmsg) {
128                if (count($this->requestAttachments) > 0) {
129                        $params['content_type'] = 'multipart/related; type=text/xml';
130                        $mimeMessage = new Mail_mimePart('', $params);
131                        unset($params);
132
133                        $params['content_type'] = 'text/xml';
134                        $params['encoding']     = '8bit';
135                        $params['charset']      = $this->soap_defencoding;
136                        $mimeMessage->addSubpart($soapmsg, $params);
137                       
138                        foreach ($this->requestAttachments as $att) {
139                                unset($params);
140
141                                $params['content_type'] = $att['contenttype'];
142                                $params['encoding']     = 'base64';
143                                $params['disposition']  = 'attachment';
144                                $params['dfilename']    = $att['filename'];
145                                $params['cid']          = $att['cid'];
146
147                                if ($att['data'] == '' && $att['filename'] <> '') {
148                                        if ($fd = fopen($att['filename'], 'rb')) {
149                                                $data = fread($fd, filesize($att['filename']));
150                                                fclose($fd);
151                                        } else {
152                                                $data = '';
153                                        }
154                                        $mimeMessage->addSubpart($data, $params);
155                                } else {
156                                        $mimeMessage->addSubpart($att['data'], $params);
157                                }
158                        }
159
160                        $output = $mimeMessage->encode();
161                        $mimeHeaders = $output['headers'];
162       
163                        foreach ($mimeHeaders as $k => $v) {
164                                $this->debug("MIME header $k: $v");
165                                if (strtolower($k) == 'content-type') {
166                                        // PHP header() seems to strip leading whitespace starting
167                                        // the second line, so force everything to one line
168                                        $this->mimeContentType = str_replace("\r\n", " ", $v);
169                                }
170                        }
171       
172                        return $output['body'];
173                }
174
175                return parent::getHTTPBody($soapmsg);
176        }
177       
178        /**
179        * gets the HTTP content type for the current request.
180        *
181        * Note: getHTTPBody must be called before this.
182        *
183        * @return string the HTTP content type for the current request.
184        * @access private
185        */
186        function getHTTPContentType() {
187                if (count($this->requestAttachments) > 0) {
188                        return $this->mimeContentType;
189                }
190                return parent::getHTTPContentType();
191        }
192       
193        /**
194        * gets the HTTP content type charset for the current request.
195        * returns false for non-text content types.
196        *
197        * Note: getHTTPBody must be called before this.
198        *
199        * @return string the HTTP content type charset for the current request.
200        * @access private
201        */
202        function getHTTPContentTypeCharset() {
203                if (count($this->requestAttachments) > 0) {
204                        return false;
205                }
206                return parent::getHTTPContentTypeCharset();
207        }
208
209        /**
210        * processes SOAP message returned from server
211        *
212        * @param        array   $headers        The HTTP headers
213        * @param        string  $data           unprocessed response data from server
214        * @return       mixed   value of the message, decoded into a PHP type
215        * @access   private
216        */
217    function parseResponse($headers, $data) {
218                $this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
219                $this->responseAttachments = array();
220                if (strstr($headers['content-type'], 'multipart/related')) {
221                        $this->debug('Decode multipart/related');
222                        $input = '';
223                        foreach ($headers as $k => $v) {
224                                $input .= "$k: $v\r\n";
225                        }
226                        $params['input'] = $input . "\r\n" . $data;
227                        $params['include_bodies'] = true;
228                        $params['decode_bodies'] = true;
229                        $params['decode_headers'] = true;
230                       
231                        $structure = Mail_mimeDecode::decode($params);
232
233                        foreach ($structure->parts as $part) {
234                                if (!isset($part->disposition)) {
235                                        $this->debug('Have root part of type ' . $part->headers['content-type']);
236                                        $return = parent::parseResponse($part->headers, $part->body);
237                                } else {
238                                        $this->debug('Have an attachment of type ' . $part->headers['content-type']);
239                                        $info['data'] = $part->body;
240                                        $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
241                                        $info['contenttype'] = $part->headers['content-type'];
242                                        $info['cid'] = $part->headers['content-id'];
243                                        $this->responseAttachments[] = $info;
244                                }
245                        }
246               
247                        if (isset($return)) {
248                                return $return;
249                        }
250                       
251                        $this->setError('No root part found in multipart/related content');
252                        return;
253                }
254                $this->debug('Not multipart/related');
255                return parent::parseResponse($headers, $data);
256        }
257}
258
259/**
260* nusoapservermime server supporting MIME attachments defined at
261* http://www.w3.org/TR/SOAP-attachments.  It depends on the PEAR Mail_MIME library.
262*
263* @author   Scott Nichol <snichol@sourceforge.net>
264* @author       Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
265* @version  $Id: nusoapmime.php,v 1.2 2013-04-11 08:14:12 mbertin Exp $
266* @access   public
267*/
268class nusoapservermime extends soap_server {
269        /**
270         * @var array Each array element in the return is an associative array with keys
271         * data, filename, contenttype, cid
272         * @access private
273         */
274        var $requestAttachments = array();
275        /**
276         * @var array Each array element in the return is an associative array with keys
277         * data, filename, contenttype, cid
278         * @access private
279         */
280        var $responseAttachments;
281        /**
282         * @var string
283         * @access private
284         */
285        var $mimeContentType;
286       
287        /**
288        * adds a MIME attachment to the current response.
289        *
290        * If the $data parameter contains an empty string, this method will read
291        * the contents of the file named by the $filename parameter.
292        *
293        * If the $cid parameter is false, this method will generate the cid.
294        *
295        * @param string $data The data of the attachment
296        * @param string $filename The filename of the attachment (default is empty string)
297        * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
298        * @param string $cid The content-id (cid) of the attachment (default is false)
299        * @return string The content-id (cid) of the attachment
300        * @access public
301        */
302        function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
303                if (! $cid) {
304                        $cid = md5(uniqid(time()));
305                }
306
307                $info['data'] = $data;
308                $info['filename'] = $filename;
309                $info['contenttype'] = $contenttype;
310                $info['cid'] = $cid;
311               
312                $this->responseAttachments[] = $info;
313
314                return $cid;
315        }
316
317        /**
318        * clears the MIME attachments for the current response.
319        *
320        * @access public
321        */
322        function clearAttachments() {
323                $this->responseAttachments = array();
324        }
325
326        /**
327        * gets the MIME attachments from the current request.
328        *
329        * Each array element in the return is an associative array with keys
330        * data, filename, contenttype, cid.  These keys correspond to the parameters
331        * for addAttachment.
332        *
333        * @return array The attachments.
334        * @access public
335        */
336        function getAttachments() {
337                return $this->requestAttachments;
338        }
339
340        /**
341        * gets the HTTP body for the current response.
342        *
343        * @param string $soapmsg The SOAP payload
344        * @return string The HTTP body, which includes the SOAP payload
345        * @access private
346        */
347        function getHTTPBody($soapmsg) {
348                if (count($this->responseAttachments) > 0) {
349                        $params['content_type'] = 'multipart/related; type=text/xml';
350                        $mimeMessage = new Mail_mimePart('', $params);
351                        unset($params);
352
353                        $params['content_type'] = 'text/xml';
354                        $params['encoding']     = '8bit';
355                        $params['charset']      = $this->soap_defencoding;
356                        $mimeMessage->addSubpart($soapmsg, $params);
357                       
358                        foreach ($this->responseAttachments as $att) {
359                                unset($params);
360
361                                $params['content_type'] = $att['contenttype'];
362                                $params['encoding']     = 'base64';
363                                $params['disposition']  = 'attachment';
364                                $params['dfilename']    = $att['filename'];
365                                $params['cid']          = $att['cid'];
366
367                                if ($att['data'] == '' && $att['filename'] <> '') {
368                                        if ($fd = fopen($att['filename'], 'rb')) {
369                                                $data = fread($fd, filesize($att['filename']));
370                                                fclose($fd);
371                                        } else {
372                                                $data = '';
373                                        }
374                                        $mimeMessage->addSubpart($data, $params);
375                                } else {
376                                        $mimeMessage->addSubpart($att['data'], $params);
377                                }
378                        }
379
380                        $output = $mimeMessage->encode();
381                        $mimeHeaders = $output['headers'];
382       
383                        foreach ($mimeHeaders as $k => $v) {
384                                $this->debug("MIME header $k: $v");
385                                if (strtolower($k) == 'content-type') {
386                                        // PHP header() seems to strip leading whitespace starting
387                                        // the second line, so force everything to one line
388                                        $this->mimeContentType = str_replace("\r\n", " ", $v);
389                                }
390                        }
391       
392                        return $output['body'];
393                }
394
395                return parent::getHTTPBody($soapmsg);
396        }
397       
398        /**
399        * gets the HTTP content type for the current response.
400        *
401        * Note: getHTTPBody must be called before this.
402        *
403        * @return string the HTTP content type for the current response.
404        * @access private
405        */
406        function getHTTPContentType() {
407                if (count($this->responseAttachments) > 0) {
408                        return $this->mimeContentType;
409                }
410                return parent::getHTTPContentType();
411        }
412       
413        /**
414        * gets the HTTP content type charset for the current response.
415        * returns false for non-text content types.
416        *
417        * Note: getHTTPBody must be called before this.
418        *
419        * @return string the HTTP content type charset for the current response.
420        * @access private
421        */
422        function getHTTPContentTypeCharset() {
423                if (count($this->responseAttachments) > 0) {
424                        return false;
425                }
426                return parent::getHTTPContentTypeCharset();
427        }
428
429        /**
430        * processes SOAP message received from client
431        *
432        * @param        array   $headers        The HTTP headers
433        * @param        string  $data           unprocessed request data from client
434        * @return       mixed   value of the message, decoded into a PHP type
435        * @access   private
436        */
437    function parseRequest($headers, $data) {
438                $this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
439                $this->requestAttachments = array();
440                if (strstr($headers['content-type'], 'multipart/related')) {
441                        $this->debug('Decode multipart/related');
442                        $input = '';
443                        foreach ($headers as $k => $v) {
444                                $input .= "$k: $v\r\n";
445                        }
446                        $params['input'] = $input . "\r\n" . $data;
447                        $params['include_bodies'] = true;
448                        $params['decode_bodies'] = true;
449                        $params['decode_headers'] = true;
450                       
451                        $structure = Mail_mimeDecode::decode($params);
452
453                        foreach ($structure->parts as $part) {
454                                if (!isset($part->disposition)) {
455                                        $this->debug('Have root part of type ' . $part->headers['content-type']);
456                                        $return = parent::parseRequest($part->headers, $part->body);
457                                } else {
458                                        $this->debug('Have an attachment of type ' . $part->headers['content-type']);
459                                        $info['data'] = $part->body;
460                                        $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
461                                        $info['contenttype'] = $part->headers['content-type'];
462                                        $info['cid'] = $part->headers['content-id'];
463                                        $this->requestAttachments[] = $info;
464                                }
465                        }
466               
467                        if (isset($return)) {
468                                return $return;
469                        }
470                       
471                        $this->setError('No root part found in multipart/related content');
472                        return;
473                }
474                $this->debug('Not multipart/related');
475                return parent::parseRequest($headers, $data);
476        }
477}
478?>
Note: See TracBrowser for help on using the repository browser.