Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e02b7abb0a | |||
| edfa8c93b9 | |||
| f933065275 | |||
| 060e54d27e | |||
| 05533d68c6 | |||
| a9e7e0331c | |||
| 83857ef4e2 | |||
| 0ae685753f | |||
| aa1ec2296f | |||
| f633d4f73d | |||
| 251bbce109 | |||
| 9b63c9261e | |||
| 2d38f72292 | |||
| ec78173e05 | |||
| 9005cff6ca | |||
| 7845cdc85b | |||
| 9ae8dd93de | |||
| f8c0d6d1b2 | |||
| 188e7fbc6e | |||
| 9d51f49bf7 | |||
| ae31644831 | |||
| f2397b6d31 | |||
| aaead5a31a | |||
| f918134469 | |||
| 69a5a99e15 | |||
| 8a173ed2c7 | |||
| 52b26b0cb6 | |||
| e79cc73e6d | |||
| 5af5a0ad06 | |||
| 72108d4d03 | |||
| 52747e51f9 | |||
| 6c068443dc | |||
| b15324c27b | |||
| 43eb936532 | |||
| c36b95a15f |
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'host' => 'localhost',
|
||||
'port' => 3306,
|
||||
'user' => 'admin',
|
||||
'pass' => 'adminpass123',
|
||||
'name' => 'siterecette'
|
||||
];
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
// Config
|
||||
return [
|
||||
'website_url' => 'http://127.0.0.1:8080/',
|
||||
'website_name' => 'Les recettes des Papis',
|
||||
'website_name' => 'Les recettes de Papis',
|
||||
|
||||
'website_path' => APP_ROOT,
|
||||
];
|
||||
215
public/assets/css/style.css
Normal file → Executable file
215
public/assets/css/style.css
Normal file → Executable file
@@ -31,7 +31,7 @@ html, body{
|
||||
|
||||
#logo {
|
||||
background-color: aqua;
|
||||
background-image: url("Logo.jpg");
|
||||
background-image: url("../images/Logo.jpg");
|
||||
/*background:no-repeat;*/
|
||||
height: 103px;
|
||||
width: 141px;
|
||||
@@ -57,7 +57,7 @@ nav {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.nav-list {
|
||||
.nav-list{
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -67,10 +67,20 @@ nav {
|
||||
border-radius: 40px;
|
||||
}
|
||||
|
||||
.nav-list li {
|
||||
/*border: 1px solid black;*/
|
||||
border-radius: 2000px;
|
||||
}
|
||||
|
||||
.nav-list li:hover {
|
||||
background-color: #00d8a2;
|
||||
}
|
||||
|
||||
|
||||
.nav-element {
|
||||
line-height: 2.5;
|
||||
padding: 10px;
|
||||
margin: 4px;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
@@ -84,12 +94,13 @@ nav {
|
||||
|
||||
#login {
|
||||
border: 1px solid black;
|
||||
border-radius: 6px;
|
||||
border-radius: 2000px;
|
||||
background-color: #ffc478;
|
||||
}
|
||||
|
||||
#login:hover {
|
||||
background-color: #0bbd90;
|
||||
box-shadow: 1px 1px 7px black;
|
||||
}
|
||||
|
||||
/*Body et son contenu */
|
||||
@@ -120,6 +131,34 @@ body {
|
||||
/*display:none;*/
|
||||
}
|
||||
|
||||
.title-site {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.random-proposition {
|
||||
gap: 5%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.recommandation img {
|
||||
max-width: calc( 7vh + 7vw );
|
||||
max-height: calc( 7vh + 7vw );
|
||||
}
|
||||
|
||||
.line-acceuil {
|
||||
color: #03be90;
|
||||
box-shadow: 20px 6px 8px #007054;
|
||||
}
|
||||
|
||||
.tag-selected-div {
|
||||
flex: 4;
|
||||
}
|
||||
@@ -142,6 +181,8 @@ body {
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-top: .5%;
|
||||
padding: .5% 0 .5% .5%;
|
||||
border: 1px solid black;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0px 0px 10px rgb(131, 131, 131);
|
||||
@@ -190,6 +231,7 @@ nav {
|
||||
background-clip: border-box;
|
||||
padding-right: 2%;
|
||||
padding-left: 2%;
|
||||
padding-bottom: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -292,9 +334,8 @@ ul {
|
||||
/*image*/
|
||||
.recette-image {
|
||||
background-color: red;
|
||||
aspect-ratio: 1/1;
|
||||
max-height: calc( 30vh + 30vw );
|
||||
max-width: calc( 30vh + 30vw );
|
||||
max-height: calc( 20vh + 20vw );
|
||||
max-width: calc( 20vh + 20vw );
|
||||
border: 1px solid white;
|
||||
border-radius: 30px;
|
||||
}
|
||||
@@ -304,6 +345,35 @@ ul {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
.recette-liste-ingr-div {
|
||||
margin-left: 120px;
|
||||
padding-left: 100px;
|
||||
width: 75%;
|
||||
border: 1px solid black;
|
||||
border-radius: 200px;
|
||||
box-shadow: 7px 4px 7px black;
|
||||
}
|
||||
|
||||
.recette-liste-ingr-elem {
|
||||
display: flex;
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
.ingr-image-prev {
|
||||
max-height: 50px;
|
||||
max-width: 50px;
|
||||
border: 1px solid black;
|
||||
border-radius: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.recette-liste-ingr-elem-nom {
|
||||
height: 100%;
|
||||
width: 15%;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.recette-div-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -418,11 +488,23 @@ ul {
|
||||
box-shadow: 2px 2px 0px #000000;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: .5% 2%;
|
||||
border: 2px solid black;
|
||||
border-radius: 10px;
|
||||
margin-top: .5%;
|
||||
margin-left: .5%;
|
||||
background-color: #ffd9a0;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #0bbd90;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
padding: 1%;
|
||||
border-radius: 10px;
|
||||
box-shadow: 3px 4px 5px #8c8c8c;
|
||||
}
|
||||
@@ -432,30 +514,145 @@ ul {
|
||||
}
|
||||
|
||||
.recette-form {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
width: 80%;
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid black;
|
||||
background: #fff9f1;
|
||||
border-radius: 20px;
|
||||
box-shadow: 2px 2px 3px #a06100;
|
||||
}
|
||||
|
||||
.recette-form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#recette-form-div-desc {
|
||||
height: 400px;
|
||||
height: 220px;
|
||||
}
|
||||
|
||||
#recette-form-description {
|
||||
height: 95%;
|
||||
}
|
||||
|
||||
.recette-add-form-all {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.recette-form-add {
|
||||
flex: 3;
|
||||
}
|
||||
|
||||
.recette-form-add-ingr {
|
||||
height: 30%;
|
||||
}
|
||||
|
||||
.recette-form-add-tag {
|
||||
height: 30%;
|
||||
}
|
||||
|
||||
.recette-form-add-additional{
|
||||
flex: 1;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.err {
|
||||
color: red;
|
||||
display: none;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.liste-ingr-elem {
|
||||
display: flex;
|
||||
height: 100px;
|
||||
padding:5px;
|
||||
background-color: #c6fdefe0;
|
||||
color: #000000;
|
||||
border: 1px solid black;
|
||||
border-radius: 10px;
|
||||
box-shadow: 1px 1px 1px black;
|
||||
margin-top: .25%;
|
||||
margin-bottom: .25%;
|
||||
}
|
||||
|
||||
.liste-ingr-elem:hover {
|
||||
border:3px solid #007054;
|
||||
box-shadow: 2px 2px 10px black;
|
||||
}
|
||||
|
||||
.liste-ingr-elem-text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex:12;
|
||||
padding-left: 20px;
|
||||
line-height: 100px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.liste-ingr-elem-modif {
|
||||
line-height: 100px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.liste-tag-elem {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
padding:5px;
|
||||
background-color: #c6fdefe0;
|
||||
color: #000000;
|
||||
border: 1px solid black;
|
||||
border-radius: 10px;
|
||||
box-shadow: 1px 1px 1px black;
|
||||
margin-top: .25%;
|
||||
margin-bottom: .25%;
|
||||
}
|
||||
|
||||
.liste-tag-elem:hover {
|
||||
border:3px solid #007054;
|
||||
box-shadow: 2px 2px 10px black;
|
||||
}
|
||||
|
||||
.liste-tag-elem-text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex:12;
|
||||
padding-left: 20px;
|
||||
line-height: 40px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.liste-tag-elem-modif {
|
||||
line-height: 40px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.ingr-image {
|
||||
flex: 1;
|
||||
border: 1px solid black;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/*Footer et son contenue*/
|
||||
footer{
|
||||
padding: 25px;
|
||||
background: rgb(11, 189, 144);
|
||||
color: white;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
.meta-recettes {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
|
||||
0
public/assets/images/Logo.jpg
Normal file → Executable file
0
public/assets/images/Logo.jpg
Normal file → Executable file
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
110
public/assets/js/advanced-search.js
Executable file
110
public/assets/js/advanced-search.js
Executable file
@@ -0,0 +1,110 @@
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
|
||||
let searchInput = "";
|
||||
let tagsId = [];
|
||||
let ingredientsId = [];
|
||||
|
||||
function buildCards( data ){
|
||||
|
||||
if( Array.isArray( data ) ){
|
||||
data = Object.assign({}, data );
|
||||
}
|
||||
|
||||
document.getElementById( "recetteList" ).innerHTML = '';
|
||||
for( const [key, recette] of Object.entries( data ) ) {
|
||||
let HTML_CONTENT = `<a class="recette-icone" href="${recette.url}">
|
||||
<img class="recette-preview-image" src="${recette.photo}">
|
||||
<div class="recette-icone-content">
|
||||
<h3>${recette.titre_recette}</h3>
|
||||
<ul>
|
||||
<li>Temps de préparation : ${recette.temps_de_preparation}</li>
|
||||
<li>Nombre d'ingrédients : ${recette.nb_ingredients}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</a>`
|
||||
document.getElementById("recetteList").innerHTML += HTML_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
function advancedSearch(){
|
||||
|
||||
let form = new FormData();
|
||||
form.append( "title", searchInput );
|
||||
form.append( "tagsId", tagsId );
|
||||
form.append( "ingredientsId", ingredientsId );
|
||||
|
||||
const XML = new XMLHttpRequest();
|
||||
XML.open( "POST", '/api/recettes/list' );
|
||||
XML.onreadystatechange = function ( e ) {
|
||||
if( XML.status === 200 && XML.readyState === XMLHttpRequest.DONE ) {
|
||||
try {
|
||||
console.log( XML.response );
|
||||
let response = JSON.parse(XML.response);
|
||||
console.log( "Reponse parsé" );
|
||||
buildCards( response.data );
|
||||
} catch( e ) {
|
||||
console.log( "Ce n'est pas un fichier JSON" );
|
||||
}
|
||||
}
|
||||
}
|
||||
XML.send( form );
|
||||
}
|
||||
|
||||
const INGREDIENTSLIST = document.getElementById( 'ingredientsList' );
|
||||
for( let item of INGREDIENTSLIST.getElementsByTagName( 'li' ) ){
|
||||
item.addEventListener( 'click', function(){
|
||||
|
||||
let ingredientId = Number( item.getAttribute( 'data-ingredient-id' ) );
|
||||
let index = ingredientsId.indexOf( ingredientId );
|
||||
|
||||
if( index > -1 ) {
|
||||
ingredientsId.splice( index, 1 );
|
||||
item.classList.add( 'tag-unselected' );
|
||||
item.classList.remove( 'tag-selected' );
|
||||
} else {
|
||||
ingredientsId.push( ingredientId );
|
||||
item.classList.add( 'tag-selected' );
|
||||
item.classList.remove( 'tag-unselected' );
|
||||
}
|
||||
|
||||
advancedSearch();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
const TAGSLIST = document.getElementById( 'tagsList' );
|
||||
for( let item of TAGSLIST.getElementsByTagName( 'li' ) ){
|
||||
item.addEventListener( 'click', function(){
|
||||
|
||||
let tagId = Number( item.getAttribute( 'data-tag-id' ) );
|
||||
let index = tagsId.indexOf( tagId );
|
||||
|
||||
if( index > -1 ) {
|
||||
tagsId.splice( index, 1 );
|
||||
item.classList.add( 'tag-unselected' );
|
||||
item.classList.remove( 'tag-selected' );
|
||||
} else {
|
||||
tagsId.push( tagId );
|
||||
item.classList.add( 'tag-selected' );
|
||||
item.classList.remove( 'tag-unselected' );
|
||||
}
|
||||
|
||||
advancedSearch();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
const SEARCHBAR = document.getElementById( 'searchForm' );
|
||||
searchInput = new URLSearchParams(document.location.search).get("s") || searchInput;
|
||||
|
||||
if( searchInput !== undefined && searchInput != "" ) {
|
||||
advancedSearch();
|
||||
}
|
||||
|
||||
SEARCHBAR.onsubmit = function( e ){
|
||||
e.preventDefault();
|
||||
searchInput = document.getElementById( 'searchFormField' ).value;
|
||||
advancedSearch();
|
||||
}
|
||||
|
||||
});
|
||||
173
public/assets/js/form.js
Normal file
173
public/assets/js/form.js
Normal file
@@ -0,0 +1,173 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
|
||||
let compl_form = document.getElementById("recette-form-complete");
|
||||
console.log(compl_form);
|
||||
|
||||
function formulaire_ingredient_update(event) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
console.log(event);
|
||||
|
||||
let form = document.getElementById("recette-form-ingr-add");
|
||||
|
||||
let cible = document.getElementById("recette-form-ingr");
|
||||
let nomIngredient = document.getElementById("recette-form-ingr-nom");
|
||||
let image = document.getElementById("recette-form-ingr-photo");
|
||||
if( nomIngredient.value === "" || image.value === "" ){
|
||||
alert( "Un champ requis est manquant." );
|
||||
return;
|
||||
}
|
||||
|
||||
let ingr = form.nom;
|
||||
|
||||
let form_data = new FormData(form);
|
||||
|
||||
fetch("/api/ingredients/create", {
|
||||
method : "POST",
|
||||
body: form_data
|
||||
}).then( reponse => {
|
||||
if (!reponse.ok) {
|
||||
let div_err = document.getElementById("recette-form-div-err-ingr");
|
||||
|
||||
div_err.style.display = "inherit";
|
||||
div_err.innerText = "Erreur de connection au serveur";
|
||||
|
||||
}
|
||||
else {
|
||||
reponse.json().then( data => {
|
||||
if (data.success) {
|
||||
let new_elem = document.createElement("option");
|
||||
|
||||
new_elem.setAttribute("value",data.id);
|
||||
new_elem.innerText = document.getElementById('recette-form-ingr-nom').value;
|
||||
|
||||
cible.appendChild(new_elem);
|
||||
|
||||
document.getElementById('recette-form-ingr-nom').value = "";
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function formulaire_tag_update(event){
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
let form = document.getElementById("recette-form-tag-add");
|
||||
|
||||
let cible = document.getElementById("recette-form-tag");
|
||||
let nomTag = document.getElementById("recette-form-tag-nom");
|
||||
if( nomTag.value === "" ){
|
||||
alert( "Un champ requis est manquant." );
|
||||
return;
|
||||
}
|
||||
|
||||
let tag = form.tag;
|
||||
|
||||
let form_data = new FormData(form);
|
||||
|
||||
fetch("/api/tags/create", {
|
||||
method : "POST",
|
||||
body: form_data
|
||||
}).then( reponse => {
|
||||
if (!reponse.ok) {
|
||||
let div_err = document.getElementById("recette-form-div-err-tag");
|
||||
|
||||
div_err.style.display = "inherit";
|
||||
div_err.innerText = "Erreur de connection au serveur";
|
||||
|
||||
}
|
||||
else {
|
||||
reponse.json().then( data => {
|
||||
if (data.success) {
|
||||
let new_elem = document.createElement("option");
|
||||
|
||||
new_elem.setAttribute("value",data.id);
|
||||
new_elem.innerText = nomTag.value;
|
||||
|
||||
cible.appendChild(new_elem);
|
||||
|
||||
nomTag.value = "";
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function formulaire_traitement(event){
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
console.log( event );
|
||||
|
||||
let nom = document.getElementById('recette-form-nom');
|
||||
let temps = document.getElementsByName('recette-form-nom');
|
||||
let photo = document.getElementById('recette-form-photo');
|
||||
let ingredients = document.getElementById('recette-form-ingr');
|
||||
let tags = document.getElementById('recette-form-tag');
|
||||
let description = document.getElementById('recette-form-description');
|
||||
|
||||
if( nom.value === "" || temps.value == "" || ingredients.value === "" || tags.value === ""){
|
||||
console.log( "Another field" );
|
||||
alert( "Un champ requis est manquant." );
|
||||
return;
|
||||
}
|
||||
if( !IS_EDIT && photo.value === ""){
|
||||
console.log( "Photo field" );
|
||||
alert( "Un champ requis est manquant." );
|
||||
return;
|
||||
}
|
||||
|
||||
if( temps <= 0 ){
|
||||
alert( "Le temps doit être positif ou supérieur à 0." );
|
||||
return;
|
||||
}
|
||||
|
||||
let form_data = new FormData(compl_form);
|
||||
form_data.append( "ingredients", form_data.getAll("ingr").join(",") );
|
||||
form_data.append( "tags", form_data.getAll( "tag").join(",") );
|
||||
if( RECETTE_ID !== 0 )
|
||||
form_data.append( 'id', RECETTE_ID );
|
||||
|
||||
let endpoint = IS_EDIT ? "/api/recettes/edit" : "/api/recettes/create";
|
||||
|
||||
fetch( endpoint, {
|
||||
method : "POST",
|
||||
body: form_data
|
||||
}).then( reponse => {
|
||||
if (!reponse.ok) {
|
||||
alert( "Erreur survenie" );
|
||||
}
|
||||
else {
|
||||
reponse.json().then( data => {
|
||||
if (data.success) {
|
||||
if( IS_EDIT )
|
||||
alert( "Votre recette a été ajouté, vous allez être redirigé." );
|
||||
else
|
||||
alert( "Votre recette a été ajouté, vous allez être redirigé." );
|
||||
window.location.href = data.route !== null ? data.route : window.location.origin;
|
||||
} else {
|
||||
alert( data.error || "" );
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
let ingr_form = document.getElementById("recette-form-ingr-add");
|
||||
|
||||
ingr_form.addEventListener('submit', formulaire_ingredient_update);
|
||||
|
||||
let tag_form = document.getElementById("recette-form-tag-add");
|
||||
|
||||
tag_form.addEventListener('submit', formulaire_tag_update);
|
||||
compl_form.addEventListener('submit', formulaire_traitement);
|
||||
|
||||
|
||||
})
|
||||
5
public/assets/js/login.js
Normal file → Executable file
5
public/assets/js/login.js
Normal file → Executable file
@@ -49,14 +49,15 @@ document.addEventListener( 'DOMContentLoaded', function(){
|
||||
fetch( FORM.action, options ).then( ( response ) => {
|
||||
if( response.ok ){
|
||||
response.json().then( ( responseJSON ) => {
|
||||
|
||||
if( responseJSON.success === true ){
|
||||
window.location.href = window.location.origin; // Redirection sur la page d'accueil si succès.
|
||||
} else {
|
||||
FORM.showError( responseJSON.message || "Mauvais nom d'utilisateur ou mauvais mot de passe." );
|
||||
FORM.showError( "Mauvais nom d'utilisateur ou mauvais mot de passe." );
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
FORM.showError( "Mauvais nom d'utilisateur ou mauvais mot de passe." );
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
62
public/assets/js/manage-ingredients.js
Normal file
62
public/assets/js/manage-ingredients.js
Normal file
@@ -0,0 +1,62 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
|
||||
let modifier_button = document.getElementsByClassName("ingr-modifier");
|
||||
|
||||
console.log(modifier_button);
|
||||
|
||||
for (const element of modifier_button) {
|
||||
element.addEventListener('click', function ( e ) {
|
||||
let modif = element.parentElement.previousSibling.previousSibling;
|
||||
|
||||
let data = e.target.getAttribute("data-id");
|
||||
|
||||
let form = document.createElement("form");
|
||||
|
||||
form.setAttribute("method", "POST");
|
||||
form.setAttribute("action", "/ingredients/edit/" + data);
|
||||
form.setAttribute("class","liste-ingr-elem-text")
|
||||
|
||||
let input = document.createElement("input");
|
||||
|
||||
input.setAttribute("type", "text");
|
||||
input.setAttribute("class", "form-control");
|
||||
input.setAttribute("name","modif_ingr");
|
||||
input.setAttribute("placeholder", "modificiation");
|
||||
|
||||
let hidden = document.createElement("input");
|
||||
|
||||
hidden.setAttribute("type","hidden");
|
||||
hidden.setAttribute("name","id");
|
||||
hidden.setAttribute("value", data);
|
||||
|
||||
let button = document.createElement("button");
|
||||
|
||||
button.setAttribute("type", "submit");
|
||||
button.setAttribute("class", "btn btn-primary");
|
||||
button.innerText = "Submit Modification";
|
||||
|
||||
form.append(input)
|
||||
form.append(hidden)
|
||||
form.append(button)
|
||||
|
||||
modif.replaceWith(form);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
let suppr = document.getElementsByClassName("ingr-suppr");
|
||||
|
||||
for (const element of suppr) {
|
||||
element.addEventListener('click', function ( e ) {
|
||||
let confirm = window.confirm("Voulez vous supprimez ?");
|
||||
|
||||
let data = e.target.getAttribute("data-id");
|
||||
|
||||
if (confirm) {
|
||||
window.location.href = "/ingredients/delete/" + data;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
62
public/assets/js/manage-tags.js
Normal file
62
public/assets/js/manage-tags.js
Normal file
@@ -0,0 +1,62 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
|
||||
let modifier_button = document.getElementsByClassName("tag-modifier");
|
||||
|
||||
console.log(modifier_button);
|
||||
|
||||
for (const element of modifier_button) {
|
||||
element.addEventListener('click', function ( e ) {
|
||||
let modif = element.parentElement.previousSibling.previousSibling;
|
||||
|
||||
let data = e.target.getAttribute("data-id");
|
||||
|
||||
let form = document.createElement("form");
|
||||
|
||||
form.setAttribute("method", "POST");
|
||||
form.setAttribute("action", "/tags/edit/" + data);
|
||||
form.setAttribute("class","liste-tag-elem-text")
|
||||
|
||||
let input = document.createElement("input");
|
||||
|
||||
input.setAttribute("type", "text");
|
||||
input.setAttribute("class", "form-control");
|
||||
input.setAttribute("name","modif_tag");
|
||||
input.setAttribute("placeholder", "modificiation");
|
||||
|
||||
let hidden = document.createElement("input");
|
||||
|
||||
hidden.setAttribute("type","hidden");
|
||||
hidden.setAttribute("name","id");
|
||||
hidden.setAttribute("value", data);
|
||||
|
||||
let button = document.createElement("button");
|
||||
|
||||
button.setAttribute("type", "submit");
|
||||
button.setAttribute("class", "btn btn-primary");
|
||||
button.innerText = "Submit Modification";
|
||||
|
||||
form.append(input)
|
||||
form.append(hidden)
|
||||
form.append(button)
|
||||
|
||||
modif.replaceWith(form);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
let suppr = document.getElementsByClassName("tag-suppr");
|
||||
|
||||
for (const element of suppr) {
|
||||
element.addEventListener('click', function ( e ) {
|
||||
let confirm = window.confirm("Voulez vous supprimez ?");
|
||||
|
||||
let data = e.target.getAttribute("data-id");
|
||||
|
||||
if (confirm) {
|
||||
window.location.href = "/tags/delete/" + data;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
0
public/index.php
Normal file → Executable file
0
public/index.php
Normal file → Executable file
0
public/uploads/.gitignore
vendored
Normal file
0
public/uploads/.gitignore
vendored
Normal file
@@ -21,6 +21,12 @@ class Ingredient extends Model {
|
||||
*/
|
||||
public string $nom_ingredient;
|
||||
|
||||
/**
|
||||
* L'URL vers l'image de l'ingrédient.
|
||||
* @var string
|
||||
*/
|
||||
public string $photo_ingredient;
|
||||
|
||||
/**
|
||||
* Retourne le numéro de l'ingrédient.
|
||||
* @return int
|
||||
|
||||
70
src/Domain/Ingredients/IngredientManagementController.php
Normal file
70
src/Domain/Ingredients/IngredientManagementController.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Ingredients;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Domain\Ingredients\IngredientRepository;
|
||||
use App\Domain\Tags\TagRepository;
|
||||
use App\Helpers\Authentification;
|
||||
use App\Http\JSONResponse;
|
||||
use App\Http\Request;
|
||||
use App\Infrastructure\View;
|
||||
|
||||
class IngredientManagementController extends Controller {
|
||||
|
||||
public static function defineRoutes(): array
|
||||
{
|
||||
return [
|
||||
self::Route( routeUrl: '/manage/ingredients', routeName: 'manage->ingredients', routeAction: 'index', pageHeadTitle: 'Gestion des ingredients' ),
|
||||
self::Route( routeUrl: '/ingredients/edit/{int}', routeName: 'ingredients->edit', routeAction: 'edit', routeMethods: [ 'POST' ] ),
|
||||
self::Route( routeUrl: '/ingredients/delete/{int}', routeName: 'ingredients->delete', routeAction: 'delete' ),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function index(){
|
||||
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$tags = new IngredientRepository()->getAll();
|
||||
return new View( 'ingredients/index', [
|
||||
'ingredients' => $tags,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function edit( int $idIngredient ): never {
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$ing = new IngredientRepository()->getByID( $idIngredient );
|
||||
if( !$ing )
|
||||
die( "Ingredient not found" );
|
||||
|
||||
$name = Request::post( 'modif_ingr' );
|
||||
if( !$name || $name == "" )
|
||||
JSONResponse::sendError( [ 'error' => 'Name not defined' ] );
|
||||
|
||||
$ing->nom_ingredient = $name;
|
||||
|
||||
if( !new IngredientRepository()->update( $ing ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while updating ingredient' ] );
|
||||
|
||||
Request::redirectTo( 'manage->ingredients');
|
||||
}
|
||||
|
||||
public function delete( int $idIngredient ): never {
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$ing = new IngredientRepository()->getByID( $idIngredient );
|
||||
if( !$ing )
|
||||
die( "Tag not found" );
|
||||
|
||||
if( !new IngredientRepository()->delete( $ing ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while deleting ingredient' ] );
|
||||
|
||||
Request::redirectTo( 'manage->ingredients' );
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class IngredientRepository extends Repository implements LinkableInterface {
|
||||
return [
|
||||
'table' => 'Ingredient',
|
||||
'columns' => [
|
||||
'num_ingredient', 'nom_ingredient'
|
||||
'num_ingredient', 'nom_ingredient', 'photo_ingredient',
|
||||
],
|
||||
'link_recettes' => 'Listeingredient'
|
||||
];
|
||||
|
||||
71
src/Domain/Ingredients/IngredientsAPIController.php
Normal file
71
src/Domain/Ingredients/IngredientsAPIController.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Ingredients;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Helpers\UploadFiles;
|
||||
use App\Http\JSONResponse;
|
||||
use App\Http\Request;
|
||||
use App\Kernel;
|
||||
|
||||
class IngredientsAPIController extends Controller {
|
||||
|
||||
public static function defineRoutes(): array
|
||||
{
|
||||
return [
|
||||
self::Route( routeUrl: '/api/ingredients/create', routeName: 'api->ingredients->create', routeAction: 'create', routeMethods: ['POST'] ),
|
||||
self::Route( routeUrl: '/api/ingredients/edit', routeName: 'api->ingredients->edit', routeAction: 'edit', routeMethods: ['POST'] ),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function create(){
|
||||
|
||||
$name = Request::post( 'name' );
|
||||
$fileNameField = "image";
|
||||
if( !$name || $name == "" )
|
||||
JSONResponse::sendError( [ 'error' => 'Name not defined' ] );
|
||||
|
||||
$urlOrError = UploadFiles::uploadFile( $fileNameField, UploadFiles::IMAGE_MIME_TYPES );
|
||||
if( is_int( $urlOrError ) ){
|
||||
JSONResponse::sendError( [ 'error' => $urlOrError ] );
|
||||
}
|
||||
|
||||
$ingredient = new Ingredient();
|
||||
|
||||
$ingredient->num_ingredient = 0;
|
||||
$ingredient->nom_ingredient = $name;
|
||||
$ingredient->photo_ingredient = $urlOrError;
|
||||
|
||||
if( !new IngredientRepository()->add( $ingredient ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while adding ingredient' ] );
|
||||
|
||||
JSONResponse::sendSuccess( [ 'image_url' => $urlOrError, 'id' => Kernel::$DB->pdo->lastInsertId() ] );
|
||||
|
||||
}
|
||||
|
||||
public function edit(){
|
||||
|
||||
$id = Request::post( 'id' ) ?? 0;
|
||||
$ingredient = new IngredientRepository()->getByID( $id );
|
||||
if( !$ingredient )
|
||||
JSONResponse::sendError( [ 'error' => 'Ingredient not found' ] );
|
||||
|
||||
$name = Request::post( 'name' );
|
||||
$fileNameField = "image";
|
||||
|
||||
if( $name ) {
|
||||
$ingredient->nom_ingredient = $name;
|
||||
}
|
||||
|
||||
$urlOrError = UploadFiles::uploadFile( $fileNameField );
|
||||
if( !is_int( $urlOrError ) ){
|
||||
$ingredient->photo_ingredient = $urlOrError;
|
||||
}
|
||||
|
||||
if( !new IngredientRepository()->update( $ingredient ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while updating ingredient' ] );
|
||||
|
||||
JSONResponse::sendSuccess( [] );
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Domain\Pages;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Domain\Recettes\RecetteRepository;
|
||||
use App\Infrastructure\View;
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ class PagesController extends Controller {
|
||||
* @return void
|
||||
*/
|
||||
public function index(): View {
|
||||
return new View( 'home', [ 'ok' => 'bla' ] );
|
||||
return new View( 'home', [ 'recettes' => new RecetteRepository()->getAllRecettesBrowse(1, 3 ) ] );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,11 +6,13 @@ use App\Domain\Ingredients\Ingredient;
|
||||
use App\Domain\Ingredients\IngredientRepository;
|
||||
use App\Domain\Ingredients\UseIngredientsInterface;
|
||||
use App\Domain\Model;
|
||||
use App\Domain\Tags\Tag;
|
||||
use App\Helpers\Markdown;
|
||||
|
||||
/**
|
||||
* Classe qui va permettre de gérer tous les objets recette.
|
||||
*/
|
||||
#[\AllowDynamicProperties]
|
||||
class Recette extends Model {
|
||||
|
||||
public int $num_recette;
|
||||
@@ -43,6 +45,15 @@ class Recette extends Model {
|
||||
return new RecetteRepository()->getAllLinkedIngredients( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère une liste de tous les tags liés à la recette.
|
||||
* @return Tag[]|null
|
||||
*/
|
||||
public function getAllLinkedTags(): ?array
|
||||
{
|
||||
return new RecetteRepository()->getAllLinkedTags( $this );
|
||||
}
|
||||
|
||||
public function getNumberOfIngredients(): int {
|
||||
|
||||
$response = $this->getAllLinkedIngredients();
|
||||
|
||||
@@ -67,7 +67,7 @@ class RecetteRepository extends Repository implements UseIngredientsInterface, U
|
||||
if( $results === null )
|
||||
return null;
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet d'avoir une recette par un ID.
|
||||
@@ -90,13 +90,47 @@ class RecetteRepository extends Repository implements UseIngredientsInterface, U
|
||||
* @return Recette|null
|
||||
*/
|
||||
public function getBySlug( string $slug ): ?Recette {
|
||||
$sqlQuery = "SELECT * FROM {$this->tableName} WHERE slug = {$slug}";
|
||||
$sqlQuery = "SELECT * FROM {$this->tableName} WHERE slug = '{$slug}'";
|
||||
$results = $this->selectGetAll($sqlQuery);
|
||||
if( $results === null || count( $results ) > 1 )
|
||||
return null;
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
public function advancedRecetteSearch( string $title = "", array $tagsId= [], array $ingredientsId= [] ): ?array {
|
||||
|
||||
$tableLinkIngredients = IngredientRepository::getStructure()['link_recettes'];
|
||||
$tableLinkTags = TagRepository::getStructure()['link_recettes'];
|
||||
|
||||
$sqlQuery = "SELECT ({$this->tableName}.num_recette) FROM {$this->tableName} LEFT JOIN {$tableLinkIngredients} ON {$this->tableName}.num_recette = {$tableLinkIngredients}.num_recette LEFT JOIN {$tableLinkTags} ON {$this->tableName}.num_recette = {$tableLinkTags}.num_recette";
|
||||
|
||||
if( $title != "" || $tagsId !== [] || $ingredientsId !== [] ) {
|
||||
$sqlQuery .= " WHERE ";
|
||||
if ($title != "")
|
||||
$sqlQuery .= " titre_recette LIKE '%{$title}%' AND";
|
||||
if ($tagsId !== [])
|
||||
$sqlQuery .= " num_tag IN (" . implode(",", $tagsId) . ") AND";
|
||||
if ($ingredientsId !== [])
|
||||
$sqlQuery .= " num_ingredient IN (" . implode(",", $ingredientsId) . ") AND";
|
||||
$sqlQuery = substr($sqlQuery, 0, -3);
|
||||
}
|
||||
$sqlQuery .= ";";
|
||||
|
||||
$results = $this->selectGetAll($sqlQuery, true);
|
||||
if( $results === null )
|
||||
return null;
|
||||
|
||||
$alreadyGettedId = [];
|
||||
for( $i = 0; $i < count( $results ); $i++ ){
|
||||
if( in_array( $results[$i]['num_recette'], $alreadyGettedId ) )
|
||||
unset( $results[$i] );
|
||||
else
|
||||
$alreadyGettedId[] = $results[$i]['num_recette'];
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function add( Model $recette ): bool {
|
||||
return $this->addEntity( $recette );
|
||||
}
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
namespace App\Domain\Recettes;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Domain\Ingredients\IngredientRepository;
|
||||
use App\Domain\Tags\TagRepository;
|
||||
use App\Helpers\UploadFiles;
|
||||
use App\Http\JSONResponse;
|
||||
use App\Http\Request;
|
||||
use App\Http\Router;
|
||||
use App\Kernel;
|
||||
|
||||
class RecettesAPIController extends Controller {
|
||||
|
||||
@@ -10,7 +17,288 @@ class RecettesAPIController extends Controller {
|
||||
{
|
||||
return [
|
||||
self::Route( routeUrl: '/api/recettes/list', routeName: 'api->recettes->list', routeAction: 'list', routeMethods: ['POST'] ),
|
||||
self::Route( routeUrl: '/api/recettes/create', routeName: 'api->recettes->create', routeAction: 'create', routeMethods: ['POST'] ),
|
||||
self::Route( routeUrl: '/api/recettes/edit', routeName: 'api->recettes->edit', routeAction: 'edit', routeMethods: ['POST'] ),
|
||||
self::Route( routeUrl: '/api/recettes/delete', routeName: 'api->recettes->delete', routeAction: 'delete', routeMethods: ['POST'] ),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function list(){
|
||||
|
||||
$title = Request::post( 'title' ) ?? "";
|
||||
$tagsId = explode( ",", Request::post( 'tagsId' ) ) ?? [];
|
||||
$ingredientsId = explode( ",", Request::post( 'ingredientsId' ) ) ?? [];
|
||||
|
||||
if( $tagsId == [ "" ] )
|
||||
$tagsId = [];
|
||||
if( $ingredientsId == [ "" ] )
|
||||
$ingredientsId = [];
|
||||
|
||||
$tagsId = array_map( 'intval', $tagsId );
|
||||
$ingredientsId = array_map( 'intval', $ingredientsId );
|
||||
|
||||
|
||||
$recetteRepo = new RecetteRepository();
|
||||
$resp = $recetteRepo->advancedRecetteSearch( $title, $tagsId, $ingredientsId );
|
||||
|
||||
$objResp = [];
|
||||
foreach( $resp as $r ){
|
||||
$r = $recetteRepo->getByID( $r['num_recette'] );
|
||||
$r->url = Router::getRouteURL( 'recettes->show', $r->slug );
|
||||
$r->nb_ingredients = $r->getNumberOfIngredients();
|
||||
if( !in_array( $r, $objResp ) ){
|
||||
$objResp[] = $r;
|
||||
}
|
||||
}
|
||||
|
||||
JSONResponse::sendSuccess( [ 'data' => $objResp ] );
|
||||
|
||||
}
|
||||
|
||||
public function create(){
|
||||
|
||||
// Récupération des champs.
|
||||
$name = Request::post( 'nom' ) ?? "";
|
||||
$temps = Request::post( 'temps' ) ?? "";
|
||||
$fileField = "image";
|
||||
|
||||
$tagsId = explode( ",", Request::post( 'tags' ) ) ?? [];
|
||||
$ingredientsId = explode( ",", Request::post( 'ingredients' ) ) ?? [];
|
||||
|
||||
if( $tagsId == [ "" ] )
|
||||
$tagsId = [];
|
||||
if( $ingredientsId == [ "" ] )
|
||||
$ingredientsId = [];
|
||||
|
||||
$tagsId = array_map( 'intval', $tagsId );
|
||||
$ingredientsId = array_map( 'intval', $ingredientsId );
|
||||
|
||||
$description = Request::post( 'description' );
|
||||
|
||||
// Vérification.
|
||||
if( $name == "" || $temps == "" || $ingredientsId == [] || $description == "" )
|
||||
JSONResponse::sendError( [ 'error' => "One required fields is missing" ] );
|
||||
|
||||
// Upload & Vérification de l'image.
|
||||
$urlOrError = UploadFiles::uploadFile( $fileField, UploadFiles::IMAGE_MIME_TYPES );
|
||||
if( is_int( $urlOrError ) ){
|
||||
JSONResponse::sendError( [ 'error' => $urlOrError ] );
|
||||
}
|
||||
|
||||
// Vérification d'une entrée qui existerait déjà.
|
||||
$slug = strtolower( $name );
|
||||
$slug = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $slug);
|
||||
$slug = str_replace( ' ', '', $slug );
|
||||
|
||||
$recetteRepo = new RecetteRepository();
|
||||
|
||||
if( $recetteRepo->getBySlug( $slug ) ){
|
||||
JSONResponse::sendError( [ 'error' => "Recette already exists" ] );
|
||||
}
|
||||
if( in_array( $slug, [ 'create', 'edit', 'delete' ] ) ){
|
||||
JSONResponse::sendError( [ 'error' => "Recette already exists" ] );
|
||||
}
|
||||
|
||||
// Création de la recette.
|
||||
$recette = new Recette();
|
||||
|
||||
$recette->num_recette = 0;
|
||||
$recette->titre_recette = $name;
|
||||
$recette->slug = $slug;
|
||||
|
||||
$recette->temps_de_preparation = intval( $temps <= 0 ? 1 : $temps );
|
||||
$recette->photo = $urlOrError;
|
||||
$recette->description_recette = $description;
|
||||
$recette->publication_date = date("Y-m-d");
|
||||
|
||||
// Importation de la recette.
|
||||
if( !$recetteRepo->add( $recette ) ){
|
||||
JSONResponse::sendError( [ 'error' => "Error adding recette" ] );
|
||||
}
|
||||
|
||||
// Pour actualiser l'ID.
|
||||
$recette = $recetteRepo->getById( Kernel::$DB->pdo->lastInsertId() );
|
||||
|
||||
// Ajout du lien ingrédients recettes.
|
||||
foreach( $ingredientsId as $ingredientId ){
|
||||
$ingredient = new IngredientRepository()->getByID( $ingredientId );
|
||||
if( $ingredient == null )
|
||||
continue;
|
||||
$recetteRepo->addAnIngredient( $ingredient, $recette );
|
||||
}
|
||||
|
||||
// Ajout du lien Recettes tags.
|
||||
if( $tagsId != [] ){
|
||||
foreach( $tagsId as $tagId ){
|
||||
$tag = new TagRepository()->getByID( $tagId );
|
||||
if( $tag == null )
|
||||
continue;
|
||||
$recetteRepo->addATag( $tag, $recette );
|
||||
}
|
||||
}
|
||||
|
||||
JSONResponse::sendSuccess( [ 'recette' => $recette, 'route' => Router::getRouteURL('recettes->show', $recette->slug ) ] );
|
||||
}
|
||||
|
||||
public function edit(){
|
||||
|
||||
// Récupération des champs.
|
||||
$id = Request::post( 'id' );
|
||||
$name = Request::post( 'nom' ) ?? "";
|
||||
$temps = Request::post( 'temps' ) ?? "";
|
||||
$fileField = "image";
|
||||
|
||||
$tagsId = explode( ",", Request::post( 'tags' ) ) ?? [];
|
||||
$ingredientsId = explode( ",", Request::post( 'ingredients' ) ) ?? [];
|
||||
|
||||
if( $tagsId == [ "" ] )
|
||||
$tagsId = [];
|
||||
if( $ingredientsId == [ "" ] )
|
||||
$ingredientsId = [];
|
||||
|
||||
$tagsId = array_map( 'intval', $tagsId );
|
||||
$ingredientsId = array_map( 'intval', $ingredientsId );
|
||||
|
||||
$description = Request::post( 'description' );
|
||||
|
||||
// Vérification.
|
||||
if( $id == "" || $name == "" || $temps == "" || $ingredientsId == [] || $description == "" )
|
||||
JSONResponse::sendError( [ 'error' => "One required fields is missing" ] );
|
||||
|
||||
$recetteRepo = new RecetteRepository();
|
||||
$recette = $recetteRepo->getByID( $id );
|
||||
if( !$recette ){
|
||||
JSONResponse::sendError( [ 'error' => "Recette not found" ] );
|
||||
}
|
||||
|
||||
// Upload & Vérification de l'image.
|
||||
$urlOrError = UploadFiles::uploadFile( $fileField, UploadFiles::IMAGE_MIME_TYPES );
|
||||
if( is_int( $urlOrError ) ){
|
||||
// Ingore image.
|
||||
} else {
|
||||
$recette->photo = $urlOrError;
|
||||
}
|
||||
|
||||
// Vérification d'une entrée qui existerait déjà.
|
||||
$slug = strtolower( $name );
|
||||
$slug = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $slug);
|
||||
$slug = str_replace( ' ', '', $slug );
|
||||
|
||||
$recette->titre_recette = $name;
|
||||
// $recette->slug = $slug;
|
||||
|
||||
$recette->temps_de_preparation = intval( $temps <= 0 ? 1 : $temps );
|
||||
$recette->description_recette = $description;
|
||||
|
||||
// Importation de la recette.
|
||||
if( !$recetteRepo->update( $recette ) ){
|
||||
JSONResponse::sendError( [ 'error' => "Error updating recette" ] );
|
||||
}
|
||||
|
||||
// Actualisation des ingrédients.
|
||||
$ingrObjArray = $recette->getAllLinkedIngredients();
|
||||
if( !$ingrObjArray || $ingrObjArray === [] ){ // Si il n'y a pas déjà d'autres ingrédients, on ajoute tous ceux présents ici.
|
||||
|
||||
foreach( $ingredientsId as $ingredientId ){
|
||||
$ingredient = new IngredientRepository()->getByID( $ingredientId );
|
||||
if( $ingredient == null )
|
||||
continue;
|
||||
$recetteRepo->addAnIngredient( $ingredient, $recette );
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$ingrIntArray = array_map( function($ingr){
|
||||
return intval( $ingr->getID() );
|
||||
}, $ingrObjArray );
|
||||
|
||||
foreach( $ingrIntArray as $ingrId ){
|
||||
// Si un ingrédient n'est pas dans la nouvelle liste d'ingrédients, il faut retirer le lien.
|
||||
if( !in_array( $ingrId, $ingredientsId ) ){
|
||||
$ingredient = new IngredientRepository()->getByID( $ingrId );
|
||||
if( $ingredient == null )
|
||||
continue;
|
||||
$recetteRepo->removeAnIngredient( $ingredient, $recette );
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $ingredientsId as $ingrId ){
|
||||
// Si un ingrédient n'est pas dans l'ancienne liste, il faut ajouter un lien.
|
||||
if( !in_array( $ingrId, $ingrIntArray ) ){
|
||||
$ingredient = new IngredientRepository()->getByID( $ingrId );
|
||||
if( $ingredient == null )
|
||||
continue;
|
||||
$recetteRepo->addAnIngredient( $ingredient, $recette );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Actualisation des tags.
|
||||
if( $tagsId != [] ) {
|
||||
$tagObjArray = $recette->getAllLinkedTags();
|
||||
if (!$tagObjArray || $tagObjArray === []) { // Si il n'y a pas déjà d'autres tags, on ajoute tous ceux présents ici.
|
||||
|
||||
foreach ($tagsId as $tagId) {
|
||||
$tag = new TagRepository()->getByID($tagId);
|
||||
if ($tag == null)
|
||||
continue;
|
||||
$recetteRepo->addATag($tag, $recette);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$tagIntArray = array_map(function ($ingr) {
|
||||
return intval( $ingr->getID() );
|
||||
}, $tagObjArray);
|
||||
|
||||
foreach ($tagIntArray as $tagId) {
|
||||
// Si un ingrédient n'est pas dans la nouvelle liste d'ingrédients, il faut retirer le lien.
|
||||
if (!in_array($tagId, $tagsId)) {
|
||||
$tag = new TagRepository()->getByID($tagId);
|
||||
if ($tag == null)
|
||||
continue;
|
||||
$recetteRepo->removeATag($tag, $recette);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($tagsId as $tagId) {
|
||||
// Si un ingrédient n'est pas dans l'ancienne liste, il faut ajouter un lien.
|
||||
if (!in_array($tagId, $tagIntArray)) {
|
||||
$tag = new TagRepository()->getByID($tagId);
|
||||
if ($tag == null)
|
||||
continue;
|
||||
$recetteRepo->addATag($tag, $recette);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
JSONResponse::sendSuccess( [ 'recette' => $recette, 'route' => Router::getRouteURL('recettes->show', $recette->slug ) ] );
|
||||
}
|
||||
|
||||
public function delete(){
|
||||
$id = Request::post( 'id' );
|
||||
$recette = new RecetteRepository()->getByID( $id );
|
||||
if( !$recette )
|
||||
JSONResponse::sendError( [ 'error' => 'Recette not found' ] );
|
||||
|
||||
$recetteRepo = new RecetteRepository();
|
||||
|
||||
// Retirer tous les liens Ingrédients/Tags.
|
||||
foreach( ( $recette->getAllLinkedIngredients() ?? [] ) as $ingr ){
|
||||
$recetteRepo->removeAnIngredient( $ingr, $recette );
|
||||
}
|
||||
foreach( ( $recette->getAllLinkedTags() ?? [] ) as $tag ){
|
||||
$recetteRepo->removeATag( $tag, $recette );
|
||||
}
|
||||
|
||||
if( !$recetteRepo->delete( $recette ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while deleting recette' ] );
|
||||
|
||||
JSONResponse::sendSuccess();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -33,4 +33,15 @@ class RecettesController extends Controller {
|
||||
] );
|
||||
}
|
||||
|
||||
public function show( string $slug ): View {
|
||||
|
||||
$recette = new RecetteRepository()->getBySlug( $slug );
|
||||
if( !$recette )
|
||||
die( "Recette not found" );
|
||||
|
||||
return new View( 'recettes/show', [
|
||||
'recette' => $recette,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,15 +3,83 @@
|
||||
namespace App\Domain\Recettes;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Domain\Ingredients\IngredientRepository;
|
||||
use App\Domain\Tags\TagRepository;
|
||||
use App\Helpers\Authentification;
|
||||
use App\Http\JSONResponse;
|
||||
use App\Http\Request;
|
||||
use App\Infrastructure\View;
|
||||
|
||||
class RecettesManagementController extends Controller {
|
||||
|
||||
public static function defineRoutes(): array
|
||||
{
|
||||
return [
|
||||
self::Route( routeUrl: '/recettes/create', routeName: 'recettes->create', routeAction: 'create' ),
|
||||
self::Route( routeUrl: '/recettes/edit/{int}', routeName: 'recettes->edit', routeAction: 'edit' ),
|
||||
self::Route( routeUrl: '/recettes/create', routeName: 'recettes->create', routeAction: 'create', pageHeadTitle: 'Créer une recette' ),
|
||||
self::Route( routeUrl: '/recettes/edit/{int}', routeName: 'recettes->edit', routeAction: 'edit', pageHeadTitle: 'Modifier une recette' ),
|
||||
self::Route( routeUrl: '/recettes/delete/{int}', routeName: 'recettes->delete', routeAction: 'delete' ),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function create(): View {
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
return new View( 'recettes/create', [
|
||||
'tags' => new TagRepository()->getAll(),
|
||||
'ingredients' => new IngredientRepository()->getAll(),
|
||||
] );
|
||||
}
|
||||
|
||||
public function edit( int $idRecette ): View {
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$recette = new RecetteRepository()->getByID( $idRecette );
|
||||
if( !$recette )
|
||||
die( "Recette not found" );
|
||||
|
||||
$tagsID = array_map( function($tag) {
|
||||
return $tag->getId();
|
||||
}
|
||||
, $recette->getAllLinkedTags() ?? [] );
|
||||
|
||||
$ingredientsID = array_map( function($tag) {
|
||||
return $tag->getId();
|
||||
}
|
||||
, $recette->getAllLinkedIngredients() ?? [] );
|
||||
|
||||
return new View( 'recettes/edit', [
|
||||
'recette' => $recette,
|
||||
'recetteTags' => $tagsID,
|
||||
'recetteIngr' => $ingredientsID,
|
||||
'tags' => new TagRepository()->getAll(),
|
||||
'ingredients' => new IngredientRepository()->getAll(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete( int $idRecette ): never {
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$recette = new RecetteRepository()->getByID( $idRecette );
|
||||
if( !$recette )
|
||||
die( "Recette not found" );
|
||||
|
||||
$recetteRepo = new RecetteRepository();
|
||||
|
||||
// Retirer tous les liens Ingrédients/Tags.
|
||||
foreach( ( $recette->getAllLinkedIngredients() ?? [] ) as $ingr ){
|
||||
$recetteRepo->removeAnIngredient( $ingr, $recette );
|
||||
}
|
||||
foreach( ( $recette->getAllLinkedTags() ?? [] ) as $tag ){
|
||||
$recetteRepo->removeATag( $tag, $recette );
|
||||
}
|
||||
|
||||
if( !$recetteRepo->delete( $recette ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while deleting recette' ] );
|
||||
|
||||
Request::redirectTo( 'recettes->index' );
|
||||
}
|
||||
}
|
||||
69
src/Domain/Tags/TagManagementController.php
Normal file
69
src/Domain/Tags/TagManagementController.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Tags;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Domain\Ingredients\IngredientRepository;
|
||||
use App\Domain\Tags\TagRepository;
|
||||
use App\Helpers\Authentification;
|
||||
use App\Http\JSONResponse;
|
||||
use App\Http\Request;
|
||||
use App\Infrastructure\View;
|
||||
|
||||
class TagManagementController extends Controller {
|
||||
|
||||
public static function defineRoutes(): array
|
||||
{
|
||||
return [
|
||||
self::Route( routeUrl: '/manage/tags', routeName: 'manage->tags', routeAction: 'index', pageHeadTitle: 'Gestion des tags' ),
|
||||
self::Route( routeUrl: '/tags/edit/{int}', routeName: 'tags->edit', routeAction: 'edit', routeMethods: [ 'POST' ] ),
|
||||
self::Route( routeUrl: '/tags/delete/{int}', routeName: 'tags->delete', routeAction: 'delete' ),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function index(){
|
||||
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$tags = new TagRepository()->getAll();
|
||||
return new View( 'tags/index', [
|
||||
'tags' => $tags,
|
||||
]);
|
||||
|
||||
}
|
||||
public function edit( int $idTag ): never {
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$tag = new TagRepository()->getByID( $idTag );
|
||||
if( !$tag )
|
||||
die( "Tag not found" );
|
||||
|
||||
$name = Request::post( 'modif_tag' );
|
||||
if( !$name || $name == "" )
|
||||
JSONResponse::sendError( [ 'error' => 'Name not defined' ] );
|
||||
|
||||
$tag->nom_tag = $name;
|
||||
|
||||
if( !new TagRepository()->update( $tag ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while updating tag' ] );
|
||||
|
||||
Request::redirectTo( 'manage->tags');
|
||||
}
|
||||
|
||||
public function delete( int $idTag ): never {
|
||||
if( !Authentification::isLoggedIn() )
|
||||
die( "Not logged in" );
|
||||
|
||||
$tag = new \App\Domain\Tags\TagRepository()->getByID( $idTag );
|
||||
if( !$tag )
|
||||
die( "Tag not found" );
|
||||
|
||||
if( !new TagRepository()->delete( $tag ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while deleting tag' ] );
|
||||
|
||||
Request::redirectTo( 'manage->tags' );
|
||||
}
|
||||
}
|
||||
73
src/Domain/Tags/TagsAPIController.php
Normal file
73
src/Domain/Tags/TagsAPIController.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Tags;
|
||||
|
||||
use App\Domain\Controller;
|
||||
use App\Helpers\UploadFiles;
|
||||
use App\Http\JSONResponse;
|
||||
use App\Http\Request;
|
||||
use App\Kernel;
|
||||
|
||||
class TagsAPIController extends Controller {
|
||||
|
||||
public static function defineRoutes(): array
|
||||
{
|
||||
return [
|
||||
self::Route( routeUrl: '/api/tags/create', routeName: 'api->tags->create', routeAction: 'create', routeMethods: ['POST'] ),
|
||||
self::Route( routeUrl: '/api/tags/edit', routeName: 'api->tags->edit', routeAction: 'edit', routeMethods: ['POST'] ),
|
||||
self::Route( routeUrl: '/api/tags/delete', routeName: 'api->tags->delete', routeAction: 'delete', routeMethods: ['POST'] ),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function create(){
|
||||
|
||||
$name = Request::post( 'name' );
|
||||
if( !$name || $name == "" )
|
||||
JSONResponse::sendError( [ 'error' => 'Name not defined' ] );
|
||||
|
||||
$tag = new Tag();
|
||||
$tag->num_tag = 0;
|
||||
$tag->nom_tag = $name;
|
||||
|
||||
if( !new TagRepository()->add( $tag ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while adding tag' ] );
|
||||
|
||||
JSONResponse::sendSuccess( [ 'id' => Kernel::$DB->pdo->lastInsertId() ] );
|
||||
|
||||
}
|
||||
|
||||
public function edit(){
|
||||
|
||||
$id = Request::post( 'id' ) ?? 0;
|
||||
$tag = new TagRepository()->getByID( $id );
|
||||
if( !$tag )
|
||||
JSONResponse::sendError( [ 'error' => 'Tag not found' ] );
|
||||
|
||||
$name = Request::post( 'name' );
|
||||
if( !$name || $name == "" )
|
||||
JSONResponse::sendError( [ 'error' => 'Name not defined' ] );
|
||||
|
||||
$tag->nom_tag = $name;
|
||||
|
||||
if( !new TagRepository()->update( $tag ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while updating tag' ] );
|
||||
|
||||
JSONResponse::sendSuccess();
|
||||
|
||||
}
|
||||
|
||||
public function delete(){
|
||||
|
||||
$id = Request::post( 'id' ) ?? 0;
|
||||
$tag = new TagRepository()->getByID( $id );
|
||||
if( !$tag )
|
||||
JSONResponse::sendError( [ 'error' => 'Tag not found' ] );
|
||||
|
||||
if( !new TagRepository()->delete( $tag ) )
|
||||
JSONResponse::sendError( [ 'error' => 'An error occured while deleting tag' ] );
|
||||
|
||||
JSONResponse::sendSuccess();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -43,19 +43,17 @@ class AuthentificationController extends Controller {
|
||||
|
||||
Request::setCORS();
|
||||
|
||||
$username = Request::get( 'username' );
|
||||
$password = Request::get( 'password' );
|
||||
$username = Request::post( 'username' );
|
||||
$password = Request::post( 'password' );
|
||||
|
||||
$success = new \App\Domain\Utilisateurs\UtilisateursRepository()->login($username,$password);
|
||||
if(!$success) return JSONResponse::sendError( [ 'user_id' => $userId ] );
|
||||
$userId = new UtilisateurRepository()->login( $username, $password );
|
||||
if( !$userId ) {
|
||||
return JSONResponse::sendError();
|
||||
}
|
||||
|
||||
$userId = $success;
|
||||
Authentification::loginUser( $userId );
|
||||
return JSONResponse::sendSuccess( [ 'user_id' => $userId ] );
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function logout(): JSONResponse {
|
||||
|
||||
@@ -5,10 +5,7 @@ namespace App\Domain\Utilisateurs;
|
||||
use App\Domain\Model;
|
||||
//use App\Helpers\Markdown;
|
||||
|
||||
/**
|
||||
* Classe qui va permettre de gérer tous les objets recette.
|
||||
*/
|
||||
class Utilisateurs extends Model {
|
||||
class Utilisateur extends Model {
|
||||
|
||||
public int $num_user;
|
||||
public string $username;
|
||||
@@ -7,14 +7,13 @@ use App\Domain\Repository;
|
||||
|
||||
|
||||
/**
|
||||
* Classe qui permet de faire le lien entre la BDD et le site pour les recettes.
|
||||
* Les recettes sont en lien avec les ingrédients.
|
||||
* Classe qui permet de faire le lien entre la BDD et le site pour les utilisateurs.
|
||||
*/
|
||||
class UtilisateursRepository extends Repository {
|
||||
class UtilisateurRepository extends Repository {
|
||||
|
||||
public static function getEntity(): string
|
||||
{
|
||||
return Utilisateurs::class;
|
||||
return Utilisateur::class;
|
||||
}
|
||||
|
||||
public static function getStructure(): array
|
||||
@@ -29,9 +28,9 @@ class UtilisateursRepository extends Repository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet d'obtenir une liste de toutes les recettes objet Recette.
|
||||
* Permet d'obtenir une liste de toutes les recettes objet Utilisateur.
|
||||
*
|
||||
* @return Recette[]|null
|
||||
* @return Utilisateur[]|null
|
||||
*/
|
||||
public function getAll(): ?array {
|
||||
$sqlQuery = "SELECT * FROM {$this->tableName};";
|
||||
@@ -43,12 +42,12 @@ class UtilisateursRepository extends Repository {
|
||||
|
||||
|
||||
/**
|
||||
* Permet d'avoir une recette par un ID.
|
||||
* Permet d'avoir un utilisateur par un ID.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Recette|null
|
||||
* @return Utilisateur|null
|
||||
*/
|
||||
public function getByID( int $id ): ?Utilisateurs {
|
||||
public function getByID( int $id ): ?Utilisateur {
|
||||
$sqlQuery = "SELECT * FROM {$this->tableName} WHERE num_user = {$id}";
|
||||
$results = $this->selectGetAll($sqlQuery);
|
||||
if( $results === null || count( $results ) > 1 )
|
||||
@@ -59,18 +58,13 @@ class UtilisateursRepository extends Repository {
|
||||
|
||||
public function login(string $name, string $pass): int|bool{
|
||||
|
||||
$users = new UtilisateursRepository()->getAll();
|
||||
echo "\n\n";
|
||||
var_dump($users);
|
||||
foreach($users as $user){
|
||||
if((strcmp($name,$user->username)==0) and (strcmp($pass,$user->userpassword)==0))return $user->num_user;
|
||||
return false;
|
||||
|
||||
$users = new UtilisateurRepository()->getAll();
|
||||
foreach($users as $user){
|
||||
if((strcmp($name,$user->username)==0) and (strcmp($pass,$user->userpassword)==0))return $user->num_user;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function add( Model $utilisateurs ): bool {
|
||||
return $this->addEntity( $utilisateurs );
|
||||
}
|
||||
@@ -83,7 +77,4 @@ class UtilisateursRepository extends Repository {
|
||||
return $this->deleteEntity( $utilisateurs, 'num_user' );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
60
src/Helpers/UploadFiles.php
Normal file
60
src/Helpers/UploadFiles.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use App\Http\Router;
|
||||
use App\Kernel;
|
||||
|
||||
class UploadFiles {
|
||||
|
||||
const array IMAGE_MIME_TYPES = [ 'image/png', 'image/jpeg' ];
|
||||
|
||||
public static function uploadFolderPath(){
|
||||
return APP_ROOT . 'public/uploads/';
|
||||
}
|
||||
public static function uploadFolderUri(){
|
||||
return Kernel::$configs['general']['website_url'] . 'uploads/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
* @param array $allowedMimeTypes Les mimes types autorisés pour ce fichier. Une liste vide n'a pas de restriction de mime type.
|
||||
*
|
||||
* @return string|int
|
||||
*
|
||||
* 1: Pas de fichier $fileArg
|
||||
* 2: Erreur dans le fichier
|
||||
* 3: Déjà existant.
|
||||
* 4: Erreur dans le déplacement.
|
||||
* 5: Erreur dans le mimetype.
|
||||
*/
|
||||
public static function uploadFile( string $fileArg, array $allowedMimeTypes = [] ): string|int {
|
||||
|
||||
if( !isset( $_FILES[ $fileArg ] ) )
|
||||
return 1;
|
||||
|
||||
$file = $_FILES[ $fileArg ];
|
||||
if( $file['error'] != 0 )
|
||||
return 2;
|
||||
|
||||
$tempFileName = $file['tmp_name'];
|
||||
$fileName = $file['name'];
|
||||
|
||||
if( $allowedMimeTypes !== [] ){
|
||||
if( !in_array( $file['type'], $allowedMimeTypes ) )
|
||||
return 5;
|
||||
}
|
||||
|
||||
$full_name = self::uploadFolderPath() . $fileName;
|
||||
$full_uri = self::uploadFolderUri() . $fileName;
|
||||
|
||||
if( file_exists( $full_name ) )
|
||||
return 3;
|
||||
|
||||
if( !move_uploaded_file($tempFileName, $full_name) )
|
||||
return 4;
|
||||
|
||||
return $full_uri;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,19 +15,19 @@ final class Router {
|
||||
* @var string
|
||||
*/
|
||||
public private(set) static string $clientRouteString;
|
||||
// private(set)
|
||||
|
||||
/**
|
||||
* Informations de la route du client.
|
||||
* @var Route
|
||||
*/
|
||||
public static Route $clientRoute;
|
||||
// private(set)
|
||||
public private(set) static Route $clientRoute;
|
||||
|
||||
/**
|
||||
* Informations sur les arguments passés à la route.
|
||||
* @var array
|
||||
*/
|
||||
public static array $clientRouteArguments;
|
||||
// private(set)
|
||||
public private(set) static array $clientRouteArguments;
|
||||
|
||||
/**
|
||||
* Liste des controllers sorti du cache ou récupéré via fetchControllers.
|
||||
* @var array
|
||||
@@ -166,10 +166,7 @@ final class Router {
|
||||
$controller = self::$clientRoute->routeController;
|
||||
$method = self::$clientRoute->routeAction;
|
||||
|
||||
(new $controller())->$method( ...self::$clientRouteArguments);
|
||||
//correction controler()->method to controler().method
|
||||
// new $controller()->$method( ...self::$clientRouteArguments);
|
||||
|
||||
new $controller()->$method( ...self::$clientRouteArguments);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,36 +1,23 @@
|
||||
<h1>Coucou</h1>
|
||||
<?php $str = "Markdown **text**\n# SOLONG\n*text*."; $md = \App\Helpers\Markdown::convertToHTML( $str ); echo "<p>$md</p>"; ?>
|
||||
<?php use App\Infrastructure\View as V; use App\Http\Router; ?>
|
||||
<?php use App\Infrastructure\View as V; ?>
|
||||
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
$recette = new \App\Domain\Recettes\RecetteRepository()->getByID( 2 );
|
||||
$modelingredient = new \App\Domain\Ingredients\Ingredient();
|
||||
$modelingredient->num_ingredient=0;
|
||||
$modelingredient->nom_ingredient='nomdingredientaupif';
|
||||
var_dump($modelingredient);
|
||||
//$ingredient = new \App\Domain\Ingredients\IngredientRepository()->add($modelingredient);
|
||||
//pas de add si numing existe déjà use autoincrement
|
||||
$ingredient = new \App\Domain\Ingredients\IngredientRepository()->getByID( 1 );
|
||||
var_dump( $recette );
|
||||
var_dump( $ingredient );
|
||||
// new \App\Domain\Recettes\RecetteRepository()->removeAnIngredient( $ingredient, $recette );
|
||||
var_dump( $recette->getAllLinkedIngredients() );
|
||||
echo "\n\n";
|
||||
$modelUtilisateurs = new \App\Domain\Utilisateurs\Utilisateurs();
|
||||
$modelUtilisateurs->num_user=0;
|
||||
$modelUtilisateurs->username="usnmaemaee";
|
||||
$modelUtilisateurs->userpassword="pawssorddd";
|
||||
//$user = new \App\Domain\Utilisateurs\UtilisateursRepository()->add($modelUtilisateurs);
|
||||
$user = new \App\Domain\Utilisateurs\UtilisateursRepository()->getByID( 2 );
|
||||
var_dump($user);
|
||||
|
||||
$success = new \App\Domain\Utilisateurs\UtilisateursRepository()->login("usnmaemaee","pawssorddd");
|
||||
echo "\n\n";
|
||||
var_dump($success);
|
||||
|
||||
?>
|
||||
<div class="content">
|
||||
<div class="title-site">
|
||||
<h1 class="title">Les Recettes De Papis</h1>
|
||||
<hr class="line-acceuil">
|
||||
<h3>Proposition de recette :</h3>
|
||||
</div>
|
||||
<div class="random-proposition">
|
||||
<?php foreach( V::arg( 'recettes' ) as $recette ): ?>
|
||||
<a class="recette-icone" href="<?php V::routeUrl( 'recettes->show', $recette->slug ); ?>">
|
||||
<img class="recette-preview-image" src="<?php echo $recette->photo; ?>">
|
||||
<div class="recette-icone-content">
|
||||
<h3><?php echo $recette->titre_recette; ?></h3>
|
||||
<ul class="meta-recettes">
|
||||
<li>Temps de préparation : <?php echo $recette->temps_de_preparation; ?> minutes</li>
|
||||
<li>Nombre d'ingrédients : <?php echo $recette->getNumberOfIngredients(); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
18
views/ingredients/index.php
Normal file
18
views/ingredients/index.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php use App\Domain\Tags\Tag;
|
||||
use App\Infrastructure\View as V; ?>
|
||||
|
||||
<div class="content">
|
||||
<?php foreach (V::arg( 'ingredients') as $ing): ?>
|
||||
<div class="liste-ingr-elem">
|
||||
<img class="ingr-image" src="<?php echo $ing->photo_ingredient; ?>">
|
||||
<div class="liste-ingr-elem-text">
|
||||
<?php echo $ing->nom_ingredient; ?>
|
||||
</div>
|
||||
<div class="liste-ingr-elem-modif">
|
||||
<a class="recette-button ingr-modifier" data-id="<?php echo $ing->getId(); ?>">Modifier</a>
|
||||
<a class="recette-button ingr-suppr" data-id="<?php echo $ing->getId(); ?>">Supprimer</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<script src="<?php V::assetUrl( 'js/manage-ingredients.js' ); ?>" ></script>
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
<footer id="footer">
|
||||
<div class="src">
|
||||
<a href="google.com">Une source</a>
|
||||
<a href="https://code.romhackplaza.org/Benjamin/LesRecettesDePapis" target="_blank">Notre Gitea</a>
|
||||
</div>
|
||||
<div class="Contact">
|
||||
Front end : Bousquet Sébastien
|
||||
--- Back end : Thorel Benjamin
|
||||
--- Base de donné : Glaudis Jordan
|
||||
--- Base de données : Glaudis Jordan
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
<title><?php echo V::getHeadTitle(); ?></title>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="<?php V::assetUrl( 'css/style.css' ); ?>" />
|
||||
<link rel="icon" type="image/x-icon" href="<?php V::assetUrl( 'images/Logo.ico' ); ?>" />
|
||||
</head>
|
||||
<body>
|
||||
<header id="header">
|
||||
<div id="logo">
|
||||
<a href="index.php">
|
||||
<a href="<?php V::routeUrl( 'home'); ?>">
|
||||
<img src="<?php V::assetUrl( 'images/Logo.jpg'); ?>" class="logo">
|
||||
</a>
|
||||
</div>
|
||||
@@ -21,10 +22,15 @@
|
||||
<?php if( \App\Helpers\Authentification::isLoggedIn() ): ?>
|
||||
<li><a id="login" class= "nav-element" href="<?php V::routeUrl( 'logout'); ?>">Logout</a></li>
|
||||
<li><a id="addBouton" class="nav-element" href="<?php V::routeUrl( 'recettes->create'); ?>">Ajouter une Recette</a></li>
|
||||
<li><a id="ingrManage" class="nav-element" href="<?php V::routeUrl( 'manage->ingredients'); ?>">Gérer les ingrédients</a></li>
|
||||
<li><a id="tagManage" class="nav-element" href="<?php V::routeUrl( 'manage->tags'); ?>">Gérer les tags</a></li>
|
||||
|
||||
<?php else: ?>
|
||||
<li><a id="login" class= "nav-element" href="<?php V::routeUrl( 'login'); ?>">Login</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
<input type="text" class="search-form search-form-recette" placeholder="Rechercher une recette ...">
|
||||
<form id="searchForm" method="get" action="<?php V::routeUrl( 'recettes->index'); ?>">
|
||||
<input name="s" id="searchFormField" type="text" class="search-form search-form-recette" placeholder="Rechercher une recette ..." value="<?php echo \App\Http\Request::get( 's' ); ?>">
|
||||
</form>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php use App\Infrastructure\View as V; ?>
|
||||
<?php use App\Infrastructure\View as V; use App\Http\Router;?>
|
||||
|
||||
<div class="sidebar">
|
||||
<div class="tag-cont">
|
||||
@@ -7,13 +7,10 @@
|
||||
<ul>
|
||||
</ul>
|
||||
</div>
|
||||
<form class="sidebar-search" action="none">
|
||||
<input type="text" class="search-form search-form-tag" name="search-tag" placeholder="Rechercher..." >
|
||||
</form>
|
||||
<div class="tag-unselected-div">
|
||||
<ul>
|
||||
<ul id="tagsList">
|
||||
<?php foreach( V::arg( 'tagsList') as $tag ): ?>
|
||||
<li class="tag tag-unselected" onclick="test()"><?php echo $tag->nom_tag; ?></li>
|
||||
<li class="tag tag-unselected" data-tag-id="<?php echo $tag->num_tag;?>"><?php echo $tag->nom_tag; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -25,15 +22,13 @@
|
||||
<ul>
|
||||
</ul>
|
||||
</div>
|
||||
<form class="sidebar-search" action="none">
|
||||
<input type="text" class="search-form search-form-tag" name="search-ingr" placeholder="Rechercher..." >
|
||||
</form>
|
||||
<div class="tag-unselected-div">
|
||||
<ul>
|
||||
<div class="ing-unselected-div">
|
||||
<ul id="ingredientsList">
|
||||
<?php foreach( V::arg( 'ingredientsList') as $tag ): ?>
|
||||
<li class="tag tag-unselected" onclick="test()"><?php echo $tag->nom_ingredient; ?></li>
|
||||
<li class="tag tag-unselected" data-ingredient-id="<?php echo $tag->num_ingredient;?>"><?php echo $tag->nom_ingredient; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="<?php echo Router::getAssetURL( 'js/advanced-search.js' ); ?>" defer></script>
|
||||
80
views/recettes/create.php
Normal file
80
views/recettes/create.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php use App\Domain\Recettes\Recette;
|
||||
use App\Infrastructure\View as V; ?>
|
||||
|
||||
<div class="main-body">
|
||||
<div class="content">
|
||||
<div class="recette-add-form-all">
|
||||
<form id="recette-form-complete" class="recette-form recette-form-add" action="/api/recettes/create" method="POST">
|
||||
<legend><h1>Nouvelle Recette : </h1></legend>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="nom">Titre : </label>
|
||||
<input type="text" class="form-control" id="recette-form-nom" name="nom" placeholder="Titre de votre recette">
|
||||
</div>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="temps">Temps (en min) : </label>
|
||||
<input type="number" class="form-control" id="recette-form-temps" name="temps" placeholder="Temps de préparation">
|
||||
</div>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="image">Photo du plat : </label>
|
||||
<input type="file" class="form-control" id="recette-form-photo" name="image" placeholder="ajouter votre image" accept="image/jpeg, image/png">
|
||||
</div>
|
||||
<div class="recette-form-group form-group" id="recette-form-div-ingr">
|
||||
<label for="ingr">Ingredients</label>
|
||||
<select multiple class="form-control" id="recette-form-ingr" name="ingr" placeholder="Ingredients">
|
||||
<?php foreach( V::arg( 'ingredients') as $ingr ): ?>
|
||||
<option value="<?php echo $ingr->getID(); ?>"><?php echo $ingr->nom_ingredient; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="recette-form-group form-group" id="recette-form-div-tag">
|
||||
<label for="tag">Tag</label>
|
||||
<select multiple class="form-control" id="recette-form-tag" name="tag" placeholder="Tag">
|
||||
<?php foreach( V::arg( 'tags') as $tag ): ?>
|
||||
<option value="<?php echo $tag->getID(); ?>"><?php echo $tag->nom_tag; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="recette-form-group form-group" id="recette-form-div-desc">
|
||||
<label for="description">Description</label>
|
||||
<textarea type="texte" class="form-control" id="recette-form-description" name="description" placeholder="Markdown supporté pour les titres de niveau 1,2, le gras ainsi que l'italique"></textarea>
|
||||
</div>
|
||||
|
||||
<button type='submit' class='btn btn-primary'>Envoyer la recette</button>
|
||||
</form>
|
||||
<div class="recette-form-add-additional">
|
||||
<form id="recette-form-ingr-add" class="recette-form recette-form-add-ingr" action="" method="POST">
|
||||
<legend><h2>Nouvel Ingrédient :</h2></legend>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="name">Nom de l'Ingrédient</label>
|
||||
<input type="texte" class="form-control" id="recette-form-ingr-nom" name="name" placeholder="Nom de l'ingrédient" value="">
|
||||
</div>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="image">Photo de l'Ingrédient</label>
|
||||
<input type="file" class="form-control" id="recette-form-ingr-photo" name="image">
|
||||
</div>
|
||||
|
||||
<button id="submit-ingr" type='submit' class='btn btn-primary'>Confirmer</button>
|
||||
<div id="recette-form-div-err-ingr" class="err">
|
||||
Erreur
|
||||
</div>
|
||||
</form>
|
||||
<form id="recette-form-tag-add" class="recette-form recette-form-add-tag" action="" method="POST">
|
||||
<legend><h2>Nouveau Tag : </h2></legend>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="tag">Tags</label>
|
||||
<input type="text" class="form-control" id="recette-form-tag-nom" name="name" placeholder="Nom de l'ingrédient">
|
||||
</div>
|
||||
|
||||
<button type='submit' class='btn btn-primary'>Confirmer</button>
|
||||
<div id="recette-form-div-err-tag" class="err">
|
||||
Erreur
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const IS_EDIT = false; const RECETTE_ID = 0;
|
||||
</script>
|
||||
<script src="<?php V::assetUrl( 'js/form.js' ); ?>" defer></script>
|
||||
80
views/recettes/edit.php
Normal file
80
views/recettes/edit.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php use App\Domain\Recettes\Recette;
|
||||
use App\Infrastructure\View as V; ?>
|
||||
<?php /** @var Recette $R */$R = V::arg( 'recette'); ?>
|
||||
<div class="main-body">
|
||||
<div class="content">
|
||||
<div class="recette-add-form-all">
|
||||
<form id="recette-form-complete" class="recette-form recette-form-add" action="/api/recettes/edit" method="POST">
|
||||
<legend><h1>Editer une Recette : </h1></legend>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="nom">Titre : </label>
|
||||
<input type="text" class="form-control" id="recette-form-nom" name="nom" placeholder="Titre de votre recette" value="<?php echo $R->titre_recette; ?>">
|
||||
</div>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="temps">Temps (en min) : </label>
|
||||
<input type="number" class="form-control" id="recette-form-temps" name="temps" placeholder="Temps de préparation" value="<?php echo $R->temps_de_preparation; ?>">
|
||||
</div>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="image">Photo du plat : </label>
|
||||
<input type="file" class="form-control" id="recette-form-photo" name="image" placeholder="ajouter votre image" accept="image/jpeg, image/png">
|
||||
</div>
|
||||
<div class="recette-form-group form-group" id="recette-form-div-ingr">
|
||||
<label for="ingr">Ingredients</label>
|
||||
<select multiple class="form-control" id="recette-form-ingr" name="ingr" placeholder="Ingredients">
|
||||
<?php foreach( V::arg( 'ingredients') as $ingr ): ?>
|
||||
<option value="<?php echo $ingr->getID(); ?>" <?php echo in_array( $ingr->getId(), V::arg( 'recetteIngr') ) ? "selected" : ""; ?> ><?php echo $ingr->nom_ingredient; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="recette-form-group form-group" id="recette-form-div-tag">
|
||||
<label for="tag">Tag</label>
|
||||
<select multiple class="form-control" id="recette-form-tag" name="tag" placeholder="Tag">
|
||||
<?php foreach( V::arg( 'tags') as $tag ): ?>
|
||||
<option value="<?php echo $tag->getID(); ?>" <?php echo in_array( $tag->getId(), V::arg( 'recetteTags' ) ) ? "selected" : ""; ?> ><?php echo $tag->nom_tag; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="recette-form-group form-group" id="recette-form-div-desc">
|
||||
<label for="description">Description</label>
|
||||
<textarea type="texte" class="form-control" id="recette-form-description" name="description" placeholder="Description..."><?php echo $R->description_recette; ?></textarea>
|
||||
</div>
|
||||
|
||||
<button type='submit' class='btn btn-primary'>Confirmer</button>
|
||||
</form>
|
||||
<div class="recette-form-add-additional">
|
||||
<form id="recette-form-ingr-add" class="recette-form recette-form-add-ingr" action="" method="POST">
|
||||
<legend><h2>Nouvel Ingrédient :</h2></legend>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="name">Nom de l'Ingrédient</label>
|
||||
<input type="texte" class="form-control" id="recette-form-ingr-nom" name="name" placeholder="Nom de l'ingrédient" value="">
|
||||
</div>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="image">Photo de l'Ingrédient</label>
|
||||
<input type="file" class="form-control" id="recette-form-ingr-photo" name="image">
|
||||
</div>
|
||||
|
||||
<button id="submit-ingr" type='submit' class='btn btn-primary'>Confirmer</button>
|
||||
<div id="recette-form-div-err-ingr" class="err">
|
||||
Erreur
|
||||
</div>
|
||||
</form>
|
||||
<form id="recette-form-tag-add" class="recette-form recette-form-add-tag" action="" method="POST">
|
||||
<legend><h2>Nouveau Tag : </h2></legend>
|
||||
<div class="recette-form-group form-group">
|
||||
<label for="tag">Tags</label>
|
||||
<input type="text" class="form-control" id="recette-form-tag-nom" name="name" placeholder="Nom de l'ingrédient">
|
||||
</div>
|
||||
|
||||
<button type='submit' class='btn btn-primary'>Confirmer</button>
|
||||
<div id="recette-form-div-err-tag" class="err">
|
||||
Erreur
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const IS_EDIT = true; const RECETTE_ID = <?php echo $R->getId(); ?>;
|
||||
</script>
|
||||
<script src="<?php V::assetUrl( 'js/form.js' ); ?>" defer></script>
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
<?php V::partial( 'tag-sidebar' ); ?>
|
||||
<div class="content">
|
||||
<div class="recettes">
|
||||
<div id="recetteList" class="recettes">
|
||||
<?php if( V::arg( 'recettesList' ) != null ) foreach( V::arg( 'recettesList' ) as $recette ): ?>
|
||||
<a class="recette-icone" href="<?php V::routeUrl( 'recettes->show', $recette->slug ); ?>">
|
||||
<img class="recette-preview-image" src="random-recette.jpg">
|
||||
<img class="recette-preview-image" src="<?php echo $recette->photo; ?>">
|
||||
<div class="recette-icone-content">
|
||||
<h3><?php echo $recette->titre_recette; ?></h3>
|
||||
<ul>
|
||||
<li>Temps de préparation : <?php echo $recette->temps_de_preparation; ?></li>
|
||||
<ul class="meta-recettes">
|
||||
<li>Temps de préparation : <?php echo $recette->temps_de_preparation; ?> minutes</li>
|
||||
<li>Nombre d'ingrédients : <?php echo $recette->getNumberOfIngredients(); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
55
views/recettes/show.php
Normal file
55
views/recettes/show.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php use App\Domain\Recettes\Recette;
|
||||
use App\Infrastructure\View as V; ?>
|
||||
<?php /** @var Recette $R */ $R = V::arg( 'recette' ); ?>
|
||||
|
||||
<div class="content">
|
||||
<div class="recette-title">
|
||||
<h1><?php echo $R->titre_recette; ?></h1>
|
||||
</div>
|
||||
<div class="recette-content">
|
||||
<div class="recette-div-info">
|
||||
<div class="recette-div-image">
|
||||
<img class="recette-image" src="<?php echo $R->photo; ?>">
|
||||
</div>
|
||||
<div class="recette-div-liste-info">
|
||||
<?php if( \App\Helpers\Authentification::isLoggedIn() ): ?>
|
||||
<ul class="recette-list-buttons">
|
||||
<li><a class="recette-button" href="#" id="delete" data-id="<?php echo $R->num_recette; ?>">Supprimer</a></li>
|
||||
<li><a class="recette-button" href="<?php V::routeUrl( 'recettes->edit', $R->getID() ); ?>">Modifier</a></li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<ul class="recette-liste-info">
|
||||
<li class="recette-liste-info-elem"><?php echo $R->publication_date; ?></li>
|
||||
<li class="recette-liste-info-elem"><?php echo $R->temps_de_preparation; ?> minutes</li>
|
||||
<li class="recette-liste-info-elem"><?php echo $R->getNumberOfIngredients(); ?> ingrédients</li>
|
||||
</ul>
|
||||
<ul class="recette-liste-tag">
|
||||
<?php foreach( $R->getAllLinkedTags() as $tag ): ?>
|
||||
<li class="tag tag-unselected"><?php echo $tag->nom_tag; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="recette-liste-ingr-div">
|
||||
<h3>Liste des ingrédients</h3>
|
||||
<ul class="recette-liste-ingr">
|
||||
<?php foreach( $R->getAllLinkedIngredients() as $ingr ): ?>
|
||||
<li class="recette-liste-ingr-elem"><img class="ingr-image-prev" src="<?php echo $ingr->photo_ingredient; ?>"> <div class="recette-liste-ingr-elem-nom"><?php echo $ingr->nom_ingredient; ?></div></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class = "recette-desc">
|
||||
<div id="description">
|
||||
<?php echo $R->getHTMLDescription(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById( 'delete' ).addEventListener( 'click', e => {
|
||||
if( window.confirm( "Êtes-vous sur de vouloir supprimer cette recette ? ") ){
|
||||
let id = document.getElementById( 'delete' ).getAttribute( 'data-id' );
|
||||
window.location.href = "/recettes/delete/" + id;
|
||||
}
|
||||
})
|
||||
</script>
|
||||
17
views/tags/index.php
Normal file
17
views/tags/index.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php use App\Domain\Tags\Tag;
|
||||
use App\Infrastructure\View as V; ?>
|
||||
|
||||
<div class="content">
|
||||
<?php foreach( V::arg( 'tags' ) as $tag ): ?>
|
||||
<div class="liste-tag-elem">
|
||||
<div class="liste-tag-elem-text">
|
||||
<?php echo $tag->nom_tag; ?>
|
||||
</div>
|
||||
<div class="liste-tag-elem-modif">
|
||||
<a class="recette-button tag-modifier" data-id="<?php echo $tag->num_tag; ?>">Modifier</a>
|
||||
<a class="recette-button tag-suppr" data-id="<?php echo $tag->num_tag; ?>">Supprimer</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<script src="<?php V::assetUrl( 'js/manage-tags.js' ); ?>" ></script>
|
||||
Reference in New Issue
Block a user