All changes as implemented over the last 3 years.

Pushes Administration into a workable state.
This commit is contained in:
Abel Hoogeveen 2023-02-08 12:57:10 +01:00
parent 50608c18e7
commit 63ea659d5b
38 changed files with 2396 additions and 1232 deletions

26
Dockerfile Normal file → Executable file
View File

@ -1,16 +1,12 @@
FROM php:7.3-apache
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
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/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
RUN a2enmod rewrite
# Amend permissions
COPY --chown=www-data . /usr/src/admin
FROM registry.i15.nl/i15/fuzephp:8.1-apache
MAINTAINER i15 <abel@i15.nl>
# Write application to image
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/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
RUN a2enmod rewrite
# Amend permissions
COPY --chown=www-data . /usr/src/admin
RUN chmod -R 777 /usr/src/admin/test/temp

40
LICENSE Normal file → Executable file
View File

@ -1,21 +1,21 @@
MIT License
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
MIT License
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.

58
composer.json Normal file → Executable file
View File

@ -1,32 +1,28 @@
{
"name": "fuzeworks/administration",
"description": "description",
"minimum-stability": "stable",
"license": ["MIT"],
"authors": [
{
"name": "Abel Hoogeveen",
"email": "abel@i15.nl"
}
],
"require": {
"php": ">=7.2.0",
"fuzeworks/core": "~1.2",
"fuzeworks/mvcr": "~1.2",
"fuzeworks/webcomponent": "~1.2",
"fuzeworks/layout": "~1.2",
"fuzeworks/database": "~1.2",
"latte/latte": "^2",
"almasaeed2010/adminlte": "^3",
"phpdocumentor/reflection-docblock": "^5"
},
"require-dev": {
"phpunit/phpunit": "^9",
"fuzeworks/tracycomponent": "~1.2"
},
"autoload": {
"psr-4": {
"FuzeWorks\\Administration\\": "src/FuzeWorks/Administration/"
}
}
{
"name": "fuzeworks/administration",
"description": "Administration interface for FuzeWorks",
"license": ["MIT"],
"authors": [
{
"name": "Abel Hoogeveen",
"email": "abel@i15.nl"
}
],
"require": {
"php": ">=8.1.0",
"fuzeworks/webcomponent": "~1.3.0",
"fuzeworks/authentication": "~1.3.0",
"fuzeworks/layout": "~1.3.0",
"latte/latte": "~2.5",
"almasaeed2010/adminlte": "^3"
},
"require-dev": {
"fuzeworks/tracycomponent": "~1.3.0",
"phpunit/phpunit": "^9"
},
"autoload": {
"psr-4": {
"FuzeWorks\\Administration\\": "src/FuzeWorks/Administration/"
}
}
}

74
config.admin.php Normal file → Executable file
View File

@ -1,38 +1,38 @@
<?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
*/
return [
'admin_enabled' => true,
'admin_url' => 'admin'
<?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
*/
return [
'admin_enabled' => true,
'admin_url' => 'admin'
];

View File

@ -1,10 +1,10 @@
<?php
/**
* FuzeWorks Framework Administration Plugin.
* i15Site.
*
* 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
* of this software and associated documentation files (the "Software"), to deal
@ -25,18 +25,18 @@
* SOFTWARE.
*
* @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
*
* @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;
use FuzeWorks\WebController;
class IndexController extends WebController
class AsyncController extends WebController
{
}

View 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;
}
}

View File

@ -1,55 +1,50 @@
<?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 FuzeWorks\Administration\AdminView;
class IndexAdminView extends AdminView
{
/**
* Hello!
*
* This does a lot of things
*
* @display Dashboard
* @icon tachometer-alt
* @priority Priority::HIGHEST
*/
public function index()
{
}
<?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\Controller;
use FuzeWorks\Administration\Attributes\DashboardAttribute;
use FuzeWorks\Administration\PageFinder;
use FuzeWorks\WebController;
class DashboardController extends WebController
{
public function populateDashboard()
{
$finder = new PageFinder();
$views = $finder->findViewsWithAttribute(DashboardAttribute::class);
}
}

View File

@ -1,80 +1,130 @@
<?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\Controller;
use FuzeWorks\Core;
use FuzeWorks\Priority;
use FuzeWorks\WebController;
class SettingsController extends WebController
{
public function findSettingsFiles(): array
{
// First collect all the known paths
$paths = [];
for ($i = Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++)
$paths[$i] = $this->config->getComponentPaths($i);
// And add the CorePath
$paths[Priority::getLowestPriority()][] = Core::$coreDir . DS . 'Config';
// Then go over every individual paths
$configFiles = [];
foreach ($paths as $priority => $foldersArray)
{
foreach ($foldersArray as $folder)
{
// Get the contents from the folder
$contents = array_diff(scandir($folder), array('..', '.'));
// Then go over the folders, and see which ones are an admin view
foreach ($contents as $file)
{
// If the file matches the expected filename, add it to the list
if (substr($file, 0, 7) === 'config.' && !isset($configFiles[$file]))
$configFiles[$file] = ['folder' => $folder, 'priority' => substr(Priority::getPriority($priority), 10)];
}
}
}
// At the end, sort the files
ksort($configFiles);
// And return them
return $configFiles;
}
<?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\Controller;
use FuzeWorks\Core;
use FuzeWorks\Exception\NotFoundException;
use FuzeWorks\Priority;
use FuzeWorks\WebController;
class SettingsController extends WebController
{
public function findSettingsFiles(): array
{
// First collect all the known paths
$paths = [];
for ($i = Priority::getHighestPriority(); $i <= Priority::getLowestPriority(); $i++)
$paths[$i] = $this->config->getComponentPaths($i);
// Then go over every individual paths
$configFiles = [];
foreach ($paths as $priority => $foldersArray) {
foreach ($foldersArray as $folder) {
// Get the contents from the folder
$contents = array_diff(scandir($folder), array('..', '.'));
// Then go over the folders, and see which ones are an admin view
foreach ($contents as $file) {
// If the file matches the expected filename, add it to the list
if (str_starts_with($file, 'config.')) {
if (!isset($configFiles[$file]))
$configFiles[$file] = [];
$configFiles[$file][] = ['folder' => $folder, 'priority' => substr(Priority::getPriority($priority), 10)];
}
}
}
}
// At the end, sort the files
ksort($configFiles);
// And return them
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;
}
}

View File

77
layouts/components/settings/layout.overview.latte Normal file → Executable file
View File

@ -1,40 +1,39 @@
<div class="row">
<div class="col-xl-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Configuration Files</h3>
</div>
<!-- /.card-header -->
<div class="card-body p-0">
<table class="table table-striped">
<thead>
<tr>
<th style="width: 10px">#</th>
<th>Name</th>
<th>Folder</th>
<th>Priority</th>
<th style="width: 20px">View</th>
<th style="width: 20px">Edit</th>
</tr>
</thead>
<tbody>
{foreach $files as $fileName => $data}
<tr>
<td>{$iterator->getCounter()}</td>
<td>{$fileName}</td>
<td>{$data['folder']}</td>
<td>{$data['priority']}</td>
<td><button type="button" class="btn btn-block btn-success">VIEW</button></td>
<td><button type="button" class="btn btn-block btn-primary">EDIT</button></td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- /.card-body -->
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Configuration Files</h3>
</div>
<!-- /.card-header -->
<div class="card-body p-0">
<table class="table table-striped">
<thead>
<tr>
<th style="width: 10px">#</th>
<th>Name</th>
<th>Folder</th>
<th>Priority</th>
<th style="width: 20px">View</th>
<th style="width: 20px">Edit</th>
</tr>
</thead>
<tbody>
{var $it = 0}
{foreach $files as $fileName => $data}
<tr n:foreach="$data as $entry">
{var $it = $it + 1}
<td>{$it}</td>
<td>{$fileName}</td>
<td>{$entry['folder']}</td>
<td>{$entry['priority']}</td>
<td><a href="/{$adminKey}/settings/view/{$fileName}/{$iterator->counter0}"><button type="button" class="btn btn-block btn-success">VIEW</button></a></td>
<td><a href="/{$adminKey}/settings/modify/{$fileName}/{$iterator->counter0}"><button type="button" class="btn btn-block btn-primary">EDIT</button></a></td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- /.card-body -->
</div>
</div>
</div>

View 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>

View 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>

View 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 -->

View 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 -->

View 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 -->

426
layouts/main/layout.panel.latte Normal file → Executable file
View File

@ -1,268 +1,158 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>AdminLTE 3 | Dashboard</title>
<!-- Tell the browser to be responsive to screen width -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Font Awesome -->
<link rel="stylesheet" href="/{$adminKey}/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 -->
<link rel="stylesheet" href="/{$adminKey}/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 -->
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<div class="wrapper">
<!-- Navbar -->
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<!-- Left navbar links -->
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="/" class="nav-link">Home</a>
</li>
</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 -->
<ul class="navbar-nav ml-auto">
<!-- Messages Dropdown Menu -->
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="far fa-comments"></i>
<span class="badge badge-danger navbar-badge">3</span>
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<a href="#" class="dropdown-item">
<!-- 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>
<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>
<a href="#" class="dropdown-item">
<!-- 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>
</li>
<!-- Notifications Dropdown Menu -->
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="far fa-bell"></i>
<span class="badge badge-warning navbar-badge">15</span>
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<span class="dropdown-item dropdown-header">15 Notifications</span>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">
<i class="fas fa-envelope mr-2"></i> 4 new messages
<span class="float-right text-muted text-sm">3 mins</span>
</a>
<div class="dropdown-divider"></div>
<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 class="nav-item">
<a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#" role="button">
<i class="fas fa-th-large"></i>
</a>
</li>
</ul>
</nav>
<!-- /.navbar -->
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-primary elevation-4">
<!-- Brand Logo -->
<a href="index3.html" class="brand-link">
<img src="/{$adminKey}/dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3"
style="opacity: .8">
<span class="brand-text font-weight-light">AdminLTE 3</span>
</a>
<!-- 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 -->
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
{foreach $sidebar as $item}
<li class="nav-item">
<a href="/{$adminKey}/{$item['url']}" class="nav-link">
<i class="nav-icon fas fa-{$item['icon']}"></i>
<p>{$item['display']}</p>
</a>
</li>
{/foreach}
</ul>
</nav>
<!-- /.sidebar-menu -->
</div>
<!-- /.sidebar -->
</aside>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0 text-dark">Dashboard</h1>
</div><!-- /.col -->
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active">Dashboard v1</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<section class="content">
<div class="container-fluid">
{$content|noescape}
</div><!-- /.container-fluid -->
</section>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<footer class="main-footer">
<strong>Copyright &copy; 2013-2020 <a href="https://i15.nl">i15.nl</a>.</strong>
All rights reserved.
<div class="float-right d-none d-sm-inline-block">
<b>Version</b> 1.3.0
</div>
</footer>
<!-- Control Sidebar -->
<aside class="control-sidebar control-sidebar-dark">
<!-- Control sidebar content goes here -->
</aside>
<!-- /.control-sidebar -->
</div>
<!-- ./wrapper -->
<!-- jQuery -->
<script src="/{$adminKey}/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 -->
<script src="/{$adminKey}/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 -->
<script src="/{$adminKey}/dist/js/adminlte.js"></script>
</body>
</html>
{varType FuzeWorks\Authentication\Model\Session $session}
{varType bool $loadAsync}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>{$serverName} | {$pageTitle}</title>
<!-- Tell the browser to be responsive to screen width -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Font Awesome -->
<link rel="stylesheet" href="/{$adminKey}/lte_plugins/fontawesome-free/css/all.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="/{$adminKey}/lte_dist/css/adminlte.min.css">
<!-- Google Font: Source Sans Pro -->
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<div class="wrapper">
<!-- Navbar -->
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<!-- Left navbar links -->
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="/{$adminKey}" class="nav-link">Dashboard</a>
</li>
</ul>
<!-- Right navbar links -->
<ul class="navbar-nav ml-auto">
{if $loadAsync}
<li id="asyncWidget" class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="fa fa-list"></i>
<span class="badge badge-warning navbar-badge">0</span>
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<span class="dropdown-item dropdown-header">Asynchronous tasks</span>
<div class="dropdown-divider"></div>
<div class="dropdown-divider"></div>
<a href="/{$adminKey}/async" class="dropdown-item dropdown-footer">See all historic tasks</a>
</div>
</li>
{/if}
<li class="nav-item dropdown user-menu">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">
<img src="/{$adminKey}/lte_dist/img/user2-160x160.jpg" class="user-image img-circle elevation-2" alt="User Image">
<span class="d-none d-md-inline">{$session->user->primaryEmail}</span>
</a>
<ul class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<!-- User image -->
<li class="user-header bg-primary">
<img src="/{$adminKey}/lte_dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">
<p>
{$session->user->primaryEmail}
<small>Member since -</small>
</p>
</li>
<!-- Menu Footer-->
<li class="user-footer">
<a href="/{$adminKey}/profile" class="btn btn-default btn-flat">Profile</a>
<a href="{$authURL}/logout" class="btn btn-default btn-flat float-right">Sign out</a>
</li>
</ul>
</li>
</ul>
</nav>
<!-- /.navbar -->
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-primary elevation-4">
<!-- Brand Logo -->
<a href="/" class="brand-link">
<img src="/{$adminKey}/lte_dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3"
style="opacity: .8">
<span class="brand-text font-weight-light">{$serverName}</span>
</a>
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar Menu -->
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
{foreach $sidebar as $item}
<li class="nav-item">
<a href="/{$adminKey}/{$item['url']}" class="nav-link">
<i class="nav-icon fas fa-{$item['icon']}"></i>
<p>{$item['display']}</p>
</a>
</li>
{/foreach}
</ul>
</nav>
<!-- /.sidebar-menu -->
</div>
<!-- /.sidebar -->
</aside>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0 text-dark">{$pageTitle}</h1>
</div><!-- /.col -->
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="/{$adminKey}">Home</a></li>
<li class="breadcrumb-item active">{$pageTitle}</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<section class="content">
<div class="container-fluid">
{$content|noescape}
</div><!-- /.container-fluid -->
</section>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<footer class="main-footer">
<strong>Copyright &copy; 2013-{date('Y')} <a href="https://i15.nl">i15.nl</a>.</strong>
All rights reserved.
<div class="float-right d-none d-sm-inline-block">
<b>Version</b> 1.3.0
</div>
</footer>
</div>
<!-- ./wrapper -->
<!-- jQuery -->
<script src="/{$adminKey}/lte_plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="/{$adminKey}/lte_plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<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>
</html>

630
src/FuzeWorks/Administration/AdminPlugin.php Normal file → Executable file
View File

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

129
src/FuzeWorks/Administration/AdminView.php Normal file → Executable file
View File

@ -1,61 +1,70 @@
<?php
/**
* FuzeWorks Framework Administration Plugin.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2020 i15
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author i15
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
* @license https://opensource.org/licenses/MIT MIT License
*
* @since Version 1.3.0
*
* @version Version 1.3.0
*/
namespace FuzeWorks\Administration;
use FuzeWorks\Factory;
use FuzeWorks\Layout;
use FuzeWorks\Priority;
use FuzeWorks\WebView;
abstract class AdminView extends WebView
{
/** @var Layout */
protected $layouts;
/**
* The priority of this AdminView.
*
* @var int
*/
protected $priority = Priority::NORMAL;
public function __construct()
{
parent::__construct();
$this->layouts = Factory::getInstance('layouts');
}
<?php
/**
* FuzeWorks Framework Administration Plugin.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2020 i15
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author i15
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
* @license https://opensource.org/licenses/MIT MIT License
*
* @since Version 1.3.0
*
* @version Version 1.3.0
*/
namespace FuzeWorks\Administration;
use FuzeWorks\Authentication\AuthenticationPlugin;
use FuzeWorks\Authentication\Model\Session;
use FuzeWorks\Authentication\Model\Users;
use FuzeWorks\Factory;
use FuzeWorks\Layout;
use FuzeWorks\Priority;
use FuzeWorks\WebView;
abstract class AdminView extends WebView
{
protected Layout $layouts;
protected Session $session;
protected Users $users;
/**
* The priority of this AdminView.
*/
protected int $priority = Priority::NORMAL;
public function __construct()
{
parent::__construct();
// Set 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();
}
}

View 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();
}

View File

@ -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()
{
}
}

View 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;
}
}

