Webseite aus Archiv
This commit is contained in:
parent
3258ce6a56
commit
934fb39856
@ -1,5 +1,5 @@
|
|||||||
# SVEN - Schulprojekt 2019
|
# SVEN - Schulprojekt 2019
|
||||||
SVEN - Lager Verwaltung mit Simulation und etwaigen Features
|
SVEN - Supermarkt Verwaltung mit Simulation und etwaigen Features
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Kasse
|
- Kasse
|
||||||
|
59
webseite/README.md
Normal file
59
webseite/README.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# SVEN
|
||||||
|
|
||||||
|
SVEN is a supermarket management system.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- PHP Version 5.5 or higher
|
||||||
|
- because of password_* functions
|
||||||
|
## File Structure
|
||||||
|
- pages/ - Pages
|
||||||
|
- public/ - CSS & Javascript Files
|
||||||
|
- sys/ - Core and Framework Files
|
||||||
|
- mysql/ - MySQL Connection Wrapper
|
||||||
|
- security/ - Authentication & miscellaneous
|
||||||
|
- sources/ - Used Libraries
|
||||||
|
- sven/ - Some important classes
|
||||||
|
- templates/ - prebuilt elements
|
||||||
|
|
||||||
|
## API Request Methods
|
||||||
|
- GET - Read from database
|
||||||
|
- POST - Insert to database
|
||||||
|
- PATCH - Update in database
|
||||||
|
- DELETE - Delete from database
|
||||||
|
|
||||||
|
## API Output Scheme
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"state": "failed", // program state
|
||||||
|
"access": "granted|denied", // authentication
|
||||||
|
"msg": "{{custom_data_msg}}",
|
||||||
|
"data": "{{data}}",
|
||||||
|
"error": ["{{error}}", ...] // optional
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Parameters
|
||||||
|
- article
|
||||||
|
- GET
|
||||||
|
- limit - limit output
|
||||||
|
- search_for - search for value
|
||||||
|
- in - column name to search in
|
||||||
|
|
||||||
|
## API Errors
|
||||||
|
- REQUEST_METHOD_NOT_SUPPORTED -> Request method not supported
|
||||||
|
- AUTHENTICATION_FAILED -> User not logged in. / Username or password wrong.
|
||||||
|
- BAD_REQUEST -> request or information are missing
|
||||||
|
- NO_OUTPUT -> No data was passed. Request unfortunately failed.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
- Ruben Meyer
|
||||||
|
- Bennet Kahrs
|
||||||
|
- [envms (fluentpdo)][fluentpdo]
|
||||||
|
- [Luís Cobucci (jwt library)][lcobucci]
|
||||||
|
|
||||||
|
## Not working things
|
||||||
|
- can't install laravel / composer to use an popular framework, so we had to write our own framework
|
||||||
|
|
||||||
|
|
||||||
|
[fluentpdo]: <http://envms.github.io/fluentpdo/>
|
||||||
|
[lcobucci]: <https://github.com/lcobucci/jwt>
|
56
webseite/api/article.php
Normal file
56
webseite/api/article.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
// @TODO Comments
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") { \sven\sys\core::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));}
|
||||||
|
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
switch($_SERVER["REQUEST_METHOD"]) {
|
||||||
|
case 'GET':
|
||||||
|
$array = (object) [];
|
||||||
|
$query = $fluent->from('t_artikel')->select('t_artikel.*');
|
||||||
|
|
||||||
|
if(isset($_GET['limit']) && !is_nan($_GET['limit'])) $query->limit($_GET['limit']);
|
||||||
|
if(isset($_GET['search_for']) && isset($_GET['in'])) $query->where($_GET['in'].' LIKE ?', $_GET['search_for'].'%');
|
||||||
|
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
$data = [];
|
||||||
|
foreach ($rows as $arr) {
|
||||||
|
$data[] = $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
$array->data = ["DATA" => $data];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
$array->data = ["POST" => \sven\sys\sven\web::getRequestBody()];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'PATCH':
|
||||||
|
$array = (object) ["DATA" => ["PATCH" => \sven\sys\sven\web::getRequestBody()]];
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
$array = (object) [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(empty($array)) {
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "No output data was passed. Request unfortunately failed.",
|
||||||
|
"error" => ["NO_OUTPUT"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$array = (object) [
|
||||||
|
"body" => $body,
|
||||||
|
"msg" => "User not logged in.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
60
webseite/api/auth.php
Normal file
60
webseite/api/auth.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
// @TODO Comments
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$session = new \sven\sys\security\session;
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") { \sven\sys\core::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));}
|
||||||
|
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
if(!$auth->loggedIn()) {
|
||||||
|
$user = (isset($body->user)) ? $body->user : (isset($_GET['user']) ? $_GET['user'] : null);
|
||||||
|
$pass = (isset($body->pass)) ? $body->pass : (isset($_GET['pass']) ? $_GET['pass'] : null);
|
||||||
|
$csrf = (isset($body->csrf)) ? $body->csrf : (isset($_GET['csrf']) ? $_GET['csrf'] : null);
|
||||||
|
if($user && $pass && $csrf) {
|
||||||
|
$query = $fluent->from('t_benutzer')->select('t_benutzer.*')->where("Name = ?", $user);
|
||||||
|
$data = $query->fetch();
|
||||||
|
|
||||||
|
// verify user exists and password is right
|
||||||
|
if($data && $auth->verifyPassword($pass, $data->Passwort)) {
|
||||||
|
if($auth->validateCSRF("login", $csrf)) {
|
||||||
|
$array = (object) [
|
||||||
|
"token" => $auth->login($user),
|
||||||
|
"msg" => "User logged in.",
|
||||||
|
"state" => "successed"
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// CSRF wrong
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "CSRF Code wrong.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Username not found or password wrong
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "Username or password wrong.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// BAD_REQUEST
|
||||||
|
$array = (object) [
|
||||||
|
"session" => $session->read("csrf_form_login"),
|
||||||
|
"body" => $body,
|
||||||
|
"msg" => "Could process request. Missing data?",
|
||||||
|
"error" => ["BAD_REQUEST"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$auth->logout();
|
||||||
|
// USER LOGGED IN; LOGOUT
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "User logged out.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
8
webseite/api/error/404.php
Normal file
8
webseite/api/error/404.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "API Interface not found. Spelling wrong?"
|
||||||
|
];
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
57
webseite/api/salesFigures.php
Normal file
57
webseite/api/salesFigures.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
// @TODO innerJoin to article
|
||||||
|
// @TODO Comments
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") { \sven\sys\core::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));}
|
||||||
|
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
switch($_SERVER["REQUEST_METHOD"]) {
|
||||||
|
case 'GET':
|
||||||
|
$array = (object) [];
|
||||||
|
$query = $fluent->from('t_verkaufszahlen')->select('t_verkaufszahlen.*');
|
||||||
|
|
||||||
|
if(isset($_GET['limit']) && !is_nan($_GET['limit'])) $query->limit($_GET['limit']);
|
||||||
|
if(isset($_GET['search_for']) && isset($_GET['in'])) $query->where($_GET['in'].' LIKE ?', $_GET['search_for'].'%');
|
||||||
|
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
$data = [];
|
||||||
|
foreach ($rows as $arr) {
|
||||||
|
$data[] = $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
$array->data = ["DATA" => $data];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
$array->data = ["POST" => \sven\sys\sven\web::getRequestBody()];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'PATCH':
|
||||||
|
$array = (object) ["DATA" => ["PATCH" => \sven\sys\sven\web::getRequestBody()]];
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
$array = (object) [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(empty($array)) {
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "No output data was passed. Request unfortunately failed.",
|
||||||
|
"error" => ["NO_OUTPUT"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$array = (object) [
|
||||||
|
"body" => $body,
|
||||||
|
"msg" => "User not logged in.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
55
webseite/api/statistics.php
Normal file
55
webseite/api/statistics.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
// @TODO Comments
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") { \sven\sys\core::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));}
|
||||||
|
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
switch($_SERVER["REQUEST_METHOD"]) {
|
||||||
|
case 'GET':
|
||||||
|
$array = (object) [];
|
||||||
|
$query = $fluent->from('t_statistik')->select('t_statistik.*');
|
||||||
|
|
||||||
|
if(isset($_GET['limit']) && !is_nan($_GET['limit'])) $query->limit($_GET['limit']);
|
||||||
|
if(isset($_GET['search_for']) && isset($_GET['in'])) $query->where($_GET['in'].' LIKE ?', $_GET['search_for'].'%');
|
||||||
|
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
$data = [];
|
||||||
|
foreach ($rows as $arr) {
|
||||||
|
$data[] = $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
$array->data = ["DATA" => $data];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
$array->data = ["POST" => \sven\sys\sven\web::getRequestBody()];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'PATCH':
|
||||||
|
$array = (object) ["DATA" => ["PATCH" => \sven\sys\sven\web::getRequestBody()]];
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
$array = (object) [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(empty($array)) {
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "No output data was passed. Request unfortunately failed.",
|
||||||
|
"error" => ["NO_OUTPUT"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "User not logged in.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
65
webseite/api/stock.php
Normal file
65
webseite/api/stock.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
// @TODO innerJoin to article
|
||||||
|
// @TODO Comments
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") { \sven\sys\core::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));}
|
||||||
|
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
switch($_SERVER["REQUEST_METHOD"]) {
|
||||||
|
case 'GET':
|
||||||
|
$array = (object) [];
|
||||||
|
$query = $fluent->from('t_lager')->select('t_lager.*');
|
||||||
|
$query_2 = $fluent->from('t_artikel')->select('t_artikel.*');
|
||||||
|
|
||||||
|
if(isset($_GET['limit']) && !is_nan($_GET['limit'])) $query->limit($_GET['limit']);
|
||||||
|
if(isset($_GET['search_for']) && isset($_GET['in'])) $query->where($_GET['in'].' LIKE ?', $_GET['search_for'].'%');
|
||||||
|
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
$rows_2 = $query_2->fetchAll();
|
||||||
|
$names = [];
|
||||||
|
foreach ($rows_2 as $key => $row) {
|
||||||
|
$names[$row->ID] = $row->Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
foreach ($rows as $key => $row) {
|
||||||
|
$row->Name = $names[$row->f_Artikel_ID];
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$array->data = ["DATA" => $data];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
$array->data = ["POST" => \sven\sys\sven\web::getRequestBody()];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'PATCH':
|
||||||
|
$array = (object) ["DATA" => ["PATCH" => \sven\sys\sven\web::getRequestBody()]];
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
$array = (object) [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(empty($array)) {
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "No output data was passed. Request unfortunately failed.",
|
||||||
|
"error" => ["NO_OUTPUT"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$array = (object) [
|
||||||
|
"body" => $body,
|
||||||
|
"msg" => "User not logged in.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
66
webseite/api/stockDeliveries.php
Normal file
66
webseite/api/stockDeliveries.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
// @TODO innerJoin to article
|
||||||
|
// @TODO Comments
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") { \sven\sys\core::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));}
|
||||||
|
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
switch($_SERVER["REQUEST_METHOD"]) {
|
||||||
|
case 'GET':
|
||||||
|
$array = (object) [];
|
||||||
|
$query = $fluent->from('t_bestellungen')->select('t_bestellungen.*');
|
||||||
|
$query_2 = $fluent->from('t_artikel')->select('t_artikel.*');
|
||||||
|
|
||||||
|
if(isset($_GET['limit']) && !is_nan($_GET['limit'])) $query->limit($_GET['limit']);
|
||||||
|
if(isset($_GET['search_for']) && isset($_GET['in'])) $query->where($_GET['in'].' LIKE ?', $_GET['search_for'].'%');
|
||||||
|
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
$rows_2 = $query_2->fetchAll();
|
||||||
|
$names = [];
|
||||||
|
foreach ($rows_2 as $key => $row) {
|
||||||
|
$names[$row->ID] = $row->Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
foreach ($rows as $key => $row) {
|
||||||
|
$row->Name = $names[$row->f_Artikel_ID];
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$array->data = ["DATA" => $data];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
$array->data = ["POST" => \sven\sys\sven\web::getRequestBody()];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'PATCH':
|
||||||
|
$array = (object) ["DATA" => ["PATCH" => \sven\sys\sven\web::getRequestBody()]];
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
$array = (object) [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(empty($array)) {
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "No output data was passed. Request unfortunately failed.",
|
||||||
|
"error" => ["NO_OUTPUT"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$array = (object) [
|
||||||
|
"body" => $body,
|
||||||
|
"msg" => "User not logged in.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
61
webseite/api/users.php
Normal file
61
webseite/api/users.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
// @TODO Comments
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") { \sven\sys\core::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));}
|
||||||
|
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
$array = (object) [];
|
||||||
|
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
switch($_SERVER["REQUEST_METHOD"]) {
|
||||||
|
case 'GET':
|
||||||
|
$array = (object) [];
|
||||||
|
$query = $fluent->from('t_benutzer')->select('t_benutzer.*');
|
||||||
|
|
||||||
|
if(isset($_GET['limit']) && !is_nan($_GET['limit'])) $query->limit($_GET['limit']);
|
||||||
|
if(isset($_GET['search_for']) && isset($_GET['in'])) $query->where($_GET['in'].' LIKE ?', $_GET['search_for'].'%');
|
||||||
|
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
$data = [];
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$row->Passwort = null;
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$array->data = ["DATA" => $data];
|
||||||
|
$array->state = "successed";
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$array = (object) [];
|
||||||
|
if(!empty($body = \sven\sys\sven\web::getRequestBody())) {
|
||||||
|
if(isset($body->user) && isset($body->pass)) {
|
||||||
|
$query = $fluent->from('t_benutzer')->select('t_benutzer.*');
|
||||||
|
$array->data = ["POST" => $body];
|
||||||
|
$array->state = "successed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'PATCH':
|
||||||
|
$array = (object) ["DATA" => ["PATCH" => \sven\sys\sven\web::getRequestBody()]];
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
$array = (object) [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(empty($array)) {
|
||||||
|
$array = (object) [
|
||||||
|
"msg" => "No output data was passed. Request unfortunately failed.",
|
||||||
|
"error" => ["NO_OUTPUT"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$array = (object) [
|
||||||
|
"body" => $body,
|
||||||
|
"msg" => "User not logged in.",
|
||||||
|
"error" => ["AUTHENTICATION_FAILED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
\sven\sys\core::replaceApiOutput($array);
|
||||||
|
|
||||||
|
?>
|
30
webseite/index.php
Normal file
30
webseite/index.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
// version check
|
||||||
|
if(version_compare(phpversion(), '7.0.0', '<')) exit('PHP VERSION insufficient ('.phpversion().')');
|
||||||
|
|
||||||
|
// class autoload
|
||||||
|
require('sys/autoload.php');
|
||||||
|
|
||||||
|
use \sven\sys\sven as sven;
|
||||||
|
use \sven\sys\mysql\mysql as mysql;
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
|
||||||
|
// Request Handler
|
||||||
|
sven\web::setSecurityHeaders();
|
||||||
|
$web = new sven\web(dirname(__FILE__));
|
||||||
|
|
||||||
|
/* TOOL: prebuilt source files for used libraries
|
||||||
|
$folder = dirname(__FILE__).'/sys/sources/';
|
||||||
|
foreach(sven\utilities::getAllFiles($folder, '.php') as $key) {
|
||||||
|
$key = str_replace($folder.'\jwt\\src\\', '$dir.\'', $key);
|
||||||
|
if(sven\utilities::startsWith($key, '$dir')) print_r($key."', ");
|
||||||
|
}
|
||||||
|
/**/
|
||||||
|
|
||||||
|
//print_r(get_required_files());
|
||||||
|
if(!sven\web::$API)
|
||||||
|
print_r(CORE::getOutput());
|
||||||
|
else
|
||||||
|
echo(CORE::getApiOutput());
|
||||||
|
|
||||||
|
?>
|
112
webseite/pages/abcxyz.php
Normal file
112
webseite/pages/abcxyz.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'ABC/XYZ Analyse');
|
||||||
|
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
|
||||||
|
|
||||||
|
function lastElement($array) {return end($array);}
|
||||||
|
|
||||||
|
|
||||||
|
$options = "";
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
$query_2 = $fluent->from('t_artikel')->select('t_artikel.Name, t_artikel.ID');
|
||||||
|
$rows_2 = $query_2->fetchAll();
|
||||||
|
$names = [];
|
||||||
|
foreach ($rows_2 as $id => $row) {
|
||||||
|
$names[$row->ID] = $row->Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $fluent->from('t_verkaufszahlen')->select('t_verkaufszahlen.*');
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'abc' => [
|
||||||
|
'mengen' => [],
|
||||||
|
'werte' => []
|
||||||
|
],
|
||||||
|
'xyz' => [],
|
||||||
|
'sorted_abc' => [0 => [], 1 => [], 2 => []],
|
||||||
|
'sorted_xyz' => [0 => [], 1 => [], 2 => []]
|
||||||
|
];
|
||||||
|
$output = "";
|
||||||
|
foreach ($rows as $id => $row) {
|
||||||
|
if($id > 0) $data['abc']['mengen'][$id] = [ ($row->Menge+$data['abc']['mengen'][$id-1][0]), $row->f_Artikel_ID];
|
||||||
|
else $data['abc']['mengen'][$id] = [$row->Menge+0, $row->f_Artikel_ID];
|
||||||
|
|
||||||
|
if($id > 0) $data['abc']['werte'][$id] = [($row->Verkaufspreis+$data['abc']['werte'][$id-1][0]), $row->f_Artikel_ID];
|
||||||
|
else $data['abc']['werte'][$id] = [$row->Verkaufspreis+0, $row->f_Artikel_ID];
|
||||||
|
|
||||||
|
$output .= "<tr>";
|
||||||
|
$output .="<td>{$names[$data['abc']['mengen'][$id][1]]}</td>";
|
||||||
|
$output .="<td>{$data['abc']['mengen'][$id][0]}</td>";
|
||||||
|
$output .="<td>{$data['abc']['werte'][$id][0]}</td>";
|
||||||
|
$output .="</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABC Zuordnung
|
||||||
|
foreach ($data['abc']['mengen'] as $key => $value) {
|
||||||
|
$value = $data['abc']['werte'][$key][0] / lastElement($data['abc']['werte'])[0];
|
||||||
|
|
||||||
|
//var_dump([$value > 0.8, 0.8 < $value && $value > 0.95, 0.95 < $value]);
|
||||||
|
if($value > 0.95) array_push($data['sorted_abc'][2], $names[$data['abc']['werte'][$key][1]]);
|
||||||
|
else if(0.8 > $value && $value < 0.95) array_push($data['sorted_abc'][1], $names[$data['abc']['werte'][$key][1]]);
|
||||||
|
else if($value < 0.8) array_push($data['sorted_abc'][0], $names[$data['abc']['werte'][$key][1]]);
|
||||||
|
//var_dump($value);
|
||||||
|
}
|
||||||
|
$XA = var_export($data['sorted_abc'][0], true);
|
||||||
|
$XB = var_export($data['sorted_abc'][1], true);
|
||||||
|
$XC = var_export($data['sorted_abc'][2], true);
|
||||||
|
|
||||||
|
$YA = "";
|
||||||
|
$YB = "";
|
||||||
|
$YC = "";
|
||||||
|
|
||||||
|
$ZA = "";
|
||||||
|
$ZB = "";
|
||||||
|
$ZC = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container" id="calc-page">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>ABC/XYZ Analyse</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Verbrauchsmenge</td>
|
||||||
|
<td>A</td>
|
||||||
|
<td>B</td>
|
||||||
|
<td>C</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>X</td>
|
||||||
|
<td>{$XA}</td>
|
||||||
|
<td>{$XB}</td>
|
||||||
|
<td>{$XC}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Y</td>
|
||||||
|
<td>{$YA}</td>
|
||||||
|
<td>{$YB}</td>
|
||||||
|
<td>{$YC}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Z</td>
|
||||||
|
<td>{$ZA}</td>
|
||||||
|
<td>{$ZB}</td>
|
||||||
|
<td>{$ZC}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
149
webseite/pages/calc.php
Normal file
149
webseite/pages/calc.php
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Kalkulation');
|
||||||
|
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
|
||||||
|
$options = "";
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
$query = $fluent->from('t_artikel')->select('t_artikel.*');
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
foreach ($rows as $id => $row) {
|
||||||
|
$selected = (($row->ID === "1") ? "selected" : "");
|
||||||
|
$options .= "<option value='{$row->ID}|{$row->Einkaufspreis}|{$row->Anzahl_pro_Palette}' $selected>{$row->Name}</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container" id="calc-page">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>Gewinnkalkulation</h2>
|
||||||
|
|
||||||
|
<div class="input-group mb-md-3" id="products-selector">
|
||||||
|
<label for="products">Produkt</label>
|
||||||
|
<select class="custom-select" id="products">
|
||||||
|
<!-- <option value="%PRICE%|%PLT_COUNT%"></option> -->
|
||||||
|
$options
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="my-md-4 form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="selected-price">Preis (GE)</label>
|
||||||
|
<input type="text" class="form-control" id="selected-price" placeholder="Preis" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="selected-plt">Anzahl pro Palette (ME)</label>
|
||||||
|
<input type="text" class="form-control" id="selected-plt" placeholder="Anzahl pro Palette" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="col-md-1"></div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label for="rabatt">Rabatt (%)</label>
|
||||||
|
<input type="text" class="form-control" id="rabatt" placeholder="Rabatt">
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label for="skonto">Skonto (%)</label>
|
||||||
|
<input type="text" class="form-control" id="skonto" placeholder="Skonto">
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label for="bezugskosten">Bezugskosten (%)</label>
|
||||||
|
<input type="text" class="form-control" id="bezugskosten" placeholder="Bezugskosten">
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label for="handelskosten">Handelskosten (%)</label>
|
||||||
|
<input type="text" class="form-control" id="handelskosten" placeholder="Handelskosten">
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label for="gewinnzuschlag">Gewinnzuschlag (%)</label>
|
||||||
|
<input type="text" class="form-control" id="gewinnzuschlag" placeholder="Gewinnzuschlag">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<!-- CALCULATION FIELDS -->
|
||||||
|
<h3> Rechnung </h3>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="listeneinkaufspreis">Listeneinkaufspreis (GE)</label>
|
||||||
|
<input type="text" class="form-control" id="listeneinkaufspreis" placeholder="Listeneinkaufspreis" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="selbstkosten">Selbstkosten (GE) | <span class="info"> ↓ Handelskosten </span></label>
|
||||||
|
<input type="text" class="form-control selbstkosten" placeholder="Selbstkosten" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="zieleinkaufspreis">Zieleinkaufspreis (GE) | <span class="info">↓ Rabatt </span></label>
|
||||||
|
<input type="text" class="form-control" id="zieleinkaufspreis" placeholder="Zieleinkaufspreis" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="angebotspreis">Angebotspreis (GE) | <span class="info">↓ Gewinnzuschlag </span></label>
|
||||||
|
<input type="text" class="form-control" id="angebotspreis" placeholder="Angebotspreis" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="bareinkaufspreis">Bareinkaufspreis (GE) | <span class="info">↓ Skonto </span></label>
|
||||||
|
<input type="text" class="form-control" id="bareinkaufspreis" placeholder="Bareinkaufspreis" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="angebotspreis_mwst">Angebotspreis(MwSt.) (19%) (GE) | <span class="info">↓ Mehrwertsteuer </span></label>
|
||||||
|
<input type="text" class="form-control" id="angebotspreis_mwst" placeholder="Angebotspreis (MwSt.)" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="bezugspreis">Bezugspreis (GE) | <span class="info">↓ Bezugskosten </span></label>
|
||||||
|
<input type="text" class="form-control" id="bezugspreis" placeholder="Bezugspreis" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="angebotspreis_stk">Angebotspreis pro Stück (GE)</label>
|
||||||
|
<input type="text" class="form-control" id="angebotspreis_stk" placeholder="Angebotspreis (Stückzahl)" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="selbstkosten">Selbstkosten (GE)</label>
|
||||||
|
<input type="text" class="form-control selbstkosten" placeholder="Selbstkosten" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="rohgewinn">Rohgewinn (GE)</label>
|
||||||
|
<input type="text" class="form-control bg-success" id="rohgewinn" placeholder="Rohgewinn" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<!-- Konkurrenzvergleich -->
|
||||||
|
<h3> Konkurrenzpreis </h3>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="selbstkosten">Selbstkosten (GE)</label>
|
||||||
|
<input type="text" class="form-control selbstkosten" placeholder="Selbstkosten" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="konkurrenzpreis">Konkurrenzpreis (GE)</label>
|
||||||
|
<input type="text" class="form-control" id="konkurrenzpreis" placeholder="Konkurrenzpreis">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="gewinn">Gewinn (GE)</label>
|
||||||
|
<input type="text" class="form-control" id="gewinn" placeholder="Gewinn" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="gewinnPrcnt">Gewinn (%)</label>
|
||||||
|
<input type="text" class="form-control" id="gewinnPrcnt" placeholder="Gewinn in Prozent" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
18
webseite/pages/deliveries.php
Normal file
18
webseite/pages/deliveries.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Lieferungen');
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>Aktuelle Lieferungen</h2>
|
||||||
|
<p>Wenn es aktuelle Lieferungen gibt, werden diese hier in Tabellenform angezeigt.</p>
|
||||||
|
<br />
|
||||||
|
<div id='lieferTabelle'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
19
webseite/pages/errors/404.php
Normal file
19
webseite/pages/errors/404.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Fehler - 404');
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2"></div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h2 class="mb-md-4"> Suchen Sie etwas bestimmtes? </h2>
|
||||||
|
<p> Die gesuchte Adresse ist nicht verfügbar. Vielleicht ein andermal? </p>
|
||||||
|
<hr />
|
||||||
|
<a class="btn btn-info" href="./">Zurück zur Startseite</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
25
webseite/pages/index.php
Normal file
25
webseite/pages/index.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Dashboard');
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="divH">
|
||||||
|
<h1 class='hWelcome'>Willkommen bei Sven<h1>
|
||||||
|
<p class="pH_Wel">Dies ist ihre Supermarkt-Verwaltungs-Software.</p>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<h2>Produkttabelle</h2>
|
||||||
|
<div id="produktTabelle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
39
webseite/pages/login.php
Normal file
39
webseite/pages/login.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
|
||||||
|
$token = $auth->createCSRF("login");
|
||||||
|
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Login');
|
||||||
|
|
||||||
|
CORE::addTemplate('main', <<<EOF
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 mx-auto mt-3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2"></div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h2>Login</h2>
|
||||||
|
<form name="login">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="loginUser">Benutzername</label>
|
||||||
|
<input type="test" class="form-control" id="loginUser" name="loginUser" placeholder="Gib deinen Benutzernamen ein">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="loginPass">Passwort</label>
|
||||||
|
<input type="password" class="form-control" id="loginPass" name="loginPass" placeholder="Und hier dein Passwort">
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="csrf_token" name="csrf_token" value="%%main_CSRF%%">
|
||||||
|
<div class="row float-right">
|
||||||
|
<button type="submit" class="btn btn-primary">Login</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
CORE::addReplacement('main', 'CSRF', $token);
|
||||||
|
?>
|
7
webseite/pages/logout.php
Normal file
7
webseite/pages/logout.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
if($auth->loggedIn())
|
||||||
|
$auth->logout();
|
||||||
|
|
||||||
|
?>
|
29
webseite/pages/stats.php
Normal file
29
webseite/pages/stats.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Statistik');
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>Verkaufte Produkte</h2>
|
||||||
|
<br />
|
||||||
|
<div class="ct-chart ct-golden-section" id="chart1" onready="gesamtMenge()"></div>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<h2>Produkte</h2>
|
||||||
|
<div id ="products-selector" class="input-group">
|
||||||
|
<label for="produkte">Produkt auswählen:</label>
|
||||||
|
<select id="produkte" class="custom-select"></select>
|
||||||
|
<button class="btn btn-primary" onclick="selectProduct()">Verkaufte Menge</button>
|
||||||
|
<button class="btn btn-primary" onclick="gewinnGraph()">Gewinngraph</button>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<div class="ct-chart ct-golden-section" id="chart2"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
16
webseite/pages/stock.php
Normal file
16
webseite/pages/stock.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Lager');
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>Lagertabelle</h2>
|
||||||
|
<div id='lagerTabelle'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
148
webseite/pages/users.php
Normal file
148
webseite/pages/users.php
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<?php
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
CORE::setLogin(true);
|
||||||
|
CORE::addReplacement('head', 'TITLE', 'Benutzerverwaltung');
|
||||||
|
|
||||||
|
$mysql = new \sven\sys\mysql\mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
|
||||||
|
$tableString = "";
|
||||||
|
if($auth->loggedIn()) {
|
||||||
|
$query = $fluent->from('t_benutzer')->select('t_benutzer.*');
|
||||||
|
$rows = $query->fetchAll();
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$banned = ($row->banned === 1) ? "Ja" : "Nein";
|
||||||
|
$tableString .= "<tr class='table-py-2'>";
|
||||||
|
$tableString .= "<td>{$row->ID}</td>";
|
||||||
|
$tableString .= "<td>{$row->Name}</td>";
|
||||||
|
$tableString .= "<td>{$banned}</td>";
|
||||||
|
$tableString .= "<td>";
|
||||||
|
$tableString .= '<button type="button" class="btn btn-warning" data-toggle="modal" data-user="'.$row->Name.'" data-target="#modalChangePassword">Passwort ändern</button>';
|
||||||
|
$tableString .= '<span class="mx-2"></span>';
|
||||||
|
$tableString .= '<button type="button" class="btn btn-danger" data-toggle="modal" data-user="'.$row->Name.'" data-target="#modalDeleteUser">Benutzer löschen</button>';
|
||||||
|
$tableString .= "</td>";
|
||||||
|
$tableString .= "</tr>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CORE::addReplacement('main', 'FILE', <<<EOF
|
||||||
|
<div class="container" id="users_page">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>Benutzerverwaltung</h2>
|
||||||
|
|
||||||
|
<table class="mb-md-2">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th> ID </th>
|
||||||
|
<th> Benutzername </th>
|
||||||
|
<th> Gebannt </th>
|
||||||
|
<th> Aktionen </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
$tableString
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="float-right">
|
||||||
|
<button type="button" class="btn btn-info" data-toggle="modal" data-target="#modalAddUser">Benutzer hinzufügen</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modalChangePassword" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Passwort ändern</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>
|
||||||
|
Möchtest du wirklich das Passwort ändern für
|
||||||
|
"<span class="m-cp-span-user"></span>"?
|
||||||
|
</p>
|
||||||
|
<form name="m_cp_form" id="m_cp_form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="change_username" class="col-form-label">Benutzername</label>
|
||||||
|
<input type="text" class="form-control" id="change_username" name="username" disabled>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password" class="col-form-label">Neues Passwort</label>
|
||||||
|
<input type="text" class="form-control" id="password" name="password">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary float-right">Abschicken</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modalDeleteUser" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Benutzer löschen</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>
|
||||||
|
Möchtest du wirklich den Benutzer "<span id="m-du-span-user"></span>" löschen?
|
||||||
|
</p>
|
||||||
|
<form name="m_du_form" id="m_du_form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="del_username" class="col-form-label">Benutzername</label>
|
||||||
|
<input type="text" class="form-control" id="del_username" name="username" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary float-right">Abschicken</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modalAddUser" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Benutzer hinzufügen</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form name="m_au_form" id="m_au_form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="add_username" class="col-form-label">Benutzername</label>
|
||||||
|
<input type="text" class="form-control" id="add_username" name="username">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="add_password" class="col-form-label">Passwort</label>
|
||||||
|
<input type="password" class="form-control" id="add_password" name="password">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary float-right">Abschicken</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
?>
|
6
webseite/public/css/bootstrap.min.css
vendored
Normal file
6
webseite/public/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
170
webseite/public/css/styles.css
Normal file
170
webseite/public/css/styles.css
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
body {
|
||||||
|
font-size: .875rem;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sidebar
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-sticky {
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
top: 48px; /* Height of navbar */
|
||||||
|
height: calc(100vh - 48px);
|
||||||
|
padding-top: .5rem;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-link {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
transition: all .2s cubic-bezier(1,.1,.13,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-link.active {
|
||||||
|
color: #007bff;
|
||||||
|
background-color: #e3e3e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-link:hover:not(.active) {
|
||||||
|
background-color: #d2d2d2;
|
||||||
|
color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-heading {
|
||||||
|
font-size: .75rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Navbar
|
||||||
|
*/
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
padding-top: .75rem;
|
||||||
|
padding-bottom: .75rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
background-color: rgba(0, 0, 0, .25);
|
||||||
|
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .form-control {
|
||||||
|
padding: .75rem 1rem;
|
||||||
|
border-width: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-dark {
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgba(255, 255, 255, .1);
|
||||||
|
border-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-dark:focus {
|
||||||
|
border-color: transparent;
|
||||||
|
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utilities
|
||||||
|
*/
|
||||||
|
|
||||||
|
.border-top { border-top: 1px solid #e5e5e5; }
|
||||||
|
.border-bottom { border-bottom: 1px solid #e5e5e5; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Charts
|
||||||
|
* @author Bennet Kahrs
|
||||||
|
*/
|
||||||
|
.ct-series-a .ct-bar {
|
||||||
|
stroke: rgb(0, 154, 174);
|
||||||
|
stroke-width:20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.ct-series-a .ct-line {
|
||||||
|
stroke: rgb(0, 154, 174);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.ct-series-a .ct-area {
|
||||||
|
fill: rgba(0, 154, 174,.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ct-series-a .ct-point {
|
||||||
|
stroke: rgb(0, 154, 174);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border: black 1px solid;
|
||||||
|
}
|
||||||
|
tbody tr:nth-child(even) {
|
||||||
|
background-color: rgba(52,58,62, .4);
|
||||||
|
}
|
||||||
|
thead {
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
background-color: rgba(52,58,62, .9);
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 100%;
|
||||||
|
min-width: 9%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Headline Dashboard
|
||||||
|
*/
|
||||||
|
.hWelcome {
|
||||||
|
text-align: center;
|
||||||
|
color: rgb(52,58,62);
|
||||||
|
font-size: 100px;
|
||||||
|
}
|
||||||
|
.pH_Wel {
|
||||||
|
color: rgb(52,58,62);
|
||||||
|
text-align: center;
|
||||||
|
font-size: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divH {
|
||||||
|
background-color: rgba(0, 154, 174,.8);
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0px 10px 15px rgba(0,82,93,.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Produkt Tabelle
|
||||||
|
*/
|
||||||
|
#products-selector > label {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 0 20px 5px 0;
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
#products-selector > button {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benutzerverwaltung
|
||||||
|
*/
|
||||||
|
.table-py-2 .btn {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.table-py-2 .btn:last-child {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#calc-page .form-row .info {
|
||||||
|
background-color: rgba(40, 167, 69, .8);
|
||||||
|
padding: 5px;
|
||||||
|
border: 1px rgba(0,0,0,.2) solid;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
17
webseite/public/js/auth.js
Normal file
17
webseite/public/js/auth.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var $userData = {};
|
||||||
|
|
||||||
|
function request(config, done, fail = null) {
|
||||||
|
if(!config.data) config.data = {};
|
||||||
|
if($userData.user) config.data.user = $userData.user;
|
||||||
|
if($userData.pass) config.data.pass = $userData.pass;
|
||||||
|
if($userData.token) {
|
||||||
|
config.data.token = $userData.token;
|
||||||
|
} else {
|
||||||
|
if(Cookies.get("JWT_SVEN"))
|
||||||
|
config.data.token = Cookies.get("JWT_SVEN");
|
||||||
|
}
|
||||||
|
if(fail) $.ajax(config).done(done).fail(fail);
|
||||||
|
else $.ajax(config).done(done);
|
||||||
|
};
|
95
webseite/public/js/calc.js
Normal file
95
webseite/public/js/calc.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
'use strict';
|
||||||
|
// CUSTOM CODE
|
||||||
|
|
||||||
|
if($('#calc-page').length) {
|
||||||
|
var values = {
|
||||||
|
data: $('#products').val(),
|
||||||
|
id: $('#products').val().split('|')[0],
|
||||||
|
price: $('#products').val().split('|')[1],
|
||||||
|
plt: $('#products').val().split('|')[2],
|
||||||
|
percentage: {
|
||||||
|
discount: 7,
|
||||||
|
cashDiscount: 9,
|
||||||
|
procurementCosts: 5,
|
||||||
|
tradingCosts: 4,
|
||||||
|
profitMargin: 20
|
||||||
|
},
|
||||||
|
fields: {},
|
||||||
|
updateFields: () => {
|
||||||
|
$('#selected-price').val(values.price);
|
||||||
|
$('#selected-plt').val(values.plt);
|
||||||
|
|
||||||
|
$('#rabatt').val(values.percentage.discount);
|
||||||
|
$('#skonto').val(values.percentage.cashDiscount);
|
||||||
|
$('#bezugskosten').val(values.percentage.procurementCosts);
|
||||||
|
$('#handelskosten').val(values.percentage.tradingCosts);
|
||||||
|
$('#gewinnzuschlag').val(values.percentage.profitMargin);
|
||||||
|
|
||||||
|
values.fields.listeneinkaufspreis = values.price * values.plt; sF('#listeneinkaufspreis');
|
||||||
|
values.fields.zieleinkaufspreis = gF('#listeneinkaufspreis') - gF('#listeneinkaufspreis') * values.percentage.discount/100; sF('#zieleinkaufspreis');
|
||||||
|
values.fields.bareinkaufspreis = gF('#zieleinkaufspreis') - gF('#zieleinkaufspreis') * values.percentage.cashDiscount/100; sF('#bareinkaufspreis');
|
||||||
|
values.fields.bezugspreis = gF('#bareinkaufspreis') - gF('#bareinkaufspreis') * values.percentage.procurementCosts/100; sF('#bezugspreis');
|
||||||
|
values.fields.selbstkosten = gF('.bezugspreis') + gF('.bezugspreis') * values.percentage.tradingCosts/100; sF('.selbstkosten');
|
||||||
|
|
||||||
|
values.fields.angebotspreis = gF('.selbstkosten') + gF('.selbstkosten')*values.percentage.profitMargin/100; sF('#angebotspreis');
|
||||||
|
values.fields.angebotspreis_mwst = gF('#angebotspreis') * 1.19; sF('#angebotspreis_mwst');
|
||||||
|
values.fields.angebotspreis_stk = gF('#angebotspreis_mwst') / values.plt; sF('#angebotspreis_stk');
|
||||||
|
values.fields.rohgewinn = gF('#angebotspreis') - gF('#bezugspreis'); sF('#rohgewinn');
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var pF = (fl) => {return parseFloat(fl)};
|
||||||
|
var sF = (id) => {
|
||||||
|
let elem = id;
|
||||||
|
id = id.substring(1);
|
||||||
|
if(values.fields[id]) $(elem).val(pF(values.fields[id]).toFixed(2));
|
||||||
|
};
|
||||||
|
var gF = (id) => {
|
||||||
|
id = id.substring(1);
|
||||||
|
if(values.fields[id]) return values.fields[id]; else return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
values.updateFields();
|
||||||
|
|
||||||
|
$('#products').change((e) => {
|
||||||
|
values.data = $('#products').val();
|
||||||
|
values.id = $('#products').val().split('|')[0];
|
||||||
|
values.price = $('#products').val().split('|')[1];
|
||||||
|
values.plt = $('#products').val().split('|')[2];
|
||||||
|
|
||||||
|
values.updateFields();
|
||||||
|
});
|
||||||
|
$('#rabatt').keyup((e) => { values.percentage.discount = $('#rabatt').val(); values.updateFields();});
|
||||||
|
$('#skonto').keyup((e) => { values.percentage.cashDiscount = $('#skonto').val(); values.updateFields();});
|
||||||
|
$('#bezugskosten').keyup((e) => { values.percentage.procurementCosts = $('#bezugskosten').val(); values.updateFields();});
|
||||||
|
$('#handelskosten').keyup((e) => { values.percentage.tradingCosts = $('#handelskosten').val(); values.updateFields();});
|
||||||
|
$('#gewinnzuschlag').keyup((e) => { values.percentage.profitMargin = $('#gewinnzuschlag').val(); values.updateFields();});
|
||||||
|
|
||||||
|
$('#konkurrenzpreis').keypress((e) => {
|
||||||
|
setTimeout(function () {
|
||||||
|
if($('#konkurrenzpreis').val().length > 0) {
|
||||||
|
$('#gewinn').val(pF($('#konkurrenzpreis').val()) - pF(gF('.selbstkosten')));
|
||||||
|
$('#gewinnPrcnt').val((100/pF(gF('.selbstkosten'))) * (pF($('#konkurrenzpreis').val()) - pF(gF('.selbstkosten'))));
|
||||||
|
} else {
|
||||||
|
$('#gewinn').val("0");
|
||||||
|
$('#gewinnPrcnt').val("0");
|
||||||
|
}
|
||||||
|
console.log($('#konkurrenzpreis').val(), gF('.selbstkosten'));
|
||||||
|
}, 30);
|
||||||
|
});
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
let rgb_values = [];
|
||||||
|
for (var r = 0; r < 255; r++) {
|
||||||
|
for (var g = 0; g < 255; g++) {
|
||||||
|
for (var b = 0; b < 255; b++) {
|
||||||
|
if(r+g+b >= 255) {
|
||||||
|
rgb_values.push([r, g, b]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(r === 254 && g === 254 && b == 254) console.log(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
356
webseite/public/js/custom.js
Normal file
356
webseite/public/js/custom.js
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
/**
|
||||||
|
* @TODO Documentation
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*Ertellen der Produkt Tabelle aus der Datenbank
|
||||||
|
*/
|
||||||
|
if (document.getElementById('produktTabelle'&& 'produkte')) {
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url: "/sven/api/article"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
|
||||||
|
var str = "";
|
||||||
|
var id = 1;
|
||||||
|
/*
|
||||||
|
* Erstellt einen String der die Tabelle beinhaltet
|
||||||
|
*/
|
||||||
|
str +='<table>';
|
||||||
|
str +='<thead>';
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<th>Produktnummer</th>';
|
||||||
|
str +='<th>Marke</th>';
|
||||||
|
str +='<th>Produktname</th>';
|
||||||
|
str +='<th>Preis</th>';
|
||||||
|
str +='</tr>';
|
||||||
|
str +='</thead>';
|
||||||
|
str +='<tbody>';
|
||||||
|
data.data.forEach(function(elem) {
|
||||||
|
//Durchläuft das Array als Schleife
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<td>'+elem.ID+'</td>';
|
||||||
|
str +='<td>'+elem.Marke+'</td>';
|
||||||
|
str +='<td>'+elem.Name+'</td>';
|
||||||
|
str +='<td>'+precisionRound(elem.Verkaufspreis, 2)+'€'+'</td>';
|
||||||
|
str +='</tr>';
|
||||||
|
});
|
||||||
|
str +='</tbody>';
|
||||||
|
str +='</table>';
|
||||||
|
$('#produktTabelle').html(str); //JQuerry
|
||||||
|
|
||||||
|
/*
|
||||||
|
*Füllt das Produkteingabefeld mit den vorhandenen Produkten
|
||||||
|
*/
|
||||||
|
var str_2 = "";
|
||||||
|
data.data.forEach(function(elem) {
|
||||||
|
str_2+='<option value='+elem.ID+'>'+elem.Name+'</option>';
|
||||||
|
});
|
||||||
|
$('#produkte').html(str_2); //JQuerry
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Produkttabelle');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*Funktion um die Werte von dem ausgewählten Produkt in den Graphen zu bringen
|
||||||
|
*/
|
||||||
|
if (document.getElementById('produkte')) {
|
||||||
|
var produkt_id = null;
|
||||||
|
$('#produkte').change(function(){
|
||||||
|
produkt_id = $(this).val()-1;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var daten_Menge;
|
||||||
|
function selectProduct(){
|
||||||
|
if(!produkt_id) return;
|
||||||
|
request({
|
||||||
|
url: "/sven/api/statistics"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
var series_2 = [];
|
||||||
|
var labels_2 = [];
|
||||||
|
data.data.forEach(function(item) {
|
||||||
|
if(item.f_Artikel_ID === produkt_id) {
|
||||||
|
labels_2.push(item.Woche);
|
||||||
|
series_2.push({x: item.Woche, y: item.Menge});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
daten_Menge = {labels: labels_2, series: [series_2]};
|
||||||
|
|
||||||
|
if (document.getElementById('chart2')) {
|
||||||
|
new Chartist.Bar('#chart2', daten_Menge, {
|
||||||
|
chartPadding: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 40,
|
||||||
|
left: 40
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
Chartist.plugins.ctAxisTitle({
|
||||||
|
axisX: {
|
||||||
|
axisTitle: 'Woche',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle'
|
||||||
|
},
|
||||||
|
axisY: {
|
||||||
|
axisTitle: 'Menge',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: -20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle',
|
||||||
|
flipTitle: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Produktgraphen');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
if (document.getElementById('chart2')) {
|
||||||
|
new Chartist.Bar('#chart2', daten_Menge);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Erstellt den 1. Graphen durch errechen der gesammt Menge die in der spezifischen Woche verkauft wurde
|
||||||
|
*/
|
||||||
|
if (document.getElementById('chart1')) {
|
||||||
|
var gesMengen_Daten;
|
||||||
|
request({
|
||||||
|
url: "/sven/api/statistics"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
var series_Menge = [];
|
||||||
|
var labels_Menge = [];
|
||||||
|
var Wochen = {};
|
||||||
|
data.data.forEach(function(item) {
|
||||||
|
item.Woche = parseInt(item.Woche);
|
||||||
|
if(!Wochen[item.Woche]) Wochen[item.Woche] = parseInt(item.Menge);
|
||||||
|
else Wochen[item.Woche] += parseInt(item.Menge);
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(Wochen).forEach(function(item) {
|
||||||
|
series_Menge.push(Wochen[item]);
|
||||||
|
});
|
||||||
|
labels_Menge =Object.keys(Wochen);
|
||||||
|
for(var i=0; i<labels_Menge.lenght;i++)
|
||||||
|
labels_Menge[i]="Woche"+labels_Menge[i];
|
||||||
|
var gesMengen_Daten = { labels: labels_Menge, series: [series_Menge]};
|
||||||
|
|
||||||
|
new Chartist.Bar('#chart1', gesMengen_Daten, {
|
||||||
|
chartPadding: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 40,
|
||||||
|
left: 40
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
Chartist.plugins.ctAxisTitle({
|
||||||
|
axisX: {
|
||||||
|
axisTitle: 'Woche',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle'
|
||||||
|
},
|
||||||
|
axisY: {
|
||||||
|
axisTitle: 'Menge',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: -20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle',
|
||||||
|
flipTitle: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Produktgraphen');
|
||||||
|
});
|
||||||
|
|
||||||
|
new Chartist.Bar('#chart1', daten_Menge);
|
||||||
|
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* Tabelle vom und fürs Lager
|
||||||
|
*/
|
||||||
|
if (document.getElementById('lagerTabelle')) {
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url: "/sven/api/stock",
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
if(data.data.length == 0) return;
|
||||||
|
|
||||||
|
var str = "";
|
||||||
|
var id = 1;
|
||||||
|
/*
|
||||||
|
* Erstellt einen String der die Tabelle beinhaltet
|
||||||
|
*/
|
||||||
|
str +='<table>';
|
||||||
|
str +='<thead>';
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<th>Lagerplatz</th>';
|
||||||
|
str +='<th>Produktname</th>';
|
||||||
|
str +='<th>Menge</th>';
|
||||||
|
str +='</tr>';
|
||||||
|
str +='</thead>';
|
||||||
|
str +='<tbody>';
|
||||||
|
data.data.forEach(function(elem) { //Durchläuft das Array als Schleife
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<td>'+elem.Lagerplatz+'</td>';
|
||||||
|
str +='<td>'+elem.f_Artikel_ID+'</td>';
|
||||||
|
str +='<td>'+elem.Menge+'</td>';
|
||||||
|
str +='</tr>';
|
||||||
|
});
|
||||||
|
str +='</tbody>';
|
||||||
|
str +='</table>';
|
||||||
|
$('#lagerTabelle').html(str); //JQuerry
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error lagerTabelle');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tabelle für erwartete Lieferungen
|
||||||
|
*/
|
||||||
|
if (document.getElementById('lieferTabelle')) {
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url: "/sven/api/stockDeliveries"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
if(data.data.length == 0) return;
|
||||||
|
var str = "";
|
||||||
|
var id = 1;
|
||||||
|
/*
|
||||||
|
* Erstellt einen String der die Tabelle beinhaltet
|
||||||
|
*/
|
||||||
|
str +='<table>';
|
||||||
|
str +='<thead>';
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<th>Bestellung</th>';
|
||||||
|
str +='<th>Produktname</th>';
|
||||||
|
str +='<th>Bestellte Menge</th>';
|
||||||
|
str +='<th>Ankunftsdatum</th>'
|
||||||
|
str +='</tr>';
|
||||||
|
str +='</thead>';
|
||||||
|
str +='<tbody>';
|
||||||
|
data.data.forEach(function(elem) { //Durchläuft das Array als Schleife
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<td>'+elem.ID+'</td>';
|
||||||
|
str +='<td>'+elem.f_ProduktID+'</td>';
|
||||||
|
str +='<td>'+elem.Menge+'</td>';
|
||||||
|
str +='<td>'+elem.Ankunftsdatum+'</td>';
|
||||||
|
str +='</tr>';
|
||||||
|
});
|
||||||
|
str +='</tbody>';
|
||||||
|
str +='</table>';
|
||||||
|
$('#lieferTabelle').html(str);
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Lieferungen');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function precisionRound(number, precision) {
|
||||||
|
return parseFloat(number).toFixed(precision);
|
||||||
|
};
|
||||||
|
|
||||||
|
function gewinnGraph() {
|
||||||
|
var gewinn = 0;
|
||||||
|
if(!produkt_id) return;
|
||||||
|
request(
|
||||||
|
{
|
||||||
|
type:"GET",
|
||||||
|
url:"/sven/api/article"
|
||||||
|
}, function(data){
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
console.log(data.data);
|
||||||
|
var series_2 = [];
|
||||||
|
var labels_2 = [];
|
||||||
|
|
||||||
|
gewinn = data.data[produkt_id].Rohgewinn / data.data[produkt_id].Anzahl_pro_Palette;
|
||||||
|
console.log(produkt_id, data.data[produkt_id].Rohgewinn, data.data[produkt_id].Anzahl_pro_Palette);
|
||||||
|
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url:"/sven/api/statistics"
|
||||||
|
}, function(data){
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
data.data.forEach(function(item) {
|
||||||
|
if(item.f_Artikel_ID === produkt_id) {
|
||||||
|
console.log(item);
|
||||||
|
labels_2.push(item.Woche);
|
||||||
|
series_2.push(gewinn);
|
||||||
|
|
||||||
|
daten_Menge = {labels: labels_2, series: [series_2]};
|
||||||
|
if (document.getElementById('chart2')) {
|
||||||
|
new Chartist.Bar('#chart2', daten_Menge, {
|
||||||
|
chartPadding: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 40,
|
||||||
|
left: 40
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
Chartist.plugins.ctAxisTitle({
|
||||||
|
axisX: {
|
||||||
|
axisTitle: 'Woche',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle'
|
||||||
|
},
|
||||||
|
axisY: {
|
||||||
|
axisTitle: 'Preis in €',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: -20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle',
|
||||||
|
flipTitle: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error 12');
|
||||||
|
});
|
||||||
|
};
|
41
webseite/public/js/deliveries.js
Normal file
41
webseite/public/js/deliveries.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (document.getElementById('lieferTabelle')) {
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url: "/sven/api/stockDeliveries"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
if(data.data.length == 0) return;
|
||||||
|
var str = "";
|
||||||
|
var id = 1;
|
||||||
|
/*
|
||||||
|
* Erstellt einen String der die Tabelle beinhaltet
|
||||||
|
*/
|
||||||
|
str +='<table>';
|
||||||
|
str +='<thead>';
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<th>Bestellung</th>';
|
||||||
|
str +='<th>Produktname</th>';
|
||||||
|
str +='<th>Bestellte Menge</th>';
|
||||||
|
str +='<th>Ankunftsdatum</th>'
|
||||||
|
str +='</tr>';
|
||||||
|
str +='</thead>';
|
||||||
|
str +='<tbody>';
|
||||||
|
data.data.forEach(function(elem) { //Durchläuft das Array als Schleife
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<td>'+elem.ID+'</td>';
|
||||||
|
str +='<td>'+elem.Name+'</td>';
|
||||||
|
str +='<td>'+elem.Menge+'</td>';
|
||||||
|
str +='<td>'+elem.Ankunftsdatum+'</td>';
|
||||||
|
str +='</tr>';
|
||||||
|
});
|
||||||
|
str +='</tbody>';
|
||||||
|
str +='</table>';
|
||||||
|
$('#lieferTabelle').html(str);
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Lieferungen');
|
||||||
|
});
|
||||||
|
};
|
48
webseite/public/js/index.js
Normal file
48
webseite/public/js/index.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
function precisionRound(number, precision) {
|
||||||
|
return parseFloat(number).toFixed(precision);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*Ertellen der Produkt Tabelle aus der Datenbank
|
||||||
|
*/
|
||||||
|
if(document.getElementById("produktTabelle"))
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url: "/sven/api/article"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
|
||||||
|
var str = "";
|
||||||
|
var id = 1;
|
||||||
|
/*
|
||||||
|
* Erstellt einen String der die Tabelle beinhaltet
|
||||||
|
*/
|
||||||
|
str +='<table>';
|
||||||
|
str +='<thead>';
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<th>Produktnummer</th>';
|
||||||
|
str +='<th>Marke</th>';
|
||||||
|
str +='<th>Produktname</th>';
|
||||||
|
str +='<th>Preis</th>';
|
||||||
|
str +='</tr>';
|
||||||
|
str +='</thead>';
|
||||||
|
str +='<tbody>';
|
||||||
|
data.data.forEach(function(elem) {
|
||||||
|
//Durchläuft das Array als Schleife
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<td>'+elem.ID+'</td>';
|
||||||
|
str +='<td>'+elem.Marke+'</td>';
|
||||||
|
str +='<td>'+elem.Name+'</td>';
|
||||||
|
str +='<td>'+precisionRound(elem.Verkaufspreis, 2)+'€'+'</td>';
|
||||||
|
str +='</tr>';
|
||||||
|
});
|
||||||
|
str +='</tbody>';
|
||||||
|
str +='</table>';
|
||||||
|
$('#produktTabelle').html(str); //JQuerry
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Produkttabelle');
|
||||||
|
});
|
23
webseite/public/js/login.js
Normal file
23
webseite/public/js/login.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
'use strict';
|
||||||
|
$('form[name="login"]').submit(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var formData = $('form[name="login"]').serializeArray().reduce(function(obj, item) {
|
||||||
|
obj[item.name] = item.value;
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
request({
|
||||||
|
url: "/sven/api/auth",
|
||||||
|
data: {
|
||||||
|
"type": "login",
|
||||||
|
"user": formData.loginUser,
|
||||||
|
"pass": formData.loginPass,
|
||||||
|
"csrf": formData.csrf_token
|
||||||
|
}
|
||||||
|
}, function(data) {
|
||||||
|
console.log(data.status, data);
|
||||||
|
document.location = "./";
|
||||||
|
}, function(data) {
|
||||||
|
console.log(data.status, data.responseJSON);
|
||||||
|
});
|
||||||
|
});
|
9
webseite/public/js/navbar.js
Normal file
9
webseite/public/js/navbar.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Bennet Kahrs
|
||||||
|
'use strict';
|
||||||
|
$(document).ready(function() {
|
||||||
|
for (var elem of $('ul.nav > li > a')) {
|
||||||
|
if(elem.href === window.location.href) {
|
||||||
|
$(elem).addClass("active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
223
webseite/public/js/stats.js
Normal file
223
webseite/public/js/stats.js
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var produkt_id = null;
|
||||||
|
|
||||||
|
if (document.getElementById('produkte')) {
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url: "/sven/api/article"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
/*
|
||||||
|
*Füllt das Produkteingabefeld mit den vorhandenen Produkten
|
||||||
|
*/
|
||||||
|
var str_2 = "";
|
||||||
|
data.data.forEach(function(elem) {
|
||||||
|
str_2+='<option value='+elem.ID+'>'+elem.Name+'</option>';
|
||||||
|
});
|
||||||
|
$('#produkte').html(str_2); //JQuerry
|
||||||
|
}, function(data) {});
|
||||||
|
$('#produkte').change(function(){
|
||||||
|
produkt_id = $(this).val();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var gesMengen_Daten;
|
||||||
|
if (document.getElementById('chart1')) {
|
||||||
|
request({
|
||||||
|
url: "/sven/api/salesFigures"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
|
||||||
|
var series_Menge = [];
|
||||||
|
var labels_Menge = [];
|
||||||
|
var Wochen = {};
|
||||||
|
data.data.forEach(function(item) {
|
||||||
|
item.Woche = parseInt(item.Woche);
|
||||||
|
if(!Wochen[item.Woche]){
|
||||||
|
Wochen[item.Woche] = parseInt(item.Menge);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Wochen[item.Woche] += parseInt(item.Menge);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(Wochen).forEach(function(item) {
|
||||||
|
series_Menge.push(Wochen[item]);
|
||||||
|
});
|
||||||
|
labels_Menge =Object.keys(Wochen);
|
||||||
|
|
||||||
|
gesMengen_Daten = { labels: labels_Menge, series: [series_Menge]};
|
||||||
|
new Chartist.Bar('#chart1', gesMengen_Daten, {
|
||||||
|
chartPadding: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 40,
|
||||||
|
left: 40
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
Chartist.plugins.ctAxisTitle({
|
||||||
|
axisX: {
|
||||||
|
axisTitle: 'Woche',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 40
|
||||||
|
},
|
||||||
|
textAnchor: 'middle'
|
||||||
|
},
|
||||||
|
axisY: {
|
||||||
|
axisTitle: 'Menge',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: -20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle',
|
||||||
|
flipTitle: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Produktgraphen');
|
||||||
|
});
|
||||||
|
|
||||||
|
new Chartist.Bar('#chart1', daten_Menge);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var daten_Menge;
|
||||||
|
function selectProduct(){
|
||||||
|
if(produkt_id === null) return;
|
||||||
|
|
||||||
|
request({
|
||||||
|
url: "/sven/api/salesFigures"
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
var series_2 = [];
|
||||||
|
var labels_2 = [];
|
||||||
|
data.data.forEach(function(item) {
|
||||||
|
if(item.f_Artikel_ID === produkt_id) {
|
||||||
|
labels_2.push(item.Woche);
|
||||||
|
series_2.push({x: item.Woche, y: item.Menge});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
daten_Menge = {labels: labels_2, series: [series_2]};
|
||||||
|
|
||||||
|
if (document.getElementById('chart2')) {
|
||||||
|
new Chartist.Bar('#chart2', daten_Menge, {
|
||||||
|
chartPadding: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 40,
|
||||||
|
left: 40
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
Chartist.plugins.ctAxisTitle({
|
||||||
|
axisX: {
|
||||||
|
axisTitle: 'Woche',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 40
|
||||||
|
},
|
||||||
|
textAnchor: 'middle'
|
||||||
|
},
|
||||||
|
axisY: {
|
||||||
|
axisTitle: 'Menge',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: -20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle',
|
||||||
|
flipTitle: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error Produktgraphen');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (document.getElementById('chart2')) {
|
||||||
|
new Chartist.Bar('#chart2', daten_Menge);
|
||||||
|
};
|
||||||
|
|
||||||
|
function gewinnGraph() {
|
||||||
|
var gewinn = 0;
|
||||||
|
if(!produkt_id) return;
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url:"/sven/api/article"
|
||||||
|
}, function(data){
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
console.log(data.data);
|
||||||
|
var series_2 = [];
|
||||||
|
var labels_2 = [];
|
||||||
|
|
||||||
|
gewinn = data.data[produkt_id-1].Rohgewinn / data.data[produkt_id-1].Anzahl_pro_Palette;
|
||||||
|
console.log(produkt_id, data.data[produkt_id-1].Rohgewinn, data.data[produkt_id-1].Anzahl_pro_Palette);
|
||||||
|
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url:"/sven/api/salesFigures"
|
||||||
|
}, function(data){
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
data.data.forEach(function(item) {
|
||||||
|
if(item.f_Artikel_ID === produkt_id) {
|
||||||
|
console.log(item);
|
||||||
|
labels_2.push(item.Woche);
|
||||||
|
series_2.push(gewinn * item.Menge);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
daten_Menge = {labels: labels_2, series: [series_2]};
|
||||||
|
|
||||||
|
if (document.getElementById('chart2')) {
|
||||||
|
new Chartist.Line('#chart2', daten_Menge, {showArea:true}, {
|
||||||
|
chartPadding: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 40,
|
||||||
|
left: 40
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
Chartist.plugins.ctAxisTitle({
|
||||||
|
axisX: {
|
||||||
|
axisTitle: 'Woche',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 40
|
||||||
|
},
|
||||||
|
textAnchor: 'middle'
|
||||||
|
},
|
||||||
|
axisY: {
|
||||||
|
axisTitle: 'Preis in €',
|
||||||
|
axisClass: 'ct-axis-title',
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: -20
|
||||||
|
},
|
||||||
|
textAnchor: 'middle',
|
||||||
|
flipTitle: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error 12');
|
||||||
|
});
|
||||||
|
})};
|
40
webseite/public/js/stock.js
Normal file
40
webseite/public/js/stock.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (document.getElementById('lagerTabelle')) {
|
||||||
|
request({
|
||||||
|
type:"GET",
|
||||||
|
url: "/sven/api/stock",
|
||||||
|
}, function (data) {
|
||||||
|
data.data = data.data.DATA;
|
||||||
|
if(data.data.length == 0) return;
|
||||||
|
|
||||||
|
var str = "";
|
||||||
|
var id = 1;
|
||||||
|
/*
|
||||||
|
* Erstellt einen String der die Tabelle beinhaltet
|
||||||
|
*/
|
||||||
|
str +='<table>';
|
||||||
|
str +='<thead>';
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<th>Lagerplatz</th>';
|
||||||
|
str +='<th>Produktname</th>';
|
||||||
|
str +='<th>Menge</th>';
|
||||||
|
str +='</tr>';
|
||||||
|
str +='</thead>';
|
||||||
|
str +='<tbody>';
|
||||||
|
data.data.forEach(function(elem) { //Durchläuft das Array als Schleife
|
||||||
|
str +='<tr>';
|
||||||
|
str +='<td>'+elem.Lagerplatz+'</td>';
|
||||||
|
str +='<td>'+elem.Name+'</td>';
|
||||||
|
str +='<td>'+elem.Menge+'</td>';
|
||||||
|
str +='</tr>';
|
||||||
|
});
|
||||||
|
str +='</tbody>';
|
||||||
|
str +='</table>';
|
||||||
|
$('#lagerTabelle').html(str); //JQuerry
|
||||||
|
|
||||||
|
}, function (data) {
|
||||||
|
console.log(data);
|
||||||
|
console.log('Error lagerTabelle');
|
||||||
|
});
|
||||||
|
};
|
50
webseite/public/js/users.js
Normal file
50
webseite/public/js/users.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
'use strict';
|
||||||
|
if($('#users_page').length) {
|
||||||
|
$('#modalChangePassword').on('show.bs.modal', function (e) {
|
||||||
|
let button = $(e.relatedTarget);
|
||||||
|
let user = button.data('user');
|
||||||
|
let modal = $(this);
|
||||||
|
modal.find('.m-cp-span-user').text(user);
|
||||||
|
modal.find('input#change_username').val(user);
|
||||||
|
//modal.find('.modal-body input').val(recipient);
|
||||||
|
});
|
||||||
|
$('#modalDeleteUser').on('show.bs.modal', function (e) {
|
||||||
|
let button = $(e.relatedTarget);
|
||||||
|
let user = button.data('user');
|
||||||
|
let modal = $(this);
|
||||||
|
modal.find('.m-du-span-user').text(user);
|
||||||
|
modal.find('input#del_username').val(user);
|
||||||
|
//modal.find('.modal-body input').val(recipient);
|
||||||
|
});
|
||||||
|
$('#m_cp_form').submit((e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#m_au_form').submit((e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let form = $('#m_au_form');
|
||||||
|
let formData = FormToObject(form);
|
||||||
|
request({
|
||||||
|
url: "/sven/api/auth",
|
||||||
|
data: {
|
||||||
|
"type": "login",
|
||||||
|
"user": formData.username,
|
||||||
|
"pass": formData.password
|
||||||
|
}
|
||||||
|
}, function(data) {
|
||||||
|
console.log(data.status, data);
|
||||||
|
document.location = "./";
|
||||||
|
}, function(data) {
|
||||||
|
console.log(data.status, data.responseJSON);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var FormToObject = (elem) => {
|
||||||
|
let data = elem.serializeArray();
|
||||||
|
let output = {};
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
output[data[i]['name']] = data[i]['value'];
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
};
|
||||||
|
}
|
44
webseite/sys/Exception.class.php
Normal file
44
webseite/sys/Exception.class.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// namespace
|
||||||
|
namespace sven\sys;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception
|
||||||
|
*
|
||||||
|
* Custom Exception Handler
|
||||||
|
*
|
||||||
|
* @package sven\sys
|
||||||
|
* @copyright 2018 Ruben Meyer
|
||||||
|
* @author Ruben Meyer <contact@rxbn.de>
|
||||||
|
* @version 0.1.0
|
||||||
|
* @see http://php.net/manual/en/class.exception.php <Documentation>
|
||||||
|
* @TODO Comments
|
||||||
|
*/
|
||||||
|
class Exception extends \Exception {
|
||||||
|
|
||||||
|
private $title;
|
||||||
|
|
||||||
|
public function __construct($title, $message = null, $code = 0, \Exception $previous = null) {
|
||||||
|
\sven\sys\core::addReplacement("head", "TITLE", "Exception", true);
|
||||||
|
if(func_get_args()[0] instanceof \Exception) {
|
||||||
|
$e = func_get_args()[0];
|
||||||
|
$this->title = get_class($e);
|
||||||
|
|
||||||
|
$code = (gettype($e->getCode()) === "integer") ? $e->getCode() : $code;
|
||||||
|
|
||||||
|
parent::__construct($e->getMessage(), $code, $e);
|
||||||
|
} else {
|
||||||
|
$this->title = $title;
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
36
webseite/sys/autoload.php
Normal file
36
webseite/sys/autoload.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
namespace sven\sys;
|
||||||
|
/**
|
||||||
|
* Autoloader
|
||||||
|
*
|
||||||
|
* A simple autoloader that loads class files recursively starting in the directory
|
||||||
|
* where this class resides.
|
||||||
|
*
|
||||||
|
* @todo lel
|
||||||
|
* @package sven\sys
|
||||||
|
* @copyright 2018 Ruben Meyer
|
||||||
|
* @author Ruben Meyer <contact@rxbn.de>
|
||||||
|
* @version 0.1.0
|
||||||
|
* @see http://php.net/manual/en/language.oop5.autoload.php <Documentation>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Autoloader {
|
||||||
|
public static function register() {
|
||||||
|
spl_autoload_register(
|
||||||
|
function($class) {
|
||||||
|
$file = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $class).'.class.php';
|
||||||
|
if(substr($file, 0, 5) == 'sven\\') $file = substr($file, 5);
|
||||||
|
|
||||||
|
if(!class_exists($class) && file_exists($file)) {
|
||||||
|
require $file;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Autoloader::register();
|
||||||
|
?>
|
420
webseite/sys/core.class.php
Normal file
420
webseite/sys/core.class.php
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
<?php
|
||||||
|
// namespace
|
||||||
|
namespace sven\sys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* core
|
||||||
|
*
|
||||||
|
* This is the core class to connect all classes to a homogeneous system
|
||||||
|
*
|
||||||
|
* @package sven\sys
|
||||||
|
* @copyright 2018 Ruben Meyer
|
||||||
|
* @author Ruben Meyer <contact@rxbn.de>
|
||||||
|
* @version 0.1.0
|
||||||
|
* @TODO Comments
|
||||||
|
*/
|
||||||
|
class core {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* needLogin
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
private static $needLogin = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setLogin
|
||||||
|
*
|
||||||
|
* sets login access
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param boolean $boolean boolean to set
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function setLogin($boolean) {
|
||||||
|
self::$needLogin = (boolean) $boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getLogin
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function getLogin() {
|
||||||
|
return self::$needLogin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ////// //////// //////// ////// // // //////// //////// ////////
|
||||||
|
* // // // // // // // // // // // // //
|
||||||
|
* ////// // // //////// ////// // // //////// //////// ////////
|
||||||
|
* // //////// // // // // // // // // // //
|
||||||
|
* // // // //////// ////// /// // // // // ////////
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* exception_categories
|
||||||
|
*
|
||||||
|
* Categories which will get imported when an exception was thrown
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $exception_categories = ['head', 'header', 'footer', 'foot'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* exceptions
|
||||||
|
*
|
||||||
|
* all thrown exceptions
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $exceptions = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* templates
|
||||||
|
*
|
||||||
|
* template array
|
||||||
|
*
|
||||||
|
* [
|
||||||
|
* 'name' => string, ....
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var array|null
|
||||||
|
*/
|
||||||
|
private static $templates = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replacements
|
||||||
|
*
|
||||||
|
* replacements array
|
||||||
|
*
|
||||||
|
* [
|
||||||
|
* 'template' => [
|
||||||
|
* 'key' => 'value',
|
||||||
|
* ...
|
||||||
|
* ],
|
||||||
|
* ...
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var array|null
|
||||||
|
*/
|
||||||
|
private static $replacements = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configurations
|
||||||
|
*
|
||||||
|
* page configuration
|
||||||
|
*
|
||||||
|
* [
|
||||||
|
* 'index' => [ //refers to 'pages/index'
|
||||||
|
* 'key' => 'value',
|
||||||
|
* ...
|
||||||
|
* ],
|
||||||
|
* ...
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $configurations = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ////// /////// // // // //////// ////// //////
|
||||||
|
* // // // // // // // // // // // //
|
||||||
|
* ////// ////// // // // //////// ////// //////
|
||||||
|
* // // // // // // // // // // //
|
||||||
|
* // // // // ////// // // // // //////
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apiOutput
|
||||||
|
*
|
||||||
|
* api output array (convertable to json and xml)
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $apiOutput = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addException
|
||||||
|
*
|
||||||
|
* adds an Exception
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param \Exception $exception Throwable Exception
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function addException($exception) {
|
||||||
|
array_push(self::$exceptions, $exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* countExceptions
|
||||||
|
*
|
||||||
|
* counts Exceptions
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function countExceptions() {
|
||||||
|
return count(self::$exceptions)||0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getExceptions
|
||||||
|
*
|
||||||
|
* gets all Exceptions
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return \Exception[]
|
||||||
|
*/
|
||||||
|
public static function getExceptions() {
|
||||||
|
return self::$exceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getExceptions
|
||||||
|
*
|
||||||
|
* adds an Replacement for $category
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param string $category Category
|
||||||
|
* @param string $text Placeholder
|
||||||
|
* @param string $replace Replacement
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function addReplacement($category, $text, $replace, $replacePrevious = false) {
|
||||||
|
$auth = new \sven\sys\security\auth;
|
||||||
|
if($auth->loggedIn() || (!$auth->loggedIn() && $category !== 'head')) {
|
||||||
|
if(!is_array(self::$replacements)) self::$replacements = [];
|
||||||
|
if(!in_array($category, array_keys(self::$replacements))) self::$replacements[$category] = [];
|
||||||
|
if(!isset(self::$replacements[$category][$text]) || $replacePrevious) self::$replacements[$category][$text] = $replace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getReplacements
|
||||||
|
*
|
||||||
|
* gets all Replacements
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getReplacements() {
|
||||||
|
return self::$replacements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addTemplate
|
||||||
|
*
|
||||||
|
* adds a Template
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param string $category Name
|
||||||
|
* @param string $string Template
|
||||||
|
* @param boolean $overwrite overwrite (default=false) (Optional)
|
||||||
|
* @return boolean State of adding the template
|
||||||
|
*/
|
||||||
|
public static function addTemplate($category, $string, $overwrite = false) {
|
||||||
|
if(!is_array(self::$templates)) self::$templates = [];
|
||||||
|
if( in_array($category, array_keys(self::$templates)) && $overwrite === true
|
||||||
|
|| !in_array($category, array_keys(self::$templates))) {
|
||||||
|
self::$templates[$category] = $string;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getTemplates
|
||||||
|
*
|
||||||
|
* gets all Templates
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public static function getTemplates() {
|
||||||
|
return self::$templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getOutput
|
||||||
|
*
|
||||||
|
* gets output for the page
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param array $order order or/and templates which get implemented
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getOutput($order = ['head', 'header', 'exception', 'main', 'footer', 'foot']) {
|
||||||
|
if(is_array(self::$templates)) {
|
||||||
|
$auth = new \sven\sys\security\auth;
|
||||||
|
if(!$auth->loggedIn()) self::$replacements['head']['TITLE'] = 'Please Login';
|
||||||
|
|
||||||
|
// replacing with variables
|
||||||
|
$parsing = "";
|
||||||
|
$replacements = self::getReplacements();
|
||||||
|
$replaced_templates = [];
|
||||||
|
foreach (self::$templates as $key => $value) {
|
||||||
|
$temp_output = $value;
|
||||||
|
if(is_array($replacements) && in_array($key, array_keys($replacements))) {
|
||||||
|
foreach ($replacements[$key] as $item => $data) {
|
||||||
|
$placeholder = '%%'.$key.'_'.$item.'%%';
|
||||||
|
if(strpos($temp_output, $placeholder) !== false) {
|
||||||
|
$temp_output = str_replace($placeholder, $data, $temp_output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// checking if key is not exception to prevent default template output of exception
|
||||||
|
if($key !== "exception")
|
||||||
|
$replaced_templates[$key] = $temp_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// replacing common replacements ($replacement_category = 'all')
|
||||||
|
foreach ($replaced_templates as $key => $value) {
|
||||||
|
if(isset($replacements["all"]) && is_array($replacements["all"])) foreach ($replacements["all"] as $item => $data) {
|
||||||
|
$placeholder = '%%'.$item.'%%';
|
||||||
|
if(strpos($value, $placeholder) !== false) {
|
||||||
|
$replaced_templates[$key] = str_replace($placeholder, $data, $replaced_templates[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i=0; $i < count($order); $i++) {
|
||||||
|
if($order[$i] === "main" && !$auth->loggedIn() && self::$needLogin) {
|
||||||
|
$replaced_templates["main"] = self::getTemplates()["login_msg"];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exception handling if exceptions were thrown
|
||||||
|
if($order[$i] === "exception" && self::getExceptions()) {
|
||||||
|
$replaced_templates["exception"] = "";
|
||||||
|
$error_template = self::getTemplates()['exception'];
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$startTag = "%%repeat_START%%";
|
||||||
|
$endTag = "%%repeat_END%%";
|
||||||
|
$start = strpos($error_template, $startTag);
|
||||||
|
$end = strpos($error_template, $endTag);
|
||||||
|
$template = \sven\sys\sven\utilities::getBetween($error_template, $startTag, $endTag);
|
||||||
|
foreach (self::getExceptions() as $exception) {
|
||||||
|
$tempException = $template;
|
||||||
|
$tempException = str_replace('%%exception_title%%', trim($exception->getTitle(), "\n\r\t"), $tempException);
|
||||||
|
$tempException = str_replace('%%exception_code%%', trim($exception->getCode(), "\n\r\t"), $tempException);
|
||||||
|
$tempException = str_replace('%%exception_message%%', trim($exception->getMessage(), "\n\r\t"), $tempException);
|
||||||
|
print_r($tempException);
|
||||||
|
}
|
||||||
|
$data = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
//$data = substr($data, 0, strlen($endTag));
|
||||||
|
|
||||||
|
//replace the normal main part
|
||||||
|
$replaced_templates["exception"] .= "\n".substr_replace($error_template, $data, $start, $end-$start+strlen($endTag));
|
||||||
|
}
|
||||||
|
|
||||||
|
//adding replaced content to output
|
||||||
|
if(in_array($order[$i], array_keys($replaced_templates))) {
|
||||||
|
$parsing .= $replaced_templates[$order[$i]]."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $parsing;
|
||||||
|
}
|
||||||
|
|
||||||
|
//no templates found
|
||||||
|
else return "ERROR 500 - \sven\sys\core::getOutput()";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rawApiOutput
|
||||||
|
*
|
||||||
|
* returns self::$apiOutput
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return mixed[]
|
||||||
|
*/
|
||||||
|
public static function rawApiOutput() {
|
||||||
|
return self::$apiOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replaceApiOutput
|
||||||
|
*
|
||||||
|
* replaces api output with $api
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param mixed[] $api api array
|
||||||
|
*/
|
||||||
|
public static function replaceApiOutput($api) {
|
||||||
|
if($api === null || $api === false) {
|
||||||
|
$api = (object) [
|
||||||
|
"msg" => "Request method not supported. See README.md for supported methods",
|
||||||
|
"error" => ["REQUEST_METHOD_NOT_SUPPORTED"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
self::$apiOutput = $api;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getApiOutput
|
||||||
|
*
|
||||||
|
* gets output for api usage
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param string $type "json" or "xml"
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getApiOutput($type='json') {
|
||||||
|
if(!isset(self::$apiOutput->state)) self::$apiOutput->state = "failed";
|
||||||
|
|
||||||
|
if(self::getExceptions()) {
|
||||||
|
self::$apiOutput->state = "failed";
|
||||||
|
self::$apiOutput->exceptions = [];
|
||||||
|
foreach (self::getExceptions() as $exception) {
|
||||||
|
$arr = [
|
||||||
|
"title" => $exception->getTitle(),
|
||||||
|
"message" => $exception->getMessage(),
|
||||||
|
"code" => $exception->getCode()
|
||||||
|
];
|
||||||
|
self::$apiOutput->exceptions[] = $arr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(self::$apiOutput->access === "denied" && self::$apiOutput->state === "failed") http_response_code(401);
|
||||||
|
elseif(self::$apiOutput->state === "failed") http_response_code(400);
|
||||||
|
|
||||||
|
if($type == "json") {
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
return json_encode(self::$apiOutput, JSON_PRETTY_PRINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
171
webseite/sys/mysql/mysql.class.php
Normal file
171
webseite/sys/mysql/mysql.class.php
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
<?php
|
||||||
|
// namespace
|
||||||
|
namespace sven\sys\mysql;
|
||||||
|
|
||||||
|
// required library
|
||||||
|
|
||||||
|
$dir = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, dirname(__FILE__)."/../sources/envms-fluentpdo/src/");
|
||||||
|
|
||||||
|
if(file_exists($dir)) {
|
||||||
|
//prebuilt directory files to serve classes faster
|
||||||
|
$files = [
|
||||||
|
$dir.'Query.php', $dir.'Literal.php', $dir.'Structure.php', $dir.'Utilities.php', $dir.'Queries\Base.php', $dir.'Queries\Common.php', $dir.'Queries\Delete.php', $dir.'Queries\Insert.php', $dir.'Queries\Select.php', $dir.'Queries\Update.php'
|
||||||
|
];
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if(file_exists($file))
|
||||||
|
require_once($file);
|
||||||
|
else
|
||||||
|
return \sven\sys\core::addException(new \sven\sys\Exception("ERROR: Files not found", "SQL Query Builder was not found ({$file})", 404));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else return \sven\sys\core::addException(new \sven\sys\Exception("ERROR: Files not found", "SQL Query Builder was not found", 404));
|
||||||
|
unset($dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mysql
|
||||||
|
*
|
||||||
|
* mysql.class uses PDO to connect to our database and handle requests
|
||||||
|
* and a SQL Query Builder to get some handsome code
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
* $db = new \sven\sys\mysql();
|
||||||
|
* $output = $db->select('*', 'users', 'ID=4');
|
||||||
|
* var_dump($output);
|
||||||
|
*
|
||||||
|
* @package sven\sys\mysql
|
||||||
|
* @copyright 2018 Ruben Meyer
|
||||||
|
* @author Ruben Meyer <contact@rxbn.de>
|
||||||
|
* @version 0.1.0
|
||||||
|
* @see https://github.com/envms/fluentpdo <query builder>
|
||||||
|
* @see http://php.net/manual/de/class.pdo.php <PDO>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class mysql {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* instance
|
||||||
|
*
|
||||||
|
* Instance
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var resource (new self();)
|
||||||
|
*/
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connection
|
||||||
|
*
|
||||||
|
* PDO Connection
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var object|null Should contain the database connection
|
||||||
|
*/
|
||||||
|
private static $connection = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __construct
|
||||||
|
*
|
||||||
|
* Class constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
self::$instance = $this;
|
||||||
|
$this->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __destruct
|
||||||
|
*
|
||||||
|
* Class destructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __destruct() { $this->disconnect(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getInstance
|
||||||
|
*
|
||||||
|
* returns Instance
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public static function getInstance() {
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getBuilder
|
||||||
|
*
|
||||||
|
* returns SQL Builder to query
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return \Envms\FluentPDO\Query|\sven\sys\sven\uncallable
|
||||||
|
*/
|
||||||
|
public function getBuilder() {
|
||||||
|
if(self::$connection !== null) return new \Envms\FluentPDO\Query(self::$connection);
|
||||||
|
else {
|
||||||
|
\sven\sys\core::addException(new \sven\sys\Exception("Exception", "Error: MySQL \$connection is NULL", 2002));
|
||||||
|
return new \sven\sys\sven\uncallable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connect
|
||||||
|
*
|
||||||
|
* connects to our database
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function connect() {
|
||||||
|
if(self::$connection) return;
|
||||||
|
if(php_uname('r') === "6.1") {
|
||||||
|
//if(false) {
|
||||||
|
// development place @ school
|
||||||
|
$data = (object) [
|
||||||
|
'host' => '102-012',
|
||||||
|
'user' => 'intabi19',
|
||||||
|
'pass' => 'hallo',
|
||||||
|
'db' => 'sven'
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// development place @ home
|
||||||
|
$data = (object) [
|
||||||
|
'host' => '127.0.0.1',
|
||||||
|
'user' => 'root',
|
||||||
|
'pass' => '',
|
||||||
|
'db' => 'sven'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if(mysqli_connect($data->host, $data->user, $data->pass)) {
|
||||||
|
self::$connection = new \PDO('mysql:host='.$data->host.';dbname='.$data->db.';charset=utf8mb4', $data->user, $data->pass);
|
||||||
|
self::$connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
|
self::$connection->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
\sven\sys\core::addException(new \sven\sys\Exception($e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disconnect
|
||||||
|
*
|
||||||
|
* closes connection
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function disconnect() {
|
||||||
|
if(gettype(self::$connection) == "object") self::$connection = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
149
webseite/sys/security/auth.class.php
Normal file
149
webseite/sys/security/auth.class.php
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<?php
|
||||||
|
// namespace
|
||||||
|
namespace sven\sys\security;
|
||||||
|
|
||||||
|
|
||||||
|
use \sven\sys\sven as sven;
|
||||||
|
use \sven\sys\mysql\mysql as mysql;
|
||||||
|
use \sven\sys\core as CORE;
|
||||||
|
use \Lcobucci\JWT\Builder as JWT_Builder;
|
||||||
|
use \Lcobucci\JWT\Signer\Hmac\Sha256 as JWT_Sha256;
|
||||||
|
use \Lcobucci\JWT\ValidationData as JWT_Validation;
|
||||||
|
use \Lcobucci\JWT\Parser as JWT_Parser;
|
||||||
|
|
||||||
|
$dir = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, dirname(__FILE__)."/../sources/jwt/src/");
|
||||||
|
if(file_exists($dir)) {
|
||||||
|
$files = [
|
||||||
|
$dir.'Claim.php', $dir.'Claim\Validatable.php', $dir.'Parser.php', $dir.'Builder.php', $dir.'Signer.php', $dir.'Token.php', $dir.'ValidationData.php', $dir.'Claim\Basic.php', $dir.'Claim\EqualsTo.php', $dir.'Claim\Factory.php', $dir.'Claim\GreaterOrEqualsTo.php', $dir.'Claim\LesserOrEqualsTo.php',
|
||||||
|
$dir.'Parsing\Decoder.php', $dir.'Parsing\Encoder.php', $dir.'Signature.php', $dir.'Signer\BaseSigner.php',
|
||||||
|
$dir.'Signer\Ecdsa\KeyParser.php', $dir.'Signer\Ecdsa.php', $dir.'Signer\Ecdsa\Sha256.php', $dir.'Signer\Ecdsa\Sha384.php', $dir.'Signer\Ecdsa\Sha512.php',
|
||||||
|
$dir.'Signer\Hmac.php', $dir.'Signer\Hmac\Sha256.php', $dir.'Signer\Hmac\Sha384.php', $dir.'Signer\Hmac\Sha512.php',
|
||||||
|
$dir.'Signer\Key.php', $dir.'Signer\Keychain.php',
|
||||||
|
$dir.'Signer\Rsa.php', $dir.'Signer\Rsa\Sha256.php', $dir.'Signer\Rsa\Sha384.php', $dir.'Signer\Rsa\Sha512.php'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if(file_exists($file)) {
|
||||||
|
require_once($file);
|
||||||
|
} else
|
||||||
|
return \sven\sys\core::addException(new \sven\sys\Exception("ERROR: Files not found", "JWT Library was not found ({$file})", 404));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return \sven\sys\core::addException(new \sven\sys\Exception("ERROR: Files not found", "JWT Library was not found", 404));
|
||||||
|
}
|
||||||
|
unset($dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* auth
|
||||||
|
*
|
||||||
|
* Authentication class
|
||||||
|
*
|
||||||
|
* @package sven\sys\security
|
||||||
|
* @copyright 2018 Ruben Meyer
|
||||||
|
* @author Ruben Meyer <contact@rxbn.de>
|
||||||
|
* @version 0.1.0
|
||||||
|
* @TODO Documentation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class auth {
|
||||||
|
|
||||||
|
private const TOKEN_SIGNATURE = "5641189c6596892b8b03a8d939803747";
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$mysql = new mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) === "sven\sys\sven\uncallable") {
|
||||||
|
CORE::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loggedIn() {
|
||||||
|
$cookie = new cookie();
|
||||||
|
$body = \sven\sys\sven\web::getRequestBody();
|
||||||
|
|
||||||
|
$token = ($cookie->read("JWT_SVEN") ? $cookie->read("JWT_SVEN") : null);
|
||||||
|
if($token) {
|
||||||
|
if($cookie->read("JWT_SVEN") || $token) {
|
||||||
|
$token = (new JWT_Parser())->parse((string) $token);
|
||||||
|
|
||||||
|
$signer = new JWT_Sha256;
|
||||||
|
return $token->verify($signer, self::TOKEN_SIGNATURE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(isset($user) && isset($pass))
|
||||||
|
return $this->verifyLogin($user, $pass);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyLogin($username, $password) {
|
||||||
|
$mysql = new mysql();
|
||||||
|
$fluent = $mysql->getBuilder();
|
||||||
|
if(get_class($fluent) !== "sven\sys\sven\uncallable") {
|
||||||
|
$query = $fluent->from('t_benutzer')->select('t_benutzer.*')->where("Name = ?", $username);
|
||||||
|
$data = $query->fetch();
|
||||||
|
|
||||||
|
if($data && $this->verifyPassword($password, $data->Passwort)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CORE::addException(new \sven\sys\Exception("\sven\sys\sven\uncallable", "Can't find/use FluentPDO"));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function login($username) {
|
||||||
|
$session = new session();
|
||||||
|
$session->write('auth_username', $username);
|
||||||
|
$session->write('auth_ip', $_SERVER['REMOTE_ADDR']);
|
||||||
|
|
||||||
|
$signer = new JWT_Sha256;
|
||||||
|
|
||||||
|
$time = time();
|
||||||
|
$token = (new JWT_Builder())->setIssuer('https://rxbn.de')
|
||||||
|
->setAudience('http://eps.local')
|
||||||
|
->setId('4f1g26a1aba', true)
|
||||||
|
->setIssuedAt($time)
|
||||||
|
->setNotBefore($time+60)
|
||||||
|
->setExpiration($time+60*60)
|
||||||
|
->set('username', $username)
|
||||||
|
->sign($signer, self::TOKEN_SIGNATURE)
|
||||||
|
->getToken();
|
||||||
|
|
||||||
|
$cookie = new cookie();
|
||||||
|
$cookie->write('JWT_SVEN', (string) $token);
|
||||||
|
return (string) $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logout() {
|
||||||
|
$cookie = new cookie();
|
||||||
|
$cookie->drop();
|
||||||
|
$session = new session();
|
||||||
|
$session->drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createCSRF($form_name) {
|
||||||
|
$token = bin2hex(random_bytes(32));
|
||||||
|
$session = new session();
|
||||||
|
$session->write('csrf_form_'.$form_name, $token);
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateCSRF($form_name, $token) {
|
||||||
|
$session = new session();
|
||||||
|
return hash_equals($session->read('csrf_form_'.$form_name), $token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hashPassword($password) {
|
||||||
|
return password_hash($password, PASSWORD_DEFAULT, ["cost" => 12]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyPassword($password, $hash) {
|
||||||
|
return password_verify($password, $hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSomething(){}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
91
webseite/sys/security/cookie.class.php
Normal file
91
webseite/sys/security/cookie.class.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
// namespace
|
||||||
|
namespace sven\sys\security;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cookie
|
||||||
|
*
|
||||||
|
* Wrapping cookie functions
|
||||||
|
*
|
||||||
|
* @package sven\sys\security
|
||||||
|
* @copyright 2018 Ruben Meyer
|
||||||
|
* @author Ruben Meyer <contact@rxbn.de>
|
||||||
|
* @version 0.1.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class cookie {
|
||||||
|
|
||||||
|
public const EXPIRE_TIME = 1800; // in seconds (30mins)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destructor
|
||||||
|
*/
|
||||||
|
public function __destruct() {
|
||||||
|
$cks = $_COOKIE;
|
||||||
|
foreach ($cks as $key => $value) {
|
||||||
|
$this->write($key, $value, time() + self::EXPIRE_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write
|
||||||
|
*
|
||||||
|
* create a cookie with a specific value
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $key Cookie name
|
||||||
|
* @param string $value Cookie value
|
||||||
|
* @param int $expire Expiring timestamp as UNIX timestamp (2018/12/15 12:14:13 => 1544876053) (0 => cookie will be deleted with session end)
|
||||||
|
* @param string $path URL
|
||||||
|
* @param string $domain Domain/Subdomain name where the cookie will be accessable
|
||||||
|
* @param boolean $secure HTTP Secure Flag
|
||||||
|
* @param boolean $httponly Unreadability for Javascript (XSS Security)
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function write($key, $value = "", $expire = 0, $path = "/", $domain = null, $secure = false, $httponly = false) {
|
||||||
|
setcookie($key, $value, $expire, $path, $domain, $secure, $httponly);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read
|
||||||
|
*
|
||||||
|
* read a cookie
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $key Cookie name
|
||||||
|
* @return string|boolean
|
||||||
|
*/
|
||||||
|
public function read($key) {
|
||||||
|
return (isset($_COOKIE[$key]) ? $_COOKIE[$key]: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove
|
||||||
|
*
|
||||||
|
* remove a cookie
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $key Cookie name
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function remove($key) {
|
||||||
|
unset($_COOKIE[$key]);
|
||||||
|
$this->write($key, "", time()-3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop
|
||||||
|
*
|
||||||
|
* drops all cookies
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function drop() {
|
||||||
|
foreach ($_COOKIE as $key => $value) {
|
||||||
|
$this->remove($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
42
webseite/sys/security/session.class.php
Normal file
42
webseite/sys/security/session.class.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
// namespace
|
||||||
|
namespace sven\sys\security;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* session
|
||||||
|
*
|
||||||
|
* Wrapping session functions
|
||||||
|
*
|
||||||
|
* @package sven\sys\security
|
||||||
|
* @copyright 2018 Ruben Meyer
|
||||||
|
* @author Ruben Meyer <contact@rxbn.de>
|
||||||
|
* @version 0.1.0
|
||||||
|
* @TODO Documentation
|
||||||
|
*/
|
||||||
|
class session {
|
||||||
|
|
||||||
|
public static $id;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
if (session_status() == PHP_SESSION_NONE) {
|
||||||
|
session_start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function write($key, $value) {
|
||||||
|
$_SESSION[$key] = $value;
|
||||||
|
}
|
||||||
|
public function read($key) {
|
||||||
|
if(isset($_SESSION[$key]))
|
||||||
|
return $_SESSION[$key];
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
public function remove($key) {
|
||||||
|
unset($_SESSION[$key]);
|
||||||
|
}
|
||||||
|
public function drop() {
|
||||||
|
session_destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
1
webseite/sys/sources/envms-fluentpdo/.gitignore
vendored
Normal file
1
webseite/sys/sources/envms-fluentpdo/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/vendor/
|
18
webseite/sys/sources/envms-fluentpdo/.travis.yml
Normal file
18
webseite/sys/sources/envms-fluentpdo/.travis.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
language: php
|
||||||
|
php:
|
||||||
|
- 7.0
|
||||||
|
- 7.1
|
||||||
|
- 7.2
|
||||||
|
- hhvm
|
||||||
|
|
||||||
|
script: php tests/run-tests.php
|
||||||
|
before_script:
|
||||||
|
- mysql -u root < tests/fluentdb.sql
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
slack:
|
||||||
|
secure: cyZnqOCV/gO9p23Z8Lr0e4sc3TqXi0v+VQ8neeRTNalYuiwgn9Co1NakCBO7yyku6qyWE9EOaypYBJlZgaLExLAyCGmaSTRduLlE7P1bdcNnkmns0ikoenFzXd5Uq26ExsegGzUGSbjwtzVhiHLUwigPsJNpnwsMOa2Co5ieo04=
|
||||||
|
|
||||||
|
os: linux
|
||||||
|
group: stable
|
||||||
|
dist: trusty
|
21
webseite/sys/sources/envms-fluentpdo/composer.json
Normal file
21
webseite/sys/sources/envms-fluentpdo/composer.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "envms/fluentpdo",
|
||||||
|
"description": "FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.",
|
||||||
|
"keywords": ["db", "database", "dbal", "pdo", "fluent", "query", "builder", "mysql", "oracle"],
|
||||||
|
"homepage": "https://github.com/envms/fluentpdo",
|
||||||
|
"license": ["Apache-2.0", "GPL-2.0+"],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "envms",
|
||||||
|
"homepage": "http://env.ms"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Envms\\FluentPDO\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^6.2"
|
||||||
|
}
|
||||||
|
}
|
1467
webseite/sys/sources/envms-fluentpdo/composer.lock
generated
Normal file
1467
webseite/sys/sources/envms-fluentpdo/composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
160
webseite/sys/sources/envms-fluentpdo/readme.md
Normal file
160
webseite/sys/sources/envms-fluentpdo/readme.md
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
# FluentPDO [](http://travis-ci.org/envms/fluentpdo) [](https://codeclimate.com/github/fpdo/fluentpdo/maintainability)
|
||||||
|
|
||||||
|
FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Easy interface for creating queries step by step
|
||||||
|
- Support for any database compatible with PDO
|
||||||
|
- Simple API based on PDO and SQL syntax
|
||||||
|
- Ability to build complex SELECT, INSERT, UPDATE & DELETE queries with little code
|
||||||
|
- Small and very fast
|
||||||
|
- Type hinting for magic methods with code completion in smart IDEs
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
The latest (2.x) release of FluentPDO supports PHP 7.0, 7.1 and 7.2
|
||||||
|
|
||||||
|
The legacy (1.x) release of FluentPDO supports PHP 5.4 to 7.1
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
[Sitepoint - Getting Started with FluentPDO](http://www.sitepoint.com/getting-started-fluentpdo/)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
### Composer
|
||||||
|
|
||||||
|
The preferred way to install FluentPDO is via [composer](http://getcomposer.org/). v1.1.x will be the last until the release of 2.0, so we recommend using 1.1.* to ensure no breaking changes are introduced.
|
||||||
|
|
||||||
|
Add the following line in your `composer.json` file:
|
||||||
|
|
||||||
|
"require": {
|
||||||
|
...
|
||||||
|
"envms/fluentpdo": "1.1.*"
|
||||||
|
}
|
||||||
|
|
||||||
|
update your dependencies with `composer update`, and you're done!
|
||||||
|
|
||||||
|
### Copy
|
||||||
|
|
||||||
|
If you prefer not to use composer, simply copy the `/FluentPDO` directory into your libraries directory and add:
|
||||||
|
|
||||||
|
```php
|
||||||
|
include "[your-library-directory]/FluentPDO/FluentPDO.php";
|
||||||
|
```
|
||||||
|
|
||||||
|
to the top of your application.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Create a new PDO instance, and pass the instance to FluentPDO:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdo = new PDO("mysql:dbname=fluentdb", "root");
|
||||||
|
$fluent = new FluentPDO($pdo);
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, creating queries is quick and easy:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$query = $fluent->from('article')
|
||||||
|
->where('published_at > ?', $date)
|
||||||
|
->orderBy('published_at DESC')
|
||||||
|
->limit(5);
|
||||||
|
```
|
||||||
|
|
||||||
|
which builds the query below:
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
WHERE published_at > ?
|
||||||
|
ORDER BY published_at DESC
|
||||||
|
LIMIT 5
|
||||||
|
```
|
||||||
|
|
||||||
|
To get data from the select, all we do is loop through the returned array:
|
||||||
|
|
||||||
|
```php
|
||||||
|
foreach ($query as $row) {
|
||||||
|
echo "$row[title]\n";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using the Smart Join Builder
|
||||||
|
|
||||||
|
Let's start with a traditional join, below:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$query = $fluent->from('article')
|
||||||
|
->leftJoin('user ON user.id = article.user_id')
|
||||||
|
->select('user.name');
|
||||||
|
```
|
||||||
|
|
||||||
|
That's pretty verbose, and not very smart. If your tables use proper primary and foreign key names, you can shorten the above to:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$query = $fluent->from('article')
|
||||||
|
->leftJoin('user')
|
||||||
|
->select('user.name');
|
||||||
|
```
|
||||||
|
|
||||||
|
That's better, but not ideal. However, it would be even easier to **not write any joins**:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$query = $fluent->from('article')
|
||||||
|
->select('user.name');
|
||||||
|
```
|
||||||
|
|
||||||
|
Awesome, right? FluentPDO is able to build the join for you, by you prepending the foreign table name to the requested column.
|
||||||
|
|
||||||
|
All three snippets above will create the exact same query:
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
SELECT article.*, user.name
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
||||||
|
```
|
||||||
|
|
||||||
|
## CRUD Query Examples
|
||||||
|
|
||||||
|
##### SELECT
|
||||||
|
|
||||||
|
```php
|
||||||
|
$query = $fluent->from('article')->where('id', 1);
|
||||||
|
$query = $fluent->from('user', 1); // shorter version if selecting one row by primary key
|
||||||
|
```
|
||||||
|
|
||||||
|
##### INSERT
|
||||||
|
|
||||||
|
```php
|
||||||
|
$values = array('title' => 'article 1', 'content' => 'content 1');
|
||||||
|
|
||||||
|
$query = $fluent->insertInto('article')->values($values)->execute();
|
||||||
|
$query = $fluent->insertInto('article', $values)->execute(); // shorter version
|
||||||
|
```
|
||||||
|
|
||||||
|
##### UPDATE
|
||||||
|
|
||||||
|
```php
|
||||||
|
$set = array('published_at' => new FluentLiteral('NOW()'));
|
||||||
|
|
||||||
|
$query = $fluent->update('article')->set($set)->where('id', 1)->execute();
|
||||||
|
$query = $fluent->update('article', $set, 1)->execute(); // shorter version if updating one row by primary key
|
||||||
|
```
|
||||||
|
|
||||||
|
##### DELETE
|
||||||
|
|
||||||
|
```php
|
||||||
|
$query = $fluent->deleteFrom('article')->where('id', 1)->execute();
|
||||||
|
$query = $fluent->deleteFrom('article', 1)->execute(); // shorter version if deleting one row by primary key
|
||||||
|
```
|
||||||
|
|
||||||
|
***Note**: INSERT, UPDATE and DELETE queries will only run after you call `->execute()`*
|
||||||
|
|
||||||
|
Full documentation can be found on the [FluentPDO homepage](http://envms.github.io/fluentpdo/)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Free for commercial and non-commercial use under the [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) or [GPL 2.0](http://www.gnu.org/licenses/gpl-2.0.html) licenses.
|
31
webseite/sys/sources/envms-fluentpdo/src/Literal.php
Normal file
31
webseite/sys/sources/envms-fluentpdo/src/Literal.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL literal value
|
||||||
|
*/
|
||||||
|
class Literal
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $value = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create literal value
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
function __construct($value) {
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get literal value
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function __toString() {
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
387
webseite/sys/sources/envms-fluentpdo/src/Queries/Base.php
Normal file
387
webseite/sys/sources/envms-fluentpdo/src/Queries/Base.php
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO\Queries;
|
||||||
|
|
||||||
|
use Envms\FluentPDO\{Query,Literal,Structure,Utilities};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base query builder
|
||||||
|
*/
|
||||||
|
abstract class Base implements \IteratorAggregate
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var Query */
|
||||||
|
private $fluent;
|
||||||
|
|
||||||
|
/** @var \PDOStatement */
|
||||||
|
private $result;
|
||||||
|
|
||||||
|
/** @var float */
|
||||||
|
private $time;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $object = false;
|
||||||
|
|
||||||
|
/** @var array - definition clauses */
|
||||||
|
protected $clauses = array();
|
||||||
|
/** @var array */
|
||||||
|
protected $statements = array();
|
||||||
|
/** @var array */
|
||||||
|
protected $parameters = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseQuery constructor.
|
||||||
|
*
|
||||||
|
* @param Query $fluent
|
||||||
|
* @param $clauses
|
||||||
|
*/
|
||||||
|
protected function __construct(Query $fluent, $clauses) {
|
||||||
|
$this->fluent = $fluent;
|
||||||
|
$this->clauses = $clauses;
|
||||||
|
$this->initClauses();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return formatted query when request class representation
|
||||||
|
* ie: echo $query
|
||||||
|
*
|
||||||
|
* @return string - formatted query
|
||||||
|
*/
|
||||||
|
public function __toString() {
|
||||||
|
return $this->getQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize statement and parameter clauses.
|
||||||
|
*/
|
||||||
|
private function initClauses() {
|
||||||
|
foreach ($this->clauses as $clause => $value) {
|
||||||
|
if ($value) {
|
||||||
|
$this->statements[$clause] = array();
|
||||||
|
$this->parameters[$clause] = array();
|
||||||
|
} else {
|
||||||
|
$this->statements[$clause] = null;
|
||||||
|
$this->parameters[$clause] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add statement for all kind of clauses
|
||||||
|
*
|
||||||
|
* @param $clause
|
||||||
|
* @param $statement
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
protected function addStatement($clause, $statement, $parameters = array()) {
|
||||||
|
if ($statement === null) {
|
||||||
|
return $this->resetClause($clause);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->clauses[$clause]) {
|
||||||
|
if (is_array($statement)) {
|
||||||
|
$this->statements[$clause] = array_merge($this->statements[$clause], $statement);
|
||||||
|
} else {
|
||||||
|
$this->statements[$clause][] = $statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->parameters[$clause] = array_merge($this->parameters[$clause], $parameters);
|
||||||
|
} else {
|
||||||
|
$this->statements[$clause] = $statement;
|
||||||
|
$this->parameters[$clause] = $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all prev defined statements
|
||||||
|
*
|
||||||
|
* @param $clause
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
protected function resetClause($clause) {
|
||||||
|
$this->statements[$clause] = null;
|
||||||
|
$this->parameters[$clause] = array();
|
||||||
|
if (isset($this->clauses[$clause]) && $this->clauses[$clause]) {
|
||||||
|
$this->statements[$clause] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements method from IteratorAggregate
|
||||||
|
*
|
||||||
|
* @return \PDOStatement
|
||||||
|
*/
|
||||||
|
public function getIterator() {
|
||||||
|
return $this->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute query with earlier added parameters
|
||||||
|
*
|
||||||
|
* @return \PDOStatement
|
||||||
|
*/
|
||||||
|
public function execute() {
|
||||||
|
$query = $this->buildQuery();
|
||||||
|
$parameters = $this->buildParameters();
|
||||||
|
|
||||||
|
$result = $this->fluent->getPdo()->prepare($query);
|
||||||
|
|
||||||
|
// At this point, $result is a PDOStatement instance, or false.
|
||||||
|
// PDO::prepare() does not reliably return errors. Some database drivers
|
||||||
|
// do not support prepared statements, and PHP emulates them. Postgresql
|
||||||
|
// does support prepared statements, but PHP does not call Postgresql's
|
||||||
|
// prepare function until we call PDOStatement::execute() below.
|
||||||
|
// If PDO::prepare() worked properly, this is where we would check
|
||||||
|
// for prepare errors, such as invalid SQL.
|
||||||
|
|
||||||
|
if ($this->object !== false) {
|
||||||
|
if (class_exists($this->object)) {
|
||||||
|
$result->setFetchMode(\PDO::FETCH_CLASS, $this->object);
|
||||||
|
} else {
|
||||||
|
$result->setFetchMode(\PDO::FETCH_OBJ);
|
||||||
|
}
|
||||||
|
} elseif ($this->fluent->getPdo()->getAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE) == \PDO::FETCH_BOTH) {
|
||||||
|
$result->setFetchMode(\PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
$time = microtime(true);
|
||||||
|
if ($result && $result->execute($parameters)) {
|
||||||
|
$this->time = microtime(true) - $time;
|
||||||
|
} else {
|
||||||
|
$result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->result = $result;
|
||||||
|
$this->debugger();
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echo/pass a debug string
|
||||||
|
*/
|
||||||
|
private function debugger() {
|
||||||
|
if ($this->fluent->debug) {
|
||||||
|
if (!is_callable($this->fluent->debug)) {
|
||||||
|
$backtrace = '';
|
||||||
|
$query = $this->getQuery();
|
||||||
|
$parameters = $this->getParameters();
|
||||||
|
$debug = '';
|
||||||
|
if ($parameters) {
|
||||||
|
$debug = '# parameters: ' . implode(', ', array_map(array($this, 'quote'), $parameters)) . "\n";
|
||||||
|
}
|
||||||
|
$debug .= $query;
|
||||||
|
$pattern = '(^' . preg_quote(__DIR__) . '(\\.php$|[/\\\\]))'; // can be static
|
||||||
|
foreach (debug_backtrace() as $backtrace) {
|
||||||
|
if (isset($backtrace['file']) && !preg_match($pattern, $backtrace['file'])) {
|
||||||
|
// stop on first file outside Query source codes
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$time = sprintf('%0.3f', $this->time * 1000) . ' ms';
|
||||||
|
$rows = ($this->result) ? $this->result->rowCount() : 0;
|
||||||
|
$finalString = "# $backtrace[file]:$backtrace[line] ($time; rows = $rows)\n$debug\n\n";
|
||||||
|
if (defined('STDERR')) { // if STDERR is set, send there, otherwise just output the string
|
||||||
|
if (is_resource(STDERR)) {
|
||||||
|
fwrite(STDERR, $finalString);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo $finalString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo $finalString;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
call_user_func($this->fluent->debug, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \PDO
|
||||||
|
*/
|
||||||
|
protected function getPDO() {
|
||||||
|
return $this->fluent->getPdo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Structure
|
||||||
|
*/
|
||||||
|
protected function getStructure() {
|
||||||
|
return $this->fluent->getStructure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PDOStatement result
|
||||||
|
*
|
||||||
|
* @return \PDOStatement
|
||||||
|
*/
|
||||||
|
public function getResult() {
|
||||||
|
return $this->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get time of execution
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function getTime() {
|
||||||
|
return $this->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get query parameters
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getParameters() {
|
||||||
|
return $this->buildParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get query string
|
||||||
|
*
|
||||||
|
* @param bool $formatted - Return formatted query
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getQuery($formatted = true) {
|
||||||
|
$query = $this->buildQuery();
|
||||||
|
if ($formatted) {
|
||||||
|
$query = Utilities::formatQuery($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate query
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
protected function buildQuery() {
|
||||||
|
$query = '';
|
||||||
|
foreach ($this->clauses as $clause => $separator) {
|
||||||
|
if ($this->clauseNotEmpty($clause)) {
|
||||||
|
if (is_string($separator)) {
|
||||||
|
$query .= " $clause " . implode($separator, $this->statements[$clause]);
|
||||||
|
} elseif ($separator === null) {
|
||||||
|
$query .= " $clause " . $this->statements[$clause];
|
||||||
|
} elseif (is_callable($separator)) {
|
||||||
|
$query .= call_user_func($separator);
|
||||||
|
} else {
|
||||||
|
throw new \Exception("Clause '$clause' is incorrectly set to '$separator'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $clause
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function clauseNotEmpty($clause) {
|
||||||
|
if ((Utilities::isCountable($this->statements[$clause])) && $this->clauses[$clause]) {
|
||||||
|
return (boolean)count($this->statements[$clause]);
|
||||||
|
} else {
|
||||||
|
return (boolean)$this->statements[$clause];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function buildParameters() {
|
||||||
|
$parameters = array();
|
||||||
|
foreach ($this->parameters as $clauses) {
|
||||||
|
if (is_array($clauses)) {
|
||||||
|
foreach ($clauses as $value) {
|
||||||
|
if (is_array($value) && is_string(key($value)) && substr(key($value), 0, 1) == ':') {
|
||||||
|
// this is named params e.g. (':name' => 'Mark')
|
||||||
|
$parameters = array_merge($parameters, $value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$parameters[] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ($clauses) {
|
||||||
|
$parameters[] = $clauses;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $value
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function quote($value) {
|
||||||
|
if (!isset($value)) {
|
||||||
|
return "NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value)) { // (a, b) IN ((1, 2), (3, 4))
|
||||||
|
return "(" . implode(", ", array_map(array($this, 'quote'), $value)) . ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $this->formatValue($value);
|
||||||
|
if (is_float($value)) {
|
||||||
|
return sprintf("%F", $value); // otherwise depends on setlocale()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value === false) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int($value) || $value instanceof Literal) { // number or SQL code - for example "NOW()"
|
||||||
|
return (string)$value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->fluent->getPdo()->quote($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DateTime $val
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function formatValue($val) {
|
||||||
|
if ($val instanceof \DateTime) {
|
||||||
|
return $val->format("Y-m-d H:i:s"); // may be driver specific
|
||||||
|
}
|
||||||
|
|
||||||
|
return $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select an item as object
|
||||||
|
*
|
||||||
|
* @param boolean|object $object If set to true, items are returned as stdClass, otherwise a class
|
||||||
|
* name can be passed and a new instance of this class is return.
|
||||||
|
* Can be set to false to return items as an associative array.
|
||||||
|
*
|
||||||
|
* @return Base
|
||||||
|
*/
|
||||||
|
public function asObject($object = true) {
|
||||||
|
$this->object = $object;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
329
webseite/sys/sources/envms-fluentpdo/src/Queries/Common.php
Normal file
329
webseite/sys/sources/envms-fluentpdo/src/Queries/Common.php
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO\Queries;
|
||||||
|
|
||||||
|
use Envms\FluentPDO\{Literal,Utilities};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommonQuery add JOIN and WHERE clauses for (SELECT, UPDATE, DELETE)
|
||||||
|
*/
|
||||||
|
abstract class Common extends Base
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var array - methods which are allowed to be call by the magic method __call() */
|
||||||
|
private $validMethods = ['from', 'fullJoin', 'group', 'groupBy', 'having', 'innerJoin', 'join', 'leftJoin',
|
||||||
|
'limit', 'offset', 'order', 'orderBy', 'outerJoin', 'rightJoin', 'select'];
|
||||||
|
|
||||||
|
/** @var array - Query tables (also include table from clause FROM) */
|
||||||
|
protected $joins = array();
|
||||||
|
|
||||||
|
/** @var bool - Disable adding undefined joins to query? */
|
||||||
|
protected $isSmartJoinEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function enableSmartJoin() {
|
||||||
|
$this->isSmartJoinEnabled = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function disableSmartJoin() {
|
||||||
|
$this->isSmartJoinEnabled = false;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isSmartJoinEnabled() {
|
||||||
|
return $this->isSmartJoinEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add where condition, more calls appends with AND
|
||||||
|
*
|
||||||
|
* @param string $condition possibly containing ? or :name (PDO syntax)
|
||||||
|
* @param mixed $parameters array or a scalar value
|
||||||
|
*
|
||||||
|
* @return Common
|
||||||
|
*/
|
||||||
|
public function where($condition, $parameters = array()) {
|
||||||
|
if ($condition === null) {
|
||||||
|
return $this->resetClause('WHERE');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$condition) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($condition)) { // where(array("column1" => 1, "column2 > ?" => 2))
|
||||||
|
foreach ($condition as $key => $val) {
|
||||||
|
$this->where($key, $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = func_get_args();
|
||||||
|
|
||||||
|
if (count($args) == 1) {
|
||||||
|
return $this->addStatement('WHERE', $condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check that there are 2 arguments, a condition and a parameter value. If the condition contains
|
||||||
|
a parameter, add them; it's up to the dev to be valid sql. Otherwise it's probably
|
||||||
|
just an identifier, so construct a new condition based on the passed parameter value.
|
||||||
|
*/
|
||||||
|
if (count($args) == 2 && !preg_match('/(\?|:\w+)/i', $condition)) {
|
||||||
|
// condition is column only
|
||||||
|
if (is_null($parameters)) {
|
||||||
|
return $this->addStatement('WHERE', "$condition is NULL");
|
||||||
|
} elseif ($args[1] === array()) {
|
||||||
|
return $this->addStatement('WHERE', 'FALSE');
|
||||||
|
} elseif (is_array($args[1])) {
|
||||||
|
$in = $this->quote($args[1]);
|
||||||
|
|
||||||
|
return $this->addStatement('WHERE', "$condition IN $in");
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't parameterize the value if it's an instance of Literal
|
||||||
|
if ($parameters instanceof Literal) {
|
||||||
|
$condition = "{$condition} = {$parameters}";
|
||||||
|
|
||||||
|
return $this->addStatement('WHERE', $condition);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$condition = "$condition = ?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array_shift($args);
|
||||||
|
|
||||||
|
return $this->addStatement('WHERE', $condition, $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param array $parameters - first is $statement followed by $parameters
|
||||||
|
*
|
||||||
|
* @return $this|Select
|
||||||
|
*/
|
||||||
|
public function __call($name, $parameters = array()) {
|
||||||
|
if (!in_array($name, $this->validMethods)) {
|
||||||
|
trigger_error("Call to invalid method " . get_class($this) . "::{$name}()", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
$clause = Utilities::toUpperWords($name);
|
||||||
|
|
||||||
|
if ($clause == 'GROUP') {
|
||||||
|
$clause = 'GROUP BY';
|
||||||
|
}
|
||||||
|
if ($clause == 'ORDER') {
|
||||||
|
$clause = 'ORDER BY';
|
||||||
|
}
|
||||||
|
if ($clause == 'FOOT NOTE') {
|
||||||
|
$clause = "\n--";
|
||||||
|
}
|
||||||
|
|
||||||
|
$statement = array_shift($parameters);
|
||||||
|
|
||||||
|
if (strpos($clause, 'JOIN') !== false) {
|
||||||
|
return $this->addJoinStatements($clause, $statement, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->addStatement($clause, $statement, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseJoin() {
|
||||||
|
return implode(' ', $this->statements['JOIN']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statement can contain more tables (e.g. "table1.table2:table3:")
|
||||||
|
*
|
||||||
|
* @param $clause
|
||||||
|
* @param $statement
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return $this|Select
|
||||||
|
*/
|
||||||
|
private function addJoinStatements($clause, $statement, $parameters = array()) {
|
||||||
|
if ($statement === null) {
|
||||||
|
$this->joins = array();
|
||||||
|
|
||||||
|
return $this->resetClause('JOIN');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_search(substr($statement, 0, -1), $this->joins) !== false) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// match "table AS alias"
|
||||||
|
preg_match('/`?([a-z_][a-z0-9_\.:]*)`?(\s+AS)?(\s+`?([a-z_][a-z0-9_]*)`?)?/i', $statement, $matches);
|
||||||
|
$joinAlias = '';
|
||||||
|
$joinTable = '';
|
||||||
|
|
||||||
|
if ($matches) {
|
||||||
|
$joinTable = $matches[1];
|
||||||
|
if (isset($matches[4]) && !in_array(strtoupper($matches[4]), array('ON', 'USING'))) {
|
||||||
|
$joinAlias = $matches[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos(strtoupper($statement), ' ON ') || strpos(strtoupper($statement), ' USING')) {
|
||||||
|
if (!$joinAlias) {
|
||||||
|
$joinAlias = $joinTable;
|
||||||
|
}
|
||||||
|
if (in_array($joinAlias, $this->joins)) {
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
$this->joins[] = $joinAlias;
|
||||||
|
$statement = " $clause $statement";
|
||||||
|
|
||||||
|
return $this->addStatement('JOIN', $statement, $parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// $joinTable is list of tables for join e.g.: table1.table2:table3....
|
||||||
|
if (!in_array(substr($joinTable, -1), array('.', ':'))) {
|
||||||
|
$joinTable .= '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
preg_match_all('/([a-z_][a-z0-9_]*[\.:]?)/i', $joinTable, $matches);
|
||||||
|
$mainTable = '';
|
||||||
|
|
||||||
|
if (isset($this->statements['FROM'])) {
|
||||||
|
$mainTable = $this->statements['FROM'];
|
||||||
|
} elseif (isset($this->statements['UPDATE'])) {
|
||||||
|
$mainTable = $this->statements['UPDATE'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastItem = array_pop($matches[1]);
|
||||||
|
array_push($matches[1], $lastItem);
|
||||||
|
|
||||||
|
foreach ($matches[1] as $joinItem) {
|
||||||
|
if ($mainTable == substr($joinItem, 0, -1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$alias = '';
|
||||||
|
|
||||||
|
if ($joinItem == $lastItem) {
|
||||||
|
$alias = $joinAlias; // use $joinAlias only for $lastItem
|
||||||
|
}
|
||||||
|
|
||||||
|
$newJoin = $this->createJoinStatement($clause, $mainTable, $joinItem, $alias);
|
||||||
|
if ($newJoin) {
|
||||||
|
$this->addStatement('JOIN', $newJoin, $parameters);
|
||||||
|
}
|
||||||
|
$mainTable = $joinItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create join string
|
||||||
|
*
|
||||||
|
* @param $clause
|
||||||
|
* @param $mainTable
|
||||||
|
* @param $joinTable
|
||||||
|
* @param string $joinAlias
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function createJoinStatement($clause, $mainTable, $joinTable, $joinAlias = '') {
|
||||||
|
if (in_array(substr($mainTable, -1), array(':', '.'))) {
|
||||||
|
$mainTable = substr($mainTable, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$referenceDirection = substr($joinTable, -1);
|
||||||
|
$joinTable = substr($joinTable, 0, -1);
|
||||||
|
$asJoinAlias = '';
|
||||||
|
|
||||||
|
if ($joinAlias) {
|
||||||
|
$asJoinAlias = " AS $joinAlias";
|
||||||
|
} else {
|
||||||
|
$joinAlias = $joinTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($joinAlias, $this->joins)) { // if the join exists don't create it again
|
||||||
|
return '';
|
||||||
|
} else {
|
||||||
|
$this->joins[] = $joinAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($referenceDirection == ':') { // back reference
|
||||||
|
$primaryKey = $this->getStructure()->getPrimaryKey($mainTable);
|
||||||
|
$foreignKey = $this->getStructure()->getForeignKey($mainTable);
|
||||||
|
|
||||||
|
return " $clause $joinTable$asJoinAlias ON $joinAlias.$foreignKey = $mainTable.$primaryKey";
|
||||||
|
} else {
|
||||||
|
$primaryKey = $this->getStructure()->getPrimaryKey($joinTable);
|
||||||
|
$foreignKey = $this->getStructure()->getForeignKey($joinTable);
|
||||||
|
|
||||||
|
return " $clause $joinTable$asJoinAlias ON $joinAlias.$primaryKey = $mainTable.$foreignKey";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function buildQuery() {
|
||||||
|
// first create extra join from statements with columns with referenced tables
|
||||||
|
$statementsWithReferences = array('WHERE', 'SELECT', 'GROUP BY', 'ORDER BY');
|
||||||
|
|
||||||
|
foreach ($statementsWithReferences as $clause) {
|
||||||
|
if (array_key_exists($clause, $this->statements)) {
|
||||||
|
$this->statements[$clause] = array_map(array($this, 'createUndefinedJoins'), $this->statements[$clause]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create undefined joins from statement with column with referenced tables
|
||||||
|
*
|
||||||
|
* @param string $statement
|
||||||
|
*
|
||||||
|
* @return string - the rewritten $statement (e.g. tab1.tab2:col => tab2.col)
|
||||||
|
*/
|
||||||
|
private function createUndefinedJoins($statement) {
|
||||||
|
if (!$this->isSmartJoinEnabled) {
|
||||||
|
return $statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// matches a table name made of any printable characters followed by a dot/colon,
|
||||||
|
// followed by any letters, numbers and most punctuation (to exclude '*')
|
||||||
|
preg_match_all('/([^[:space:]\(\)]+[.:])[\p{L}\p{N}\p{Pd}\p{Pi}\p{Pf}\p{Pc}]*/u', $statement, $matches);
|
||||||
|
|
||||||
|
foreach ($matches[1] as $join) {
|
||||||
|
if (!in_array(substr($join, 0, -1), $this->joins)) {
|
||||||
|
$this->addJoinStatements('LEFT JOIN', $join);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't rewrite table from other databases
|
||||||
|
foreach ($this->joins as $join) {
|
||||||
|
if (strpos($join, '.') !== false && strpos($statement, $join) === 0) {
|
||||||
|
return $statement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove extra referenced tables (rewrite tab1.tab2:col => tab2.col)
|
||||||
|
$statement = preg_replace('/(?:[^\s]*[.:])?([^\s]+)[.:]([^\s]*)/u', '$1.$2', $statement);
|
||||||
|
|
||||||
|
return $statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
97
webseite/sys/sources/envms-fluentpdo/src/Queries/Delete.php
Normal file
97
webseite/sys/sources/envms-fluentpdo/src/Queries/Delete.php
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO\Queries;
|
||||||
|
|
||||||
|
use Envms\FluentPDO\Query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE query builder
|
||||||
|
*
|
||||||
|
* @method Delete leftJoin(string $statement) add LEFT JOIN to query
|
||||||
|
* ($statement can be 'table' name only or 'table:' means back reference)
|
||||||
|
* @method Delete innerJoin(string $statement) add INNER JOIN to query
|
||||||
|
* ($statement can be 'table' name only or 'table:' means back reference)
|
||||||
|
* @method Delete from(string $table) add LIMIT to query
|
||||||
|
* @method Delete orderBy(string $column) add ORDER BY to query
|
||||||
|
* @method Delete limit(int $limit) add LIMIT to query
|
||||||
|
*/
|
||||||
|
class Delete extends Common
|
||||||
|
{
|
||||||
|
|
||||||
|
private $ignore = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete constructor
|
||||||
|
*
|
||||||
|
* @param Query $fluent
|
||||||
|
* @param string $table
|
||||||
|
*/
|
||||||
|
public function __construct(Query $fluent, $table) {
|
||||||
|
$clauses = array(
|
||||||
|
'DELETE FROM' => array($this, 'getClauseDeleteFrom'),
|
||||||
|
'DELETE' => array($this, 'getClauseDelete'),
|
||||||
|
'FROM' => null,
|
||||||
|
'JOIN' => array($this, 'getClauseJoin'),
|
||||||
|
'WHERE' => ' AND ',
|
||||||
|
'ORDER BY' => ', ',
|
||||||
|
'LIMIT' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
parent::__construct($fluent, $clauses);
|
||||||
|
|
||||||
|
$this->statements['DELETE FROM'] = $table;
|
||||||
|
$this->statements['DELETE'] = $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces delete operation to fail silently
|
||||||
|
*
|
||||||
|
* @return Delete
|
||||||
|
*/
|
||||||
|
public function ignore() {
|
||||||
|
$this->ignore = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function buildQuery() {
|
||||||
|
if ($this->statements['FROM']) {
|
||||||
|
unset($this->clauses['DELETE FROM']);
|
||||||
|
} else {
|
||||||
|
unset($this->clauses['DELETE']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute DELETE query
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function execute() {
|
||||||
|
$result = parent::execute();
|
||||||
|
if ($result) {
|
||||||
|
return $result->rowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseDelete() {
|
||||||
|
return 'DELETE' . ($this->ignore ? " IGNORE" : '') . ' ' . $this->statements['DELETE'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseDeleteFrom() {
|
||||||
|
return 'DELETE' . ($this->ignore ? " IGNORE" : '') . ' FROM ' . $this->statements['DELETE FROM'];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
224
webseite/sys/sources/envms-fluentpdo/src/Queries/Insert.php
Normal file
224
webseite/sys/sources/envms-fluentpdo/src/Queries/Insert.php
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO\Queries;
|
||||||
|
|
||||||
|
use Envms\FluentPDO\{Query,Literal};
|
||||||
|
|
||||||
|
/** INSERT query builder
|
||||||
|
*/
|
||||||
|
class Insert extends Base
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $columns = array();
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $firstValue = array();
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $ignore = false;
|
||||||
|
/** @var bool */
|
||||||
|
private $delayed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InsertQuery constructor.
|
||||||
|
*
|
||||||
|
* @param Query $fluent
|
||||||
|
* @param string $table
|
||||||
|
* @param $values
|
||||||
|
*/
|
||||||
|
public function __construct(Query $fluent, $table, $values) {
|
||||||
|
$clauses = array(
|
||||||
|
'INSERT INTO' => array($this, 'getClauseInsertInto'),
|
||||||
|
'VALUES' => array($this, 'getClauseValues'),
|
||||||
|
'ON DUPLICATE KEY UPDATE' => array($this, 'getClauseOnDuplicateKeyUpdate'),
|
||||||
|
);
|
||||||
|
parent::__construct($fluent, $clauses);
|
||||||
|
|
||||||
|
$this->statements['INSERT INTO'] = $table;
|
||||||
|
$this->values($values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute insert query
|
||||||
|
*
|
||||||
|
* @param mixed $sequence
|
||||||
|
*
|
||||||
|
* @return integer last inserted id or false
|
||||||
|
*/
|
||||||
|
public function execute($sequence = null) {
|
||||||
|
$result = parent::execute();
|
||||||
|
if ($result) {
|
||||||
|
return $this->getPDO()->lastInsertId($sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add ON DUPLICATE KEY UPDATE
|
||||||
|
*
|
||||||
|
* @param array $values
|
||||||
|
*
|
||||||
|
* @return Insert
|
||||||
|
*/
|
||||||
|
public function onDuplicateKeyUpdate($values) {
|
||||||
|
$this->statements['ON DUPLICATE KEY UPDATE'] = array_merge(
|
||||||
|
$this->statements['ON DUPLICATE KEY UPDATE'], $values
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add VALUES
|
||||||
|
*
|
||||||
|
* @param $values
|
||||||
|
*
|
||||||
|
* @return Insert
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function values($values) {
|
||||||
|
if (!is_array($values)) {
|
||||||
|
throw new \Exception('Param VALUES for INSERT query must be array');
|
||||||
|
}
|
||||||
|
$first = current($values);
|
||||||
|
if (is_string(key($values))) {
|
||||||
|
// is one row array
|
||||||
|
$this->addOneValue($values);
|
||||||
|
} elseif (is_array($first) && is_string(key($first))) {
|
||||||
|
// this is multi values
|
||||||
|
foreach ($values as $oneValue) {
|
||||||
|
$this->addOneValue($oneValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force insert operation to fail silently
|
||||||
|
*
|
||||||
|
* @return Insert
|
||||||
|
*/
|
||||||
|
public function ignore() {
|
||||||
|
$this->ignore = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Force insert operation delay support
|
||||||
|
*
|
||||||
|
* @return Insert
|
||||||
|
*/
|
||||||
|
public function delayed() {
|
||||||
|
$this->delayed = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseInsertInto() {
|
||||||
|
return 'INSERT' . ($this->ignore ? " IGNORE" : '') . ($this->delayed ? " DELAYED" : '') . ' INTO ' . $this->statements['INSERT INTO'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $param
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function parameterGetValue($param) {
|
||||||
|
return $param instanceof Literal ? (string)$param : '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseValues() {
|
||||||
|
$valuesArray = array();
|
||||||
|
foreach ($this->statements['VALUES'] as $rows) {
|
||||||
|
// literals should not be parametrized.
|
||||||
|
// They are commonly used to call engine functions or literals.
|
||||||
|
// Eg: NOW(), CURRENT_TIMESTAMP etc
|
||||||
|
$placeholders = array_map(array($this, 'parameterGetValue'), $rows);
|
||||||
|
$valuesArray[] = '(' . implode(', ', $placeholders) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = implode(', ', $this->columns);
|
||||||
|
$values = implode(', ', $valuesArray);
|
||||||
|
|
||||||
|
return " ($columns) VALUES $values";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all Literal instances from the argument
|
||||||
|
* since they are not to be used as PDO parameters but rather injected directly into the query
|
||||||
|
*
|
||||||
|
* @param $statements
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function filterLiterals($statements) {
|
||||||
|
$f = function ($item) {
|
||||||
|
return !$item instanceof Literal;
|
||||||
|
};
|
||||||
|
|
||||||
|
return array_map(function ($item) use ($f) {
|
||||||
|
if (is_array($item)) {
|
||||||
|
return array_filter($item, $f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}, array_filter($statements, $f));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function buildParameters() {
|
||||||
|
$this->parameters = array_merge(
|
||||||
|
$this->filterLiterals($this->statements['VALUES']),
|
||||||
|
$this->filterLiterals($this->statements['ON DUPLICATE KEY UPDATE'])
|
||||||
|
);
|
||||||
|
|
||||||
|
return parent::buildParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseOnDuplicateKeyUpdate() {
|
||||||
|
$result = array();
|
||||||
|
foreach ($this->statements['ON DUPLICATE KEY UPDATE'] as $key => $value) {
|
||||||
|
$result[] = "$key = " . $this->parameterGetValue($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ' ON DUPLICATE KEY UPDATE ' . implode(', ', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $oneValue
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
private function addOneValue($oneValue) {
|
||||||
|
// check if all $keys are strings
|
||||||
|
foreach ($oneValue as $key => $value) {
|
||||||
|
if (!is_string($key)) {
|
||||||
|
throw new \Exception('INSERT query: All keys of value array have to be strings.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$this->firstValue) {
|
||||||
|
$this->firstValue = $oneValue;
|
||||||
|
}
|
||||||
|
if (!$this->columns) {
|
||||||
|
$this->columns = array_keys($oneValue);
|
||||||
|
}
|
||||||
|
if ($this->columns != array_keys($oneValue)) {
|
||||||
|
throw new \Exception('INSERT query: All VALUES have to same keys (columns).');
|
||||||
|
}
|
||||||
|
$this->statements['VALUES'][] = $oneValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
201
webseite/sys/sources/envms-fluentpdo/src/Queries/Select.php
Normal file
201
webseite/sys/sources/envms-fluentpdo/src/Queries/Select.php
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO\Queries;
|
||||||
|
|
||||||
|
use Envms\FluentPDO\{Query,Utilities};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SELECT query builder
|
||||||
|
*
|
||||||
|
* @method Select select(string $column) add one or more columns in SELECT to query
|
||||||
|
* @method Select leftJoin(string $statement) add LEFT JOIN to query
|
||||||
|
* ($statement can be 'table' name only or 'table:' means back reference)
|
||||||
|
* @method Select innerJoin(string $statement) add INNER JOIN to query
|
||||||
|
* ($statement can be 'table' name only or 'table:' means back reference)
|
||||||
|
* @method Select groupBy(string $column) add GROUP BY to query
|
||||||
|
* @method Select having(string $column) add HAVING query
|
||||||
|
* @method Select orderBy(string $column) add ORDER BY to query
|
||||||
|
* @method Select limit(int $limit) add LIMIT to query
|
||||||
|
* @method Select offset(int $offset) add OFFSET to query
|
||||||
|
*/
|
||||||
|
class Select extends Common implements \Countable
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var mixed */
|
||||||
|
private $fromTable;
|
||||||
|
/** @var mixed */
|
||||||
|
private $fromAlias;
|
||||||
|
|
||||||
|
/** @var boolean */
|
||||||
|
private $convertTypes = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SelectQuery constructor.
|
||||||
|
*
|
||||||
|
* @param Query $fluent
|
||||||
|
* @param $from
|
||||||
|
*/
|
||||||
|
function __construct(Query $fluent, $from) {
|
||||||
|
$clauses = array(
|
||||||
|
'SELECT' => ', ',
|
||||||
|
'FROM' => null,
|
||||||
|
'JOIN' => array($this, 'getClauseJoin'),
|
||||||
|
'WHERE' => ' AND ',
|
||||||
|
'GROUP BY' => ',',
|
||||||
|
'HAVING' => ' AND ',
|
||||||
|
'ORDER BY' => ', ',
|
||||||
|
'LIMIT' => null,
|
||||||
|
'OFFSET' => null,
|
||||||
|
"\n--" => "\n--",
|
||||||
|
);
|
||||||
|
parent::__construct($fluent, $clauses);
|
||||||
|
|
||||||
|
// initialize statements
|
||||||
|
$fromParts = explode(' ', $from);
|
||||||
|
$this->fromTable = reset($fromParts);
|
||||||
|
$this->fromAlias = end($fromParts);
|
||||||
|
|
||||||
|
$this->statements['FROM'] = $from;
|
||||||
|
$this->statements['SELECT'][] = $this->fromAlias . '.*';
|
||||||
|
$this->joins[] = $this->fromAlias;
|
||||||
|
|
||||||
|
if(isset($fluent->convertTypes) && $fluent->convertTypes){
|
||||||
|
$this->convertTypes = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return table name from FROM clause
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function getFromTable() {
|
||||||
|
return $this->fromTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return table alias from FROM clause
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function getFromAlias() {
|
||||||
|
return $this->fromAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a single column
|
||||||
|
*
|
||||||
|
* @param int $columnNumber
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function fetchColumn($columnNumber = 0) {
|
||||||
|
if (($s = $this->execute()) !== false) {
|
||||||
|
return $s->fetchColumn($columnNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch first row or column
|
||||||
|
*
|
||||||
|
* @param string $column column name or empty string for the whole row
|
||||||
|
*
|
||||||
|
* @return mixed string, array or false if there is no row
|
||||||
|
*/
|
||||||
|
public function fetch($column = '') {
|
||||||
|
$s = $this->execute();
|
||||||
|
if ($s === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$row = $s->fetch();
|
||||||
|
|
||||||
|
if($this->convertTypes){
|
||||||
|
$row = Utilities::convertToNativeTypes($s,$row);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($row && $column != '') {
|
||||||
|
if (is_object($row)) {
|
||||||
|
return $row->{$column};
|
||||||
|
} else {
|
||||||
|
return $row[$column];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch pairs
|
||||||
|
*
|
||||||
|
* @param $key
|
||||||
|
* @param $value
|
||||||
|
* @param $object
|
||||||
|
*
|
||||||
|
* @return array of fetched rows as pairs
|
||||||
|
*/
|
||||||
|
public function fetchPairs($key, $value, $object = false) {
|
||||||
|
if (($s = $this->select(null)->select("$key, $value")->asObject($object)->execute()) !== false) {
|
||||||
|
return $s->fetchAll(\PDO::FETCH_KEY_PAIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fetch all row
|
||||||
|
*
|
||||||
|
* @param string $index specify index column
|
||||||
|
* @param string $selectOnly select columns which could be fetched
|
||||||
|
*
|
||||||
|
* @return \PDOStatement|array of fetched rows
|
||||||
|
*/
|
||||||
|
public function fetchAll($index = '', $selectOnly = '') {
|
||||||
|
if ($selectOnly) {
|
||||||
|
$this->select(null)->select($index . ', ' . $selectOnly);
|
||||||
|
}
|
||||||
|
if ($index) {
|
||||||
|
$data = [];
|
||||||
|
foreach ($this as $row) {
|
||||||
|
if (is_object($row)) {
|
||||||
|
$data[$row->{$index}] = $row;
|
||||||
|
} else {
|
||||||
|
$data[$row[$index]] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
} else {
|
||||||
|
if (($s = $this->execute()) !== false) {
|
||||||
|
if($this->convertTypes){
|
||||||
|
return Utilities::convertToNativeTypes($s, $s->fetchAll());
|
||||||
|
} else {
|
||||||
|
return $s->fetchAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \Countable interface doesn't break current select query
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count() {
|
||||||
|
$fluent = clone $this;
|
||||||
|
|
||||||
|
return (int)$fluent->select(null)->select('COUNT(*)')->fetchColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \ArrayIterator|\PDOStatement
|
||||||
|
* @todo look into \Countable implementation
|
||||||
|
*/
|
||||||
|
public function getIterator() {
|
||||||
|
if ($this->convertTypes) {
|
||||||
|
return new \ArrayIterator($this->fetchAll());
|
||||||
|
} else {
|
||||||
|
return $this->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
111
webseite/sys/sources/envms-fluentpdo/src/Queries/Update.php
Normal file
111
webseite/sys/sources/envms-fluentpdo/src/Queries/Update.php
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO\Queries;
|
||||||
|
|
||||||
|
use Envms\FluentPDO\{Query,Literal};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UPDATE query builder
|
||||||
|
*
|
||||||
|
* @method Update leftJoin(string $statement) add LEFT JOIN to query
|
||||||
|
* ($statement can be 'table' name only or 'table:' means back reference)
|
||||||
|
* @method Update innerJoin(string $statement) add INNER JOIN to query
|
||||||
|
* ($statement can be 'table' name only or 'table:' means back reference)
|
||||||
|
* @method Update orderBy(string $column) add ORDER BY to query
|
||||||
|
* @method Update limit(int $limit) add LIMIT to query
|
||||||
|
*/
|
||||||
|
class Update extends Common
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateQuery constructor
|
||||||
|
*
|
||||||
|
* @param Query $fluent
|
||||||
|
* @param $table
|
||||||
|
*/
|
||||||
|
public function __construct(Query $fluent, $table) {
|
||||||
|
$clauses = array(
|
||||||
|
'UPDATE' => array($this, 'getClauseUpdate'),
|
||||||
|
'JOIN' => array($this, 'getClauseJoin'),
|
||||||
|
'SET' => array($this, 'getClauseSet'),
|
||||||
|
'WHERE' => ' AND ',
|
||||||
|
'ORDER BY' => ', ',
|
||||||
|
'LIMIT' => null,
|
||||||
|
);
|
||||||
|
parent::__construct($fluent, $clauses);
|
||||||
|
|
||||||
|
$this->statements['UPDATE'] = $table;
|
||||||
|
|
||||||
|
$tableParts = explode(' ', $table);
|
||||||
|
$this->joins[] = end($tableParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|array $fieldOrArray
|
||||||
|
* @param bool|string $value
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function set($fieldOrArray, $value = false) {
|
||||||
|
if (!$fieldOrArray) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
if (is_string($fieldOrArray) && $value !== false) {
|
||||||
|
$this->statements['SET'][$fieldOrArray] = $value;
|
||||||
|
} else {
|
||||||
|
if (!is_array($fieldOrArray)) {
|
||||||
|
throw new \Exception('You must pass a value, or provide the SET list as an associative array. column => value');
|
||||||
|
} else {
|
||||||
|
foreach ($fieldOrArray as $field => $value) {
|
||||||
|
$this->statements['SET'][$field] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute update query
|
||||||
|
*
|
||||||
|
* @param boolean $getResultAsPdoStatement true to return the pdo statement instead of row count
|
||||||
|
*
|
||||||
|
* @return int|boolean|\PDOStatement
|
||||||
|
*/
|
||||||
|
public function execute($getResultAsPdoStatement = false) {
|
||||||
|
$result = parent::execute();
|
||||||
|
if ($getResultAsPdoStatement) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
if ($result) {
|
||||||
|
return $result->rowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseUpdate() {
|
||||||
|
return 'UPDATE ' . $this->statements['UPDATE'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClauseSet() {
|
||||||
|
$setArray = array();
|
||||||
|
foreach ($this->statements['SET'] as $field => $value) {
|
||||||
|
if ($value instanceof Literal) {
|
||||||
|
$setArray[] = $field . ' = ' . $value;
|
||||||
|
} else {
|
||||||
|
$setArray[] = $field . ' = ?';
|
||||||
|
$this->parameters['SET'][$field] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ' SET ' . implode(', ', $setArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
158
webseite/sys/sources/envms-fluentpdo/src/Query.php
Normal file
158
webseite/sys/sources/envms-fluentpdo/src/Query.php
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO;
|
||||||
|
|
||||||
|
use Envms\FluentPDO\Queries\{Insert,Select,Update,Delete};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.
|
||||||
|
*
|
||||||
|
* For more information see readme.md
|
||||||
|
*
|
||||||
|
* @link http://github.com/envms/fluentpdo
|
||||||
|
* @author envms, start@env.ms
|
||||||
|
* @copyright 2012-2017 env.ms - Chris Bornhoft, Aldo Matelli, Stefan Yohansson, Kevin Sanabria, Carol Zhang, Marek Lichtner
|
||||||
|
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||||
|
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Query
|
||||||
|
*/
|
||||||
|
class Query
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var \PDO */
|
||||||
|
protected $pdo;
|
||||||
|
/** @var Structure|null */
|
||||||
|
protected $structure;
|
||||||
|
|
||||||
|
/** @var bool|callback */
|
||||||
|
public $debug;
|
||||||
|
|
||||||
|
/** @var boolean */
|
||||||
|
public $convertTypes = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query constructor
|
||||||
|
*
|
||||||
|
* @param \PDO $pdo
|
||||||
|
* @param Structure|null $structure
|
||||||
|
*/
|
||||||
|
function __construct(\PDO $pdo, Structure $structure = null) {
|
||||||
|
$this->pdo = $pdo;
|
||||||
|
if (!$structure) {
|
||||||
|
$structure = new Structure();
|
||||||
|
}
|
||||||
|
$this->structure = $structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create SELECT query from $table
|
||||||
|
*
|
||||||
|
* @param string $table - db table name
|
||||||
|
* @param integer $primaryKey - return one row by primary key
|
||||||
|
*
|
||||||
|
* @return Select
|
||||||
|
*/
|
||||||
|
public function from($table, $primaryKey = null) {
|
||||||
|
$query = new Select($this, $table);
|
||||||
|
if ($primaryKey !== null) {
|
||||||
|
$tableTable = $query->getFromTable();
|
||||||
|
$tableAlias = $query->getFromAlias();
|
||||||
|
$primaryKeyName = $this->structure->getPrimaryKey($tableTable);
|
||||||
|
$query = $query->where("$tableAlias.$primaryKeyName", $primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create INSERT INTO query
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @param array $values - accepts one or multiple rows, @see docs
|
||||||
|
*
|
||||||
|
* @return Insert
|
||||||
|
*/
|
||||||
|
public function insertInto($table, $values = array()) {
|
||||||
|
$query = new Insert($this, $table, $values);
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create UPDATE query
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @param array|string $set
|
||||||
|
* @param string $primaryKey
|
||||||
|
*
|
||||||
|
* @return Update
|
||||||
|
*/
|
||||||
|
public function update($table, $set = array(), $primaryKey = null) {
|
||||||
|
$query = new Update($this, $table);
|
||||||
|
$query->set($set);
|
||||||
|
if ($primaryKey) {
|
||||||
|
$primaryKeyName = $this->getStructure()->getPrimaryKey($table);
|
||||||
|
$query = $query->where($primaryKeyName, $primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create DELETE query
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @param string $primaryKey delete only row by primary key
|
||||||
|
*
|
||||||
|
* @return Delete
|
||||||
|
*/
|
||||||
|
public function delete($table, $primaryKey = null) {
|
||||||
|
$query = new Delete($this, $table);
|
||||||
|
if ($primaryKey) {
|
||||||
|
$primaryKeyName = $this->getStructure()->getPrimaryKey($table);
|
||||||
|
$query = $query->where($primaryKeyName, $primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create DELETE FROM query
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @param string $primaryKey
|
||||||
|
*
|
||||||
|
* @return Delete
|
||||||
|
*/
|
||||||
|
public function deleteFrom($table, $primaryKey = null) {
|
||||||
|
$args = func_get_args();
|
||||||
|
|
||||||
|
return call_user_func_array(array($this, 'delete'), $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \PDO
|
||||||
|
*/
|
||||||
|
public function getPdo() {
|
||||||
|
return $this->pdo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Structure
|
||||||
|
*/
|
||||||
|
public function getStructure() {
|
||||||
|
return $this->structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the \PDO connection to the database
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
public function close() {
|
||||||
|
$this->pdo = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
61
webseite/sys/sources/envms-fluentpdo/src/Structure.php
Normal file
61
webseite/sys/sources/envms-fluentpdo/src/Structure.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Structure
|
||||||
|
*/
|
||||||
|
class Structure
|
||||||
|
{
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $primaryKey;
|
||||||
|
/** @var string */
|
||||||
|
private $foreignKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure constructor
|
||||||
|
*
|
||||||
|
* @param string $primaryKey
|
||||||
|
* @param string $foreignKey
|
||||||
|
*/
|
||||||
|
function __construct($primaryKey = 'id', $foreignKey = '%s_id') {
|
||||||
|
if ($foreignKey === null) {
|
||||||
|
$foreignKey = $primaryKey;
|
||||||
|
}
|
||||||
|
$this->primaryKey = $primaryKey;
|
||||||
|
$this->foreignKey = $foreignKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPrimaryKey($table) {
|
||||||
|
return $this->key($this->primaryKey, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getForeignKey($table) {
|
||||||
|
return $this->key($this->foreignKey, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|callback $key
|
||||||
|
* @param string $table
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function key($key, $table) {
|
||||||
|
if (is_callable($key)) {
|
||||||
|
return $key($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf($key, $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
100
webseite/sys/sources/envms-fluentpdo/src/Utilities.php
Normal file
100
webseite/sys/sources/envms-fluentpdo/src/Utilities.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
namespace Envms\FluentPDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Utilities
|
||||||
|
*/
|
||||||
|
class Utilities
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert "camelCaseWord" to "CAMEL CASE WORD"
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function toUpperWords($string) {
|
||||||
|
return trim(strtoupper(preg_replace('/(.)([A-Z]+)/', '$1 $2', $string)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function formatQuery($query) {
|
||||||
|
$query = preg_replace(
|
||||||
|
'/\b(WHERE|FROM|GROUP BY|HAVING|ORDER BY|LIMIT|OFFSET|UNION|ON DUPLICATE KEY UPDATE|VALUES|SET)\b/',
|
||||||
|
"\n$0", $query
|
||||||
|
);
|
||||||
|
|
||||||
|
$query = preg_replace(
|
||||||
|
'/\b(INNER|OUTER|LEFT|RIGHT|FULL|CASE|WHEN|END|ELSE|AND)\b/',
|
||||||
|
"\n $0", $query
|
||||||
|
);
|
||||||
|
|
||||||
|
$query = preg_replace("/\s+\n/", "\n", $query); // remove trailing spaces
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts columns from strings to types according to
|
||||||
|
* PDOStatement::columnMeta
|
||||||
|
* http://stackoverflow.com/a/9952703/3006989
|
||||||
|
*
|
||||||
|
* @param \PDOStatement $statement
|
||||||
|
* @param array|\Traversable $rows - provided by PDOStatement::fetch with PDO::FETCH_ASSOC
|
||||||
|
* @return array|\Traversable - copy of $assoc with matching type fields
|
||||||
|
*/
|
||||||
|
public static function convertToNativeTypes(\PDOStatement $statement, $rows)
|
||||||
|
{
|
||||||
|
for ($i = 0; ($columnMeta = $statement->getColumnMeta($i)) !== false; $i++)
|
||||||
|
{
|
||||||
|
$type = $columnMeta['native_type'];
|
||||||
|
|
||||||
|
switch($type)
|
||||||
|
{
|
||||||
|
case 'DECIMAL':
|
||||||
|
case 'NEWDECIMAL':
|
||||||
|
case 'FLOAT':
|
||||||
|
case 'DOUBLE':
|
||||||
|
case 'TINY':
|
||||||
|
case 'SHORT':
|
||||||
|
case 'LONG':
|
||||||
|
case 'LONGLONG':
|
||||||
|
case 'INT24':
|
||||||
|
if(isset($rows[$columnMeta['name']])){
|
||||||
|
$rows[$columnMeta['name']] = $rows[$columnMeta['name']] + 0;
|
||||||
|
}else{
|
||||||
|
if(is_array($rows) || $rows instanceof \Traversable){
|
||||||
|
foreach($rows as &$row){
|
||||||
|
if(isset($row[$columnMeta['name']])){
|
||||||
|
$row[$columnMeta['name']] = $row[$columnMeta['name']] + 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'DATETIME':
|
||||||
|
case 'DATE':
|
||||||
|
case 'TIMESTAMP':
|
||||||
|
// convert to date type?
|
||||||
|
break;
|
||||||
|
// default: keep as string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $subject
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isCountable($subject) {
|
||||||
|
return (is_array($subject) || ($subject instanceof \Countable));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
webseite/sys/sources/envms-fluentpdo/tests/01-basic.phpt
Normal file
31
webseite/sys/sources/envms-fluentpdo/tests/01-basic.phpt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
--TEST--
|
||||||
|
Basic operations
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')->where('id > ?', 0)->orderBy('name');
|
||||||
|
$query = $query->where('name = ?', 'Marek');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
print_r($query->fetch());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
WHERE id > ?
|
||||||
|
AND name = ?
|
||||||
|
ORDER BY name
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 0
|
||||||
|
[1] => Marek
|
||||||
|
)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[country_id] => 1
|
||||||
|
[type] => admin
|
||||||
|
[name] => Marek
|
||||||
|
)
|
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
Query with select, group, having, order
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent
|
||||||
|
->from('user')
|
||||||
|
->select(null)
|
||||||
|
->select('type, count(id) AS type_count')
|
||||||
|
->where('id > ?', 1)
|
||||||
|
->groupBy('type')
|
||||||
|
->having('type_count > ?', 1)
|
||||||
|
->orderBy('name');
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT type, count(id) AS type_count
|
||||||
|
FROM user
|
||||||
|
WHERE id > ?
|
||||||
|
GROUP BY type
|
||||||
|
HAVING type_count > ?
|
||||||
|
ORDER BY name
|
20
webseite/sys/sources/envms-fluentpdo/tests/03-from-id.phpt
Normal file
20
webseite/sys/sources/envms-fluentpdo/tests/03-from-id.phpt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
--TEST--
|
||||||
|
from($table, $id)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user', 2);
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
WHERE user.id = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 2
|
||||||
|
)
|
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
where(array(...))
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')->where(array(
|
||||||
|
'id' => 2,
|
||||||
|
'type' => 'author',
|
||||||
|
));
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
WHERE id = ?
|
||||||
|
AND type = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 2
|
||||||
|
[1] => author
|
||||||
|
)
|
@ -0,0 +1,20 @@
|
|||||||
|
--TEST--
|
||||||
|
where('column', 'value')
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')->where('type', 'author');
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
WHERE type = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => author
|
||||||
|
)
|
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
where('column', null)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')->where('type', null);
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
WHERE type is NULL
|
@ -0,0 +1,19 @@
|
|||||||
|
--TEST--
|
||||||
|
where('column', array(..))
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')->where('id', array(1,2,3));
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
WHERE id IN (1, 2, 3)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
)
|
@ -0,0 +1,30 @@
|
|||||||
|
--TEST--
|
||||||
|
where with named :params
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')
|
||||||
|
->where('type = :type', array(':type' => 'author'))
|
||||||
|
->where('id > :id AND name <> :name', array(':id' => 1, ':name' => 'Marek'));
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
foreach ($query as $row) {
|
||||||
|
echo "$row[name]\n";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
WHERE type = :type
|
||||||
|
AND id > :id
|
||||||
|
AND name <> :name
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[:type] => author
|
||||||
|
[:id] => 1
|
||||||
|
[:name] => Marek
|
||||||
|
)
|
||||||
|
Robert
|
25
webseite/sys/sources/envms-fluentpdo/tests/09-join-full.phpt
Normal file
25
webseite/sys/sources/envms-fluentpdo/tests/09-join-full.phpt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
full join
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')
|
||||||
|
->select('user.name')
|
||||||
|
->leftJoin('user ON user.id = article.user_id')
|
||||||
|
->orderBy('article.title');
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
foreach ($query as $row) {
|
||||||
|
echo "$row[name] - $row[title]\n";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*, user.name
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
||||||
|
ORDER BY article.title
|
||||||
|
Marek - article 1
|
||||||
|
Robert - article 2
|
||||||
|
Marek - article 3
|
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
short join - default join is left join
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->leftJoin('user');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('article')->leftJoin('user author');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('article')->leftJoin('user AS author');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user AS author ON author.id = article.user_id
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user AS author ON author.id = article.user_id
|
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
short join back reference
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')->innerJoin('article:');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('user')->innerJoin('article: with_articles');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('user')->innerJoin('article: AS with_articles');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
INNER JOIN article ON article.user_id = user.id
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
INNER JOIN article AS with_articles ON with_articles.user_id = user.id
|
||||||
|
SELECT user.*
|
||||||
|
FROM user
|
||||||
|
INNER JOIN article AS with_articles ON with_articles.user_id = user.id
|
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
join same two tables
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('comment')->leftJoin('article.user');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT comment.*
|
||||||
|
FROM comment
|
||||||
|
LEFT JOIN article ON article.id = comment.article_id
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
multi short join
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->innerJoin('comment:user AS comment_user');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->fetch());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
INNER JOIN comment ON comment.article_id = article.id
|
||||||
|
INNER JOIN user AS comment_user ON comment_user.id = comment.user_id
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[user_id] => 1
|
||||||
|
[published_at] => 2011-12-10 12:10:00
|
||||||
|
[title] => article 1
|
||||||
|
[content] => content 1
|
||||||
|
)
|
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
join two same tables
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->leftJoin('user')->leftJoin('user');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
@ -0,0 +1,32 @@
|
|||||||
|
--TEST--
|
||||||
|
join two tables via difference keys
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('comment')
|
||||||
|
->where('comment.id', 1)
|
||||||
|
->leftJoin('user comment_author')->select('comment_author.name AS comment_name')
|
||||||
|
->leftJoin('article.user AS article_author')->select('article_author.name AS author_name');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$result = $query->fetch();
|
||||||
|
print_r($result);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT comment.*, comment_author.name AS comment_name, article_author.name AS author_name
|
||||||
|
FROM comment
|
||||||
|
LEFT JOIN user AS comment_author ON comment_author.id = comment.user_id
|
||||||
|
LEFT JOIN article ON article.id = comment.article_id
|
||||||
|
LEFT JOIN user AS article_author ON article_author.id = article.user_id
|
||||||
|
WHERE comment.id = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[article_id] => 1
|
||||||
|
[user_id] => 2
|
||||||
|
[content] => comment 1.1
|
||||||
|
[comment_name] => Robert
|
||||||
|
[author_name] => Marek
|
||||||
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
--TEST--
|
||||||
|
Basic operations
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
|
||||||
|
echo "'" . Envms\FluentPDO\Utilities::toUpperWords('one') . "'\n";
|
||||||
|
echo "'" . Envms\FluentPDO\Utilities::toUpperWords(' one ') . "'\n";
|
||||||
|
echo "'" . Envms\FluentPDO\Utilities::toUpperWords('oneTwo') . "'\n";
|
||||||
|
echo "'" . Envms\FluentPDO\Utilities::toUpperWords('OneTwo') . "'\n";
|
||||||
|
echo "'" . Envms\FluentPDO\Utilities::toUpperWords('oneTwoThree') . "'\n";
|
||||||
|
echo "'" . Envms\FluentPDO\Utilities::toUpperWords(' oneTwoThree ') . "'\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
'ONE'
|
||||||
|
'ONE'
|
||||||
|
'ONE TWO'
|
||||||
|
'ONE TWO'
|
||||||
|
'ONE TWO THREE'
|
||||||
|
'ONE TWO THREE'
|
@ -0,0 +1,19 @@
|
|||||||
|
--TEST--
|
||||||
|
join in where
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->where('comment:content <> "" AND user.country.id = ?', 1);
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN comment ON comment.article_id = article.id
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
||||||
|
LEFT JOIN country ON country.id = user.country_id
|
||||||
|
WHERE comment.content <> ""
|
||||||
|
AND country.id = ?
|
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
join in where
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->select('user.name as author');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*, user.name as author
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
@ -0,0 +1,16 @@
|
|||||||
|
--TEST--
|
||||||
|
join in where
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->orderBy('user.name, article.title');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
||||||
|
ORDER BY user.name, article.title
|
@ -0,0 +1,33 @@
|
|||||||
|
--TEST--
|
||||||
|
join in where
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->groupBy('user.type')
|
||||||
|
->select(null)->select('user.type, count(article.id) as article_count');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$result = $query->fetchAll();
|
||||||
|
print_r($result);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.type, count(article.id) as article_count
|
||||||
|
FROM article
|
||||||
|
LEFT JOIN user ON user.id = article.user_id
|
||||||
|
GROUP BY user.type
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => Array
|
||||||
|
(
|
||||||
|
[type] => admin
|
||||||
|
[article_count] => 2
|
||||||
|
)
|
||||||
|
|
||||||
|
[1] => Array
|
||||||
|
(
|
||||||
|
[type] => author
|
||||||
|
[article_count] => 1
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
@ -0,0 +1,35 @@
|
|||||||
|
--TEST--
|
||||||
|
don't create second join if table or alias was joined
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->innerJoin('user AS author ON article.user_id = author.id')
|
||||||
|
->select('author.name');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('article')->innerJoin('user ON article.user_id = user.id')
|
||||||
|
->select('user.name');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('article')->innerJoin('user AS author ON article.user_id = author.id')
|
||||||
|
->select('author.country.name');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('article')->innerJoin('user ON article.user_id = user.id')
|
||||||
|
->select('user.country.name');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*, author.name
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user AS author ON article.user_id = author.id
|
||||||
|
SELECT article.*, user.name
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user ON article.user_id = user.id
|
||||||
|
SELECT article.*, country.name
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user AS author ON article.user_id = author.id
|
||||||
|
LEFT JOIN country ON country.id = author.country_id
|
||||||
|
SELECT article.*, country.name
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user ON article.user_id = user.id
|
||||||
|
LEFT JOIN country ON country.id = user.country_id
|
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
clause with referenced table before join
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->select('user.name')->innerJoin('user');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('article')->select('author.name')->innerJoin('user as author');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
$query = $fluent->from('user')->select('article:title')->innerJoin('article:');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*, user.name
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user ON user.id = article.user_id
|
||||||
|
SELECT article.*, author.name
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user AS author ON author.id = article.user_id
|
||||||
|
SELECT user.*, article.title
|
||||||
|
FROM user
|
||||||
|
INNER JOIN article ON article.user_id = user.id
|
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
aliases for clauses: group -> groupBy, order -> orderBy
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('article')->group('user_id')->order('id');
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*
|
||||||
|
FROM article
|
||||||
|
GROUP BY user_id
|
||||||
|
ORDER BY id
|
24
webseite/sys/sources/envms-fluentpdo/tests/24-fetch.phpt
Normal file
24
webseite/sys/sources/envms-fluentpdo/tests/24-fetch.phpt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
fetch
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
echo $fluent->from('user', 1)->fetch('name') . "\n";
|
||||||
|
print_r($fluent->from('user', 1)->fetch());
|
||||||
|
if ($fluent->from('user', 3)->fetch() === false) echo "false\n";
|
||||||
|
if ($fluent->from('user', 3)->fetch('name') === false) echo "false\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Marek
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[country_id] => 1
|
||||||
|
[type] => admin
|
||||||
|
[name] => Marek
|
||||||
|
)
|
||||||
|
false
|
||||||
|
false
|
@ -0,0 +1,38 @@
|
|||||||
|
--TEST--
|
||||||
|
fetch pairs, fetch all
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$result = $fluent->from('user')->fetchPairs('id', 'name');
|
||||||
|
print_r($result);
|
||||||
|
$result = $fluent->from('user')->fetchAll();
|
||||||
|
print_r($result);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[1] => Marek
|
||||||
|
[2] => Robert
|
||||||
|
)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[country_id] => 1
|
||||||
|
[type] => admin
|
||||||
|
[name] => Marek
|
||||||
|
)
|
||||||
|
|
||||||
|
[1] => Array
|
||||||
|
(
|
||||||
|
[id] => 2
|
||||||
|
[country_id] => 1
|
||||||
|
[type] => author
|
||||||
|
[name] => Robert
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
27
webseite/sys/sources/envms-fluentpdo/tests/26-debug.phpt
Normal file
27
webseite/sys/sources/envms-fluentpdo/tests/26-debug.phpt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
--TEST--
|
||||||
|
debug callback
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $fluent->debug = true; // log queries to STDERR
|
||||||
|
* $fluent->debug = $callback; // see below
|
||||||
|
*/
|
||||||
|
|
||||||
|
$fluent->debug = function($BaseQuery) {
|
||||||
|
echo "query: " . $BaseQuery->getQuery(false) . "\n";
|
||||||
|
echo "parameters: " . implode(', ', $BaseQuery->getParameters()) . "\n";
|
||||||
|
echo "rowCount: " . $BaseQuery->getResult()->rowCount() . "\n";
|
||||||
|
// time is impossible to test (each time is other)
|
||||||
|
// echo $FluentQuery->getTime() . "\n";
|
||||||
|
};
|
||||||
|
|
||||||
|
$fluent->from('user')->where('id < ? AND name <> ?', 7, 'Peter')->execute();
|
||||||
|
$fluent->debug = null;
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
query: SELECT user.* FROM user WHERE id < ? AND name <> ?
|
||||||
|
parameters: 7, Peter
|
||||||
|
rowCount: 2
|
@ -0,0 +1,29 @@
|
|||||||
|
--TEST--
|
||||||
|
fetch all with params
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$result = $fluent->from('user')->fetchAll('id', 'type, name');
|
||||||
|
print_r($result);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[1] => Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[type] => admin
|
||||||
|
[name] => Marek
|
||||||
|
)
|
||||||
|
|
||||||
|
[2] => Array
|
||||||
|
(
|
||||||
|
[id] => 2
|
||||||
|
[type] => author
|
||||||
|
[name] => Robert
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
FROM table from other database
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('db2.user')->order('db2.user.name')->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT db2.user.*
|
||||||
|
FROM db2.user
|
||||||
|
ORDER BY db2.user.name
|
@ -0,0 +1,18 @@
|
|||||||
|
--TEST--
|
||||||
|
FROM table from other database
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user')
|
||||||
|
->innerJoin('db2.types ON db2.types.id = user.type')
|
||||||
|
->select('db2.types.*')
|
||||||
|
->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT user.*, db2.types.*
|
||||||
|
FROM user
|
||||||
|
INNER JOIN db2.types ON db2.types.id = user.type
|
@ -0,0 +1,41 @@
|
|||||||
|
--TEST--
|
||||||
|
join using USING
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var $fluent2 Envms\FluentPDO\Query */
|
||||||
|
$fluent_structure2 = new Envms\FluentPDO\Structure('%s_id', '%s_id');
|
||||||
|
$fluent2 = new Envms\FluentPDO\Query($pdo, $fluent_structure2);
|
||||||
|
|
||||||
|
$query = $fluent2->from('article')
|
||||||
|
->innerJoin('user USING (user_id)')
|
||||||
|
->select('user.*')
|
||||||
|
->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
|
||||||
|
$query = $fluent2->from('article')
|
||||||
|
->innerJoin('user u USING (user_id)')
|
||||||
|
->select('u.*')
|
||||||
|
->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
|
||||||
|
$query = $fluent2->from('article')
|
||||||
|
->innerJoin('user AS u USING (user_id)')
|
||||||
|
->select('u.*')
|
||||||
|
->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
|
||||||
|
unset($fluent_structure2);
|
||||||
|
unset($fluent2);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT article.*, user.*
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user USING (user_id)
|
||||||
|
SELECT article.*, u.*
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user u USING (user_id)
|
||||||
|
SELECT article.*, u.*
|
||||||
|
FROM article
|
||||||
|
INNER JOIN user AS u USING (user_id)
|
@ -0,0 +1,28 @@
|
|||||||
|
--TEST--
|
||||||
|
FROM with alias
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('user author')->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
$query = $fluent->from('user AS author')->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
$query = $fluent->from('user AS author', 1)->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
$query = $fluent->from('user AS author')->select('country.name')->getQuery();
|
||||||
|
echo "$query\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
SELECT author.*
|
||||||
|
FROM user author
|
||||||
|
SELECT author.*
|
||||||
|
FROM user AS author
|
||||||
|
SELECT author.*
|
||||||
|
FROM user AS author
|
||||||
|
WHERE author.id = ?
|
||||||
|
SELECT author.*, country.name
|
||||||
|
FROM user AS author
|
||||||
|
LEFT JOIN country ON country.id = user AS author.country_id
|
29
webseite/sys/sources/envms-fluentpdo/tests/32-insert.phpt
Normal file
29
webseite/sys/sources/envms-fluentpdo/tests/32-insert.phpt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
--TEST--
|
||||||
|
insert into
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->insertInto('article',
|
||||||
|
array(
|
||||||
|
'user_id' => 1,
|
||||||
|
'title' => 'new title',
|
||||||
|
'content' => 'new content'
|
||||||
|
));
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
$lastInsert = $query->execute();
|
||||||
|
|
||||||
|
$pdo->query('DELETE FROM article WHERE id > 3')->execute();
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
INSERT INTO article (user_id, title, content)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 1
|
||||||
|
[1] => new title
|
||||||
|
[2] => new content
|
||||||
|
)
|
@ -0,0 +1,54 @@
|
|||||||
|
--TEST--
|
||||||
|
INSERT with ON DUPLICATE KEY UPDATE
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/** @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->insertInto('article', array('id' => 1))
|
||||||
|
->onDuplicateKeyUpdate(array(
|
||||||
|
'title' => 'article 1b',
|
||||||
|
'content' => new Envms\FluentPDO\Literal('abs(-1)') // let's update with a literal and a parameter value
|
||||||
|
));
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
echo 'last_inserted_id = ' . $query->execute() . "\n";
|
||||||
|
$q = $fluent->from('article', 1)->fetch();
|
||||||
|
print_r($q);
|
||||||
|
$query = $fluent->insertInto('article', array('id' => 1))
|
||||||
|
->onDuplicateKeyUpdate(array(
|
||||||
|
'title' => 'article 1',
|
||||||
|
'content' => 'content 1',
|
||||||
|
))->execute();
|
||||||
|
echo "last_inserted_id = $query\n";
|
||||||
|
$q = $fluent->from('article', 1)->fetch();
|
||||||
|
print_r($q);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
INSERT INTO article (id)
|
||||||
|
VALUES (?)
|
||||||
|
ON DUPLICATE KEY UPDATE title = ?, content = abs(-1)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 1
|
||||||
|
[1] => article 1b
|
||||||
|
)
|
||||||
|
last_inserted_id = 1
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[user_id] => 1
|
||||||
|
[published_at] => 2011-12-10 12:10:00
|
||||||
|
[title] => article 1b
|
||||||
|
[content] => 1
|
||||||
|
)
|
||||||
|
last_inserted_id = 1
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[user_id] => 1
|
||||||
|
[published_at] => 2011-12-10 12:10:00
|
||||||
|
[title] => article 1
|
||||||
|
[content] => content 1
|
||||||
|
)
|
@ -0,0 +1,26 @@
|
|||||||
|
--TEST--
|
||||||
|
insert ignore
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->insertInto('article',
|
||||||
|
array(
|
||||||
|
'user_id' => 1,
|
||||||
|
'title' => 'new title',
|
||||||
|
'content' => 'new content',
|
||||||
|
))->ignore();
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
INSERT IGNORE INTO article (user_id, title, content)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 1
|
||||||
|
[1] => new title
|
||||||
|
[2] => new content
|
||||||
|
)
|
@ -0,0 +1,28 @@
|
|||||||
|
--TEST--
|
||||||
|
insert with literal
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->insertInto('article',
|
||||||
|
array(
|
||||||
|
'user_id' => 1,
|
||||||
|
'updated_at' => new Envms\FluentPDO\Literal('NOW()'),
|
||||||
|
'title' => 'new title',
|
||||||
|
'content' => 'new content',
|
||||||
|
));
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters());
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
INSERT INTO article (user_id, updated_at, title, content)
|
||||||
|
VALUES (?, NOW(), ?, ?)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 1
|
||||||
|
[1] => new title
|
||||||
|
[2] => new content
|
||||||
|
)
|
@ -0,0 +1,49 @@
|
|||||||
|
--TEST--
|
||||||
|
Disable and enable smart join feature
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->from('comment')
|
||||||
|
->select('user.name')
|
||||||
|
->orderBy('article.published_at')
|
||||||
|
->getQuery();
|
||||||
|
echo "-- Plain:\n$query\n\n";
|
||||||
|
|
||||||
|
$query = $fluent->from('comment')
|
||||||
|
->select('user.name')
|
||||||
|
->disableSmartJoin()
|
||||||
|
->orderBy('article.published_at')
|
||||||
|
->getQuery();
|
||||||
|
echo "-- Disable:\n$query\n\n";
|
||||||
|
|
||||||
|
$query = $fluent->from('comment')
|
||||||
|
->disableSmartJoin()
|
||||||
|
->select('user.name')
|
||||||
|
->enableSmartJoin()
|
||||||
|
->orderBy('article.published_at')
|
||||||
|
->getQuery();
|
||||||
|
echo "-- Disable and enable:\n$query\n\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
-- Plain:
|
||||||
|
SELECT comment.*, user.name
|
||||||
|
FROM comment
|
||||||
|
LEFT JOIN user ON user.id = comment.user_id
|
||||||
|
LEFT JOIN article ON article.id = comment.article_id
|
||||||
|
ORDER BY article.published_at
|
||||||
|
|
||||||
|
-- Disable:
|
||||||
|
SELECT comment.*, user.name
|
||||||
|
FROM comment
|
||||||
|
ORDER BY article.published_at
|
||||||
|
|
||||||
|
-- Disable and enable:
|
||||||
|
SELECT comment.*, user.name
|
||||||
|
FROM comment
|
||||||
|
LEFT JOIN user ON user.id = comment.user_id
|
||||||
|
LEFT JOIN article ON article.id = comment.article_id
|
||||||
|
ORDER BY article.published_at
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
--TEST--
|
||||||
|
fetch column
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
echo $fluent->from('user', 1)->fetchColumn() . "\n";
|
||||||
|
echo $fluent->from('user', 1)->fetchColumn(3) . "\n";
|
||||||
|
if ($fluent->from('user', 3)->fetchColumn() === false) echo "false\n";
|
||||||
|
if ($fluent->from('user', 3)->fetchColumn(3) === false) echo "false\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
1
|
||||||
|
Marek
|
||||||
|
false
|
||||||
|
false
|
@ -0,0 +1,31 @@
|
|||||||
|
--TEST--
|
||||||
|
PDO::FETCH_OBJ option.
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
|
||||||
|
$query = $fluent->from('user')->where('id > ?', 0)->orderBy('name');
|
||||||
|
$query = $query->where('name = ?', 'Marek');
|
||||||
|
$fluent->getPdo()->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
|
||||||
|
|
||||||
|
print_r($query->getParameters());
|
||||||
|
print_r($query->fetch());
|
||||||
|
|
||||||
|
// Set back for other tests.
|
||||||
|
$fluent->getPdo()->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_BOTH);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 0
|
||||||
|
[1] => Marek
|
||||||
|
)
|
||||||
|
stdClass Object
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[country_id] => 1
|
||||||
|
[type] => admin
|
||||||
|
[name] => Marek
|
||||||
|
)
|
@ -0,0 +1,39 @@
|
|||||||
|
--TEST--
|
||||||
|
Basic update
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->update('country')->set('name', 'aikavolS')->where('id', 1);
|
||||||
|
$query->execute();
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters()) . "\n";
|
||||||
|
|
||||||
|
$query = $fluent->from('country')->where('id', 1);
|
||||||
|
print_r($query->fetch());
|
||||||
|
|
||||||
|
$fluent->update('country')->set('name', 'Slovakia')->where('id', 1)->execute();
|
||||||
|
|
||||||
|
$query = $fluent->from('country')->where('id', 1);
|
||||||
|
print_r($query->fetch());
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
UPDATE country
|
||||||
|
SET name = ?
|
||||||
|
WHERE id = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => aikavolS
|
||||||
|
[1] => 1
|
||||||
|
)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[name] => aikavolS
|
||||||
|
)
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[id] => 1
|
||||||
|
[name] => Slovakia
|
||||||
|
)
|
@ -0,0 +1,19 @@
|
|||||||
|
--TEST--
|
||||||
|
Basic update
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->update('article')->set('published_at', new Envms\FluentPDO\Literal('NOW()'))->where('user_id', 1);
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters()) . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
UPDATE article
|
||||||
|
SET published_at = NOW()
|
||||||
|
WHERE user_id = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => 1
|
||||||
|
)
|
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
Basic update
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->update('user')->set(array('name' => 'keraM', '`type`' => 'author'))->where('id', 1);
|
||||||
|
$query->execute();
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters()) . "\n";
|
||||||
|
|
||||||
|
$query = $fluent->update('user')->set(array('name' => 'Marek', '`type`' => 'admin'))->where('id', 1);
|
||||||
|
$query->execute();
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
UPDATE user
|
||||||
|
SET name = ?, `type` = ?
|
||||||
|
WHERE id = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => keraM
|
||||||
|
[1] => author
|
||||||
|
[2] => 1
|
||||||
|
)
|
@ -0,0 +1,26 @@
|
|||||||
|
--TEST--
|
||||||
|
Basic update
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->update('user')
|
||||||
|
->outerJoin('country ON country.id = user.country_id')
|
||||||
|
->set(array('name' => 'keraM', '`type`' => 'author'))
|
||||||
|
->where('id', 1);
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters()) . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
UPDATE user
|
||||||
|
OUTER JOIN country ON country.id = user.country_id
|
||||||
|
SET name = ?, `type` = ?
|
||||||
|
WHERE id = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => keraM
|
||||||
|
[1] => author
|
||||||
|
[2] => 1
|
||||||
|
)
|
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
Update with smart join
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->update('user')
|
||||||
|
->set(array('type' => 'author'))
|
||||||
|
->where('country.id', 1);
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters()) . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
UPDATE user
|
||||||
|
LEFT JOIN country ON country.id = user.country_id
|
||||||
|
SET type = ?
|
||||||
|
WHERE country.id = ?
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => author
|
||||||
|
[1] => 1
|
||||||
|
)
|
@ -0,0 +1,27 @@
|
|||||||
|
--TEST--
|
||||||
|
Update with ORDER BY and LIMIT
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||||
|
/* @var Envms\FluentPDO\Query */
|
||||||
|
|
||||||
|
$query = $fluent->update('user')
|
||||||
|
->set(array('type' => 'author'))
|
||||||
|
->where('id', 2)
|
||||||
|
->orderBy('name')
|
||||||
|
->limit(1);
|
||||||
|
|
||||||
|
echo $query->getQuery() . "\n";
|
||||||
|
print_r($query->getParameters()) . "\n";
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
UPDATE user
|
||||||
|
SET type = ?
|
||||||
|
WHERE id = ?
|
||||||
|
ORDER BY name
|
||||||
|
LIMIT 1
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[0] => author
|
||||||
|
[1] => 2
|
||||||
|
)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user