<?php
namespace Cake\Http;
use Cake\Core\App;
use Cake\Routing\Exception\MissingControllerException;
use Cake\Utility\Inflector;
use ReflectionClass;
class ControllerFactory
{
public function create(ServerRequest $request, Response $response)
{
$className = $this->getControllerClass($request);
if (!$className) {
$this->missingController($request);
}
$reflection = new ReflectionClass($className);
if ($reflection->isAbstract() || $reflection->isInterface()) {
$this->missingController($request);
}
$controller = $reflection->newInstance($request, $response);
return $controller;
}
public function getControllerClass(ServerRequest $request)
{
$pluginPath = $controller = null;
$namespace = 'Controller';
if ($request->getParam('controller')) {
$controller = $request->getParam('controller');
}
if ($request->getParam('plugin')) {
$pluginPath = $request->getParam('plugin') . '.';
}
if ($request->getParam('prefix')) {
if (strpos($request->getParam('prefix'), '/') === false) {
$namespace .= '/' . Inflector::camelize($request->getParam('prefix'));
} else {
$prefixes = array_map(
'Cake\Utility\Inflector::camelize',
explode('/', $request->getParam('prefix'))
);
$namespace .= '/' . implode('/', $prefixes);
}
}
$firstChar = substr($controller, 0, 1);
if (strpos($controller, '\\') !== false ||
strpos($controller, '/') !== false ||
strpos($controller, '.') !== false ||
$firstChar === strtolower($firstChar)
) {
$this->missingController($request);
}
return App::className($pluginPath . $controller, $namespace, 'Controller') ?: null;
}
protected function missingController($request)
{
throw new MissingControllerException([
'class' => $request->getParam('controller'),
'plugin' => $request->getParam('plugin'),
'prefix' => $request->getParam('prefix'),
'_ext' => $request->getParam('_ext')
]);
}
}