<?php
namespace Cake\Http;
use Cake\Utility\Hash;
use Psr\Http\Message\ServerRequestInterface as PsrRequest;
class RequestTransformer
{
public static function toCake(PsrRequest $request)
{
$post = $request->getParsedBody();
$headers = [];
foreach ($request->getHeaders() as $k => $value) {
$name = sprintf('HTTP_%s', strtoupper(str_replace('-', '_', $k)));
$headers[$name] = implode(',', $value);
}
$server = $headers + $request->getServerParams();
$files = static::getFiles($request);
if (!empty($files)) {
$post = Hash::merge($post, $files);
}
$input = $request->getBody()->getContents();
$input = $input === '' ? null : $input;
return new ServerRequest([
'query' => $request->getQueryParams(),
'post' => $post,
'cookies' => $request->getCookieParams(),
'environment' => $server,
'params' => static::getParams($request),
'url' => $request->getUri()->getPath(),
'base' => $request->getAttribute('base', ''),
'webroot' => $request->getAttribute('webroot', '/'),
'session' => $request->getAttribute('session', null),
'input' => $input,
]);
}
protected static function getParams(PsrRequest $request)
{
$params = (array)$request->getAttribute('params', []);
$params += [
'plugin' => null,
'controller' => null,
'action' => null,
'_ext' => null,
'pass' => []
];
return $params;
}
protected static function getFiles($request)
{
return static::convertFiles([], $request->getUploadedFiles());
}
protected static function convertFiles($data, $files, $path = '')
{
foreach ($files as $key => $file) {
$newPath = $path;
if ($newPath === '') {
$newPath = $key;
}
if ($newPath !== $key) {
$newPath .= '.' . $key;
}
if (is_array($file)) {
$data = static::convertFiles($data, $file, $newPath);
} else {
$data = Hash::insert($data, $newPath, static::convertFile($file));
}
}
return $data;
}
protected static function convertFile($file)
{
$error = $file->getError();
$tmpName = '';
if ($error === UPLOAD_ERR_OK) {
$tmpName = $file->getStream()->getMetadata('uri');
}
return [
'name' => $file->getClientFilename(),
'type' => $file->getClientMediaType(),
'tmp_name' => $tmpName,
'error' => $error,
'size' => $file->getSize(),
];
}
}