2014-05-14 13:24:20 +00:00
|
|
|
<?php namespace Backend\Classes;
|
|
|
|
|
|
|
|
|
|
use Str;
|
|
|
|
|
use App;
|
|
|
|
|
use File;
|
2016-06-04 21:16:11 +00:00
|
|
|
use View;
|
2019-02-21 16:44:58 +00:00
|
|
|
use Event;
|
2016-06-04 21:16:11 +00:00
|
|
|
use Config;
|
2019-02-27 20:27:41 +00:00
|
|
|
use Request;
|
2016-06-04 21:16:11 +00:00
|
|
|
use Response;
|
2015-02-04 08:31:41 +00:00
|
|
|
use Illuminate\Routing\Controller as ControllerBase;
|
2014-05-14 13:24:20 +00:00
|
|
|
use October\Rain\Router\Helper as RouterHelper;
|
2018-11-15 19:51:11 +00:00
|
|
|
use System\Classes\PluginManager;
|
2019-11-02 05:30:33 +00:00
|
|
|
use Closure;
|
2018-11-15 19:51:11 +00:00
|
|
|
|
2014-05-14 13:24:20 +00:00
|
|
|
/**
|
2017-03-16 06:08:20 +00:00
|
|
|
* This is the master controller for all back-end pages.
|
|
|
|
|
* All requests that are prefixed with the backend URI pattern are sent here,
|
|
|
|
|
* then the next URI segments are analysed and the request is routed to the
|
|
|
|
|
* relevant back-end controller.
|
2014-05-14 13:24:20 +00:00
|
|
|
*
|
2017-03-16 06:08:20 +00:00
|
|
|
* For example, a request with the URL `/backend/acme/blog/posts` will look
|
|
|
|
|
* for the `Posts` controller inside the `Acme.Blog` plugin.
|
|
|
|
|
*
|
|
|
|
|
* @see Backend\Classes\Controller Base class for back-end controllers
|
2014-05-14 13:24:20 +00:00
|
|
|
* @package october\backend
|
|
|
|
|
* @author Alexey Bobkov, Samuel Georges
|
|
|
|
|
*/
|
|
|
|
|
class BackendController extends ControllerBase
|
|
|
|
|
{
|
2015-04-21 10:07:34 +00:00
|
|
|
use \October\Rain\Extension\ExtendableTrait;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array Behaviors implemented by this controller.
|
|
|
|
|
*/
|
|
|
|
|
public $implement;
|
|
|
|
|
|
2014-05-14 13:24:20 +00:00
|
|
|
/**
|
|
|
|
|
* @var string Allows early access to page action.
|
|
|
|
|
*/
|
|
|
|
|
public static $action;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array Allows early access to page parameters.
|
|
|
|
|
*/
|
|
|
|
|
public static $params;
|
|
|
|
|
|
2019-02-21 16:44:58 +00:00
|
|
|
/**
|
|
|
|
|
* @var boolean Flag to indicate that the CMS module is handling the current request
|
|
|
|
|
*/
|
|
|
|
|
protected $cmsHandling = false;
|
|
|
|
|
|
2015-04-21 10:07:34 +00:00
|
|
|
/**
|
|
|
|
|
* Instantiate a new BackendController instance.
|
|
|
|
|
*/
|
|
|
|
|
public function __construct()
|
|
|
|
|
{
|
|
|
|
|
$this->extendableConstruct();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extend this object properties upon construction.
|
|
|
|
|
*/
|
|
|
|
|
public static function extend(Closure $callback)
|
|
|
|
|
{
|
|
|
|
|
self::extendableExtendCallback($callback);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-15 17:46:48 +00:00
|
|
|
/**
|
|
|
|
|
* Pass unhandled URLs to the CMS Controller, if it exists
|
|
|
|
|
*
|
|
|
|
|
* @param string $url
|
|
|
|
|
* @return Response
|
|
|
|
|
*/
|
|
|
|
|
protected function passToCmsController($url)
|
|
|
|
|
{
|
2019-03-19 22:31:14 +00:00
|
|
|
if (
|
|
|
|
|
in_array('Cms', Config::get('cms.loadModules', [])) &&
|
|
|
|
|
class_exists('\Cms\Classes\Controller')
|
|
|
|
|
) {
|
2019-02-21 16:44:58 +00:00
|
|
|
$this->cmsHandling = true;
|
2019-01-15 17:46:48 +00:00
|
|
|
return App::make('Cms\Classes\Controller')->run($url);
|
2019-11-06 22:56:46 +00:00
|
|
|
} else {
|
2019-01-15 17:46:48 +00:00
|
|
|
return Response::make(View::make('backend::404'), 404);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-14 13:24:20 +00:00
|
|
|
/**
|
|
|
|
|
* Finds and serves the requested backend controller.
|
|
|
|
|
* If the controller cannot be found, returns the Cms page with the URL /404.
|
|
|
|
|
* If the /404 page doesn't exist, returns the system 404 page.
|
|
|
|
|
* @param string $url Specifies the requested page URL.
|
|
|
|
|
* If the parameter is omitted, the current URL used.
|
|
|
|
|
* @return string Returns the processed page content.
|
|
|
|
|
*/
|
|
|
|
|
public function run($url = null)
|
|
|
|
|
{
|
|
|
|
|
$params = RouterHelper::segmentizeUrl($url);
|
|
|
|
|
|
2019-02-21 16:44:58 +00:00
|
|
|
// Handle NotFoundHttpExceptions in the backend (usually triggered by abort(404))
|
|
|
|
|
Event::listen('exception.beforeRender', function ($exception, $httpCode, $request) {
|
|
|
|
|
if (!$this->cmsHandling && $exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
|
|
|
|
|
return View::make('backend::404');
|
|
|
|
|
}
|
|
|
|
|
}, 1);
|
|
|
|
|
|
2016-06-04 21:16:11 +00:00
|
|
|
/*
|
|
|
|
|
* Database check
|
|
|
|
|
*/
|
|
|
|
|
if (!App::hasDatabase()) {
|
|
|
|
|
return Config::get('app.debug', false)
|
|
|
|
|
? Response::make(View::make('backend::no_database'), 200)
|
2019-01-15 17:46:48 +00:00
|
|
|
: $this->passToCmsController($url);
|
2016-06-04 21:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-14 13:24:20 +00:00
|
|
|
/*
|
|
|
|
|
* Look for a Module controller
|
|
|
|
|
*/
|
2018-08-15 17:15:13 +00:00
|
|
|
$module = $params[0] ?? 'backend';
|
|
|
|
|
$controller = $params[1] ?? 'index';
|
2014-08-08 12:02:46 +00:00
|
|
|
self::$action = $action = isset($params[2]) ? $this->parseAction($params[2]) : 'index';
|
2014-05-14 13:24:20 +00:00
|
|
|
self::$params = $controllerParams = array_slice($params, 3);
|
|
|
|
|
$controllerClass = '\\'.$module.'\Controllers\\'.$controller;
|
2015-02-12 10:02:47 +00:00
|
|
|
if ($controllerObj = $this->findController(
|
|
|
|
|
$controllerClass,
|
|
|
|
|
$action,
|
|
|
|
|
base_path().'/modules'
|
|
|
|
|
)) {
|
2019-11-02 05:16:32 +00:00
|
|
|
return $controllerObj->run($action, $controllerParams);
|
2014-10-10 21:12:50 +00:00
|
|
|
}
|
2014-05-14 13:24:20 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Look for a Plugin controller
|
|
|
|
|
*/
|
|
|
|
|
if (count($params) >= 2) {
|
|
|
|
|
list($author, $plugin) = $params;
|
2018-11-15 19:51:11 +00:00
|
|
|
|
|
|
|
|
$pluginCode = ucfirst($author) . '.' . ucfirst($plugin);
|
|
|
|
|
if (PluginManager::instance()->isDisabled($pluginCode)) {
|
2019-01-15 17:46:48 +00:00
|
|
|
return Response::make(View::make('backend::404'), 404);
|
2018-11-15 19:51:11 +00:00
|
|
|
}
|
|
|
|
|
|
2018-08-15 17:15:13 +00:00
|
|
|
$controller = $params[2] ?? 'index';
|
2014-08-08 12:02:46 +00:00
|
|
|
self::$action = $action = isset($params[3]) ? $this->parseAction($params[3]) : 'index';
|
2014-05-14 13:24:20 +00:00
|
|
|
self::$params = $controllerParams = array_slice($params, 4);
|
|
|
|
|
$controllerClass = '\\'.$author.'\\'.$plugin.'\Controllers\\'.$controller;
|
2014-10-10 21:12:50 +00:00
|
|
|
if ($controllerObj = $this->findController(
|
|
|
|
|
$controllerClass,
|
|
|
|
|
$action,
|
2015-02-07 04:37:07 +00:00
|
|
|
plugins_path()
|
2014-10-10 21:12:50 +00:00
|
|
|
)) {
|
2019-11-02 05:16:32 +00:00
|
|
|
return $controllerObj->run($action, $controllerParams);
|
2014-10-10 21:12:50 +00:00
|
|
|
}
|
2014-05-14 13:24:20 +00:00
|
|
|
}
|
2014-07-14 09:06:23 +00:00
|
|
|
|
2019-11-02 05:16:32 +00:00
|
|
|
/*
|
|
|
|
|
* Fall back on Cms controller
|
|
|
|
|
*/
|
|
|
|
|
return $this->passToCmsController($url);
|
2014-05-14 13:24:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This method is used internally.
|
|
|
|
|
* Finds a backend controller with a callable action method.
|
|
|
|
|
* @param string $controller Specifies a method name to execute.
|
|
|
|
|
* @param string $action Specifies a method name to execute.
|
2015-02-12 10:02:47 +00:00
|
|
|
* @param string $inPath Base path for class file location.
|
2014-05-14 13:24:20 +00:00
|
|
|
* @return ControllerBase Returns the backend controller object
|
|
|
|
|
*/
|
2015-02-12 10:02:47 +00:00
|
|
|
protected function findController($controller, $action, $inPath)
|
2014-05-14 13:24:20 +00:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* Workaround: Composer does not support case insensitivity.
|
|
|
|
|
*/
|
|
|
|
|
if (!class_exists($controller)) {
|
|
|
|
|
$controller = Str::normalizeClassName($controller);
|
2015-02-07 04:37:07 +00:00
|
|
|
$controllerFile = $inPath.strtolower(str_replace('\\', '/', $controller)) . '.php';
|
2014-10-10 21:12:50 +00:00
|
|
|
if ($controllerFile = File::existsInsensitive($controllerFile)) {
|
2018-08-15 16:49:52 +00:00
|
|
|
include_once $controllerFile;
|
2014-10-10 21:12:50 +00:00
|
|
|
}
|
2014-05-14 13:24:20 +00:00
|
|
|
}
|
|
|
|
|
|
2014-10-10 21:12:50 +00:00
|
|
|
if (!class_exists($controller)) {
|
2019-11-02 05:16:32 +00:00
|
|
|
return false;
|
2014-10-10 21:12:50 +00:00
|
|
|
}
|
2014-05-14 13:24:20 +00:00
|
|
|
|
|
|
|
|
$controllerObj = App::make($controller);
|
|
|
|
|
|
2014-10-10 21:12:50 +00:00
|
|
|
if ($controllerObj->actionExists($action)) {
|
2019-11-02 05:16:32 +00:00
|
|
|
return $controllerObj;
|
2014-10-10 21:12:50 +00:00
|
|
|
}
|
2014-05-14 13:24:20 +00:00
|
|
|
|
2019-11-02 05:16:32 +00:00
|
|
|
return false;
|
2014-05-14 13:24:20 +00:00
|
|
|
}
|
2014-08-08 12:02:46 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Process the action name, since dashes are not supported in PHP methods.
|
|
|
|
|
* @param string $actionName
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
protected function parseAction($actionName)
|
|
|
|
|
{
|
2014-10-10 21:12:50 +00:00
|
|
|
if (strpos($actionName, '-') !== false) {
|
2014-08-08 12:02:46 +00:00
|
|
|
return camel_case($actionName);
|
2014-10-10 21:12:50 +00:00
|
|
|
}
|
2014-08-08 12:02:46 +00:00
|
|
|
|
|
|
|
|
return $actionName;
|
|
|
|
|
}
|
2019-02-27 20:27:41 +00:00
|
|
|
}
|