Added some models and worked on API-class
parent
e4f224cde7
commit
370055e3cc
|
@ -15,6 +15,10 @@ spl_autoload_register(function ($class_name) {
|
|||
elseif(file_exists(__DIR__ . "/models/" . $class_name . ".php")) {
|
||||
include_once __DIR__."/models/Model.php";
|
||||
include_once __DIR__ . "/models/" . $class_name . ".php";
|
||||
// echo "Load class ".__DIR__."/models/".$class_name.'.php'."<br>\n";
|
||||
}elseif(file_exists(__DIR__ . "/models/Plan/" . $class_name . ".php")) {
|
||||
include_once __DIR__."/models/Model.php";
|
||||
include_once __DIR__ . "/models/Plan/" . $class_name . ".php";
|
||||
// echo "Load class ".__DIR__."/models/".$class_name.'.php'."<br>\n";
|
||||
}
|
||||
});
|
||||
|
|
|
@ -227,6 +227,7 @@ class Auth {
|
|||
}
|
||||
|
||||
public static function currentUserId(){
|
||||
$a = Auth::getInstance();
|
||||
return $_SESSION['user_id'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ class WebPage {
|
|||
public $pr = ""; // project root
|
||||
public $err = array();
|
||||
public $msg = array();
|
||||
public $data = array();
|
||||
|
||||
|
||||
public function __construct(){
|
||||
|
|
|
@ -9,8 +9,11 @@ abstract class Model {
|
|||
protected static $table;
|
||||
protected static $tableExtends = null;
|
||||
protected static $fields;
|
||||
protected $isLoaded = false;
|
||||
protected $initialValues = [];
|
||||
protected $errors = [];
|
||||
|
||||
public function __construct(){
|
||||
public function __construct($id = 0){
|
||||
foreach (static::$fields as $field => $type){
|
||||
switch ($type){
|
||||
case "INT":
|
||||
|
@ -23,6 +26,29 @@ abstract class Model {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($id > 0){
|
||||
try {
|
||||
$firstField = array_keys(static::$fields)[0];
|
||||
$result = DB::query("SELECT `".implode("`, `", array_keys(static::$fields))."` FROM ".static::$database.".".static::$table . " t1 WHERE `$firstField` = ?", $id )->fetch_assoc();
|
||||
|
||||
$values = [];
|
||||
foreach (static::$fields as $field => $type){
|
||||
$this->{ $field } = $result[$field];
|
||||
|
||||
// cache initial value
|
||||
$values[$field] = $this->{$field};
|
||||
}
|
||||
|
||||
$this->isLoaded = true;
|
||||
|
||||
} catch (DatabaseException $e) {
|
||||
$this->errors[] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$this->initialValues = $this->asArray();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,6 +121,7 @@ abstract class Model {
|
|||
$result = array();
|
||||
while($row = $q->fetch_assoc()){
|
||||
$res = new static();
|
||||
$res->isLoaded = true;
|
||||
|
||||
/* Alternative for non-joined queries:
|
||||
foreach (static::$fields as $key => $ignore){
|
||||
|
@ -118,9 +145,67 @@ abstract class Model {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function isLoaded() : bool {
|
||||
return $this->isLoaded;
|
||||
}
|
||||
|
||||
// public function set($value, )
|
||||
|
||||
/**
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function save(){
|
||||
|
||||
$newFields = [];
|
||||
$newValues = [];
|
||||
$allExceptFirstFields = [];
|
||||
$allExceptFirstValues = [];
|
||||
|
||||
$fieldCount = 0;
|
||||
foreach(static::$fields as $field => $type){
|
||||
$currValue = $this->{ $field };
|
||||
if(!empty($this->initialValues) && $currValue != $this->initialValues[$field]){
|
||||
$newFields[] = $field;
|
||||
$newValues[] = $currValue;
|
||||
}
|
||||
if($fieldCount > 0){
|
||||
$allExceptFirstFields[] = $field;
|
||||
$allExceptFirstValues[] = $currValue;
|
||||
}
|
||||
|
||||
$fieldCount++;
|
||||
}
|
||||
|
||||
if(!empty($this->initialValues) && empty($newValues)){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->isLoaded()){
|
||||
$updateSets = [];
|
||||
foreach($newFields as $field){
|
||||
$updateSets[] = "`$field` = ?";
|
||||
}
|
||||
|
||||
DB::query(sprintf('UPDATE %s.%s SET %s WHERE %s LIMIT 1', static::$database, static::$table, implode(', ', $updateSets), "`" . array_keys(static::$fields)[0] . "` = ?"), array_merge($newValues, [$this->{array_keys(static::$fields)[0]}]));
|
||||
}
|
||||
else {
|
||||
$sql = sprintf('INSERT INTO %s.%s (%s) VALUE (%s)', static::$database, static::$table, implode(', ', $newFields), implode(', ', array_fill(0, count($newFields), '?')));
|
||||
|
||||
DB::query($sql, $newValues);
|
||||
$insertid = DB::insert_id();
|
||||
$this->{ array_keys(static::$fields)[0] } = $insertid;
|
||||
$this->isLoaded = true;
|
||||
return $insertid;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function asArray(): array {
|
||||
$arr = [];
|
||||
foreach ($this as $key => $val){
|
||||
$arr[$key] = $val;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
//namespace models;
|
||||
|
||||
class PlanStore extends Model {
|
||||
protected static $table = "plan_store";
|
||||
protected static $fields = [
|
||||
"plan_store_id" => "INT",
|
||||
"space_id" => "INT",
|
||||
"name" => "VARCHAR",
|
||||
"created" => "DATETIME",
|
||||
"state" => [ 'planning', 'shopping', 'closed' ]
|
||||
];
|
||||
|
||||
public static function getUserSpaces(){
|
||||
$spaces = array_merge(
|
||||
static::get([ 'owner_id' => Auth::currentUserId() ]),
|
||||
PlanSpaceMember::get([ 'member_id' => Auth::currentUserId() ])
|
||||
);
|
||||
|
||||
foreach ($spaces as $s){
|
||||
if($s->space_name == ""){
|
||||
$spaceOwner = User::get(['user_id' => $s->owner_id])[0];
|
||||
$s->space_name = $spaceOwner->full_name != "" ? sprintf('%ss space', $spaceOwner->full_name ) : "A users space";;
|
||||
}
|
||||
}
|
||||
|
||||
return $spaces;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
//namespace models;
|
||||
|
||||
class PlanSpace extends Model {
|
||||
protected static $table = "plan_space";
|
||||
protected static $fields = [
|
||||
"space_id" => "INT",
|
||||
"space_name" => "VARCHAR",
|
||||
"owner_id" => "INT",
|
||||
"space_type" => [ 'STORE', 'CHECK', 'CALORIES' ]
|
||||
];
|
||||
|
||||
public static function getUserSpaces(){
|
||||
$spaces = array_merge(
|
||||
static::get([ 'owner_id' => Auth::currentUserId() ]),
|
||||
PlanSpaceMember::get([ 'member_id' => Auth::currentUserId() ])
|
||||
);
|
||||
|
||||
foreach ($spaces as $s){
|
||||
if($s->space_name == ""){
|
||||
$spaceOwner = User::get(['user_id' => $s->owner_id])[0];
|
||||
$s->space_name = $spaceOwner->full_name != "" ? sprintf('%ss space', $spaceOwner->full_name ) : "A users space";;
|
||||
}
|
||||
}
|
||||
|
||||
return $spaces;
|
||||
}
|
||||
}
|
|
@ -7,14 +7,23 @@ class PlanSpace extends Model {
|
|||
protected static $fields = [
|
||||
"space_id" => "INT",
|
||||
"space_name" => "VARCHAR",
|
||||
"owner_id" => "VARCHAR",
|
||||
"owner_id" => "INT",
|
||||
"space_type" => [ 'STORE', 'CHECK', 'CALORIES' ]
|
||||
];
|
||||
|
||||
public static function getUserSpaces(){
|
||||
return array_merge(
|
||||
$spaces = array_merge(
|
||||
static::get([ 'owner_id' => Auth::currentUserId() ]),
|
||||
PlanSpaceMember::get([ 'member_id' => Auth::currentUserId() ])
|
||||
);
|
||||
|
||||
foreach ($spaces as $s){
|
||||
if($s->space_name == ""){
|
||||
$spaceOwner = User::get(['user_id' => $s->owner_id])[0];
|
||||
$s->space_name = $spaceOwner->full_name != "" ? sprintf('%ss space', $spaceOwner->full_name ) : "A users space";;
|
||||
}
|
||||
}
|
||||
|
||||
return $spaces;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
//namespace models;
|
||||
|
||||
class User extends Model {
|
||||
protected static $table = "user";
|
||||
protected static $fields = [
|
||||
"user_id" => "INT",
|
||||
"md5_id" => "VARCHAR",
|
||||
"full_name" => "VARCHAR",
|
||||
"user_email" => "VARCHAR",
|
||||
"user_level" => "INT",
|
||||
"date" => "DATE"
|
||||
];
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
<label class="input-group-text" for="spaceSelect">Space:</label>
|
||||
<select class="form-select" id='spaceSelect' aria-label="Select space">
|
||||
{% for space in spaces %}
|
||||
<option>...</option>
|
||||
<option value="{{ space.space_id }}">{{ space.space_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,13 @@ abstract class Api {
|
|||
}
|
||||
|
||||
if($this->success){
|
||||
$this->execute();
|
||||
try {
|
||||
$this->execute();
|
||||
}
|
||||
catch (Exception | DatabaseException $e){
|
||||
$this->success = false;
|
||||
$this->message = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$this->printResult();
|
||||
|
@ -52,6 +58,9 @@ abstract class Api {
|
|||
echo json_encode( $returns );
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
protected function execute(){ }
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
include_once '../../../Router.php';
|
||||
include_once 'api.php';
|
||||
|
||||
|
||||
$dirs = [];
|
||||
$file = "";
|
||||
$args = [];
|
||||
|
@ -22,9 +30,15 @@ foreach($_GET as $arg){
|
|||
|
||||
if(!empty($filePath)){
|
||||
$_GET['args'] = $args;
|
||||
echo $filePath;
|
||||
// echo __dir__ . '/' . $filePath;
|
||||
|
||||
// include $filePath;
|
||||
if(file_exists( __dir__ . '/' . $filePath )){
|
||||
include_once __dir__ . '/' . $filePath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
http_send_status(500);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([ 'error' => "API not found." ]);
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
class CreateStoreApi extends Api {
|
||||
|
||||
protected $methods = [
|
||||
"POST" => [
|
||||
[
|
||||
"name" => "space_id",
|
||||
"keyword" => "space_id",
|
||||
"type" => VERIFY_STRING
|
||||
],
|
||||
[
|
||||
"name" => "name",
|
||||
"keyword" => "name",
|
||||
"type" => VERIFY_STRING
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
function execute(){
|
||||
try {
|
||||
$store = new PlanStore();
|
||||
$store->space_id = $this->data['space_id'];
|
||||
$store->name = $this->data['name'];
|
||||
|
||||
$this->result = $store->save();
|
||||
|
||||
$this->success = true;
|
||||
$this->message = "OK";
|
||||
}
|
||||
catch (DatabaseException $e){
|
||||
$this->success = false;
|
||||
$this->message = "Error: " . $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$request = new CreateStoreApi();
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
class ModifyStoreApi extends Api {
|
||||
|
||||
protected $methods = [
|
||||
"POST" => [
|
||||
[
|
||||
"name" => "store_id",
|
||||
"keyword" => "store_id",
|
||||
"type" => VERIFY_INT
|
||||
],
|
||||
[
|
||||
"name" => "newname",
|
||||
"keyword" => "newname",
|
||||
"type" => VERIFY_STRING
|
||||
],
|
||||
[
|
||||
"name" => "state",
|
||||
"keyword" => "state",
|
||||
"type" => VERIFY_STRING
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
function execute(){
|
||||
|
||||
$store = PlanStore::get(['plan_store_id' => $this->data['store_id']])[0];
|
||||
if(isset($this->data['newname'])){
|
||||
$store->name = $this->data['newname'];
|
||||
}
|
||||
elseif(isset($this->data['state'])){
|
||||
$store->state = $this->data['state'];
|
||||
}
|
||||
|
||||
|
||||
$store->save();
|
||||
|
||||
$this->result = $store;
|
||||
|
||||
$this->success = true;
|
||||
$this->message = "OK";
|
||||
}
|
||||
}
|
||||
|
||||
$request = new ModifyStoreApi();
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
class GetStoresApi extends Api {
|
||||
|
||||
protected $methods = [
|
||||
"GET" => [
|
||||
[
|
||||
"name" => "space",
|
||||
"keyword" => "space",
|
||||
"type" => VERIFY_INT
|
||||
],
|
||||
],
|
||||
"URI" => [
|
||||
[
|
||||
"name" => "space",
|
||||
"keyword" => "space",
|
||||
"type" => VERIFY_INT
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
function execute(){
|
||||
$stores = PlanStore::get(['space_id' => $this->data['space'] ]);
|
||||
|
||||
$this->result = $stores;
|
||||
|
||||
$this->success = true;
|
||||
$this->message = "OK";
|
||||
}
|
||||
}
|
||||
|
||||
$request = new GetStoresApi();
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
class CreateSpacesApi extends Api {
|
||||
|
||||
protected $methods = [
|
||||
"POST" => [
|
||||
[
|
||||
"name" => "space_name",
|
||||
"keyword" => "space_name",
|
||||
"type" => VERIFY_STRING
|
||||
],
|
||||
[
|
||||
"name" => "space_type",
|
||||
"keyword" => "space_type",
|
||||
"type" => VERIFY_STRING
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
function execute(){
|
||||
|
||||
$space = new PlanSpace();
|
||||
$space->space_name = $this->data['space_name'];
|
||||
$space->space_type = $this->data['space_type'] ?? 'STORE';
|
||||
$space->owner_id = Auth::currentUserId();
|
||||
|
||||
$this->result = $space->save();
|
||||
|
||||
$this->success = true;
|
||||
$this->message = "OK";
|
||||
}
|
||||
}
|
||||
|
||||
$request = new CreateSpacesApi();
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
require_once '../api.php';
|
||||
|
||||
class GetSpacesApi extends Api {
|
||||
|
||||
protected $methods = [
|
||||
|
@ -15,7 +13,8 @@ class GetSpacesApi extends Api {
|
|||
];
|
||||
|
||||
function execute(){
|
||||
$this->result = PlanSpace::get();
|
||||
$this->result = PlanSpace::getUserSpaces();
|
||||
|
||||
$this->success = true;
|
||||
$this->message = "OK";
|
||||
}
|
||||
|
|
125
www/plan/plan.js
125
www/plan/plan.js
|
@ -227,7 +227,8 @@ class Store {
|
|||
}
|
||||
|
||||
if(prevState !== state){
|
||||
ajaxReq({ plan: 'setState', storeID: this.storeID, state: this.state });
|
||||
// ajaxReq({ plan: 'setState', storeID: this.storeID, state: this.state });
|
||||
qAPI('plan/modify', 'POST', { store_id: this.storeID, state: this.state })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,7 +613,7 @@ class Store {
|
|||
getStoreID(){
|
||||
let that = this;
|
||||
|
||||
return ajaxReq({ plan: 'saveStore', storeName: this.title })
|
||||
return qAPI('plan/create', 'POST', { space_id: spaceID, name: this.title })
|
||||
.done(json => {
|
||||
console.log("getStore:", json);
|
||||
that.storeID = json['data'];
|
||||
|
@ -624,7 +625,14 @@ class Store {
|
|||
this.title = newName;
|
||||
|
||||
if(this.storeID !== null){
|
||||
return ajaxReq({ plan: 'renameStore', storeID: this.storeID, newName: newName });
|
||||
return qAPI('plan/modify', 'POST', { store_id: this.storeID, newname: newName })
|
||||
// return ajaxReq({ plan: 'renameStore', storeID: this.storeID, newName: newName });
|
||||
}
|
||||
else {
|
||||
return qAPI('plan/create', 'POST', { space_id: spaceID, name: this.title }).done(json => {
|
||||
this.storeID = json.data;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Return blank ajax as a false
|
||||
|
@ -663,63 +671,54 @@ function updateTotalPrice(){
|
|||
}
|
||||
|
||||
let spaceID = 0;
|
||||
function getSpaces(){
|
||||
$("#stores").html("Loading...");
|
||||
return ajaxReq({plan: 'spaces'}).done(json => {
|
||||
let optionsHtml = "";
|
||||
|
||||
// console.log(json);
|
||||
|
||||
let spaceNum = 1;
|
||||
for(const spaceI in json.data.spaces){
|
||||
const space = json.data.spaces[spaceI];
|
||||
if(spaceID === 0){
|
||||
spaceID = space['space_id'];
|
||||
}
|
||||
let spaceName = space['space_name'] || "Space "+spaceNum;
|
||||
optionsHtml += "<option value='"+space['space_id']+"'>"+spaceName+"</option>\n";
|
||||
spaceNum++;
|
||||
}
|
||||
|
||||
let spaceSelectElem = $("#spaceSelect");
|
||||
spaceSelectElem
|
||||
.html(optionsHtml)
|
||||
.on('change', ev => {
|
||||
spaceID = $(ev.target).val();
|
||||
getStores(spaceID);
|
||||
});
|
||||
|
||||
if(typeof json.data.lastSpace !== "undefined"){
|
||||
spaceID = Number(json.data.lastSpace);
|
||||
spaceSelectElem.val(spaceID);
|
||||
}
|
||||
});
|
||||
// function getSpaces(){
|
||||
// $("#stores").html("Loading...");
|
||||
// return ajaxReq({plan: 'spaces'}).done(json => {
|
||||
// let optionsHtml = "";
|
||||
//
|
||||
// console.log(json);
|
||||
//
|
||||
// let spaceNum = 1;
|
||||
// for(const spaceI in json.data.spaces){
|
||||
// const space = json.data.spaces[spaceI];
|
||||
// if(spaceID === 0){
|
||||
// spaceID = space['space_id'];
|
||||
// }
|
||||
// let spaceName = space['space_name'] || "Space "+spaceNum;
|
||||
// optionsHtml += "<option value='"+space['space_id']+"'>"+spaceName+"</option>\n";
|
||||
// spaceNum++;
|
||||
// }
|
||||
// .html(optionsHtml)
|
||||
|
||||
|
||||
}
|
||||
getSpaces().done(() => { getStores(spaceID); });
|
||||
|
||||
// if(typeof json.data.lastSpace !== "undefined"){
|
||||
// spaceID = Number(json.data.lastSpace);
|
||||
// spaceSelectElem.val(spaceID);
|
||||
// }
|
||||
// });
|
||||
|
||||
// }
|
||||
// getSpaces().done(() => { getStores(spaceID); });
|
||||
|
||||
let spaceSelectElem = $("#spaceSelect");
|
||||
spaceSelectElem.on('change', ev => {
|
||||
// console.debug('Change space');
|
||||
spaceID = $(ev.target).val();
|
||||
getStores(spaceID);
|
||||
}).trigger('change');
|
||||
|
||||
|
||||
// GET STORES
|
||||
function getStores(spaceID){
|
||||
spaceID = spaceID || 0;
|
||||
|
||||
// $("#stores").html("");
|
||||
stores = [];
|
||||
|
||||
let options = { plan: '' };
|
||||
if(spaceID !== 0){
|
||||
options = { plan: '', space: spaceID }
|
||||
}
|
||||
|
||||
return $.getJSON('do.php', options)
|
||||
return qAPI('plan/stores/'+spaceID )
|
||||
.done(json => {
|
||||
if(handleJsonErrors(json)){
|
||||
return;
|
||||
}
|
||||
|
||||
$("#stores").html("");
|
||||
|
||||
// console.log(json);
|
||||
for(const store in json.data){
|
||||
let storeKey = stores.length;
|
||||
|
||||
|
@ -735,12 +734,13 @@ function getStores(spaceID){
|
|||
stores[storeKey].setState(json.data[store].state, 1);
|
||||
}
|
||||
updateTotalPrice();
|
||||
})
|
||||
.fail(handleAjaxErrors);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function ajaxReq( data ){
|
||||
console.log("REQUEST STOPPED", data);
|
||||
return false;
|
||||
if(typeof spaceID !== "undefined" && spaceID !== 0){
|
||||
data.space = spaceID;
|
||||
}
|
||||
|
@ -756,10 +756,31 @@ function ajaxReq( data ){
|
|||
.fail(handleAjaxErrors);
|
||||
}
|
||||
|
||||
function qAPI( path, method, data ){
|
||||
method = method || 'GET';
|
||||
data = data || {};
|
||||
|
||||
// if(typeof spaceID !== "undefined" && spaceID !== 0){
|
||||
// data.space = spaceID;
|
||||
// }
|
||||
|
||||
return $.ajax({
|
||||
method: method,
|
||||
url: "/api/v2/" + path,
|
||||
data: data,
|
||||
dataType: 'JSON'
|
||||
})
|
||||
.done(json => {
|
||||
return !handleJsonErrors(json);
|
||||
})
|
||||
.fail(handleAjaxErrors);
|
||||
}
|
||||
|
||||
function handleJsonErrors(json){
|
||||
if(typeof json.status != "undefined" && json.status !== 0){
|
||||
if(typeof json.status != "undefined" && json.status !== true && json.status !== 0){
|
||||
if(json.message === "Not logged in"){
|
||||
location.href = '../login.php';
|
||||
// location.href = '../login.php';
|
||||
alert("Not logged in...");
|
||||
}
|
||||
else {
|
||||
alert(json.message);
|
||||
|
|
Loading…
Reference in New Issue