Frontend, Bugfixes
This commit is contained in:
		
							parent
							
								
									efe3ada470
								
							
						
					
					
						commit
						8ce74edc38
					
				@ -2,14 +2,38 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Api\User;
 | 
					namespace Api\User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Api\Parameter\Parameter;
 | 
				
			||||||
use \Api\Request;
 | 
					use \Api\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Fetch extends Request {
 | 
					class Fetch extends Request {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const SELECT_SIZE = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private int $userCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function __construct($user, $externalCall = false) {
 | 
					  public function __construct($user, $externalCall = false) {
 | 
				
			||||||
    parent::__construct($user, $externalCall, array());
 | 
					
 | 
				
			||||||
 | 
					    parent::__construct($user, $externalCall, array(
 | 
				
			||||||
 | 
					      'page' => new Parameter('page', Parameter::TYPE_INT, true, 1)
 | 
				
			||||||
 | 
					    ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $this->loginRequired = true;
 | 
					    $this->loginRequired = true;
 | 
				
			||||||
    $this->requiredGroup = USER_GROUP_ADMIN;
 | 
					    $this->requiredGroup = USER_GROUP_ADMIN;
 | 
				
			||||||
 | 
					    $this->userCount = 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function getUserCount() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $sql = $this->user->getSQL();
 | 
				
			||||||
 | 
					    $res = $sql->select($sql->count())->from("User")->execute();
 | 
				
			||||||
 | 
					    $this->success = ($res !== FALSE);
 | 
				
			||||||
 | 
					    $this->lastError = $sql->getLastError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($this->success) {
 | 
				
			||||||
 | 
					      $this->userCount = $res[0]["count"];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $this->success;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function execute($values = array()) {
 | 
					  public function execute($values = array()) {
 | 
				
			||||||
@ -17,11 +41,25 @@ class Fetch extends Request {
 | 
				
			|||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $page = $this->getParam("page");
 | 
				
			||||||
 | 
					    if($page < 1) {
 | 
				
			||||||
 | 
					      return $this->createError("Invalid page count");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!$this->getUserCount()) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $sql = $this->user->getSQL();
 | 
					    $sql = $this->user->getSQL();
 | 
				
			||||||
    $res = $sql->select("User.uid as userId", "User.name", "User.email", "Group.uid as groupId", "Group.name as groupName")
 | 
					    $res = $sql->select("User.uid as userId", "User.name", "User.email", "User.created_at",
 | 
				
			||||||
 | 
					                        "Group.uid as groupId", "Group.name as groupName")
 | 
				
			||||||
      ->from("User")
 | 
					      ->from("User")
 | 
				
			||||||
      ->leftJoin("UserGroup", "User.uid", "UserGroup.user_id")
 | 
					      ->leftJoin("UserGroup", "User.uid", "UserGroup.user_id")
 | 
				
			||||||
      ->leftJoin("Group", "Group.uid", "UserGroup.group_id")
 | 
					      ->leftJoin("Group", "Group.uid", "UserGroup.group_id")
 | 
				
			||||||
 | 
					      ->orderBy("User.uid")
 | 
				
			||||||
 | 
					      ->ascending()
 | 
				
			||||||
 | 
					      ->limit(Fetch::SELECT_SIZE)
 | 
				
			||||||
 | 
					      ->offset(($page - 1) * Fetch::SELECT_SIZE)
 | 
				
			||||||
      ->execute();
 | 
					      ->execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $this->success = ($res !== FALSE);
 | 
					    $this->success = ($res !== FALSE);
 | 
				
			||||||
@ -30,14 +68,15 @@ class Fetch extends Request {
 | 
				
			|||||||
    if($this->success) {
 | 
					    if($this->success) {
 | 
				
			||||||
      $this->result["users"] = array();
 | 
					      $this->result["users"] = array();
 | 
				
			||||||
      foreach($res as $row) {
 | 
					      foreach($res as $row) {
 | 
				
			||||||
        $userId = $row["userId"];
 | 
					        $userId = intval($row["userId"]);
 | 
				
			||||||
        $groupId = $row["groupId"];
 | 
					        $groupId = intval($row["groupId"]);
 | 
				
			||||||
        $groupName = $row["groupName"];
 | 
					        $groupName = $row["groupName"];
 | 
				
			||||||
        if (!isset($this->result["users"][$userId])) {
 | 
					        if (!isset($this->result["users"][$userId])) {
 | 
				
			||||||
          $this->result["users"][$userId] = array(
 | 
					          $this->result["users"][$userId] = array(
 | 
				
			||||||
            "uid" => $userId,
 | 
					            "uid" => $userId,
 | 
				
			||||||
            "name" => $row["name"],
 | 
					            "name" => $row["name"],
 | 
				
			||||||
            "email" => $row["email"],
 | 
					            "email" => $row["email"],
 | 
				
			||||||
 | 
					            "created_at" => $row["created_at"],
 | 
				
			||||||
            "groups" => array(),
 | 
					            "groups" => array(),
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -46,6 +85,7 @@ class Fetch extends Request {
 | 
				
			|||||||
          $this->result["users"][$userId]["groups"][$groupId] = $groupName;
 | 
					          $this->result["users"][$userId]["groups"][$groupId] = $groupName;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      $this->result["pages"] = intval(ceil($this->userCount / Fetch::SELECT_SIZE));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return $this->success;
 | 
					    return $this->success;
 | 
				
			||||||
 | 
				
			|||||||
@ -31,6 +31,7 @@ class CreateDatabase {
 | 
				
			|||||||
      ->addString("salt", 16)
 | 
					      ->addString("salt", 16)
 | 
				
			||||||
      ->addString("password", 64)
 | 
					      ->addString("password", 64)
 | 
				
			||||||
      ->addInt("language_id", true, 1)
 | 
					      ->addInt("language_id", true, 1)
 | 
				
			||||||
 | 
					      ->addDateTime("registered_at", false, $sql->currentTimestamp())
 | 
				
			||||||
      ->primaryKey("uid")
 | 
					      ->primaryKey("uid")
 | 
				
			||||||
      ->unique("email")
 | 
					      ->unique("email")
 | 
				
			||||||
      ->unique("name")
 | 
					      ->unique("name")
 | 
				
			||||||
 | 
				
			|||||||
@ -5,12 +5,12 @@ namespace Documents {
 | 
				
			|||||||
  use Documents\Admin\AdminHead;
 | 
					  use Documents\Admin\AdminHead;
 | 
				
			||||||
  use Elements\Document;
 | 
					  use Elements\Document;
 | 
				
			||||||
  use Objects\User;
 | 
					  use Objects\User;
 | 
				
			||||||
  use Views\AdminDashboard;
 | 
					  use Views\Admin\AdminDashboardBody;
 | 
				
			||||||
  use Views\LoginBody;
 | 
					  use Views\LoginBody;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  class Admin extends Document {
 | 
					  class Admin extends Document {
 | 
				
			||||||
    public function __construct(User $user) {
 | 
					    public function __construct(User $user) {
 | 
				
			||||||
      $body = $user->isLoggedIn() ? AdminDashboard::class : LoginBody::class;
 | 
					      $body = $user->isLoggedIn() ? AdminDashboardBody::class : LoginBody::class;
 | 
				
			||||||
      parent::__construct($user, AdminHead::class, $body);
 | 
					      parent::__construct($user, AdminHead::class, $body);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@ namespace Documents\Document404 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  use Elements\Body;
 | 
					  use Elements\Body;
 | 
				
			||||||
  use Elements\Head;
 | 
					  use Elements\Head;
 | 
				
			||||||
 | 
					  use Views\View404;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  class Head404 extends Head {
 | 
					  class Head404 extends Head {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -25,11 +26,6 @@ namespace Documents\Document404 {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function initSources() {
 | 
					    protected function initSources() {
 | 
				
			||||||
      // $this->loadJQuery();
 | 
					 | 
				
			||||||
      // $this->loadBootstrap();
 | 
					 | 
				
			||||||
      // $this->loadFontawesome();
 | 
					 | 
				
			||||||
      // $this->addJS(\Elements\Script::CORE);
 | 
					 | 
				
			||||||
      // $this->addCSS(\Elements\Link::CORE);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function initMetas() {
 | 
					    protected function initMetas() {
 | 
				
			||||||
@ -59,7 +55,7 @@ namespace Documents\Document404 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function getCode() {
 | 
					    public function getCode() {
 | 
				
			||||||
      $html = parent::getCode();
 | 
					      $html = parent::getCode();
 | 
				
			||||||
      $html .= "<b>404 Not Found</b>";
 | 
					      $html .= "<body>" . (new View404($this->getDocument())) . "</body>";
 | 
				
			||||||
      return $html;
 | 
					      return $html;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@ namespace Documents {
 | 
				
			|||||||
namespace Documents\Install {
 | 
					namespace Documents\Install {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  use Api\Notifications\Create;
 | 
					  use Api\Notifications\Create;
 | 
				
			||||||
 | 
					  use Api\Parameter\Parameter;
 | 
				
			||||||
  use Configuration\CreateDatabase;
 | 
					  use Configuration\CreateDatabase;
 | 
				
			||||||
  use Driver\SQL\SQL;
 | 
					  use Driver\SQL\SQL;
 | 
				
			||||||
  use Elements\Body;
 | 
					  use Elements\Body;
 | 
				
			||||||
@ -289,8 +290,8 @@ namespace Documents\Install {
 | 
				
			|||||||
      $username = $this->getParameter("username");
 | 
					      $username = $this->getParameter("username");
 | 
				
			||||||
      $password = $this->getParameter("password");
 | 
					      $password = $this->getParameter("password");
 | 
				
			||||||
      $confirmPassword = $this->getParameter("confirmPassword");
 | 
					      $confirmPassword = $this->getParameter("confirmPassword");
 | 
				
			||||||
 | 
					      $email = $this->getParameter("email") ?? "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      $msg = $this->errorString;
 | 
					 | 
				
			||||||
      $success = true;
 | 
					      $success = true;
 | 
				
			||||||
      $missingInputs = array();
 | 
					      $missingInputs = array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -321,13 +322,16 @@ namespace Documents\Install {
 | 
				
			|||||||
      } else if(strlen($password) < 6) {
 | 
					      } else if(strlen($password) < 6) {
 | 
				
			||||||
        $msg = "The password should be at least 6 characters long";
 | 
					        $msg = "The password should be at least 6 characters long";
 | 
				
			||||||
        $success = false;
 | 
					        $success = false;
 | 
				
			||||||
 | 
					      } else if($email && Parameter::parseType($email) !== Parameter::TYPE_EMAIL) {
 | 
				
			||||||
 | 
					        $msg = "Invalid email address";
 | 
				
			||||||
 | 
					        $success = false;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        $salt = generateRandomString(16);
 | 
					        $salt = generateRandomString(16);
 | 
				
			||||||
        $hash = hash('sha256', $password . $salt);
 | 
					        $hash = hash('sha256', $password . $salt);
 | 
				
			||||||
        $sql = $user->getSQL();
 | 
					        $sql = $user->getSQL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $success = $sql->insert("User", array("name", "salt", "password"))
 | 
					        $success = $sql->insert("User", array("name", "salt", "password", "email"))
 | 
				
			||||||
          ->addRow($username, $salt, $hash)
 | 
					          ->addRow($username, $salt, $hash, $email)
 | 
				
			||||||
          ->returning("uid")
 | 
					          ->returning("uid")
 | 
				
			||||||
          ->execute()
 | 
					          ->execute()
 | 
				
			||||||
          && $sql->insert("UserGroup", array("group_id", "user_id"))
 | 
					          && $sql->insert("UserGroup", array("group_id", "user_id"))
 | 
				
			||||||
@ -606,6 +610,7 @@ namespace Documents\Install {
 | 
				
			|||||||
          "title" => "Create a User",
 | 
					          "title" => "Create a User",
 | 
				
			||||||
          "form" => array(
 | 
					          "form" => array(
 | 
				
			||||||
            array("title" => "Username", "name"  => "username", "type"  => "text", "required" => true),
 | 
					            array("title" => "Username", "name"  => "username", "type"  => "text", "required" => true),
 | 
				
			||||||
 | 
					            array("title" => "Email", "name"  => "email", "type"  => "text"),
 | 
				
			||||||
            array("title" => "Password", "name"  => "password", "type"  => "password", "required" => true),
 | 
					            array("title" => "Password", "name"  => "password", "type"  => "password", "required" => true),
 | 
				
			||||||
            array("title" => "Confirm Password", "name"  => "confirmPassword", "type"  => "password", "required" => true),
 | 
					            array("title" => "Confirm Password", "name"  => "confirmPassword", "type"  => "password", "required" => true),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
@ -704,7 +709,7 @@ namespace Documents\Install {
 | 
				
			|||||||
        $id = $button["id"];
 | 
					        $id = $button["id"];
 | 
				
			||||||
        $float = $button["float"];
 | 
					        $float = $button["float"];
 | 
				
			||||||
        $disabled = (isset($button["disabled"]) && $button["disabled"]) ? " disabled" : "";
 | 
					        $disabled = (isset($button["disabled"]) && $button["disabled"]) ? " disabled" : "";
 | 
				
			||||||
        $button = "<button type=\"button\" id=\"$id\" class=\"btn btn-$type margin-xs\"$disabled>$title</button>";
 | 
					        $button = "<button type=\"button\" id=\"$id\" class=\"btn btn-$type m-1\"$disabled>$title</button>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($float === "left") {
 | 
					        if($float === "left") {
 | 
				
			||||||
          $buttonsLeft .= $button;
 | 
					          $buttonsLeft .= $button;
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ class CondOr extends Condition {
 | 
				
			|||||||
  private array $conditions;
 | 
					  private array $conditions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function __construct(...$conditions) {
 | 
					  public function __construct(...$conditions) {
 | 
				
			||||||
    $this->conditions = $conditions;
 | 
					    $this->conditions = (!empty($conditions) && is_array($conditions[0])) ? $conditions[0] : $conditions;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function getConditions() { return $this->conditions; }
 | 
					  public function getConditions() { return $this->conditions; }
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Driver\SQL\Query;
 | 
					namespace Driver\SQL\Query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Driver\SQL\Condition\CondOr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Delete extends Query {
 | 
					class Delete extends Query {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private string $table;
 | 
					  private string $table;
 | 
				
			||||||
@ -14,7 +16,7 @@ class Delete extends Query {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function where(...$conditions) {
 | 
					  public function where(...$conditions) {
 | 
				
			||||||
    $this->conditions = array_merge($this->conditions, $conditions);
 | 
					    $this->conditions[] = (count($conditions) === 1 ? $conditions : new CondOr($conditions));
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -7,9 +7,16 @@ use Driver\SQL\SQL;
 | 
				
			|||||||
abstract class Query {
 | 
					abstract class Query {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected SQL $sql;
 | 
					  protected SQL $sql;
 | 
				
			||||||
 | 
					  public bool $dump;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function __construct($sql) {
 | 
					  public function __construct($sql) {
 | 
				
			||||||
    $this->sql = $sql;
 | 
					    $this->sql = $sql;
 | 
				
			||||||
 | 
					    $this->dump = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function dump() {
 | 
				
			||||||
 | 
					    $this->dump = true;
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public abstract function execute();
 | 
					  public abstract function execute();
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Driver\SQL\Query;
 | 
					namespace Driver\SQL\Query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Driver\SQL\Condition\CondOr;
 | 
				
			||||||
use Driver\SQL\Join;
 | 
					use Driver\SQL\Join;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Select extends Query {
 | 
					class Select extends Query {
 | 
				
			||||||
@ -33,7 +34,7 @@ class Select extends Query {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function where(...$conditions) {
 | 
					  public function where(...$conditions) {
 | 
				
			||||||
    $this->conditions = array_merge($this->conditions, $conditions);
 | 
					    $this->conditions[] = (count($conditions) === 1 ? $conditions : new CondOr($conditions));
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Driver\SQL\Query;
 | 
					namespace Driver\SQL\Query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Driver\SQL\Condition\CondOr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Update extends Query {
 | 
					class Update extends Query {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private array $values;
 | 
					  private array $values;
 | 
				
			||||||
@ -16,7 +18,7 @@ class Update extends Query {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function where(...$conditions) {
 | 
					  public function where(...$conditions) {
 | 
				
			||||||
    $this->conditions = array_merge($this->conditions, $conditions);
 | 
					    $this->conditions[] = (count($conditions) === 1 ? $conditions : new CondOr($conditions));
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -144,6 +144,7 @@ abstract class SQL {
 | 
				
			|||||||
    $returning = $this->getReturning($returningCol);
 | 
					    $returning = $this->getReturning($returningCol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $query = "INSERT INTO $tableName$columnStr VALUES$values$onDuplicateKey$returning";
 | 
					    $query = "INSERT INTO $tableName$columnStr VALUES$values$onDuplicateKey$returning";
 | 
				
			||||||
 | 
					    if($insert->dump) { var_dump($query); var_dump($parameters); }
 | 
				
			||||||
    $res = $this->execute($query, $parameters, !empty($returning));
 | 
					    $res = $this->execute($query, $parameters, !empty($returning));
 | 
				
			||||||
    $success = ($res !== FALSE);
 | 
					    $success = ($res !== FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -189,6 +190,7 @@ abstract class SQL {
 | 
				
			|||||||
    $limit = ($select->getLimit() > 0 ? (" LIMIT " . $select->getLimit()) : "");
 | 
					    $limit = ($select->getLimit() > 0 ? (" LIMIT " . $select->getLimit()) : "");
 | 
				
			||||||
    $offset = ($select->getOffset() > 0 ? (" OFFSET " . $select->getOffset()) : "");
 | 
					    $offset = ($select->getOffset() > 0 ? (" OFFSET " . $select->getOffset()) : "");
 | 
				
			||||||
    $query = "SELECT $columns FROM $tables$joinStr$where$orderBy$limit$offset";
 | 
					    $query = "SELECT $columns FROM $tables$joinStr$where$orderBy$limit$offset";
 | 
				
			||||||
 | 
					    if($select->dump) { var_dump($query); var_dump($params); }
 | 
				
			||||||
    return $this->execute($query, $params, true);
 | 
					    return $this->execute($query, $params, true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -198,6 +200,7 @@ abstract class SQL {
 | 
				
			|||||||
    $where = $this->getWhereClause($delete->getConditions(), $params);
 | 
					    $where = $this->getWhereClause($delete->getConditions(), $params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $query = "DELETE FROM $table$where";
 | 
					    $query = "DELETE FROM $table$where";
 | 
				
			||||||
 | 
					    if($delete->dump) { var_dump($query); }
 | 
				
			||||||
    return $this->execute($query);
 | 
					    return $this->execute($query);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -218,6 +221,7 @@ abstract class SQL {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    $where = $this->getWhereClause($update->getConditions(), $params);
 | 
					    $where = $this->getWhereClause($update->getConditions(), $params);
 | 
				
			||||||
    $query = "UPDATE $table SET $valueStr$where";
 | 
					    $query = "UPDATE $table SET $valueStr$where";
 | 
				
			||||||
 | 
					    if($update->dump) { var_dump($query); var_dump($params); }
 | 
				
			||||||
    return $this->execute($query, $params);
 | 
					    return $this->execute($query, $params);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -290,6 +294,7 @@ abstract class SQL {
 | 
				
			|||||||
  protected abstract function execute($query, $values=NULL, $returnValues=false);
 | 
					  protected abstract function execute($query, $values=NULL, $returnValues=false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function buildCondition($condition, &$params) {
 | 
					  protected function buildCondition($condition, &$params) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ($condition instanceof CondOr) {
 | 
					    if ($condition instanceof CondOr) {
 | 
				
			||||||
      $conditions = array();
 | 
					      $conditions = array();
 | 
				
			||||||
      foreach($condition->getConditions() as $cond) {
 | 
					      foreach($condition->getConditions() as $cond) {
 | 
				
			||||||
@ -304,7 +309,7 @@ abstract class SQL {
 | 
				
			|||||||
    } else if ($condition instanceof CondBool) {
 | 
					    } else if ($condition instanceof CondBool) {
 | 
				
			||||||
      return $this->columnName($condition->getValue());
 | 
					      return $this->columnName($condition->getValue());
 | 
				
			||||||
    } else if (is_array($condition)) {
 | 
					    } else if (is_array($condition)) {
 | 
				
			||||||
      if (count($condition) == 1) {
 | 
					      if (count($condition) === 1) {
 | 
				
			||||||
        return $this->buildCondition($condition[0], $params);
 | 
					        return $this->buildCondition($condition[0], $params);
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        $conditions = array();
 | 
					        $conditions = array();
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Elements;
 | 
					namespace Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use View;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class Body extends View {
 | 
					abstract class Body extends View {
 | 
				
			||||||
  public function __construct($document) {
 | 
					  public function __construct($document) {
 | 
				
			||||||
    parent::__construct($document);
 | 
					    parent::__construct($document);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Elements;
 | 
					namespace Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use View;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class Head extends View {
 | 
					abstract class Head extends View {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected array $sources;
 | 
					  protected array $sources;
 | 
				
			||||||
@ -47,7 +45,7 @@ abstract class Head extends View {
 | 
				
			|||||||
  public function addKeywords($keywords) { array_merge($this->keywords, $keywords); }
 | 
					  public function addKeywords($keywords) { array_merge($this->keywords, $keywords); }
 | 
				
			||||||
  public function getTitle() { return $this->title; }
 | 
					  public function getTitle() { return $this->title; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function addCSS($href, $type = Link::MIME_TEXT_CSS)  { $this->sources[] = new Link("stylesheet", $href, $type); }
 | 
					  public function addCSS($href, $type = Link::MIME_TEXT_CSS)  { $this->sources[] = new Link(Link::STYLESHEET, $href, $type); }
 | 
				
			||||||
  public function addStyle($style) { $this->sources[] = new Style($style); }
 | 
					  public function addStyle($style) { $this->sources[] = new Style($style); }
 | 
				
			||||||
  public function addJS($url) { $this->sources[] = new Script(Script::MIME_TEXT_JAVASCRIPT, $url, ""); }
 | 
					  public function addJS($url) { $this->sources[] = new Script(Script::MIME_TEXT_JAVASCRIPT, $url, ""); }
 | 
				
			||||||
  public function addJSCode($code) { $this->sources[] = new Script(Script::MIME_TEXT_JAVASCRIPT, "", $code); }
 | 
					  public function addJSCode($code) { $this->sources[] = new Script(Script::MIME_TEXT_JAVASCRIPT, "", $code); }
 | 
				
			||||||
 | 
				
			|||||||
@ -2,28 +2,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Elements;
 | 
					namespace Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use View;
 | 
					class Link extends StaticView {
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Link extends View {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const STYLESHEET    = "stylesheet";
 | 
					  const STYLESHEET    = "stylesheet";
 | 
				
			||||||
  const MIME_TEXT_CSS = "text/css";
 | 
					  const MIME_TEXT_CSS = "text/css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const FONTAWESOME               = '/css/fontawesome.min.css';
 | 
					  const FONTAWESOME = "/css/fontawesome.min.css";
 | 
				
			||||||
  // const JQUERY_UI                 = '/css/jquery-ui.css';
 | 
					  const BOOTSTRAP   = "/css/bootstrap.min.css";
 | 
				
			||||||
  // const JQUERY_TERMINAL           = '/css/jquery.terminal.min.css';
 | 
					 | 
				
			||||||
  const BOOTSTRAP                 = '/css/bootstrap.min.css';
 | 
					 | 
				
			||||||
  // const BOOTSTRAP_THEME           = '/css/bootstrap-theme.min.css';
 | 
					 | 
				
			||||||
  // const BOOTSTRAP_DATEPICKER_CSS  = '/css/bootstrap-datepicker.standalone.min.css';
 | 
					 | 
				
			||||||
  // const BOOTSTRAP_DATEPICKER3_CSS = '/css/bootstrap-datepicker.standalone.min.css';
 | 
					 | 
				
			||||||
  // const HIGHLIGHT                 = '/css/highlight.css';
 | 
					 | 
				
			||||||
  // const HIGHLIGHT_THEME           = '/css/theme.css';
 | 
					 | 
				
			||||||
  const CORE        = "/css/style.css";
 | 
					  const CORE        = "/css/style.css";
 | 
				
			||||||
  const ADMIN       = "/css/admin.css";
 | 
					  const ADMIN       = "/css/admin.css";
 | 
				
			||||||
  // const HOME                      = "/css/home.css";
 | 
					 | 
				
			||||||
  // const REVEALJS                  = "/css/reveal.css";
 | 
					 | 
				
			||||||
  // const REVEALJS_THEME_MOON       = "/css/reveal_moon.css";
 | 
					 | 
				
			||||||
  // const REVEALJS_THEME_BLACK      = "/css/reveal_black.css";
 | 
					 | 
				
			||||||
  const ADMINLTE    = "/css/adminlte.min.css";
 | 
					  const ADMINLTE    = "/css/adminlte.min.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private string $type;
 | 
					  private string $type;
 | 
				
			||||||
 | 
				
			|||||||
@ -2,36 +2,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Elements;
 | 
					namespace Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Script extends \View {
 | 
					class Script extends StaticView {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const MIME_TEXT_JAVASCRIPT    = "text/javascript";
 | 
					  const MIME_TEXT_JAVASCRIPT    = "text/javascript";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const CORE      = "/js/script.js";
 | 
					  const CORE      = "/js/script.js";
 | 
				
			||||||
  // const HOME                    = "/js/home.js";
 | 
					 | 
				
			||||||
  const ADMIN     = "/js/admin.js";
 | 
					  const ADMIN     = "/js/admin.js";
 | 
				
			||||||
  // const SORTTABLE               = "/js/sorttable.js";
 | 
					 | 
				
			||||||
  const JQUERY    = "/js/jquery.min.js";
 | 
					  const JQUERY    = "/js/jquery.min.js";
 | 
				
			||||||
  // const JQUERY_UI               = "/js/jquery-ui.js";
 | 
					 | 
				
			||||||
  // const JQUERY_MASKED_INPUT     = "/js/jquery.maskedinput.min.js";
 | 
					 | 
				
			||||||
  // const JQUERY_CONTEXT_MENU     = "/js/jquery.contextmenu.min.js";
 | 
					 | 
				
			||||||
  // const JQUERY_TERMINAL         = "/js/jquery.terminal.min.js";
 | 
					 | 
				
			||||||
  // const JQUERY_TERMINAL_UNIX    = "/js/unix_formatting.js";
 | 
					 | 
				
			||||||
  // const JSCOLOR                 = "/js/jscolor.min.js";
 | 
					 | 
				
			||||||
  // const SYNTAX_HIGHLIGHTER      = "/js/syntaxhighlighter.js";
 | 
					 | 
				
			||||||
  // const HIGHLIGHT               = "/js/highlight.pack.js";
 | 
					 | 
				
			||||||
  // const GOOGLE_CHARTS           = "/js/loader.js";
 | 
					 | 
				
			||||||
  // const BOOTSTRAP               = "/js/bootstrap.min.js";
 | 
					 | 
				
			||||||
  // const BOOTSTRAP_DATEPICKER_JS = "/js/bootstrap-datepicker.min.js";
 | 
					 | 
				
			||||||
  // const POPPER                  = "/js/popper.min.js";
 | 
					 | 
				
			||||||
  // const JSMPEG                  = "/js/jsmpeg.min.js";
 | 
					 | 
				
			||||||
  // const MOMENT                  = "/js/moment.min.js";
 | 
					 | 
				
			||||||
  // const CHART                   = "/js/chart.js";
 | 
					 | 
				
			||||||
  // const REVEALJS                = "/js/reveal.js";
 | 
					 | 
				
			||||||
  // const REVEALJS_PLUGIN_NOTES   = "/js/reveal_notes.js";
 | 
					 | 
				
			||||||
  const INSTALL   = "/js/install.js";
 | 
					  const INSTALL   = "/js/install.js";
 | 
				
			||||||
  const BOOTSTRAP = "/js/bootstrap.bundle.min.js";
 | 
					  const BOOTSTRAP = "/js/bootstrap.bundle.min.js";
 | 
				
			||||||
 | 
					 | 
				
			||||||
  const HIGHLIGHT_JS_LOADER = "\$(document).ready(function(){\$('code').each(function(i, block) { hljs.highlightBlock(block); }); })";
 | 
					 | 
				
			||||||
  const ADMINLTE  = "/js/adminlte.min.js";
 | 
					  const ADMINLTE  = "/js/adminlte.min.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private string $type;
 | 
					  private string $type;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								core/Elements/StaticView.class.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										9
									
								
								core/Elements/StaticView.class.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					abstract class StaticView {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public abstract function getCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -2,9 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Elements;
 | 
					namespace Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use View;
 | 
					class Style extends StaticView {
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Style extends View {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private string $style;
 | 
					  private string $style;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Elements\Document;
 | 
					namespace Elements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class View {
 | 
					abstract class View extends StaticView {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private Document $document;
 | 
					  private Document $document;
 | 
				
			||||||
  private bool $loadView;
 | 
					  private bool $loadView;
 | 
				
			||||||
@ -112,4 +112,9 @@ abstract class View {
 | 
				
			|||||||
    $hidden = ($hidden?" hidden" : "");
 | 
					    $hidden = ($hidden?" hidden" : "");
 | 
				
			||||||
    return "<div class=\"alert alert-$type$hidden\" role=\"alert\"$id>$text</div>";
 | 
					    return "<div class=\"alert alert-$type$hidden\" role=\"alert\"$id>$text</div>";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function createBadge($type, $text) {
 | 
				
			||||||
 | 
					    $text = htmlspecialchars($text);
 | 
				
			||||||
 | 
					    return "<span class=\"badge badge-$type\">$text</span>";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -9,7 +9,8 @@ use External\JWT;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Session extends ApiObject {
 | 
					class Session extends ApiObject {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const DURATION = 120;
 | 
					  # in minutes
 | 
				
			||||||
 | 
					  const DURATION = 60*24;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private ?int $sessionId;
 | 
					  private ?int $sessionId;
 | 
				
			||||||
  private User $user;
 | 
					  private User $user;
 | 
				
			||||||
@ -91,13 +92,13 @@ class Session extends ApiObject {
 | 
				
			|||||||
    $this->updateMetaData();
 | 
					    $this->updateMetaData();
 | 
				
			||||||
    $sql = $this->user->getSQL();
 | 
					    $sql = $this->user->getSQL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $hours = Session::DURATION;
 | 
					    $minutes = Session::DURATION;
 | 
				
			||||||
    $columns = array("expires", "user_id", "ipAddress", "os", "browser", "data", "stay_logged_in");
 | 
					    $columns = array("expires", "user_id", "ipAddress", "os", "browser", "data", "stay_logged_in");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $success = $sql
 | 
					    $success = $sql
 | 
				
			||||||
      ->insert("Session", $columns)
 | 
					      ->insert("Session", $columns)
 | 
				
			||||||
      ->addRow(
 | 
					      ->addRow(
 | 
				
			||||||
        (new DateTime())->modify("+$hours hour"),
 | 
					        (new DateTime())->modify("+$minutes minute"),
 | 
				
			||||||
        $this->user->getId(),
 | 
					        $this->user->getId(),
 | 
				
			||||||
        $this->ipAddress,
 | 
					        $this->ipAddress,
 | 
				
			||||||
        $this->os,
 | 
					        $this->os,
 | 
				
			||||||
@ -125,11 +126,11 @@ class Session extends ApiObject {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  public function update() {
 | 
					  public function update() {
 | 
				
			||||||
    $this->updateMetaData();
 | 
					    $this->updateMetaData();
 | 
				
			||||||
    $hours = Session::DURATION;
 | 
					    $minutes = Session::DURATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $sql = $this->user->getSQL();
 | 
					    $sql = $this->user->getSQL();
 | 
				
			||||||
    return $sql->update("Session")
 | 
					    return $sql->update("Session")
 | 
				
			||||||
      ->set("Session.expires", (new DateTime())->modify("+$hours hour"))
 | 
					      ->set("Session.expires", (new DateTime())->modify("+$minutes minute"))
 | 
				
			||||||
      ->set("Session.ipAddress", $this->ipAddress)
 | 
					      ->set("Session.ipAddress", $this->ipAddress)
 | 
				
			||||||
      ->set("Session.os", $this->os)
 | 
					      ->set("Session.os", $this->os)
 | 
				
			||||||
      ->set("Session.browser", $this->browser)
 | 
					      ->set("Session.browser", $this->browser)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,24 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Views;
 | 
					namespace Views\Admin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Source: https://adminlte.io/themes/v3/
 | 
					// Source: https://adminlte.io/themes/v3/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Documents\Document404\Body404;
 | 
				
			||||||
use Elements\Body;
 | 
					use Elements\Body;
 | 
				
			||||||
use Elements\Script;
 | 
					use Elements\Script;
 | 
				
			||||||
 | 
					use Elements\View;
 | 
				
			||||||
 | 
					use Views\View404;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AdminDashboard extends Body {
 | 
					class AdminDashboardBody extends Body {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private array $errorMessages;
 | 
					  private array $errorMessages;
 | 
				
			||||||
 | 
					  private array $notifications;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function __construct($document) {
 | 
					  public function __construct($document) {
 | 
				
			||||||
    parent::__construct($document);
 | 
					    parent::__construct($document);
 | 
				
			||||||
    $this->errorMessages = array();
 | 
					    $this->errorMessages = array();
 | 
				
			||||||
 | 
					    $this->notifications = array();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private function getNotifications() : array {
 | 
					  private function getNotifications() : array {
 | 
				
			||||||
@ -49,8 +54,7 @@ class AdminDashboard extends Body {
 | 
				
			|||||||
    $iconMail = $this->createIcon("envelope", "fas");
 | 
					    $iconMail = $this->createIcon("envelope", "fas");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Notifications
 | 
					    // Notifications
 | 
				
			||||||
    $notifications = $this->getNotifications();
 | 
					    $numNotifications = count($this->notifications);
 | 
				
			||||||
    $numNotifications = count($notifications);
 | 
					 | 
				
			||||||
    if ($numNotifications === 0) {
 | 
					    if ($numNotifications === 0) {
 | 
				
			||||||
      $notificationText = L("No new notifications");
 | 
					      $notificationText = L("No new notifications");
 | 
				
			||||||
    } else if($numNotifications === 1) {
 | 
					    } else if($numNotifications === 1) {
 | 
				
			||||||
@ -98,7 +102,7 @@ class AdminDashboard extends Body {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Notifications
 | 
					    // Notifications
 | 
				
			||||||
    $i = 0;
 | 
					    $i = 0;
 | 
				
			||||||
    foreach($notifications as $notification) {
 | 
					    foreach($this->notifications as $notification) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      $title = $notification["title"];
 | 
					      $title = $notification["title"];
 | 
				
			||||||
      $notificationId = $notification["uid"];
 | 
					      $notificationId = $notification["uid"];
 | 
				
			||||||
@ -150,12 +154,17 @@ class AdminDashboard extends Body {
 | 
				
			|||||||
      ),
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $notificationCount = count($this->notifications);
 | 
				
			||||||
 | 
					    if ($notificationCount > 0) {
 | 
				
			||||||
 | 
					      $menuEntries["dashboard"]["badge"] = array("type" => "warning", "value" => $notificationCount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $currentView = $_GET["view"] ?? "dashboard";
 | 
					    $currentView = $_GET["view"] ?? "dashboard";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $html =
 | 
					    $html =
 | 
				
			||||||
      "<aside class=\"main-sidebar sidebar-dark-primary elevation-4\">
 | 
					      "<aside class=\"main-sidebar sidebar-dark-primary elevation-4\">
 | 
				
			||||||
        <!-- Brand Logo -->
 | 
					        <!-- Brand Logo -->
 | 
				
			||||||
        <a href=\"index3.html\" class=\"brand-link\">
 | 
					        <a href=\"/admin\" class=\"brand-link\">
 | 
				
			||||||
          <img src=\"/img/web_base_logo.png\" alt=\"WebBase Logo\" class=\"brand-image img-circle elevation-3\"
 | 
					          <img src=\"/img/web_base_logo.png\" alt=\"WebBase Logo\" class=\"brand-image img-circle elevation-3\"
 | 
				
			||||||
               style=\"opacity: .8\">
 | 
					               style=\"opacity: .8\">
 | 
				
			||||||
          <span class=\"brand-text font-weight-light\">WebBase</span>
 | 
					          <span class=\"brand-text font-weight-light\">WebBase</span>
 | 
				
			||||||
@ -172,11 +181,17 @@ class AdminDashboard extends Body {
 | 
				
			|||||||
      $name = L($menuEntry["name"]);
 | 
					      $name = L($menuEntry["name"]);
 | 
				
			||||||
      $icon = $this->createIcon($menuEntry["icon"], "fas", "nav-icon");
 | 
					      $icon = $this->createIcon($menuEntry["icon"], "fas", "nav-icon");
 | 
				
			||||||
      $active = ($currentView === $view) ? " active" : "";
 | 
					      $active = ($currentView === $view) ? " active" : "";
 | 
				
			||||||
 | 
					      $badge = $menuEntry["badge"] ?? "";
 | 
				
			||||||
 | 
					      if($badge) {
 | 
				
			||||||
 | 
					        $badgeType = $badge["type"];
 | 
				
			||||||
 | 
					        $badgeValue = $badge["value"];
 | 
				
			||||||
 | 
					        $badge = "<span class=\"badge badge-$badgeType right\">$badgeValue</span>";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      $html .=
 | 
					      $html .=
 | 
				
			||||||
        "<li class=\"nav-item\">
 | 
					        "<li class=\"nav-item\">
 | 
				
			||||||
                <a href=\"?view=$view\" class=\"nav-link$active\">
 | 
					                <a href=\"?view=$view\" class=\"nav-link$active\">
 | 
				
			||||||
                  $icon
 | 
					                  $icon<p>$name$badge</p>
 | 
				
			||||||
                  <p>$name </p>
 | 
					 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
              </li>";
 | 
					              </li>";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -190,32 +205,64 @@ class AdminDashboard extends Body {
 | 
				
			|||||||
    return $html;
 | 
					    return $html;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function getView() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $views = array(
 | 
				
			||||||
 | 
					      "dashboard" => Dashboard::class,
 | 
				
			||||||
 | 
					      "users" => UserOverview::class,
 | 
				
			||||||
 | 
					      "404" => View404::class,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $currentView = $_GET["view"] ?? "dashboard";
 | 
				
			||||||
 | 
					    if (!isset($views[$currentView])) {
 | 
				
			||||||
 | 
					      $currentView = "404";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $view = new $views[$currentView]($this->getDocument());
 | 
				
			||||||
 | 
					    assert($view instanceof View);
 | 
				
			||||||
 | 
					    $code = $view->getCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($view instanceof AdminView) {
 | 
				
			||||||
 | 
					      $this->errorMessages = array_merge($this->errorMessages, $view->getErrorMessages());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $code;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function loadView() {
 | 
				
			||||||
 | 
					    parent::loadView();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $head = $this->getDocument()->getHead();
 | 
				
			||||||
 | 
					    $head->addJS(Script::BOOTSTRAP);
 | 
				
			||||||
 | 
					    $head->loadAdminlte();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->notifications = $this->getNotifications();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private function getContent() {
 | 
					  private function getContent() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $this->getUsers();
 | 
					    $this->getUsers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $view = $this->getView();
 | 
				
			||||||
    $html = "<div class=\"content-wrapper p-2\">";
 | 
					    $html = "<div class=\"content-wrapper p-2\">";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    foreach($this->errorMessages as $errorMessage) {
 | 
					    foreach($this->errorMessages as $errorMessage) {
 | 
				
			||||||
      $html .= $this->createErrorText($errorMessage);
 | 
					      $html .= $this->createErrorText($errorMessage);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $html .= $view;
 | 
				
			||||||
    $html .= "</div>";
 | 
					    $html .= "</div>";
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return $html;
 | 
					    return $html;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function getCode() {
 | 
					  public function getCode() {
 | 
				
			||||||
 | 
					    $html = parent::getCode();
 | 
				
			||||||
    $head = $this->getDocument()->getHead();
 | 
					 | 
				
			||||||
    $head->addJS(Script::BOOTSTRAP);
 | 
					 | 
				
			||||||
    $head->loadAdminlte();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $header = $this->getHeader();
 | 
					    $header = $this->getHeader();
 | 
				
			||||||
    $sidebar = $this->getSidebar();
 | 
					    $sidebar = $this->getSidebar();
 | 
				
			||||||
    $content = $this->getContent();
 | 
					    $content = $this->getContent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $html =
 | 
					    $html .=
 | 
				
			||||||
      "<!-- LICENSE: /docs/LICENSE_ADMINLTE -->
 | 
					      "<!-- LICENSE: /docs/LICENSE_ADMINLTE -->
 | 
				
			||||||
      <body class=\"hold-transition sidebar-mini layout-fixed\">
 | 
					      <body class=\"hold-transition sidebar-mini layout-fixed\">
 | 
				
			||||||
          <div class=\"wrapper\">
 | 
					          <div class=\"wrapper\">
 | 
				
			||||||
							
								
								
									
										46
									
								
								core/Views/Admin/AdminView.class.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										46
									
								
								core/Views/Admin/AdminView.class.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Views\Admin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Elements\Document;
 | 
				
			||||||
 | 
					use Elements\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AdminView extends View {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected array $errorMessages;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function __construct(Document $document) {
 | 
				
			||||||
 | 
					    parent::__construct($document);
 | 
				
			||||||
 | 
					    $this->errorMessages = array();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getErrorMessages() {
 | 
				
			||||||
 | 
					    return $this->errorMessages;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getCode() {
 | 
				
			||||||
 | 
					    $html = parent::getCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $home = L("Home");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $html .=
 | 
				
			||||||
 | 
					      "<div class=\"content-header\">
 | 
				
			||||||
 | 
					        <div class=\"container-fluid\">
 | 
				
			||||||
 | 
					          <div class=\"row mb-2\">
 | 
				
			||||||
 | 
					            <div class=\"col-sm-6\">
 | 
				
			||||||
 | 
					              <h1 class=\"m-0 text-dark\">$this->title</h1>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <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\">$this->title</li>
 | 
				
			||||||
 | 
					              </ol>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div><!-- /.container-fluid -->
 | 
				
			||||||
 | 
					      </div>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $html;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								core/Views/Admin/Dashboard.class.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										25
									
								
								core/Views/Admin/Dashboard.class.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Views\Admin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Elements\Document;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Dashboard extends AdminView {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function __construct(Document $document) {
 | 
				
			||||||
 | 
					    parent::__construct($document);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function loadView() {
 | 
				
			||||||
 | 
					    parent::loadView();
 | 
				
			||||||
 | 
					    $this->title = L("Dashboard");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getCode() {
 | 
				
			||||||
 | 
					    $html = parent::getCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $html;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										164
									
								
								core/Views/Admin/UserOverview.class.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										164
									
								
								core/Views/Admin/UserOverview.class.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,164 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Views\Admin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use DateTime;
 | 
				
			||||||
 | 
					use Elements\Document;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserOverview extends AdminView {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private array $users;
 | 
				
			||||||
 | 
					  private int $page;
 | 
				
			||||||
 | 
					  private int $pageCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function __construct(Document $document) {
 | 
				
			||||||
 | 
					    parent::__construct($document);
 | 
				
			||||||
 | 
					    $this->users = array();
 | 
				
			||||||
 | 
					    $this->pageCount = 0;
 | 
				
			||||||
 | 
					    $this->page = 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function loadView() {
 | 
				
			||||||
 | 
					    parent::loadView();
 | 
				
			||||||
 | 
					    $this->title = L("User Control");
 | 
				
			||||||
 | 
					    $this->requestUsers();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function requestUsers() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(isset($_GET["page"]) && is_numeric($_GET["page"])) {
 | 
				
			||||||
 | 
					      $this->page = intval($_GET["page"]);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $this->page = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $req = new \Api\User\Fetch($this->getDocument()->getUser());
 | 
				
			||||||
 | 
					    if (!$req->execute(array("page" => $this->page))) {
 | 
				
			||||||
 | 
					      $this->errorMessages[] = $req->getLastError();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $result = $req->getResult();
 | 
				
			||||||
 | 
					      $this->users = $result["users"];
 | 
				
			||||||
 | 
					      $this->pageCount = $result["pages"];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function getGroups($groups) {
 | 
				
			||||||
 | 
					    $badges = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    foreach($groups as $groupId => $group) {
 | 
				
			||||||
 | 
					      $badgeClass = "secondary";
 | 
				
			||||||
 | 
					      if ($groupId === USER_GROUP_ADMIN) {
 | 
				
			||||||
 | 
					        $badgeClass = "danger";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      $badges[] = $this->createBadge($badgeClass, $group);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return implode(" ", $badges);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function getPagination() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $userPageNavigation = L("User page navigation");
 | 
				
			||||||
 | 
					    $previousDisabled = ($this->page == 1 ? " disabled" : "");
 | 
				
			||||||
 | 
					    $nextDisabled = ($this->page >= $this->pageCount ? " disabled" : "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $html =
 | 
				
			||||||
 | 
					      "<nav aria-label=\"$userPageNavigation\" id=\"userPageNavigation\">
 | 
				
			||||||
 | 
					        <ul class=\"pagination p-2 m-0 justify-content-end\">
 | 
				
			||||||
 | 
					          <li class=\"page-item$previousDisabled\"><a class=\"page-link\" href=\"#\">Previous</a></li>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for($i = 1; $i <= $this->pageCount; $i++) {
 | 
				
			||||||
 | 
					      $active = $i === $this->page ? " active" : "";
 | 
				
			||||||
 | 
					      $html .=
 | 
				
			||||||
 | 
					          "<li class=\"page-item$active\"><a class=\"page-link\" href=\"#\">$i</a></li>";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $html .=
 | 
				
			||||||
 | 
					          "<li class=\"page-item$nextDisabled\"><a class=\"page-link\" href=\"#\">Next</a></li>
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					      </nav>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $html;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function getUserRows() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $dateFormat = L("Y/m/d");
 | 
				
			||||||
 | 
					    $userRows = array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    foreach($this->users as $uid => $user) {
 | 
				
			||||||
 | 
					      $name = $user["name"];
 | 
				
			||||||
 | 
					      $email = $user["email"] ?? "";
 | 
				
			||||||
 | 
					      $registeredAt = (new DateTime($user["created_at"]))->format($dateFormat);
 | 
				
			||||||
 | 
					      $groups = $this->getGroups($user["groups"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      $userRows[] =
 | 
				
			||||||
 | 
					        "<tr data-id=\"$uid\">
 | 
				
			||||||
 | 
					           <td>$name</td>
 | 
				
			||||||
 | 
					           <td>$email</td>
 | 
				
			||||||
 | 
					           <td>$groups</td>
 | 
				
			||||||
 | 
					           <td>$registeredAt</td>
 | 
				
			||||||
 | 
					        </tr>";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return implode("", $userRows);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getCode() {
 | 
				
			||||||
 | 
					    $html = parent::getCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Icons
 | 
				
			||||||
 | 
					    $iconRefresh = $this->createIcon("sync");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Locale
 | 
				
			||||||
 | 
					    $users = L("Users");
 | 
				
			||||||
 | 
					    $name = L("Name");
 | 
				
			||||||
 | 
					    $email = L("Email");
 | 
				
			||||||
 | 
					    $groups = L("Groups");
 | 
				
			||||||
 | 
					    $registeredAt = L("Registered At");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Content
 | 
				
			||||||
 | 
					    $pagination = $this->getPagination();
 | 
				
			||||||
 | 
					    $userRows = $this->getUserRows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $html .=
 | 
				
			||||||
 | 
					      "<div class=\"content\">
 | 
				
			||||||
 | 
					        <div class=\"container-fluid\">
 | 
				
			||||||
 | 
					          <div class=\"row\">
 | 
				
			||||||
 | 
					            <div class=\"col-lg-12\">
 | 
				
			||||||
 | 
					               <div class=\"card\">
 | 
				
			||||||
 | 
					                <div class=\"card-header border-0\">
 | 
				
			||||||
 | 
					                  <h3 class=\"card-title\">$users</h3>
 | 
				
			||||||
 | 
					                  <div class=\"card-tools\">
 | 
				
			||||||
 | 
					                    <a href=\"#\" class=\"btn btn-tool btn-sm\" id=\"userTableRefresh\">
 | 
				
			||||||
 | 
					                      $iconRefresh
 | 
				
			||||||
 | 
					                    </a>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class=\"card-body table-responsive p-0\">
 | 
				
			||||||
 | 
					                  <table class=\"table table-striped table-valign-middle\" id=\"userTable\">
 | 
				
			||||||
 | 
					                    <thead>
 | 
				
			||||||
 | 
					                    <tr>
 | 
				
			||||||
 | 
					                      <th>$name</th>
 | 
				
			||||||
 | 
					                      <th>$email</th>
 | 
				
			||||||
 | 
					                      <th>$groups</th>
 | 
				
			||||||
 | 
					                      <th>$registeredAt</th>
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
 | 
					                    </thead>
 | 
				
			||||||
 | 
					                    <tbody>
 | 
				
			||||||
 | 
					                      $userRows
 | 
				
			||||||
 | 
					                    </tbody>
 | 
				
			||||||
 | 
					                  </table>
 | 
				
			||||||
 | 
					                  $pagination
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $html;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -3,20 +3,26 @@
 | 
				
			|||||||
namespace Views;
 | 
					namespace Views;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Api\GetLanguages;
 | 
					use Api\GetLanguages;
 | 
				
			||||||
 | 
					use Elements\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LanguageFlags extends \View {
 | 
					class LanguageFlags extends View {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private array $languageFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function __construct($document) {
 | 
					  public function __construct($document) {
 | 
				
			||||||
    parent::__construct($document);
 | 
					    parent::__construct($document);
 | 
				
			||||||
 | 
					    $this->languageFlags = array();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function getCode() {
 | 
					  public function loadView() {
 | 
				
			||||||
 | 
					    parent::loadView();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $request = new GetLanguages($this->getDocument()->getUser());
 | 
				
			||||||
 | 
					    if($request->execute()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      $requestUri = $_SERVER["REQUEST_URI"];
 | 
					      $requestUri = $_SERVER["REQUEST_URI"];
 | 
				
			||||||
      $queryString = $_SERVER['QUERY_STRING'];
 | 
					      $queryString = $_SERVER['QUERY_STRING'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $flags = array();
 | 
					 | 
				
			||||||
    $request = new GetLanguages($this->getDocument()->getUser());
 | 
					 | 
				
			||||||
      $params = explode("&", $queryString);
 | 
					      $params = explode("&", $queryString);
 | 
				
			||||||
      $query = array();
 | 
					      $query = array();
 | 
				
			||||||
      foreach($params as $param) {
 | 
					      foreach($params as $param) {
 | 
				
			||||||
@ -33,22 +39,22 @@ class LanguageFlags extends \View {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      $url = parse_url($requestUri, PHP_URL_PATH) . "?";
 | 
					      $url = parse_url($requestUri, PHP_URL_PATH) . "?";
 | 
				
			||||||
    if($request->execute()) {
 | 
					
 | 
				
			||||||
      foreach($request->getResult()['languages'] as $lang) {
 | 
					      foreach($request->getResult()['languages'] as $lang) {
 | 
				
			||||||
        $langCode = $lang['code'];
 | 
					        $langCode = $lang['code'];
 | 
				
			||||||
        $langName = $lang['name'];
 | 
					        $langName = $lang['name'];
 | 
				
			||||||
        $query['lang'] = $langCode;
 | 
					        $query['lang'] = $langCode;
 | 
				
			||||||
        $queryString = http_build_query($query);
 | 
					        $queryString = http_build_query($query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $flags[] = $this->createLink(
 | 
					        $this->languageFlags[] = $this->createLink(
 | 
				
			||||||
          "$url$queryString",
 | 
					          "$url$queryString",
 | 
				
			||||||
          "<img class=\"p-1\" src=\"/img/icons/lang/$langCode.gif\" alt=\"$langName\" title=\"$langName\">"
 | 
					          "<img class=\"p-1\" src=\"/img/icons/lang/$langCode.gif\" alt=\"$langName\" title=\"$langName\">"
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    }
 | 
				
			||||||
      $flags[] = $this->createErrorText($request->getLastError());
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return implode('', $flags);
 | 
					  public function getCode() {
 | 
				
			||||||
 | 
					    return implode('', $this->languageFlags);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -10,9 +10,13 @@ class LoginBody extends Body {
 | 
				
			|||||||
    parent::__construct($document);
 | 
					    parent::__construct($document);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function getCode() {
 | 
					  public function loadView() {
 | 
				
			||||||
 | 
					    parent::loadView();
 | 
				
			||||||
    $this->getDocument()->getHead()->loadBootstrap();
 | 
					    $this->getDocument()->getHead()->loadBootstrap();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getCode() {
 | 
				
			||||||
 | 
					    $html = parent::getCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $username = L("Username");
 | 
					    $username = L("Username");
 | 
				
			||||||
    $password = L("Password");
 | 
					    $password = L("Password");
 | 
				
			||||||
@ -25,7 +29,7 @@ class LoginBody extends Body {
 | 
				
			|||||||
    $domain = $_SERVER['HTTP_HOST'];
 | 
					    $domain = $_SERVER['HTTP_HOST'];
 | 
				
			||||||
    $protocol = getProtocol();
 | 
					    $protocol = getProtocol();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $html = "<body>";
 | 
					    $html .= "<body>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $accountCreated = "";
 | 
					    $accountCreated = "";
 | 
				
			||||||
    if(isset($_GET["accountCreated"])) {
 | 
					    if(isset($_GET["accountCreated"])) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								core/Views/View404.class.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										13
									
								
								core/Views/View404.class.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Views;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Elements\View;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class View404 extends View {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getCode() {
 | 
				
			||||||
 | 
					    return parent::getCode() . "<b>Not found</b>";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										26
									
								
								js/admin.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										26
									
								
								js/admin.js
									
									
									
									
									
								
							@ -1,4 +1,6 @@
 | 
				
			|||||||
$(document).ready(function() {
 | 
					$(document).ready(function() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Login
 | 
				
			||||||
  $("#username").keypress(function(e) { if(e.which == 13) $("#password").focus(); });
 | 
					  $("#username").keypress(function(e) { if(e.which == 13) $("#password").focus(); });
 | 
				
			||||||
  $("#password").keypress(function(e) { if(e.which == 13) $("#btnLogin").click(); });
 | 
					  $("#password").keypress(function(e) { if(e.which == 13) $("#btnLogin").click(); });
 | 
				
			||||||
  $("#btnLogin").click(function() {
 | 
					  $("#btnLogin").click(function() {
 | 
				
			||||||
@ -24,8 +26,26 @@ $(document).ready(function() {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $("#toggleSidebar").click(function() {
 | 
					  $("#userTableRefresh").click(function() {
 | 
				
			||||||
    $(".main-wrapper").toggleClass("sidebar-collapsed");
 | 
					    let tbody = $("#userTable > tbody");
 | 
				
			||||||
    $(".main-sidebar").toggleClass("collapsed");
 | 
					    let page = parseInt($("#userPageNavigation li.active > a").text().trim());
 | 
				
			||||||
 | 
					    tbody.find("tr").remove();
 | 
				
			||||||
 | 
					    tbody.append("<tr><td colspan=\"4\" class=\"text-center\">Loading… " + createLoadingIcon() + "</td></tr>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    jsCore.apiCall("/user/fetch", { page: page}, function (data) {
 | 
				
			||||||
 | 
					      let pageCount = data["pages"];
 | 
				
			||||||
 | 
					      let users = data["users"];
 | 
				
			||||||
 | 
					      let userRows = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // TODO: .. maybe use ts instead of plain js?
 | 
				
			||||||
 | 
					      for(let userId in users) {
 | 
				
			||||||
 | 
					        let user = users[userId];
 | 
				
			||||||
 | 
					        userRows.push("<tr><td>" + user.name + "</td><td>" + user.email + "</td><td></td><td></td></tr>");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      tbody.html(userRows.join(""));
 | 
				
			||||||
 | 
					    }, function (err) {
 | 
				
			||||||
 | 
					      alert(err);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -274,3 +274,7 @@ let jsCore = new Core();
 | 
				
			|||||||
$(document).ready(function() {
 | 
					$(document).ready(function() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createLoadingIcon() {
 | 
				
			||||||
 | 
					  return '<i class="fas fa-spin fa-spinner"></i>';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -10,7 +10,7 @@ class ApiTestCase(PhpTest):
 | 
				
			|||||||
            # ApiKeys
 | 
					            # ApiKeys
 | 
				
			||||||
            "Testing get api keys empty…": self.test_get_api_keys_empty,
 | 
					            "Testing get api keys empty…": self.test_get_api_keys_empty,
 | 
				
			||||||
            "Testing create api key…": self.test_create_api_key,
 | 
					            "Testing create api key…": self.test_create_api_key,
 | 
				
			||||||
            "Testing referesh api key…": self.test_refresh_api_key,
 | 
					            "Testing refresh api key…": self.test_refresh_api_key,
 | 
				
			||||||
            "Testing revoke api key…": self.test_revoke_api_key,
 | 
					            "Testing revoke api key…": self.test_revoke_api_key,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Notifications
 | 
					            # Notifications
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@ class InstallTestCase(PhpTest):
 | 
				
			|||||||
            "Testing invalid usernames…": self.test_invalid_usernames,
 | 
					            "Testing invalid usernames…": self.test_invalid_usernames,
 | 
				
			||||||
            "Testing invalid password…": self.test_invalid_password,
 | 
					            "Testing invalid password…": self.test_invalid_password,
 | 
				
			||||||
            "Testing not matching password…": self.test_not_matching_passwords,
 | 
					            "Testing not matching password…": self.test_not_matching_passwords,
 | 
				
			||||||
 | 
					            "Testing invalid email…": self.test_invalid_email,
 | 
				
			||||||
            "Testing user creation…": self.test_create_user,
 | 
					            "Testing user creation…": self.test_create_user,
 | 
				
			||||||
            "Testing skip mail configuration…": self.test_skil_mail_config,
 | 
					            "Testing skip mail configuration…": self.test_skil_mail_config,
 | 
				
			||||||
            "Testing complete setup…": self.test_complete_setup,
 | 
					            "Testing complete setup…": self.test_complete_setup,
 | 
				
			||||||
@ -40,8 +41,13 @@ class InstallTestCase(PhpTest):
 | 
				
			|||||||
        self.assertEquals(False, obj["success"])
 | 
					        self.assertEquals(False, obj["success"])
 | 
				
			||||||
        self.assertEquals("The given passwords do not match", obj["msg"])
 | 
					        self.assertEquals("The given passwords do not match", obj["msg"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_invalid_email(self):
 | 
				
			||||||
 | 
					        obj = self.httpPost(data={ "username": PhpTest.ADMIN_USERNAME, "password": PhpTest.ADMIN_PASSWORD, "confirmPassword": PhpTest.ADMIN_PASSWORD, "email": "123abc" })
 | 
				
			||||||
 | 
					        self.assertEquals(False, obj["success"])
 | 
				
			||||||
 | 
					        self.assertEquals("Invalid email address", obj["msg"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_user(self):
 | 
					    def test_create_user(self):
 | 
				
			||||||
        obj = self.httpPost(data={ "username": PhpTest.ADMIN_USERNAME, "password": PhpTest.ADMIN_PASSWORD, "confirmPassword": PhpTest.ADMIN_PASSWORD })
 | 
					        obj = self.httpPost(data={ "username": PhpTest.ADMIN_USERNAME, "password": PhpTest.ADMIN_PASSWORD, "confirmPassword": PhpTest.ADMIN_PASSWORD, "email": "test@test.com" })
 | 
				
			||||||
        self.assertEquals(True, obj["success"], obj["msg"])
 | 
					        self.assertEquals(True, obj["success"], obj["msg"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_skil_mail_config(self):
 | 
					    def test_skil_mail_config(self):
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user