|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2008-2011 Benjamin Mack <mack@xnos.org> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 00028 /** 00029 * class to hold all the information about an AJAX call and send 00030 * the right headers for the request type 00031 * 00032 * @author Benjamin Mack <mack@xnos.org> 00033 * @package TYPO3 00034 * @subpackage core 00035 */ 00036 class TYPO3AJAX { 00037 protected $ajaxId = null; 00038 protected $errorMessage = null; 00039 protected $isError = false; 00040 protected $content = array(); 00041 protected $contentFormat = 'plain'; 00042 protected $charset = 'utf-8'; 00043 protected $requestCharset = 'utf-8'; 00044 protected $javascriptCallbackWrap = ' 00045 <script type="text/javascript"> 00046 /*<![CDATA[*/ 00047 response = |; 00048 /*]]>*/ 00049 </script> 00050 '; 00051 00052 /** 00053 * sets the charset and the ID for the AJAX call 00054 * due some charset limitations in Javascript (prototype uses encodeURIcomponent, which converts 00055 * all data to utf-8), we need to detect if the encoding of the request differs from the 00056 * backend encoding (e.g. forceCharset), and then convert all incoming data (_GET and _POST) 00057 * in the expected backend encoding. 00058 * 00059 * @param string the AJAX id 00060 * @return void 00061 */ 00062 public function __construct($ajaxId) { 00063 00064 if ($GLOBALS['LANG']->charSet != $this->charset) { 00065 $this->charset = $GLOBALS['LANG']->charSet; 00066 } 00067 00068 // get charset from current AJAX request (which is expected to be utf-8) 00069 preg_match('/;\s*charset\s*=\s*([a-zA-Z0-9_-]*)/i', $_SERVER['CONTENT_TYPE'], $contenttype); 00070 $charset = $GLOBALS['LANG']->csConvObj->parse_charset($contenttype[1]); 00071 if ($charset && $charset != $this->requestCharset) { 00072 $this->requestCharset = $charset; 00073 } 00074 00075 // if the AJAX request does not have the same encoding like the backend 00076 // we need to convert the POST and GET parameters in the right charset 00077 if ($this->charset != $this->requestCharset) { 00078 $GLOBALS['LANG']->csConvObj->convArray($_POST, $this->requestCharset, $this->charset); 00079 $GLOBALS['LANG']->csConvObj->convArray($_GET, $this->requestCharset, $this->charset); 00080 } 00081 00082 $this->ajaxId = $ajaxId; 00083 } 00084 00085 00086 /** 00087 * returns the ID for the AJAX call 00088 * 00089 * @return string the AJAX id 00090 */ 00091 public function getAjaxID() { 00092 return $this->ajaxId; 00093 } 00094 00095 00096 /** 00097 * overwrites the existing content with the first parameter 00098 * 00099 * @param array the new content 00100 * @return mixed the old content as array; if the new content was not an array, false is returned 00101 */ 00102 public function setContent($content) { 00103 $oldcontent = false; 00104 if (is_array($content)) { 00105 $oldcontent = $this->content; 00106 $this->content = $content; 00107 } 00108 return $oldcontent; 00109 } 00110 00111 00112 /** 00113 * adds new content 00114 * 00115 * @param string the new content key where the content should be added in the content array 00116 * @param string the new content to add 00117 * @return mixed the old content; if the old content didn't exist before, false is returned 00118 */ 00119 public function addContent($key, $content) { 00120 $oldcontent = false; 00121 if (array_key_exists($key, $this->content)) { 00122 $oldcontent = $this->content[$key]; 00123 } 00124 if (!isset($content) || empty($content)) { 00125 unset($this->content[$key]); 00126 } elseif (!isset($key) || empty($key)) { 00127 $this->content[] = $content; 00128 } else { 00129 $this->content[$key] = $content; 00130 } 00131 return $oldcontent; 00132 } 00133 00134 00135 /** 00136 * returns the content for the ajax call 00137 * 00138 * @return mixed the content for a specific key or the whole content 00139 */ 00140 public function getContent($key = '') { 00141 return ($key && array_key_exists($key, $this->content) ? $this->content[$key] : $this->content); 00142 } 00143 00144 00145 /** 00146 * sets the content format for the ajax call 00147 * 00148 * @param string can be one of 'plain' (default), 'xml', 'json', 'javascript', 'jsonbody' or 'jsonhead' 00149 * @return void 00150 */ 00151 public function setContentFormat($format) { 00152 if (t3lib_div::inArray(array('plain', 'xml', 'json', 'jsonhead', 'jsonbody', 'javascript'), $format)) { 00153 $this->contentFormat = $format; 00154 } 00155 } 00156 00157 /** 00158 * Specifies the wrap to be used if contentFormat is "javascript". 00159 * The wrap used by default stores the results in a variable "response" and 00160 * adds <script>-Tags around it. 00161 * 00162 * @param string $javascriptCallbackWrap the javascript callback wrap to be used 00163 * @return void 00164 */ 00165 public function setJavascriptCallbackWrap($javascriptCallbackWrap) { 00166 $this->javascriptCallbackWrap = $javascriptCallbackWrap; 00167 } 00168 00169 /** 00170 * sets an error message and the error flag 00171 * 00172 * @param string the error message 00173 * @return void 00174 */ 00175 public function setError($errorMsg = '') { 00176 $this->errorMessage = $errorMsg; 00177 $this->isError = true; 00178 } 00179 00180 00181 /** 00182 * checks whether an error occured during the execution or not 00183 * 00184 * @return boolean whether this AJAX call had errors 00185 */ 00186 public function isError() { 00187 return $this->isError; 00188 } 00189 00190 00191 /** 00192 * renders the AJAX call based on the $contentFormat variable and exits the request 00193 * 00194 * @return void 00195 */ 00196 public function render() { 00197 if ($this->isError) { 00198 $this->renderAsError(); 00199 exit; 00200 } 00201 switch ($this->contentFormat) { 00202 case 'jsonhead': 00203 case 'jsonbody': 00204 case 'json': 00205 $this->renderAsJSON(); 00206 break; 00207 case 'javascript': 00208 $this->renderAsJavascript(); 00209 break; 00210 case 'xml': 00211 $this->renderAsXML(); 00212 break; 00213 default: 00214 $this->renderAsPlain(); 00215 } 00216 exit; 00217 } 00218 00219 00220 /** 00221 * renders the AJAX call in XML error style to handle with JS 00222 * the "responseXML" of the transport object will be filled with the error message then 00223 * 00224 * @return void 00225 */ 00226 protected function renderAsError() { 00227 header(t3lib_utility_Http::HTTP_STATUS_500 . ' (AJAX)'); 00228 header('Content-type: text/xml; charset='.$this->charset); 00229 header('X-JSON: false'); 00230 die('<t3err>'.htmlspecialchars($this->errorMessage).'</t3err>'); 00231 } 00232 00233 00234 /** 00235 * renders the AJAX call with text/html headers 00236 * the content will be available in the "responseText" value of the transport object 00237 * 00238 * @return void 00239 */ 00240 protected function renderAsPlain() { 00241 header('Content-type: text/html; charset='.$this->charset); 00242 header('X-JSON: true'); 00243 echo implode('', $this->content); 00244 } 00245 00246 00247 /** 00248 * renders the AJAX call with text/xml headers 00249 * the content will be available in the "responseXML" value of the transport object 00250 * 00251 * @return void 00252 */ 00253 protected function renderAsXML() { 00254 header('Content-type: text/xml; charset='.$this->charset); 00255 header('X-JSON: true'); 00256 echo implode('', $this->content); 00257 } 00258 00259 00260 /** 00261 * renders the AJAX call with JSON evaluated headers 00262 * note that you need to have requestHeaders: {Accept: 'application/json'}, 00263 * in your AJAX options of your AJAX request object in JS 00264 * 00265 * the content will be available 00266 * - in the second parameter of the onSuccess / onComplete callback (except when contentFormat = 'jsonbody') 00267 * - and in the xhr.responseText as a string (except when contentFormat = 'jsonhead') 00268 * you can evaluate this in JS with xhr.responseText.evalJSON(); 00269 * 00270 * @return void 00271 */ 00272 protected function renderAsJSON() { 00273 // if the backend does not run in UTF-8 then we need to convert it to unicode as 00274 // the json_encode method will return empty otherwise 00275 if ($this->charset != $this->requestCharset) { 00276 $GLOBALS['LANG']->csConvObj->convArray($this->content, $this->charset, $this->requestCharset); 00277 } 00278 00279 $content = json_encode($this->content); 00280 00281 header('Content-type: application/json; charset='.$this->requestCharset); 00282 header('X-JSON: '.($this->contentFormat != 'jsonbody' ? $content : true)); 00283 00284 // bring content in xhr.responseText except when in "json head only" mode 00285 if ($this->contentFormat != 'jsonhead') { 00286 echo $content; 00287 } 00288 } 00289 00290 /** 00291 * Renders the AJAX call as inline JSON inside a script tag. This is useful 00292 * when an iframe is used as the AJAX transport. 00293 * 00294 * @return void 00295 */ 00296 protected function renderAsJavascript() { 00297 // if the backend does not run in UTF-8 then we need to convert it to unicode as 00298 // the json_encode method will return empty otherwise 00299 if ($this->charset != $this->requestCharset) { 00300 $GLOBALS['LANG']->csConvObj->convArray($this->content, $this->charset, $this->requestCharset); 00301 } 00302 00303 $content = str_replace('|', json_encode($this->content), $this->javascriptCallbackWrap); 00304 00305 header('Content-type: text/html; charset=' . $this->requestCharset); 00306 echo $content; 00307 } 00308 } 00309 00310 00311 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3ajax.php'])) { 00312 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3ajax.php']); 00313 } 00314 00315 ?>
1.8.0