Development

/branches/1.0/lib/request/sfWebRequest.class.php

You must first sign up to be able to contribute.

root/branches/1.0/lib/request/sfWebRequest.class.php

Revision 16347, 23.9 kB (checked in by fabien, 5 years ago)

[1.0, 1.1] fixed sfWebRequest->getUriPrefix() should use getHost() inststead of HOST? (closes #6093)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  * (c) 2004-2006 Sean Kerr <sean@code-box.org>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 /**
13  * sfWebRequest class.
14  *
15  * This class manages web requests. It parses input from the request and store them as parameters.
16  * sfWebRequest is able to parse request with routing support enabled.
17  *
18  * @package    symfony
19  * @subpackage request
20  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
21  * @author     Sean Kerr <sean@code-box.org>
22  * @version    SVN: $Id$
23  */
24 class sfWebRequest extends sfRequest
25 {
26   /**
27    * A list of languages accepted by the browser.
28    * @var array
29    */
30   protected $languages = null;
31
32   /**
33    * A list of charsets accepted by the browser
34    * @var array
35    */
36   protected $charsets = null;
37
38   /**
39    * @var array  List of content types accepted by the client.
40    */
41   protected $acceptableContentTypes = null;
42
43   protected $pathInfoArray = null;
44
45   protected $relativeUrlRoot = null;
46
47   protected $filesInfos;
48
49   /**
50    * Retrieves an array of file information.
51    *
52    * @param string A file name
53    *
54    * @return array An associative array of file information, if the file exists, otherwise null
55    */
56   public function getFile($name)
57   {
58     return ($this->hasFile($name) ? $this->getFileValues($name) : null);
59   }
60
61   /**
62    * Retrieves a file error.
63    *
64    * @param string A file name
65    *
66    * @return int One of the following error codes:
67    *
68    *             - <b>UPLOAD_ERR_OK</b>        (no error)
69    *             - <b>UPLOAD_ERR_INI_SIZE</b>  (the uploaded file exceeds the
70    *                                           upload_max_filesize directive
71    *                                           in php.ini)
72    *             - <b>UPLOAD_ERR_FORM_SIZE</b> (the uploaded file exceeds the
73    *                                           MAX_FILE_SIZE directive that
74    *                                           was specified in the HTML form)
75    *             - <b>UPLOAD_ERR_PARTIAL</b>   (the uploaded file was only
76    *                                           partially uploaded)
77    *             - <b>UPLOAD_ERR_NO_FILE</b>   (no file was uploaded)
78    */
79   public function getFileError($name)
80   {
81     return ($this->hasFile($name) ? $this->getFileValue($name, 'error') : UPLOAD_ERR_NO_FILE);
82   }
83
84   /**
85    * Retrieves a file name.
86    *
87    * @param string A file nam.
88    *
89    * @return string A file name, if the file exists, otherwise null
90    */
91   public function getFileName($name)
92   {
93     return ($this->hasFile($name) ? $this->getFileValue($name, 'name') : null);
94   }
95
96   /**
97    * Retrieves an array of file names.
98    *
99    * @return array An indexed array of file names
100    */
101   public function getFileNames()
102   {
103     return array_keys($_FILES);
104   }
105
106   /**
107    * Retrieves an array of files.
108    *
109    * @return array An associative array of files
110    */
111   public function getFiles()
112   {
113     return $_FILES;
114   }
115
116   /**
117    * Retrieves a file path.
118    *
119    * @param string A file name
120    *
121    * @return string A file path, if the file exists, otherwise null
122    */
123   public function getFilePath($name)
124   {
125     return ($this->hasFile($name) ? $this->getFileValue($name, 'tmp_name') : null);
126   }
127
128   /**
129    * Retrieve a file size.
130    *
131    * @param string A file name
132    *
133    * @return int A file size, if the file exists, otherwise null
134    */
135   public function getFileSize($name)
136   {
137     return ($this->hasFile($name) ? $this->getFileValue($name, 'size') : null);
138   }
139
140   /**
141    * Retrieves a file type.
142    *
143    * This may not be accurate. This is the mime-type sent by the browser
144    * during the upload.
145    *
146    * @param string A file name
147    *
148    * @return string A file type, if the file exists, otherwise null
149    */
150   public function getFileType($name)
151   {
152     return ($this->hasFile($name) ? $this->getFileValue($name, 'type') : null);
153   }
154
155   /**
156    * Indicates whether or not a file exists.
157    *
158    * @param string A file name
159    *
160    * @return boolean true, if the file exists, otherwise false
161    */
162   public function hasFile($name)
163   {
164     if (strpos($name, '['))
165     {
166       return !is_null(sfToolkit::getArrayValueForPath($this->filesInfos, $name));
167     }
168     else
169     {
170       return isset($this->filesInfos[$name]);
171     }
172   }
173
174   /**
175    * Indicates whether or not a file error exists.
176    *
177    * @param string A file name
178    *
179    * @return boolean true, if the file error exists, otherwise false
180    */
181   public function hasFileError($name)
182   {
183     return ($this->hasFile($name) ? ($this->getFileValue($name, 'error') != UPLOAD_ERR_OK) : false);
184   }
185
186   /**
187    * Indicates whether or not any file errors occured.
188    *
189    * @return boolean true, if any file errors occured, otherwise false
190    */
191   public function hasFileErrors()
192   {
193     foreach ($this->getFileNames() as $name)
194     {
195       if ($this->hasFileError($name) === true)
196       {
197         return true;
198       }
199     }
200
201     return false;
202   }
203
204   /**
205    * Indicates whether or not any files exist.
206    *
207    * @return boolean true, if any files exist, otherwise false
208    */
209   public function hasFiles()
210   {
211     return (count($_FILES) > 0);
212   }
213
214   /**
215    * Retrieves a file value.
216    *
217    * @param string A file name
218    * @param string Value to search in the file
219    *
220    * @return string File value
221    */
222   public function getFileValue($name, $key)
223   {
224     $fileInfos = $this->getFileValues($name);
225
226     return isset($fileInfos[$key]) ? $fileInfos[$key] : null;
227   }
228
229   /**
230    * Retrieves all the values from a file.
231    *
232    * @param string A file name
233    *
234    * @return array Associative list of the file values
235    */
236   public function getFileValues($name)
237   {
238     if (strpos($name, '['))
239     {
240       return sfToolkit::getArrayValueForPath($this->filesInfos, $name);
241     }
242     else
243     {
244       return isset($this->filesInfos[$name]) ? $this->filesInfos[$name] : null;
245     }
246   }
247
248   /**
249    * Converts uploaded file array to a format following the $_GET and $POST naming convention.
250    *
251    * It's safe to pass an already converted array, in which case this method just returns the original array unmodified.
252    *
253    * @param  array An array representing uploaded file information
254    *
255    * @return array An array of re-ordered uploaded file information
256    */
257   protected function convertFileInformation($taintedFiles)
258   {
259     return $this->pathsToArray(preg_replace('#^(/[^/]+)?(/name|/type|/tmp_name|/error|/size)([^\s]*)( = [^\n]*)#m', '$1$3$2$4', $this->arrayToPaths($taintedFiles)));
260   }
261
262   /**
263    * Retrieves an extension for a given file.
264    *
265    * @param string A file name
266    *
267    * @return string Extension for the file
268    */
269   public function getFileExtension($name)
270   {
271     static $mimeTypes = null;
272
273     $fileType = $this->getFileType($name);
274
275     if (!$fileType)
276     {
277       return '.bin';
278     }
279
280     if (is_null($mimeTypes))
281     {
282       $mimeTypes = unserialize(file_get_contents(sfConfig::get('sf_symfony_data_dir').'/data/mime_types.dat'));
283     }
284
285     return isset($mimeTypes[$fileType]) ? '.'.$mimeTypes[$fileType] : '.bin';
286   }
287
288   /**
289    * Initializes this sfRequest.
290    *
291    * @param sfContext A sfContext instance
292    * @param array   An associative array of initialization parameters
293    * @param array   An associative array of initialization attributes
294    *
295    * @return boolean true, if initialization completes successfully, otherwise false
296    *
297    * @throws <b>sfInitializationException</b> If an error occurs while initializing this Request
298    */
299   public function initialize($context, $parameters = array(), $attributes = array())
300   {
301     parent::initialize($context, $parameters, $attributes);
302
303     if (isset($_SERVER['REQUEST_METHOD']))
304     {
305       switch ($_SERVER['REQUEST_METHOD'])
306       {
307         case 'GET':
308           $this->setMethod(self::GET);
309           break;
310
311         case 'POST':
312           $this->setMethod(self::POST);
313           break;
314
315         case 'PUT':
316           $this->setMethod(self::PUT);
317           break;
318
319         case 'DELETE':
320           $this->setMethod(self::DELETE);
321           break;
322
323         case 'HEAD':
324           $this->setMethod(self::HEAD);
325           break;
326
327         default:
328           $this->setMethod(self::GET);
329       }
330     }
331     else
332     {
333       // set the default method
334       $this->setMethod(self::GET);
335     }
336
337     // load parameters from GET/PATH_INFO/POST
338     $this->loadParameters();
339   }
340
341   /**
342    * Returns the array that contains all request information ($_SERVER or $_ENV).
343    *
344    * This information is stored in the [sf_path_info_array] constant.
345    *
346    * @return  array Path information
347    */
348   protected function getPathInfoArray()
349   {
350     if (!$this->pathInfoArray)
351     {
352       // parse PATH_INFO
353       switch (sfConfig::get('sf_path_info_array'))
354       {
355         case 'SERVER':
356           $this->pathInfoArray =& $_SERVER;
357           break;
358
359         case 'ENV':
360         default:
361           $this->pathInfoArray =& $_ENV;
362       }
363     }
364
365     return $this->pathInfoArray;
366   }
367
368   /**
369    * Retrieves the uniform resource identifier for the current web request.
370    *
371    * @return string Unified resource identifier
372    */
373   public function getUri()
374   {
375     $pathArray = $this->getPathInfoArray();
376
377     // for IIS with rewrite module (IIFR, ISAPI Rewrite, ...)
378     if ('HTTP_X_REWRITE_URL' == sfConfig::get('sf_path_info_key'))
379     {
380       $uri = isset($pathArray['HTTP_X_REWRITE_URL']) ? $pathArray['HTTP_X_REWRITE_URL'] : '';
381     }
382     else
383     {
384       $uri = isset($pathArray['REQUEST_URI']) ? $pathArray['REQUEST_URI'] : '';
385     }
386
387     return $this->isAbsUri() ? $uri : $this->getUriPrefix().$uri;
388   }
389
390   /**
391    * See if the client is using absolute uri
392    *
393    * @return boolean true, if is absolute uri otherwise false
394    */
395   public function isAbsUri()
396   {
397     $pathArray = $this->getPathInfoArray();
398
399     return preg_match('/^http/', $pathArray['REQUEST_URI']);
400   }
401
402   /**
403    * Returns Uri prefix, including protocol, hostname and server port.
404    *
405    * @return string Uniform resource identifier prefix
406    */
407   public function getUriPrefix()
408   {
409     $pathArray = $this->getPathInfoArray();
410     if ($this->isSecure())
411     {
412       $standardPort = '443';
413       $protocol = 'https';
414     }
415     else
416     {
417       $standardPort = '80';
418       $protocol = 'http';
419     }
420
421     $host = explode(":", $this->getHost());
422     if (count($host) == 1)
423     {
424       $host[] = isset($pathArray['SERVER_PORT']) ? $pathArray['SERVER_PORT'] : '';
425     }
426
427     if ($host[1] == $standardPort || empty($host[1]))
428     {
429       unset($host[1]);
430     }
431
432     return $protocol.'://'.implode(':', $host);;
433   }
434
435   /**
436    * Retrieves the path info for the current web request.
437    *
438    * @return string Path info
439    */
440   public function getPathInfo()
441   {
442     $pathInfo = '';
443
444     $pathArray = $this->getPathInfoArray();
445
446     // simulate PATH_INFO if needed
447     $sf_path_info_key = sfConfig::get('sf_path_info_key');
448     if (!isset($pathArray[$sf_path_info_key]) || !$pathArray[$sf_path_info_key])
449     {
450       if (isset($pathArray['REQUEST_URI']))
451       {
452         $script_name = $this->getScriptName();
453         $uri_prefix = $this->isAbsUri() ? $this->getUriPrefix() : '';
454         $pathInfo = preg_replace('/^'.preg_quote($uri_prefix, '/').'/','',$pathArray['REQUEST_URI']);
455         $pathInfo = preg_replace('/^'.preg_quote($script_name, '/').'/', '', $pathInfo);
456         $prefix_name = preg_replace('#/[^/]+$#', '', $script_name);
457         $pathInfo = preg_replace('/^'.preg_quote($prefix_name, '/').'/', '', $pathInfo);
458         $pathInfo = preg_replace('/\??'.preg_quote($pathArray['QUERY_STRING'], '/').'$/', '', $pathInfo);
459       }
460     }
461     else
462     {
463       $pathInfo = $pathArray[$sf_path_info_key];
464       if ($sf_relative_url_root = $this->getRelativeUrlRoot())
465       {
466         $pathInfo = preg_replace('/^'.str_replace('/', '\\/', $sf_relative_url_root).'\//', '', $pathInfo);
467       }
468     }
469
470     // for IIS
471     if (isset($_SERVER['SERVER_SOFTWARE']) && false !== stripos($_SERVER['SERVER_SOFTWARE'], 'iis') && $pos = stripos($pathInfo, '.php'))
472     {
473       $pathInfo = substr($pathInfo, $pos + 4);
474     }
475
476     if (!$pathInfo)
477     {
478       $pathInfo = '/';
479     }
480
481     return $pathInfo;
482   }
483
484   /**
485    * Loads GET, PATH_INFO and POST data into the parameter list.
486    *
487    */
488   protected function loadParameters()
489   {
490     // merge GET parameters
491     if (get_magic_quotes_gpc())
492     {
493       $_GET = sfToolkit::stripslashesDeep($_GET);
494     }
495     $this->getParameterHolder()->addByRef($_GET);
496
497     $pathInfo = $this->getPathInfo();
498     if ($pathInfo)
499     {
500       // routing map defined?
501       $r = sfRouting::getInstance();
502       if ($r->hasRoutes())
503       {
504         $results = $r->parse($pathInfo);
505         if ($results !== null)
506         {
507           $this->getParameterHolder()->addByRef($results);
508         }
509         else
510         {
511           $this->setParameter('module', sfConfig::get('sf_error_404_module'));
512           $this->setParameter('action', sfConfig::get('sf_error_404_action'));
513         }
514       }
515       else
516       {
517         $array = explode('/', trim($pathInfo, '/'));
518         $count = count($array);
519
520         for ($i = 0; $i < $count; $i++)
521         {
522           // see if there's a value associated with this parameter,
523           // if not we're done with path data
524           if ($count > ($i + 1))
525           {
526             $this->getParameterHolder()->setByRef($array[$i], $array[++$i]);
527           }
528         }
529       }
530     }
531
532     $this->filesInfos = $this->convertFileInformation($_FILES);
533
534     // merge POST parameters
535     if (get_magic_quotes_gpc())
536     {
537       $_POST = sfToolkit::stripslashesDeep((array) $_POST);
538     }
539     $this->getParameterHolder()->addByRef($_POST);
540
541     // move symfony parameters in a protected namespace (parameters prefixed with _sf_)
542     foreach ($this->getParameterHolder()->getAll() as $key => $value)
543     {
544       if (0 === stripos($key, '_sf_'))
545       {
546         $this->getParameterHolder()->remove($key);
547         $this->setParameter($key, $value, 'symfony/request/sfWebRequest');
548         unset($_GET[$key]);
549       }
550     }
551
552     if (sfConfig::get('sf_logging_enabled'))
553     {
554       $this->getContext()->getLogger()->info(sprintf('{sfRequest} request parameters %s', str_replace("\n", '', var_export($this->getParameterHolder()->getAll(), true))));
555     }
556   }
557
558   /**
559    * Moves an uploaded file.
560    *
561    * @param string A file name
562    * @param string An absolute filesystem path to where you would like the
563    *               file moved. This includes the new filename as well, since
564    *               uploaded files are stored with random names
565    * @param int    The octal mode to use for the new file
566    * @param boolean   Indicates that we should make the directory before moving the file
567    * @param int    The octal mode to use when creating the directory
568    *
569    * @return boolean true, if the file was moved, otherwise false
570    *
571    * @throws <b>sfFileException</b> If a major error occurs while attempting to move the file
572    */
573   public function moveFile($name, $file, $fileMode = 0666, $create = true, $dirMode = 0777)
574   {
575     if ($this->hasFile($name) && $this->getFileValue($name, 'error') == UPLOAD_ERR_OK && $this->getFileValue($name, 'size') > 0)
576     {
577       // get our directory path from the destination filename
578       $directory = dirname($file);
579
580       if (!is_readable($directory))
581       {
582         $fmode = 0777;
583
584         if ($create && !@mkdir($directory, $dirMode, true))
585         {
586           // failed to create the directory
587           $error = 'Failed to create file upload directory "%s"';
588           $error = sprintf($error, $directory);
589
590           throw new sfFileException($error);
591         }
592
593         // chmod the directory since it doesn't seem to work on
594         // recursive paths
595         @chmod($directory, $dirMode);
596       }
597       else if (!is_dir($directory))
598       {
599         // the directory path exists but it's not a directory
600         $error = 'File upload path "%s" exists, but is not a directory';
601         $error = sprintf($error, $directory);
602
603         throw new sfFileException($error);
604       }
605       else if (!is_writable($directory))
606       {
607         // the directory isn't writable
608         $error = 'File upload path "%s" is not writable';
609         $error = sprintf($error, $directory);
610
611         throw new sfFileException($error);
612       }
613
614       if (@move_uploaded_file($this->getFileValue($name, 'tmp_name'), $file))
615       {
616         // chmod our file
617         @chmod($file, $fileMode);
618
619         return true;
620       }
621     }
622
623     return false;
624   }
625
626   /**
627    * Returns referer.
628    *
629    * @return  string
630    */
631   public function getReferer()
632   {
633     $pathArray = $this->getPathInfoArray();
634
635     return isset($pathArray['HTTP_REFERER']) ? $pathArray['HTTP_REFERER'] : '';
636   }
637
638   /**
639    * Returns current host name.
640    *
641    * @return  string
642    */
643   public function getHost()
644   {
645     $pathArray = $this->getPathInfoArray();
646
647     return isset($pathArray['HTTP_X_FORWARDED_HOST']) ? $pathArray['HTTP_X_FORWARDED_HOST'] : (isset($pathArray['HTTP_HOST']) ? $pathArray['HTTP_HOST'] : '');
648   }
649
650   /**
651    * Returns current script name.
652    *
653    * @return  string
654    */
655   public function getScriptName()
656   {
657     $pathArray = $this->getPathInfoArray();
658
659     return isset($pathArray['SCRIPT_NAME']) ? $pathArray['SCRIPT_NAME'] : (isset($pathArray['ORIG_SCRIPT_NAME']) ? $pathArray['ORIG_SCRIPT_NAME'] : '');
660   }
661
662   /**
663    * Returns request method.
664    *
665    * @return  string
666    */
667   public function getMethodName()
668   {
669     $pathArray = $this->getPathInfoArray();
670
671     return isset($pathArray['REQUEST_METHOD']) ? $pathArray['REQUEST_METHOD'] : 'GET';
672   }
673
674   /**
675    * Gets a list of languages acceptable by the client browser
676    *
677    * @return array Languages ordered in the user browser preferences
678    */
679   public function getLanguages()
680   {
681     if ($this->languages)
682     {
683       return $this->languages;
684     }
685
686     if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
687     {
688       return array();
689     }
690
691     $languages = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT_LANGUAGE']);
692     foreach ($languages as $lang)
693     {
694       if (strstr($lang, '-'))
695       {
696         $codes = explode('-', $lang);
697         if ($codes[0] == 'i')
698         {
699           // Language not listed in ISO 639 that are not variants
700           // of any listed language, which can be registerd with the
701           // i-prefix, such as i-cherokee
702           if (count($codes) > 1)
703           {
704             $lang = $codes[1];
705           }
706         }
707         else
708         {
709           for ($i = 0, $max = count($codes); $i < $max; $i++)
710           {
711             if ($i == 0)
712             {
713               $lang = strtolower($codes[0]);
714             }
715             else
716             {
717               $lang .= '_'.strtoupper($codes[$i]);
718             }
719           }
720         }
721       }
722
723       $this->languages[] = $lang;
724     }
725
726     return $this->languages;
727   }
728
729   /**
730    * Gets a list of charsets acceptable by the client browser.
731    *
732    * @return array List of charsets in preferable order
733    */
734   public function getCharsets()
735   {
736     if ($this->charsets)
737     {
738       return $this->charsets;
739     }
740
741     if (!isset($_SERVER['HTTP_ACCEPT_CHARSET']))
742     {
743       return array();
744     }
745
746     $this->charsets = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT_CHARSET']);
747
748     return $this->charsets;
749   }
750
751   /**
752    * Gets a list of content types acceptable by the client browser
753    *
754    * @return array Languages ordered in the user browser preferences
755    */
756   public function getAcceptableContentTypes()
757   {
758     if ($this->acceptableContentTypes)
759     {
760       return $this->acceptableContentTypes;
761     }
762
763     if (!isset($_SERVER['HTTP_ACCEPT']))
764     {
765       return array();
766     }
767
768     $this->acceptableContentTypes = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT']);
769
770     return $this->acceptableContentTypes;
771   }
772
773   /**
774    * Returns true if the request is a XMLHttpRequest.
775    *
776    * It works if your JavaScript library set an X-Requested-With HTTP header.
777    * Works with Prototype, Mootools, jQuery, and perhaps others.
778    *
779    * @return Boolean true if the request is an XMLHttpRequest, false otherwise
780    */
781   public function isXmlHttpRequest()
782   {
783     return ($this->getHttpHeader('X_REQUESTED_WITH') == 'XMLHttpRequest');
784   }
785
786   public function getHttpHeader($name, $prefix = 'http')
787   {
788     if ($prefix)
789     {
790       $prefix = strtoupper($prefix).'_';
791     }
792
793     $name = $prefix.strtoupper(strtr($name, '-', '_'));
794
795     $pathArray = $this->getPathInfoArray();
796
797     return isset($pathArray[$name]) ? sfToolkit::stripslashesDeep($pathArray[$name]) : null;
798   }
799
800   /**
801    * Gets a cookie value.
802    *
803    * @return mixed
804    */
805   public function getCookie($name, $defaultValue = null)
806   {
807     $retval = $defaultValue;
808
809     if (isset($_COOKIE[$name]))
810     {
811       $retval = get_magic_quotes_gpc() ? sfToolkit::stripslashesDeep($_COOKIE[$name]) : $_COOKIE[$name];
812     }
813
814     return $retval;
815   }
816
817   /**
818    * Returns true if the current request is secure (HTTPS protocol).
819    *
820    * @return boolean
821    */
822   public function isSecure()
823   {
824     $pathArray = $this->getPathInfoArray();
825
826     return (
827       (isset($pathArray['HTTPS']) && (strtolower($pathArray['HTTPS']) == 'on' || strtolower($pathArray['HTTPS']) == 1))
828       ||
829       (isset($pathArray['HTTP_X_FORWARDED_PROTO']) && strtolower($pathArray['HTTP_X_FORWARDED_PROTO']) == 'https')
830     );
831   }
832
833   /**
834    * Retrieves relative root url.
835    *
836    * @return string URL
837    */
838   public function getRelativeUrlRoot()
839   {
840     if ($this->relativeUrlRoot === null)
841     {
842       $this->relativeUrlRoot = sfConfig::get('sf_relative_url_root', preg_replace('#/[^/]+\.php5?$#', '', $this->getScriptName()));
843     }
844
845     return $this->relativeUrlRoot;
846   }
847
848   /**
849    * Sets the relative root url for the current web request.
850    *
851    * @param string Value for the url
852    */
853   public function setRelativeUrlRoot($value)
854   {
855     $this->relativeUrlRoot = $value;
856   }
857
858   /**
859    * Executes the shutdown procedure.
860    *
861    */
862   public function shutdown()
863   {
864   }
865
866   /**
867    * Splits an HTTP header for the current web request.
868    *
869    * @param string Header to split
870    */
871   public function splitHttpAcceptHeader($header)
872   {
873     $values = array();
874     foreach (array_filter(explode(',', $header)) as $value)
875     {
876       // Cut off any q-value that might come after a semi-colon
877       if ($pos = strpos($value, ';'))
878       {
879         $q     = (float) trim(substr($value, $pos + 3));
880         $value = trim(substr($value, 0, $pos));
881       }
882       else
883       {
884         $q = 1;
885       }
886
887       $values[$value] = $q;
888     }
889
890     arsort($values);
891
892     return array_keys($values);
893   }
894
895   /**
896    * Converts a string of paths separated by newlines into an array.
897    *
898    * Code adapted from http://www.shauninman.com/archive/2006/11/30/fixing_the_files_superglobal
899    * @author Shaun Inman (www.shauninman.com)
900    *
901    * @param  string A string representing an array
902    *
903    * @return Array  An array
904    */
905   protected function pathsToArray($str)
906   {
907     $array = array();
908     $lines = explode("\n", trim($str));
909
910     if (!empty($lines[0]))
911     {
912       foreach ($lines as $line)
913       {
914         list($path, $value) = explode(' = ', $line);
915
916         $steps = explode('/', $path);
917         array_shift($steps);
918
919         $insertion =& $array;
920
921         foreach ($steps as $step)
922         {
923           if (!isset($insertion[$step]))
924           {
925             $insertion[$step] = array();
926           }
927           $insertion =& $insertion[$step];
928         }
929         $insertion = ctype_digit($value) ? (int) $value : $value;
930       }
931     }
932
933     return $array;
934   }
935
936   /**
937    * Converts an array into a string containing the path to each of its values separated by a newline.
938    *
939    * Code adapted from http://www.shauninman.com/archive/2006/11/30/fixing_the_files_superglobal
940    * @author Shaun Inman (www.shauninman.com)
941    *
942    * @param  Array  An array
943    *
944    * @return string A string representing the array
945    */
946   protected function arrayToPaths($array = array(), $prefix = '')
947   {
948     $str = '';
949     $freshPrefix = $prefix;
950
951     foreach ($array as $key => $value)
952     {
953       $freshPrefix .= "/{$key}";
954
955       if (is_array($value))
956       {
957         $str .= $this->arrayToPaths($value, $freshPrefix);
958         $freshPrefix = $prefix;
959       }
960       else
961       {
962         $str .= "{$prefix}/{$key} = {$value}\n";
963       }
964     }
965
966     return $str;
967   }
968 }
969
Note: See TracBrowser for help on using the browser.