First implementation of database

This commit is contained in:
keplyx 2020-02-10 23:36:17 +01:00
parent 3c089f5d16
commit 64a584927b
15 changed files with 609 additions and 402 deletions

View file

@ -1,26 +1,11 @@
<?php
$relativePath = "../";
require_once $relativePath . 'classes/dao.php';
$file = '../data/stock-v2.json';
$fp = fopen($file, 'r');
$result = fread($fp, filesize($file));
fclose($fp);
$dao = new Dao();
$categories = $dao->get_categories();
ob_start();
?>
<tr>
<th class="id-column">Id</th>
<th class="name-column">Nom</th>
<th class="icon-column">
<a href="https://materialdesignicons.com/" target="_blank">
Icone
<i class="fas fa-external-link-alt"></i>
</a>
</th>
<th class="actions-column">Actions</th>
</tr>
<?php
$tableHeader = ob_get_clean();
ob_start();
?>
<div class="admin-container">
@ -30,48 +15,23 @@ ob_start();
</a>
<h1 class="text-center">Gestion des Catégories</h1>
<h2 class="text-center">Ajouter une catégorie</h2>
<table>
<tbody>
<?= $tableHeader ?>
<tr>
<td>
<input type="text" class="form-control" id="idInput" placeholder="Id">
</td>
<td>
<input type="text" class="form-control" id="nameInput" placeholder="Nom">
</td>
<td>
<input type="text" class="form-control" id="iconInput" placeholder="Icone">
</td>
<td>
<button type="submit" class="btn btn-success" onclick="addNewItem()"><i class="fas fa-check"></i>
</button>
</td>
</tr>
</tbody>
</table>
<h2 class="text-center">Liste des catégories</h2>
<table id="categoriesTable">
<tbody>
<?= $tableHeader ?>
</tbody>
</table>
<div style="display: flex; margin-top: 100px; margin-bottom: 100px">
<button class="btn btn-success btn-lg" style="margin: auto"
onclick="saveDataset()">
Sauvegarder les catégories
<div style="display: flex">
<button class="btn btn-success" style="margin: auto" onclick="listManager.showEditPopup(-1)">
<i class="mdi mdi-plus"></i>
</button>
</div>
<ul id="dataList">
</ul>
<script type="text/javascript">
let json_dump = <?php echo $result; ?>;
let json_dump = <?php echo json_encode($categories); ?>;
</script>
</>
</div>
<link type="text/css" rel="stylesheet" href="https://cdn.materialdesignicons.com/4.4.95/css/materialdesignicons.min.css"
media="screen,projection"/>
@ -82,6 +42,12 @@ ob_start();
<?php
$pageContent = ob_get_clean();
$pageTitle = "Gestion des catégories";
$pageScripts = "<script type=\"text/javascript\" src=\"" . $relativePath . "assets/js/saveManager.js\"></script><script type=\"text/javascript\" src=\"" . $relativePath . "assets/js/categories.js\"></script>";
$pageScripts =
"
<script type=\"text/javascript\" src=\"" . $relativePath . "assets/js/jquery-confirm-defaults.js\"></script>
<script type=\"text/javascript\" src=\"" . $relativePath . "assets/js/saveManager.js\"></script>
<script type=\"text/javascript\" src=\"" . $relativePath . "assets/js/listManager.js\"></script>
<script type=\"text/javascript\" src=\"" . $relativePath . "assets/js/categories.js\"></script>
";
include($relativePath . "includes/template.php");
?>

View file

@ -1,57 +0,0 @@
<?php
echo 'Ouverture du fichier V1...
';
$file = '../data/stock.json';
$fp = fopen($file, 'r');
$result = json_decode(fread($fp, filesize($file)));
fclose($fp);
function getConvertedTypes($oldTypes) {
$newTypes = [];
$counter = 1;
foreach ($oldTypes as $type) {
array_push($newTypes, (object) ["id" => strval($counter), "name" => $type, "icon" => "file"]);
$counter += 1;
}
return $newTypes;
}
function getConvertedArticles($articles, $newTypes) {
foreach ($articles as $article) {
$article->description = "Pas de description";
foreach ($article->type as $key=>$value) {
$article->type[$key] = getTypeIdFromName($value, $newTypes);
}
}
return $articles;
}
function getTypeIdFromName($name, $types) {
foreach ($types as $type) {
if ($type->name == $name)
return $type->id;
}
}
if ($result) {
echo 'Conversion en cours...
';
$newTypes = getConvertedTypes($result->types);
$newArticles = getConvertedArticles($result->articles, $newTypes);
$v2File = json_encode(["types"=>$newTypes, "articles"=>$newArticles]);
echo 'Conversion réussie...
';
echo 'Sauvegarde dans fichier V2...
';
$fp = fopen('../data/stock-v2.json', 'w');
$result = fwrite($fp, $v2File);
fclose($fp);
echo 'Sauvegarde réussie...
';
} else {
echo 'Echec!
'; // Allows to create a newline
var_dump($_POST);
}

39
admin/save_manager.php Normal file
View file

@ -0,0 +1,39 @@
<?php
$relativePath = "../";
require_once $relativePath . 'classes/dao.php';
$rest_json = file_get_contents("php://input");
$_POST = json_decode($rest_json, true);
//var_dump($_POST);
$result = -1;
$status = 0;
$message = "Success";
$dao = new Dao();
if ($_POST["function"] == "create_category")
$result = $dao->create_category($_POST["data"]);
else if ($_POST["function"] == "update_category") {
$result = $dao->update_category($_POST["data"]);
} else if ($_POST["function"] == "remove_category")
$result = $dao->remove_category($_POST["data"]);
else {
$status = 1;
$message = "Error: Unknown function";
}
if ($result < 0) {
$status = 2;
$message = "Error: SQL error";
}
$array = array(
"status" => $status,
"message" => $message,
"data" => $result,
);
echo json_encode($array);

View file

@ -1,10 +1,16 @@
<?php
$relativePath = "../";
require_once $relativePath.'classes/dao.php';
$file = '../data/stock-v2.json';
$fp = fopen($file, 'r');
$result = fread($fp, filesize($file));
fclose($fp);
$dao = new Dao();
$stock = $dao->get_articles();
$categories = $dao->get_categories();
for ($i = 0; $i < sizeof($stock); $i++) {
$article_categories = $dao->get_article_categories($stock[$i]["id"]);
$stock[$i]["type"] = $article_categories;
}
ob_start();
?>
@ -16,7 +22,6 @@ ob_start();
<th class="code-column">Code Barre</th>
<th class="type-column">Type</th>
<th class="image-column">Image</th>
<th class="actions-column">Actions</th>
</tr>
<?php
$tableHeader = ob_get_clean();
@ -29,7 +34,7 @@ ob_start();
</a>
<h1 class="text-center">Gestion des Stocks</h1>
<?php if ($result): ?>
<?php if ($stock): ?>
<h2 class="text-center">Ajouter un article</h2>
<table>
<tbody>
@ -56,10 +61,6 @@ ob_start();
<td>
<input type="text" class="form-control" id="imageInput" placeholder="Lien Image">
</td>
<td>
<button type="submit" class="btn btn-success" onclick="addNewItem()"><i class="fas fa-check"></i>
</button>
</td>
</tr>
</tbody>
</table>
@ -87,13 +88,22 @@ ob_start();
</div>
<?php endif; ?>
<script type="text/javascript">
let json_dump =
let json_dump = {
types:
<?php
if ($result)
echo $result;
if ($categories)
echo json_encode($categories);
else
echo 'undefined'
?>;
echo 'undefined';
?>,
articles:
<?php
if ($stock)
echo json_encode($stock);
else
echo 'undefined';
?>
}
</script>

View file

@ -1,19 +1,25 @@
#categoriesTable tr {
border-bottom: 1px solid #dedede;
#dataList {
list-style: none;
}
#dataList li {
text-align: center;
height: 50px;
line-height: 50px;
display: flex;
cursor: pointer;
transition: 0.2s;
}
#dataList li:hover {
background-color: #e5e5e5;
}
#dataList li div {
margin: auto;
display: flex;
}
.mdi {
font-size: 2rem;
}
.actions-column {
width: 100px;
}
.id-column {
width: 200px;
}
.icon-column {
width: 200px;
}

9
assets/css/jquery-confirm.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,135 +1,143 @@
let currentDataset = [];
let currentTypes = [];
let originalEditedItem = {};
function initValuesFromPHPDump() {
currentDataset = json_dump.articles; // json_dump is set using PHP
currentTypes = json_dump.types;
console.log(currentDataset);
console.log(currentTypes);
generateTable(currentTypes);
}
// let listContainer = $("#dataList");
// let currentTypes = [];
// let displayedTypes = [];
let listManager;
$(document).ready(function () {
initValuesFromPHPDump();
setEditFieldValues('', '', '');
listManager = new ListManager($("#dataList"), json_dump,
[
{
name: 'icon',
description: 'Icone',
type: 'icon'
},
{
name: 'name',
description: 'Nom',
type: 'text'
},
]);
});
function generateTable(dataset) {
for (let i = 0; i < dataset.length; i++) {
generateLine(dataset[i]);
}
}
function generateLine(item) {
$.selector_cache('#categoriesTable').append(
'<tr id="row_' + item.id + '">' +
'<td>' + item.id + '</td>' +
'<td>' + item.name + '</td>' +
'<td><span class="mdi mdi-' + item.icon + '"></span></td>' +
'<td>' +
'<button class="btn btn-danger" id="delete_' + item.id + '" onclick="deleteItem(this)"><i class="fas fa-times"></i></button>' +
'<button class="btn btn-primary" id="edit_' + item.id + '" onclick="editItem(this)"><i class="fas fa-edit"></i></button>' +
'</td>' +
'</tr>'
);
}
function addNewItem() {
if (isItemInputFilled()) {
let item = {
id: $.selector_cache('#idInput').val(),
name: $.selector_cache('#nameInput').val(),
icon: $.selector_cache('#iconInput').val(),
};
if (isIdAvailable(item.id)) {
updateExistingItemsType(originalEditedItem.id, item.id);
setEditFieldValues('', '', '');
currentTypes.push(item);
generateLine(item);
}
}
}
function editItem(elem) {
if (isItemInputEmpty()) {
let id = elem.id.replace('edit_', '');
let item = getTypeOfId(id);
originalEditedItem = item;
setEditFieldValues(item.id, item.name, item.icon);
removeItemFromList(item); // Move the item in the edit fields
}
}
function deleteItem(elem) {
let id = elem.id.replace('delete_', '');
let item = getTypeOfId(id);
updateExistingItemsType(id, undefined);
removeItemFromList(item);
}
function removeItemFromList(item) {
currentTypes.splice(currentTypes.indexOf(item), 1);
$('#row_' + item.id).remove();
}
function setEditFieldValues(id, name, icon) {
$.selector_cache('#idInput').val(id);
$.selector_cache('#nameInput').val(name);
$.selector_cache('#iconInput').val(icon);
}
function updateExistingItemsType(oldTypeID, newTypeID) {
for (let i = 0; i < currentDataset.length; i++) {
for (let k = 0; k < currentDataset[i].type.length; k++) {
if (currentDataset[i].type[k] === oldTypeID) {
console.log(newTypeID);
if (newTypeID !== undefined)
currentDataset[i].type[k] = newTypeID;
else
currentDataset[i].type.splice(k, 1);
break;
}
}
}
}
function getTypeOfId(id) {
let item = {};
for (let i = 0; i < currentTypes.length; i++) {
if (currentTypes[i].id === id) {
item = currentTypes[i];
break;
}
}
return item;
}
function isIdAvailable(id) {
let isAvailable = true;
for (let i = 0; i < currentTypes.length; i++) {
if (currentTypes[i].id === id) {
isAvailable = false;
break;
}
}
return isAvailable;
}
function isItemInputEmpty() {
return $.selector_cache('#idInput').val() === '' &&
$.selector_cache('#nameInput').val() === '' &&
$.selector_cache('#iconInput').val() === '';
}
function isItemInputFilled() {
return $.selector_cache('#idInput').val() !== '' &&
$.selector_cache('#nameInput').val() !== '' &&
$.selector_cache('#iconInput').val() !== '';
}
function saveDataset() {
SaveManager.saveData(currentTypes, currentDataset);
}
//
// function initValuesFromPHPDump() {
// currentTypes = json_dump;
// console.log(currentTypes);
//
// }
//
// $(document).ready(function () {
// initValuesFromPHPDump();
// generateList();
// console.log(displayedTypes);
// });
//
// function generateList() {
// for (let i = 0; i < currentTypes.length; i++) {
// createNewListEntry(currentTypes[i]);
// }
// }
//
// function createNewListEntry(type) {
// displayedTypes.push(
// $("<li id='listItem_" + type["id"] + "' onclick='showEditPopup(" + displayedTypes.length + ")'>" +
// "<div>" +
// "<span class='category-icon'><i class='mdi mdi-" + type["icon"] + "'></i></span>" +
// "<span class='category-title'>" + type["name"] + "</span>" +
// "</div>" +
// "</li>"));
// listContainer.append(displayedTypes[displayedTypes.length - 1]);
// }
//
// function deleteListEntry(id) {
// $('#listItem_' + id).remove();
// }
//
//
// function showEditPopup(index) {
// let defaultValues = {
// name: "",
// icon: ""
// };
// let title = "Créer une catégorie";
// if (index !== -1) {
// defaultValues = currentTypes[index];
// title = "Modifier la catégorie";
// }
// $.confirm({
// title: title,
// content:
// '<form action="" class="categoryForm">' +
// '<div class="form-group">' +
// '<label for="nameInput">Nom :</label>' +
// '<input id="nameInput" type="text" placeholder="Nom" class="name-input form-control" value="' + defaultValues['name'] + '" required />' +
// '<label for="iconInput">Icone :</label>' +
// '<input id="iconInput" type="text" placeholder="icone" class="icon-input form-control" value="' + defaultValues['icon'] + '" required />' +
// '</div>' +
// '</form>',
// buttons: {
// formSubmit: {
// text: 'Sauvegarder',
// btnClass: 'btn-blue',
// action: async function () {
// let name = this.$content.find('#nameInput').val();
// let icon = this.$content.find('#iconInput').val();
// if (!name) {
// $.alert('Merci de donner un nom');
// return false;
// } else if (!icon) {
// $.alert('Merci de donner une icone');
// return false;
// }
// let itemToSave;
// if (index !== -1) {
// currentTypes[index]['name'] = name;
// currentTypes[index]['icon'] = icon;
// itemToSave = currentTypes[index];
// displayedTypes[index].find(".category-title").text(name);
// displayedTypes[index].find(".mdi")[0].className = "mdi mdi-" + icon;
// } else {
// itemToSave = {
// name: name,
// icon: icon,
// display_order: 0,
// };
// }
// let id = await SaveManager.saveCategory(itemToSave, index === -1);
// if (id >= 0 && index === -1) {
// itemToSave = {
// name: name,
// icon: icon,
// display_order: 0,
// id: id
// };
// currentTypes[displayedTypes.length] = itemToSave;
// createNewListEntry(itemToSave);
// }
// }
// },
// deleteButton: {
// text: 'Supprimer',
// btnClass: 'btn-red',
// isHidden: index === -1,
// action: function () {
// let id = currentTypes[index]['id'];
// SaveManager.deleteCategory(id);
// deleteListEntry(id);
// }
// },
// cancelButton: {
// text: 'Annuler',
// },
// },
// onContentReady: function () {
// // bind to events
// let jc = this;
// this.$content.find('form').on('submit', function (e) {
// // if the user submits the form by pressing enter in the field.
// e.preventDefault();
// jc.$$formSubmit.trigger('click'); // reference the button and click it
// });
// }
// });
// }

