Administration/src/FuzeWorks/Administration/AdminPlugin.php

212 lines
6.7 KiB
PHP

<?php
/**
* FuzeWorks Framework Administration Plugin.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2020 i15
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author i15
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
* @license https://opensource.org/licenses/MIT MIT License
*
* @since Version 1.3.0
*
* @version Version 1.3.0
*/
namespace FuzeWorks\Administration;
use FuzeWorks\Config;
use FuzeWorks\ConfigORM\ConfigORM;
use FuzeWorks\Controllers;
use FuzeWorks\Event\LayoutLoadEvent;
use FuzeWorks\Event\RouteWebRequestEvent;
use FuzeWorks\Events;
use FuzeWorks\Factory;
use FuzeWorks\Layout;
use FuzeWorks\Logger;
use FuzeWorks\Models;
use FuzeWorks\Priority;
use FuzeWorks\Resources;
use FuzeWorks\Router;
use FuzeWorks\Views;
class AdminPlugin implements \FuzeWorks\iPluginHeader
{
private $pluginKey = 'admin';
/** @var Config */
private $config;
/** @var Router */
private $router;
/** @var Models */
private $models;
/** @var Views */
private $views;
/** @var Controllers */
private $controllers;
/** @var ConfigORM */
private $adminCFG;
/**
* @var string
*/
private $pluginPath;
/**
* @inheritDoc
*/
public function init()
{
// Make a listener for a web request
Events::addListener([$this, 'routeWebRequestEventListener'], 'routeWebRequestEvent', Priority::NORMAL);
$this->pluginPath = dirname(__DIR__, 3);
}
public function routeWebRequestEventListener(RouteWebRequestEvent $event)
{
// If this request has nothing to do with the admin interface, don't bother routing the request
if (substr($event->uriString, 0, strlen($this->pluginKey)) !== $this->pluginKey)
return;
Logger::log("Administration: observed admin request. Activating plugin.");
// Load the dependencies
$this->config = Factory::getInstance('config');
$this->router = Factory::getInstance('router');
$this->models = Factory::getInstance('models');
$this->views = Factory::getInstance('views');
$this->controllers = Factory::getInstance('controllers');
// Load the admin configuration
$this->config->addComponentPath($this->pluginPath, Priority::LOWEST);
$this->adminCFG = $this->config->getConfig('admin');
// If admin is not enabled, stop here
if (!$this->adminCFG->get('admin_enabled'))
return;
// Now load the pluginKey
$this->pluginKey = $this->adminCFG->get('admin_url');
// If it does, register everything
/** @var Resources $resources */
$resources = Factory::getInstance('resources');
// Serve the AdminLTE distribution files
$adminLTE = $this->pluginPath . DS . 'vendor' . DS . 'almasaeed2010' . DS . 'adminlte';
$resources->registerResources('admin/dist', $adminLTE . DS . 'dist');
$resources->registerResources('admin/plugins', $adminLTE . DS . 'plugins');
// And serve the actual pages
$routeString = '^' . $this->pluginKey . '(|\/(?P<viewName>.*?)(|\/(?P<viewMethod>.*?)(|\/(?P<viewParameters>.*?))))';
$this->router->addRoute($routeString, ['callable' => [$this, 'adminCallable']], Priority::HIGHEST);
// And add componentPaths for models, views, controllers
$this->models->addComponentPath($this->pluginPath . DS . 'models', Priority::LOW);
$this->views->addComponentPath($this->pluginPath . DS . 'views', Priority::LOW);
$this->controllers->addComponentPath($this->pluginPath . DS . 'controllers', Priority::LOW);
}
public function adminCallable(array $matches, string $routeString)
{
Logger::log("AdminCallable called. Loading admin page.");
// Load layouts and assign componentPath, in case the loaded view needs access to it
/** @var Layout $layouts */
$layouts = Factory::getInstance('layouts');
$layouts->addComponentPath($this->pluginPath . DS . 'layouts', Priority::LOW);
// And add a layoutLoadEventListener, to add global administration variables
Events::addListener([$this, 'layoutLoadEventListener'], 'layoutLoadEvent', Priority::NORMAL);
// Let's generate the sidebar
$finder = new PageFinder();
$sidebar = $finder->generateSidebar();
// Afterwards, pass on to the admin view and its contents
Logger::log("Forwarding request to Router::defaultCallable().");
$matches['viewType'] = 'admin';
$content = $this->router->defaultCallable($matches, $routeString);
// Reset and assign
Logger::log("Generating panel wrapper.");
$layouts->reset(false);
$layouts->assign('sidebar', $sidebar);
$layouts->assign('content', $content);
// And load the page
Logger::log("Forwarding output back to Router.");
$page = $layouts->get('main/panel');
return $page;
}
/**
* Listener for LayoutLoadEvent
*
* Assigns variables to Layout that this plugin's layouts may require.
*
* @param LayoutLoadEvent $event
*/
public function layoutLoadEventListener(LayoutLoadEvent $event)
{
$event->assign('adminKey', $this->pluginKey);
}
/**
* @inheritDoc
*/
public function getName(): string
{
return 'FuzeWorksAdministration';
}
/**
* @inheritDoc
*/
public function getClassesPrefix(): ?string
{
return null;
}
/**
* @inheritDoc
*/
public function getSourceDirectory(): ?string
{
return null;
}
/**
* @inheritDoc
*/
public function getPluginClass(): ?string
{
return null;
}
}