Readme, some fixes, rel noopener for _blank links

This commit is contained in:
Roman 2021-04-03 10:39:13 +02:00
parent 2087e56626
commit 18e7955b12
12 changed files with 82 additions and 27 deletions

@ -214,7 +214,7 @@ namespace Documents\Example {
}
public function getCode(): string {
$view = $this->getDocument()->getView() ?? "<Empty>";
$view = $this->getDocument()->getRequestedView() ?? "<Empty>";
return "<b>Requested View:</b> " . htmlspecialchars($view);
}
}
@ -223,6 +223,48 @@ namespace Documents\Example {
Of course, the head and body classes can be placed in any file, as the code might get big and complex.
### Localization
Currently, there are two languages specified, which are stored in the database: `en_US` and `de_DE`.
A language is dynamically loaded according to the sent `Accept-Language`-Header, but can also be set using the `lang` parameter
or [/api/language/set](/core/Api/LanguageAPI.class.php) endpoint. Localization of strings can be achieved using the [LanguageModule](/core/Objects/lang/LanguageModule.php)-Class.
Let's look at this example:
```php
class ExampleLangModule extends \Objects\lang\LanguageModule {
public function getEntries(string $langCode) {
$entries = array();
switch ($langCode) {
case 'de_DE':
$entries["EXAMPLE_KEY"] = "Das ist eine Beispielübersetzung";
$entries["Welcome"] = "Willkommen";
break;
default:
$entries["EXAMPLE_KEY"] = "This is an example translation";
break;
}
return $entries;
}
}
```
If any translation key is not defined, the key is returned, which means, we don't need to specify the string `Welcome` again. To access the translations,
we firstly have to load the module. This is done by adding the class, or the object inside the constructor.
To translate the defined strings, we can use the global `L()` function. The following code snipped shows the use of
our sample language module:
```php
class SomeView extends \Elements\View {
public function __construct(\Elements\Document $document) {
parent::__construct($document);
$this->langModules[] = ExampleModule::class;
}
public function getCode() : string{
return L("Welcome") . "! " . L("EXAMPLE_KEY");
}
}
```
## Anything more?

@ -75,7 +75,7 @@ export default function Sidebar(props) {
let filePath = parent.filesPath;
if (filePath) {
li.push(<li className={"nav-item"} key={"files"}>
<a href={filePath} className={"nav-link"} target={"_blank"} rel={"noopener noreferrer"}>
<a href={filePath} className={"nav-link"} target={"_blank"} rel={"noopener"}>
<Icon icon={"folder"} className={"nav-icon"} />
<p>Files</p>
</a>

@ -121,7 +121,13 @@ export default function HelpPage() {
<b>Project Lead & Main Developer</b>
<ul className={"list-unstyled"}>
<li><small><Icon icon={"address-card"} className={"mr-1"}/>Roman Hergenreder</small></li>
<li><small><Icon icon={"globe"} className={"mr-1"}/><a href={"https://romanh.de/"} target={"_blank"}>https://romanh.de/</a></small></li>
<li>
<small><Icon icon={"globe"} className={"mr-1"}/>
<a href={"https://romanh.de/"} target={"_blank"} rel={"noopener"}>
https://romanh.de/
</a>
</small>
</li>
<li><small><Icon icon={"envelope"} className={"mr-1"}/><a href={"mailto:webmaster@romanh.de"}>webmaster@romanh.de</a></small></li>
</ul>

@ -422,7 +422,7 @@ export default class Settings extends React.Component {
<label className={"form-check-label"} htmlFor={"recaptcha_enabled"}>
Enable Google's reCaptcha
<span className={"ml-2"}>
(<a href={"https://www.google.com/recaptcha/intro/v3.html"} target={"_blank"}>
(<a href={"https://www.google.com/recaptcha/intro/v3.html"} target={"_blank"} rel={"noopener noreferrer"}>
More Info
<sup><small><Icon icon={"external-link-alt"} className={"ml-1"}/></small></sup>
</a>)

@ -27,12 +27,17 @@ abstract class Document {
public function getView() : ?View {
$file = getClassPath($this->activeView);
if(!file_exists($file) || !is_subclass_of($this->activeView, View::class)) {
$view = parseClass($this->activeView);
$file = getClassPath($view);
if(!file_exists($file) || !is_subclass_of($view, View::class)) {
return null;
}
return new $this->activeView($this);
return new $view($this);
}
public function getRequestedView(): string {
return $this->activeView;
}
function getCode(): string {

@ -89,7 +89,7 @@ abstract class View extends StaticView {
protected function createExternalLink($link, $title=null): string {
if(is_null($title)) $title=$link;
return "<a href=\"$link\" target=\"_blank\" class=\"external\">$title</a>";
return "<a href=\"$link\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"external\">$title</a>";
}
protected function createIcon($icon, $type = "fas", $classes = ""): string {

@ -4,7 +4,7 @@ namespace Objects;
abstract class ApiObject implements \JsonSerializable {
public abstract function jsonSerialize();
public abstract function jsonSerialize(): array;
public function __toString() { return json_encode($this); }

@ -31,7 +31,10 @@ namespace Objects {
public function getEntries() { return $this->entries; }
public function getModules() { return $this->modules; }
public function loadModule(LanguageModule $module) {
/**
* @param $module LanguageModule class or object
*/
public function loadModule($module) {
if(!is_object($module))
$module = new $module;
@ -40,7 +43,7 @@ namespace Objects {
$this->modules[] = $module;
}
public function translate($key) {
public function translate(string $key): string {
if(isset($this->entries[$key]))
return $this->entries[$key];
@ -51,7 +54,7 @@ namespace Objects {
setcookie('lang', $this->langCode, 0, "/", "");
}
public function jsonSerialize() {
public function jsonSerialize(): array {
return array(
'uid' => $this->languageId,
'code' => $this->langCode,

@ -28,7 +28,7 @@ class Session extends ApiObject {
$this->csrfToken = $csrfToken ?? generateRandomString(16);
}
public static function create($user, $stayLoggedIn) {
public static function create($user, $stayLoggedIn): ?Session {
$session = new Session($user, null, null);
if($session->insert($stayLoggedIn)) {
return $session;
@ -69,15 +69,15 @@ class Session extends ApiObject {
setcookie('session', $sessionCookie, $this->getExpiresTime(), "/", "", $secure);
}
public function getExpiresTime() {
public function getExpiresTime(): int {
return ($this->stayLoggedIn == 0 ? 0 : $this->expires);
}
public function getExpiresSeconds() {
public function getExpiresSeconds(): int {
return ($this->stayLoggedIn == 0 ? -1 : $this->expires - time());
}
public function jsonSerialize() {
public function jsonSerialize(): array {
return array(
'uid' => $this->sessionId,
'user_id' => $this->user->getId(),
@ -89,7 +89,7 @@ class Session extends ApiObject {
);
}
public function insert($stayLoggedIn) {
public function insert($stayLoggedIn): bool {
$this->updateMetaData();
$sql = $this->user->getSQL();

@ -1,8 +1,8 @@
<?php
define("WEBBASE_VERSION", "1.2.2");
define("WEBBASE_VERSION", "1.2.3");
function getProtocol() {
function getProtocol(): string {
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https" : "http";
}
@ -26,12 +26,12 @@ function generateRandomString($length): string {
return $randomString;
}
function startsWith($haystack, $needle) {
function startsWith($haystack, $needle): bool {
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
function endsWith($haystack, $needle) {
function endsWith($haystack, $needle): bool {
$length = strlen($needle);
if ($length == 0)
return true;
@ -97,7 +97,7 @@ function createError($msg) {
return json_encode(array("success" => false, "msg" => $msg));
}
function serveStatic(string $webRoot, string $file) {
function serveStatic(string $webRoot, string $file): string {
$path = realpath($webRoot . "/" . $file);
if (!startsWith($path, $webRoot . "/")) {

@ -141,12 +141,11 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
$response = serveStatic($currentDir, $target);
break;
case "dynamic":
$view = parseClass($extra);
$file = getClassPath($target);
if(!file_exists($file) || !is_subclass_of($target, Document::class)) {
$document = new Document404($user, $view);
if (!file_exists($file) || !is_subclass_of($target, Document::class)) {
$document = new Document404($user, $extra);
} else {
$document = new $target($user, $view);
$document = new $target($user, $extra);
}
$response = $document->getCode();

2
js/admin.min.js vendored

File diff suppressed because one or more lines are too long