1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Symfony\Component\HttpFoundation;
13:
14: use Symfony\Component\HttpFoundation\Session\SessionInterface;
15:
16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
31: class Request
32: {
33: const = 'client_ip';
34: const = 'client_host';
35: const = 'client_proto';
36: const = 'client_port';
37:
38: protected static $trustProxy = false;
39:
40: protected static $trustedProxies = array();
41:
42: 43: 44: 45: 46: 47: 48:
49: protected static = array(
50: self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
51: self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
52: self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
53: self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
54: );
55:
56: protected static $httpMethodParameterOverride = false;
57:
58: 59: 60: 61: 62:
63: public $attributes;
64:
65: 66: 67: 68: 69:
70: public $request;
71:
72: 73: 74: 75: 76:
77: public $query;
78:
79: 80: 81: 82: 83:
84: public $server;
85:
86: 87: 88: 89: 90:
91: public $files;
92:
93: 94: 95: 96: 97:
98: public $cookies;
99:
100: 101: 102: 103: 104:
105: public ;
106:
107: 108: 109:
110: protected $content;
111:
112: 113: 114:
115: protected $languages;
116:
117: 118: 119:
120: protected $charsets;
121:
122: 123: 124:
125: protected $acceptableContentTypes;
126:
127: 128: 129:
130: protected $pathInfo;
131:
132: 133: 134:
135: protected $requestUri;
136:
137: 138: 139:
140: protected $baseUrl;
141:
142: 143: 144:
145: protected $basePath;
146:
147: 148: 149:
150: protected $method;
151:
152: 153: 154:
155: protected $format;
156:
157: 158: 159:
160: protected $session;
161:
162: 163: 164:
165: protected $locale;
166:
167: 168: 169:
170: protected $defaultLocale = 'en';
171:
172: 173: 174:
175: protected static $formats;
176:
177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189:
190: public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
191: {
192: $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
193: }
194:
195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209:
210: public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
211: {
212: $this->request = new ParameterBag($request);
213: $this->query = new ParameterBag($query);
214: $this->attributes = new ParameterBag($attributes);
215: $this->cookies = new ParameterBag($cookies);
216: $this->files = new FileBag($files);
217: $this->server = new ServerBag($server);
218: $this->headers = new HeaderBag($this->server->getHeaders());
219:
220: $this->content = $content;
221: $this->languages = null;
222: $this->charsets = null;
223: $this->acceptableContentTypes = null;
224: $this->pathInfo = null;
225: $this->requestUri = null;
226: $this->baseUrl = null;
227: $this->basePath = null;
228: $this->method = null;
229: $this->format = null;
230: }
231:
232: 233: 234: 235: 236: 237: 238:
239: public static function createFromGlobals()
240: {
241: $request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
242:
243: if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
244: && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))
245: ) {
246: parse_str($request->getContent(), $data);
247: $request->request = new ParameterBag($data);
248: }
249:
250: return $request;
251: }
252:
253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270:
271: public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
272: {
273: $server = array_replace(array(
274: 'SERVER_NAME' => 'localhost',
275: 'SERVER_PORT' => 80,
276: 'HTTP_HOST' => 'localhost',
277: 'HTTP_USER_AGENT' => 'Symfony/2.X',
278: 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
279: 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
280: 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
281: 'REMOTE_ADDR' => '127.0.0.1',
282: 'SCRIPT_NAME' => '',
283: 'SCRIPT_FILENAME' => '',
284: 'SERVER_PROTOCOL' => 'HTTP/1.1',
285: 'REQUEST_TIME' => time(),
286: ), $server);
287:
288: $server['PATH_INFO'] = '';
289: $server['REQUEST_METHOD'] = strtoupper($method);
290:
291: $components = parse_url($uri);
292: if (isset($components['host'])) {
293: $server['SERVER_NAME'] = $components['host'];
294: $server['HTTP_HOST'] = $components['host'];
295: }
296:
297: if (isset($components['scheme'])) {
298: if ('https' === $components['scheme']) {
299: $server['HTTPS'] = 'on';
300: $server['SERVER_PORT'] = 443;
301: } else {
302: unset($server['HTTPS']);
303: $server['SERVER_PORT'] = 80;
304: }
305: }
306:
307: if (isset($components['port'])) {
308: $server['SERVER_PORT'] = $components['port'];
309: $server['HTTP_HOST'] = $server['HTTP_HOST'].':'.$components['port'];
310: }
311:
312: if (isset($components['user'])) {
313: $server['PHP_AUTH_USER'] = $components['user'];
314: }
315:
316: if (isset($components['pass'])) {
317: $server['PHP_AUTH_PW'] = $components['pass'];
318: }
319:
320: if (!isset($components['path'])) {
321: $components['path'] = '/';
322: }
323:
324: switch (strtoupper($method)) {
325: case 'POST':
326: case 'PUT':
327: case 'DELETE':
328: if (!isset($server['CONTENT_TYPE'])) {
329: $server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
330: }
331: case 'PATCH':
332: $request = $parameters;
333: $query = array();
334: break;
335: default:
336: $request = array();
337: $query = $parameters;
338: break;
339: }
340:
341: if (isset($components['query'])) {
342: parse_str(html_entity_decode($components['query']), $qs);
343: $query = array_replace($qs, $query);
344: }
345: $queryString = http_build_query($query, '', '&');
346:
347: $server['REQUEST_URI'] = $components['path'].('' !== $queryString ? '?'.$queryString : '');
348: $server['QUERY_STRING'] = $queryString;
349:
350: return new static($query, $request, array(), $cookies, $files, $server, $content);
351: }
352:
353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366:
367: public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
368: {
369: $dup = clone $this;
370: if ($query !== null) {
371: $dup->query = new ParameterBag($query);
372: }
373: if ($request !== null) {
374: $dup->request = new ParameterBag($request);
375: }
376: if ($attributes !== null) {
377: $dup->attributes = new ParameterBag($attributes);
378: }
379: if ($cookies !== null) {
380: $dup->cookies = new ParameterBag($cookies);
381: }
382: if ($files !== null) {
383: $dup->files = new FileBag($files);
384: }
385: if ($server !== null) {
386: $dup->server = new ServerBag($server);
387: $dup->headers = new HeaderBag($dup->server->getHeaders());
388: }
389: $dup->languages = null;
390: $dup->charsets = null;
391: $dup->acceptableContentTypes = null;
392: $dup->pathInfo = null;
393: $dup->requestUri = null;
394: $dup->baseUrl = null;
395: $dup->basePath = null;
396: $dup->method = null;
397: $dup->format = null;
398:
399: return $dup;
400: }
401:
402: 403: 404: 405: 406: 407:
408: public function __clone()
409: {
410: $this->query = clone $this->query;
411: $this->request = clone $this->request;
412: $this->attributes = clone $this->attributes;
413: $this->cookies = clone $this->cookies;
414: $this->files = clone $this->files;
415: $this->server = clone $this->server;
416: $this->headers = clone $this->headers;
417: }
418:
419: 420: 421: 422: 423:
424: public function __toString()
425: {
426: return
427: sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
428: $this->headers."\r\n".
429: $this->getContent();
430: }
431:
432: 433: 434: 435: 436: 437: 438: 439:
440: public function overrideGlobals()
441: {
442: $_GET = $this->query->all();
443: $_POST = $this->request->all();
444: $_SERVER = $this->server->all();
445: $_COOKIE = $this->cookies->all();
446:
447: foreach ($this->headers->all() as $key => $value) {
448: $key = strtoupper(str_replace('-', '_', $key));
449: if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) {
450: $_SERVER[$key] = implode(', ', $value);
451: } else {
452: $_SERVER['HTTP_'.$key] = implode(', ', $value);
453: }
454: }
455:
456: $request = array('g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE);
457:
458: $requestOrder = ini_get('request_order') ?: ini_get('variable_order');
459: $requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';
460:
461: $_REQUEST = array();
462: foreach (str_split($requestOrder) as $order) {
463: $_REQUEST = array_merge($_REQUEST, $request[$order]);
464: }
465: }
466:
467: 468: 469: 470: 471:
472: public static function trustProxyData()
473: {
474: trigger_error('trustProxyData() is deprecated since version 2.0 and will be removed in 2.3. Use setTrustedProxies() instead.', E_USER_DEPRECATED);
475:
476: self::$trustProxy = true;
477: }
478:
479: 480: 481: 482: 483: 484: 485: 486: 487:
488: public static function setTrustedProxies(array $proxies)
489: {
490: self::$trustedProxies = $proxies;
491: self::$trustProxy = $proxies ? true : false;
492: }
493:
494: 495: 496: 497: 498:
499: public static function getTrustedProxies()
500: {
501: return self::$trustedProxies;
502: }
503:
504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520:
521: public static function ($key, $value)
522: {
523: if (!array_key_exists($key, self::$trustedHeaders)) {
524: throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key));
525: }
526:
527: self::$trustedHeaders[$key] = $value;
528: }
529:
530: 531: 532: 533: 534: 535: 536: 537:
538: public static function isProxyTrusted()
539: {
540: return self::$trustProxy;
541: }
542:
543: 544: 545: 546: 547: 548: 549: 550: 551: 552:
553: public static function normalizeQueryString($qs)
554: {
555: if ('' == $qs) {
556: return '';
557: }
558:
559: $parts = array();
560: $order = array();
561:
562: foreach (explode('&', $qs) as $param) {
563: if ('' === $param || '=' === $param[0]) {
564:
565:
566:
567: continue;
568: }
569:
570: $keyValuePair = explode('=', $param, 2);
571:
572:
573:
574:
575: $parts[] = isset($keyValuePair[1]) ?
576: rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) :
577: rawurlencode(urldecode($keyValuePair[0]));
578: $order[] = urldecode($keyValuePair[0]);
579: }
580:
581: array_multisort($order, SORT_ASC, $parts);
582:
583: return implode('&', $parts);
584: }
585:
586: 587: 588: 589: 590: 591: 592: 593:
594: public static function enableHttpMethodParameterOverride()
595: {
596: self::$httpMethodParameterOverride = true;
597: }
598:
599: 600: 601: 602: 603:
604: public static function getHttpMethodParameterOverride()
605: {
606: return self::$httpMethodParameterOverride;
607: }
608:
609: 610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623: 624: 625: 626: 627: 628: 629:
630: public function get($key, $default = null, $deep = false)
631: {
632: return $this->query->get($key, $this->attributes->get($key, $this->request->get($key, $default, $deep), $deep), $deep);
633: }
634:
635: 636: 637: 638: 639: 640: 641:
642: public function getSession()
643: {
644: return $this->session;
645: }
646:
647: 648: 649: 650: 651: 652: 653: 654:
655: public function hasPreviousSession()
656: {
657:
658: return $this->hasSession() && $this->cookies->has($this->session->getName());
659: }
660:
661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671:
672: public function hasSession()
673: {
674: return null !== $this->session;
675: }
676:
677: 678: 679: 680: 681: 682: 683:
684: public function setSession(SessionInterface $session)
685: {
686: $this->session = $session;
687: }
688:
689: 690: 691: 692: 693: 694: 695: 696: 697: 698: 699: 700: 701: 702: 703: 704: 705: 706: 707:
708: public function getClientIp()
709: {
710: $ip = $this->server->get('REMOTE_ADDR');
711:
712: if (!self::$trustProxy) {
713: return $ip;
714: }
715:
716: if (!self::$trustedHeaders[self::HEADER_CLIENT_IP] || !$this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
717: return $ip;
718: }
719:
720: $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
721: $clientIps[] = $ip;
722:
723: $trustedProxies = self::$trustProxy && !self::$trustedProxies ? array($ip) : self::$trustedProxies;
724: $clientIps = array_diff($clientIps, $trustedProxies);
725:
726: return array_pop($clientIps);
727: }
728:
729: 730: 731: 732: 733: 734: 735:
736: public function getScriptName()
737: {
738: return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', ''));
739: }
740:
741: 742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755: 756:
757: public function getPathInfo()
758: {
759: if (null === $this->pathInfo) {
760: $this->pathInfo = $this->preparePathInfo();
761: }
762:
763: return $this->pathInfo;
764: }
765:
766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776: 777: 778: 779:
780: public function getBasePath()
781: {
782: if (null === $this->basePath) {
783: $this->basePath = $this->prepareBasePath();
784: }
785:
786: return $this->basePath;
787: }
788:
789: 790: 791: 792: 793: 794: 795: 796: 797: 798: 799: 800:
801: public function getBaseUrl()
802: {
803: if (null === $this->baseUrl) {
804: $this->baseUrl = $this->prepareBaseUrl();
805: }
806:
807: return $this->baseUrl;
808: }
809:
810: 811: 812: 813: 814: 815: 816:
817: public function getScheme()
818: {
819: return $this->isSecure() ? 'https' : 'http';
820: }
821:
822: 823: 824: 825: 826: 827: 828: 829: 830: 831: 832: 833: 834: 835: 836:
837: public function getPort()
838: {
839: if (self::$trustProxy && self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) {
840: return $port;
841: }
842:
843: return $this->server->get('SERVER_PORT');
844: }
845:
846: 847: 848: 849: 850:
851: public function getUser()
852: {
853: return $this->server->get('PHP_AUTH_USER');
854: }
855:
856: 857: 858: 859: 860:
861: public function getPassword()
862: {
863: return $this->server->get('PHP_AUTH_PW');
864: }
865:
866: 867: 868: 869: 870:
871: public function getUserInfo()
872: {
873: $userinfo = $this->getUser();
874:
875: $pass = $this->getPassword();
876: if ('' != $pass) {
877: $userinfo .= ":$pass";
878: }
879:
880: return $userinfo;
881: }
882:
883: 884: 885: 886: 887: 888: 889: 890: 891:
892: public function getHttpHost()
893: {
894: $scheme = $this->getScheme();
895: $port = $this->getPort();
896:
897: if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) {
898: return $this->getHost();
899: }
900:
901: return $this->getHost().':'.$port;
902: }
903:
904: 905: 906: 907: 908: 909: 910:
911: public function getRequestUri()
912: {
913: if (null === $this->requestUri) {
914: $this->requestUri = $this->prepareRequestUri();
915: }
916:
917: return $this->requestUri;
918: }
919:
920: 921: 922: 923: 924: 925: 926: 927:
928: public function getSchemeAndHttpHost()
929: {
930: return $this->getScheme().'://'.$this->getHttpHost();
931: }
932:
933: 934: 935: 936: 937: 938: 939: 940: 941:
942: public function getUri()
943: {
944: if (null !== $qs = $this->getQueryString()) {
945: $qs = '?'.$qs;
946: }
947:
948: return $this->getSchemeAndHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs;
949: }
950:
951: 952: 953: 954: 955: 956: 957: 958: 959:
960: public function getUriForPath($path)
961: {
962: return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path;
963: }
964:
965: 966: 967: 968: 969: 970: 971: 972: 973: 974:
975: public function getQueryString()
976: {
977: $qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));
978:
979: return '' === $qs ? null : $qs;
980: }
981:
982: 983: 984: 985: 986: 987: 988: 989: 990: 991: 992: 993: 994: 995: 996: 997:
998: public function isSecure()
999: {
1000: if (self::$trustProxy && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) {
1001: return in_array(strtolower($proto), array('https', 'on', '1'));
1002: }
1003:
1004: return 'on' == strtolower($this->server->get('HTTPS')) || 1 == $this->server->get('HTTPS');
1005: }
1006:
1007: 1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 1020: 1021: 1022: 1023:
1024: public function getHost()
1025: {
1026: if (self::$trustProxy && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) {
1027: $elements = explode(',', $host);
1028:
1029: $host = $elements[count($elements) - 1];
1030: } elseif (!$host = $this->headers->get('HOST')) {
1031: if (!$host = $this->server->get('SERVER_NAME')) {
1032: $host = $this->server->get('SERVER_ADDR', '');
1033: }
1034: }
1035:
1036:
1037:
1038: $host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
1039:
1040:
1041:
1042: if ($host && !preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host)) {
1043: throw new \UnexpectedValueException('Invalid Host');
1044: }
1045:
1046: return $host;
1047: }
1048:
1049: 1050: 1051: 1052: 1053: 1054: 1055:
1056: public function setMethod($method)
1057: {
1058: $this->method = null;
1059: $this->server->set('REQUEST_METHOD', $method);
1060: }
1061:
1062: 1063: 1064: 1065: 1066: 1067: 1068: 1069: 1070: 1071: 1072: 1073: 1074: 1075: 1076: 1077: 1078:
1079: public function getMethod()
1080: {
1081: if (null === $this->method) {
1082: $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
1083:
1084: if ('POST' === $this->method) {
1085: if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
1086: $this->method = strtoupper($method);
1087: } elseif (self::$httpMethodParameterOverride) {
1088: $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
1089: }
1090: }
1091: }
1092:
1093: return $this->method;
1094: }
1095:
1096: 1097: 1098: 1099: 1100: 1101: 1102:
1103: public function getRealMethod()
1104: {
1105: return strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
1106: }
1107:
1108: 1109: 1110: 1111: 1112: 1113: 1114: 1115: 1116:
1117: public function getMimeType($format)
1118: {
1119: if (null === static::$formats) {
1120: static::initializeFormats();
1121: }
1122:
1123: return isset(static::$formats[$format]) ? static::$formats[$format][0] : null;
1124: }
1125:
1126: 1127: 1128: 1129: 1130: 1131: 1132: 1133: 1134:
1135: public function getFormat($mimeType)
1136: {
1137: if (false !== $pos = strpos($mimeType, ';')) {
1138: $mimeType = substr($mimeType, 0, $pos);
1139: }
1140:
1141: if (null === static::$formats) {
1142: static::initializeFormats();
1143: }
1144:
1145: foreach (static::$formats as $format => $mimeTypes) {
1146: if (in_array($mimeType, (array) $mimeTypes)) {
1147: return $format;
1148: }
1149: }
1150:
1151: return null;
1152: }
1153:
1154: 1155: 1156: 1157: 1158: 1159: 1160: 1161:
1162: public function setFormat($format, $mimeTypes)
1163: {
1164: if (null === static::$formats) {
1165: static::initializeFormats();
1166: }
1167:
1168: static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes);
1169: }
1170:
1171: 1172: 1173: 1174: 1175: 1176: 1177: 1178: 1179: 1180: 1181: 1182: 1183: 1184: 1185:
1186: public function getRequestFormat($default = 'html')
1187: {
1188: if (null === $this->format) {
1189: $this->format = $this->get('_format', $default);
1190: }
1191:
1192: return $this->format;
1193: }
1194:
1195: 1196: 1197: 1198: 1199: 1200: 1201:
1202: public function setRequestFormat($format)
1203: {
1204: $this->format = $format;
1205: }
1206:
1207: 1208: 1209: 1210: 1211: 1212: 1213:
1214: public function getContentType()
1215: {
1216: return $this->getFormat($this->headers->get('CONTENT_TYPE'));
1217: }
1218:
1219: 1220: 1221: 1222: 1223: 1224: 1225:
1226: public function setDefaultLocale($locale)
1227: {
1228: $this->defaultLocale = $locale;
1229:
1230: if (null === $this->locale) {
1231: $this->setPhpDefaultLocale($locale);
1232: }
1233: }
1234:
1235: 1236: 1237: 1238: 1239: 1240: 1241:
1242: public function setLocale($locale)
1243: {
1244: $this->setPhpDefaultLocale($this->locale = $locale);
1245: }
1246:
1247: 1248: 1249: 1250: 1251:
1252: public function getLocale()
1253: {
1254: return null === $this->locale ? $this->defaultLocale : $this->locale;
1255: }
1256:
1257: 1258: 1259: 1260: 1261: 1262: 1263:
1264: public function isMethod($method)
1265: {
1266: return $this->getMethod() === strtoupper($method);
1267: }
1268:
1269: 1270: 1271: 1272: 1273: 1274: 1275:
1276: public function isMethodSafe()
1277: {
1278: return in_array($this->getMethod(), array('GET', 'HEAD'));
1279: }
1280:
1281: 1282: 1283: 1284: 1285: 1286: 1287: 1288: 1289:
1290: public function getContent($asResource = false)
1291: {
1292: if (false === $this->content || (true === $asResource && null !== $this->content)) {
1293: throw new \LogicException('getContent() can only be called once when using the resource return type.');
1294: }
1295:
1296: if (true === $asResource) {
1297: $this->content = false;
1298:
1299: return fopen('php://input', 'rb');
1300: }
1301:
1302: if (null === $this->content) {
1303: $this->content = file_get_contents('php://input');
1304: }
1305:
1306: return $this->content;
1307: }
1308:
1309: 1310: 1311: 1312: 1313:
1314: public function getETags()
1315: {
1316: return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
1317: }
1318:
1319: 1320: 1321:
1322: public function isNoCache()
1323: {
1324: return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
1325: }
1326:
1327: 1328: 1329: 1330: 1331: 1332: 1333: 1334: 1335:
1336: public function getPreferredLanguage(array $locales = null)
1337: {
1338: $preferredLanguages = $this->getLanguages();
1339:
1340: if (empty($locales)) {
1341: return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null;
1342: }
1343:
1344: if (!$preferredLanguages) {
1345: return $locales[0];
1346: }
1347:
1348: $extendedPreferredLanguages = array();
1349: foreach ($preferredLanguages as $language) {
1350: $extendedPreferredLanguages[] = $language;
1351: if (false !== $position = strpos($language, '_')) {
1352: $superLanguage = substr($language, 0, $position);
1353: if (!in_array($superLanguage, $preferredLanguages)) {
1354: $extendedPreferredLanguages[] = $superLanguage;
1355: }
1356: }
1357: }
1358:
1359: $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));
1360:
1361: return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0];
1362: }
1363:
1364: 1365: 1366: 1367: 1368: 1369: 1370:
1371: public function getLanguages()
1372: {
1373: if (null !== $this->languages) {
1374: return $this->languages;
1375: }
1376:
1377: $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all();
1378: $this->languages = array();
1379: foreach (array_keys($languages) as $lang) {
1380: if (strstr($lang, '-')) {
1381: $codes = explode('-', $lang);
1382: if ($codes[0] == 'i') {
1383:
1384:
1385:
1386: if (count($codes) > 1) {
1387: $lang = $codes[1];
1388: }
1389: } else {
1390: for ($i = 0, $max = count($codes); $i < $max; $i++) {
1391: if ($i == 0) {
1392: $lang = strtolower($codes[0]);
1393: } else {
1394: $lang .= '_'.strtoupper($codes[$i]);
1395: }
1396: }
1397: }
1398: }
1399:
1400: $this->languages[] = $lang;
1401: }
1402:
1403: return $this->languages;
1404: }
1405:
1406: 1407: 1408: 1409: 1410: 1411: 1412:
1413: public function getCharsets()
1414: {
1415: if (null !== $this->charsets) {
1416: return $this->charsets;
1417: }
1418:
1419: return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all());
1420: }
1421:
1422: 1423: 1424: 1425: 1426: 1427: 1428:
1429: public function getAcceptableContentTypes()
1430: {
1431: if (null !== $this->acceptableContentTypes) {
1432: return $this->acceptableContentTypes;
1433: }
1434:
1435: return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all());
1436: }
1437:
1438: 1439: 1440: 1441: 1442: 1443: 1444: 1445: 1446: 1447: 1448:
1449: public function isXmlHttpRequest()
1450: {
1451: return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
1452: }
1453:
1454: 1455: 1456: 1457: 1458: 1459: 1460: 1461: 1462:
1463: public function ($header)
1464: {
1465: trigger_error('splitHttpAcceptHeader() is deprecated since version 2.2 and will be removed in 2.3.', E_USER_DEPRECATED);
1466:
1467: $headers = array();
1468: foreach (AcceptHeader::fromString($header)->all() as $item) {
1469: $key = $item->getValue();
1470: foreach ($item->getAttributes() as $name => $value) {
1471: $key .= sprintf(';%s=%s', $name, $value);
1472: }
1473: $headers[$key] = $item->getQuality();
1474: }
1475:
1476: return $headers;
1477: }
1478:
1479: 1480: 1481: 1482: 1483: 1484: 1485:
1486:
1487: protected function prepareRequestUri()
1488: {
1489: $requestUri = '';
1490:
1491: if ($this->headers->has('X_ORIGINAL_URL') && false !== stripos(PHP_OS, 'WIN')) {
1492:
1493: $requestUri = $this->headers->get('X_ORIGINAL_URL');
1494: $this->headers->remove('X_ORIGINAL_URL');
1495: } elseif ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) {
1496:
1497: $requestUri = $this->headers->get('X_REWRITE_URL');
1498: $this->headers->remove('X_REWRITE_URL');
1499: } elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
1500:
1501: $requestUri = $this->server->get('UNENCODED_URL');
1502: $this->server->remove('UNENCODED_URL');
1503: $this->server->remove('IIS_WasUrlRewritten');
1504: } elseif ($this->server->has('REQUEST_URI')) {
1505: $requestUri = $this->server->get('REQUEST_URI');
1506:
1507: $schemeAndHttpHost = $this->getSchemeAndHttpHost();
1508: if (strpos($requestUri, $schemeAndHttpHost) === 0) {
1509: $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
1510: }
1511: } elseif ($this->server->has('ORIG_PATH_INFO')) {
1512:
1513: $requestUri = $this->server->get('ORIG_PATH_INFO');
1514: if ('' != $this->server->get('QUERY_STRING')) {
1515: $requestUri .= '?'.$this->server->get('QUERY_STRING');
1516: }
1517: $this->server->remove('ORIG_PATH_INFO');
1518: }
1519:
1520:
1521: $this->server->set('REQUEST_URI', $requestUri);
1522:
1523: return $requestUri;
1524: }
1525:
1526: 1527: 1528: 1529: 1530:
1531: protected function prepareBaseUrl()
1532: {
1533: $filename = basename($this->server->get('SCRIPT_FILENAME'));
1534:
1535: if (basename($this->server->get('SCRIPT_NAME')) === $filename) {
1536: $baseUrl = $this->server->get('SCRIPT_NAME');
1537: } elseif (basename($this->server->get('PHP_SELF')) === $filename) {
1538: $baseUrl = $this->server->get('PHP_SELF');
1539: } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) {
1540: $baseUrl = $this->server->get('ORIG_SCRIPT_NAME');
1541: } else {
1542:
1543:
1544: $path = $this->server->get('PHP_SELF', '');
1545: $file = $this->server->get('SCRIPT_FILENAME', '');
1546: $segs = explode('/', trim($file, '/'));
1547: $segs = array_reverse($segs);
1548: $index = 0;
1549: $last = count($segs);
1550: $baseUrl = '';
1551: do {
1552: $seg = $segs[$index];
1553: $baseUrl = '/'.$seg.$baseUrl;
1554: ++$index;
1555: } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
1556: }
1557:
1558:
1559: $requestUri = $this->getRequestUri();
1560:
1561: if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
1562:
1563: return $prefix;
1564: }
1565:
1566: if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl))) {
1567:
1568: return rtrim($prefix, '/');
1569: }
1570:
1571: $truncatedRequestUri = $requestUri;
1572: if (($pos = strpos($requestUri, '?')) !== false) {
1573: $truncatedRequestUri = substr($requestUri, 0, $pos);
1574: }
1575:
1576: $basename = basename($baseUrl);
1577: if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
1578:
1579: return '';
1580: }
1581:
1582:
1583:
1584:
1585: if ((strlen($requestUri) >= strlen($baseUrl)) && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) {
1586: $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
1587: }
1588:
1589: return rtrim($baseUrl, '/');
1590: }
1591:
1592: 1593: 1594: 1595: 1596:
1597: protected function prepareBasePath()
1598: {
1599: $filename = basename($this->server->get('SCRIPT_FILENAME'));
1600: $baseUrl = $this->getBaseUrl();
1601: if (empty($baseUrl)) {
1602: return '';
1603: }
1604:
1605: if (basename($baseUrl) === $filename) {
1606: $basePath = dirname($baseUrl);
1607: } else {
1608: $basePath = $baseUrl;
1609: }
1610:
1611: if ('\\' === DIRECTORY_SEPARATOR) {
1612: $basePath = str_replace('\\', '/', $basePath);
1613: }
1614:
1615: return rtrim($basePath, '/');
1616: }
1617:
1618: 1619: 1620: 1621: 1622:
1623: protected function preparePathInfo()
1624: {
1625: $baseUrl = $this->getBaseUrl();
1626:
1627: if (null === ($requestUri = $this->getRequestUri())) {
1628: return '/';
1629: }
1630:
1631: $pathInfo = '/';
1632:
1633:
1634: if ($pos = strpos($requestUri, '?')) {
1635: $requestUri = substr($requestUri, 0, $pos);
1636: }
1637:
1638: if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) {
1639:
1640: return '/';
1641: } elseif (null === $baseUrl) {
1642: return $requestUri;
1643: }
1644:
1645: return (string) $pathInfo;
1646: }
1647:
1648: 1649: 1650:
1651: protected static function initializeFormats()
1652: {
1653: static::$formats = array(
1654: 'html' => array('text/html', 'application/xhtml+xml'),
1655: 'txt' => array('text/plain'),
1656: 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'),
1657: 'css' => array('text/css'),
1658: 'json' => array('application/json', 'application/x-json'),
1659: 'xml' => array('text/xml', 'application/xml', 'application/x-xml'),
1660: 'rdf' => array('application/rdf+xml'),
1661: 'atom' => array('application/atom+xml'),
1662: 'rss' => array('application/rss+xml'),
1663: );
1664: }
1665:
1666: 1667: 1668: 1669: 1670:
1671: private function setPhpDefaultLocale($locale)
1672: {
1673:
1674:
1675:
1676: try {
1677: if (class_exists('Locale', false)) {
1678: \Locale::setDefault($locale);
1679: }
1680: } catch (\Exception $e) {
1681: }
1682: }
1683:
1684: 1685: 1686: 1687: 1688: 1689: 1690: 1691: 1692:
1693: private function getUrlencodedPrefix($string, $prefix)
1694: {
1695: if (0 !== strpos(rawurldecode($string), $prefix)) {
1696: return false;
1697: }
1698:
1699: $len = strlen($prefix);
1700:
1701: if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) {
1702: return $match[0];
1703: }
1704:
1705: return false;
1706: }
1707: }
1708: