1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: namespace Cake\Http;
16:
17: use Cake\Core\Configure;
18: use Cake\Utility\Hash;
19: use Zend\Diactoros\ServerRequestFactory as BaseFactory;
20:
21: 22: 23: 24: 25: 26: 27:
28: abstract class ServerRequestFactory extends BaseFactory
29: {
30: 31: 32:
33: public static function fromGlobals(
34: array $server = null,
35: array $query = null,
36: array $body = null,
37: array $cookies = null,
38: array $files = null
39: ) {
40: $server = static::normalizeServer($server ?: $_SERVER);
41: $uri = static::createUri($server);
42: $sessionConfig = (array)Configure::read('Session') + [
43: 'defaults' => 'php',
44: 'cookiePath' => $uri->webroot
45: ];
46: $session = Session::create($sessionConfig);
47: $request = new ServerRequest([
48: 'environment' => $server,
49: 'uri' => $uri,
50: 'files' => $files ?: $_FILES,
51: 'cookies' => $cookies ?: $_COOKIE,
52: 'query' => $query ?: $_GET,
53: 'post' => $body ?: $_POST,
54: 'webroot' => $uri->webroot,
55: 'base' => $uri->base,
56: 'session' => $session,
57: ]);
58:
59: return $request;
60: }
61:
62: 63: 64: 65: 66: 67: 68:
69: public static function createUri(array $server = [])
70: {
71: $server += $_SERVER;
72: $server = static::normalizeServer($server);
73: $headers = static::marshalHeaders($server);
74:
75: return static::marshalUriFromServer($server, $headers);
76: }
77:
78: 79: 80: 81: 82: 83: 84: 85: 86: 87:
88: public static function marshalUriFromServer(array $server, array $headers)
89: {
90: $uri = parent::marshalUriFromServer($server, $headers);
91: list($base, $webroot) = static::getBase($uri, $server);
92:
93:
94:
95: $pathInfo = Hash::get($server, 'PATH_INFO');
96: if ($pathInfo) {
97: $uri = $uri->withPath($pathInfo);
98: } else {
99: $uri = static::updatePath($base, $uri);
100: }
101:
102: if (!$uri->getHost()) {
103: $uri = $uri->withHost('localhost');
104: }
105:
106:
107:
108: $uri->base = $base;
109: $uri->webroot = $webroot;
110:
111: return $uri;
112: }
113:
114: 115: 116: 117: 118: 119: 120:
121: protected static function updatePath($base, $uri)
122: {
123: $path = $uri->getPath();
124: if (strlen($base) > 0 && strpos($path, $base) === 0) {
125: $path = substr($path, strlen($base));
126: }
127: if ($path === '/index.php' && $uri->getQuery()) {
128: $path = $uri->getQuery();
129: }
130: if (empty($path) || $path === '/' || $path === '//' || $path === '/index.php') {
131: $path = '/';
132: }
133: $endsWithIndex = '/' . (Configure::read('App.webroot') ?: 'webroot') . '/index.php';
134: $endsWithLength = strlen($endsWithIndex);
135: if (strlen($path) >= $endsWithLength &&
136: substr($path, -$endsWithLength) === $endsWithIndex
137: ) {
138: $path = '/';
139: }
140:
141: return $uri->withPath($path);
142: }
143:
144: 145: 146: 147: 148: 149: 150:
151: protected static function getBase($uri, $server)
152: {
153: $config = (array)Configure::read('App') + [
154: 'base' => null,
155: 'webroot' => null,
156: 'baseUrl' => null
157: ];
158: $base = $config['base'];
159: $baseUrl = $config['baseUrl'];
160: $webroot = $config['webroot'];
161:
162: if ($base !== false && $base !== null) {
163: return [$base, $base . '/'];
164: }
165:
166: if (!$baseUrl) {
167: $base = dirname(Hash::get($server, 'PHP_SELF'));
168:
169: $base = preg_replace('#/+#', '/', $base);
170:
171: $indexPos = strpos($base, '/' . $webroot . '/index.php');
172: if ($indexPos !== false) {
173: $base = substr($base, 0, $indexPos) . '/' . $webroot;
174: }
175: if ($webroot === basename($base)) {
176: $base = dirname($base);
177: }
178:
179: if ($base === DIRECTORY_SEPARATOR || $base === '.') {
180: $base = '';
181: }
182: $base = implode('/', array_map('rawurlencode', explode('/', $base)));
183:
184: return [$base, $base . '/'];
185: }
186:
187: $file = '/' . basename($baseUrl);
188: $base = dirname($baseUrl);
189:
190: if ($base === DIRECTORY_SEPARATOR || $base === '.') {
191: $base = '';
192: }
193: $webrootDir = $base . '/';
194:
195: $docRoot = Hash::get($server, 'DOCUMENT_ROOT');
196: $docRootContainsWebroot = strpos($docRoot, $webroot);
197:
198: if (!empty($base) || !$docRootContainsWebroot) {
199: if (strpos($webrootDir, '/' . $webroot . '/') === false) {
200: $webrootDir .= $webroot . '/';
201: }
202: }
203:
204: return [$base . $file, $webrootDir];
205: }
206: }
207: