00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00034
00035
00036
00037
00038
00039 class RequestHandlerComponent extends Object {
00040
00041
00042
00043
00044
00045
00046
00047 var $ajaxLayout = 'ajax';
00048
00049
00050
00051
00052
00053
00054 var $enabled = true;
00055
00056
00057
00058
00059
00060
00061
00062 var $__responseTypeSet = null;
00063
00064
00065
00066
00067
00068
00069 var $params = array();
00070
00071
00072
00073
00074
00075
00076
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
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 var $__acceptTypes = array();
00117
00118
00119
00120
00121
00122
00123 var $__renderType = null;
00124
00125
00126
00127
00128
00129
00130
00131 var $ext = null;
00132
00133
00134
00135
00136
00137
00138
00139 var $__typesInitialized = false;
00140
00141
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
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 function initialize(&$controller) {
00167 if (isset($controller->params['url']['ext'])) {
00168 $this->ext = $controller->params['url']['ext'];
00169 }
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
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
00222
00223
00224
00225
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
00239
00240
00241
00242
00243 function isAjax() {
00244 return env('HTTP_X_REQUESTED_WITH') === "XMLHttpRequest";
00245 }
00246
00247
00248
00249
00250
00251
00252 function isFlash() {
00253 return (preg_match('/^(Shockwave|Adobe) Flash/', env('HTTP_USER_AGENT')) == 1);
00254 }
00255
00256
00257
00258
00259
00260
00261 function isSSL() {
00262 return env('HTTPS');
00263 }
00264
00265
00266
00267
00268
00269
00270 function isXml() {
00271 return $this->prefers('xml');
00272 }
00273
00274
00275
00276
00277
00278
00279 function isRss() {
00280 return $this->prefers('rss');
00281 }
00282
00283
00284
00285
00286
00287
00288 function isAtom() {
00289 return $this->prefers('atom');
00290 }
00291
00292
00293
00294
00295
00296
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
00307
00308
00309
00310
00311 function isWap() {
00312 return $this->prefers('wap');
00313 }
00314
00315
00316
00317
00318
00319
00320 function isPost() {
00321 return (strtolower(env('REQUEST_METHOD')) == 'post');
00322 }
00323
00324
00325
00326
00327
00328
00329 function isPut() {
00330 return (strtolower(env('REQUEST_METHOD')) == 'put');
00331 }
00332
00333
00334
00335
00336
00337
00338 function isGet() {
00339 return (strtolower(env('REQUEST_METHOD')) == 'get');
00340 }
00341
00342
00343
00344
00345
00346
00347 function isDelete() {
00348 return (strtolower(env('REQUEST_METHOD')) == 'delete');
00349 }
00350
00351
00352
00353
00354
00355
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
00365
00366
00367
00368
00369
00370
00371
00372
00373
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
00384
00385
00386
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
00400
00401
00402
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
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
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
00474
00475
00476
00477
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
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
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
00563
00564
00565
00566
00567
00568
00569
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
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
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
00678
00679
00680
00681
00682
00683 function responseType() {
00684 if ($this->__responseTypeSet == null) {
00685 return null;
00686 }
00687 return $this->mapType($this->__responseTypeSet);
00688 }
00689
00690
00691
00692
00693
00694
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
00722
00723
00724
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 ?>