root/trunk/lib/nusoapmime.php

Revision 61, 14.5 kB (checked in by yann, 5 years ago)

use nusoap library for SOAP access (can be included in plugin package)

Line 
1 <?php
2 /*
3 $Id: nusoapmime.php,v 1.7 2005/07/27 19:24:42 snichol Exp $
4
5 NuSOAP - Web Services Toolkit for PHP
6
7 Copyright (c) 2002 NuSphere Corporation
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 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 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser 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 If you have any questions or comments, please email:
24
25 Dietrich Ayala
26 dietrich@ganx4.com
27 http://dietrich.ganx4.com/nusoap
28
29 NuSphere Corporation
30 http://www.nusphere.com
31
32 */
33
34 /*require_once('nusoap.php');*/
35 /* PEAR Mail_MIME library */
36 require_once('Mail/mimeDecode.php');
37 require_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.7 2005/07/27 19:24:42 snichol Exp $
46 * @access   public
47 */
48 class 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.7 2005/07/27 19:24:42 snichol Exp $
266 * @access   public
267 */
268 class 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 ?>
479
Note: See TracBrowser for help on using the browser.