Browse Source

Readme, some fixes, rel noopener for _blank links

Roman 3 years ago
parent
commit
18e7955b12

+ 43 - 1
README.md

@@ -214,7 +214,7 @@ namespace Documents\Example {
     }
     }
     
     
     public function getCode(): string {
     public function getCode(): string {
-       $view = $this->getDocument()->getView() ?? "<Empty>";
+       $view = $this->getDocument()->getRequestedView() ?? "<Empty>";
        return "<b>Requested View:</b> " . htmlspecialchars($view);
        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.
 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?
 ## Anything more?
 
 

+ 1 - 1
adminPanel/src/sidebar.js

@@ -75,7 +75,7 @@ export default function Sidebar(props) {
     let filePath = parent.filesPath;
     let filePath = parent.filesPath;
     if (filePath) {
     if (filePath) {
         li.push(<li className={"nav-item"} key={"files"}>
         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"} />
                 <Icon icon={"folder"} className={"nav-icon"} />
                 <p>Files</p>
                 <p>Files</p>
             </a>
             </a>

+ 7 - 1
adminPanel/src/views/help.js

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

+ 1 - 1
adminPanel/src/views/settings.js

@@ -422,7 +422,7 @@ export default class Settings extends React.Component {
                     <label className={"form-check-label"} htmlFor={"recaptcha_enabled"}>
                     <label className={"form-check-label"} htmlFor={"recaptcha_enabled"}>
                         Enable Google's reCaptcha
                         Enable Google's reCaptcha
                         <span className={"ml-2"}>
                         <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
                                 More Info
                                 <sup><small><Icon icon={"external-link-alt"} className={"ml-1"}/></small></sup>
                                 <sup><small><Icon icon={"external-link-alt"} className={"ml-1"}/></small></sup>
                             </a>)
                             </a>)

+ 8 - 3
core/Elements/Document.class.php

@@ -27,12 +27,17 @@ abstract class Document {
 
 
   public function getView() : ?View {
   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 null;
     }
     }
 
 
-    return new $this->activeView($this);
+    return new $view($this);
+  }
+
+  public function getRequestedView(): string {
+    return $this->activeView;
   }
   }
 
 
   function getCode(): string {
   function getCode(): string {

+ 1 - 1
core/Elements/View.class.php

@@ -89,7 +89,7 @@ abstract class View extends StaticView {
 
 
   protected function createExternalLink($link, $title=null): string {
   protected function createExternalLink($link, $title=null): string {
     if(is_null($title)) $title=$link;
     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 {
   protected function createIcon($icon, $type = "fas", $classes = ""): string {

+ 1 - 1
core/Objects/ApiObject.class.php

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

+ 6 - 3
core/Objects/Language.class.php

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

+ 5 - 5
core/Objects/Session.class.php

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

+ 5 - 5
core/core.php

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

+ 3 - 4
index.php

@@ -141,12 +141,11 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
             $response = serveStatic($currentDir, $target);
             $response = serveStatic($currentDir, $target);
             break;
             break;
           case "dynamic":
           case "dynamic":
-            $view = parseClass($extra);
             $file = getClassPath($target);
             $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 {
             } else {
-              $document = new $target($user, $view);
+              $document = new $target($user, $extra);
             }
             }
 
 
             $response = $document->getCode();
             $response = $document->getCode();

File diff suppressed because it is too large
+ 0 - 0
js/admin.min.js


Some files were not shown because too many files changed in this diff