All changes as implemented over the last 3 years.
Pushes Administration into a workable state.
This commit is contained in:
parent
50608c18e7
commit
63ea659d5b
6
Dockerfile
Normal file → Executable file
6
Dockerfile
Normal file → Executable file
@ -1,10 +1,6 @@
|
|||||||
FROM php:7.3-apache
|
FROM registry.i15.nl/i15/fuzephp:8.1-apache
|
||||||
MAINTAINER i15 <abel@i15.nl>
|
MAINTAINER i15 <abel@i15.nl>
|
||||||
|
|
||||||
# Install PHP Deps
|
|
||||||
# First PDO and MySQL
|
|
||||||
RUN docker-php-ext-install mysqli pdo_mysql opcache
|
|
||||||
|
|
||||||
# Write application to image
|
# Write application to image
|
||||||
ENV APACHE_DOCUMENT_ROOT /usr/src/admin/www
|
ENV APACHE_DOCUMENT_ROOT /usr/src/admin/www
|
||||||
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
|
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
|
||||||
|
2
LICENSE
Normal file → Executable file
2
LICENSE
Normal file → Executable file
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2013-2020 i15
|
Copyright (c) 2013-2023 i15
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
22
composer.json
Normal file → Executable file
22
composer.json
Normal file → Executable file
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fuzeworks/administration",
|
"name": "fuzeworks/administration",
|
||||||
"description": "description",
|
"description": "Administration interface for FuzeWorks",
|
||||||
"minimum-stability": "stable",
|
|
||||||
"license": ["MIT"],
|
"license": ["MIT"],
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
@ -10,19 +9,16 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.2.0",
|
"php": ">=8.1.0",
|
||||||
"fuzeworks/core": "~1.2",
|
"fuzeworks/webcomponent": "~1.3.0",
|
||||||
"fuzeworks/mvcr": "~1.2",
|
"fuzeworks/authentication": "~1.3.0",
|
||||||
"fuzeworks/webcomponent": "~1.2",
|
"fuzeworks/layout": "~1.3.0",
|
||||||
"fuzeworks/layout": "~1.2",
|
"latte/latte": "~2.5",
|
||||||
"fuzeworks/database": "~1.2",
|
"almasaeed2010/adminlte": "^3"
|
||||||
"latte/latte": "^2",
|
|
||||||
"almasaeed2010/adminlte": "^3",
|
|
||||||
"phpdocumentor/reflection-docblock": "^5"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9",
|
"fuzeworks/tracycomponent": "~1.3.0",
|
||||||
"fuzeworks/tracycomponent": "~1.2"
|
"phpunit/phpunit": "^9"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
0
config.admin.php
Normal file → Executable file
0
config.admin.php
Normal file → Executable file
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* FuzeWorks Framework Administration Plugin.
|
* i15Site.
|
||||||
*
|
*
|
||||||
* The FuzeWorks PHP FrameWork
|
* The FuzeWorks PHP FrameWork
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2020 i15
|
* Copyright (C) 2013-2022 i15
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -25,18 +25,18 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*
|
*
|
||||||
* @author i15
|
* @author i15
|
||||||
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
|
* @copyright Copyright (c) 2013 - 2022, i15. (http://i15.nl)
|
||||||
* @license https://opensource.org/licenses/MIT MIT License
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
*
|
*
|
||||||
* @since Version 1.3.0
|
* @link https://i15.nl
|
||||||
|
* @since Version 2.0.0
|
||||||
*
|
*
|
||||||
* @version Version 1.3.0
|
* @version Version 2.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Application\Controller;
|
namespace Application\Controller;
|
||||||
use FuzeWorks\WebController;
|
use FuzeWorks\WebController;
|
||||||
|
|
||||||
class IndexController extends WebController
|
class AsyncController extends WebController
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
36
controllers/main/controller.cache.php
Normal file
36
controllers/main/controller.cache.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Application\Controller;
|
||||||
|
|
||||||
|
use FuzeWorks\Factory;
|
||||||
|
use FuzeWorks\ObjectStorage\ObjectStorageComponent;
|
||||||
|
use FuzeWorks\WebController;
|
||||||
|
|
||||||
|
class CacheController extends WebController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function getCacheItems(int $index = 1, int $pageSize = 50): ?array
|
||||||
|
{
|
||||||
|
// Get storage
|
||||||
|
/** @var ObjectStorageComponent $storage */
|
||||||
|
$storage = Factory::getInstance("storage");
|
||||||
|
$store = $storage->getStorage();
|
||||||
|
|
||||||
|
// First retrieve the index
|
||||||
|
$objectIndex = $store->getIndex();
|
||||||
|
|
||||||
|
$out = [];
|
||||||
|
for ($i = $index; $i < ($index + $pageSize); $i++)
|
||||||
|
{
|
||||||
|
if (!isset($objectIndex[$i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
$out[] = $store->getItem($objectIndex[$i]);
|
||||||
|
//$out[] = $store->getItemMeta($objectIndex[$i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
views/view.admin.index.php → controllers/main/controller.dashboard.php
Normal file → Executable file
21
views/view.admin.index.php → controllers/main/controller.dashboard.php
Normal file → Executable file
@ -33,23 +33,18 @@
|
|||||||
* @version Version 1.3.0
|
* @version Version 1.3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Application\View;
|
namespace Application\Controller;
|
||||||
use FuzeWorks\Administration\AdminView;
|
use FuzeWorks\Administration\Attributes\DashboardAttribute;
|
||||||
|
use FuzeWorks\Administration\PageFinder;
|
||||||
|
use FuzeWorks\WebController;
|
||||||
|
|
||||||
class IndexAdminView extends AdminView
|
class DashboardController extends WebController
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
public function populateDashboard()
|
||||||
* Hello!
|
|
||||||
*
|
|
||||||
* This does a lot of things
|
|
||||||
*
|
|
||||||
* @display Dashboard
|
|
||||||
* @icon tachometer-alt
|
|
||||||
* @priority Priority::HIGHEST
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
{
|
||||||
|
$finder = new PageFinder();
|
||||||
|
$views = $finder->findViewsWithAttribute(DashboardAttribute::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
72
controllers/controller.settings.php → controllers/main/controller.settings.php
Normal file → Executable file
72
controllers/controller.settings.php → controllers/main/controller.settings.php
Normal file → Executable file
@ -34,7 +34,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Application\Controller;
|
namespace Application\Controller;
|
||||||
|
|
||||||
use FuzeWorks\Core;
|
use FuzeWorks\Core;
|
||||||
|
use FuzeWorks\Exception\NotFoundException;
|
||||||
use FuzeWorks\Priority;
|
use FuzeWorks\Priority;
|
||||||
use FuzeWorks\WebController;
|
use FuzeWorks\WebController;
|
||||||
|
|
||||||
@ -48,24 +50,22 @@ class SettingsController extends WebController
|
|||||||
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++)
|
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++)
|
||||||
$paths[$i] = $this->config->getComponentPaths($i);
|
$paths[$i] = $this->config->getComponentPaths($i);
|
||||||
|
|
||||||
// And add the CorePath
|
|
||||||
$paths[Priority::getLowestPriority()][] = Core::$coreDir . DS . 'Config';
|
|
||||||
|
|
||||||
// Then go over every individual paths
|
// Then go over every individual paths
|
||||||
$configFiles = [];
|
$configFiles = [];
|
||||||
foreach ($paths as $priority => $foldersArray)
|
foreach ($paths as $priority => $foldersArray) {
|
||||||
{
|
foreach ($foldersArray as $folder) {
|
||||||
foreach ($foldersArray as $folder)
|
|
||||||
{
|
|
||||||
// Get the contents from the folder
|
// Get the contents from the folder
|
||||||
$contents = array_diff(scandir($folder), array('..', '.'));
|
$contents = array_diff(scandir($folder), array('..', '.'));
|
||||||
|
|
||||||
// Then go over the folders, and see which ones are an admin view
|
// Then go over the folders, and see which ones are an admin view
|
||||||
foreach ($contents as $file)
|
foreach ($contents as $file) {
|
||||||
{
|
|
||||||
// If the file matches the expected filename, add it to the list
|
// If the file matches the expected filename, add it to the list
|
||||||
if (substr($file, 0, 7) === 'config.' && !isset($configFiles[$file]))
|
if (str_starts_with($file, 'config.')) {
|
||||||
$configFiles[$file] = ['folder' => $folder, 'priority' => substr(Priority::getPriority($priority), 10)];
|
if (!isset($configFiles[$file]))
|
||||||
|
$configFiles[$file] = [];
|
||||||
|
|
||||||
|
$configFiles[$file][] = ['folder' => $folder, 'priority' => substr(Priority::getPriority($priority), 10)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,4 +77,54 @@ class SettingsController extends WebController
|
|||||||
return $configFiles;
|
return $configFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a file
|
||||||
|
*
|
||||||
|
* @param string $fileName
|
||||||
|
* @return array
|
||||||
|
* @throws NotFoundException
|
||||||
|
*/
|
||||||
|
public function fetchFile(string $fileName, int $selector): array
|
||||||
|
{
|
||||||
|
// Fetch files
|
||||||
|
$files = $this->findSettingsFiles();
|
||||||
|
|
||||||
|
// Check if the file exists
|
||||||
|
if (!isset($files[$fileName]))
|
||||||
|
throw new NotFoundException("The requested settings file could not be found.");
|
||||||
|
|
||||||
|
// Select correct data
|
||||||
|
$meta = $files[$fileName][$selector];
|
||||||
|
|
||||||
|
// Find the file
|
||||||
|
$file = $meta['folder'] . DS . $fileName;
|
||||||
|
if (!file_exists($file))
|
||||||
|
throw new NotFoundException("The requested settings file could not be found.");
|
||||||
|
|
||||||
|
// Load the raw data
|
||||||
|
$raw = file_get_contents($file);
|
||||||
|
|
||||||
|
// And try to load the editable data
|
||||||
|
$data = include($file);
|
||||||
|
|
||||||
|
// Prepare output variable
|
||||||
|
return ['name' => $fileName, 'directory' => $meta['folder'], 'raw' => $raw, 'data' => $data];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function verifyFileData(array $fileData): bool
|
||||||
|
{
|
||||||
|
foreach ($fileData as $key => $val) {
|
||||||
|
switch (gettype($val)) {
|
||||||
|
case 'array':
|
||||||
|
case 'object':
|
||||||
|
case 'resource':
|
||||||
|
case 'unknown type':
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
0
layouts/components/cache/layout.overview.latte
vendored
Normal file
0
layouts/components/cache/layout.overview.latte
vendored
Normal file
19
layouts/components/settings/layout.overview.latte
Normal file → Executable file
19
layouts/components/settings/layout.overview.latte
Normal file → Executable file
@ -1,5 +1,5 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xl-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Configuration Files</h3>
|
<h3 class="card-title">Configuration Files</h3>
|
||||||
@ -18,14 +18,16 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{var $it = 0}
|
||||||
{foreach $files as $fileName => $data}
|
{foreach $files as $fileName => $data}
|
||||||
<tr>
|
<tr n:foreach="$data as $entry">
|
||||||
<td>{$iterator->getCounter()}</td>
|
{var $it = $it + 1}
|
||||||
|
<td>{$it}</td>
|
||||||
<td>{$fileName}</td>
|
<td>{$fileName}</td>
|
||||||
<td>{$data['folder']}</td>
|
<td>{$entry['folder']}</td>
|
||||||
<td>{$data['priority']}</td>
|
<td>{$entry['priority']}</td>
|
||||||
<td><button type="button" class="btn btn-block btn-success">VIEW</button></td>
|
<td><a href="/{$adminKey}/settings/view/{$fileName}/{$iterator->counter0}"><button type="button" class="btn btn-block btn-success">VIEW</button></a></td>
|
||||||
<td><button type="button" class="btn btn-block btn-primary">EDIT</button></td>
|
<td><a href="/{$adminKey}/settings/modify/{$fileName}/{$iterator->counter0}"><button type="button" class="btn btn-block btn-primary">EDIT</button></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -35,6 +37,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
63
layouts/components/settings/layout.view.latte
Executable file
63
layouts/components/settings/layout.view.latte
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
{varType FuzeWorks\Forms\Form $form}
|
||||||
|
{varType FuzeWorks\Forms\Field $field}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<!-- Custom Tabs -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header d-flex p-0">
|
||||||
|
<h3 class="card-title p-3">{$config['name']}</h3>
|
||||||
|
<ul class="nav nav-pills ml-auto p-2">
|
||||||
|
{ifset $config['data']}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" href="#data" data-toggle="tab">Data</a>
|
||||||
|
</li>
|
||||||
|
{/ifset}
|
||||||
|
<li class="nav-item"><a class="nav-link {$config['data'] ? '' : 'active'}" href="#raw" data-toggle="tab">Raw</a></li>
|
||||||
|
</ul>
|
||||||
|
</div><!-- /.card-header -->
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
{foreach $form->getFields() as $field}
|
||||||
|
{switch get_class($field)}
|
||||||
|
{case "FuzeWorks\Forms\Fields\HiddenField", "FuzeWorks\Forms\Fields\SubmitField"}
|
||||||
|
{$field|noescape}
|
||||||
|
{case "FuzeWorks\Forms\Fields\CheckboxField"}
|
||||||
|
<div class="form-check">
|
||||||
|
{$field->addClass("form-check-input")|noescape}
|
||||||
|
<label for="{$field->getId()}" class="form-check-label">{$field->getLabel()}</label>
|
||||||
|
{if $field->isValidated() && !$field->isValid()}
|
||||||
|
<small class="text-danger">{$field->getErrors()|implode}</small>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{default}
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="{$field->getId()}">{$field->getLabel()}</label>
|
||||||
|
{if $field->isValidated() && !$field->isValid()}
|
||||||
|
{$field->class(["form-control", "is-invalid"])|noescape}
|
||||||
|
<small class="text-danger">{$field->getErrors()|implode}</small>
|
||||||
|
{elseif $field->isValidated() && $field->isValid()}
|
||||||
|
{$field->class(["form-control", "is-valid"])|noescape}
|
||||||
|
{else}
|
||||||
|
{$field->addClass("form-control")|noescape}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/switch}
|
||||||
|
{/foreach}
|
||||||
|
<div class="tab-pane {$config['data'] ? '' : 'active'}" id="raw">
|
||||||
|
<textarea disabled style="min-width: 100%; height: 100%" oninput='resizeRawArea(this)'>{$config['raw']}</textarea>
|
||||||
|
</div>
|
||||||
|
<!-- /.tab-pane -->
|
||||||
|
</div>
|
||||||
|
<!-- /.tab-content -->
|
||||||
|
</div><!-- /.card-body -->
|
||||||
|
</div>
|
||||||
|
<!-- ./card -->
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function resizeRawArea(jq_in) {
|
||||||
|
jq_in.style.height = "";
|
||||||
|
jq_in.style.height = jq_in.scrollHeight + 3 + "px";
|
||||||
|
}
|
||||||
|
</script>
|
12
layouts/components/test/layout.home.latte
Executable file
12
layouts/components/test/layout.home.latte
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
{varType FuzeWorks\Forms\Form $form}
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card card-primary">
|
||||||
|
<div class="card card-header">
|
||||||
|
<h3 class="card-title">{$form->getLabel()}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{$form|noescape}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
13
layouts/main/layout.error403.latte
Normal file
13
layouts/main/layout.error403.latte
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<div class="error-page">
|
||||||
|
<h2 class="headline text-danger">403</h2>
|
||||||
|
|
||||||
|
<div class="error-content">
|
||||||
|
<h3><i class="fas fa-exclamation-triangle text-danger"></i> Unauthorized! </h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You do not have permission to view that page.
|
||||||
|
Meanwhile, you may <a href="/{$adminKey}">return to dashboard</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.error-page -->
|
14
layouts/main/layout.error404.latte
Normal file
14
layouts/main/layout.error404.latte
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<div class="error-page">
|
||||||
|
<h2 class="headline text-warning"> 404</h2>
|
||||||
|
|
||||||
|
<div class="error-content">
|
||||||
|
<h3><i class="fas fa-exclamation-triangle text-warning"></i> Oops! Page not found.</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We could not find the page you were looking for.
|
||||||
|
Meanwhile, you may <a href="/{$adminKey}">return to dashboard</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!-- /.error-content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.error-page -->
|
13
layouts/main/layout.error500.latte
Normal file
13
layouts/main/layout.error500.latte
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<div class="error-page">
|
||||||
|
<h2 class="headline text-danger">500</h2>
|
||||||
|
|
||||||
|
<div class="error-content">
|
||||||
|
<h3><i class="fas fa-exclamation-triangle text-danger"></i> Oops! Something went wrong.</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We will work on fixing that right away.
|
||||||
|
Meanwhile, you may <a href="/{$adminKey}">return to dashboard</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.error-page -->
|
212
layouts/main/layout.panel.latte
Normal file → Executable file
212
layouts/main/layout.panel.latte
Normal file → Executable file
@ -1,29 +1,17 @@
|
|||||||
|
{varType FuzeWorks\Authentication\Model\Session $session}
|
||||||
|
{varType bool $loadAsync}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<title>AdminLTE 3 | Dashboard</title>
|
<title>{$serverName} | {$pageTitle}</title>
|
||||||
<!-- Tell the browser to be responsive to screen width -->
|
<!-- Tell the browser to be responsive to screen width -->
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<!-- Font Awesome -->
|
<!-- Font Awesome -->
|
||||||
<link rel="stylesheet" href="/{$adminKey}/plugins/fontawesome-free/css/all.min.css">
|
<link rel="stylesheet" href="/{$adminKey}/lte_plugins/fontawesome-free/css/all.min.css">
|
||||||
<!-- Ionicons -->
|
|
||||||
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
|
|
||||||
<!-- Tempusdominus Bbootstrap 4 -->
|
|
||||||
<link rel="stylesheet" href="/{$adminKey}/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">
|
|
||||||
<!-- iCheck -->
|
|
||||||
<link rel="stylesheet" href="/{$adminKey}/plugins/icheck-bootstrap/icheck-bootstrap.min.css">
|
|
||||||
<!-- JQVMap -->
|
|
||||||
<link rel="stylesheet" href="/{$adminKey}/plugins/jqvmap/jqvmap.min.css">
|
|
||||||
<!-- Theme style -->
|
<!-- Theme style -->
|
||||||
<link rel="stylesheet" href="/{$adminKey}/dist/css/adminlte.min.css">
|
<link rel="stylesheet" href="/{$adminKey}/lte_dist/css/adminlte.min.css">
|
||||||
<!-- overlayScrollbars -->
|
|
||||||
<link rel="stylesheet" href="/{$adminKey}/plugins/overlayScrollbars/css/OverlayScrollbars.min.css">
|
|
||||||
<!-- Daterange picker -->
|
|
||||||
<link rel="stylesheet" href="/{$adminKey}/plugins/daterangepicker/daterangepicker.css">
|
|
||||||
<!-- summernote -->
|
|
||||||
<link rel="stylesheet" href="/{$adminKey}/plugins/summernote/summernote-bs4.css">
|
|
||||||
<!-- Google Font: Source Sans Pro -->
|
<!-- Google Font: Source Sans Pro -->
|
||||||
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
@ -38,113 +26,46 @@
|
|||||||
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
|
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item d-none d-sm-inline-block">
|
<li class="nav-item d-none d-sm-inline-block">
|
||||||
<a href="/" class="nav-link">Home</a>
|
<a href="/{$adminKey}" class="nav-link">Dashboard</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- SEARCH FORM -->
|
|
||||||
<form class="form-inline ml-3">
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-navbar" type="submit">
|
|
||||||
<i class="fas fa-search"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- Right navbar links -->
|
<!-- Right navbar links -->
|
||||||
<ul class="navbar-nav ml-auto">
|
<ul class="navbar-nav ml-auto">
|
||||||
<!-- Messages Dropdown Menu -->
|
{if $loadAsync}
|
||||||
<li class="nav-item dropdown">
|
<li id="asyncWidget" class="nav-item dropdown">
|
||||||
<a class="nav-link" data-toggle="dropdown" href="#">
|
<a class="nav-link" data-toggle="dropdown" href="#">
|
||||||
<i class="far fa-comments"></i>
|
<i class="fa fa-list"></i>
|
||||||
<span class="badge badge-danger navbar-badge">3</span>
|
<span class="badge badge-warning navbar-badge">0</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
|
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
|
||||||
<a href="#" class="dropdown-item">
|
<span class="dropdown-item dropdown-header">Asynchronous tasks</span>
|
||||||
<!-- Message Start -->
|
|
||||||
<div class="media">
|
|
||||||
<img src="/{$adminKey}/dist/img/user1-128x128.jpg" alt="User Avatar" class="img-size-50 mr-3 img-circle">
|
|
||||||
<div class="media-body">
|
|
||||||
<h3 class="dropdown-item-title">
|
|
||||||
Brad Diesel
|
|
||||||
<span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span>
|
|
||||||
</h3>
|
|
||||||
<p class="text-sm">Call me whenever you can...</p>
|
|
||||||
<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Message End -->
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a href="#" class="dropdown-item">
|
|
||||||
<!-- Message Start -->
|
|
||||||
<div class="media">
|
|
||||||
<img src="/{$adminKey}/dist/img/user8-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
|
|
||||||
<div class="media-body">
|
|
||||||
<h3 class="dropdown-item-title">
|
|
||||||
John Pierce
|
|
||||||
<span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span>
|
|
||||||
</h3>
|
|
||||||
<p class="text-sm">I got your message bro</p>
|
|
||||||
<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Message End -->
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a href="#" class="dropdown-item">
|
<a href="/{$adminKey}/async" class="dropdown-item dropdown-footer">See all historic tasks</a>
|
||||||
<!-- Message Start -->
|
|
||||||
<div class="media">
|
|
||||||
<img src="/{$adminKey}/dist/img/user3-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
|
|
||||||
<div class="media-body">
|
|
||||||
<h3 class="dropdown-item-title">
|
|
||||||
Nora Silvester
|
|
||||||
<span class="float-right text-sm text-warning"><i class="fas fa-star"></i></span>
|
|
||||||
</h3>
|
|
||||||
<p class="text-sm">The subject goes here</p>
|
|
||||||
<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Message End -->
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a href="#" class="dropdown-item dropdown-footer">See All Messages</a>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<!-- Notifications Dropdown Menu -->
|
{/if}
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown user-menu">
|
||||||
<a class="nav-link" data-toggle="dropdown" href="#">
|
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">
|
||||||
<i class="far fa-bell"></i>
|
<img src="/{$adminKey}/lte_dist/img/user2-160x160.jpg" class="user-image img-circle elevation-2" alt="User Image">
|
||||||
<span class="badge badge-warning navbar-badge">15</span>
|
<span class="d-none d-md-inline">{$session->user->primaryEmail}</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
|
<ul class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
|
||||||
<span class="dropdown-item dropdown-header">15 Notifications</span>
|
<!-- User image -->
|
||||||
<div class="dropdown-divider"></div>
|
<li class="user-header bg-primary">
|
||||||
<a href="#" class="dropdown-item">
|
<img src="/{$adminKey}/lte_dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">
|
||||||
<i class="fas fa-envelope mr-2"></i> 4 new messages
|
<p>
|
||||||
<span class="float-right text-muted text-sm">3 mins</span>
|
{$session->user->primaryEmail}
|
||||||
</a>
|
<small>Member since -</small>
|
||||||
<div class="dropdown-divider"></div>
|
</p>
|
||||||
<a href="#" class="dropdown-item">
|
|
||||||
<i class="fas fa-users mr-2"></i> 8 friend requests
|
|
||||||
<span class="float-right text-muted text-sm">12 hours</span>
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a href="#" class="dropdown-item">
|
|
||||||
<i class="fas fa-file mr-2"></i> 3 new reports
|
|
||||||
<span class="float-right text-muted text-sm">2 days</span>
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<!-- Menu Footer-->
|
||||||
<a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#" role="button">
|
<li class="user-footer">
|
||||||
<i class="fas fa-th-large"></i>
|
<a href="/{$adminKey}/profile" class="btn btn-default btn-flat">Profile</a>
|
||||||
</a>
|
<a href="{$authURL}/logout" class="btn btn-default btn-flat float-right">Sign out</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
@ -153,24 +74,14 @@
|
|||||||
<!-- Main Sidebar Container -->
|
<!-- Main Sidebar Container -->
|
||||||
<aside class="main-sidebar sidebar-dark-primary elevation-4">
|
<aside class="main-sidebar sidebar-dark-primary elevation-4">
|
||||||
<!-- Brand Logo -->
|
<!-- Brand Logo -->
|
||||||
<a href="index3.html" class="brand-link">
|
<a href="/" class="brand-link">
|
||||||
<img src="/{$adminKey}/dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3"
|
<img src="/{$adminKey}/lte_dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3"
|
||||||
style="opacity: .8">
|
style="opacity: .8">
|
||||||
<span class="brand-text font-weight-light">AdminLTE 3</span>
|
<span class="brand-text font-weight-light">{$serverName}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<!-- Sidebar user panel (optional) -->
|
|
||||||
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
|
|
||||||
<div class="image">
|
|
||||||
<img src="/{$adminKey}/dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">
|
|
||||||
</div>
|
|
||||||
<div class="info">
|
|
||||||
<a href="#" class="d-block">Juris LLM</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Sidebar Menu -->
|
<!-- Sidebar Menu -->
|
||||||
<nav class="mt-2">
|
<nav class="mt-2">
|
||||||
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
|
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
|
||||||
@ -196,12 +107,12 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<h1 class="m-0 text-dark">Dashboard</h1>
|
<h1 class="m-0 text-dark">{$pageTitle}</h1>
|
||||||
</div><!-- /.col -->
|
</div><!-- /.col -->
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<ol class="breadcrumb float-sm-right">
|
<ol class="breadcrumb float-sm-right">
|
||||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
<li class="breadcrumb-item"><a href="/{$adminKey}">Home</a></li>
|
||||||
<li class="breadcrumb-item active">Dashboard v1</li>
|
<li class="breadcrumb-item active">{$pageTitle}</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div><!-- /.col -->
|
</div><!-- /.col -->
|
||||||
</div><!-- /.row -->
|
</div><!-- /.row -->
|
||||||
@ -219,50 +130,29 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.content-wrapper -->
|
<!-- /.content-wrapper -->
|
||||||
<footer class="main-footer">
|
<footer class="main-footer">
|
||||||
<strong>Copyright © 2013-2020 <a href="https://i15.nl">i15.nl</a>.</strong>
|
<strong>Copyright © 2013-{date('Y')} <a href="https://i15.nl">i15.nl</a>.</strong>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
<div class="float-right d-none d-sm-inline-block">
|
<div class="float-right d-none d-sm-inline-block">
|
||||||
<b>Version</b> 1.3.0
|
<b>Version</b> 1.3.0
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!-- Control Sidebar -->
|
|
||||||
<aside class="control-sidebar control-sidebar-dark">
|
|
||||||
<!-- Control sidebar content goes here -->
|
|
||||||
</aside>
|
|
||||||
<!-- /.control-sidebar -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- jQuery -->
|
<!-- jQuery -->
|
||||||
<script src="/{$adminKey}/plugins/jquery/jquery.min.js"></script>
|
<script src="/{$adminKey}/lte_plugins/jquery/jquery.min.js"></script>
|
||||||
<!-- jQuery UI 1.11.4 -->
|
|
||||||
<script src="/{$adminKey}/plugins/jquery-ui/jquery-ui.min.js"></script>
|
|
||||||
<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
|
|
||||||
<script>
|
|
||||||
$.widget.bridge('uibutton', $.ui.button)
|
|
||||||
</script>
|
|
||||||
<!-- Bootstrap 4 -->
|
<!-- Bootstrap 4 -->
|
||||||
<script src="/{$adminKey}/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
|
<script src="/{$adminKey}/lte_plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
<!-- ChartJS -->
|
|
||||||
<script src="/{$adminKey}/plugins/chart.js/Chart.min.js"></script>
|
|
||||||
<!-- Sparkline -->
|
|
||||||
<script src="/{$adminKey}/plugins/sparklines/sparkline.js"></script>
|
|
||||||
<!-- JQVMap -->
|
|
||||||
<script src="/{$adminKey}/plugins/jqvmap/jquery.vmap.min.js"></script>
|
|
||||||
<script src="/{$adminKey}/plugins/jqvmap/maps/jquery.vmap.usa.js"></script>
|
|
||||||
<!-- jQuery Knob Chart -->
|
|
||||||
<script src="/{$adminKey}/plugins/jquery-knob/jquery.knob.min.js"></script>
|
|
||||||
<!-- daterangepicker -->
|
|
||||||
<script src="/{$adminKey}/plugins/moment/moment.min.js"></script>
|
|
||||||
<script src="/{$adminKey}/plugins/daterangepicker/daterangepicker.js"></script>
|
|
||||||
<!-- Tempusdominus Bootstrap 4 -->
|
|
||||||
<script src="/{$adminKey}/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
|
|
||||||
<!-- Summernote -->
|
|
||||||
<script src="/{$adminKey}/plugins/summernote/summernote-bs4.min.js"></script>
|
|
||||||
<!-- overlayScrollbars -->
|
|
||||||
<script src="/{$adminKey}/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
|
|
||||||
<!-- AdminLTE App -->
|
<!-- AdminLTE App -->
|
||||||
<script src="/{$adminKey}/dist/js/adminlte.js"></script>
|
<script src="/{$adminKey}/lte_dist/js/adminlte.js"></script>
|
||||||
|
{if $loadAsync}
|
||||||
|
<script src="/{$adminKey}/admin_dist/async.ts"></script>
|
||||||
|
{/if}
|
||||||
|
<script>
|
||||||
|
$.widget.bridge('uibutton', $.ui.button);
|
||||||
|
</script>
|
||||||
|
{ifset $footer}
|
||||||
|
{$footer|noescape}
|
||||||
|
{/ifset}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
332
src/FuzeWorks/Administration/AdminPlugin.php
Normal file → Executable file
332
src/FuzeWorks/Administration/AdminPlugin.php
Normal file → Executable file
@ -34,136 +34,252 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace FuzeWorks\Administration;
|
namespace FuzeWorks\Administration;
|
||||||
|
use FuzeWorks\Administration\Attributes\DisplayAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\FooterCodeMethodAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\IconAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PermissionAttribute;
|
||||||
|
use FuzeWorks\Authentication\AuthenticationPlugin;
|
||||||
|
use FuzeWorks\Authentication\Model\Session;
|
||||||
use FuzeWorks\Config;
|
use FuzeWorks\Config;
|
||||||
use FuzeWorks\ConfigORM\ConfigORM;
|
use FuzeWorks\ConfigORM\ConfigORM;
|
||||||
use FuzeWorks\Controllers;
|
use FuzeWorks\Controllers;
|
||||||
|
use FuzeWorks\Core;
|
||||||
use FuzeWorks\Event\LayoutLoadEvent;
|
use FuzeWorks\Event\LayoutLoadEvent;
|
||||||
|
use FuzeWorks\Event\RouterCallViewEvent;
|
||||||
use FuzeWorks\Event\RouteWebRequestEvent;
|
use FuzeWorks\Event\RouteWebRequestEvent;
|
||||||
use FuzeWorks\Events;
|
use FuzeWorks\Events;
|
||||||
|
use FuzeWorks\Exception\ConfigException;
|
||||||
|
use FuzeWorks\Exception\EventException;
|
||||||
|
use FuzeWorks\Exception\Exception;
|
||||||
|
use FuzeWorks\Exception\FactoryException;
|
||||||
|
use FuzeWorks\Exception\HaltException;
|
||||||
|
use FuzeWorks\Exception\LayoutException;
|
||||||
|
use FuzeWorks\Exception\OutputException;
|
||||||
|
use FuzeWorks\Exception\WebException;
|
||||||
use FuzeWorks\Factory;
|
use FuzeWorks\Factory;
|
||||||
|
use FuzeWorks\iPluginHeader;
|
||||||
use FuzeWorks\Layout;
|
use FuzeWorks\Layout;
|
||||||
use FuzeWorks\Logger;
|
use FuzeWorks\Logger;
|
||||||
use FuzeWorks\Models;
|
use FuzeWorks\Models;
|
||||||
|
use FuzeWorks\Output;
|
||||||
use FuzeWorks\Priority;
|
use FuzeWorks\Priority;
|
||||||
use FuzeWorks\Resources;
|
use FuzeWorks\Resources;
|
||||||
use FuzeWorks\Router;
|
use FuzeWorks\Router;
|
||||||
|
use FuzeWorks\View;
|
||||||
use FuzeWorks\Views;
|
use FuzeWorks\Views;
|
||||||
|
use ReflectionClass;
|
||||||
|
use ReflectionException;
|
||||||
|
|
||||||
class AdminPlugin implements \FuzeWorks\iPluginHeader
|
class AdminPlugin implements iPluginHeader
|
||||||
{
|
{
|
||||||
|
|
||||||
private $pluginKey = 'admin';
|
private Config $config;
|
||||||
|
private Router $router;
|
||||||
|
private Models $models;
|
||||||
|
private Views $views;
|
||||||
|
private Controllers $controllers;
|
||||||
|
private AuthenticationPlugin $authPlugin;
|
||||||
|
|
||||||
/** @var Config */
|
private string $pluginKey = 'admin';
|
||||||
private $config;
|
private string $pluginPath;
|
||||||
|
private string $adminURL;
|
||||||
|
private string $apiRoute;
|
||||||
|
private string $webRoute;
|
||||||
|
|
||||||
/** @var Router */
|
private ?Session $session = null;
|
||||||
private $router;
|
private bool $loadAsync = false;
|
||||||
|
|
||||||
/** @var Models */
|
|
||||||
private $models;
|
|
||||||
|
|
||||||
/** @var Views */
|
|
||||||
private $views;
|
|
||||||
|
|
||||||
/** @var Controllers */
|
|
||||||
private $controllers;
|
|
||||||
|
|
||||||
/** @var ConfigORM */
|
|
||||||
private $adminCFG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $pluginPath;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
|
* @throws EventException
|
||||||
|
* @throws FactoryException
|
||||||
|
* @throws ConfigException
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
// Make a listener for a web request
|
// Make a listener for a web request
|
||||||
Events::addListener([$this, 'routeWebRequestEventListener'], 'routeWebRequestEvent', Priority::NORMAL);
|
|
||||||
$this->pluginPath = dirname(__DIR__, 3);
|
$this->pluginPath = dirname(__DIR__, 3);
|
||||||
}
|
|
||||||
|
|
||||||
public function routeWebRequestEventListener(RouteWebRequestEvent $event)
|
// Load the admin configuration
|
||||||
{
|
$this->config = Factory::getInstance('config');
|
||||||
// If this request has nothing to do with the admin interface, don't bother routing the request
|
$this->config->addComponentPath($this->pluginPath, Priority::LOWEST);
|
||||||
if (substr($event->uriString, 0, strlen($this->pluginKey)) !== $this->pluginKey)
|
$adminCFG = $this->config->getConfig('admin');
|
||||||
|
|
||||||
|
// If admin is not enabled, stop here
|
||||||
|
if (!$adminCFG->get('admin_enabled'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger::log("Administration: observed admin request. Activating plugin.");
|
// Register the event
|
||||||
|
Events::addListener([$this, 'routeWebRequestEventListener'], 'routeWebRequestEvent', Priority::NORMAL);
|
||||||
|
|
||||||
|
// Now load the pluginKey
|
||||||
|
$this->pluginKey = $adminCFG->get('admin_url');
|
||||||
|
|
||||||
|
// Settle admin URL
|
||||||
|
$webURL = $this->config->getConfig("web")->get("base_url");
|
||||||
|
$this->adminURL = $webURL . "/" . $this->pluginKey;
|
||||||
|
|
||||||
|
// Determine routing paths
|
||||||
|
$this->webRoute = '^' . $this->pluginKey . '(|\/(?P<viewName>.*?)(|\/(?P<viewMethod>.*?)(|\/(?P<viewParameters>.*?))))';
|
||||||
|
$this->apiRoute = '^' . $this->pluginKey . '(|\/(?P<viewName>.*?)(|\/(?P<viewMethod>.*?)(|\/(?P<viewParameters>.*?)))).json';
|
||||||
|
|
||||||
// Load the dependencies
|
// Load the dependencies
|
||||||
$this->config = Factory::getInstance('config');
|
|
||||||
$this->router = Factory::getInstance('router');
|
$this->router = Factory::getInstance('router');
|
||||||
$this->models = Factory::getInstance('models');
|
$this->models = Factory::getInstance('models');
|
||||||
$this->views = Factory::getInstance('views');
|
$this->views = Factory::getInstance('views');
|
||||||
$this->controllers = Factory::getInstance('controllers');
|
$this->controllers = Factory::getInstance('controllers');
|
||||||
|
}
|
||||||
|
|
||||||
// Load the admin configuration
|
/**
|
||||||
$this->config->addComponentPath($this->pluginPath, Priority::LOWEST);
|
* @param RouteWebRequestEvent $event
|
||||||
$this->adminCFG = $this->config->getConfig('admin');
|
* @return void
|
||||||
|
* @throws FactoryException
|
||||||
// If admin is not enabled, stop here
|
* @throws WebException
|
||||||
if (!$this->adminCFG->get('admin_enabled'))
|
*/
|
||||||
return;
|
public function routeWebRequestEventListener(RouteWebRequestEvent $event): void
|
||||||
|
{
|
||||||
// Now load the pluginKey
|
Logger::log("Administration: observed web request. Activating plugin.");
|
||||||
$this->pluginKey = $this->adminCFG->get('admin_url');
|
|
||||||
|
|
||||||
// If it does, register everything
|
// If it does, register everything
|
||||||
/** @var Resources $resources */
|
/** @var Resources $resources */
|
||||||
$resources = Factory::getInstance('resources');
|
$resources = Factory::getInstance('resources');
|
||||||
|
|
||||||
// Serve the AdminLTE distribution files
|
// Serve the AdminLTE distribution files
|
||||||
$adminLTE = $this->pluginPath . DS . 'vendor' . DS . 'almasaeed2010' . DS . 'adminlte';
|
$adminLTE = dirname(Core::$coreDir, 4) . DS . 'vendor' . DS . 'almasaeed2010' . DS . 'adminlte';
|
||||||
$resources->registerResources('admin/dist', $adminLTE . DS . 'dist');
|
$resources->registerResources('admin/lte_dist', $adminLTE . DS . 'dist');
|
||||||
$resources->registerResources('admin/plugins', $adminLTE . DS . 'plugins');
|
$resources->registerResources('admin/lte_plugins', $adminLTE . DS . 'plugins');
|
||||||
|
$resources->registerResources("admin/admin_dist", $this->pluginPath . DS . 'www' . DS . 'dist');
|
||||||
|
|
||||||
|
// @todo TEMPORARY!!
|
||||||
|
//$resources->registerResources("lte_top", $adminLTE);
|
||||||
|
|
||||||
// And serve the actual pages
|
// And serve the actual pages
|
||||||
$routeString = '^' . $this->pluginKey . '(|\/(?P<viewName>.*?)(|\/(?P<viewMethod>.*?)(|\/(?P<viewParameters>.*?))))';
|
$this->router->addRoute('^' . $this->pluginKey, ['viewName' => 'dashboard', 'callable' => [$this, 'adminCallable']], Priority::HIGHEST);
|
||||||
$this->router->addRoute($routeString, ['callable' => [$this, 'adminCallable']], Priority::HIGHEST);
|
$this->router->addRoute($this->apiRoute, ['callable' => [$this, 'adminCallable']], Priority::HIGH);
|
||||||
|
$this->router->addRoute($this->webRoute, ['callable' => [$this, 'adminCallable']], Priority::HIGH);
|
||||||
// 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)
|
/**
|
||||||
|
* @param array $matches
|
||||||
|
* @param array $routeData
|
||||||
|
* @param string $routeString
|
||||||
|
* @return string|null
|
||||||
|
* @throws EventException
|
||||||
|
* @throws FactoryException
|
||||||
|
* @throws LayoutException
|
||||||
|
* @throws OutputException
|
||||||
|
*/
|
||||||
|
public function adminCallable(array $matches, array $routeData, string $routeString): ?string
|
||||||
{
|
{
|
||||||
Logger::log("AdminCallable called. Loading admin page.");
|
Logger::log("AdminCallable called. Loading admin page.");
|
||||||
|
|
||||||
|
// Add componentPaths for models, views, controllers
|
||||||
|
$this->models->addComponentPath($this->pluginPath . DS . 'models' . DS . 'main', Priority::LOW);
|
||||||
|
$this->views->addComponentPath($this->pluginPath . DS . 'views' . DS . 'main', Priority::LOW);
|
||||||
|
$this->controllers->addComponentPath($this->pluginPath . DS . 'controllers' . DS . 'main', Priority::LOW);
|
||||||
|
|
||||||
// Load layouts and assign componentPath, in case the loaded view needs access to it
|
// Load layouts and assign componentPath, in case the loaded view needs access to it
|
||||||
/** @var Layout $layouts */
|
/** @var Layout $layouts */
|
||||||
$layouts = Factory::getInstance('layouts');
|
$layouts = Factory::getInstance('layouts');
|
||||||
$layouts->addComponentPath($this->pluginPath . DS . 'layouts', Priority::LOW);
|
$layouts->addComponentPath($this->pluginPath . DS . 'layouts', Priority::LOW);
|
||||||
|
|
||||||
// And add a layoutLoadEventListener, to add global administration variables
|
// And add a layoutLoadEventListener, to add global administration variables
|
||||||
Events::addListener([$this, 'layoutLoadEventListener'], 'layoutLoadEvent', Priority::NORMAL);
|
Events::addListener([$this, 'layoutLoadEventListener'], 'layoutLoadEvent', Priority::HIGH);
|
||||||
|
Events::addListener([$this, 'verifyViewPermissions'], 'routerCallViewEvent', Priority::HIGH);
|
||||||
|
Events::addListener([$this, 'logViewNameAndIcon'], 'routerCallViewEvent', Priority::NORMAL);
|
||||||
|
|
||||||
|
if (class_exists("\FuzeWorks\Async\Tasks"))
|
||||||
|
{
|
||||||
|
// Mark async to be loaded
|
||||||
|
$this->loadAsync = true;
|
||||||
|
|
||||||
|
// Add componentPaths for models, views, controllers
|
||||||
|
$this->models->addComponentPath($this->pluginPath . DS . 'models' . DS . 'async', Priority::LOW);
|
||||||
|
$this->views->addComponentPath($this->pluginPath . DS . 'views' . DS . 'async', Priority::LOW);
|
||||||
|
$this->controllers->addComponentPath($this->pluginPath . DS . 'controllers' . DS . 'async', Priority::LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the current session
|
||||||
|
/** @var Output $output */
|
||||||
|
$this->authPlugin = Factory::getInstance("plugins")->get('auth');
|
||||||
|
$output = Factory::getInstance("output");
|
||||||
|
|
||||||
|
// Redirect the user to login if they're not logged in
|
||||||
|
$this->session = $this->authPlugin->sessions->start();
|
||||||
|
if ($this->session->user->id === "0")
|
||||||
|
{
|
||||||
|
$output->setHeader("Location: " . $this->authPlugin->getAuthenticationURL() . "/login?location=" . $this->getAdminURL());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
// Let's generate the sidebar
|
// Let's generate the sidebar
|
||||||
$finder = new PageFinder();
|
$finder = new PageFinder();
|
||||||
$sidebar = $finder->generateSidebar();
|
$sidebar = $finder->generateSidebar($this->session);
|
||||||
|
$footer = "";
|
||||||
|
|
||||||
// Afterwards, pass on to the admin view and its contents
|
// Afterwards, pass on to the admin view and its contents
|
||||||
Logger::log("Forwarding request to Router::defaultCallable().");
|
Logger::log("Forwarding request to Router::defaultCallable().");
|
||||||
$matches['viewType'] = 'admin';
|
|
||||||
$content = $this->router->defaultCallable($matches, $routeString);
|
|
||||||
|
|
||||||
// Reset and assign
|
// Determine viewType
|
||||||
|
if ($routeString === $this->apiRoute)
|
||||||
|
$routeData['viewType'] = 'AdminAPI';
|
||||||
|
else
|
||||||
|
$routeData['viewType'] = 'admin';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch content from requested view
|
||||||
|
$content = $this->router->defaultCallable($matches, $routeData, $routeString);
|
||||||
|
|
||||||
|
// If content is false, nothing is found and should return 404
|
||||||
|
if (is_bool($content) && $content === false)
|
||||||
|
{
|
||||||
|
$output->setStatusHeader(404);
|
||||||
|
$content = $layouts->get("main/error404");
|
||||||
|
$this->selectedMethodName = "Not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
// And check for footer code
|
||||||
|
if (!empty($this->footerMethod))
|
||||||
|
{
|
||||||
|
if (!method_exists($this->selectedView, $this->footerMethod))
|
||||||
|
throw new Exception("Could not load view. Requested footerMethod not found.");
|
||||||
|
|
||||||
|
$footer = call_user_func_array([$this->selectedView, $this->footerMethod], []);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (HaltException $e) {
|
||||||
|
$output->setStatusHeader(403);
|
||||||
|
$content = $layouts->get("main/error403");
|
||||||
|
$this->selectedMethodName = "Unauthorized";
|
||||||
|
} catch (Exception|\Throwable $e) {
|
||||||
|
Logger::exceptionHandler($e, false);
|
||||||
|
$output->setStatusHeader(500);
|
||||||
|
$content = $layouts->get("main/error500");
|
||||||
|
$this->selectedMethodName = "Fatal error";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If an api is requested, return the content as a json object
|
||||||
|
if ($routeData['viewType'] === 'AdminAPI')
|
||||||
|
{
|
||||||
|
$output->setContentType('json');
|
||||||
|
return json_encode($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, load the panel and return that
|
||||||
Logger::log("Generating panel wrapper.");
|
Logger::log("Generating panel wrapper.");
|
||||||
$layouts->reset(false);
|
$layouts->reset(false);
|
||||||
|
$layouts->assign("pageTitle", $this->selectedMethodName);
|
||||||
|
$layouts->assign("pageIcon", $this->selectedMethodIcon);
|
||||||
$layouts->assign('sidebar', $sidebar);
|
$layouts->assign('sidebar', $sidebar);
|
||||||
$layouts->assign('content', $content);
|
$layouts->assign('content', $content);
|
||||||
|
$layouts->assign("footer", $footer);
|
||||||
|
|
||||||
// And load the page
|
return $layouts->get('main/panel');
|
||||||
Logger::log("Forwarding output back to Router.");
|
}
|
||||||
$page = $layouts->get('main/panel');
|
|
||||||
return $page;
|
public function getAdminURL(): string
|
||||||
|
{
|
||||||
|
return $this->adminURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,6 +292,98 @@ class AdminPlugin implements \FuzeWorks\iPluginHeader
|
|||||||
public function layoutLoadEventListener(LayoutLoadEvent $event)
|
public function layoutLoadEventListener(LayoutLoadEvent $event)
|
||||||
{
|
{
|
||||||
$event->assign('adminKey', $this->pluginKey);
|
$event->assign('adminKey', $this->pluginKey);
|
||||||
|
$event->assign('session', $this->session);
|
||||||
|
$event->assign('authURL', $this->authPlugin->getAuthenticationURL());
|
||||||
|
$event->assign("loadAsync", $this->loadAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener for RouterCallViewEvent
|
||||||
|
*
|
||||||
|
* Verifies that the current user has access to the requested methods.
|
||||||
|
*
|
||||||
|
* @param RouterCallViewEvent $event
|
||||||
|
* @return RouterCallViewEvent
|
||||||
|
* @throws ReflectionException
|
||||||
|
* @throws HaltException
|
||||||
|
*/
|
||||||
|
public function verifyViewPermissions(RouterCallViewEvent $event): RouterCallViewEvent
|
||||||
|
{
|
||||||
|
// Load reflector
|
||||||
|
$reflector = new ReflectionClass(get_class($event->view));
|
||||||
|
|
||||||
|
// Pass over each requested method
|
||||||
|
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++) {
|
||||||
|
if (!isset($event->viewMethods[$i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach ($event->viewMethods[$i] as $key => $method)
|
||||||
|
{
|
||||||
|
// If the method doesn't exist, skip it in general
|
||||||
|
if (!method_exists($event->view, $method))
|
||||||
|
{
|
||||||
|
unset($event->viewMethods[$i][$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the method exists, verify permission
|
||||||
|
$methodReflector = $reflector->getMethod($method);
|
||||||
|
$permissionAttributes = $methodReflector->getAttributes(PermissionAttribute::class);
|
||||||
|
if (!empty($permissionAttributes))
|
||||||
|
{
|
||||||
|
// Fetch nodes
|
||||||
|
$nodes = $permissionAttributes[0]->newInstance()->getValue();
|
||||||
|
|
||||||
|
// Check if any of the nodes are permitted
|
||||||
|
$found = false;
|
||||||
|
foreach ($nodes as $node)
|
||||||
|
if ($this->session->hasPermission($node))
|
||||||
|
$found = true;
|
||||||
|
|
||||||
|
// If not, skip
|
||||||
|
if (!$found)
|
||||||
|
{
|
||||||
|
|
||||||
|
Logger::logWarning("Current user does not have permission for the requested method. Blocking.");
|
||||||
|
$event->setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $event;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string $selectedMethodName = "";
|
||||||
|
protected string $selectedMethodIcon = "";
|
||||||
|
protected string $footerMethod = "";
|
||||||
|
protected View $selectedView;
|
||||||
|
|
||||||
|
public function logViewNameAndIcon(RouterCallViewEvent $event): RouterCallViewEvent
|
||||||
|
{
|
||||||
|
$reflector = new ReflectionClass(get_class($event->view));
|
||||||
|
$this->selectedView = $event->view;
|
||||||
|
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++)
|
||||||
|
{
|
||||||
|
if (!isset($event->viewMethods[$i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach ($event->viewMethods[$i] as $key => $method)
|
||||||
|
{
|
||||||
|
$methodReflector = $reflector->getMethod($method);
|
||||||
|
|
||||||
|
// Check for display attribute.
|
||||||
|
$displayAttributes = $methodReflector->getAttributes(DisplayAttribute::class);
|
||||||
|
$iconAttributes = $methodReflector->getAttributes(IconAttribute::class);
|
||||||
|
$footerAttributes = $methodReflector->getAttributes(FooterCodeMethodAttribute::class);
|
||||||
|
$this->selectedMethodName = !empty($displayAttributes) ? $displayAttributes[0]->newInstance()->getValue() : ucfirst($methodReflector->getName());
|
||||||
|
$this->selectedMethodIcon = !empty($iconAttributes) ? $iconAttributes[0]->newInstance()->getValue() : "";
|
||||||
|
$this->footerMethod = !empty($footerAttributes) ? $footerAttributes[0]->newInstance()->getvalue() : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,7 +391,7 @@ class AdminPlugin implements \FuzeWorks\iPluginHeader
|
|||||||
*/
|
*/
|
||||||
public function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return 'FuzeWorksAdministration';
|
return 'admin';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
21
src/FuzeWorks/Administration/AdminView.php
Normal file → Executable file
21
src/FuzeWorks/Administration/AdminView.php
Normal file → Executable file
@ -34,6 +34,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace FuzeWorks\Administration;
|
namespace FuzeWorks\Administration;
|
||||||
|
use FuzeWorks\Authentication\AuthenticationPlugin;
|
||||||
|
use FuzeWorks\Authentication\Model\Session;
|
||||||
|
use FuzeWorks\Authentication\Model\Users;
|
||||||
use FuzeWorks\Factory;
|
use FuzeWorks\Factory;
|
||||||
use FuzeWorks\Layout;
|
use FuzeWorks\Layout;
|
||||||
use FuzeWorks\Priority;
|
use FuzeWorks\Priority;
|
||||||
@ -41,21 +44,27 @@ use FuzeWorks\WebView;
|
|||||||
|
|
||||||
abstract class AdminView extends WebView
|
abstract class AdminView extends WebView
|
||||||
{
|
{
|
||||||
|
protected Layout $layouts;
|
||||||
/** @var Layout */
|
protected Session $session;
|
||||||
protected $layouts;
|
protected Users $users;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The priority of this AdminView.
|
* The priority of this AdminView.
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
protected $priority = Priority::NORMAL;
|
protected int $priority = Priority::NORMAL;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
// Set layouts
|
||||||
$this->layouts = Factory::getInstance('layouts');
|
$this->layouts = Factory::getInstance('layouts');
|
||||||
|
|
||||||
|
/** @var AuthenticationPlugin $plugin */
|
||||||
|
$plugin = $this->plugins->get('auth');
|
||||||
|
|
||||||
|
// Set current session
|
||||||
|
$this->users = $plugin->users;
|
||||||
|
$this->session = $plugin->sessions->getCurrentSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
41
src/FuzeWorks/Administration/Attributes/AdminAttribute.php
Executable file
41
src/FuzeWorks/Administration/Attributes/AdminAttribute.php
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksAdministration
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 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 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
|
||||||
|
interface AdminAttribute
|
||||||
|
{
|
||||||
|
|
||||||
|
public function getValue();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksAdministration
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2023 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 - 2023, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute]
|
||||||
|
class DashboardAttribute implements AdminAttribute
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
57
src/FuzeWorks/Administration/Attributes/DisplayAttribute.php
Executable file
57
src/FuzeWorks/Administration/Attributes/DisplayAttribute.php
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksAdministration
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 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 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute]
|
||||||
|
class DisplayAttribute implements AdminAttribute
|
||||||
|
{
|
||||||
|
|
||||||
|
const VALUE = '';
|
||||||
|
|
||||||
|
private string $value;
|
||||||
|
|
||||||
|
public function __construct(string $value = '')
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(): string
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksAdministration
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 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 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute]
|
||||||
|
class FooterCodeMethodAttribute implements AdminAttribute
|
||||||
|
{
|
||||||
|
|
||||||
|
const VALUE = '';
|
||||||
|
|
||||||
|
private string $value;
|
||||||
|
|
||||||
|
public function __construct(string $value = '')
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(): string
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
src/FuzeWorks/Administration/Attributes/HiddenAttribute.php
Executable file
44
src/FuzeWorks/Administration/Attributes/HiddenAttribute.php
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksAdministration
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 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 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute]
|
||||||
|
class HiddenAttribute implements AdminAttribute
|
||||||
|
{
|
||||||
|
public function getValue(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
53
src/FuzeWorks/Administration/Attributes/IconAttribute.php
Executable file
53
src/FuzeWorks/Administration/Attributes/IconAttribute.php
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksAdministration
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 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 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute]
|
||||||
|
class IconAttribute implements AdminAttribute
|
||||||
|
{
|
||||||
|
|
||||||
|
private string $value;
|
||||||
|
|
||||||
|
public function __construct(string $value = '')
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(): string
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksWorkspace.
|
||||||
|
*
|
||||||
|
* The FuzeWorks PHP FrameWork
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2022 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 - 2022, i15. (http://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @link https://i15.nl
|
||||||
|
* @since Version 2.0.0
|
||||||
|
*
|
||||||
|
* @version Version 2.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute]
|
||||||
|
class PermissionAttribute implements AdminAttribute
|
||||||
|
{
|
||||||
|
private array $nodes;
|
||||||
|
|
||||||
|
public function __construct(array $nodes = [])
|
||||||
|
{
|
||||||
|
$this->nodes = $nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(): array
|
||||||
|
{
|
||||||
|
return $this->nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
54
src/FuzeWorks/Administration/Attributes/PriorityAttribute.php
Executable file
54
src/FuzeWorks/Administration/Attributes/PriorityAttribute.php
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksAdministration
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 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 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Attributes;
|
||||||
|
use Attribute;
|
||||||
|
use FuzeWorks\Priority;
|
||||||
|
|
||||||
|
#[Attribute]
|
||||||
|
class PriorityAttribute implements AdminAttribute
|
||||||
|
{
|
||||||
|
|
||||||
|
private int $priority;
|
||||||
|
|
||||||
|
public function __construct(int $value = Priority::NORMAL)
|
||||||
|
{
|
||||||
|
$this->priority = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(): int
|
||||||
|
{
|
||||||
|
return $this->priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksWorkspace.
|
||||||
|
*
|
||||||
|
* The FuzeWorks PHP FrameWork
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2022 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 - 2022, i15. (http://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @link https://i15.nl
|
||||||
|
* @since Version 2.0.0
|
||||||
|
*
|
||||||
|
* @version Version 2.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Exceptions;
|
||||||
|
|
||||||
|
use FuzeWorks\Exception\PluginException;
|
||||||
|
|
||||||
|
class AdminPluginException extends PluginException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksWorkspace.
|
||||||
|
*
|
||||||
|
* The FuzeWorks PHP FrameWork
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2022 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 - 2022, i15. (http://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @link https://i15.nl
|
||||||
|
* @since Version 2.0.0
|
||||||
|
*
|
||||||
|
* @version Version 2.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FuzeWorks\Administration\Exceptions;
|
||||||
|
|
||||||
|
class UnauthorizedException extends AdminPluginException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
218
src/FuzeWorks/Administration/PageFinder.php
Normal file → Executable file
218
src/FuzeWorks/Administration/PageFinder.php
Normal file → Executable file
@ -35,13 +35,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace FuzeWorks\Administration;
|
namespace FuzeWorks\Administration;
|
||||||
|
use FuzeWorks\Administration\Attributes\DisplayAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\HiddenAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\IconAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PermissionAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PriorityAttribute;
|
||||||
|
use FuzeWorks\Administration\Events\AdminFindViewsEvent;
|
||||||
use FuzeWorks\Administration\Events\AdminGenerateSidebarEvent;
|
use FuzeWorks\Administration\Events\AdminGenerateSidebarEvent;
|
||||||
|
use FuzeWorks\Authentication\Model\Session;
|
||||||
use FuzeWorks\Events;
|
use FuzeWorks\Events;
|
||||||
use FuzeWorks\Factory;
|
use FuzeWorks\Factory;
|
||||||
use FuzeWorks\Logger;
|
use FuzeWorks\Logger;
|
||||||
use FuzeWorks\Priority;
|
use FuzeWorks\Priority;
|
||||||
use FuzeWorks\Views;
|
use FuzeWorks\Views;
|
||||||
use phpDocumentor\Reflection\DocBlockFactory;
|
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
@ -50,39 +56,56 @@ class PageFinder
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
protected Session $session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an array of all sidebar elements.
|
* Generates an array of all sidebar elements.
|
||||||
*
|
*
|
||||||
* First searches for all the available AdminViews. Then parses over all their methods and populates the array
|
* First searches for all the available AdminViews. Then parses over all their methods and populates the array
|
||||||
* using each method's individual docblock.
|
* using each method's attributes.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function generateSidebar(): array
|
public function generateSidebar(Session $session): array
|
||||||
{
|
{
|
||||||
|
$this->session = $session;
|
||||||
|
|
||||||
Logger::log("Generating sidebar...");
|
Logger::log("Generating sidebar...");
|
||||||
$event = Events::fireEvent('adminGenerateSidebarEvent');
|
$event = Events::fireEvent('adminGenerateSidebarEvent');
|
||||||
if ($event->isCancelled())
|
if ($event->isCancelled())
|
||||||
return [];
|
return [];
|
||||||
|
|
||||||
// First find all views
|
// First find all views
|
||||||
$viewFileList = $this->findViews();
|
$views = $this->findViews();
|
||||||
Logger::log("Found " . count($viewFileList) . ' admin views.');
|
Logger::log("Found " . count($views) . ' admin views.');
|
||||||
|
|
||||||
// Then sort all those views into methods in the sidebar
|
// Then sort all those views into methods in the sidebar
|
||||||
$sorted = $this->sort($viewFileList);
|
$sorted = $this->sortSidebar($views);
|
||||||
|
|
||||||
// Log the result and return
|
// Log the result and return
|
||||||
Logger::log("Found " . count($sorted) . ' entries for sidebar.');
|
Logger::log("Found " . count($sorted) . ' entries for sidebar.');
|
||||||
return $sorted;
|
return $sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all views that have methods with attributes of a specific kind.
|
||||||
|
*
|
||||||
|
* @param string $attributeClass
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function findViewsWithAttribute(string $attributeClass): array
|
||||||
|
{
|
||||||
|
// First find all admin views
|
||||||
|
$views = $this->findViews();
|
||||||
|
return $this->sortByAttribute($views, $attributeClass);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse over every view component path and find all admin views.
|
* Parse over every view component path and find all admin views.
|
||||||
*
|
*
|
||||||
* Return a file list.
|
* Return a file list.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
protected function findViews(): array
|
protected function findViews(): array
|
||||||
{
|
{
|
||||||
@ -95,7 +118,7 @@ class PageFinder
|
|||||||
$paths[$i] = $views->getComponentPaths($i);
|
$paths[$i] = $views->getComponentPaths($i);
|
||||||
|
|
||||||
// Then go over every individual paths
|
// Then go over every individual paths
|
||||||
$viewFiles = [];
|
$views = [];
|
||||||
foreach ($paths as $priority => $foldersArray)
|
foreach ($paths as $priority => $foldersArray)
|
||||||
{
|
{
|
||||||
foreach ($foldersArray as $folder)
|
foreach ($foldersArray as $folder)
|
||||||
@ -107,44 +130,79 @@ class PageFinder
|
|||||||
foreach ($contents as $file)
|
foreach ($contents as $file)
|
||||||
{
|
{
|
||||||
// If the file matches the expected filename, add it to the list
|
// If the file matches the expected filename, add it to the list
|
||||||
if (substr($file, 0, 11) === 'view.admin.' && !isset($viewFiles[$file]))
|
if (!str_starts_with($file, 'view.admin.'))
|
||||||
$viewFiles[$file] = $folder . DS . $file;
|
continue;
|
||||||
|
|
||||||
|
// Attempt to load the view
|
||||||
|
$viewFile = $folder . DS . $file;
|
||||||
|
$id = substr($file, 11, -4);
|
||||||
|
$className = 'Application\View\\' . ucfirst($id) . 'AdminView';
|
||||||
|
require_once($viewFile);
|
||||||
|
if (!class_exists($className))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$views[] = $className;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $viewFiles;
|
return $views;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function sort(array $viewFileList): array
|
/**
|
||||||
|
* Returns all views which have methods which have Attributes with the attributeClassName
|
||||||
|
*
|
||||||
|
* @param string[] $views
|
||||||
|
* @param string $attributeClassName
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
protected function sortByAttribute(array $views, string $attributeClassName): array
|
||||||
{
|
{
|
||||||
// Reflection docblock factory
|
$out = [];
|
||||||
$factory = DocBlockFactory::createInstance();
|
foreach ($views as $view)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$reflector = new ReflectionClass($view);
|
||||||
|
} catch (ReflectionException $e) {
|
||||||
|
// If reflector doesn't work, simply ignore it.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the class actually inherits AdminView
|
||||||
|
if (!$reflector->isSubclassOf(AdminView::class))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Select all methods
|
||||||
|
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||||
|
foreach ($methods as $method)
|
||||||
|
if (!empty($method->getAttributes($attributeClassName)))
|
||||||
|
$out[] = $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sortSidebar(array $views): array
|
||||||
|
{
|
||||||
// Start sorting all methods
|
// Start sorting all methods
|
||||||
$entries = [];
|
$entries = [];
|
||||||
foreach ($viewFileList as $viewId => $viewFile)
|
foreach ($views as $view)
|
||||||
{
|
{
|
||||||
// Load the file
|
|
||||||
require_once $viewFile;
|
|
||||||
|
|
||||||
// Determine the className
|
|
||||||
$id = substr($viewId, 11, -4);
|
|
||||||
$className = 'Application\View\\' . ucfirst($id) . 'AdminView';
|
|
||||||
|
|
||||||
// Try and reflect on this class.
|
// Try and reflect on this class.
|
||||||
try {
|
try {
|
||||||
$reflector = new ReflectionClass($className);
|
$reflector = new ReflectionClass($view);
|
||||||
} catch (ReflectionException $e) {
|
} catch (ReflectionException $e) {
|
||||||
// If that doesn't work, simply ignore it. Don't drag the whole interface down.
|
// If that doesn't work, simply ignore it. Don't drag the whole interface down.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this class actually inherits AdminView
|
// Check if this class actually inherits AdminView
|
||||||
$parent = $reflector->getParentClass();
|
if (!$reflector->isSubclassOf("FuzeWorks\Administration\AdminView"))
|
||||||
if ($parent === false || $parent->getName() !== 'FuzeWorks\Administration\AdminView')
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Determine view Id
|
||||||
|
$id = strtolower(substr($reflector->getShortName(), 0, -9));
|
||||||
|
|
||||||
// Select all methods
|
// Select all methods
|
||||||
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
|
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||||
|
|
||||||
@ -154,77 +212,75 @@ class PageFinder
|
|||||||
$entry = [
|
$entry = [
|
||||||
'url' => ($id !== 'index' ? $id : '') . ($method->getName() !== 'index' ? '/' . $method->getName() : ''),
|
'url' => ($id !== 'index' ? $id : '') . ($method->getName() !== 'index' ? '/' . $method->getName() : ''),
|
||||||
'priority' => Priority::NORMAL,
|
'priority' => Priority::NORMAL,
|
||||||
'display' => $reflector->getShortName() . '/' . $method->getName(),
|
'display' => $reflector->getShortName() . '::' . $method->getName(),
|
||||||
'icon' => 'round'
|
'icon' => 'round'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Only allow the methods in the actual class. Not from the parent method.
|
// Only allow the methods in the actual class. Not from the parent method.
|
||||||
if ($method->class !== $className)
|
if ($method->class !== $view)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Then fetch the docComments.
|
// Read attributes
|
||||||
$docComment = $method->getDocComment();
|
// First read hidden attribute. If present, skip this method
|
||||||
if ($docComment !== false)
|
$hiddenAttributes = $method->getAttributes(HiddenAttribute::class);
|
||||||
{
|
if (!empty($hiddenAttributes))
|
||||||
$docBlock = $factory->create($docComment);
|
|
||||||
$docTags = $docBlock->getTags();
|
|
||||||
|
|
||||||
// Find known tags
|
|
||||||
$hidden = $docBlock->getTagsByName('hidden');
|
|
||||||
$display = $docBlock->getTagsByName('display');
|
|
||||||
$icon = $docBlock->getTagsByName('icon');
|
|
||||||
$priority = $docBlock->getTagsByName('priority');
|
|
||||||
|
|
||||||
// First test for hidden. If found, it should not be added to the sidebar
|
|
||||||
if (!empty($hidden))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Then test for display
|
// Then check for permissions
|
||||||
if (!empty($display))
|
$permissionAttributes = $method->getAttributes(PermissionAttribute::class);
|
||||||
$entry['display'] = (string) $display[0];
|
if (!empty($permissionAttributes))
|
||||||
|
|
||||||
// Then test for icon
|
|
||||||
if (!empty($icon))
|
|
||||||
$entry['icon'] = (string) $icon[0];
|
|
||||||
|
|
||||||
// Then test for priority
|
|
||||||
if (!empty($priority))
|
|
||||||
{
|
{
|
||||||
$priority = (string) $priority[0];
|
// Fetch nodes
|
||||||
switch ($priority) {
|
$nodes = $permissionAttributes[0]->newInstance()->getValue();
|
||||||
case 'Priority::LOWEST':
|
|
||||||
$entry['priority'] = 5;
|
// Check if any of the nodes are permitted
|
||||||
break;
|
$found = false;
|
||||||
case 'Priority::LOW':
|
foreach ($nodes as $node)
|
||||||
$entry['priority'] = 4;
|
if ($this->session->hasPermission($node))
|
||||||
break;
|
$found = true;
|
||||||
case 'Priority::NORMAL':
|
|
||||||
$entry['priority'] = 3;
|
// If not, skip
|
||||||
break;
|
if (!$found)
|
||||||
case 'Priority::HIGH':
|
continue;
|
||||||
$entry['priority'] = 2;
|
|
||||||
break;
|
|
||||||
case 'Priority::HIGHEST':
|
|
||||||
$entry['priority'] = 1;
|
|
||||||
break;
|
|
||||||
case 'Priority::MONITOR':
|
|
||||||
$entry['priority'] = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Logger::logError("Method " . $reflector->getName() . '::' . $method->getName() . ' has invalid value for @priority.');
|
|
||||||
$entry['priority'] = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Then check for display attribute.
|
||||||
|
$displayAttributes = $method->getAttributes(DisplayAttribute::class);
|
||||||
|
if (!empty($displayAttributes))
|
||||||
|
$entry['display'] = $displayAttributes[0]->newInstance()->getValue();
|
||||||
|
|
||||||
|
// Then check for icon
|
||||||
|
$iconAttributes = $method->getAttributes(IconAttribute::class);
|
||||||
|
if (!empty($iconAttributes))
|
||||||
|
$entry['icon'] = $iconAttributes[0]->newInstance()->getValue();
|
||||||
|
|
||||||
|
// Then check for priority
|
||||||
|
$priorityAttributes = $method->getAttributes(PriorityAttribute::class);
|
||||||
|
if (!empty($priorityAttributes))
|
||||||
|
$entry['priority'] = $priorityAttributes[0]->newInstance()->getValue();
|
||||||
|
|
||||||
|
// Add priority
|
||||||
|
if (!isset($entries[$entry['priority']]))
|
||||||
|
$entries[$entry['priority']] = [];
|
||||||
|
|
||||||
// Write to entries
|
// Write to entries
|
||||||
$entries[] = $entry;
|
$entries[$entry['priority']][] = $entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// And finally return those
|
// Sort by priority
|
||||||
return $entries;
|
$out = [];
|
||||||
|
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++) {
|
||||||
|
if (!isset($entries[$i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$p = $entries[$i];
|
||||||
|
foreach ($p as $entry)
|
||||||
|
$out[] = $entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And finally return the sidebar entries
|
||||||
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
0
test/bootstrap.php
Normal file → Executable file
0
test/bootstrap.php
Normal file → Executable file
76
views/async/view.admin.async.php
Normal file
76
views/async/view.admin.async.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* i15Site.
|
||||||
|
*
|
||||||
|
* The FuzeWorks PHP FrameWork
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2022 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 - 2022, i15. (http://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @link https://i15.nl
|
||||||
|
* @since Version 2.0.0
|
||||||
|
*
|
||||||
|
* @version Version 2.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Application\View;
|
||||||
|
use Application\Controller\AsyncController;
|
||||||
|
use FuzeWorks\Administration\AdminView;
|
||||||
|
use FuzeWorks\Administration\Attributes\DisplayAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\HiddenAttribute;
|
||||||
|
use FuzeWorks\Async\Tasks;
|
||||||
|
use FuzeWorks\Controller;
|
||||||
|
|
||||||
|
class AsyncAdminView extends AdminView
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AsyncController
|
||||||
|
*/
|
||||||
|
protected Controller $controller;
|
||||||
|
protected Tasks $tasks;
|
||||||
|
|
||||||
|
#[HiddenAttribute]
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
/** @var Tasks $lib */
|
||||||
|
$lib = $this->libraries->get("tasks");
|
||||||
|
$this->tasks = $lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[HiddenAttribute]
|
||||||
|
#[DisplayAttribute("Overview")]
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
// Read out all tasks
|
||||||
|
$storage = $this->tasks->getTaskStorage();
|
||||||
|
$tasks = $storage->readTasks();
|
||||||
|
|
||||||
|
// And assign them
|
||||||
|
$this->layouts->assign("tasks", $tasks);
|
||||||
|
return json_encode($tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
67
views/async/view.adminapi.async.php
Normal file
67
views/async/view.adminapi.async.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* i15Site.
|
||||||
|
*
|
||||||
|
* The FuzeWorks PHP FrameWork
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2022 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 - 2022, i15. (http://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @link https://i15.nl
|
||||||
|
* @since Version 2.0.0
|
||||||
|
*
|
||||||
|
* @version Version 2.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Application\View;
|
||||||
|
|
||||||
|
use Application\Controller\AsyncController;
|
||||||
|
use FuzeWorks\Administration\AdminView;
|
||||||
|
use FuzeWorks\Async\Tasks;
|
||||||
|
use FuzeWorks\Controller;
|
||||||
|
|
||||||
|
class AsyncAdminApiView extends AdminView
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var AsyncController
|
||||||
|
*/
|
||||||
|
protected Controller $controller;
|
||||||
|
protected Tasks $tasks;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
/** @var Tasks $lib */
|
||||||
|
$lib = $this->libraries->get("tasks");
|
||||||
|
$this->tasks = $lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return ["Hello world"];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
views/main/view.admin.cache.php
Normal file
32
views/main/view.admin.cache.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Application\View;
|
||||||
|
|
||||||
|
use Application\Controller\CacheController;
|
||||||
|
use FuzeWorks\Administration\AdminView;
|
||||||
|
use FuzeWorks\Administration\Attributes\DisplayAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\HiddenAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\IconAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PermissionAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PriorityAttribute;
|
||||||
|
use FuzeWorks\Controller;
|
||||||
|
use FuzeWorks\Factory;
|
||||||
|
use FuzeWorks\ObjectStorage\ObjectStorageComponent;
|
||||||
|
use FuzeWorks\Priority;
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
|
class CacheAdminView extends AdminView
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var CacheController $controller */
|
||||||
|
protected Controller $controller;
|
||||||
|
#[DisplayAttribute("ObjectStorage"), IconAttribute("server"), PriorityAttribute(Priority::LOW)]
|
||||||
|
#[HiddenAttribute]
|
||||||
|
#[PermissionAttribute(["ADMIN"])]
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$items = $this->controller->getCacheItems();
|
||||||
|
return json_encode($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
views/view.admin.settings.php → views/main/view.admin.dashboard.php
Normal file → Executable file
42
views/view.admin.settings.php → views/main/view.admin.dashboard.php
Normal file → Executable file
@ -34,43 +34,33 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Application\View;
|
namespace Application\View;
|
||||||
use Application\Controller\SettingsController;
|
use Application\Controller\DashboardController;
|
||||||
use FuzeWorks\Administration\AdminView;
|
use FuzeWorks\Administration\AdminView;
|
||||||
|
use FuzeWorks\Administration\Attributes\DashboardAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\DisplayAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\HiddenAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\IconAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PriorityAttribute;
|
||||||
|
use FuzeWorks\Controller;
|
||||||
|
use FuzeWorks\Priority;
|
||||||
|
|
||||||
class SettingsAdminView extends AdminView
|
class DashboardAdminView extends AdminView
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var SettingsController
|
* @var DashboardController
|
||||||
*/
|
*/
|
||||||
protected $controller;
|
protected Controller $controller;
|
||||||
|
|
||||||
/**
|
#[DisplayAttribute("Dashboard"), IconAttribute("tachometer-alt"), PriorityAttribute(Priority::HIGHEST)]
|
||||||
* Displays a list of settings files
|
|
||||||
*
|
|
||||||
* @display Settings
|
|
||||||
* @icon cog
|
|
||||||
* @priority Priority::LOW
|
|
||||||
*/
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$files = $this->controller->findSettingsFiles();
|
//$content = $this->controller->populateDashboard();
|
||||||
$this->layouts->assign('files', $files);
|
//$this->layouts->assign('content', $content);
|
||||||
return $this->layouts->get('components/settings/overview');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[HiddenAttribute, DashboardAttribute("Hello!")]
|
||||||
* @hidden
|
public function test()
|
||||||
*/
|
|
||||||
public function view()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
public function modify()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
124
views/main/view.admin.settings.php
Executable file
124
views/main/view.admin.settings.php
Executable file
@ -0,0 +1,124 @@
|
|||||||
|
<?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 Application\View;
|
||||||
|
use Application\Controller\SettingsController;
|
||||||
|
use FuzeWorks\Administration\AdminView;
|
||||||
|
use FuzeWorks\Administration\Attributes\DisplayAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\HiddenAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\IconAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PermissionAttribute;
|
||||||
|
use FuzeWorks\Administration\Attributes\PriorityAttribute;
|
||||||
|
use FuzeWorks\Controller;
|
||||||
|
use FuzeWorks\Exception\NotFoundException;
|
||||||
|
use FuzeWorks\Forms\Fields\CheckboxField;
|
||||||
|
use FuzeWorks\Forms\Fields\TextField;
|
||||||
|
use FuzeWorks\Forms\Forms;
|
||||||
|
use FuzeWorks\Priority;
|
||||||
|
|
||||||
|
class SettingsAdminView extends AdminView
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SettingsController
|
||||||
|
*/
|
||||||
|
protected Controller $controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a list of settings files
|
||||||
|
*/
|
||||||
|
#[DisplayAttribute("Config"), IconAttribute("cog"), PriorityAttribute(Priority::LOWEST)]
|
||||||
|
#[PermissionAttribute(["SUPER"])]
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$files = $this->controller->findSettingsFiles();
|
||||||
|
$this->layouts->assign('files', $files);
|
||||||
|
return $this->layouts->get('components/settings/overview');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NotFoundException
|
||||||
|
*/
|
||||||
|
#[HiddenAttribute, DisplayAttribute("View config file")]
|
||||||
|
#[PermissionAttribute(["SUPER"])]
|
||||||
|
public function view(string $request)
|
||||||
|
{
|
||||||
|
// Determine parts
|
||||||
|
$parts = explode("/", $request);
|
||||||
|
$file = $parts[0];
|
||||||
|
$selector = intval($parts[1]);
|
||||||
|
|
||||||
|
// Select the file
|
||||||
|
$data = $this->controller->fetchFile($file, $selector);
|
||||||
|
|
||||||
|
// Create a form out of the data
|
||||||
|
/** @var Forms $forms */
|
||||||
|
$forms = $this->libraries->get("forms");
|
||||||
|
$form = $forms->getForm("ConfigEdit");
|
||||||
|
foreach ($data['data'] as $key => $value)
|
||||||
|
{
|
||||||
|
switch (gettype($value))
|
||||||
|
{
|
||||||
|
case "string":
|
||||||
|
case "integer":
|
||||||
|
$field = new TextField($key);
|
||||||
|
$field->setLabel($key)->setValue($value)->lock();
|
||||||
|
$form->field($field);
|
||||||
|
break;
|
||||||
|
case "boolean":
|
||||||
|
$field = new CheckboxField($key);
|
||||||
|
$field->setLabel($key)->setValue($value)->lock();
|
||||||
|
$form->field($field);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dump(gettype($value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign and load layout
|
||||||
|
$this->layouts->assign('config', $data);
|
||||||
|
$this->layouts->assign('form', $form);
|
||||||
|
return $this->layouts->get('components/settings/view');
|
||||||
|
}
|
||||||
|
|
||||||
|
#[HiddenAttribute, DisplayAttribute("Edit config file")]
|
||||||
|
#[PermissionAttribute(["SUPER"])]
|
||||||
|
public function modify()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
0
www/.htaccess
Normal file → Executable file
0
www/.htaccess
Normal file → Executable file
29
www/dist/async.ts
vendored
Normal file
29
www/dist/async.ts
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
class AsyncManager {
|
||||||
|
protected readonly url: string = "/admin/async";
|
||||||
|
|
||||||
|
constructor(url?: string) {
|
||||||
|
if (url !== undefined)
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTaskList(onSuccess: Function, onError?: Function): void {
|
||||||
|
let xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", this.url + ".json", true);
|
||||||
|
xhr.send();
|
||||||
|
// @todo Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let async: AsyncManager = new AsyncManager();
|
||||||
|
|
||||||
|
const url = "/admin/async";
|
||||||
|
let xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", url + ".json", true);
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
xhr.onload = function () {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
0
www/index.php
Normal file → Executable file
0
www/index.php
Normal file → Executable file
Loading…
Reference in New Issue
Block a user