View file

@ -70,78 +70,3 @@ function animateCss($elem, animationName, callback) {
callback();
});
}
jconfirm.defaults = {
title: 'Title',
titleClass: '',
type: 'red',
typeAnimated: true,
draggable: false,
dragWindowGap: 15,
dragWindowBorder: true,
animateFromElement: true,
smoothContent: true,
content: 'content',
escapeKey: 'ok',
buttons: {},
defaultButtons: {
ok: {
keys: ['enter'],
text: 'OK',
action: function () {
}
},
close: {
action: function () {
}
},
},
contentLoaded: function (data, status, xhr) {
},
icon: '',
lazyOpen: false,
bgOpacity: null,
theme: 'supervan',
animation: 'scale',
closeAnimation: 'scale',
animationSpeed: 300,
animationBounce: 1,
rtl: false,
container: 'body',
containerFluid: false,
backgroundDismiss: false,
backgroundDismissAnimation: 'shake',
autoClose: false,
closeIcon: null,
closeIconClass: false,
watchInterval: 100,
columnClass: 'xlarge',
boxWidth: '50%',
scrollToPreviousElement: true,
scrollToPreviousElementAnimate: true,
useBootstrap: true,
offsetTop: 40,
offsetBottom: 40,
bootstrapClasses: {
container: 'container',
containerFluid: 'container-fluid',
row: 'row',
},
onContentReady: function () {
},
onOpenBefore: function () {
// after the modal is displayed.
$('body').css('overflow', 'hidden');
},
onOpen: function () {
},
onClose: function () {
// before the modal is hidden.
$('body').css('overflow', 'auto');
},
onDestroy: function () {
},
onAction: function () {
}
};

73
assets/js/jquery-confirm-defaults.js vendored Normal file
View file

@ -0,0 +1,73 @@
jconfirm.defaults = {
title: 'Title',
titleClass: '',
type: 'red',
typeAnimated: true,
draggable: false,
dragWindowGap: 15,
dragWindowBorder: true,
animateFromElement: false,
smoothContent: true,
content: 'content',
escapeKey: 'ok',
buttons: {},
defaultButtons: {
ok: {
keys: ['enter'],
text: 'OK',
action: function () {
}
},
close: {
action: function () {
}
},
},
contentLoaded: function (data, status, xhr) {
},
icon: '',
lazyOpen: false,
bgOpacity: null,
theme: 'material',
animation: 'scale',
closeAnimation: 'scale',
animationSpeed: 300,
animationBounce: 1.3,
rtl: false,
container: 'body',
containerFluid: false,
backgroundDismiss: false,
backgroundDismissAnimation: 'shake',
autoClose: false,
closeIcon: null,
closeIconClass: false,
watchInterval: 100,
columnClass: 'xlarge',
boxWidth: '50%',
scrollToPreviousElement: true,
scrollToPreviousElementAnimate: true,
useBootstrap: true,
offsetTop: 40,
offsetBottom: 40,
bootstrapClasses: {
container: 'container',
containerFluid: 'container-fluid',
row: 'row',
},
onContentReady: function () {
},
onOpenBefore: function () {
// after the modal is displayed.
$('body').css('overflow', 'hidden');
},
onOpen: function () {
},
onClose: function () {
// before the modal is hidden.
$('body').css('overflow', 'auto');
},
onDestroy: function () {
},
onAction: function () {
}
};

10
assets/js/jquery-confirm.min.js vendored Normal file

File diff suppressed because one or more lines are too long

167
assets/js/listManager.js Normal file
View file

