Add documentation
parent
882c5ae372
commit
36ef1c5721
41
README.md
41
README.md
|
@ -1,2 +1,41 @@
|
||||||
# OpenSim-Gridverwaltung
|
# MCP: OpenSim-Gridverwaltung
|
||||||
|
|
||||||
|
Das MCP ist ein PHP-Webinterface für Benutzer und Administratoren von OpenSimulator-Grids. Es ermöglicht Benutzern die Registrierung (auf Einladung) und Verwaltung des eigenen OpenSimulator-Accounts im Self-Service-Verfahren. Administratoren können Accounts und Regionen einfacher verwalten.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Voraussetzung ist, dass die Datenbankstruktur eines OpenSimulator-Grids bereits existiert. Das MCP muss vor der Nutzung mit den Zugangsdaten derselben Datenbank konfiguriert werden. Eigene Tabellen des MCP besitzen zur Vermeidung von Konflikten den Präfix `mcp_`.
|
||||||
|
|
||||||
|
Folgende PHP-Erweiterungen werden benötigt:
|
||||||
|
1. php-curl
|
||||||
|
2. php-mysql (PDO)
|
||||||
|
3. php-xml
|
||||||
|
4. php-xmlrpc
|
||||||
|
|
||||||
|
Für bessere Performance kann optional `php-apcu` installiert werden.
|
||||||
|
|
||||||
|
Die Installation läuft folgendermaßen ab:
|
||||||
|
1. Gewünschtes Release als ZIP/TAR-Archiv oder per `git clone` herunterladen
|
||||||
|
2. Verzeichnisse `app`, `data`, `lib`, `public` und `templates` in das Verzeichnis des Webservers entpacken
|
||||||
|
3. Öffentliche Stammverzeichnis des Webservers (Apache: `DocumentRoot`, nginx: `root`) auf Pfad zum Verzeichnis `public` ändern
|
||||||
|
4. Index des Webservers auf index.php ändern, falls erforderlich
|
||||||
|
5. Beispielkonfiguration `config.example.ini` anpassen, in `config.ini` umbenennen und in das Verzeichnis der in Schritt 2 entpackten Verzeichnisse verschieben
|
||||||
|
|
||||||
|
## Aktualisierung
|
||||||
|
|
||||||
|
Zur Aktualisierung müssen lediglich die Verzeichnisse `app`, `lib`, `public` und `templates`, sowie der Inhalt von `data` (außer `iars`) ersetzt werden.
|
||||||
|
Die Migration der Datenbankstruktur erfolgt automatisch. Möglicherweise erforderliche Änderungen an der Konfiguration sind den Release-Informationen zu entnehmen.
|
||||||
|
|
||||||
|
## Entwickler
|
||||||
|
|
||||||
|
Die Abhängigkeiten des Frontends werden über [npm](https://www.npmjs.com/) verwaltet. Alle erforderlichen Pakete können nach dem Download des Repository über `npm install` heruntergeladen werden.
|
||||||
|
In `package.json` ist zudem ein Buildprozess (Befehl: `npm build`) definiert, durch den die Sass-Stylesheets im Verzeichnis `scss` kompiliert und optimiert und zusammen mit Schriftarten und Skripts im öffentlichen Webverzeichnis abgelegt werden.
|
||||||
|
|
||||||
|
Das Backend besitzt kein Dependency Management. Die einzige Abhängigkeit, [PHPMailer](https://github.com/PHPMailer/PHPMailer), wurde manuell in das Repository eingefügt. Der Autoloader sucht im Verzeichnis `lib` nach solchen externen Klassen.
|
||||||
|
|
||||||
|
### Verarbeitung von Anfragen
|
||||||
|
|
||||||
|
Das Skript `index.php` wird bei allen Anfragen aufgerufen. Die angeforderte Route wird als GET-Parameter `<Gruppe>=<Name>` übermittelt. Gruppen (momentan `api` und `page`), zugehörige Seiten und die assoziierte `RequestHandler`-Subklasse sind in `Mcp.php` definiert.
|
||||||
|
|
||||||
|
Ist zu einer Anfrage eine Route definiert, wird der zugehörige `RequestHandler` erzeugt. Ist eine `Middleware`-Klasse für diesen definiert, ist die weitere Verarbeitung von dem Rückgabewert von `Middleware::canAccess()` abhängig.
|
||||||
|
Schließlich wird je nach Methode der Anfrage `RequestHandler::get()` bzw. `RequestHandler::post()` aufgerufen.
|
18
app/Mcp.php
18
app/Mcp.php
|
@ -67,6 +67,9 @@ class Mcp implements ConnectionProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the MySQL database (if not done already) and returns the connection.
|
||||||
|
*/
|
||||||
public function db(): PDO
|
public function db(): PDO
|
||||||
{
|
{
|
||||||
if ($this->db == null) {
|
if ($this->db == null) {
|
||||||
|
@ -78,17 +81,29 @@ class Mcp implements ConnectionProvider
|
||||||
return $this->db;
|
return $this->db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value associated with the specified key in this config, as either a string, an integer or an array.
|
||||||
|
* Keys are lower-cased for compatibility reasons.
|
||||||
|
*
|
||||||
|
* If there is no entry with this key, an empty array is returned.
|
||||||
|
*/
|
||||||
public function config($key): string|array|int
|
public function config($key): string|array|int
|
||||||
{
|
{
|
||||||
$realKey = strtolower($key);
|
$realKey = strtolower($key);
|
||||||
return isset($this->config[$realKey]) ? $this->config[$realKey] : array();
|
return isset($this->config[$realKey]) ? $this->config[$realKey] : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a hidden form field with the current CSRF token set.
|
||||||
|
*/
|
||||||
public function csrfField(): string
|
public function csrfField(): string
|
||||||
{
|
{
|
||||||
return '<input type="hidden" name="csrf" value="'.(isset($_SESSION['csrf']) ? $_SESSION['csrf'] : '').'">';
|
return '<input type="hidden" name="csrf" value="'.(isset($_SESSION['csrf']) ? $_SESSION['csrf'] : '').'">';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a TemplateBuilder instance for the specified template file, setting some basic variables.
|
||||||
|
*/
|
||||||
public function template($name): TemplateBuilder
|
public function template($name): TemplateBuilder
|
||||||
{
|
{
|
||||||
return (new TemplateBuilder($this->templateDir, $name))->vars([
|
return (new TemplateBuilder($this->templateDir, $name))->vars([
|
||||||
|
@ -98,6 +113,9 @@ class Mcp implements ConnectionProvider
|
||||||
])->unsafeVar('csrf', $this->csrfField());
|
])->unsafeVar('csrf', $this->csrfField());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path of the data/ directory, mostly used for dynamically created assets.
|
||||||
|
*/
|
||||||
public function getDataDir(): string
|
public function getDataDir(): string
|
||||||
{
|
{
|
||||||
return $this->dataDir;
|
return $this->dataDir;
|
||||||
|
|
|
@ -19,12 +19,20 @@ class TemplateBuilder
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets another template to be the "parent" of this one.
|
||||||
|
*
|
||||||
|
* The template specified in this TemplateBuilder's constructor will be included into the parent.
|
||||||
|
*/
|
||||||
public function parent(string $parent): TemplateBuilder
|
public function parent(string $parent): TemplateBuilder
|
||||||
{
|
{
|
||||||
$this->parent = $parent;
|
$this->parent = $parent;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets multiple variables after escaping them.
|
||||||
|
*/
|
||||||
public function vars(array $vars): TemplateBuilder
|
public function vars(array $vars): TemplateBuilder
|
||||||
{
|
{
|
||||||
foreach ($vars as $key => $val) {
|
foreach ($vars as $key => $val) {
|
||||||
|
@ -33,18 +41,29 @@ class TemplateBuilder
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the specified variable for this template, after escaping it.
|
||||||
|
*/
|
||||||
public function var(string $key, string $val): TemplateBuilder
|
public function var(string $key, string $val): TemplateBuilder
|
||||||
{
|
{
|
||||||
$this->vars[$key] = htmlspecialchars($val);
|
$this->vars[$key] = htmlspecialchars($val);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the specified variable for this template WITHOUT escaping it.
|
||||||
|
*
|
||||||
|
* User input included this way has to be manually sanitized before.
|
||||||
|
*/
|
||||||
public function unsafeVar(string $key, string $val): TemplateBuilder
|
public function unsafeVar(string $key, string $val): TemplateBuilder
|
||||||
{
|
{
|
||||||
$this->vars[$key] = $val;
|
$this->vars[$key] = $val;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the template(s) with the current set of variables.
|
||||||
|
*/
|
||||||
public function render(): void
|
public function render(): void
|
||||||
{
|
{
|
||||||
$v = new TemplateVarArray($this->vars);
|
$v = new TemplateVarArray($this->vars);
|
||||||
|
|
|
@ -5,10 +5,10 @@ namespace Mcp\Cron;
|
||||||
|
|
||||||
enum Frequency
|
enum Frequency
|
||||||
{
|
{
|
||||||
case YEARLY;
|
case YEARLY; // 01.01. of each year
|
||||||
case MONTHLY;
|
case MONTHLY; // 1st of each month
|
||||||
case WEEKLY;
|
case WEEKLY; // 1 week after last run
|
||||||
case DAILY;
|
case DAILY; // Next day after last run, at 00:00
|
||||||
case HOURLY;
|
case HOURLY; // One hour after last run
|
||||||
case EACH_MINUTE;
|
case EACH_MINUTE; // One minute after last run
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,20 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Mcp\Middleware;
|
namespace Mcp\Middleware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Middleware implementations can be registered for a RequestHandler.
|
||||||
|
*
|
||||||
|
* If this is done, request processing continues only if Middleware::canAccess() returns true.
|
||||||
|
*/
|
||||||
interface Middleware
|
interface Middleware
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns true if the request should be processed, i.e. if the client has permissionn to perform this request.
|
||||||
|
*/
|
||||||
public function canAccess(): bool;
|
public function canAccess(): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when canAcces() returns false, e.g. to redirect unauthorized users.
|
||||||
|
*/
|
||||||
public function handleUnauthorized(): void;
|
public function handleUnauthorized(): void;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue