Compare commits
33 commits
master
...
feature/VE
Author | SHA1 | Date | |
---|---|---|---|
|
6523e77742 | ||
eb6770204a | |||
|
32a78ed1b9 | ||
|
7b90160c48 | ||
|
6f93d0d4dd | ||
|
3c9be5efba | ||
|
430681d84f | ||
|
196ff0b1f1 | ||
85549fbd43 | |||
|
7d540d809a | ||
|
147cd09d13 | ||
|
6bac93205c | ||
|
e29163165f | ||
|
aacf885c56 | ||
|
1e4e71ad9c | ||
|
2d9fbc3b99 | ||
147189288f | |||
|
f9dd03193e | ||
3d92f5347a | |||
5c44d50989 | |||
8d246aa381 | |||
a34201ffc2 | |||
|
f7b7b6c956 | ||
|
9519236662 | ||
|
162cc4b0a4 | ||
|
8b87c7d2f7 | ||
597be3ce2e | |||
|
0baed1a7fc | ||
|
a2931d93f7 | ||
|
c7984873c0 | ||
|
f00bdc99ec | ||
|
2db5aa8693 | ||
|
f7fa124535 |
100 changed files with 3609 additions and 258 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -466,3 +466,8 @@ conf/modules.inc.php
|
|||
conf/routers.inc.php
|
||||
conf/lang.inc.php
|
||||
logs/Exception.log
|
||||
|
||||
|
||||
z_dome/
|
||||
composer.lock
|
||||
adminer.php
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<?php
|
||||
|
||||
use Venom\Core\Config;
|
||||
use Venom\Core\DatabaseHandler;
|
||||
use Venom\Core\Database\Database;
|
||||
|
||||
$config = Config::getInstance();
|
||||
$config->setVersion(1.0);
|
||||
$config->setDatabase([
|
||||
DatabaseHandler::DB_TYPE => 'mysql', //please change only if you know what you're doing! this can break a lot.
|
||||
DatabaseHandler::DB_HOST => '127.0.0.1',
|
||||
DatabaseHandler::DB_PORT => '3306', //default port is 3306
|
||||
DatabaseHandler::DB_USER => 'venom',
|
||||
DatabaseHandler::DB_PASSWORD => 'venomPassword',
|
||||
DatabaseHandler::DB_DB => 'venomCMS',
|
||||
DatabaseHandler::DB_EXTRA => '' // need to start with ';'
|
||||
Database::DB_TYPE => 'mysql', //please change only if you know what you're doing! this can break a lot.
|
||||
Database::DB_HOST => '127.0.0.1',
|
||||
Database::DB_PORT => '3306', //default port is 3306
|
||||
Database::DB_USER => 'venom',
|
||||
Database::DB_PASSWORD => 'venomPassword',
|
||||
Database::DB_DB => 'venomCMS',
|
||||
Database::DB_EXTRA => '' // need to start with ';'
|
||||
]);
|
||||
|
||||
/**
|
||||
|
|
0
base/lang.base.php
Normal file → Executable file
0
base/lang.base.php
Normal file → Executable file
|
@ -1,9 +1,4 @@
|
|||
<?php
|
||||
|
||||
//register modules -> need to have the Module Class at parent with the init function ;)
|
||||
//register modules -> only apply Module Path! like Meta now the ModuleLoader search for /modules/Meta/module.php!
|
||||
$modules = [];
|
||||
|
||||
// register controllers that can handle templates ;) need to have a render function for this
|
||||
$controllers = [
|
||||
'test' => \Controllers\TestController::class,
|
||||
];
|
18
base/router.base.php
Normal file → Executable file
18
base/router.base.php
Normal file → Executable file
|
@ -11,19 +11,5 @@ if (!isset($venom)) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
$router = new Router('defaultRouter', 1.0, 'api/');
|
||||
$router->addRoutes([
|
||||
'/test' => [
|
||||
'cl' => Route::class,
|
||||
'roles' => ['ROLE_GUEST'],
|
||||
'routes' => [
|
||||
'*' => [
|
||||
"GET" => 'getAll'
|
||||
],
|
||||
'1' => [
|
||||
"GET" => 'getAll'
|
||||
]
|
||||
]
|
||||
],
|
||||
]);
|
||||
$venom->addRouter('defaultRouter', $router);
|
||||
$router = new Router(Router::DEFAULT_ROUTER, 1.0, 'api/');
|
||||
$venom->addRouter($router);
|
|
@ -5,11 +5,19 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Maurice Grönwoldt",
|
||||
"email": "mauricegroenwoldt@gmail.com"
|
||||
"email": "mauricegroenwoldt@gmail.com",
|
||||
"role": "founder"
|
||||
},
|
||||
{
|
||||
"name": "Dominic Seela",
|
||||
"email": "kontakt@engineertrooper.com",
|
||||
"role": "friendly developer, supporter"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"ext-pdo": "*"
|
||||
"ext-pdo": "*",
|
||||
"ext-http": "*",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
0
conf/.gitkeep
Normal file → Executable file
0
conf/.gitkeep
Normal file → Executable file
|
@ -7,6 +7,14 @@ create table if not exists seoData
|
|||
)
|
||||
comment 'seo url mapping';
|
||||
|
||||
create table if not exists metaTagData
|
||||
(
|
||||
id int(255) auto_increment not null unique primary key,
|
||||
content JSON not null,
|
||||
isActive tinyint(1) default 1 null
|
||||
)
|
||||
comment 'Meta Tag File';
|
||||
|
||||
create table if not exists language
|
||||
(
|
||||
id int(255) auto_increment not null unique primary key,
|
||||
|
@ -27,3 +35,26 @@ create table if not exists data
|
|||
datatype enum ('content', 'form')
|
||||
)
|
||||
comment 'DataLoader File';
|
||||
|
||||
create table if not exists users
|
||||
(
|
||||
id int(255) auto_increment not null unique primary key,
|
||||
username varchar(255) not null unique,
|
||||
firstname varchar(255) not null,
|
||||
lastname varchar(255) not null,
|
||||
email varchar(255) not null,
|
||||
password varchar(255) not null,
|
||||
token varchar(255) not null,
|
||||
salt varchar(255) not null,
|
||||
roleId text default '0' not null,
|
||||
isActive tinyint(1) default 1 null
|
||||
)
|
||||
comment 'User File';
|
||||
|
||||
create table if not exists roles
|
||||
(
|
||||
id int(255) auto_increment not null unique primary key,
|
||||
name varchar(255) not null unique,
|
||||
content JSON not null,
|
||||
isActive tinyint(1) default 1 null
|
||||
)
|
0
lang/example.php
Normal file → Executable file
0
lang/example.php
Normal file → Executable file
0
logs/.gitkeep
Normal file → Executable file
0
logs/.gitkeep
Normal file → Executable file
0
public/.htaccess
Normal file → Executable file
0
public/.htaccess
Normal file → Executable file
|
@ -1,7 +0,0 @@
|
|||
RewriteEngine On
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
RewriteCond %{REQUEST_URI} (/[^.]*|\.)$ [NC]
|
||||
RewriteRule .* index.php [L]
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Venom\Core\Config;
|
||||
use Venom\Core\Setup;
|
||||
use Venom\Venom;
|
||||
|
||||
require_once '../../vendor/autoload.php';
|
||||
Setup::loadConfig(true);
|
||||
Setup::loadLanguage();
|
||||
|
||||
$config = Config::getInstance();
|
||||
if ($config->isMaintenance()) {
|
||||
echo 'Currently not available';
|
||||
exit;
|
||||
}
|
||||
//if devMode is on show all errors!
|
||||
if ($config->isDevMode()) {
|
||||
error_reporting(E_ALL);
|
||||
ini_set('error_reporting', E_ALL);
|
||||
}
|
||||
$venom = new Venom();
|
||||
Setup::loadRouters($venom);
|
||||
Setup::loadModules($venom);
|
||||
$venom->run();
|
0
public/content/.gitkeep
Normal file → Executable file
0
public/content/.gitkeep
Normal file → Executable file
|
@ -2,10 +2,12 @@
|
|||
|
||||
use Venom\Core\Config;
|
||||
use Venom\Core\Setup;
|
||||
use Venom\Helper\URLHelper;
|
||||
use Venom\Venom;
|
||||
|
||||
require_once '../vendor/autoload.php';
|
||||
Setup::loadConfig(false);
|
||||
session_start();
|
||||
Setup::loadConfig(URLHelper::getInstance()->isAdminUrl());
|
||||
Setup::loadLanguage();
|
||||
|
||||
$config = Config::getInstance();
|
||||
|
@ -21,4 +23,4 @@ if ($config->isDevMode()) {
|
|||
$venom = new Venom();
|
||||
Setup::loadRouters($venom);
|
||||
Setup::loadModules($venom);
|
||||
$venom->run();
|
||||
$venom->inject();
|
1
public/theme/admin/css/admin-panel.css
Executable file
1
public/theme/admin/css/admin-panel.css
Executable file
|
@ -0,0 +1 @@
|
|||
main{display:flex;height:100vh;overflow:hidden}main h1{margin-top:30px;margin-bottom:20px}main h2{margin-top:35px;margin-bottom:25px}main h3{margin-top:20px;margin-bottom:15px}main h4{margin-top:15px;margin-bottom:10px}main.nav-open .menu{transform:translateX(0)}main.nav-open .app{transform:translateX(220px)}main.nav-open .app .nav-toggle span{transition:width .3s;width:0}main.nav-open .app .nav-toggle span:before{transform:translateY(8px) rotate(-135deg)}main.nav-open .app .nav-toggle span:after{transform:translateY(-8px) rotate(135deg)}.app{transform:translateX(0);transition:transform .4s;flex-grow:1;overflow-y:auto;margin:.6rem .8rem;width:100%;max-height:100%;background:rgba(27,27,27,.5);position:relative}.app .nav-toggle{position:absolute;cursor:pointer;left:1rem;height:25px;width:25px}.app .nav-toggle span{transform:translateY(21px)}.app .nav-toggle span,.app .nav-toggle span:after,.app .nav-toggle span:before{border-radius:1px;height:2px;width:25px;background:#fff;position:absolute;content:'';transition:transform .5s,width .4s ease-in}.app .nav-toggle span:before{top:-8px}.app .nav-toggle span:after{bottom:-8px}.menu{width:220px;background-color:#1b1b1b;box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23);height:100%;position:fixed;z-index:1;top:0;left:0;overflow-x:hidden;transition:.4s;transform:translateX(-220px);display:flex;flex-direction:column}.menu .logo{text-align:center;font-family:monospace}.menu div[data-link]{padding:.75rem .5rem;position:relative}.menu div[data-link]:after{background-color:#3949ab;content:"";position:absolute;left:0;bottom:0;height:3px;width:100%;transform:scaleX(0);transition:transform .4s;transform-origin:left}.menu div[data-link]:hover:after{transform:scaleX(1)}.menu div[data-link]:last-child{margin-top:auto}.menu div[data-link].active{font-weight:700}.content-area{width:calc(100% - 20px);padding-top:30px;margin:0 auto;display:block}.content-area header{display:block;text-align:center}.content-area header h2{margin:25px 0}.content-area .back-arrow{width:36px;height:36px}.content-area textarea{background:rgba(27,27,27,.5);color:#fff;margin:15px 0 0 0;font-family:sans-serif;font-size:1.1rem;min-width:100%}.content-area .modules div{padding:6px 20px 6px 0}.content-area .add-new,.content-area .overview{width:100%}.content-area .overview div[data-link]{margin-right:10px;padding:10px;background-color:rgba(0,0,0,.3)}.content-area .overview div[data-link]:hover{background-color:rgba(0,0,0,.5)}.content-area .overview .icon{display:inline-block}.content-area .add-new{padding-top:25px}@media only screen and (min-width:768px){.content-area{width:calc(100% - 40px)}.content-area .flexbox{display:flex}.content-area .overview{flex-grow:1;width:60%}.content-area .add-new{padding-top:0;flex-grow:1;width:40%}}@media only screen and (min-width:1024px){.content-area{max-width:860px;padding-top:0;margin:0 0 0 20px}}@media only screen and (min-width:1024px){main,main.nav-open{display:flex}main .app,main.nav-open .app{transform:translateX(0)}main .menu,main.nav-open .menu{position:relative;transform:translateX(0)}main .nav-toggle,main.nav-open .nav-toggle{display:none}}.role-edit .privileges .name{font-size:1.15rem}
|
1
public/theme/admin/css/login.css
Executable file
1
public/theme/admin/css/login.css
Executable file
|
@ -0,0 +1 @@
|
|||
body,html{display:flex;justify-content:center;align-items:center}.hide{display:none!important}#login-background{background-color:rgba(31,31,31,.25);-webkit-filter:blur(10px);filter:blur(10px);position:absolute;top:0;left:0;width:100%;height:100%}login{display:flex;position:relative;max-width:860px;width:90%;height:400px;padding:1rem;border-radius:10px 40px;overflow:hidden;box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}#login{z-index:1;display:flex;flex-direction:column;align-items:center;width:100%}#login .logo{width:50%;margin-bottom:20px}#login .error-message{background-color:#c51162;padding:1rem;font-size:.7rem;display:block;width:50%}#login .input-group{width:50%}#login a{text-decoration:none;color:#fff}#login a:hover{color:#3949ab}
|
1
public/theme/admin/css/style.css
Executable file
1
public/theme/admin/css/style.css
Executable file
File diff suppressed because one or more lines are too long
1
public/theme/admin/icon-sprite.svg
Executable file
1
public/theme/admin/icon-sprite.svg
Executable file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg"><symbol viewBox="0 0 24 24" id="vt-add" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></symbol><symbol viewBox="0 0 24 24" id="vt-arrow-back" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></symbol><symbol viewBox="0 0 24 24" id="vt-check" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></symbol><symbol viewBox="0 0 24 24" id="vt-delete" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/><path d="M0 0h24v24H0z" fill="none"/></symbol><symbol viewBox="0 0 24 24" id="vt-edit" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a.996.996 0 000-1.41l-2.34-2.34a.996.996 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></symbol><symbol viewBox="0 0 24 24" id="vt-visibility" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></symbol></svg>
|
After Width: | Height: | Size: 1.5 KiB |
10
public/theme/admin/images/logo.svg
Executable file
10
public/theme/admin/images/logo.svg
Executable file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.9 KiB |
186
public/theme/admin/js/components.js
Executable file
186
public/theme/admin/js/components.js
Executable file
|
@ -0,0 +1,186 @@
|
|||
class Component {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
this.start();
|
||||
}
|
||||
|
||||
handle(data, ds) {
|
||||
}
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
return '';
|
||||
}
|
||||
|
||||
start() {
|
||||
if (window.routerIsReady) {
|
||||
router.addComponent(this.name || VUtils.tempId(), this);
|
||||
this.init();
|
||||
} else {
|
||||
window.addEventListener('routerReady', this.start.bind(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
class MetaDataComponent extends Component {
|
||||
constructor() {
|
||||
super("/metaData");
|
||||
this.tpl = "metaDataList";
|
||||
this.tpl2 = "metaDataEdit";
|
||||
this._url = "/admin/api/metaData";
|
||||
}
|
||||
|
||||
async handle(data, ds) {
|
||||
let meTpl = ds.id ? this.tpl2 : this.tpl;
|
||||
await tpl.loadTemplate(meTpl);
|
||||
return await tpl.renderOn(meTpl, data.content);
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
let url = this._url;
|
||||
if (ds.id) {
|
||||
url += '/' + ds.id;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
class OverviewComponent extends Component {
|
||||
constructor() {
|
||||
super("/overview");
|
||||
this.tpl = "overview";
|
||||
this._url = "/admin/api/overview";
|
||||
}
|
||||
|
||||
async handle(data, ds) {
|
||||
await tpl.loadTemplate(this.tpl);
|
||||
return await tpl.renderOn(this.tpl, data.content);
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
return this._url;
|
||||
}
|
||||
}
|
||||
class PagesComponent extends Component {
|
||||
constructor() {
|
||||
super("/pages");
|
||||
this.tpl = "pagesList";
|
||||
this.tpl2 = "pageEdit";
|
||||
this._url = "/admin/api/pages";
|
||||
}
|
||||
|
||||
async handle(data, ds) {
|
||||
let meTpl = ds.id ? this.tpl2 : this.tpl;
|
||||
await tpl.loadTemplate(meTpl);
|
||||
return await tpl.renderOn(meTpl, data.content);
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
let url = this._url;
|
||||
if (ds.id) {
|
||||
url += '/' + ds.id;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
class RolesComponent extends Component {
|
||||
constructor() {
|
||||
super("/roles");
|
||||
this.tpl = "rolesList";
|
||||
this.tpl2 = "roleEdit";
|
||||
this._url = "/admin/api/roles";
|
||||
}
|
||||
|
||||
async handle(data, ds) {
|
||||
let meTpl = ds.id ? this.tpl2 : this.tpl;
|
||||
await tpl.loadTemplate(meTpl);
|
||||
return await tpl.renderOn(meTpl, data.content);
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
let url = this._url;
|
||||
if (ds.id) {
|
||||
url += '/' + ds.id;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
class SeoUrlComponent extends Component {
|
||||
constructor() {
|
||||
super("/seoUrl");
|
||||
this.tpl = "seoUrlList";
|
||||
this.tpl2 = "seoUrlEdit";
|
||||
this._url = "/admin/api/seoUrl";
|
||||
}
|
||||
|
||||
async handle(data, ds) {
|
||||
let meTpl = ds.id ? this.tpl2 : this.tpl;
|
||||
await tpl.loadTemplate(meTpl);
|
||||
return await tpl.renderOn(meTpl, data.content);
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
let url = this._url;
|
||||
if (ds.id) {
|
||||
url += '/' + ds.id;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
class UsersComponent extends Component {
|
||||
constructor() {
|
||||
super("/users");
|
||||
this.tpl = "usersList";
|
||||
this.tpl2 = "userEdit";
|
||||
this._url = "/admin/api/users";
|
||||
}
|
||||
|
||||
async handle(data, ds) {
|
||||
let meTpl = ds.id ? this.tpl2 : this.tpl;
|
||||
await tpl.loadTemplate(meTpl);
|
||||
return await tpl.renderOn(meTpl, data.content);
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
let url = this._url;
|
||||
if (ds.id) {
|
||||
url += '/' + ds.id;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
class VenomStatusComponent extends Component {
|
||||
constructor() {
|
||||
super("/venomStatus");
|
||||
this.tpl = "venomStatus";
|
||||
this._url = "/admin/api/venomStatus";
|
||||
}
|
||||
|
||||
async handle(data, ds) {
|
||||
await tpl.loadTemplate(this.tpl);
|
||||
return await tpl.renderOn(this.tpl, data.content);
|
||||
}
|
||||
|
||||
getUrl(ds) {
|
||||
return this._url;
|
||||
}
|
||||
}
|
||||
(() => {
|
||||
// init all Components ;)
|
||||
new MetaDataComponent();
|
||||
new OverviewComponent();
|
||||
new PagesComponent();
|
||||
new RolesComponent();
|
||||
new SeoUrlComponent();
|
||||
new UsersComponent();
|
||||
new VenomStatusComponent();
|
||||
|
||||
|
||||
if (routerIsReady) {
|
||||
document.body.dispatchEvent(new CustomEvent('triggerRouter'));
|
||||
} else {
|
||||
document.addEventListener('routerReady', e => {
|
||||
document.body.dispatchEvent(new CustomEvent('triggerRouter'));
|
||||
})
|
||||
}
|
||||
})();
|
1
public/theme/admin/js/components.min.js
vendored
Executable file
1
public/theme/admin/js/components.min.js
vendored
Executable file
|
@ -0,0 +1 @@
|
|||
class Component{constructor(t){this.name=t,this.start()}handle(t,e){}init(){}getUrl(t){return""}start(){window.routerIsReady?(router.addComponent(this.name||VUtils.tempId(),this),this.init()):window.addEventListener("routerReady",this.start.bind(this))}}class MetaDataComponent extends Component{constructor(){super("/metaData"),this.tpl="metaDataList",this.tpl2="metaDataEdit",this._url="/admin/api/metaData"}async handle(t,e){let n=e.id?this.tpl2:this.tpl;return await tpl.loadTemplate(n),await tpl.renderOn(n,t.content)}getUrl(t){let e=this._url;return t.id&&(e+="/"+t.id),e}}class OverviewComponent extends Component{constructor(){super("/overview"),this.tpl="overview",this._url="/admin/api/overview"}async handle(t,e){return await tpl.loadTemplate(this.tpl),await tpl.renderOn(this.tpl,t.content)}getUrl(t){return this._url}}class PagesComponent extends Component{constructor(){super("/pages"),this.tpl="pagesList",this.tpl2="pageEdit",this._url="/admin/api/pages"}async handle(t,e){let n=e.id?this.tpl2:this.tpl;return await tpl.loadTemplate(n),await tpl.renderOn(n,t.content)}getUrl(t){let e=this._url;return t.id&&(e+="/"+t.id),e}}class RolesComponent extends Component{constructor(){super("/roles"),this.tpl="rolesList",this.tpl2="roleEdit",this._url="/admin/api/roles"}async handle(t,e){let n=e.id?this.tpl2:this.tpl;return await tpl.loadTemplate(n),await tpl.renderOn(n,t.content)}getUrl(t){let e=this._url;return t.id&&(e+="/"+t.id),e}}class SeoUrlComponent extends Component{constructor(){super("/seoUrl"),this.tpl="seoUrlList",this.tpl2="seoUrlEdit",this._url="/admin/api/seoUrl"}async handle(t,e){let n=e.id?this.tpl2:this.tpl;return await tpl.loadTemplate(n),await tpl.renderOn(n,t.content)}getUrl(t){let e=this._url;return t.id&&(e+="/"+t.id),e}}class UsersComponent extends Component{constructor(){super("/users"),this.tpl="usersList",this.tpl2="userEdit",this._url="/admin/api/users"}async handle(t,e){let n=e.id?this.tpl2:this.tpl;return await tpl.loadTemplate(n),await tpl.renderOn(n,t.content)}getUrl(t){let e=this._url;return t.id&&(e+="/"+t.id),e}}class VenomStatusComponent extends Component{constructor(){super("/venomStatus"),this.tpl="venomStatus",this._url="/admin/api/venomStatus"}async handle(t,e){return await tpl.loadTemplate(this.tpl),await tpl.renderOn(this.tpl,t.content)}getUrl(t){return this._url}}new MetaDataComponent,new OverviewComponent,new PagesComponent,new RolesComponent,new SeoUrlComponent,new UsersComponent,new VenomStatusComponent,routerIsReady?document.body.dispatchEvent(new CustomEvent("triggerRouter")):document.addEventListener("routerReady",t=>{document.body.dispatchEvent(new CustomEvent("triggerRouter"))});
|
1218
public/theme/admin/js/scripts.js
Executable file
1218
public/theme/admin/js/scripts.js
Executable file
File diff suppressed because it is too large
Load diff
1
public/theme/admin/js/scripts.min.js
vendored
Executable file
1
public/theme/admin/js/scripts.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
0
public/theme/default/css/test.css
Normal file → Executable file
0
public/theme/default/css/test.css
Normal file → Executable file
0
public/theme/default/js/test.js
Normal file → Executable file
0
public/theme/default/js/test.js
Normal file → Executable file
51
src/Venom/Admin/AdminController.php
Executable file
51
src/Venom/Admin/AdminController.php
Executable file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Admin;
|
||||
|
||||
|
||||
use Venom\Entities\RoleEntity;
|
||||
use Venom\Helper\URLHelper;
|
||||
use Venom\Security\Security;
|
||||
use Venom\Views\Asset;
|
||||
use Venom\Views\RenderController;
|
||||
use Venom\Views\VenomRenderer;
|
||||
|
||||
class AdminController implements RenderController
|
||||
|
||||
{
|
||||
|
||||
private string $tpl = 'default';
|
||||
|
||||
public function register(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function render(VenomRenderer $renderer): bool
|
||||
{
|
||||
if (!in_array(URLHelper::getInstance()->getUrl(), ['/admin/', '/admin'])) {
|
||||
http_response_code(404);
|
||||
$this->tpl = 'async';
|
||||
}
|
||||
|
||||
$isLogin = Security::get()->hasPermission("admin", RoleEntity::TYPE_READ);
|
||||
$renderer->addVar('isLoggedIn', $isLogin);
|
||||
if (!$isLogin) {
|
||||
Asset::get()->addCSS('login', 'login.css');
|
||||
} else {
|
||||
Asset::get()->addCSS('admin', 'admin-panel.css');
|
||||
}
|
||||
Asset::get()->addCSS('styles', 'style.css', 1);
|
||||
Asset::get()->addJS('scripts', 'scripts.min.js', 1);
|
||||
// Components are the Rendering-Pipeline to know how each Admin-Component needs to be rendered
|
||||
Asset::get()->addJS('components', 'components.min.js', 5);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTemplate(): string
|
||||
{
|
||||
return $this->tpl;
|
||||
}
|
||||
}
|
38
src/Venom/Admin/AdminRouterInit.php
Executable file
38
src/Venom/Admin/AdminRouterInit.php
Executable file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Admin;
|
||||
|
||||
|
||||
use Venom\Admin\Routes\LoginRoute;
|
||||
use Venom\Admin\Routes\TemplateLoader;
|
||||
use Venom\Routing\Route;
|
||||
use Venom\Routing\Router;
|
||||
use Venom\Venom;
|
||||
|
||||
class AdminRouterInit
|
||||
{
|
||||
public static function registerAdminRouters(Venom $venom): void
|
||||
{
|
||||
$venom->getRouter(Router::ADMIN_ROUTER)->addRoutes(self::getRoutes());
|
||||
}
|
||||
|
||||
public static function getRoutes(): array
|
||||
{
|
||||
return [
|
||||
'/login' => new Route(LoginRoute::class, [
|
||||
'*' => [
|
||||
"POST" => 'login'
|
||||
],
|
||||
'1' => [
|
||||
"GET" => 'handle'
|
||||
]
|
||||
]),
|
||||
'/templateLoader' => new Route(TemplateLoader::class, [
|
||||
'*' => [
|
||||
"GET" => 'handle'
|
||||
],
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
27
src/Venom/Admin/Routes/LoginRoute.php
Executable file
27
src/Venom/Admin/Routes/LoginRoute.php
Executable file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Admin\Routes;
|
||||
|
||||
|
||||
use Venom\Security\Security;
|
||||
|
||||
class LoginRoute
|
||||
{
|
||||
|
||||
public function login(): bool
|
||||
{
|
||||
Security::get()->login();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handle($fnc): bool
|
||||
{
|
||||
if ($fnc === 'logout') {
|
||||
Security::get()->logout();
|
||||
echo '{"reload": true}';
|
||||
die();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
25
src/Venom/Admin/Routes/TemplateLoader.php
Executable file
25
src/Venom/Admin/Routes/TemplateLoader.php
Executable file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Admin\Routes;
|
||||
|
||||
use Venom\Core\ArgumentHandler;
|
||||
use Venom\Core\Config;
|
||||
use Venom\Helper\TemplateUtil;
|
||||
|
||||
class TemplateLoader
|
||||
{
|
||||
public function handle(): bool
|
||||
{
|
||||
if (!Config::getInstance()->isDevMode()) {
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + (60 * 60 * 60 * 30)));
|
||||
header('Cache-Control: public');
|
||||
}
|
||||
$id = ArgumentHandler::get()->getItem('tpl', '..');
|
||||
if (strpos($id, '..')) {
|
||||
return false;
|
||||
}
|
||||
echo TemplateUtil::includeTemplate('jsTemplates/' . $id, '.tpl');
|
||||
die();
|
||||
}
|
||||
}
|
4
src/Venom/Routing/SeoController.php → src/Venom/Controller/SeoController.php
Normal file → Executable file
4
src/Venom/Routing/SeoController.php → src/Venom/Controller/SeoController.php
Normal file → Executable file
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Routing;
|
||||
namespace Venom\Controller;
|
||||
|
||||
|
||||
use Venom\Core\ArgumentHandler;
|
||||
use Venom\Core\Config;
|
||||
use Venom\Core\DatabaseHandler;
|
||||
use Venom\Core\Database\DatabaseHandler;
|
||||
use Venom\Helper\ErrorHandler;
|
||||
use Venom\Helper\URLHelper;
|
||||
|
|
@ -8,6 +8,7 @@ class ArgumentHandler
|
|||
{
|
||||
public static ?ArgumentHandler $instance = null;
|
||||
private array $arguments = [];
|
||||
private array $post = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -16,6 +17,7 @@ class ArgumentHandler
|
|||
}
|
||||
foreach ($_POST as $key => $item) {
|
||||
$this->arguments[htmlspecialchars($key)] = htmlspecialchars($item);
|
||||
$this->post[htmlspecialchars($key)] = htmlspecialchars($item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,4 +43,14 @@ class ArgumentHandler
|
|||
{
|
||||
return isset($this->arguments[$key]);
|
||||
}
|
||||
|
||||
public function getPostItem(string $key, $default = null)
|
||||
{
|
||||
return $this->post[$key] ?? $default;
|
||||
}
|
||||
|
||||
public function hasPostItem(string $key): bool
|
||||
{
|
||||
return isset($this->post[$key]);
|
||||
}
|
||||
}
|
3
src/Venom/Core/Config.php
Normal file → Executable file
3
src/Venom/Core/Config.php
Normal file → Executable file
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace Venom\Core;
|
||||
|
||||
use Venom\Models\ConfigObject;
|
||||
use Venom\Core\Database\DatabaseHandler;
|
||||
use Venom\Entities\ConfigObject;
|
||||
|
||||
class Config
|
||||
{
|
||||
|
|
102
src/Venom/Core/Database/Database.php
Executable file
102
src/Venom/Core/Database/Database.php
Executable file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace Venom\Core\Database;
|
||||
// class that hold the Database Connection! and Executes like the DatabaseHandler
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use PDOStatement;
|
||||
use Venom\Entities\DatabaseObject;
|
||||
|
||||
class Database
|
||||
{
|
||||
// constants
|
||||
public const DB_TYPE = 'type';
|
||||
public const DB_HOST = 'host';
|
||||
public const DB_PORT = 'port';
|
||||
public const DB_USER = 'user';
|
||||
public const DB_PASSWORD = 'pw';
|
||||
public const DB_DB = 'db';
|
||||
public const DB_EXTRA = 'extra';
|
||||
private ?\PDO $db = null;
|
||||
|
||||
public function init(array $data): void
|
||||
{
|
||||
//init instance with the current data... only working if the db is not init!
|
||||
if ($this->db != null) {
|
||||
return;
|
||||
}
|
||||
$dsn = '%s:host=%s;dbname=%s;port=%s';
|
||||
$connectString = sprintf($dsn, $data[self::DB_TYPE], $data[self::DB_HOST], $data[self::DB_DB], $data[self::DB_PORT] . $data[self::DB_EXTRA]);
|
||||
try {
|
||||
$this->db = new PDO($connectString, $data[self::DB_USER], $data[self::DB_PASSWORD]);
|
||||
} catch (PDOException $e) {
|
||||
trigger_error($e->getMessage());
|
||||
die($e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
public function getOne(string|EasyQuery $query, array $args = []): ?DatabaseObject
|
||||
{
|
||||
$sql = $query;
|
||||
if ($query instanceof EasyQuery) {
|
||||
$sql = $query->getQuery();
|
||||
$args = $query->getArgs();
|
||||
}
|
||||
$data = $this->getAll($sql, $args);
|
||||
if (count($data) > 0) {
|
||||
return $data[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAll(string|EasyQuery $query, array $args = []): array
|
||||
{
|
||||
$sql = $query;
|
||||
if ($query instanceof EasyQuery) {
|
||||
$sql = $query->getQuery();
|
||||
$args = $query->getArgs();
|
||||
}
|
||||
$stmt = $this->db->prepare($sql);
|
||||
$stmt->setFetchMode(PDO::FETCH_CLASS, DatabaseObject::class);
|
||||
$stmt->execute($args);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public function execute(string|EasyQuery $query, array $args = []): bool
|
||||
{
|
||||
$sql = $query;
|
||||
if ($query instanceof EasyQuery) {
|
||||
$sql = $query->getQuery();
|
||||
$args = $query->getArgs();
|
||||
}
|
||||
$stmt = $this->db->prepare($sql);
|
||||
return $stmt->execute($args);
|
||||
}
|
||||
|
||||
public function createStatement($query): bool|PDOStatement
|
||||
{
|
||||
$stmt = $this->db->prepare($query);
|
||||
$stmt->setFetchMode(PDO::FETCH_CLASS, DatabaseObject::class); // set to default fetch-mode :D
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
public function setClass($stmt, $class)
|
||||
{
|
||||
$stmt->setFetchMode(PDO::FETCH_CLASS, $class);
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
$this->db->beginTransaction();
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
$this->db->commit();
|
||||
}
|
||||
|
||||
public function rollBack()
|
||||
{
|
||||
$this->db->rollBack();
|
||||
}
|
||||
}
|
38
src/Venom/Core/Database/DatabaseHandler.php
Executable file
38
src/Venom/Core/Database/DatabaseHandler.php
Executable file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Venom\Core\Database;
|
||||
|
||||
class DatabaseHandler
|
||||
{
|
||||
private static ?DatabaseHandler $instance = null;
|
||||
private Database $db;
|
||||
private array $cache; //EntityManager Cache!
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
$this->db = new Database();
|
||||
}
|
||||
|
||||
public static function get(): Database
|
||||
{
|
||||
return self::getInstance()->db;
|
||||
}
|
||||
|
||||
public static function getInstance(): DatabaseHandler
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new DatabaseHandler();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public static function getEntityManager($entityClass): EntityManager
|
||||
{
|
||||
$instance = self::getInstance();
|
||||
// i dont make sure this class exist because the user should do this ;)
|
||||
if (!isset($instance->cache[$entityClass])) {
|
||||
$instance->cache[$entityClass] = new EntityManager($entityClass, self::get());
|
||||
}
|
||||
return $instance->cache[$entityClass];
|
||||
}
|
||||
}
|
220
src/Venom/Core/Database/EasyQuery.php
Executable file
220
src/Venom/Core/Database/EasyQuery.php
Executable file
|
@ -0,0 +1,220 @@
|
|||
<?php
|
||||
|
||||
namespace Venom\Core\Database;
|
||||
|
||||
// the QueryBuilder is stupid! dont use it for Very Complex Queries because it's should do Entity Loading Easier :)
|
||||
class EasyQuery
|
||||
{
|
||||
const ORDER_ASC = 0;
|
||||
const ORDER_DESC = 1;
|
||||
const WHERE_AND = "AND";
|
||||
const WHERE_AND_NOT = "AND NOT";
|
||||
const WHERE_OR = "OR";
|
||||
const WHERE_OR_NOT = "OR NOT";
|
||||
const WHERE_NOT = "NOT";
|
||||
|
||||
private array $where = [];
|
||||
private array $args = [];
|
||||
private string $query = "";
|
||||
private int $limit = -1;
|
||||
private int $offset = 0;
|
||||
private string $whereStmt = "";
|
||||
private string $havingStmt = "";
|
||||
private array $order = [];
|
||||
private array $groupBy = [];
|
||||
private array $having = [];
|
||||
|
||||
public function __construct(private string $tableName, private array $fields = [])
|
||||
{
|
||||
}
|
||||
|
||||
public static function createSelect(array $fields, string $table): string
|
||||
{
|
||||
return "SELECT " . implode(", ", $fields) . " FROM " . $table;
|
||||
}
|
||||
|
||||
public function setWhere(string $statement): static
|
||||
{
|
||||
$this->whereStmt = $statement;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHaving(string $statement): static
|
||||
{
|
||||
$this->havingStmt = $statement;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLimit(int $limit): static
|
||||
{
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setOffset(int $offset): static
|
||||
{
|
||||
$this->offset = $offset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addField($field, $as = ""): static
|
||||
{
|
||||
if ($as !== "") {
|
||||
$field .= " AS " . $as;
|
||||
}
|
||||
$this->fields[] = $field;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addFields(array $fields): static
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
$this->fields[] = $field;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function where($key, $value, $type = "AND"): static
|
||||
{
|
||||
$this->where[] = [$key, $type];
|
||||
$this->args[":" . $key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function having($key, $value, $type = "AND"): static
|
||||
{
|
||||
$this->having[] = [$key, $type];
|
||||
$this->args[":" . $key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orderBy(string $key, int $mode = self::ORDER_ASC): static
|
||||
{
|
||||
$this->order[] = $mode === self::ORDER_DESC ? $key . " DESC" : $key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function groupBy(string $key): static
|
||||
{
|
||||
$this->groupBy[] = $key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setArg($key, $value): static
|
||||
{
|
||||
$this->args[":" . $key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// returns a Query
|
||||
|
||||
public function addArgAndField($key, $value): static
|
||||
{
|
||||
$this->args[":" . $key] = $value;
|
||||
$this->fields[] = $key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildSelect(): static
|
||||
{
|
||||
// we build an easyQuery Builder that can very easy stuff
|
||||
$query = self::createSelect($this->fields, $this->tableName);
|
||||
if (count($this->where) > 0) {
|
||||
$this->whereStmt = $this->parseStmt($this->where, $this->whereStmt);
|
||||
}
|
||||
if (count($this->having) > 0) {
|
||||
$this->havingStmt = $this->parseStmt($this->having, $this->havingStmt);
|
||||
}
|
||||
if ($this->whereStmt !== "") {
|
||||
$query .= " WHERE " . $this->whereStmt;
|
||||
}
|
||||
if (count($this->groupBy)) {
|
||||
$query .= " GROUP BY " . implode(", ", $this->groupBy);
|
||||
}
|
||||
if ($this->havingStmt !== "") {
|
||||
$query .= " HAVING " . $this->havingStmt;
|
||||
}
|
||||
if (count($this->order)) {
|
||||
$query .= " ORDER BY " . implode(", ", $this->order);
|
||||
}
|
||||
if ($this->offset > 0) {
|
||||
$query .= " OFFSET " . $this->offset;
|
||||
}
|
||||
if ($this->limit > 0) {
|
||||
$query .= " LIMIT " . $this->limit;
|
||||
}
|
||||
$this->query = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildInsertQuery(): static
|
||||
{
|
||||
$query = "INSERT INTO " . $this->tableName;
|
||||
$joinedFields = implode(", ", $this->fields);
|
||||
$values = implode(", ", array_keys($this->args));
|
||||
$query .= "(" . $joinedFields . ") VALUES (" . $values . ")";
|
||||
$this->query = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildUpdateQuery(): static
|
||||
{
|
||||
$query = "UPDATE " . $this->tableName . " SET ";
|
||||
$setFields = [];
|
||||
foreach ($this->fields as $field) {
|
||||
$setFields[] = $field . " = :" . $field;
|
||||
}
|
||||
$query .= implode(", ", $setFields);
|
||||
if (count($this->where) > 0) {
|
||||
$this->whereStmt = $this->parseStmt($this->where, $this->whereStmt);
|
||||
}
|
||||
if ($this->whereStmt !== "") {
|
||||
$query .= " WHERE " . $this->whereStmt;
|
||||
}
|
||||
$this->query = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildDeleteQuery(): static
|
||||
{
|
||||
$query = "DELETE FROM " . $this->tableName;
|
||||
if (count($this->where) > 0) {
|
||||
$this->whereStmt = $this->parseStmt($this->where, $this->whereStmt);
|
||||
}
|
||||
if ($this->whereStmt !== "") {
|
||||
$query .= " WHERE " . $this->whereStmt;
|
||||
}
|
||||
$this->query = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuery(): string
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
public function getArgs(): array
|
||||
{
|
||||
return $this->args;
|
||||
}
|
||||
|
||||
public function getFields(): array
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
private function parseStmt($items, $default = ""): string
|
||||
{
|
||||
$query = $default;
|
||||
foreach ($items as $item) {
|
||||
if ($query !== "") {
|
||||
$query .= " " . $item[1] . " ";
|
||||
}
|
||||
if ($item[1] === self::WHERE_NOT && $query === "") {
|
||||
$query .= "NOT ";
|
||||
}
|
||||
$query .= $item[0] . " = :" . $item[0];
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
}
|
137
src/Venom/Core/Database/Entity.php
Executable file
137
src/Venom/Core/Database/Entity.php
Executable file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
namespace Venom\Core\Database;
|
||||
|
||||
// Entity has a Load and Save function!
|
||||
// The Entity needs to have a primary key... most of the time this is a id!
|
||||
use JsonSerializable;
|
||||
use RuntimeException;
|
||||
|
||||
abstract class Entity implements JsonSerializable
|
||||
{
|
||||
public static string $tableName = "";
|
||||
// make sure this exists!
|
||||
public int $id = -1;
|
||||
public string $primaryKey = "id";
|
||||
public array $loadedFields = [];
|
||||
public array $blackList = ["id"];
|
||||
// Please override this Property in the Class you implement the Abstract Class! this is needed to run the right SQL calls
|
||||
public ?array $fields = null;
|
||||
|
||||
// Override this if you want special fields :)
|
||||
|
||||
public function getLoadedFieldValues(): array
|
||||
{
|
||||
$keyValue = [];
|
||||
foreach ($this->loadedFields as $var) {
|
||||
$keyValue[$var] = $this->$var;
|
||||
}
|
||||
return $keyValue;
|
||||
}
|
||||
|
||||
public function getFieldsToWrite(): array
|
||||
{
|
||||
if ($this->fields !== null) {
|
||||
return $this->fields;
|
||||
}
|
||||
$localBlacklist = array_merge(["primaryKey", "tableName", "loadedFields", "blackList", "fields"], $this->blackList);
|
||||
$allLoaded = in_array("*", $this->loadedFields);
|
||||
$vars = get_object_vars($this);
|
||||
foreach ($vars as $key => $var) {
|
||||
if (in_array($key, $localBlacklist)) {
|
||||
unset($vars[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$allLoaded) {
|
||||
foreach ($vars as $key => $var) {
|
||||
if (!in_array($key, $this->loadedFields)) {
|
||||
unset($vars[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($vars[$this->primaryKey]);
|
||||
$this->fields = $vars;
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
public function save(): bool
|
||||
{
|
||||
$this->preSave();
|
||||
$primaryKey = $this->primaryKey;
|
||||
$fields = $this->removeEmptyFields($this->getFieldsToWrite());
|
||||
$query = new EasyQuery(static::$tableName);
|
||||
foreach ($fields as $key => $field) {
|
||||
$query->addArgAndField($key, $field);
|
||||
}
|
||||
if ($this->$primaryKey === "") {
|
||||
$query->buildInsertQuery();
|
||||
} else {
|
||||
$query->where($primaryKey, $this->$primaryKey)->buildUpdateQuery();
|
||||
}
|
||||
return DatabaseHandler::get()->execute($query);
|
||||
}
|
||||
|
||||
public function load($fields = ['*'], ?EasyQuery $query = null): static
|
||||
{
|
||||
if ($query === null) {
|
||||
$primaryKey = $this->primaryKey;
|
||||
$query = new EasyQuery(static::$tableName, $fields);
|
||||
$query->where($primaryKey, $this->$primaryKey)->setLimit(1)->buildSelect();
|
||||
|
||||
} else {
|
||||
$query->setLimit(1)->buildSelect();
|
||||
}
|
||||
|
||||
$item = DatabaseHandler::get()->getOne($query);
|
||||
if ($item === null) {
|
||||
return $this;
|
||||
}
|
||||
$lazy = $item->getData();
|
||||
$this->id = $item->id;
|
||||
foreach ($lazy as $key => $item) {
|
||||
$this->$key = $item;
|
||||
}
|
||||
$this->fields = null;
|
||||
$this->loadedFields = array_merge($this->loadedFields, $query->getFields());
|
||||
$this->postLoad();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
// Implement your own if you want to override this behaviour!
|
||||
throw new RuntimeException("Write to Property: $name that is not Available in the Entity!");
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$key = $this->primaryKey;
|
||||
$query = new EasyQuery(self::$tableName);
|
||||
$query->setArg($this->primaryKey, $this->$key)->buildDeleteQuery();
|
||||
DatabaseHandler::get()->execute($query->getQuery(), $query->getArgs());
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return $this->getLoadedFieldValues();
|
||||
}
|
||||
|
||||
public function preSave()
|
||||
{
|
||||
}
|
||||
|
||||
public function postLoad()
|
||||
{
|
||||
}
|
||||
|
||||
private function removeEmptyFields(array $vars): array
|
||||
{
|
||||
foreach ($vars as $name => $item) {
|
||||
if (empty($item) && $name != $this->primaryKey) {
|
||||
unset($vars[$name]);
|
||||
}
|
||||
}
|
||||
return $vars;
|
||||
}
|
||||
}
|
136
src/Venom/Core/Database/EntityManager.php
Executable file
136
src/Venom/Core/Database/EntityManager.php
Executable file
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace Venom\Core\Database;
|
||||
|
||||
use Exception;
|
||||
|
||||
class EntityManager
|
||||
{
|
||||
/** @var Entity[] */
|
||||
private array $entities = [];
|
||||
|
||||
public function __construct(private string $classType, private Database $db)
|
||||
{
|
||||
}
|
||||
|
||||
public static function create($callable): EntityManager
|
||||
{
|
||||
return DatabaseHandler::getEntityManager($callable);
|
||||
}
|
||||
|
||||
public function createEntity()
|
||||
{
|
||||
$ent = new $this->classType;
|
||||
$this->entities[] = $ent;
|
||||
return $ent;
|
||||
}
|
||||
|
||||
public function addEntity(Entity $entity)
|
||||
{
|
||||
$this->entities[] = $entity;
|
||||
}
|
||||
|
||||
public function removeEntity(Entity $entity)
|
||||
{
|
||||
foreach ($this->entities as $key => $item) {
|
||||
if ($entity === $item) {
|
||||
unset($this->entities[$key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function findBy($key, $value): ?Entity
|
||||
{
|
||||
foreach ($this->entities as $entity) {
|
||||
if ($entity->$key === $value) {
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function saveAll(): bool
|
||||
{
|
||||
if (count($this->entities) === 0) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
$this->db->start();
|
||||
foreach ($this->entities as $entity) {
|
||||
$entity->save();
|
||||
}
|
||||
$this->db->commit();
|
||||
} catch (Exception $ex) {
|
||||
trigger_error($ex->getMessage());
|
||||
$this->db->rollBack();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteEntities(): bool
|
||||
{
|
||||
try {
|
||||
$this->db->start();
|
||||
foreach ($this->entities as $entity) {
|
||||
$entity->delete();
|
||||
}
|
||||
$this->db->commit();
|
||||
} catch (Exception $ex) {
|
||||
trigger_error($ex->getMessage());
|
||||
$this->db->rollBack();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function clearAll()
|
||||
{
|
||||
$this->entities = [];
|
||||
}
|
||||
|
||||
public function load(string|EasyQuery $query, $args = [], array $fields = ["*"])
|
||||
{
|
||||
$sql = $query;
|
||||
if ($query instanceof EasyQuery) {
|
||||
$query->buildSelect();
|
||||
$sql = $query->getQuery();
|
||||
$args = $query->getArgs();
|
||||
$fields = $query->getFields();
|
||||
}
|
||||
$stmt = $this->db->createStatement($sql);
|
||||
$this->db->setClass($stmt, $this->classType);
|
||||
if ($stmt->execute($args)) {
|
||||
/** @var Entity[] $all */
|
||||
$all = $stmt->fetchAll();
|
||||
foreach ($all as $item) {
|
||||
$item->loadedFields = $fields;
|
||||
$item->postLoad();
|
||||
$this->addEntity($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function execute($query): bool
|
||||
{
|
||||
return $this->db->execute($query);
|
||||
}
|
||||
|
||||
public function getAll(): array
|
||||
{
|
||||
return $this->entities;
|
||||
}
|
||||
|
||||
public function getFirst(): ?Entity
|
||||
{
|
||||
return $this->entities[0] ?? null;
|
||||
}
|
||||
|
||||
private function addEntities(array $entities)
|
||||
{
|
||||
foreach ($entities as $entity) {
|
||||
$this->entities[] = $entity;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Core;
|
||||
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use Venom\Models\DatabaseObject;
|
||||
|
||||
/**
|
||||
* Singleton DatabaseHandler... make sure we only have one connection to the database..
|
||||
* @package Venom\Database
|
||||
*/
|
||||
class DatabaseHandler
|
||||
{
|
||||
// constants
|
||||
public const DB_TYPE = 'type';
|
||||
public const DB_HOST = 'host';
|
||||
public const DB_PORT = 'port';
|
||||
public const DB_USER = 'user';
|
||||
public const DB_PASSWORD = 'pw';
|
||||
public const DB_DB = 'db';
|
||||
public const DB_EXTRA = 'extra';
|
||||
private static ?self $instance = null;
|
||||
private ?PDO $db = null;
|
||||
|
||||
public static function get(): DatabaseHandler
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(array $data): void
|
||||
{
|
||||
//init instance with the current data... only working if the db is not init!
|
||||
if ($this->db != null) {
|
||||
return;
|
||||
}
|
||||
$dsn = '%s:host=%s;dbname=%s;port=%s';
|
||||
$connectString = sprintf($dsn, $data[self::DB_TYPE], $data[self::DB_HOST], $data[self::DB_DB], $data[self::DB_PORT] . $data[self::DB_EXTRA]);
|
||||
try {
|
||||
$this->db = new PDO($connectString, $data[self::DB_USER], $data[self::DB_PASSWORD]);
|
||||
} catch (PDOException $e) {
|
||||
trigger_error($e->getMessage());
|
||||
die($e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
public function getOne(string $query, array $args): ?DatabaseObject
|
||||
{
|
||||
$data = $this->getAll($query, $args);
|
||||
if (count($data) > 0) {
|
||||
return $data[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAll(string $query, array $args): array
|
||||
{
|
||||
$stmt = $this->db->prepare($query);
|
||||
$stmt->setFetchMode(PDO::FETCH_CLASS, DatabaseObject::class);
|
||||
$stmt->execute($args);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public function execute(string $query, array $args): bool
|
||||
{
|
||||
$stmt = $this->db->prepare($query);
|
||||
return $stmt->execute($args);
|
||||
}
|
||||
}
|
5
src/Venom/Core/Language.php
Normal file → Executable file
5
src/Venom/Core/Language.php
Normal file → Executable file
|
@ -5,7 +5,8 @@ namespace Venom\Core;
|
|||
|
||||
|
||||
use RuntimeException;
|
||||
use Venom\Models\DatabaseObject;
|
||||
use Venom\Core\Database\DatabaseHandler;
|
||||
use Venom\Entities\DatabaseObject;
|
||||
|
||||
class Language
|
||||
{
|
||||
|
@ -20,7 +21,7 @@ class Language
|
|||
|
||||
public function initLang()
|
||||
{
|
||||
$lang = ArgumentHandler::get()->getItem("lang", $this->defaultLang->shortTag);
|
||||
$lang = ArgumentHandler::get()->getItem("lang", $this->defaultLang->shortTag ?? 'de');
|
||||
//check if language exists
|
||||
$data = DatabaseHandler::get()->getOne("select id from language where shortTag = :shortTag", [
|
||||
':shortTag' => $lang
|
||||
|
|
15
src/Venom/Core/Module.php
Normal file → Executable file
15
src/Venom/Core/Module.php
Normal file → Executable file
|
@ -3,10 +3,17 @@
|
|||
|
||||
namespace Venom\Core;
|
||||
|
||||
|
||||
interface Module
|
||||
{
|
||||
public function register(): bool;
|
||||
|
||||
public function init(): void;
|
||||
const NAME = "name";
|
||||
const AUTHOR = "author";
|
||||
const SECURE = "secure";
|
||||
const ROUTE = "routes";
|
||||
const ADMIN_ROUTE = "adminRoutes";
|
||||
const DESC = "description";
|
||||
const TEMPLATES = "templates";
|
||||
const ADMIN_TEMPLATES = "adminTemplates";
|
||||
const CONTROLLER = "controllers";
|
||||
const TEMPLATE_PATH = "tplPath";
|
||||
const ACTIVE = "isActive";
|
||||
}
|
72
src/Venom/Core/ModuleLoader.php
Executable file
72
src/Venom/Core/ModuleLoader.php
Executable file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Core;
|
||||
|
||||
use RuntimeException;
|
||||
use Venom\Helper\TemplateUtil;
|
||||
use Venom\Routing\Route;
|
||||
use Venom\Routing\Router;
|
||||
use Venom\Venom;
|
||||
|
||||
class ModuleLoader
|
||||
{
|
||||
public static function getModules(): array
|
||||
{
|
||||
return [
|
||||
'Meta',
|
||||
'User',
|
||||
'Data',
|
||||
'Role',
|
||||
'SEO',
|
||||
'VenomStatus',
|
||||
];
|
||||
}
|
||||
|
||||
public static function loadModule(string $name, Venom $venom)
|
||||
{
|
||||
// load module search in the Module Path for a module.php file
|
||||
$dir = __DIR__ . "/../../modules/" . $name . "/module.php";
|
||||
if (!file_exists($dir)) {
|
||||
throw new RuntimeException("Module File: \"$dir\" Not found");
|
||||
}
|
||||
include_once $dir;
|
||||
}
|
||||
|
||||
public static function initModule(array $module, Venom $venom): bool
|
||||
{
|
||||
if (!$module[Module::ACTIVE]) {
|
||||
return false;
|
||||
}
|
||||
// register Router, Templates and more :)
|
||||
$isAdmin = Config::getInstance()->isAdmin();
|
||||
if ($isAdmin) {
|
||||
self::registerRoutes($module,
|
||||
$venom,
|
||||
$module[Module::ADMIN_ROUTE],
|
||||
$venom->getRouter(Router::ADMIN_ROUTER)
|
||||
);
|
||||
TemplateUtil::getInstance()->addTemplates($module[Module::ADMIN_TEMPLATES], $module[Module::TEMPLATE_PATH]);
|
||||
} else {
|
||||
self::registerRoutes($module,
|
||||
$venom,
|
||||
$module[Module::ROUTE],
|
||||
$venom->getRouter(Router::DEFAULT_ROUTER)
|
||||
);
|
||||
TemplateUtil::getInstance()->addTemplates($module[Module::TEMPLATES], $module[Module::TEMPLATE_PATH]);
|
||||
}
|
||||
$venom->addControllers($module[Module::CONTROLLER]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function registerRoutes(array $module, Venom $venom, array $routes, Router $router)
|
||||
{
|
||||
foreach ($routes as $key => $route) {
|
||||
/** @var Route $route */
|
||||
$route->module = $module[Module::NAME];
|
||||
$route->isSecure = $module[Module::SECURE];
|
||||
$route->venom = $venom;
|
||||
$router->addRoute($key, $route);
|
||||
}
|
||||
}
|
||||
}
|
2
src/Venom/Core/Registry.php
Normal file → Executable file
2
src/Venom/Core/Registry.php
Normal file → Executable file
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace Venom\Core;
|
||||
|
||||
use Venom\Routing\SeoController;
|
||||
use Venom\Controller\SeoController;
|
||||
|
||||
/**
|
||||
* Singleton Class... hold current URL => can
|
||||
|
|
3
src/Venom/Core/Setup.php
Normal file → Executable file
3
src/Venom/Core/Setup.php
Normal file → Executable file
|
@ -39,9 +39,6 @@ class Setup
|
|||
if (isset($modules)) {
|
||||
$venom->initModules($modules);
|
||||
}
|
||||
if (isset($controllers)) {
|
||||
$venom->initControllers($controllers);
|
||||
}
|
||||
}
|
||||
|
||||
public static function loadRouters(Venom $venom): void
|
||||
|
|
6
src/Venom/Models/ConfigObject.php → src/Venom/Entities/ConfigObject.php
Normal file → Executable file
6
src/Venom/Models/ConfigObject.php → src/Venom/Entities/ConfigObject.php
Normal file → Executable file
|
@ -1,10 +1,12 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Models;
|
||||
namespace Venom\Entities;
|
||||
|
||||
|
||||
class ConfigObject
|
||||
use Venom\Core\Database\Entity;
|
||||
|
||||
class ConfigObject extends Entity
|
||||
{
|
||||
private array $data = [];
|
||||
|
|
@ -1,31 +1,25 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Models;
|
||||
namespace Venom\Entities;
|
||||
|
||||
|
||||
class DataModel
|
||||
use Venom\Core\Database\Entity;
|
||||
|
||||
class DataEntity extends Entity
|
||||
{
|
||||
public const TYPE_CONTENT = 'content';
|
||||
public const TYPE_FORM = 'form';
|
||||
|
||||
public string $id;
|
||||
public string $raw;
|
||||
public string $generated;
|
||||
public string $type;
|
||||
public int $active = 1;
|
||||
|
||||
public function __construct(
|
||||
string $id,
|
||||
string $type = self::TYPE_CONTENT,
|
||||
string $raw = '',
|
||||
string $generated = ''
|
||||
public string $id,
|
||||
public string $type = self::TYPE_CONTENT,
|
||||
public string $raw = '',
|
||||
public string $generated = ''
|
||||
)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
$this->raw = $raw;
|
||||
$this->generated = $generated;
|
||||
}
|
||||
|
||||
public function getId(): string
|
16
src/Venom/Models/DatabaseObject.php → src/Venom/Entities/DatabaseObject.php
Normal file → Executable file
16
src/Venom/Models/DatabaseObject.php → src/Venom/Entities/DatabaseObject.php
Normal file → Executable file
|
@ -1,15 +1,16 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Models;
|
||||
namespace Venom\Entities;
|
||||
|
||||
use Venom\Core\Database\Entity;
|
||||
|
||||
/**
|
||||
* Database Object to use queries like this $obj->id, $obj->value
|
||||
* also the option to print it in csv format ; as delimiter
|
||||
* @package Venom\Database
|
||||
*/
|
||||
class DatabaseObject
|
||||
class DatabaseObject extends Entity
|
||||
{
|
||||
private array $data = [];
|
||||
|
||||
|
@ -26,19 +27,24 @@ class DatabaseObject
|
|||
$this->data[$name] = $value;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
public function __isset($name): bool
|
||||
{
|
||||
return isset($this->data[$name]);
|
||||
}
|
||||
|
||||
public function toString()
|
||||
public function toString(): string
|
||||
{
|
||||
return implode(';', $this->data);
|
||||
}
|
||||
|
||||
public function getHead()
|
||||
public function getHead(): string
|
||||
{
|
||||
$keys = array_keys($this->data);
|
||||
return implode(';', $keys);
|
||||
}
|
||||
|
||||
public function getData(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
59
src/Venom/Entities/RoleEntity.php
Executable file
59
src/Venom/Entities/RoleEntity.php
Executable file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Entities;
|
||||
|
||||
use Venom\Core\Database\EasyQuery;
|
||||
use Venom\Core\Database\Entity;
|
||||
|
||||
class RoleEntity extends Entity
|
||||
{
|
||||
public static string $tableName = "roles";
|
||||
public string $name = "";
|
||||
public string $content = "";
|
||||
public bool $isActive = true;
|
||||
private array $roles = [];
|
||||
|
||||
public const TYPE_WRITE = 1;
|
||||
public const TYPE_READ = 0;
|
||||
public const TYPE_NO = -1;
|
||||
|
||||
|
||||
public function hasPermission(string $module, int $type): bool
|
||||
{
|
||||
if ($this->id === -1) {
|
||||
return true;
|
||||
}
|
||||
if ($type === self::TYPE_NO) {
|
||||
return true;
|
||||
}
|
||||
if (!isset($this->roles[$module]) && $type) {
|
||||
return false;
|
||||
}
|
||||
$mod = $this->roles[$module];
|
||||
return $mod["type"] === $type;
|
||||
}
|
||||
|
||||
|
||||
public function postLoad()
|
||||
{
|
||||
if (!empty($this->content)) {
|
||||
$this->roles = json_decode($this->content);
|
||||
}
|
||||
}
|
||||
|
||||
public function preSave()
|
||||
{
|
||||
$this->content = json_encode($this->roles);
|
||||
}
|
||||
|
||||
public function load($fields = ['*'], ?EasyQuery $query = null): static
|
||||
{
|
||||
if ($this->id === -1 || $this->id === 0) {
|
||||
return $this;
|
||||
}
|
||||
return parent::load($fields, $query);
|
||||
}
|
||||
|
||||
|
||||
}
|
57
src/Venom/Entities/User.php
Executable file
57
src/Venom/Entities/User.php
Executable file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Entities;
|
||||
|
||||
|
||||
use Venom\Core\Database\EasyQuery;
|
||||
use Venom\Core\Database\Entity;
|
||||
|
||||
class User extends Entity
|
||||
{
|
||||
public const ADMIN_ROLE = '-1';
|
||||
public const GUEST_ROLE = '0';
|
||||
|
||||
public static string $tableName = "users";
|
||||
public string $username = "GUEST";
|
||||
public string $firstname = "";
|
||||
public string $lastname = "";
|
||||
public string $email = "";
|
||||
public string $password = "";
|
||||
public string $token = "";
|
||||
public string $salt = "";
|
||||
public int $roleId = 0;
|
||||
public bool $isActive = true;
|
||||
private ?RoleEntity $roleEntity = null;
|
||||
private bool $loaded = false;
|
||||
|
||||
public function hasPermission(string $module, $type = RoleEntity::TYPE_WRITE): bool
|
||||
{
|
||||
if ($this->roleEntity === null) {
|
||||
$this->roleEntity = new RoleEntity();
|
||||
$this->roleEntity->id = $this->roleId;
|
||||
$this->roleEntity->load();
|
||||
}
|
||||
return $this->roleEntity->hasPermission($module, $type);
|
||||
}
|
||||
|
||||
public function postLoad()
|
||||
{
|
||||
$this->loaded = true;
|
||||
}
|
||||
|
||||
|
||||
public function isLoaded(): bool
|
||||
{
|
||||
return $this->loaded;
|
||||
}
|
||||
|
||||
public function loadUser()
|
||||
{
|
||||
$eq = new EasyQuery(User::$tableName, ["*"]);
|
||||
$eq->where("username", $this->username)
|
||||
->where("id", $this->id, EasyQuery::WHERE_OR);
|
||||
$this->load([], $eq);
|
||||
return true;
|
||||
}
|
||||
}
|
0
src/Venom/Exceptions/ExceptionHandler.php
Normal file → Executable file
0
src/Venom/Exceptions/ExceptionHandler.php
Normal file → Executable file
37
src/Venom/Helper/AdminHelper.php
Executable file
37
src/Venom/Helper/AdminHelper.php
Executable file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Helper;
|
||||
|
||||
|
||||
class AdminHelper
|
||||
{
|
||||
public static function sendResponse($content, string $component = '', bool $shouldReload = false, $extra = false)
|
||||
{
|
||||
$response = [
|
||||
'content' => $content,
|
||||
'component' => $component
|
||||
];
|
||||
|
||||
if ($shouldReload) {
|
||||
$response['reload'] = true;
|
||||
}
|
||||
if ($extra) {
|
||||
$response['extra'] = $extra;
|
||||
}
|
||||
echo json_encode($response);
|
||||
die();
|
||||
}
|
||||
|
||||
public static function sendStatus(bool $isSuccess, string $message = "")
|
||||
{
|
||||
if ($message == "") {
|
||||
$message = $isSuccess ? "Operation Success" : "Operation failed";
|
||||
}
|
||||
echo json_encode([
|
||||
"status" => $isSuccess ? 'success' : 'failed',
|
||||
"message" => $message
|
||||
]);
|
||||
die();
|
||||
}
|
||||
}
|
29
src/Venom/Helper/MetaGenerator.php
Normal file → Executable file
29
src/Venom/Helper/MetaGenerator.php
Normal file → Executable file
|
@ -4,11 +4,40 @@
|
|||
namespace Venom\Helper;
|
||||
|
||||
|
||||
use Venom\Core\ArgumentHandler;
|
||||
use Venom\Core\DatabaseHandler;
|
||||
|
||||
/**
|
||||
* Class MetaGenerator
|
||||
* @package Venom\Helper
|
||||
*/
|
||||
class MetaGenerator
|
||||
{
|
||||
private array $container = [];
|
||||
private string $id;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->id = (string)ArgumentHandler::get()->getItem('metaId', '-1');
|
||||
}
|
||||
|
||||
public function loadById(): void
|
||||
{
|
||||
if ($this->id === '-1') {
|
||||
return;
|
||||
}
|
||||
$db = DatabaseHandler::get();
|
||||
$data = $db->getOne('select content from metaTagData where id = :id', [':id' => $this->id]);
|
||||
if ($data !== null) {
|
||||
$this->container = json_decode($data->content ?? '', true);
|
||||
$this->container = array_merge([], $this->container);
|
||||
}
|
||||
}
|
||||
|
||||
public function render(): void
|
||||
{
|
||||
foreach ($this->container as $key => $value) {
|
||||
echo '<meta name="' . $key . '" content="' . $value . '">';
|
||||
}
|
||||
}
|
||||
}
|
75
src/Venom/Helper/TemplateUtil.php
Executable file
75
src/Venom/Helper/TemplateUtil.php
Executable file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Helper;
|
||||
|
||||
|
||||
use Venom\Core\Config;
|
||||
|
||||
class TemplateUtil
|
||||
{
|
||||
private static ?TemplateUtil $instance = null;
|
||||
private string $baseTemplate;
|
||||
private string $templateDir;
|
||||
private array $templates = [];
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
if (Config::getInstance()->isAdmin()) {
|
||||
$base = 'base';
|
||||
$theme = 'admin';
|
||||
} else {
|
||||
$data = Config::getInstance()->getRenderer();
|
||||
$theme = $data->theme;
|
||||
$base = $data->baseFile ?? 'base';
|
||||
}
|
||||
$this->baseTemplate = $base . '.php';
|
||||
$this->templateDir = __DIR__ . '/../../../tpl/' . $theme . '/';
|
||||
}
|
||||
|
||||
public static function getInstance(): TemplateUtil
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new TemplateUtil();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function getDir(): string
|
||||
{
|
||||
return $this->templateDir;
|
||||
}
|
||||
|
||||
public function getBase(): string
|
||||
{
|
||||
return $this->baseTemplate;
|
||||
}
|
||||
|
||||
public function addTemplates($templates, string $basePath)
|
||||
{
|
||||
foreach ($templates as $key => $template) {
|
||||
$this->templates[$key] = $basePath . $template;
|
||||
}
|
||||
}
|
||||
|
||||
public static function includeTemplate($template, $suffix = '.php'): bool|string
|
||||
{
|
||||
$tx = self::getInstance()->getCache($template);
|
||||
if ($tx === "") {
|
||||
$dir = self::getInstance()->getDir();
|
||||
$tx = $dir . $template;
|
||||
}
|
||||
$tx .= $suffix;
|
||||
if (file_exists($tx)) {
|
||||
ob_start();
|
||||
include_once $tx;
|
||||
return ob_get_clean();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
private function getCache($template)
|
||||
{
|
||||
return $this->templates[$template] ?? '';
|
||||
}
|
||||
}
|
5
src/Venom/Helper/URLHelper.php
Normal file → Executable file
5
src/Venom/Helper/URLHelper.php
Normal file → Executable file
|
@ -42,4 +42,9 @@ class URLHelper
|
|||
{
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function isAdminUrl(): bool
|
||||
{
|
||||
return strpos($this->parsedUrl, '/admin') === 0;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Venom\Models;
|
||||
|
||||
|
||||
class User
|
||||
{
|
||||
private string $username;
|
||||
private string $password;
|
||||
private string $salt;
|
||||
private string $token;
|
||||
private array $roles;
|
||||
}
|
44
src/Venom/Routing/Route.php
Normal file → Executable file
44
src/Venom/Routing/Route.php
Normal file → Executable file
|
@ -4,7 +4,47 @@
|
|||
namespace Venom\Routing;
|
||||
|
||||
|
||||
interface Route
|
||||
{
|
||||
use RuntimeException;
|
||||
use Venom\Entities\RoleEntity;
|
||||
use Venom\Security\Security;
|
||||
use Venom\Venom;
|
||||
|
||||
class Route
|
||||
{
|
||||
const GET = "GET";
|
||||
const POST = "POST";
|
||||
const PUT = "PUT";
|
||||
const DELETE = "DELETE";
|
||||
|
||||
public string $url;
|
||||
public array $routes = [];
|
||||
public int $maxParameters = 0;
|
||||
public string $module = "unknown";
|
||||
public bool $isSecure = false;
|
||||
public Venom $venom;
|
||||
|
||||
public function __construct(public string $controller, array $config)
|
||||
{
|
||||
$count = count($config);
|
||||
if ($count === 0) {
|
||||
throw new RuntimeException("Route: \"$controller\" no valid Routes Found!");
|
||||
}
|
||||
$count -= isset($config["*"]) ? 1 : 0;
|
||||
$this->maxParameters = $count;
|
||||
$this->routes = $config;
|
||||
}
|
||||
|
||||
public function getDefinitions($method, mixed $subRoute): ?array
|
||||
{
|
||||
if ($this->isSecure && !Security::get()->hasPermission($this->module, $method === Route::GET ? RoleEntity::TYPE_READ : RoleEntity::TYPE_WRITE)) {
|
||||
return null;
|
||||
}
|
||||
if (isset($this->routes[$subRoute]) && isset($this->routes[$subRoute][$method])) {
|
||||
return [
|
||||
"cl" => $this->controller,
|
||||
"fnc" => $this->routes[$subRoute][$method]
|
||||
];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
48
src/Venom/Routing/Router.php
Normal file → Executable file
48
src/Venom/Routing/Router.php
Normal file → Executable file
|
@ -5,9 +5,12 @@ namespace Venom\Routing;
|
|||
|
||||
|
||||
use Exception;
|
||||
use Venom\Exceptions\ExceptionHandler;
|
||||
|
||||
class Router
|
||||
{
|
||||
public const DEFAULT_ROUTER = 'defaultRouter';
|
||||
public const ADMIN_ROUTER = 'adminRouter';
|
||||
protected string $id = 'defaultRouter';
|
||||
protected int $version;
|
||||
protected string $prefix = '';
|
||||
|
@ -22,10 +25,10 @@ class Router
|
|||
|
||||
public function addRoutes(array $routes): void
|
||||
{
|
||||
$this->routes = $routes;
|
||||
$this->routes = array_merge($this->routes, $routes);
|
||||
}
|
||||
|
||||
public function addRoute(string $path, array $route): void
|
||||
public function addRoute(string $path, Route $route): void
|
||||
{
|
||||
$this->routes[$path] = $route;
|
||||
}
|
||||
|
@ -36,6 +39,7 @@ class Router
|
|||
public function findRoute($url, $method): ?array
|
||||
{
|
||||
$url = $this->removeIfFirst($url, $this->prefix);
|
||||
$url = $this->removeTrailingSlash($url);
|
||||
// check if full match... this can easily done if the url isset select the empty!
|
||||
$method = strtoupper($method);
|
||||
$route = $this->getRouteByName($url, $method);
|
||||
|
@ -51,26 +55,25 @@ class Router
|
|||
return null;
|
||||
}
|
||||
|
||||
private function removeIfFirst($rawString, $string)
|
||||
private function removeIfFirst($rawString, $string): bool|string
|
||||
{
|
||||
if ($string !== '' && 0 === strpos($rawString, $string)) {
|
||||
if ($string !== '' && str_starts_with($rawString, $string)) {
|
||||
return substr($rawString, strlen($string));
|
||||
}
|
||||
return $rawString;
|
||||
}
|
||||
|
||||
/* @todo implement Security Check if SecurityModule is used */
|
||||
private function getRouteByName($url, $method, $subRoute = '*', $params = []): ?array
|
||||
{
|
||||
$routeAvailable = isset($this->routes[$url]);
|
||||
$subRouteFound = isset($this->routes[$url]['routes'][$subRoute]);
|
||||
$methodFound = isset($this->routes[$url]['routes'][$subRoute][$method]);
|
||||
if ($routeAvailable && $subRouteFound && $methodFound) {
|
||||
return [
|
||||
'cl' => $this->routes[$url]['cl'],
|
||||
'fnc' => $this->routes[$url]['routes'][$subRoute][$method],
|
||||
'params' => $params
|
||||
];
|
||||
if (isset($this->routes[$url])) {
|
||||
/** @var Route $route */
|
||||
$route = $this->routes[$url];
|
||||
$sub = $route->getDefinitions($method, $subRoute);
|
||||
if ($sub === null) {
|
||||
return null;
|
||||
}
|
||||
$sub["params"] = array_reverse($params);
|
||||
return $sub;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -95,17 +98,32 @@ class Router
|
|||
|
||||
public function tryFunctionCall(?array $aRoute): bool
|
||||
{
|
||||
if ($aRoute === null || !is_callable(array($aRoute['cl'], $aRoute['fnc']))) {
|
||||
if ($aRoute === null || empty($aRoute['cl']) || empty($aRoute['fnc']) || !class_exists($aRoute['cl'])) {
|
||||
return false;
|
||||
}
|
||||
$route = new $aRoute['cl']();
|
||||
if (!is_callable(array($route, $aRoute['fnc']))) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$fnc = $aRoute['fnc'];
|
||||
$params = $aRoute['params'] ?? [];
|
||||
$route->$fnc(...$params);
|
||||
return true;
|
||||
} catch (Exception $ex) {
|
||||
ExceptionHandler::handleException($ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function removeTrailingSlash(string $rawString): bool|string
|
||||
{
|
||||
$len = strlen($rawString);
|
||||
return $rawString[$len - 1] === '/' ? substr($rawString, 0, strlen($rawString) - 1) : $rawString;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
46
src/Venom/Security/BaseLogin.php
Normal file → Executable file
46
src/Venom/Security/BaseLogin.php
Normal file → Executable file
|
@ -4,10 +4,54 @@
|
|||
namespace Venom\Security;
|
||||
|
||||
|
||||
use Venom\Core\ArgumentHandler;
|
||||
use Venom\Core\Config;
|
||||
use Venom\Entities\User;
|
||||
use Venom\Helper\URLHelper;
|
||||
|
||||
/**
|
||||
* Class that Login stupid via Password, Username
|
||||
*/
|
||||
class BaseLogin
|
||||
class BaseLogin implements Login
|
||||
{
|
||||
|
||||
private User $user;
|
||||
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function checkCredentials(): bool
|
||||
{
|
||||
$handler = ArgumentHandler::get();
|
||||
return $handler->hasPostItem('USERNAME') && $handler->hasPostItem('PASSWORD');
|
||||
}
|
||||
|
||||
public function redirect(): void
|
||||
{
|
||||
$url = ArgumentHandler::get()->getPostItem('REDIRECT_TO', URLHelper::getInstance()->getUrl());
|
||||
if ($url === 'NO') {
|
||||
echo json_encode(['message' => 'login'], JSON_THROW_ON_ERROR);
|
||||
} else {
|
||||
header('Location: ' . $url);
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
public function login(): bool
|
||||
{
|
||||
$sec = Config::getInstance()->getSecurity();
|
||||
$this->user->username = (string)ArgumentHandler::get()->getPostItem('USERNAME');
|
||||
if (!$this->user->loadUser()) {
|
||||
return false;
|
||||
}
|
||||
$secret = $sec->secret ?? 'venom';
|
||||
$hashed = hash($sec->algo ?? 'SHA256', ArgumentHandler::get()->getPostItem('PASSWORD') . $secret . $this->user->salt);
|
||||
if ($this->user->password === $hashed) {
|
||||
$_SESSION['userID'] = $this->user->id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
6
src/Venom/Security/Login.php
Normal file → Executable file
6
src/Venom/Security/Login.php
Normal file → Executable file
|
@ -4,16 +4,12 @@
|
|||
namespace Venom\Security;
|
||||
|
||||
|
||||
use Venom\Models\User;
|
||||
use Venom\Entities\User;
|
||||
|
||||
interface Login
|
||||
{
|
||||
public function __construct(User $user);
|
||||
|
||||
public function checkUsername(): bool;
|
||||
|
||||
public function checkPassword(): bool;
|
||||
|
||||
public function checkCredentials(): bool;
|
||||
|
||||
public function login(): bool;
|
||||
|
|
38
src/Venom/Security/Security.php
Normal file → Executable file
38
src/Venom/Security/Security.php
Normal file → Executable file
|
@ -3,10 +3,22 @@
|
|||
|
||||
namespace Venom\Security;
|
||||
|
||||
use RuntimeException;
|
||||
use Venom\Core\Config;
|
||||
use Venom\Entities\RoleEntity;
|
||||
use Venom\Entities\User;
|
||||
|
||||
class Security
|
||||
{
|
||||
private static ?Security $instance = null;
|
||||
private ?User $user;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->user = new User();
|
||||
$this->user->id = $_SESSION['userID'] ?? "-1";
|
||||
$this->user->load();
|
||||
}
|
||||
|
||||
public static function get(): Security
|
||||
{
|
||||
|
@ -16,15 +28,29 @@ class Security
|
|||
return self::$instance;
|
||||
}
|
||||
|
||||
/* @todo implement logic */
|
||||
public function hasRole(string $role): bool
|
||||
public function hasPermission(string $module, $type = RoleEntity::TYPE_WRITE): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user->hasPermission($module, $type);
|
||||
}
|
||||
|
||||
/* @todo implement logic */
|
||||
public function hasRoles(array $roles): bool
|
||||
public function login(): void
|
||||
{
|
||||
return true;
|
||||
if ($this->user->isLoaded()) {
|
||||
throw new RuntimeException('Try to re-login!');
|
||||
}
|
||||
$sec = Config::getInstance()->getSecurity();
|
||||
$login = new $sec->securityClass($this->user);
|
||||
if ($login instanceof Login) {
|
||||
if (!$login->checkCredentials() || !$login->login()) {
|
||||
http_response_code(401);
|
||||
}
|
||||
$login->redirect();
|
||||
}
|
||||
}
|
||||
|
||||
public function logout(): void
|
||||
{
|
||||
unset($_SESSION['userID']);
|
||||
$this->user = new User();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
namespace Venom;
|
||||
|
||||
|
||||
use Venom\Admin\AdminController;
|
||||
use Venom\Admin\AdminRouterInit;
|
||||
use Venom\Core\ArgumentHandler;
|
||||
use Venom\Core\Config;
|
||||
use Venom\Core\Module;
|
||||
use Venom\Core\ModuleLoader;
|
||||
use Venom\Core\Registry;
|
||||
use Venom\Exceptions\ExceptionHandler;
|
||||
use Venom\Helper\ErrorHandler;
|
||||
|
@ -27,16 +30,26 @@ class Venom
|
|||
{
|
||||
ExceptionHandler::setExceptionHandler();
|
||||
$this->renderer = new VenomRenderer($this);
|
||||
$this->routers[Router::ADMIN_ROUTER] = new Router(Router::ADMIN_ROUTER, 1.0, '/admin/api');
|
||||
Asset::get()->setRenderer($this->renderer);
|
||||
}
|
||||
|
||||
public function inject(): void
|
||||
{
|
||||
$this->run();
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$arguments = ArgumentHandler::get();
|
||||
$arguments->setItem(ErrorHandler::ERROR_KEY, false);
|
||||
$config = Config::getInstance();
|
||||
if ($config->isAdmin()) {
|
||||
$this->initAdmin();
|
||||
}
|
||||
// we need to load the current controller and the current start template.
|
||||
// after this we can start the renderer
|
||||
if (Config::getInstance()->isRouterEnabled()) {
|
||||
if ($config->isRouterEnabled() || $config->isAdmin()) {
|
||||
$status = $this->useRouter();
|
||||
if ($status['found']) {
|
||||
if ($status['status']) {
|
||||
|
@ -48,18 +61,32 @@ class Venom
|
|||
$registry = Registry::getInstance();
|
||||
$registry->getLang()->initLang();
|
||||
// if site is errored then dont load via SEO
|
||||
if (!$arguments->getItem(ErrorHandler::ERROR_KEY)) {
|
||||
if (!$config->isAdmin() && !$arguments->getItem(ErrorHandler::ERROR_KEY)) {
|
||||
$registry->getSeo()->loadSite();
|
||||
}
|
||||
$this->renderer->init($this->findController());
|
||||
$this->renderer->render();
|
||||
}
|
||||
|
||||
public function initAdmin(): void
|
||||
{
|
||||
$this->controllers['adminCtrl'] = AdminController::class;
|
||||
AdminRouterInit::registerAdminRouters($this);
|
||||
ArgumentHandler::get()->setItem('cl', 'adminCtrl');
|
||||
}
|
||||
|
||||
private function useRouter(): array
|
||||
{
|
||||
$url = URLHelper::getInstance()->getUrl();
|
||||
$isAdmin = Config::getInstance()->isAdmin();
|
||||
/** @var Router $router */
|
||||
foreach ($this->routers as $router) {
|
||||
foreach ($this->routers as $key => $router) {
|
||||
if ($isAdmin && $key !== Router::ADMIN_ROUTER) {
|
||||
continue;
|
||||
}
|
||||
if (!$isAdmin && $key === Router::ADMIN_ROUTER) {
|
||||
continue;
|
||||
}
|
||||
$route = $router->findRoute($url, $_SERVER['REQUEST_METHOD']);
|
||||
$status = $router->tryFunctionCall($route);
|
||||
if ($route !== null) {
|
||||
|
@ -89,21 +116,33 @@ class Venom
|
|||
|
||||
public function initModules(array $modules): void
|
||||
{
|
||||
foreach ($modules as $key => $moduleClass) {
|
||||
$module = new $moduleClass;
|
||||
if ($module instanceof Module && $module->register()) {
|
||||
$this->modules[$key] = $module;
|
||||
}
|
||||
if (Config::getInstance()->isAdmin()) {
|
||||
$modules = array_merge(ModuleLoader::getModules(), $modules);
|
||||
}
|
||||
foreach ($modules as $module) {
|
||||
ModuleLoader::loadModule($module, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function initControllers(array $controllers): void
|
||||
public function addControllers(array $controllers): void
|
||||
{
|
||||
$this->controllers = $controllers;
|
||||
$this->controllers = array_merge($this->controllers, $controllers);
|
||||
}
|
||||
|
||||
public function addRouter(string $name, Router $router): void
|
||||
public function addRouter(Router $router): void
|
||||
{
|
||||
$this->routers[$name] = $router;
|
||||
$this->routers[$router->getId()] = $router;
|
||||
}
|
||||
|
||||
public function getRouter(string $router): ?Router
|
||||
{
|
||||
return $this->routers[$router];
|
||||
}
|
||||
|
||||
public function registerModule(array $module)
|
||||
{
|
||||
if (ModuleLoader::initModule($module, $this)) {
|
||||
$this->modules[$module[Module::NAME]] = $module;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,7 +62,7 @@ class Asset
|
|||
usort($this->jsFiles, function ($a, $b) {
|
||||
return $a['pos'] <=> $b['pos'];
|
||||
});
|
||||
$theme = $this->getPath('/theme/' . Config::getInstance()->getRenderer()->assetDir . '/js/');
|
||||
$theme = $this->getPath('/js/');
|
||||
foreach ($this->jsFiles as $key => $file) {
|
||||
echo '<script src="' . $theme . $file['file'] . '" id="js-' . $key . '"></script>';
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ class Asset
|
|||
|
||||
private function getPath($base): string
|
||||
{
|
||||
$preDir = $base;
|
||||
$dir = Config::getInstance()->isAdmin() ? 'admin' : Config::getInstance()->getRenderer()->assetDir;
|
||||
$preDir = '/theme/' . $dir . $base;
|
||||
$config = Config::getInstance();
|
||||
$baseUrl = Config::getInstance()->getBaseUrl();
|
||||
if ($baseUrl !== '' && $config->getRenderer()->useStaticUrl) {
|
||||
|
@ -84,7 +85,7 @@ class Asset
|
|||
usort($this->cssFiles, function ($a, $b) {
|
||||
return $a['pos'] <=> $b['pos'];
|
||||
});
|
||||
$theme = $this->getPath('/theme/' . Config::getInstance()->getRenderer()->assetDir . '/css/');
|
||||
$theme = $this->getPath('/css/');
|
||||
foreach ($this->cssFiles as $key => $file) {
|
||||
echo '<link rel="stylesheet" href="' . $theme . $file['file'] . '" id="css-' . $key . '">';
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Venom\Views;
|
|||
|
||||
use RuntimeException;
|
||||
use Venom\Core\DatabaseHandler;
|
||||
use Venom\Models\DataModel;
|
||||
use Venom\Entities\DataEntity;
|
||||
|
||||
class DataLoader
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ class DataLoader
|
|||
return self::$instance;
|
||||
}
|
||||
|
||||
public static function loadById(string $id): ?DataModel
|
||||
public static function loadById(string $id): ?DataEntity
|
||||
{
|
||||
if ($id === '') {
|
||||
throw new RuntimeException('Try to Load empty ID from Database');
|
||||
|
@ -33,14 +33,14 @@ class DataLoader
|
|||
]);
|
||||
|
||||
if ($data !== null) {
|
||||
$model = new DataModel($data->identity, $data->datatype, $data->raw, $data->generated);
|
||||
$model = new DataEntity($data->identity, $data->datatype, $data->raw, $data->generated);
|
||||
$model->setActive(true);
|
||||
return $model;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function updateData(DataModel $model): bool
|
||||
public function updateData(DataEntity $model): bool
|
||||
{
|
||||
if ($model->getId() === '') {
|
||||
return $this->insertData($model);
|
||||
|
@ -57,7 +57,7 @@ class DataLoader
|
|||
);
|
||||
}
|
||||
|
||||
public function insertData(DataModel $model): bool
|
||||
public function insertData(DataEntity $model): bool
|
||||
{
|
||||
|
||||
$this->validateModel($model);
|
||||
|
@ -73,7 +73,7 @@ class DataLoader
|
|||
);
|
||||
}
|
||||
|
||||
private function validateModel(DataModel $model): void
|
||||
private function validateModel(DataEntity $model): void
|
||||
{
|
||||
if ($model->getId() === '') {
|
||||
$model->setId($this->generateID());
|
||||
|
@ -87,8 +87,8 @@ class DataLoader
|
|||
private function generateID(string $id = ''): string
|
||||
{
|
||||
if ($id === '') {
|
||||
$id = bin2hex(random_bytes(16));
|
||||
$id = bin2hex(random_bytes(32));
|
||||
}
|
||||
return $id;
|
||||
return hash('SHA256', $id);
|
||||
}
|
||||
}
|
0
src/Venom/Views/RenderController.php
Normal file → Executable file
0
src/Venom/Views/RenderController.php
Normal file → Executable file
|
@ -6,14 +6,17 @@ namespace Venom\Views;
|
|||
|
||||
use Venom\Core\ArgumentHandler;
|
||||
use Venom\Core\Config;
|
||||
use Venom\Helper\MetaGenerator;
|
||||
use Venom\Helper\TemplateUtil;
|
||||
use Venom\Venom;
|
||||
|
||||
class VenomRenderer
|
||||
{
|
||||
private Venom $venom;
|
||||
private ?RenderController $controller;
|
||||
private ?MetaGenerator $metaGenerator;
|
||||
private string $templateData = '';
|
||||
private array $vars = [];
|
||||
private array $vars = [];
|
||||
private string $baseTemplate = '';
|
||||
private string $templateDir = '';
|
||||
|
||||
|
@ -50,8 +53,7 @@ class VenomRenderer
|
|||
public function renderTemplate($template): void
|
||||
{
|
||||
// random variable name... to remove it instantly
|
||||
echo $this->includeTemplate($template, '1408138186');
|
||||
unset($this->vars['1408138186']);
|
||||
echo TemplateUtil::includeTemplate($template);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,16 +64,9 @@ class VenomRenderer
|
|||
*/
|
||||
public function includeTemplate($template, $varName = '')
|
||||
{
|
||||
$template .= '.php';
|
||||
if (file_exists($this->templateDir . $template)) {
|
||||
ob_start();
|
||||
include_once $this->templateDir . $template;
|
||||
$data = ob_get_clean();
|
||||
$this->vars[$varName] = $data;
|
||||
return $data;
|
||||
}
|
||||
$this->vars[$varName] = '';
|
||||
return '';
|
||||
$data = TemplateUtil::includeTemplate($template);
|
||||
$this->vars[$varName] = $data;
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function addVar($name, $value): void
|
||||
|
@ -84,7 +79,7 @@ class VenomRenderer
|
|||
return $this->vars[$name];
|
||||
}
|
||||
|
||||
public function deleteVar($name)
|
||||
public function deleteVar($name): void
|
||||
{
|
||||
unset($this->vars[$name]);
|
||||
}
|
||||
|
@ -92,8 +87,12 @@ class VenomRenderer
|
|||
public function init(?RenderController $controller): void
|
||||
{
|
||||
$this->controller = $controller;
|
||||
$data = Config::getInstance()->getRenderer();
|
||||
$this->baseTemplate = $data->baseFile . '.php' ?? 'base.php';
|
||||
$this->templateDir = __DIR__ . '/../../../tpl/' . $data->theme . '/';
|
||||
if (!Config::getInstance()->isAdmin()) {
|
||||
$this->metaGenerator = new MetaGenerator();
|
||||
$this->metaGenerator->loadById();
|
||||
}
|
||||
$util = TemplateUtil::getInstance();
|
||||
$this->templateDir = $util->getDir();
|
||||
$this->baseTemplate = $util->getBase();
|
||||
}
|
||||
}
|
||||
|
|
0
src/modules/.gitkeep
Normal file → Executable file
0
src/modules/.gitkeep
Normal file → Executable file
13
src/modules/Data/Controller/DataController.php
Normal file
13
src/modules/Data/Controller/DataController.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Modules\Data\Controller;
|
||||
|
||||
|
||||
class DataController
|
||||
{
|
||||
public function get()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
34
src/modules/Data/module.php
Executable file
34
src/modules/Data/module.php
Executable file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Modules\Data\Controller\DataController;
|
||||
use Venom\Core\Module;
|
||||
use Venom\Routing\Route;
|
||||
|
||||
|
||||
$venom = $venom ?? die();
|
||||
$venom->registerModule([
|
||||
Module::ACTIVE => true,
|
||||
Module::NAME => 'DataModule',
|
||||
Module::DESC => 'Data Module for Content every',
|
||||
Module::AUTHOR => 'VstZ dev',
|
||||
// NEED TO CHECK RIGHTS? :D IF FALSE WRITE IS ALWAYS ALLOWED ALSO READ!
|
||||
Module::SECURE => true,
|
||||
Module::ROUTE => [],
|
||||
Module::ADMIN_ROUTE => [
|
||||
'/data' => new Route(DataController::class, [
|
||||
"*" => [
|
||||
Route::GET => 'get'
|
||||
]
|
||||
])
|
||||
],
|
||||
Module::TEMPLATE_PATH => __DIR__ . "/tpl/",
|
||||
Module::TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::ADMIN_TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::CONTROLLER => [
|
||||
|
||||
]
|
||||
]);
|
36
src/modules/Meta/Controller/MetaAPIController.php
Executable file
36
src/modules/Meta/Controller/MetaAPIController.php
Executable file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Modules\Meta\Controller;
|
||||
|
||||
|
||||
use Venom\Core\DatabaseHandler;
|
||||
use Venom\Helper\AdminHelper;
|
||||
|
||||
class MetaAPIController
|
||||
{
|
||||
public function get()
|
||||
{
|
||||
AdminHelper::sendResponse([]);
|
||||
}
|
||||
|
||||
public function getById($id)
|
||||
{
|
||||
AdminHelper::sendResponse(SeoUrlController::getById($id));
|
||||
}
|
||||
|
||||
public function update($id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function create($id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
18
src/modules/Meta/Controller/MetaController.php
Executable file
18
src/modules/Meta/Controller/MetaController.php
Executable file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Modules\Meta\Controller;
|
||||
|
||||
|
||||
class MetaController
|
||||
{
|
||||
public static function get(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function getById($id): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
41
src/modules/Meta/module.php
Executable file
41
src/modules/Meta/module.php
Executable file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
use Modules\Meta\Controller\MetaAPIController;
|
||||
use Venom\Core\Module;
|
||||
use Venom\Routing\Route;
|
||||
|
||||
|
||||
$venom = $venom ?? die();
|
||||
$venom->registerModule([
|
||||
Module::ACTIVE => true,
|
||||
Module::NAME => 'MetaModule',
|
||||
Module::DESC => 'Meta Data Module for SEO',
|
||||
Module::AUTHOR => 'VstZ dev',
|
||||
// NEED TO CHECK RIGHTS? :D IF FALSE WRITE IS ALWAYS ALLOWED ALSO READ!
|
||||
Module::SECURE => true,
|
||||
Module::ROUTE => [],
|
||||
Module::ADMIN_ROUTE => [
|
||||
'/metaData' => new Route(MetaAPIController::class, [
|
||||
"*" => [
|
||||
Route::GET => 'get'
|
||||
],
|
||||
"1" => [
|
||||
Route::GET => 'getById',
|
||||
Route::POST => 'update',
|
||||
Route::PUT => 'insert',
|
||||
Route::DELETE => 'delete'
|
||||
]
|
||||
])
|
||||
],
|
||||
Module::TEMPLATE_PATH => __DIR__ . "/tpl/",
|
||||
Module::TEMPLATES => [
|
||||
// Include Templates with shorter names! $render->include("meta_roles")
|
||||
//'meta_roles' => 'PATH_TO_TEMPLATE_FROM_TEMPLATE_PATH'
|
||||
],
|
||||
Module::ADMIN_TEMPLATES => [
|
||||
//
|
||||
],
|
||||
Module::CONTROLLER => [
|
||||
|
||||
]
|
||||
]);
|
21
src/modules/Role/Controller/RoleController.php
Normal file
21
src/modules/Role/Controller/RoleController.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Modules\Role\Controller;
|
||||
|
||||
|
||||
use Venom\Helper\AdminHelper;
|
||||
|
||||
class RoleController
|
||||
{
|
||||
public function get()
|
||||
{
|
||||
AdminHelper::sendResponse([
|
||||
'roles' => [
|
||||
['id' => 1, 'name' => 'Admin', 'icon' => 'vt-visibility'],
|
||||
['id' => 2, 'name' => 'Moderator', 'icon' => 'vt-edit'],
|
||||
['id' => 3, 'name' => 'Gast', 'icon' => 'vt-edit'],
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
34
src/modules/Role/module.php
Executable file
34
src/modules/Role/module.php
Executable file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Modules\Role\Controller\RoleController;
|
||||
use Venom\Core\Module;
|
||||
use Venom\Routing\Route;
|
||||
|
||||
|
||||
$venom = $venom ?? die();
|
||||
$venom->registerModule([
|
||||
Module::ACTIVE => true,
|
||||
Module::NAME => 'RoleModule',
|
||||
Module::DESC => 'Role Management',
|
||||
Module::AUTHOR => 'VstZ dev',
|
||||
// NEED TO CHECK RIGHTS? :D IF FALSE WRITE IS ALWAYS ALLOWED ALSO READ!
|
||||
Module::SECURE => true,
|
||||
Module::ROUTE => [],
|
||||
Module::ADMIN_ROUTE => [
|
||||
'/roles' => new Route(RoleController::class, [
|
||||
"*" => [
|
||||
Route::GET => 'get'
|
||||
]
|
||||
])
|
||||
],
|
||||
Module::TEMPLATE_PATH => __DIR__ . "/tpl/",
|
||||
Module::TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::ADMIN_TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::CONTROLLER => [
|
||||
|
||||
]
|
||||
]);
|
18
src/modules/SEO/Controller/SeoUrlController.php
Executable file
18
src/modules/SEO/Controller/SeoUrlController.php
Executable file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Modules\SEO\Controller;
|
||||
|
||||
|
||||
class SeoUrlController
|
||||
{
|
||||
public static function get(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function getById($id): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
40
src/modules/SEO/module.php
Executable file
40
src/modules/SEO/module.php
Executable file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Modules\SEO\Controller\SeoUrlController;
|
||||
use Venom\Core\Module;
|
||||
use Venom\Routing\Route;
|
||||
|
||||
|
||||
$venom = $venom ?? die();
|
||||
$venom->registerModule([
|
||||
Module::ACTIVE => true,
|
||||
Module::NAME => 'SeoModule',
|
||||
Module::DESC => 'SEO Management for beautiful URLs',
|
||||
Module::AUTHOR => 'VstZ dev',
|
||||
// NEED TO CHECK RIGHTS? :D IF FALSE WRITE IS ALWAYS ALLOWED ALSO READ!
|
||||
Module::SECURE => true,
|
||||
Module::ROUTE => [],
|
||||
Module::ADMIN_ROUTE => [
|
||||
'/seoUrl' => new Route(SeoUrlController::class, [
|
||||
"*" => [
|
||||
Route::GET => 'get'
|
||||
],
|
||||
"1" => [
|
||||
Route::GET => 'getById',
|
||||
Route::POST => 'update',
|
||||
Route::PUT => 'insert',
|
||||
Route::DELETE => 'delete'
|
||||
]
|
||||
])
|
||||
],
|
||||
Module::TEMPLATE_PATH => __DIR__ . "/tpl/",
|
||||
Module::TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::ADMIN_TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::CONTROLLER => [
|
||||
|
||||
]
|
||||
]);
|
57
src/modules/User/Controller/UserAPIController.php
Executable file
57
src/modules/User/Controller/UserAPIController.php
Executable file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Modules\User\Controller;
|
||||
|
||||
use Venom\Core\ArgumentHandler;
|
||||
use Venom\Core\Database\EasyQuery;
|
||||
use Venom\Core\Database\EntityManager;
|
||||
use Venom\Entities\User;
|
||||
use Venom\Helper\AdminHelper;
|
||||
|
||||
class UserAPIController
|
||||
{
|
||||
public function get()
|
||||
{
|
||||
$entityManager = EntityManager::create(User::class);
|
||||
$easyQuery = new EasyQuery(User::$tableName, ["id", "username", "firstname", "lastname", "email", "isActive"]);
|
||||
$entityManager->load($easyQuery);
|
||||
//['id' => 1, 'name' => 'engineertrooper', 'icon' => 'vt-edit'],
|
||||
AdminHelper::sendResponse(["users" => $entityManager->getAll()]);
|
||||
}
|
||||
|
||||
public function getById($id)
|
||||
{
|
||||
$entityManager = EntityManager::create(User::class);
|
||||
$easyQuery = new EasyQuery(User::$tableName, ["id", "username", "firstname", "lastname", "email", "isActive"]);
|
||||
$easyQuery->where("id", $id);
|
||||
$entityManager->load($easyQuery);
|
||||
AdminHelper::sendResponse($entityManager->getFirst());
|
||||
}
|
||||
|
||||
public function update($id)
|
||||
{
|
||||
$entityManager = EntityManager::create(User::class);
|
||||
$easyQuery = new EasyQuery(User::$tableName, ["id", "username", "firstname", "lastname", "email", "isActive"]);
|
||||
$easyQuery->where("id", $id);
|
||||
$entityManager->load($easyQuery);
|
||||
/** @var User|null $original */
|
||||
$original = $entityManager->getFirst();
|
||||
if ($original == null) {
|
||||
AdminHelper::sendStatus(false, "User not Found");
|
||||
}
|
||||
parse_str(file_get_contents('php://input'), $_PUT);
|
||||
/* var_dump(array_keys($_PUT));*/
|
||||
AdminHelper::sendStatus($entityManager->saveAll());
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
}
|
||||
|
||||
public function create($id)
|
||||
{
|
||||
// INSERT INTO
|
||||
AdminHelper::sendStatus(true);
|
||||
}
|
||||
}
|
42
src/modules/User/module.php
Executable file
42
src/modules/User/module.php
Executable file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use Modules\User\Controller\UserAPIController;
|
||||
use Venom\Core\Module;
|
||||
use Venom\Routing\Route;
|
||||
use Venom\Venom;
|
||||
|
||||
|
||||
/** @var Venom $venom */
|
||||
$venom = $venom ?? die();
|
||||
$venom->registerModule([
|
||||
Module::ACTIVE => true,
|
||||
Module::NAME => 'UserModule',
|
||||
Module::DESC => 'User Management',
|
||||
Module::AUTHOR => 'VstZ dev',
|
||||
// NEED TO CHECK RIGHTS? :D IF FALSE WRITE IS ALWAYS ALLOWED ALSO READ!
|
||||
Module::SECURE => true,
|
||||
Module::ROUTE => [],
|
||||
Module::ADMIN_ROUTE => [
|
||||
'/users' => new Route(UserAPIController::class, [
|
||||
"*" => [
|
||||
Route::GET => 'get'
|
||||
],
|
||||
"1" => [
|
||||
Route::GET => 'getById',
|
||||
Route::POST => 'update',
|
||||
Route::PUT => 'update',
|
||||
Route::DELETE => 'delete'
|
||||
]
|
||||
]
|
||||
)
|
||||
],
|
||||
Module::TEMPLATE_PATH => __DIR__ . "/tpl/",
|
||||
Module::TEMPLATES => [
|
||||
],
|
||||
Module::ADMIN_TEMPLATES => [
|
||||
//
|
||||
],
|
||||
Module::CONTROLLER => [
|
||||
|
||||
]
|
||||
]);
|
13
src/modules/VenomStatus/Controller/VenomStatusController.php
Normal file
13
src/modules/VenomStatus/Controller/VenomStatusController.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Modules\VenomStatus\Controller;
|
||||
|
||||
|
||||
class VenomStatusController
|
||||
{
|
||||
public function get()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
34
src/modules/VenomStatus/module.php
Executable file
34
src/modules/VenomStatus/module.php
Executable file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Modules\VenomStatus\Controller\VenomStatusController;
|
||||
use Venom\Core\Module;
|
||||
use Venom\Routing\Route;
|
||||
|
||||
|
||||
$venom = $venom ?? die();
|
||||
$venom->registerModule([
|
||||
Module::ACTIVE => true,
|
||||
Module::NAME => 'VenomStatusModule',
|
||||
Module::DESC => 'Show Routes and Modules!',
|
||||
Module::AUTHOR => 'VstZ dev',
|
||||
// NEED TO CHECK RIGHTS? :D IF FALSE WRITE IS ALWAYS ALLOWED ALSO READ!
|
||||
Module::SECURE => true,
|
||||
Module::ROUTE => [],
|
||||
Module::ADMIN_ROUTE => [
|
||||
'/venomStatus' => new Route(VenomStatusController::class, [
|
||||
"*" => [
|
||||
Route::GET => 'get'
|
||||
]
|
||||
])
|
||||
],
|
||||
Module::TEMPLATE_PATH => __DIR__ . "/tpl/",
|
||||
Module::TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::ADMIN_TEMPLATES => [
|
||||
|
||||
],
|
||||
Module::CONTROLLER => [
|
||||
|
||||
]
|
||||
]);
|
0
tpl/.gitkeep
Normal file → Executable file
0
tpl/.gitkeep
Normal file → Executable file
22
tpl/admin/admin-panel.php
Executable file
22
tpl/admin/admin-panel.php
Executable file
|
@ -0,0 +1,22 @@
|
|||
<main>
|
||||
<nav class="menu">
|
||||
<h1 class="logo">Venom</h1>
|
||||
<div data-link="/metaData">Meta Data</div>
|
||||
<div data-link="/pages">Pages</div>
|
||||
<div data-link="/roles">Roles</div>
|
||||
<div data-link="/seoUrl">SEO-URL</div>
|
||||
<div data-link="/users">Users</div>
|
||||
<div data-link="/venomStatus">Venom-Status</div>
|
||||
<div data-link="/admin/api/login/logout">Ausloggen</div>
|
||||
</nav>
|
||||
<div class="app">
|
||||
<div class="nav-toggle"><span></span></div>
|
||||
<div class="content-area">
|
||||
</div>
|
||||
</div>
|
||||
<div class="loader hide">
|
||||
<svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</main>
|
28
tpl/admin/base.php
Executable file
28
tpl/admin/base.php
Executable file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
use Venom\Views\Asset;
|
||||
use Venom\Core\Config;
|
||||
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Venom Admin Interface</title>
|
||||
<?php Asset::get()->renderCSS(); ?>
|
||||
<!--link rel="stylesheet" href="/theme/admin/css/admin-panel.css"-->
|
||||
</head>
|
||||
<body <?=Config::getInstance()->isDevMode() ? 'debug' : ''?>>
|
||||
<?php
|
||||
if (!$this->getVar('isLoggedIn')) {
|
||||
$this->renderTemplate('login');
|
||||
} else {
|
||||
$this->renderTemplate('admin-panel');
|
||||
}
|
||||
Asset::get()->renderJS();
|
||||
?>
|
||||
</body>
|
||||
</html>
|
4
tpl/admin/jsTemplates/includes/btn.tpl
Executable file
4
tpl/admin/jsTemplates/includes/btn.tpl
Executable file
|
@ -0,0 +1,4 @@
|
|||
<button class="btn btn--${type} ${classes}">
|
||||
<span class="btn-ripple"></span>
|
||||
<span class="btn__content">${content}</span>
|
||||
</button>
|
9
tpl/admin/jsTemplates/includes/input.tpl
Executable file
9
tpl/admin/jsTemplates/includes/input.tpl
Executable file
|
@ -0,0 +1,9 @@
|
|||
<v-input
|
||||
class="${classes}"
|
||||
data-label="${label}"
|
||||
required
|
||||
name="${name}"
|
||||
type="${type}"
|
||||
data-error="${error}"
|
||||
class="${class}">${default}
|
||||
</v-input>
|
8
tpl/admin/jsTemplates/includes/select.tpl
Executable file
8
tpl/admin/jsTemplates/includes/select.tpl
Executable file
|
@ -0,0 +1,8 @@
|
|||
<v-select ${required} name="${name}" class="${classes}">
|
||||
<v-label empty="${label}"></v-label>
|
||||
<v-options>
|
||||
{foreach(object as item)}
|
||||
<v-option value="${item.value}" ${item.selected}>${item.name}</v-option>
|
||||
{/for}
|
||||
</v-options>
|
||||
</v-select>
|
3
tpl/admin/jsTemplates/includes/svg.tpl
Executable file
3
tpl/admin/jsTemplates/includes/svg.tpl
Executable file
|
@ -0,0 +1,3 @@
|
|||
<svg role="img" class="icon ${class}">
|
||||
<use href="/theme/admin/icon-sprite.svg#${icon}" xlink:href="/theme/admin/icon-sprite.svg#${icon}"></use>
|
||||
</svg>
|
After Width: | Height: | Size: 155 B |
5
tpl/admin/jsTemplates/includes/switch.tpl
Executable file
5
tpl/admin/jsTemplates/includes/switch.tpl
Executable file
|
@ -0,0 +1,5 @@
|
|||
<v-switch data-id="${id}" class="${classes}">
|
||||
<input type="checkbox" required name="${name}">
|
||||
<label></label>
|
||||
<span>${desc}</span>
|
||||
</v-switch>
|
5
tpl/admin/jsTemplates/metaDataList.tpl
Executable file
5
tpl/admin/jsTemplates/metaDataList.tpl
Executable file
|
@ -0,0 +1,5 @@
|
|||
<div class="meta-data">
|
||||
<header>
|
||||
<h2>Meta Data</h2>
|
||||
</header>
|
||||
</div>
|
3
tpl/admin/jsTemplates/overview.tpl
Executable file
3
tpl/admin/jsTemplates/overview.tpl
Executable file
|
@ -0,0 +1,3 @@
|
|||
<header>
|
||||
<h2>Overview</h2>
|
||||
</header>
|
35
tpl/admin/jsTemplates/pageEdit.tpl
Executable file
35
tpl/admin/jsTemplates/pageEdit.tpl
Executable file
|
@ -0,0 +1,35 @@
|
|||
<div class="page-edit">
|
||||
<header>
|
||||
<h2>Page Edit: Turbinen sind geil</h2>
|
||||
</header>
|
||||
<div>
|
||||
<span data-link="/pages" class="icon-text">
|
||||
{include(includes/svg;class=back-arrow;icon=vt-arrow-back)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>Page Information</h3>
|
||||
{include(includes/input;class=input-group;label=Page Name;name=PageName;error=Page Name is required;default=Turbinen sind geil)}
|
||||
</div>
|
||||
<div>
|
||||
{include(includes/select;name=pageVisibility;label=Current Author;object=$users)}
|
||||
</div>
|
||||
<div>
|
||||
<v-select required name="pageVisibility">
|
||||
<v-label empty="Page Visibility"></v-label>
|
||||
<v-options>
|
||||
<v-option value="visible">Visible</v-option>
|
||||
<v-option value="privat">Privat</v-option>
|
||||
</v-options>
|
||||
</v-select>
|
||||
</div>
|
||||
<div>
|
||||
<v-editor name="pageTextArea" rows="25">!</v-editor>
|
||||
</div>
|
||||
<div class="btn-line">
|
||||
{include(includes/btn;type=valid;content=Save)}
|
||||
{include(includes/btn;type=primary;content=Reset)}
|
||||
{include(includes/btn;type=warn;content=Delete Page)}
|
||||
</div>
|
||||
</div>
|
22
tpl/admin/jsTemplates/pagesList.tpl
Executable file
22
tpl/admin/jsTemplates/pagesList.tpl
Executable file
|
@ -0,0 +1,22 @@
|
|||
<div class="pages-list">
|
||||
<header>
|
||||
<h2>Pages</h2>
|
||||
</header>
|
||||
<div class="add-new">
|
||||
<h3>Add new Page</h3>
|
||||
{include(includes/input;label=New Page Name;name=newPageName;error=New Page Name is required;type=text)}
|
||||
{include(includes/btn;type=primary;content=Add)}
|
||||
</div>
|
||||
<div class="overview">
|
||||
<h3>All Pages</h3>
|
||||
{foreach(pages as page,key)}
|
||||
<div data-link="/pages" data-id="${page.id}">
|
||||
<span>
|
||||
{include(includes/svg;icon=$page.icon)}
|
||||
</span>
|
||||
<span>${page.name}</span>
|
||||
</div>
|
||||
{/for}
|
||||
</div>
|
||||
</div>
|
||||
|
59
tpl/admin/jsTemplates/roleEdit.tpl
Executable file
59
tpl/admin/jsTemplates/roleEdit.tpl
Executable file
|
@ -0,0 +1,59 @@
|
|||
<div class="role-edit">
|
||||
<header>
|
||||
<h2>Role: ${roles.name}</h2>
|
||||
</header>
|
||||
<span data-link="/roles" class="icon-back">
|
||||
{include(includes/svg;class=back-arrow;icon=vt-arrow-back)}
|
||||
</span>
|
||||
<div class="spacer">
|
||||
{include(includes/switch;id=${switch.id};name=permissionEditMetaData;desc=Active)}
|
||||
{include(includes/input;class=input-group;label=Name;name=roleName;error=Name is required;default=$roles.name;classes=spacer)}
|
||||
</div>
|
||||
<v-table class="privileges">
|
||||
<h3>Privileges</h3>
|
||||
<v-table-body>
|
||||
<v-table-header>
|
||||
<v-cell class="name">Module</v-cell>
|
||||
<v-cell class="name">Edit</v-cell>
|
||||
<v-cell class="name">View</v-cell>
|
||||
</v-table-header>
|
||||
<v-table-row>
|
||||
<v-cell class="description">Meta-Data</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionEditMetaData)}</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionViewMetaData)}</v-cell>
|
||||
</v-table-row>
|
||||
<v-table-row>
|
||||
<v-cell class="description">Pages</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionEditPages)}</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionViewPages)}</v-cell>
|
||||
</v-table-row>
|
||||
<v-table-row>
|
||||
<v-cell class="description">Roles</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionEditRoles)}</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionViewRoles)}</v-cell>
|
||||
</v-table-row>
|
||||
<v-table-row>
|
||||
<v-cell class="description">SEO-URL</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionEditSeoUrl)}</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionViewSeoUrl)}</v-cell>
|
||||
</v-table-row>
|
||||
<v-table-row>
|
||||
<v-cell class="description">Users</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionEditUsers)}</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionViewUsers)}</v-cell>
|
||||
</v-table-row>
|
||||
<v-table-row>
|
||||
<v-cell class="description">VENOM-Status</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionEditVenomStatus)}</v-cell>
|
||||
<v-cell>{include(includes/switch;id=${switch.id};name=permissionViewVenomStatus)}</v-cell>
|
||||
</v-table-row>
|
||||
</v-table-body>
|
||||
</v-table>
|
||||
<div class="btn-line">
|
||||
<div>
|
||||
{include(includes/btn;type=valid;content=Save)}
|
||||
{include(includes/btn;type=primary;content=Reset)}
|
||||
{include(includes/btn;type=warn;content=Delete Role)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
23
tpl/admin/jsTemplates/rolesList.tpl
Executable file
23
tpl/admin/jsTemplates/rolesList.tpl
Executable file
|
@ -0,0 +1,23 @@
|
|||
<div class="roles-list">
|
||||
<header>
|
||||
<h2>Roles</h2>
|
||||
</header>
|
||||
<div class="flexbox">
|
||||
<div class="overview">
|
||||
<h3>Overview</h3>
|
||||
{foreach(roles as role,key)}
|
||||
<div data-link="/roles" data-id="${role.id}">
|
||||
<span>
|
||||
{include(includes/svg;icon=$role.icon)}
|
||||
</span>
|
||||
<span>${role.name}</span>
|
||||
</div>
|
||||
{/for}
|
||||
</div>
|
||||
<div class="add-new">
|
||||
<h3>Add new Role</h3>
|
||||
{include(includes/input;label=New Role Name;name=newRoleName;error=New Role Name is required;type=text)}
|
||||
{include(includes/btn;type=primary;content=Add)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
10
tpl/admin/jsTemplates/seoUrlEdit.tpl
Executable file
10
tpl/admin/jsTemplates/seoUrlEdit.tpl
Executable file
|
@ -0,0 +1,10 @@
|
|||
<div class="seo-url-list">
|
||||
<header>
|
||||
<h2>SEO Urls Edit</h2>
|
||||
</header>
|
||||
<div>
|
||||
<span data-link="/seoUrl" class="icon-text">
|
||||
{include(includes/svg;class=back-arrow;icon=vt-arrow-back)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
5
tpl/admin/jsTemplates/seoUrlList.tpl
Executable file
5
tpl/admin/jsTemplates/seoUrlList.tpl
Executable file
|
@ -0,0 +1,5 @@
|
|||
<div class="seo-url-list">
|
||||
<header>
|
||||
<h2>SEO Urls</h2>
|
||||
</header>
|
||||
</div>
|
34
tpl/admin/jsTemplates/userEdit.tpl
Executable file
34
tpl/admin/jsTemplates/userEdit.tpl
Executable file
|
@ -0,0 +1,34 @@
|
|||
<div class="users-edit">
|
||||
<header>
|
||||
<h2>User: ${username}</h2>
|
||||
</header>
|
||||
<div>
|
||||
<span data-link="/users" class="icon-text">
|
||||
{include(includes/svg;class=back-arrow;icon=vt-arrow-back)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h3>User-Data</h3>
|
||||
<form id="user-form" data-id="${id}">
|
||||
<div class="spacer">
|
||||
{include(includes/input;class=input-group;label=Username;name=username;error=Username is required;default=$username)}
|
||||
{include(includes/input;class=input-group;label=Firstname;name=firstname;error=Firstname is required;default=$firstname;classes=spacer)}
|
||||
{include(includes/input;class=input-group;label=Lastname;name=lastname;error=Lastname is required;default=$lastname;classes=spacer)}
|
||||
{include(includes/input;class=input-group;label=E-Mail;name=newEMailAddress;error=E-Mail Address is required;default=$email;classes=spacer)}
|
||||
|
||||
</div>
|
||||
<div class="btn-line">
|
||||
{include(includes/btn;type=valid;content=Save)}
|
||||
{include(includes/btn;type=warn;content=Delete User)}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h3>Change Password</h3>
|
||||
<form id="password-form" data-id="${id}">
|
||||
{include(includes/input;class=input-group;label=Password;name=password;type=password;classes=spacer)}
|
||||
{include(includes/input;class=input-group;label=Password (Repeat);name=passwordRepeat;type=password;classes=spacer)}
|
||||
<div class="btn-line">
|
||||
{include(includes/btn;type=valid;content=Save)}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
23
tpl/admin/jsTemplates/usersList.tpl
Executable file
23
tpl/admin/jsTemplates/usersList.tpl
Executable file
|
@ -0,0 +1,23 @@
|
|||
<div class="users-list">
|
||||
<header>
|
||||
<h2>Users</h2>
|
||||
</header>
|
||||
</div>
|
||||
<div class="roles-list">
|
||||
<div class="flexbox">
|
||||
<div class="overview">
|
||||
<h3>Overview</h3>
|
||||
{foreach(users as user)}
|
||||
<div data-link="/users" data-id="${user.id}">
|
||||
<span class="icon-text">
|
||||
{include(includes/svg;icon=vt-edit)}
|
||||
</span>
|
||||
<span>${user.username} (${user.firstname} ${user.lastname})</span>
|
||||
</div>
|
||||
{/for}
|
||||
</div>
|
||||
<div class="add-new">
|
||||
{include(includes/btn;type=primary;content=Add User)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
5
tpl/admin/jsTemplates/venomStatus.tpl
Executable file
5
tpl/admin/jsTemplates/venomStatus.tpl
Executable file
|
@ -0,0 +1,5 @@
|
|||
<div class="venom-status">
|
||||
<header>
|
||||
<h2>Venom Status</h2>
|
||||
</header>
|
||||
</div>
|
28
tpl/admin/login.php
Executable file
28
tpl/admin/login.php
Executable file
|
@ -0,0 +1,28 @@
|
|||
<login>
|
||||
<div id="login-background"></div>
|
||||
<form id="login" novalidate method="POST" action="/admin/api/login">
|
||||
<img class="logo" alt="Be Careful" src="/theme/admin/images/logo.svg">
|
||||
<p class="error-message hide">Login Failed</p>
|
||||
<input type="hidden" name="REDIRECT_TO" value="NO">
|
||||
<v-input
|
||||
class="input-group"
|
||||
data-label="Username"
|
||||
required
|
||||
name="USERNAME"
|
||||
data-error="Username is required">
|
||||
</v-input>
|
||||
<v-input
|
||||
class="input-group"
|
||||
data-label="Password"
|
||||
required
|
||||
name="PASSWORD"
|
||||
type="password"
|
||||
data-error="Password is required">
|
||||
</v-input>
|
||||
<button class="btn btn--primary">
|
||||
<span class="btn-ripple"></span>
|
||||
<span class="btn__content">Login</span>
|
||||
</button>
|
||||
<a href="">Forgotten Password? [not active!]</a>
|
||||
</form>
|
||||
</login>
|
0
tpl/default/base.php
Normal file → Executable file
0
tpl/default/base.php
Normal file → Executable file
Loading…
Reference in a new issue