@ -0,0 +1,167 @@
class ListManager {
currentTypes = [];
displayedTypes = [];
editableTypes = [];
constructor(listContainer, initialData, editableTypes) {
this.listContainer = listContainer;
this.currentTypes = initialData;
this.editableTypes = editableTypes;
this.generateList();
}
generateList() {
for (let i = 0; i < this.currentTypes.length; i++) {
this.createNewListEntry(this.currentTypes[i]);
}
}
createNewListEntry(item) {
let listItem = this.getListItem(item);
this.displayedTypes.push($(listItem));
const index = this.displayedTypes.length-1;
let JQueryItem = this.displayedTypes[index];
this.listContainer.append(JQueryItem);
JQueryItem.on('click', () => {
this.showEditPopup(index);
});
}
deleteListEntry(id) {
$('#listItem_' + id).remove();
}
getListItem(item) {
let listItem = "<li id='listItem_" + item["id"] + "'><div>";
for (let i = 0; i < this.editableTypes.length; i++) {
listItem += "<span class='list-" + this.editableTypes[i]["name"] + "'>";
if (this.editableTypes[i]["type"] === "icon")
listItem += "<i class='mdi mdi-" + item["icon"] + "' style='margin-right: 5px'></i></span>";
else
listItem += item["name"] + '</span>';
}
listItem += "</div></li>";
return listItem;
}
getFormData(defaultValues) {
let formData = '<form action="" class="categoryForm"><div class="form-group">';
for (let i = 0; i < this.editableTypes.length; i++) {
let inputId = this.editableTypes[i]['name'] + 'Input';
let value = defaultValues[this.editableTypes[i]['name']];
formData += '<label for="' + inputId + '">' + this.editableTypes[i]['description'] + ' :</label>' +
'<input id="' + inputId + '" type="text" placeholder="Entrez une valeur" class="form-control" value="' + value + '" required />';
}
formData += "</div></form>";
return formData;
}
getFormValues(form) {
let values = [];
for (let i = 0; i < this.editableTypes.length; i++) {
values.push(form.find('#' + this.editableTypes[i]['name'] + 'Input').val())
}
return values;
}
isFormValid(values) {
let isValid = true;
for (let i = 0; i < values.length; i++) {
if (values[i] === '') {
isValid = false;
break;
}
}
return isValid;
}
insertFormDataIntoObject(values, object) {
for (let i = 0; i < values.length; i++) {
object[this.editableTypes[i]['name']] = values[i];
}
return object;
}
updateListItem(values, index) {
for (let i = 0; i < values.length; i++) {
if (this.editableTypes[i]['type'] === 'icon')
this.displayedTypes[index].find(".mdi")[0].className = "mdi mdi-" + values[i];
else
this.displayedTypes[index].find(".list-" + this.editableTypes[i]['name']).text(values[i]);
}
}
showEditPopup(index) {
let defaultValues = {
name: "",
icon: ""
};
let title = "Créer une nouvelle entrée";
if (index !== -1) {
defaultValues = this.currentTypes[index];
title = "Modifier l'entrée";
}
let formData = this.getFormData(defaultValues);
let thisInstance = this;
$.confirm({
title: title,
content: formData,
buttons: {
formSubmit: {
text: 'Sauvegarder',
btnClass: 'btn-blue',
action: async function () {
let values = thisInstance.getFormValues(this.$content);
if (!thisInstance.isFormValid(values)) {
$.alert('Merci de rentrer toutes les valeurs');
return false;
}
let itemToSave = {};
if (index !== -1) {
itemToSave = thisInstance.currentTypes[index];
}
itemToSave = thisInstance.insertFormDataIntoObject(values, itemToSave);
if (index !== -1) {
thisInstance.currentTypes[index] = itemToSave;
thisInstance.updateListItem(values, index);
}
let id = await SaveManager.saveCategory(itemToSave, index === -1);
if (id >= 0 && index === -1) {
itemToSave["id"] = id;
thisInstance.currentTypes[thisInstance.displayedTypes.length] = itemToSave;
thisInstance.createNewListEntry(itemToSave);
}
}
},
deleteButton: {
text: 'Supprimer',
btnClass: 'btn-red',
isHidden: index === -1,
action: function () {
let id = thisInstance.currentTypes[index]['id'];
SaveManager.deleteCategory(id);
thisInstance.deleteListEntry(id);
}
},
cancelButton: {
text: 'Annuler',
},
},
onContentReady: function () {
// bind to events
let jc = this;
this.$content.find('form').on('submit', function (e) {
// if the user submits the form by pressing enter in the field.
e.preventDefault();
jc.$$formSubmit.trigger('click'); // reference the button and click it
});
}
});
}
}

View file