View File

@ -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;
}
}

View 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;
}
}

View 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;
}
}

View File

@ -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;
}
}

View 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;
}
}

View File

@ -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
{
}

View File

@ -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
{
}

514
src/FuzeWorks/Administration/PageFinder.php Normal file → Executable file
View File

@ -1,230 +1,286 @@
<?php
/**
* FuzeWorks Framework Administration Plugin.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2020 i15
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author i15
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
* @license https://opensource.org/licenses/MIT MIT License
*
* @since Version 1.3.0
*
* @version Version 1.3.0
*/
namespace FuzeWorks\Administration;
use FuzeWorks\Administration\Events\AdminGenerateSidebarEvent;
use FuzeWorks\Events;
use FuzeWorks\Factory;
use FuzeWorks\Logger;
use FuzeWorks\Priority;
use FuzeWorks\Views;
use phpDocumentor\Reflection\DocBlockFactory;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
class PageFinder
{
/**
* Generates an array of all sidebar elements.
*
* First searches for all the available AdminViews. Then parses over all their methods and populates the array
* using each method's individual docblock.
*
* @return array
*/
public function generateSidebar(): array
{
Logger::log("Generating sidebar...");
$event = Events::fireEvent('adminGenerateSidebarEvent');
if ($event->isCancelled())
return [];
// First find all views
$viewFileList = $this->findViews();
Logger::log("Found " . count($viewFileList) . ' admin views.');
// Then sort all those views into methods in the sidebar
$sorted = $this->sort($viewFileList);
// Log the result and return
Logger::log("Found " . count($sorted) . ' entries for sidebar.');
return $sorted;
}
/**
* Parse over every view component path and find all admin views.
*
* Return a file list.
*
* @return array
*/
protected function findViews(): array
{
/** @var Views $views */
$views = Factory::getInstance('views');
// First collect all the known paths
$paths = [];
for ($i = Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++)
$paths[$i] = $views->getComponentPaths($i);
// Then go over every individual paths
$viewFiles = [];
foreach ($paths as $priority => $foldersArray)
{
foreach ($foldersArray as $folder)
{
// Get the contents from the folder
$contents = array_diff(scandir($folder), array('..', '.'));
// Then go over the folders, and see which ones are an admin view
foreach ($contents as $file)
{
// If the file matches the expected filename, add it to the list
if (substr($file, 0, 11) === 'view.admin.' && !isset($viewFiles[$file]))
$viewFiles[$file] = $folder . DS . $file;
}
}
}
return $viewFiles;
}
protected function sort(array $viewFileList): array
{
// Reflection docblock factory
$factory = DocBlockFactory::createInstance();
// Start sorting all methods
$entries = [];
foreach ($viewFileList as $viewId => $viewFile)
{
// 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 {
$reflector = new ReflectionClass($className);
} catch (ReflectionException $e) {
// If that doesn't work, simply ignore it. Don't drag the whole interface down.
continue;
}
// Check if this class actually inherits AdminView
$parent = $reflector->getParentClass();
if ($parent === false || $parent->getName() !== 'FuzeWorks\Administration\AdminView')
continue;
// Select all methods
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
// And pass over all of them
foreach ($methods as $method) {
// Prepare the entry output
$entry = [
'url' => ($id !== 'index' ? $id : '') . ($method->getName() !== 'index' ? '/' . $method->getName() : ''),
'priority' => Priority::NORMAL,
'display' => $reflector->getShortName() . '/' . $method->getName(),
'icon' => 'round'
];
// Only allow the methods in the actual class. Not from the parent method.
if ($method->class !== $className)
continue;
// Then fetch the docComments.
$docComment = $method->getDocComment();
if ($docComment !== false)
{
$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;
// Then test for display
if (!empty($display))
$entry['display'] = (string) $display[0];
// Then test for icon
if (!empty($icon))
$entry['icon'] = (string) $icon[0];
// Then test for priority
if (!empty($priority))
{
$priority = (string) $priority[0];
switch ($priority) {
case 'Priority::LOWEST':
$entry['priority'] = 5;
break;
case 'Priority::LOW':
$entry['priority'] = 4;
break;
case 'Priority::NORMAL':
$entry['priority'] = 3;
break;
case 'Priority::HIGH':
$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;
}
}
}
// Write to entries
$entries[] = $entry;
}
}
// And finally return those
return $entries;
}
<?php
/**
* FuzeWorks Framework Administration Plugin.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2020 i15
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author i15
* @copyright Copyright (c) 2013 - 2020, i15. (https://i15.nl)
* @license https://opensource.org/licenses/MIT MIT License
*
* @since Version 1.3.0
*
* @version Version 1.3.0
*/
namespace FuzeWorks\Administration;
use FuzeWorks\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\Authentication\Model\Session;
use FuzeWorks\Events;
use FuzeWorks\Factory;
use FuzeWorks\Logger;
use FuzeWorks\Priority;
use FuzeWorks\Views;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
class PageFinder
{
protected Session $session;
/**
* Generates an array of all sidebar elements.
*
* First searches for all the available AdminViews. Then parses over all their methods and populates the array
* using each method's attributes.
*
* @return array
*/
public function generateSidebar(Session $session): array
{
$this->session = $session;
Logger::log("Generating sidebar...");
$event = Events::fireEvent('adminGenerateSidebarEvent');
if ($event->isCancelled())
return [];
// First find all views
$views = $this->findViews();
Logger::log("Found " . count($views) . ' admin views.');
// Then sort all those views into methods in the sidebar
$sorted = $this->sortSidebar($views);
// Log the result and return
Logger::log("Found " . count($sorted) . ' entries for sidebar.');
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.
*
* Return a file list.
*
* @return string[]
*/
protected function findViews(): array
{
/** @var Views $views */
$views = Factory::getInstance('views');
// First collect all the known paths
$paths = [];
for ($i = Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++)
$paths[$i] = $views->getComponentPaths($i);
// Then go over every individual paths
$views = [];
foreach ($paths as $priority => $foldersArray)
{
foreach ($foldersArray as $folder)
{
// Get the contents from the folder
$contents = array_diff(scandir($folder), array('..', '.'));
// Then go over the folders, and see which ones are an admin view
foreach ($contents as $file)
{
// If the file matches the expected filename, add it to the list
if (!str_starts_with($file, 'view.admin.'))
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 $views;
}
/**
* 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
{
$out = [];
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
$entries = [];
foreach ($views as $view)
{
// Try and reflect on this class.
try {
$reflector = new ReflectionClass($view);
} catch (ReflectionException $e) {
// If that doesn't work, simply ignore it. Don't drag the whole interface down.
continue;
}
// Check if this class actually inherits AdminView
if (!$reflector->isSubclassOf("FuzeWorks\Administration\AdminView"))
continue;
// Determine view Id
$id = strtolower(substr($reflector->getShortName(), 0, -9));
// Select all methods
$methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC);
// And pass over all of them
foreach ($methods as $method) {
// Prepare the entry output
$entry = [
'url' => ($id !== 'index' ? $id : '') . ($method->getName() !== 'index' ? '/' . $method->getName() : ''),
'priority' => Priority::NORMAL,
'display' => $reflector->getShortName() . '::' . $method->getName(),
'icon' => 'round'
];
// Only allow the methods in the actual class. Not from the parent method.
if ($method->class !== $view)
continue;
// Read attributes
// First read hidden attribute. If present, skip this method
$hiddenAttributes = $method->getAttributes(HiddenAttribute::class);
if (!empty($hiddenAttributes))
continue;
// Then check for permissions
$permissionAttributes = $method->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)
continue;
}
// 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
$entries[$entry['priority']][] = $entry;
}
}
// Sort by priority
$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;
}
}

124
test/bootstrap.php Normal file → Executable file
View File

@ -1,63 +1,63 @@
<?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
*/
require_once(dirname(__DIR__) . '/vendor/autoload.php');
$configurator = new \FuzeWorks\Configurator();
// Set directories
$configurator->setTempDirectory(__DIR__ . '/temp');
$configurator->setLogDirectory(__DIR__ . '/temp');
// Other values
$configurator->setTimeZone('Europe/Amsterdam');
// Add components and plugins
$webComponent = new \FuzeWorks\WebComponent();
$webComponent->enableComponent();
$configurator->addComponent($webComponent);
// Add LayoutComponent
$configurator->addComponent(new \FuzeWorks\LayoutComponent());
// Add TracyComponent
$configurator->addComponent(new \FuzeWorks\TracyComponent());
// Debug related
$configurator->enableDebugMode();
$configurator->setDebugAddress('ALL');
$container = $configurator->createContainer();
$container->plugins->addPlugin(new \FuzeWorks\Administration\AdminPlugin());
<?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
*/
require_once(dirname(__DIR__) . '/vendor/autoload.php');
$configurator = new \FuzeWorks\Configurator();
// Set directories
$configurator->setTempDirectory(__DIR__ . '/temp');
$configurator->setLogDirectory(__DIR__ . '/temp');
// Other values
$configurator->setTimeZone('Europe/Amsterdam');
// Add components and plugins
$webComponent = new \FuzeWorks\WebComponent();
$webComponent->enableComponent();
$configurator->addComponent($webComponent);
// Add LayoutComponent
$configurator->addComponent(new \FuzeWorks\LayoutComponent());
// Add TracyComponent
$configurator->addComponent(new \FuzeWorks\TracyComponent());
// Debug related
$configurator->enableDebugMode();
$configurator->setDebugAddress('ALL');
$container = $configurator->createContainer();
$container->plugins->addPlugin(new \FuzeWorks\Administration\AdminPlugin());
return $container;

View 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);
}
}

View 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"];
}
}

