PageRenderTime 52ms CodeModel.GetById 41ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 1ms

/plugin/box-api/class.curl.php

https://bitbucket.org/chamilo/chamilo-ext-repo-box-dev/
PHP | 361 lines | 128 code | 50 blank | 183 comment | 11 complexity | 46b4486d8c7d16fedfd68536df5f4e63 MD5 | raw file
  1<?php
  2/**
  3 * @author Dick Munroe (munroe@csworks.com)
  4 * @copyright copyright @ 2004, Dick Munroe, released under the GPL.
  5 *
  6 * The cURL class is a thin wrapper around the procedural interface
  7 * to cURL provided by PHP.  I use it mostly as a base class for
  8 * web services whose low level interface is, literally, web pages.
  9 *
 10 * There are a few differences (value added, I guess) between the interface
 11 * provided by this class and the procedural cURL interface.  Most
 12 * noticable are:
 13 *
 14 * 1. The curl::exec function (when returning data to the caller rather
 15 * than simply outputing it) always parses the HTTP header and returns
 16 * only the body portion of the reqeust.  The header is available via
 17 * the curl::getHeader method.
 18 * 2. The status of the last curl::exec is always maintained.  It is
 19 * available via the curl::getStatus method.  In addition to the information
 20 * returned by curl_getinfo, that of curl_error and curl_errno is folded
 21 * in as well.
 22 *
 23 * @example ./example.class.curl.php
 24 */
 25
 26//
 27// Edit History:
 28//
 29//  Dick Munroe munroe@csworks.com 30-Nov-2004
 30//	Initial Version Created.
 31//
 32//  Dick Munroe munroe@csworks.com 01-Dec-2004
 33//	Forgot to check for cURL actually being in this instance of PHP.
 34//
 35
 36
 37class curl
 38{
 39    /**
 40     * The mapping to caseless header names.
 41     *
 42     * @access private
 43     * @var array
 44     */
 45    
 46    var $m_caseless;
 47    
 48    /**
 49     * The handle for the current curl session.
 50     *
 51     * @access private
 52     * @var resource
 53     */
 54    
 55    var $m_handle;
 56    
 57    /**
 58     * The parsed contents of the HTTP header if one happened in the
 59     * message.  All repeated elements appear as arrays.
 60     *
 61     * The headers are stored as an associative array, the key of which
 62     * is the name of the header, e.g., Set-Cookie, and the values of which
 63     * are the bodies of the header in the order in which they occurred.
 64     * 
 65     * Some headers can be repeated in a single header, e.g., Set-Cookie and
 66     * pragma, so each type of header has an array containing one or more
 67     * headers of the same type.
 68     *
 69     * The names of the headers can, potentially, vary in spelling from
 70     * server to server and client to client.  No attempt to regulate this
 71     * is made, i.e., the curl class does not force all headers to lower
 72     * or upper class, but it DOES collect all headers of the same type
 73     * under the spelling of the type of header used by the FIRST header
 74     * of that type.
 75     *
 76     * For example, two headers:
 77     *
 78     * 1. Set-Cookie: ...
 79     * 2. set-cookie: ...
 80     *
 81     * Would appear as $this->m_header['Set-Cookie'][0] and ...[1]
 82     *
 83     * @access private
 84     * @var mixed
 85     */
 86    
 87    var $m_header;
 88    
 89    /**
 90     * Current setting of the curl options.
 91     *
 92     * @access private
 93     * @var mixed
 94     */
 95    
 96    var $m_options;
 97    
 98    /**
 99     * Status information for the last executed http request.  Includes the errno and error
100     * in addition to the information returned by curl_getinfo.
101     *
102     * The keys defined are those returned by curl_getinfo with two additional
103     * ones specified, 'error' which is the value of curl_error and 'errno' which
104     * is the value of curl_errno.
105     *
106     * @link http://www.php.net/curl_getinfo
107     * @link http://www.php.net/curl_errno
108     * @link http://www.php.net/curl_error
109     * @access private
110     * @var mixed
111     */
112    
113    var $m_status;
114
115    /**
116     * curl class constructor
117     *
118     * Initializes the curl class for it's default behavior:
119     * o no HTTP headers.
120     * o return the transfer as a string.
121     * o URL to access.
122     * By default, the curl class will simply read the URL provided
123     * in the constructor.
124     *
125     * @link http://www.php.net/curl_init
126     * @param string $theURL [optional] the URL to be accessed by this instance of the class.
127     */
128    
129    function curl($theURL = null)
130    {
131        if (! function_exists('curl_init'))
132        {
133            trigger_error('PHP was not built with --with-curl, rebuild PHP to use the curl class.', E_USER_ERROR);
134        }
135        
136        $this->m_handle = curl_init();
137        
138        $this->m_caseless = null;
139        $this->m_header = null;
140        $this->m_options = null;
141        $this->m_status = null;
142        
143        if (! empty($theURL))
144        {
145            $this->setopt(CURLOPT_URL, $theURL);
146        }
147        $this->setopt(CURLOPT_HEADER, false);
148        $this->setopt(CURLOPT_RETURNTRANSFER, true);
149    }
150
151    /**
152     * Free the resources associated with the curl session.
153     *
154     * @link http://www.php.net/curl_close
155     */
156    
157    function close()
158    {
159        curl_close($this->m_handle);
160        $this->m_handle = null;
161    }
162
163    /**
164     * Execute the curl request and return the result.
165     *
166     * @link http://www.php.net/curl_exec
167     * @link http://www.php.net/curl_getinfo
168     * @link http://www.php.net/curl_errno
169     * @link http://www.php.net/curl_error
170     * @return string The contents of the page (or other interaction as defined by the
171     * settings of the various curl options).
172     */
173    
174    function exec()
175    {
176        $theReturnValue = curl_exec($this->m_handle);
177        
178        $this->m_status = curl_getinfo($this->m_handle);
179        $this->m_status['errno'] = curl_errno($this->m_handle);
180        $this->m_status['error'] = curl_error($this->m_handle);
181        
182        //
183        // Parse out the http header (if any).
184        //
185        
186
187        $this->m_header = null;
188        
189        if ($this->getOption(CURLOPT_HEADER))
190        {
191            $theArray = preg_split("/(\r\n){2,2}/", $theReturnValue, 2);
192            
193            $this->parseHeader($theArray[0]);
194            
195            return $theArray[1];
196        }
197        
198        return $theReturnValue;
199    }
200
201    /**
202     * Returns the parsed http header.
203     *
204     * @param string $theHeader [optional] the name of the header to be returned.
205     * The name of the header is case insensitive.  If
206     * the header name is omitted the parsed header is
207     * returned.  If the requested header doesn't exist
208     * false is returned.
209     * @returns mixed
210     */
211    
212    function getHeader($theHeader = null)
213    {
214        if (empty($theHeader))
215        {
216            return $this->m_header;
217        }
218        else
219        {
220            $theHeader = strtoupper($theHeader);
221            if (isset($this->m_caseless[$theHeader]))
222            {
223                return $this->m_header[$this->m_caseless[$theHeader]];
224            }
225            else
226            {
227                return false;
228            }
229        }
230    }
231
232    /**
233     * Returns the current setting of the request option.  If no 
234     * option has been set, it return null.
235     *
236     * @param integer the requested CURLOPT.
237     * @returns mixed
238     */
239    
240    function getOption($theOption)
241    {
242        if (isset($this->m_options[$theOption]))
243        {
244            return $this->m_options[$theOption];
245        }
246        
247        return null;
248    }
249
250    /**
251     * Did the last curl exec operation have an error?
252     *
253     * @return mixed The error message associated with the error if an error 
254     * occurred, false otherwise.
255     */
256    
257    function hasError()
258    {
259        if (isset($this->m_status['error']))
260        {
261            return (empty($this->m_status['error']) ? false : $this->m_status['error']);
262        }
263        else
264        {
265            return false;
266        }
267    }
268
269    /**
270     * Parse an HTTP header.
271     *
272     * As a side effect it stores the parsed header in the
273     * m_header instance variable.  The header is stored as
274     * an associative array and the case of the headers 
275     * as provided by the server is preserved and all
276     * repeated headers (pragma, set-cookie, etc) are grouped
277     * with the first spelling for that header
278     * that is seen.
279     *
280     * All headers are stored as if they COULD be repeated, so
281     * the headers are really stored as an array of arrays.
282     *
283     * @param string $theHeader The HTTP data header.
284     */
285    
286    function parseHeader($theHeader)
287    {
288        $this->m_caseless = array();
289        
290        $theArray = preg_split("/(\r\n)+/", $theHeader);
291        
292        //
293        // Ditch the HTTP status line.
294        //
295        
296
297        if (preg_match('/^HTTP/', $theArray[0]))
298        {
299            $theArray = array_slice($theArray, 1);
300        }
301        
302        foreach ($theArray as $theHeaderString)
303        {
304            $theHeaderStringArray = preg_split("/\s*:\s*/", $theHeaderString, 2);
305            
306            $theCaselessTag = strtoupper($theHeaderStringArray[0]);
307            
308            if (! isset($this->m_caseless[$theCaselessTag]))
309            {
310                $this->m_caseless[$theCaselessTag] = $theHeaderStringArray[0];
311            }
312            
313            $this->m_header[$this->m_caseless[$theCaselessTag]][] = $theHeaderStringArray[1];
314        }
315    }
316
317    /**
318     * Return the status information of the last curl request.
319     *
320     * @param string $theField [optional] the particular portion
321     * of the status information desired.
322     * If omitted the array of status
323     * information is returned.  If a non-existant
324     * status field is requested, false is returned.
325     * @returns mixed
326     */
327    
328    function getStatus($theField = null)
329    {
330        if (empty($theField))
331        {
332            return $this->m_status;
333        }
334        else
335        {
336            if (isset($this->m_status[$theField]))
337            {
338                return $this->m_status[$theField];
339            }
340            else
341            {
342                return false;
343            }
344        }
345    }
346
347    /**
348     * Set a curl option.
349     *
350     * @link http://www.php.net/curl_setopt
351     * @param mixed $theOption One of the valid CURLOPT defines.
352     * @param mixed $theValue the value of the curl option.
353     */
354    
355    function setopt($theOption, $theValue)
356    {
357        curl_setopt($this->m_handle, $theOption, $theValue);
358        $this->m_options[$theOption] = $theValue;
359    }
360}
361?>