@ -1,76 +1,40 @@
class SaveManager {
static saveData(types, dataset) {
let finalDataset = {
v1: SaveManager.generateV1JSON(types, dataset),
v2: SaveManager.generateV2JSON(types, dataset)
static deleteCategory(id) {
let data = {
function: "remove_category",
data: id,
};
console.log(finalDataset);
console.log(data);
$.ajax({
type: "POST",
url: "write_json.php",
data: JSON.stringify(finalDataset),
url: "save_manager.php",
data: JSON.stringify(data),
dataType: "json",
contentType: "application/json; charset=utf-8",
complete: function (data) {
alert(data.responseText);
$.alert(data.responseText);
console.log(data);
},
});
}
static generateV1JSON(savedTypes, savedDataset) {
let types = [];
// Replace type objects by names
for (let i = 0; i < savedTypes.length; i++) {
types.push(savedTypes[i].name);
}
let dataset = JSON.parse(JSON.stringify(savedDataset)); // Deep copy of object
for (let i = 0; i < dataset.length; i++) {
// Replace type ids by names
for (let k = 0; k < dataset[i].type.length; k++) {
dataset[i].type[k] = SaveManager.getTypeOfId(savedTypes, dataset[i].type[k]).name;
}
// remove the description field
delete dataset[i].description
}
return {
types: types,
articles: dataset
}
}
static async saveCategory(category, isNew) {
let data = {
function: isNew ? "create_category" : "update_category",
data: category,
};
static generateV2JSON(savedTypes, savedDataset) {
return {
types: savedTypes,
articles: savedDataset
}
}
static getTypeOfId(types, id) {
let item = {};
for (let i = 0; i < types.length; i++) {
if (types[i].id === id) {
item = types[i];
break;
}
}
return item;
}
static convertToV2() {
$.ajax({
let response = await $.ajax({
type: "POST",
url: "convert_json.php",
url: "save_manager.php",
data: JSON.stringify(data),
dataType: "json",
contentType: "application/json; charset=utf-8",
complete: function (data) {
alert(data.responseText);
console.log(data);
window.location.reload();
},
});
console.log(response);
return response['data'];
}
}

2
assets/js/sortable.min.js vendored Normal file

File diff suppressed because one or more lines are too long

83
classes/dao.php Normal file
View file

@ -0,0 +1,83 @@
<?php
class Dao
{
private $conn;
public function __construct()
{
$username = 'proximo';
$password = $this->read_password();
$dsn = 'mysql:dbname=proximo;host=127.0.0.1';
try {
$this->conn = new PDO($dsn, $username, $password, [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8']);
} catch (PDOException $e) {
echo "error";
echo $e;
}
}
private function read_password()
{
$real_path = __DIR__ . DIRECTORY_SEPARATOR . ".htpassdb";
$file = fopen($real_path, "r") or die("Unable to open DB password file!");
$password = fgets($file);
fclose($file);
return trim($password);
}
public function get_articles()
{
$sql = 'SELECT * FROM articles';
$cursor = $this->conn->prepare($sql);
$cursor->execute();
return $cursor->fetchAll(PDO::FETCH_ASSOC);
}
public function get_article_categories($article_id)
{
$sql = 'SELECT category_id FROM article_categories WHERE article_id=?';
$cursor = $this->conn->prepare($sql);
$cursor->execute([$article_id]);
$result = $cursor->fetchAll(PDO::FETCH_ASSOC);
$final = [];
foreach ($result as $row) {
array_push($final, $row["category_id"]);
}
return $final;
}
public function get_categories()
{
$sql = 'SELECT * FROM categories';
$cursor = $this->conn->prepare($sql);
$cursor->execute();
return $cursor->fetchAll(PDO::FETCH_ASSOC);
}
public function create_category($category) {
$sql = 'INSERT INTO categories (name, icon) VALUES (?, ?)';
$cursor = $this->conn->prepare($sql);
$data = [$category["name"], $category["icon"]];
$cursor->execute($data);
return $this->conn->lastInsertId();
}
public function update_category($category)
{
$sql = 'UPDATE categories SET name=?, icon=? WHERE id=?';
$cursor = $this->conn->prepare($sql);
$data = [$category["name"], $category["icon"], $category["id"]];
$cursor->execute($data);
return $category["id"];
}
public function remove_category($id)
{
$sql = 'DELETE FROM categories WHERE id=?';
$cursor = $this->conn->prepare($sql);
$data = [$id];
return $cursor->execute($data);
}
}

View file

@ -28,8 +28,8 @@ if (!isset($hasHeader))
<link type="text/css" rel="stylesheet" href="<?= $relativePath ?>assets/css/hamburger.css"
media="screen,projection"/>
<link type="text/css" rel="stylesheet" href="<?= $relativePath ?>assets/css/sidenav.css" media="screen,projection"/>
<link type="text/css" rel="stylesheet" href="<?= $relativePath ?>assets/css/bootstrapOverwrite.css"
media="screen,projection"/>
<link type="text/css" rel="stylesheet" href="<?= $relativePath ?>assets/css/bootstrapOverwrite.css" media="screen,projection"/>
<link type="text/css" rel="stylesheet" href="<?= $relativePath ?>assets/css/jquery-confirm.min.css" media="screen,projection"/>
<link rel="icon" type="image/png" href="<?= $relativePath ?>assets/images/favicon.png">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
@ -71,6 +71,8 @@ if (!isset($hasHeader))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.2/jquery-confirm.min.js"></script>
<script type="text/javascript" src="<?= $relativePath ?>assets/js/init.js"></script>
<script type="text/javascript" src="<?= $relativePath ?>assets/js/sidenav.js"></script>
<script type="text/javascript" src="<?= $relativePath ?>assets/js/jquery-confirm.min.js"></script>
<script src="<?= $relativePath ?>assets/js/sortable.min.js"></script>
<?= $pageScripts ?>
</body>