View 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);
}
}

View File

@ -1,78 +1,68 @@
<?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;
class SettingsAdminView extends AdminView
{
/**
* @var SettingsController
*/
protected $controller;
/**
* Displays a list of settings files
*
* @display Settings
* @icon cog
* @priority Priority::LOW
*/
public function index()
{
$files = $this->controller->findSettingsFiles();
$this->layouts->assign('files', $files);
return $this->layouts->get('components/settings/overview');
}
/**
* @hidden
*/
public function view()
{
}
/**
* @hidden
*/
public function modify()
{
}
<?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\DashboardController;
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 DashboardAdminView extends AdminView
{
/**
* @var DashboardController
*/
protected Controller $controller;
#[DisplayAttribute("Dashboard"), IconAttribute("tachometer-alt"), PriorityAttribute(Priority::HIGHEST)]
public function index()
{
//$content = $this->controller->populateDashboard();
//$this->layouts->assign('content', $content);
}
#[HiddenAttribute, DashboardAttribute("Hello!")]
public function test()
{
}
}

View 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()
{
}
}

6
www/.htaccess Normal file → Executable file
View File

@ -1,4 +1,4 @@
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?path=$1 [QSA,L]

29
www/dist/async.ts vendored Normal file
View 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) {
}
}

80
www/index.php Normal file → Executable file
View File

@ -1,41 +1,41 @@
<?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
*/
/** @var \FuzeWorks\Factory $container */
$container = require(dirname(__DIR__) . '/test/bootstrap.php');
/** @var \FuzeWorks\WebComponent $web */
$web = $container->web;
<?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
*/
/** @var \FuzeWorks\Factory $container */
$container = require(dirname(__DIR__) . '/test/bootstrap.php');
/** @var \FuzeWorks\WebComponent $web */
$web = $container->web;
$web->routeWebRequest();