request_handler.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: request_handler.php 8230 2009-07-14 03:52:06Z mark_story $ */
00003 /**
00004  * Request object for handling alternative HTTP requests
00005  *
00006  * Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers,
00007  * and the like.  These units have no use for Ajax requests, and this Component can tell how Cake
00008  * should respond to the different needs of a handheld computer and a desktop machine.
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs.controller.components
00021  * @since         CakePHP(tm) v 0.10.4.1076
00022  * @version       $Revision: 8230 $
00023  * @modifiedby    $LastChangedBy: mark_story $
00024  * @lastmodified  $Date: 2009-07-13 23:52:06 -0400 (Mon, 13 Jul 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 
00028 if (!defined('REQUEST_MOBILE_UA')) {
00029     define('REQUEST_MOBILE_UA', '(iPhone|MIDP|AvantGo|BlackBerry|J2ME|Opera Mini|DoCoMo|NetFront|Nokia|PalmOS|PalmSource|portalmmm|Plucker|ReqwirelessWeb|SonyEricsson|Symbian|UP\.Browser|Windows CE|Xiino)');
00030 }
00031 
00032 /**
00033  * Request object for handling HTTP requests
00034  *
00035  * @package       cake
00036  * @subpackage    cake.cake.libs.controller.components
00037  *
00038  */
00039 class RequestHandlerComponent extends Object {
00040 /**
00041  * The layout that will be switched to for Ajax requests
00042  *
00043  * @var string
00044  * @access public
00045  * @see RequestHandler::setAjax()
00046  */
00047     var $ajaxLayout = 'ajax';
00048 /**
00049  * Determines whether or not callbacks will be fired on this component
00050  *
00051  * @var boolean
00052  * @access public
00053  */
00054     var $enabled = true;
00055 /**
00056  * Holds the content-type of the response that is set when using
00057  * RequestHandler::respondAs()
00058  *
00059  * @var string
00060  * @access private
00061  */
00062     var $__responseTypeSet = null;
00063 /**
00064  * Holds the copy of Controller::$params
00065  *
00066  * @var array
00067  * @access public
00068  */
00069     var $params = array();
00070 /**
00071  * Friendly content-type mappings used to set response types and determine
00072  * request types.  Can be modified with RequestHandler::setContent()
00073  *
00074  * @var array
00075  * @access private
00076  * @see RequestHandlerComponent::setContent
00077  */
00078     var $__requestContent = array(
00079         'javascript'    => 'text/javascript',
00080         'js'            => 'text/javascript',
00081         'json'          => 'application/json',
00082         'css'           => 'text/css',
00083         'html'          => array('text/html', '*/*'),
00084         'text'          => 'text/plain',
00085         'txt'           => 'text/plain',
00086         'csv'           => array('application/vnd.ms-excel', 'text/plain'),
00087         'form'          => 'application/x-www-form-urlencoded',
00088         'file'          => 'multipart/form-data',
00089         'xhtml'         => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
00090         'xhtml-mobile'  => 'application/vnd.wap.xhtml+xml',
00091         'xml'           => array('application/xml', 'text/xml'),
00092         'rss'           => 'application/rss+xml',
00093         'atom'          => 'application/atom+xml',
00094         'amf'           => 'application/x-amf',
00095         'wap'           => array(
00096             'text/vnd.wap.wml',
00097             'text/vnd.wap.wmlscript',
00098             'image/vnd.wap.wbmp'
00099         ),
00100         'wml'           => 'text/vnd.wap.wml',
00101         'wmlscript'     => 'text/vnd.wap.wmlscript',
00102         'wbmp'          => 'image/vnd.wap.wbmp',
00103         'pdf'           => 'application/pdf',
00104         'zip'           => 'application/x-zip',
00105         'tar'           => 'application/x-tar'
00106     );
00107 /**
00108  * Content-types accepted by the client.  If extension parsing is enabled in the
00109  * Router, and an extension is detected, the corresponding content-type will be
00110  * used as the overriding primary content-type accepted.
00111  *
00112  * @var array
00113  * @access private
00114  * @see Router::parseExtensions()
00115  */
00116     var $__acceptTypes = array();
00117 /**
00118  * The template to use when rendering the given content type.
00119  *
00120  * @var string
00121  * @access private
00122  */
00123     var $__renderType = null;
00124 /**
00125  * Contains the file extension parsed out by the Router
00126  *
00127  * @var string
00128  * @access public
00129  * @see Router::parseExtensions()
00130  */
00131     var $ext = null;
00132 /**
00133  * Flag set when MIME types have been initialized
00134  *
00135  * @var boolean
00136  * @access private
00137  * @see RequestHandler::__initializeTypes()
00138  */
00139     var $__typesInitialized = false;
00140 /**
00141  * Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT
00142  *
00143  */
00144     function __construct() {
00145         $this->__acceptTypes = explode(',', env('HTTP_ACCEPT'));
00146 
00147         foreach ($this->__acceptTypes as $i => $type) {
00148             if (strpos($type, ';')) {
00149                 $type = explode(';', $type);
00150                 $this->__acceptTypes[$i] = $type[0];
00151             }
00152         }
00153         parent::__construct();
00154     }
00155 /**
00156  * Initializes the component, gets a reference to Controller::$parameters, and
00157  * checks to see if a file extension has been parsed by the Router.  If yes, the
00158  * corresponding content-type is pushed onto the list of accepted content-types
00159  * as the first item.
00160  *
00161  * @param object $controller A reference to the controller
00162  * @return void
00163  * @see Router::parseExtensions()
00164  * @access public
00165  */
00166     function initialize(&$controller) {
00167         if (isset($controller->params['url']['ext'])) {
00168             $this->ext = $controller->params['url']['ext'];
00169         }
00170     }
00171 /**
00172  * The startup method of the RequestHandler enables several automatic behaviors
00173  * related to the detection of certain properties of the HTTP request, including:
00174  *
00175  * - Disabling layout rendering for Ajax requests (based on the HTTP_X_REQUESTED_WITH header)
00176  * - If Router::parseExtensions() is enabled, the layout and template type are
00177  *   switched based on the parsed extension.  For example, if controller/action.xml
00178  *   is requested, the view path becomes <i>app/views/controller/xml/action.ctp</i>.
00179  * - If a helper with the same name as the extension exists, it is added to the controller.
00180  * - If the extension is of a type that RequestHandler understands, it will set that
00181  *   Content-type in the response header.
00182  * - If the XML data is POSTed, the data is parsed into an XML object, which is assigned
00183  *   to the $data property of the controller, which can then be saved to a model object.
00184  *
00185  * @param object $controller A reference to the controller
00186  * @return void
00187  * @access public
00188  */
00189     function startup(&$controller) {
00190         if (!$this->enabled) {
00191             return;
00192         }
00193 
00194         $this->__initializeTypes();
00195         $controller->params['isAjax'] = $this->isAjax();
00196         $isRecognized = (
00197             !in_array($this->ext, array('html', 'htm')) &&
00198             in_array($this->ext, array_keys($this->__requestContent))
00199         );
00200 
00201         if (!empty($this->ext) && $isRecognized) {
00202             $this->renderAs($controller, $this->ext);
00203         } elseif ($this->isAjax()) {
00204             $this->renderAs($controller, 'ajax');
00205         }
00206 
00207         if ($this->requestedWith('xml')) {
00208             if (!class_exists('XmlNode')) {
00209                 App::import('Core', 'Xml');
00210             }
00211             $xml = new Xml(trim(file_get_contents('php://input')));
00212 
00213             if (is_object($xml->child('data')) && count($xml->children) == 1) {
00214                 $controller->data = $xml->child('data');
00215             } else {
00216                 $controller->data = $xml;
00217             }
00218         }
00219     }
00220 /**
00221  * Handles (fakes) redirects for Ajax requests using requestAction()
00222  *
00223  * @param object $controller A reference to the controller
00224  * @param mixed $url A string or array containing the redirect location
00225  * @access public
00226  */
00227     function beforeRedirect(&$controller, $url) {
00228         if (!$this->isAjax()) {
00229             return;
00230         }
00231         foreach ($_POST as $key => $val) {
00232             unset($_POST[$key]);
00233         }
00234         echo $this->requestAction($url, array('return'));
00235         $this->_stop();
00236     }
00237 /**
00238  * Returns true if the current HTTP request is Ajax, false otherwise
00239  *
00240  * @return boolean True if call is Ajax
00241  * @access public
00242  */
00243     function isAjax() {
00244         return env('HTTP_X_REQUESTED_WITH') === "XMLHttpRequest";
00245     }
00246 /**
00247  * Returns true if the current HTTP request is coming from a Flash-based client
00248  *
00249  * @return boolean True if call is from Flash
00250  * @access public
00251  */
00252     function isFlash() {
00253         return (preg_match('/^(Shockwave|Adobe) Flash/', env('HTTP_USER_AGENT')) == 1);
00254     }
00255 /**
00256  * Returns true if the current request is over HTTPS, false otherwise.
00257  *
00258  * @return bool True if call is over HTTPS
00259  * @access public
00260  */
00261     function isSSL() {
00262         return env('HTTPS');
00263     }
00264 /**
00265  * Returns true if the current call accepts an XML response, false otherwise
00266  *
00267  * @return boolean True if client accepts an XML response
00268  * @access public
00269  */
00270     function isXml() {
00271         return $this->prefers('xml');
00272     }
00273 /**
00274  * Returns true if the current call accepts an RSS response, false otherwise
00275  *
00276  * @return boolean True if client accepts an RSS response
00277  * @access public
00278  */
00279     function isRss() {
00280         return $this->prefers('rss');
00281     }
00282 /**
00283  * Returns true if the current call accepts an Atom response, false otherwise
00284  *
00285  * @return boolean True if client accepts an RSS response
00286  * @access public
00287  */
00288     function isAtom() {
00289         return $this->prefers('atom');
00290     }
00291 /**
00292  * Returns true if user agent string matches a mobile web browser, or if the
00293  * client accepts WAP content.
00294  *
00295  * @return boolean True if user agent is a mobile web browser
00296  * @access public
00297  */
00298     function isMobile() {
00299         preg_match('/' . REQUEST_MOBILE_UA . '/i', env('HTTP_USER_AGENT'), $match);
00300         if (!empty($match) || $this->accepts('wap')) {
00301             return true;
00302         }
00303         return false;
00304     }
00305 /**
00306  * Returns true if the client accepts WAP content
00307  *
00308  * @return bool
00309  * @access public
00310  */
00311     function isWap() {
00312         return $this->prefers('wap');
00313     }
00314 /**
00315  * Returns true if the current call a POST request
00316  *
00317  * @return boolean True if call is a POST
00318  * @access public
00319  */
00320     function isPost() {
00321         return (strtolower(env('REQUEST_METHOD')) == 'post');
00322     }
00323 /**
00324  * Returns true if the current call a PUT request
00325  *
00326  * @return boolean True if call is a PUT
00327  * @access public
00328  */
00329     function isPut() {
00330         return (strtolower(env('REQUEST_METHOD')) == 'put');
00331     }
00332 /**
00333  * Returns true if the current call a GET request
00334  *
00335  * @return boolean True if call is a GET
00336  * @access public
00337  */
00338     function isGet() {
00339         return (strtolower(env('REQUEST_METHOD')) == 'get');
00340     }
00341 /**
00342  * Returns true if the current call a DELETE request
00343  *
00344  * @return boolean True if call is a DELETE
00345  * @access public
00346  */
00347     function isDelete() {
00348         return (strtolower(env('REQUEST_METHOD')) == 'delete');
00349     }
00350 /**
00351  * Gets Prototype version if call is Ajax, otherwise empty string.
00352  * The Prototype library sets a special "Prototype version" HTTP header.
00353  *
00354  * @return string Prototype version of component making Ajax call
00355  * @access public
00356  */
00357     function getAjaxVersion() {
00358         if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
00359             return env('HTTP_X_PROTOTYPE_VERSION');
00360         }
00361         return false;
00362     }
00363 /**
00364  * Adds/sets the Content-type(s) for the given name.  This method allows
00365  * content-types to be mapped to friendly aliases (or extensions), which allows
00366  * RequestHandler to automatically respond to requests of that type in the
00367  * startup method.
00368  *
00369  * @param string $name The name of the Content-type, i.e. "html", "xml", "css"
00370  * @param mixed $type The Content-type or array of Content-types assigned to the name,
00371  *    i.e. "text/html", or "application/xml"
00372  * @return void
00373  * @access public
00374  */
00375     function setContent($name, $type = null) {
00376         if (is_array($name)) {
00377             $this->__requestContent = array_merge($this->__requestContent, $name);
00378             return;
00379         }
00380         $this->__requestContent[$name] = $type;
00381     }
00382 /**
00383  * Gets the server name from which this request was referred
00384  *
00385  * @return string Server address
00386  * @access public
00387  */
00388     function getReferrer() {
00389         if (env('HTTP_HOST') != null) {
00390             $sessHost = env('HTTP_HOST');
00391         }
00392 
00393         if (env('HTTP_X_FORWARDED_HOST') != null) {
00394             $sessHost = env('HTTP_X_FORWARDED_HOST');
00395         }
00396         return trim(preg_replace('/(?:\:.*)/', '', $sessHost));
00397     }
00398 /**
00399  * Gets remote client IP
00400  *
00401  * @return string Client IP address
00402  * @access public
00403  */
00404     function getClientIP($safe = true) {
00405         if (!$safe && env('HTTP_X_FORWARDED_FOR') != null) {
00406             $ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR'));
00407         } else {
00408             if (env('HTTP_CLIENT_IP') != null) {
00409                 $ipaddr = env('HTTP_CLIENT_IP');
00410             } else {
00411                 $ipaddr = env('REMOTE_ADDR');
00412             }
00413         }
00414 
00415         if (env('HTTP_CLIENTADDRESS') != null) {
00416             $tmpipaddr = env('HTTP_CLIENTADDRESS');
00417 
00418             if (!empty($tmpipaddr)) {
00419                 $ipaddr = preg_replace('/(?:,.*)/', '', $tmpipaddr);
00420             }
00421         }
00422         return trim($ipaddr);
00423     }
00424 /**
00425  * Determines which content types the client accepts.  Acceptance is based on
00426  * the file extension parsed by the Router (if present), and by the HTTP_ACCEPT
00427  * header.
00428  *
00429  * @param mixed $type Can be null (or no parameter), a string type name, or an
00430  *   array of types
00431  * @return mixed If null or no parameter is passed, returns an array of content
00432  *   types the client accepts.  If a string is passed, returns true
00433  *   if the client accepts it.  If an array is passed, returns true
00434  *   if the client accepts one or more elements in the array.
00435  * @access public
00436  * @see RequestHandlerComponent::setContent()
00437  */
00438     function accepts($type = null) {
00439         $this->__initializeTypes();
00440 
00441         if ($type == null) {
00442             return $this->mapType($this->__acceptTypes);
00443 
00444         } elseif (is_array($type)) {
00445             foreach ($type as $t) {
00446                 if ($this->accepts($t) == true) {
00447                     return true;
00448                 }
00449             }
00450             return false;
00451         } elseif (is_string($type)) {
00452 
00453             if (!isset($this->__requestContent[$type])) {
00454                 return false;
00455             }
00456 
00457             $content = $this->__requestContent[$type];
00458 
00459             if (is_array($content)) {
00460                 foreach ($content as $c) {
00461                     if (in_array($c, $this->__acceptTypes)) {
00462                         return true;
00463                     }
00464                 }
00465             } else {
00466                 if (in_array($content, $this->__acceptTypes)) {
00467                     return true;
00468                 }
00469             }
00470         }
00471     }
00472 /**
00473  * Determines the content type of the data the client has sent (i.e. in a POST request)
00474  *
00475  * @param mixed $type Can be null (or no parameter), a string type name, or an array of types
00476  * @return mixed
00477  * @access public
00478  */
00479     function requestedWith($type = null) {
00480         if (!$this->isPost() && !$this->isPut()) {
00481             return null;
00482         }
00483 
00484         list($contentType) = explode(';', env('CONTENT_TYPE'));
00485         if ($type == null) {
00486             return $this->mapType($contentType);
00487         } elseif (is_array($type)) {
00488             foreach ($type as $t) {
00489                 if ($this->requestedWith($t)) {
00490                     return $this->mapType($t);
00491                 }
00492             }
00493             return false;
00494         } elseif (is_string($type)) {
00495             return ($type == $this->mapType($contentType));
00496         }
00497     }
00498 /**
00499  * Determines which content-types the client prefers.  If no parameters are given,
00500  * the content-type that the client most likely prefers is returned.  If $type is
00501  * an array, the first item in the array that the client accepts is returned.
00502  * Preference is determined primarily by the file extension parsed by the Router
00503  * if provided, and secondarily by the list of content-types provided in
00504  * HTTP_ACCEPT.
00505  *
00506  * @param mixed $type An optional array of 'friendly' content-type names, i.e.
00507  *   'html', 'xml', 'js', etc.
00508  * @return mixed If $type is null or not provided, the first content-type in the
00509  *    list, based on preference, is returned.
00510  * @access public
00511  * @see RequestHandlerComponent::setContent()
00512  */
00513     function prefers($type = null) {
00514         $this->__initializeTypes();
00515         $accept = $this->accepts();
00516 
00517         if ($type == null) {
00518             if (empty($this->ext)) {
00519                 if (is_array($accept)) {
00520                     return $accept[0];
00521                 }
00522                 return $accept;
00523             }
00524             return $this->ext;
00525         }
00526 
00527         $types = $type;
00528         if (is_string($type)) {
00529             $types = array($type);
00530         }
00531 
00532         if (count($types) === 1) {
00533             if (!empty($this->ext)) {
00534                 return ($types[0] == $this->ext);
00535             }
00536             return ($types[0] == $accept[0]);
00537         }
00538         $accepts = array();
00539 
00540         foreach ($types as $type) {
00541             if (in_array($type, $accept)) {
00542                 $accepts[] = $type;
00543             }
00544         }
00545 
00546         if (count($accepts) === 0) {
00547             return false;
00548         } elseif (count($types) === 1) {
00549             return ($types[0] === $accepts[0]);
00550         } elseif (count($accepts) === 1) {
00551             return $accepts[0];
00552         }
00553 
00554         $acceptedTypes = array();
00555         foreach ($this->__acceptTypes as $type) {
00556             $acceptedTypes[] = $this->mapType($type);
00557         }
00558         $accepts = array_intersect($acceptedTypes, $accepts);
00559         return $accepts[0];
00560     }
00561 /**
00562  * Sets the layout and template paths for the content type defined by $type.
00563  *
00564  * @param object $controller A reference to a controller object
00565  * @param string $type Type of response to send (e.g: 'ajax')
00566  * @return void
00567  * @access public
00568  * @see RequestHandlerComponent::setContent()
00569  * @see RequestHandlerComponent::respondAs()
00570  */
00571     function renderAs(&$controller, $type) {
00572         $this->__initializeTypes();
00573         $options = array('charset' => 'UTF-8');
00574 
00575         if (Configure::read('App.encoding') !== null) {
00576             $options = array('charset' => Configure::read('App.encoding'));
00577         }
00578 
00579         if ($type == 'ajax') {
00580             $controller->layout = $this->ajaxLayout;
00581             return $this->respondAs('html', $options);
00582         }
00583         $controller->ext = '.ctp';
00584 
00585         if (empty($this->__renderType)) {
00586             $controller->viewPath .= '/' . $type;
00587         } else {
00588             $remove = preg_replace("/(?:\/{$this->__renderType})$/", '/' . $type, $controller->viewPath);
00589             $controller->viewPath = $remove;
00590         }
00591         $this->__renderType = $type;
00592         $controller->layoutPath = $type;
00593 
00594         if (isset($this->__requestContent[$type])) {
00595             $this->respondAs($type, $options);
00596         }
00597 
00598         $helper = ucfirst($type);
00599         $isAdded = (
00600             in_array($helper, $controller->helpers) ||
00601             array_key_exists($helper, $controller->helpers)
00602         );
00603 
00604         if (!$isAdded) {
00605             if (App::import('Helper', $helper)) {
00606                 $controller->helpers[] = $helper;
00607             }
00608         }
00609     }
00610 /**
00611  * Sets the response header based on type map index name.  If DEBUG is greater than 2, the header
00612  * is not set.
00613  *
00614  * @param mixed $type Friendly type name, i.e. 'html' or 'xml', or a full content-type,
00615  *    like 'application/x-shockwave'.
00616  * @param array $options If $type is a friendly type name that is associated with
00617  *    more than one type of content, $index is used to select which content-type to use.
00618  *   
00619  * @return boolean Returns false if the friendly type name given in $type does
00620  *    not exist in the type map, or if the Content-type header has
00621  *    already been set by this method.
00622  * @access public
00623  * @see RequestHandlerComponent::setContent()
00624  */
00625     function respondAs($type, $options = array()) {
00626         $this->__initializeTypes();
00627         if ($this->__responseTypeSet != null) {
00628             return false;
00629         }
00630         if (!array_key_exists($type, $this->__requestContent) && strpos($type, '/') === false) {
00631             return false;
00632         }
00633         $defaults = array('index' => 0, 'charset' => null, 'attachment' => false);
00634         $options = array_merge($defaults, $options);
00635 
00636         if (strpos($type, '/') === false && isset($this->__requestContent[$type])) {
00637             $cType = null;
00638             if (is_array($this->__requestContent[$type]) && isset($this->__requestContent[$type][$options['index']])) {
00639                 $cType = $this->__requestContent[$type][$options['index']];
00640             } elseif (is_array($this->__requestContent[$type]) && isset($this->__requestContent[$type][0])) {
00641                 $cType = $this->__requestContent[$type][0];
00642             } elseif (isset($this->__requestContent[$type])) {
00643                 $cType = $this->__requestContent[$type];
00644             } else {
00645                 return false;
00646             }
00647 
00648             if (is_array($cType)) {
00649                 if ($this->prefers($cType)) {
00650                     $cType = $this->prefers($cType);
00651                 } else {
00652                     $cType = $cType[0];
00653                 }
00654             }
00655         } else {
00656             $cType = $type;
00657         }
00658 
00659         if ($cType != null) {
00660             $header = 'Content-type: ' . $cType;
00661 
00662             if (!empty($options['charset'])) {
00663                 $header .= '; charset=' . $options['charset'];
00664             }
00665             if (!empty($options['attachment'])) {
00666                 header("Content-Disposition: attachment; filename=\"{$options['attachment']}\"");
00667             }
00668             if (Configure::read() < 2 && !defined('CAKEPHP_SHELL')) {
00669                 @header($header);
00670             }
00671             $this->__responseTypeSet = $cType;
00672             return true;
00673         }
00674         return false;
00675     }
00676 /**
00677  * Returns the current response type (Content-type header), or null if none has been set
00678  *
00679  * @return mixed A string content type alias, or raw content type if no alias map exists,
00680  *    otherwise null
00681  * @access public
00682  */
00683     function responseType() {
00684         if ($this->__responseTypeSet == null) {
00685             return null;
00686         }
00687         return $this->mapType($this->__responseTypeSet);
00688     }
00689 /**
00690  * Maps a content-type back to an alias
00691  *
00692  * @param mixed $type Content type
00693  * @return mixed Alias
00694  * @access public
00695  */
00696     function mapType($ctype) {
00697         if (is_array($ctype)) {
00698             $out = array();
00699             foreach ($ctype as $t) {
00700                 $out[] = $this->mapType($t);
00701             }
00702             return $out;
00703         } else {
00704             $keys = array_keys($this->__requestContent);
00705             $count = count($keys);
00706 
00707             for ($i = 0; $i < $count; $i++) {
00708                 $name = $keys[$i];
00709                 $type = $this->__requestContent[$name];
00710 
00711                 if (is_array($type) && in_array($ctype, $type)) {
00712                     return $name;
00713                 } elseif (!is_array($type) && $type == $ctype) {
00714                     return $name;
00715                 }
00716             }
00717             return $ctype;
00718         }
00719     }
00720 /**
00721  * Initializes MIME types
00722  *
00723  * @return void
00724  * @access private
00725  */
00726     function __initializeTypes() {
00727         if ($this->__typesInitialized) {
00728             return;
00729         }
00730         if (isset($this->__requestContent[$this->ext])) {
00731             $content = $this->__requestContent[$this->ext];
00732             if (is_array($content)) {
00733                 $content = $content[0];
00734             }
00735             array_unshift($this->__acceptTypes, $content);
00736         }
00737         $this->__typesInitialized = true;
00738     }
00739 }
00740 
00741 ?>

Generated on Sun Nov 22 00:30:53 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7