diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index db60a95..e745855 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,22 +15,23 @@ jobs: with: host: boulayoune.com username: yass - key: ${{ secrets.SSH_KEY }} + key: | + ${{ secrets.SSH_KEY }} port: 22 + debug: true script: | - set -e echo "➡️ Connexion réussie !" cd /var/www/projet_php echo "➡️ Mise à jour du code..." - # On enlève le SUDO ici pour que Git utilise la clé de l'utilisateur yass git fetch origin main git reset --hard origin/main echo "➡️ Correction des permissions et nettoyage..." - # On garde le SUDO ici car ces commandes touchent au système sudo chown -R yass:www-data /var/www/projet_php sudo chmod -R 775 /var/www/projet_php/templates_c sudo rm -rf /var/www/projet_php/templates_c/* + sudo chmod -R 775 /var/www/projet_php/uploads/projects + sudo chmod -R 775 /var/www/projet_php/uploads/profiles - echo "✅ Déploiement terminé ! (Shin-en no Egotisu)" \ No newline at end of file + echo "✅ Déploiement terminé ! (Shin-en no Egotisu)" diff --git a/controllers/project_controller.php b/controllers/project_controller.php index 9b62f84..ae44662 100644 --- a/controllers/project_controller.php +++ b/controllers/project_controller.php @@ -116,20 +116,21 @@ * Fonction d'affichage de la page projet * @author Christel adapter par Guillaume */ - public function addedit_project() { + public function addedit_project(){ if (!isset($_SESSION['user'])){ // Pas d'utilisateur connecté header("Location:index.php?ctrl=error&action=error_403"); exit; } - $objProject = new Project; - $objProjectModel = new ProjectModel; - $objCategoryModel = new CategoryModel; + $objProject = new Project; + $objProjectModel = new ProjectModel; + $objCategoryModel = new CategoryModel; - // dans la cas de modif + // Dans la cas de modif if (isset($_GET['id'])){ - $arrProject = $objProjectModel->findOne($_GET['id']); + $arrProject = $objProjectModel->findOne($_GET['id']); $objProject->hydrate($arrProject); // BDD + $this->_arrData['arrImages'] = $objProjectModel->getImagesByProjectId($objProject->getId()); } // Tester le formulaire @@ -147,26 +148,23 @@ if ($objProject->getContent() == ""){ $arrError['content'] = "Le contenu est obligatoire"; - } + } - // Vérification de l'image - $arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp'); + // Vérification de l'image (Thumbnail) + $arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp'); if ($_FILES['thumbnail']['error'] != 4){ if (!in_array($_FILES['thumbnail']['type'], $arrTypeAllowed)){ $arrError['thumbnail'] = "Le type de fichier n'est pas autorisé"; }else{ - // Vérification des codes d'erreur switch ($_FILES['thumbnail']['error']){ case 0 : - // Renommage de l'image - $strImageName = uniqid().".webp"; - - // Récupère le nom de l'image avant changement - $strOldImg = $objProject->getThumbnail(); - // Mise à jour du nom de l'image dans l'objet + $strImageName = uniqid().".webp"; + $strOldImg = $objProject->getThumbnail(); $objProject->setThumbnail($strImageName); break; case 1 : + $arrError['thumbnail'] = "Le fichier est trop volumineux"; + break; case 2 : $arrError['thumbnail'] = "Le fichier est trop volumineux"; break; @@ -181,113 +179,213 @@ break; } } - }else{ - // Est-ce que le fichier existe ? if (is_null($objProject->getThumbnail())){ $arrError['thumbnail'] = "L'image est obligatoire"; } } - // SI pas d'erreur : on traite l'image depuis la bdd - if (count($arrError) == 0){ + // SI pas d'erreur : on traite l'image principale + if (count($arrError) == 0){ - $boolImageOk = true; - - // Redimensionnement de l'image - if (isset($strImageName)){ - $strDest = $_ENV['IMG_PATH'].$strImageName; - $strSource = $_FILES['thumbnail']['tmp_name']; - list($intWidth, $intHeight) = getimagesize($strSource); - - $intDestWidth = 200; $intDestHeight = 250; - $fltDestRatio = $intDestWidth / $intDestHeight; - $fltSourceRatio = $intWidth / $intHeight; - - if ($fltSourceRatio > $fltDestRatio) { - $intCropHeight = $intHeight; - $intCropWidth = (int)round($intHeight * $fltDestRatio); - $intCropX = (int)(($intWidth - $intCropWidth) / 2); - $intCropY = 0; - } else { - $intCropWidth = $intWidth; - $intCropHeight = (int)round($intWidth / $fltDestRatio); - $intCropX = 0; - $intCropY = (int)(($intHeight - $intCropHeight) / 2); - } + $boolImageOk = true; + + // On peux changer ces dimensions si on veux que la miniature soit plus grande/petite + if (isset($strImageName)){ + $strDest = $_ENV['IMG_PROJECT_PATH'].$strImageName; + $strSource = $_FILES['thumbnail']['tmp_name']; + list($intWidth, $intHeight) = getimagesize($strSource); - // Condition en fonction de l'extension de l'image - $objDest = imagecreatetruecolor($intDestWidth, $intDestHeight); - switch ($_FILES['thumbnail']['type']) { - case 'image/jpeg' : + // Redimensionnement de la Thumbnail + $intDestWidth = 200; $intDestHeight = 250; + $fltDestRatio = $intDestWidth / $intDestHeight; + $fltSourceRatio = $intWidth / $intHeight; + + if ($fltSourceRatio > $fltDestRatio) { + $intCropHeight = $intHeight; + $intCropWidth = (int)round($intHeight * $fltDestRatio); + $intCropX = (int)(($intWidth - $intCropWidth) / 2); + $intCropY = 0; + } else { + $intCropWidth = $intWidth; + $intCropHeight = (int)round($intWidth / $fltDestRatio); + $intCropX = 0; + $intCropY = (int)(($intHeight - $intCropHeight) / 2); + } + + $objDest = imagecreatetruecolor($intDestWidth, $intDestHeight); + switch ($_FILES['thumbnail']['type']) { + case 'image/jpeg' : $objSource = imagecreatefromjpeg($strSource); - break; - case 'image/png' : + break; + case 'image/png' : $objSource = imagecreatefrompng($strSource); - break; - case 'image/webp' : + break; + case 'image/webp' : $objSource = imagecreatefromwebp($strSource); - break; - } - - imagecopyresampled($objDest, $objSource, 0, 0, $intCropX, $intCropY, $intDestWidth, $intDestHeight, $intCropWidth, $intCropHeight); - - // Sauvegarde du fichier - $boolImageOk = imagewebp($objDest, $strDest); - imagedestroy($objDest); - imagedestroy($objSource); - } + break; + } + + imagecopyresampled($objDest, $objSource, 0, 0, $intCropX, $intCropY, $intDestWidth, $intDestHeight, $intCropWidth, $intCropHeight); + $boolImageOk = imagewebp($objDest, $strDest); + + //Suppression des doublons pour la mémoire vive + imagedestroy($objDest); + imagedestroy($objSource); + } - // SI image ok, on balance tout dans la bdd - if ($boolImageOk){ - if (!isset($_GET['id'])){ - $objProject->setUser_id($_SESSION['user']['user_id']); - $boolOk = $objProjectModel->insert($objProject); - } else { - $boolOk = $objProjectModel->updateProject($objProject); - } + // SI image ok, on balance tout dans la bdd + if ($boolImageOk){ + if (!isset($_GET['id'])){ + $objProject->setUser_id($_SESSION['user']['user_id']); + $boolOk = $objProjectModel->insert($objProject); + } else { + $boolOk = $objProjectModel->updateProject($objProject); + } + + // Gestion des 20 Images après l'envoie de la Thumbnail en BDD + if ($boolOk){ + //Si pas d'erreur + if (isset($_FILES['imageProject']) && $_FILES['imageProject']['error'][0] != 4) { + $files = $_FILES['imageProject']; + $maxPhotos = 20; - if ($boolOk){ - // Suppression de l'ancienne image - if(isset($strOldImg) && !empty($strOldImg) && isset($strImageName)){ - $strOldFile = $_ENV['IMG_PATH'].$strOldImg; - if (file_exists($strOldFile)) unlink($strOldFile); - } + // 1. On compte combien d'images le projet possède déjà en BDD + $currentImages = $objProjectModel->getImagesByProjectId($objProject->getId()); + $totalExisting = count($currentImages); - $_SESSION['success'] = (!isset($_GET['id'])) ? "Le projet a bien été créé" : "Le projet a bien été modifié"; - header("Location:index.php"); - exit; - } else { - $arrError[] = "Erreur lors de l'enregistrement en base de données"; - } - } else { - $arrError['thumbnail'] = "Erreur dans le traitement de l'image"; - } - } + // 2. On calcule combien de photos on peut encore ajouter + $remainingSlots = $maxPhotos - $totalExisting; + + // Si on a déjà atteint ou dépassé la limite, on ne traite même pas les fichiers + if ($remainingSlots <= 0) { + $_SESSION['error'] = "Limite de $maxPhotos photos atteinte. Supprimez-en pour en ajouter de nouvelles."; + } else { + $uploadedCount = 0; + + foreach ($files['name'] as $key => $name) { + // 3. On utilise le quota restant comme condition d'arrêt + if ($uploadedCount >= $remainingSlots) break; + + if ($files['error'][$key] === 0 && in_array($files['type'][$key], $arrTypeAllowed)) { + + $galleryName = uniqid() . "_gallery.webp"; + $strDestGallery = $_ENV['IMG_PROJECT_PATH'].$galleryName; + $strSourceGallery = $files['tmp_name'][$key]; + + // Reprise de la logique de redimensionnement + list($intW, $intH) = getimagesize($strSourceGallery); + + // On peux changer ces dimensions si on veux que la galerie soit plus grande/petite + $intDestW = 150; $intDestH = 150; + $fltDestR = $intDestW / $intDestH; + $fltSourceR = $intW / $intH; + + if ($fltSourceR > $fltDestR) { + $intCropH = $intH; + $intCropW = (int)round($intH * $fltDestR); + $intCropX = (int)(($intW - $intCropW) / 2); + $intCropY = 0; + } else { + $intCropW = $intW; + $intCropH = (int)round($intW / $fltDestR); + $intCropX = 0; + $intCropY = (int)(($intH - $intCropH) / 2); + } + + $objDestGallery = imagecreatetruecolor($intDestW, $intDestH); + + // Création de la source selon le type de chaque image de la boucle + switch ($files['type'][$key]) { + case 'image/jpeg' : + $objSourceGallery = imagecreatefromjpeg($strSourceGallery); + break; + case 'image/png' : + $objSourceGallery = imagecreatefrompng($strSourceGallery); + break; + case 'image/webp' : + $objSourceGallery = imagecreatefromwebp($strSourceGallery); + break; + } + + if ($objSourceGallery) { + imagecopyresampled($objDestGallery, $objSourceGallery, 0, 0, $intCropX, $intCropY, $intDestW, $intDestH, $intCropW, $intCropH); + + if (imagewebp($objDestGallery, $strDestGallery)) { + // Insertion en BDD + $objProjectModel->addImageInProject($galleryName, $objProject->getId()); + $uploadedCount++; + } + + imagedestroy($objDestGallery); + imagedestroy($objSourceGallery); + } + } + } + + if ($uploadedCount > 0) { + $_SESSION['success'] = "$uploadedCount image(s) ajoutée(s) à la galerie !"; + } + } + } + + // Suppression de l'ancienne miniature + if(isset($strOldImg) && !empty($strOldImg) && isset($strImageName)){ + $strOldFile = $_ENV['IMG_PROJECT_PATH'].$strOldImg; + if (file_exists($strOldFile)) unlink($strOldFile); + } + + $_SESSION['success'] = (!isset($_GET['id'])) ? "Le projet a bien été créé" : "Le projet a bien été modifié"; + header("Location:index.php"); + exit; + } else { + $arrError[] = "Erreur lors de l'enregistrement en base de données"; + } + } else { + $arrError['thumbnail'] = "Erreur dans le traitement de l'image"; + } + } } - + // Données pour la vue $this->_arrData['arrCategory'] = $objCategoryModel->findAllCategory(); - $this->_arrData['objProject'] = $objProject; - $this->_arrData['arrError'] = $arrError; + $this->_arrData['objProject'] = $objProject; + $this->_arrData['arrError'] = $arrError; + + // Si on est en modifications de projet, on récupère les images pour les afficher dans le formulaire + if ($objProject->getId()) { + // On récupère les images via le modèle et on les stocke dans le tableau de données + $this->_arrData['arrImages'] = $objProjectModel->getImagesByProjectId($objProject->getId()); + } else { + // Sinon on initialise un tableau vide pour éviter que Smarty ne râle + $this->_arrData['arrImages'] = []; + } $this->_display('addedit_project'); } - + + /** + * Fonction d'affichage de projet + */ public function display() { $intId = $_GET['id'] ?? null; if ($intId) { $objProjectModel = new ProjectModel(); $arrProject = $objProjectModel->findOne((int)$intId); - + + // CORRECTION ICI : on utilise $intId (pas $id) + $arrImages = $objProjectModel->getImagesByProjectId((int)$intId); + if ($arrProject) { $objProject = new Project(); $objProject->hydrate($arrProject); - - $this->_arrData["objProject"] = $objProject; - $this->_arrData["arrProject"] = $arrProject; + + $this->_arrData["objProject"] = $objProject; + $this->_arrData["arrImages"] = $arrImages; + $this->_display("project_display"); + } else { header("Location: index.php?ctrl=project&action=home"); exit; @@ -298,6 +396,9 @@ } } + /** + * Fonction de partage de projet + */ public function shareProject(){ if (count($_POST) > 0) { @@ -364,6 +465,10 @@ exit; } + /** + * Fonction de modération de projet = accepté + * @author Guillaume + */ public function accept(){ //Récupéré l'id dans l'url @@ -377,7 +482,11 @@ header("Location: index.php"); exit; } - + + /** + * Fonction de modération de projet = refusé + * @author Guillaume + */ public function refuse(){ //Récupéré l'id dans l'url @@ -391,7 +500,11 @@ header("Location: index.php"); exit; } - + + /** + * Fonction de suppression de projet + * @author Guillaume + */ public function delete(){ //Récupéré l'id dans l'url @@ -406,6 +519,99 @@ exit; } + /** + * Fonction de changement de statut (Approuvé, Refusé, En attente) + * @author Guillaume + */ + public function change_image_status() { + if (isset($_GET['id_img']) && isset($_GET['status'])) { + $idImg = (int)$_GET['id_img']; + $status = $_GET['status']; // "en_attente" passage à "approuvé" + + $objProjectModel = new ProjectModel(); + + // On passe le statut texte directement à ta méthode de modèle + if ($objProjectModel->updateImageStatus($idImg, $status)) { + $_SESSION['success'] = "Le statut de l'image est désormais : " . ucfirst($status); + } + } + + // La redirection : Si on sait d'où on vient, on y retourne, sinon index + $urlRedirect = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "index.php"; + header("Location: " . $urlRedirect); + exit; + } + + + /** + * Fonction de validation de l'image de projet + * @author Guillaume + */ + public function delete_image() { + // Vérifier l'id de l'image + $idImg = $_GET['id_img']; + $objProjectModel = new ProjectModel(); + + // Récupérer le nom du fichier pour le supprimer physiquement + $image = $objProjectModel->findImage($idImg); + if ($image) { + $filePath = $_ENV['IMG_PROJECT_PATH'] . $image['image_name']; + if (file_exists($filePath)) unlink($filePath); + + $objProjectModel->deleteImage($idImg); + $_SESSION['success'] = "Image supprimée !"; + } + + // La redirection : Si on sait d'où on vient, on y retourne, sinon index + $url = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : "index.php"; + header("Location: " . $url); + exit; + } + + + /** + * Fonction d'ajout des 20 images max du projet + * @author Guillaume + * @param string $fileName = le nom de l'image, int $projectId = L'Id du projet que l'on veut afficher, string $alt = qui affichera pars défaut "Image de projet" + * @return bool Est-ce que la requête s'est bien passée + */ + public function addImageInProject(string $fileName, int $projectId, string $alt = "Image de projet"): bool { + $strRq = "INSERT INTO image ( + image_name, + image_alt, + image_status, + image_project + ) + VALUES (:name, :alt, :status, :project)"; + + $rqPrep = $this->_db->prepare($strRq); + + $rqPrep->bindValue(":name", $fileName, PDO::PARAM_STR); + $rqPrep->bindValue(":alt", $alt, PDO::PARAM_STR); + $rqPrep->bindValue(":status", "en_attente", PDO::PARAM_STR); // Valeur string en brute + $rqPrep->bindValue(":project", $projectId, PDO::PARAM_INT); + + return $rqPrep->execute(); + } + + /** + * Fonction d'affichage des 20 images max du projet + * @author Guillaume + * @param array $ProjectId L'Id du projet que l'on veut afficher + * @return bool Est-ce que la requête s'est bien passée + */ + public function getImagesByProjectId(int $projectId): array { + $strRq = "SELECT image_id, image_name, image_alt, image_status + FROM image + WHERE image_project = :id"; + + $rqPrep = $this->_db->prepare($strRq); + $rqPrep->bindValue(":id", $projectId, PDO::PARAM_INT); + $rqPrep->execute(); + + return $rqPrep->fetchAll(PDO::FETCH_ASSOC); + } + /** * Page mentions légales */ @@ -413,8 +619,7 @@ // Afficher $this->_display("mentions"); } - - + /** * Page à propos */ diff --git a/controllers/templates_c/299f75d7692a19207f23bf5795a2721f507c3fc6_0.file_home.tpl.php b/controllers/templates_c/299f75d7692a19207f23bf5795a2721f507c3fc6_0.file_home.tpl.php new file mode 100644 index 0000000..208dcfd --- /dev/null +++ b/controllers/templates_c/299f75d7692a19207f23bf5795a2721f507c3fc6_0.file_home.tpl.php @@ -0,0 +1,69 @@ +getCompiled()->isFresh($_smarty_tpl, array ( + 'version' => '5.7.0', + 'unifunc' => 'content_6985a47abcda40_19846426', + 'has_nocache_code' => false, + 'file_dependency' => + array ( + '299f75d7692a19207f23bf5795a2721f507c3fc6' => + array ( + 0 => 'views/home.tpl', + 1 => 1770365364, + 2 => 'file', + ), + ), + 'includes' => + array ( + 'file:views/_partial/preview.tpl' => 1, + ), +))) { +function content_6985a47abcda40_19846426 (\Smarty\Template $_smarty_tpl) { +$_smarty_current_dir = 'C:\\wamp64\\www\\projetphp\\views'; +$_smarty_tpl->getInheritance()->init($_smarty_tpl, false); +?> + +getInheritance()->instanceBlock($_smarty_tpl, 'Block_3150142016985a47abb6c29_00747518', "content"); +?> + + + +
+

Folliow

+

Là où les talents rencontrent leur avenir

+

Une plateforme de portfolio adapté à vos besoins et aux besoins des entreprises. + Créer un portfolio réellement pertinent aux exigences du marché et rentrez + directement en contact avec les entreprises.

+
+ +
+

Les 4 derniers articles

+
+ + getSmarty()->getRuntime('Foreach')->init($_smarty_tpl, $_smarty_tpl->getValue('arrProjectToDisplay'), 'objProject'); +$foreach0DoElse = true; +foreach ($_from ?? [] as $_smarty_tpl->getVariable('objProject')->value) { +$foreach0DoElse = false; +?> + renderSubTemplate("file:views/_partial/preview.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, 0, $_smarty_tpl->cache_lifetime, array(), (int) 0, $_smarty_current_dir); +?> + getSmarty()->getRuntime('Foreach')->restore($_smarty_tpl, 1);?> +
+getCompiled()->isFresh($_smarty_tpl, array ( + 'version' => '5.7.0', + 'unifunc' => 'content_6985a47ad585d5_25749521', + 'has_nocache_code' => false, + 'file_dependency' => + array ( + 'c724044e55872f26030b02de6dcd14dc34a20b16' => + array ( + 0 => 'views/_partial/preview.tpl', + 1 => 1770365554, + 2 => 'file', + ), + ), + 'includes' => + array ( + ), +))) { +function content_6985a47ad585d5_25749521 (\Smarty\Template $_smarty_tpl) { +$_smarty_current_dir = 'C:\\wamp64\\www\\projetphp\\views\\_partial'; +?>
+
+ +
+ +
+ +
+ + Photo de profil + +
+

getValue('objProject')->getTitle();?> +

+ + + + – getValue('objProject')->getCreatorname();?> + + + + + Lire la suite → + +
+ +
+ +
+
getMail()) === "") { - $arrError['user_mail'] = "Le mail est obligatoire"; + $arrError['user_mail'] = "L'adresse e-mail est obligatoire"; } elseif (!filter_var($objUser->getMail(), FILTER_VALIDATE_EMAIL)) { - $arrError['user_mail'] = "Le format du mail n'est pas correct"; + $arrError['user_mail'] = "Le format de l'adresse e-mail est invalide"; } if (trim($objUser->getPseudo()) === "") { $arrError['user_pseudo'] = "Le pseudo est obligatoire"; } - $strRegex = "/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{16,}$/"; + $strRegex = "/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{15,}$/"; if ($objUser->getPwd() == ""){ $arrError['user_password'] = "Le mot de passe est obligatoire"; }else if (!preg_match($strRegex, $objUser->getPwd())){ - $arrError['user_password'] = "Le mot de passe ne correspond pas aux règles"; + $arrError['user_password'] = "Le mot de passe ne respecte pas les critères"; }else if($objUser->getPwd() != $strPwdConfirm){ - $arrError['pwd_confirm'] = "Le mot de passe et sa confirmation ne sont pas identiques"; + $arrError['pwd_confirm'] = "La confirmation du mot de passe ne correspond pas"; } - // Si pas d'erreurs => insertion if (count($arrError) === 0) { $objUserModel = new UserModel(); + // Vérif mail if ($objUserModel->mailExists($objUser->getMail())) { + $arrError['user_mail'] = "Impossible de créer le compte avec ces informations"; + } - $arrError['user_mail'] = "Ce mail existe déjà"; - } else { + // Vérif pseudo + if ($objUserModel->pseudoExists($objUser->getPseudo())) { + $arrError['user_pseudo'] = "Ce pseudo existe déjà"; + } + + // Si aucune erreur => insert + if (count($arrError) === 0) { $boolInsert = $objUserModel->insert($objUser); if ($boolInsert === true) { @@ -154,172 +167,236 @@ class UserCtrl extends MotherCtrl { } // Affichage de la vue inscription - $this->_arrData["arrError"] = $arrError; - $this->_display("inscription"); - } - - /** - * le controlleur affichage de la page user - */ - public function user(){ - - /**$intId = isset($_GET['id']) ? (int)$_GET['id'] : 0; - - if ($intId <= 0) { - header("Location: index.php"); - exit; - } - - //affichage info utilisateur - $objUserModel = new UserModel; - $arrUserData = $objUserModel->findUserById($intId); - - if ($arrUserData === false) { - header("Location: index.php"); - exit; - }*/ - - $strPseudo = $_GET['pseudo']??''; - - $objUserModel = new UserModel; - $arrUserData = $objUserModel->findUserByPseudo($strPseudo); - - if ($arrUserData === false) { - header("Location: index.php"); - exit; - } - - $objUser = new User; - $objUser->hydrate($arrUserData); - - //affichage projet de l'utilisateur - $objProjectModel = new ProjectModel; - $arrProjects = $objProjectModel->findAll(0,'',$objUser->getId()); - - $arrProjectToDisplay = array(); - foreach($arrProjects as $projectData) { - $objProject = new Project(); - $objProject->hydrate($projectData); - $arrProjectToDisplay[] = $objProject; - } - - $this->_arrData['user'] = $objUser; - $this->_arrData['arrProjectToDisplay'] = $arrProjectToDisplay; - $this->_display("user"); - } - - public function edit(){ - if(!isset($_SESSION['user'])){ - header("Location: index.php"); - exit; + $this->_arrData['objUser'] = $objUser; + $this->_arrData['arrError'] = $arrError; + $this->_display("signup"); } - - $objUserModel = new UserModel; - $arrError = []; - $objUser = new User; - $arrUserData = $objUserModel->findUserById($_SESSION['user']['user_id']); - $objUser->hydrate($arrUserData); - if (!empty($_POST)) { - if ($objUserModel->mailExists($_POST['user_mail']) && ($_POST['user_mail'] != $objUser->getMail())) { - - $arrError['user_mail'] = "Ce mail est déjà associé"; - } else { - if ($objUserModel->pseudoExists($_POST['user_pseudo']) && ($_POST['user_pseudo'] != $objUser->getPseudo())){ - $arrError['user_pseudo'] = "Ce pseudo est déjà utiliser"; - }else{ - $objUser->hydrate($_POST); - $objUser->setId($_SESSION['user']['user_id']); - - // Vérification de l'image - $arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp'); - $boolImageOk = true; - - if ($_FILES['image']['error'] != 4) { - if (!in_array($_FILES['image']['type'], $arrTypeAllowed)) { - $arrError['image'] = "Le type de fichier n'est pas autorisé"; - } else { - switch ($_FILES['image']['error']) { - case 0: - $strImageName = uniqid() . ".webp"; - $strOldImg = $objUser->getImage(); - $objUser->setImage($strImageName); - break; - case 1: - case 2: - $arrError['image'] = "Le fichier est trop volumineux"; - break; - case 3: - $arrError['image'] = "Le fichier a été partiellement téléchargé"; - break; - case 6: - $arrError['image'] = "Le répertoire temporaire est manquant"; - break; - default: - $arrError['image'] = "Erreur sur l'image"; - break; - } - } - } - - // Traitement de l'image si pas d'erreur - if (count($arrError) == 0 && isset($strImageName)) { - $strDest = $_ENV['IMG_USER_PATH'] . $strImageName; - $strSource = $_FILES['image']['tmp_name']; - list($intWidth, $intHeight) = getimagesize($strSource); - - $intDestWidth = 200; $intDestHeight = 200; - $fltDestRatio = $intDestWidth / $intDestHeight; - $fltSourceRatio = $intWidth / $intHeight; - - if ($fltSourceRatio > $fltDestRatio) { - $intCropHeight = $intHeight; - $intCropWidth = (int)round($intHeight * $fltDestRatio); - $intCropX = (int)(($intWidth - $intCropWidth) / 2); - $intCropY = 0; - } else { - $intCropWidth = $intWidth; - $intCropHeight = (int)round($intWidth / $fltDestRatio); - $intCropX = 0; - $intCropY = (int)(($intHeight - $intCropHeight) / 2); - } - - $objDest = imagecreatetruecolor($intDestWidth, $intDestHeight); - switch ($_FILES['image']['type']) { - case 'image/jpeg': $objSource = imagecreatefromjpeg($strSource); break; - case 'image/png': $objSource = imagecreatefrompng($strSource); break; - case 'image/webp': $objSource = imagecreatefromwebp($strSource); break; - } - - imagecopyresampled($objDest, $objSource, 0, 0, $intCropX, $intCropY, $intDestWidth, $intDestHeight, $intCropWidth, $intCropHeight); - $boolImageOk = imagewebp($objDest, $strDest); - imagedestroy($objDest); - imagedestroy($objSource); - } - - - $boolInsert = $objUserModel->update($objUser); - - if ($boolInsert === true) { - if (isset($strOldImg) && !empty($strOldImg) && isset($strImageName)) { - $strOldFile = $_ENV['IMG_USER_PATH'] . $strOldImg; - if (file_exists($strOldFile)) unlink($strOldFile); - } - $arrNewInfo = $objUserModel->findUserByPseudo($objUser->getPseudo()); - $_SESSION['user'] = $arrNewInfo; - $_SESSION['success'] = "Compte modifier avec succès"; - header("Location:?ctrl=user&action=user&pseudo=".$objUser->getPseudo()); - exit; - } else { - $arrError['global'] = "Erreur lors de l'update"; - } - } + + /** + * Fonction de connexion d'un utilisateur + * Vérifie les informations envoyées par le formulaire + * et crée la session si les identifiants sont valides + * @return void + */ + public function login(){ + + $strMail = $_POST['user_mail']??""; + $strPwd = $_POST['user_password']??""; + + // Tester le formulaire + $arrError = []; + if (count($_POST) > 0) { + // Vérifier le formulaire + if ($strMail == ""){ + $arrError['mail'] = "L'adresse e-mail est obligatoire"; + } + if ($strPwd == ""){ + $arrError['pwd'] = "Le mot de passe est obligatoire"; + } + + // Si le formulaire est rempli correctement + if (count($arrError) == 0){ + // Vérifier l'utilisateur en BDD + $objUserModel = new UserModel; + $arrResult = $objUserModel->verifUser($strMail, $strPwd); + //var_dump($arrResult); + if ($arrResult === false){ // Si la base de données ne renvoie rien + $arrError[] = "Identifiants incorrects"; + }else{ + // Ajoute l'utilisateur en session + $_SESSION['user'] = $arrResult; + $_SESSION['success'] = "Bienvenue, vous êtes bien connecté"; + + header("Location:index.php"); + exit; } + } + } + $this->_arrData['arrError'] = $arrError; + $this->_display("login"); + + } + + + public function logout(){ + session_start(); + /*session_destroy(); + session_start();*/ + + // on supprime l'utilisateur en session + unset($_SESSION['user']); + + $_SESSION['success'] = "Vous êtes bien déconnecté"; + + header("Location:index.php"); + exit; + + } + + + + /** + * le controlleur affichage de la page user + */ + public function user(){ + + /**$intId = isset($_GET['id']) ? (int)$_GET['id'] : 0; + + if ($intId <= 0) { + header("Location: index.php"); + exit; + } + + //affichage info utilisateur + $objUserModel = new UserModel; + $arrUserData = $objUserModel->findUserById($intId); + + if ($arrUserData === false) { + header("Location: index.php"); + exit; + }*/ + + $strPseudo = $_GET['pseudo']??''; + + $objUserModel = new UserModel; + $arrUserData = $objUserModel->findUserByPseudo($strPseudo); + + if ($arrUserData === false) { + header("Location: index.php"); + exit; + } + + $objUser = new User; + $objUser->hydrate($arrUserData); + + //affichage projet de l'utilisateur + $objProjectModel = new ProjectModel; + $arrProjects = $objProjectModel->findAll(0,'',$objUser->getId()); + + $arrProjectToDisplay = array(); + foreach($arrProjects as $projectData) { + $objProject = new Project(); + $objProject->hydrate($projectData); + $arrProjectToDisplay[] = $objProject; + } + + $this->_arrData['user'] = $objUser; + $this->_arrData['arrProjectToDisplay'] = $arrProjectToDisplay; + $this->_display("user"); } - $this->_arrData["arrError"] = $arrError; - $this->_arrData['objUser'] = $objUser; - $this->_display("useredit"); + public function edit(){ + if(!isset($_SESSION['user'])){ + header("Location: index.php"); + exit; + } + + $objUserModel = new UserModel; + $arrError = []; + $objUser = new User; + $arrUserData = $objUserModel->findUserById($_SESSION['user']['user_id']); + $objUser->hydrate($arrUserData); + if (!empty($_POST)) { + if ($objUserModel->mailExists($_POST['user_mail']) && ($_POST['user_mail'] != $objUser->getMail())) { - } - + $arrError['user_mail'] = "Ce mail est déjà associé"; + } else { + if ($objUserModel->pseudoExists($_POST['user_pseudo']) && ($_POST['user_pseudo'] != $objUser->getPseudo())){ + $arrError['user_pseudo'] = "Ce pseudo est déjà utiliser"; + }else{ + $objUser->hydrate($_POST); + $objUser->setId($_SESSION['user']['user_id']); + + // Vérification de l'image + $arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp'); + $boolImageOk = true; + + if ($_FILES['image']['error'] != 4) { + if (!in_array($_FILES['image']['type'], $arrTypeAllowed)) { + $arrError['image'] = "Le type de fichier n'est pas autorisé"; + } else { + switch ($_FILES['image']['error']) { + case 0: + $strImageName = uniqid() . ".webp"; + $strOldImg = $objUser->getImage(); + $objUser->setImage($strImageName); + break; + case 1: + case 2: + $arrError['image'] = "Le fichier est trop volumineux"; + break; + case 3: + $arrError['image'] = "Le fichier a été partiellement téléchargé"; + break; + case 6: + $arrError['image'] = "Le répertoire temporaire est manquant"; + break; + default: + $arrError['image'] = "Erreur sur l'image"; + break; + } + } + } + + // Traitement de l'image si pas d'erreur + if (count($arrError) == 0 && isset($strImageName)) { + $strDest = $_ENV['IMG_USER_PATH'] . $strImageName; + $strSource = $_FILES['image']['tmp_name']; + list($intWidth, $intHeight) = getimagesize($strSource); + + $intDestWidth = 200; $intDestHeight = 200; + $fltDestRatio = $intDestWidth / $intDestHeight; + $fltSourceRatio = $intWidth / $intHeight; + + if ($fltSourceRatio > $fltDestRatio) { + $intCropHeight = $intHeight; + $intCropWidth = (int)round($intHeight * $fltDestRatio); + $intCropX = (int)(($intWidth - $intCropWidth) / 2); + $intCropY = 0; + } else { + $intCropWidth = $intWidth; + $intCropHeight = (int)round($intWidth / $fltDestRatio); + $intCropX = 0; + $intCropY = (int)(($intHeight - $intCropHeight) / 2); + } + + $objDest = imagecreatetruecolor($intDestWidth, $intDestHeight); + switch ($_FILES['image']['type']) { + case 'image/jpeg': $objSource = imagecreatefromjpeg($strSource); break; + case 'image/png': $objSource = imagecreatefrompng($strSource); break; + case 'image/webp': $objSource = imagecreatefromwebp($strSource); break; + } + + imagecopyresampled($objDest, $objSource, 0, 0, $intCropX, $intCropY, $intDestWidth, $intDestHeight, $intCropWidth, $intCropHeight); + $boolImageOk = imagewebp($objDest, $strDest); + imagedestroy($objDest); + imagedestroy($objSource); + } + + + $boolInsert = $objUserModel->update($objUser); + + if ($boolInsert === true) { + if (isset($strOldImg) && !empty($strOldImg) && isset($strImageName)) { + $strOldFile = $_ENV['IMG_USER_PATH'] . $strOldImg; + if (file_exists($strOldFile)) unlink($strOldFile); + } + $arrNewInfo = $objUserModel->findUserByPseudo($objUser->getPseudo()); + $_SESSION['user'] = $arrNewInfo; + $_SESSION['success'] = "Compte modifier avec succès"; + header("Location:?ctrl=user&action=user&pseudo=".$objUser->getPseudo()); + exit; + } else { + $arrError['global'] = "Erreur lors de l'update"; + } + } + } + } + + $this->_arrData["arrError"] = $arrError; + $this->_arrData['objUser'] = $objUser; + $this->_display("useredit"); + + } + } diff --git a/entities/project_entity.php b/entities/project_entity.php index cde9bbe..6e7e944 100644 --- a/entities/project_entity.php +++ b/entities/project_entity.php @@ -41,8 +41,9 @@ class Project extends Entity{ * Mise à jour de l'id du projet * @param int le nouvelle id */ - public function setId($id){ - $this->_id = $id; + public function setId(int $id){ + $this->_id = $id; + return $this; } /** diff --git a/env b/env index af95f41..1ba2754 100644 --- a/env +++ b/env @@ -4,4 +4,8 @@ DB_CONNECTION=mysql DB_HOSTNAME=boulayoune.com DB_DATABASE=projet_folliow DB_USERNAME= -DB_PASSWORD= \ No newline at end of file +DB_PASSWORD= + +# image path +IMG_PROJECT_PATH = uploads/projects/ +IMG_USER_PATH = uploads/profiles/ \ No newline at end of file diff --git a/models/mother_model.php b/models/mother_model.php index c3f088c..7758599 100644 --- a/models/mother_model.php +++ b/models/mother_model.php @@ -23,14 +23,14 @@ } /** - Pour passer sur le serveur de YASS: + *Pour passer sur le serveur de YASS: *"mysql:host=boulayoune.com;dbname=projet_folliow", // Serveur et BDD "projet_user", //Nom d'utilisateur de la base de données "F0lliowRules!",// Mot de passe de la base de données Site pour BDD: https://phpmyadmin.boulayoune.com/index.php?route=/sql&pos=0&db=projet_folliow&table=project - Pour passer en local: - "mysql:host=localhost;dbname=projet_folliow", // Serveur et BDD - "root", //Nom d'utilisateur de la base de données - "",// Mot de passe de la base de données + *Pour passer en local: + *"mysql:host=localhost;dbname=projet_folliow", // Serveur et BDD + *"root", //Nom d'utilisateur de la base de données + *"",// Mot de passe de la base de données */ \ No newline at end of file diff --git a/models/project_model.php b/models/project_model.php index 8d2a9a2..04bd1a6 100644 --- a/models/project_model.php +++ b/models/project_model.php @@ -16,72 +16,90 @@ * @return array */ public function findAll(int $intLimit=0, string $strKeywords='', int $intAuthor=0, - int $intPeriod=0, string $strDate='', string $strStartDate='', - string $strEndDate='', int $intCategory=0, bool $bool6Months=false):array{ + int $intPeriod=0, string $strDate='', string $strStartDate='', + string $strEndDate='', int $intCategory=0, bool $boolOlderThan6Months=false): array { + $strRq = "SELECT project.*, user_pseudo AS 'project_creatorname', user_image FROM project - INNER JOIN users ON user_id = project_user_id"; - - $strWhere = " WHERE "; + INNER JOIN users ON user_id = project_user_id + WHERE 1=1"; - // Recherche par mot clé avec quote pour éviter bug du ' if ($strKeywords != '') { - - $strSafeKeywords = $this->_db->quote("%" . $strKeywords . "%"); - - $strRq .= " WHERE (project_title LIKE ".$strSafeKeywords." - OR project_content LIKE ".$strSafeKeywords.") "; - - //$boolWhere = true; - $strWhere = " AND "; + $strRq .= " AND (project_title LIKE :keywords OR project_content LIKE :keywords)"; } - - // Recherche par auteur + if ($intAuthor > 0){ - $strRq .= $strWhere." user_id = ".$intAuthor; - $strWhere = " AND "; + $strRq .= " AND project_user_id = :author"; } - // Recherche par catégorie if ($intCategory > 0){ - $strRq .= $strWhere." project_category = ".$intCategory; - $strWhere = " AND "; + $strRq .= " AND project_category = :category"; } - //recherche par ancienneté - if ($bool6Months === true) { - $strRq .= $strWhere . " project_creation_date <= DATE_SUB(NOW(), INTERVAL 6 MONTH) "; - $strWhere = " AND "; + if ($boolOlderThan6Months === true) { + $strRq .= " AND project_creation_date <= DATE_SUB(NOW(), INTERVAL 6 MONTH)"; } - - // Recherche par dates + if ($intPeriod == 0){ if ($strDate != ''){ - $strRq .= $strWhere." project_creation_date = '".$strDate."'"; + $strRq .= " AND project_creation_date = :date_exacte"; } - }else{ + } else { if ($strStartDate != '' && $strEndDate != ''){ - $strRq .= $strWhere." project_creation_date BETWEEN '".$strStartDate."' AND '".$strEndDate."'"; - }else{ + $strRq .= " AND project_creation_date BETWEEN :date_debut AND :date_fin"; + } else { if ($strStartDate != ''){ - $strRq .= $strWhere." project_creation_date >= '".$strStartDate."'"; - }else if ($strEndDate != ''){ - $strRq .= $strWhere." project_creation_date <= '".$strEndDate."'"; + $strRq .= " AND project_creation_date >= :date_debut"; + } else if ($strEndDate != ''){ + $strRq .= " AND project_creation_date <= :date_fin"; } } } - + $strRq .= " ORDER BY project_creation_date DESC"; if ($intLimit > 0){ - $strRq .= " LIMIT ".$intLimit; + $strRq .= " LIMIT :limit"; } - return $this->_db->query($strRq)->fetchAll(); + $rqPrep = $this->_db->prepare($strRq); + + if ($strKeywords != '') { + $rqPrep->bindValue(':keywords', '%' . $strKeywords . '%', PDO::PARAM_STR); + } + if ($intAuthor > 0){ + $rqPrep->bindValue(':author', $intAuthor, PDO::PARAM_INT); + } + if ($intCategory > 0){ + $rqPrep->bindValue(':category', $intCategory, PDO::PARAM_INT); + } + if ($intPeriod == 0){ + if ($strDate != ''){ + $rqPrep->bindValue(':date_exacte', $strDate, PDO::PARAM_STR); + } + } else { + if ($strStartDate != '' && $strEndDate != ''){ + $rqPrep->bindValue(':date_debut', $strStartDate, PDO::PARAM_STR); + $rqPrep->bindValue(':date_fin', $strEndDate, PDO::PARAM_STR); + } else { + if ($strStartDate != ''){ + $rqPrep->bindValue(':date_debut', $strStartDate, PDO::PARAM_STR); + } else if ($strEndDate != ''){ + $rqPrep->bindValue(':date_fin', $strEndDate, PDO::PARAM_STR); + } + } + } + if ($intLimit > 0){ + $rqPrep->bindValue(':limit', $intLimit, PDO::PARAM_INT); + } + + $rqPrep->execute(); + return $rqPrep->fetchAll(); } + /** * Fonction d'insertion d'un nouveau projet dans la bdd @@ -103,7 +121,16 @@ $rqPrep->bindValue(":project_user_id", $objProject->getUser_id(), PDO::PARAM_STR); $rqPrep->bindValue(":project_category", $objProject->getCategory(), PDO::PARAM_STR); - return $rqPrep->execute(); + // On met une variable boolOk pour récupérer l'id du projet + $boolOk = $rqPrep->execute(); + + // Si boolOk est remplis + if ($boolOk) { + // On récupère l'ID auto-incrémenté et on l'injecte dans l'objet + $objProject->setId($this->_db->lastInsertId()); + } + + return $boolOk; } /** @@ -113,7 +140,7 @@ */ public function findOne(int $intId) :array{ $strRq = "SELECT project.*, - CONCAT(users.user_firstname, ' ', users.user_name) AS 'project_creatorname', + users.user_pseudo AS 'project_creatorname', users.user_image, category.category_name FROM project @@ -136,12 +163,10 @@ */ public function accept(int $id){ - //SQL pour changer le status en accept $strRq = "UPDATE project SET project_status= 'publié' WHERE project_id =".$id; - //retourne la commande return $this->_db->query($strRq); } @@ -200,10 +225,16 @@ return $rqPrep->execute(); } + /** + * Fonction de récupération d'image d'un projet en BDD + * @author Guillaume + * @param int $objProject L'Id du projet choisit + * @return array Un tableau avec les informations de la bdd + */ public function getImagesByProjectId(int $projectId): array { - $strRq = "SELECT image_id, image_name, image_alt + $strRq = "SELECT image_id, image_name, image_alt, image_status FROM image - WHERE image_project = :id AND image_status = 1"; + WHERE image_project = :id"; $rqPrep = $this->_db->prepare($strRq); $rqPrep->bindValue(":id", $projectId, PDO::PARAM_INT); @@ -212,6 +243,56 @@ return $rqPrep->fetchAll(PDO::FETCH_ASSOC); } + /** + * Fonction de récupération d'image d'un projet en BDD + * @author Guillaume + * @param int $id L'Id de l'image choisit + * @return array Un tableau avec les informations de la bdd + */ + public function deleteImage(int $id): bool { + $strRq = "DELETE FROM image WHERE image_id = :id"; + $rqPrep = $this->_db->prepare($strRq); + $rqPrep->bindValue(':id', $id, PDO::PARAM_INT); + return $rqPrep->execute(); + } + + /** + * Fonction de modifications de status de l'image d'un projet en BDD + * @author Guillaume + * @param int $id L'Id de l'image choisit, string $status le status choisit + * @return array Un tableau avec les informations de la bdd + */ + public function updateImageStatus(int $id, string $status): bool { + $strRq = "UPDATE image SET image_status = :status WHERE image_id = :id"; + $rqPrep = $this->_db->prepare($strRq); + $rqPrep->bindValue(':status', $status, PDO::PARAM_STR); + $rqPrep->bindValue(':id', $id, PDO::PARAM_INT); + return $rqPrep->execute(); + } + + /** + * Fonction de récupération d'image d'un projet en BDD + * @author Guillaume + * @param int $id L'Id de l'image choisit + * @return array Un tableau avec les informations de la bdd + */ + public function findImage(int $id): array|bool { + $strRq = "SELECT * FROM image WHERE image_id = :id"; + $rqPrep = $this->_db->prepare($strRq); + $rqPrep->bindValue(':id', $id, PDO::PARAM_INT); + $rqPrep->execute(); + return $rqPrep->fetch(PDO::FETCH_ASSOC); + } + + + /** + * Ajoute une image liée à un projet dans la table 'image' + * @author Guillaume + * @param string $fileName Nom du fichier image + * @param int $projectId ID du projet parent + * @param string $alt Texte alternatif + * @return bool + */ public function addImageInProject(string $fileName, int $projectId, string $alt = "Image projet"): bool { $strRq = "INSERT INTO image ( image_name, @@ -225,9 +306,10 @@ $rqPrep->bindValue(":name", $fileName, PDO::PARAM_STR); $rqPrep->bindValue(":alt", $alt, PDO::PARAM_STR); - $rqPrep->bindValue(":status", "en_attente", PDO::PARAM_STR); // Valeur string brute + // On met le statut par défaut en "en_attente" pour la modération + $rqPrep->bindValue(":status", "en_attente", PDO::PARAM_STR); $rqPrep->bindValue(":project", $projectId, PDO::PARAM_INT); return $rqPrep->execute(); - } + } } \ No newline at end of file diff --git a/uploads/profiles/699d648ba35c3.webp b/uploads/profiles/699d648ba35c3.webp new file mode 100644 index 0000000..3fa3f0a Binary files /dev/null and b/uploads/profiles/699d648ba35c3.webp differ diff --git a/uploads/profiles/images.jpg b/uploads/profiles/images.jpg new file mode 100644 index 0000000..44949df Binary files /dev/null and b/uploads/profiles/images.jpg differ diff --git a/uploads/projects/6998730421d82.webp b/uploads/projects/6998730421d82.webp deleted file mode 100644 index 3582ecf..0000000 Binary files a/uploads/projects/6998730421d82.webp and /dev/null differ diff --git a/uploads/projects/6998793d6b378.webp b/uploads/projects/6998793d6b378.webp deleted file mode 100644 index 89961e9..0000000 Binary files a/uploads/projects/6998793d6b378.webp and /dev/null differ diff --git a/uploads/projects/699ca2c207e75.webp b/uploads/projects/699ca2c207e75.webp new file mode 100644 index 0000000..4f5030e Binary files /dev/null and b/uploads/projects/699ca2c207e75.webp differ diff --git a/uploads/projects/699ca2cf9f010.webp b/uploads/projects/699ca2cf9f010.webp new file mode 100644 index 0000000..4f5030e Binary files /dev/null and b/uploads/projects/699ca2cf9f010.webp differ diff --git a/uploads/projects/699ca324b5dbc.webp b/uploads/projects/699ca324b5dbc.webp new file mode 100644 index 0000000..4f5030e Binary files /dev/null and b/uploads/projects/699ca324b5dbc.webp differ diff --git a/uploads/projects/699ca3d159d4f.webp b/uploads/projects/699ca3d159d4f.webp new file mode 100644 index 0000000..e460ae1 Binary files /dev/null and b/uploads/projects/699ca3d159d4f.webp differ diff --git a/uploads/projects/699d9a6c0f3ff.webp b/uploads/projects/699d9a6c0f3ff.webp new file mode 100644 index 0000000..a58a521 Binary files /dev/null and b/uploads/projects/699d9a6c0f3ff.webp differ diff --git a/uploads/projects/699da2d0f019d_gallery.webp b/uploads/projects/699da2d0f019d_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699da2d0f019d_gallery.webp differ diff --git a/uploads/projects/699da361ad88b_gallery.webp b/uploads/projects/699da361ad88b_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699da361ad88b_gallery.webp differ diff --git a/uploads/projects/699da361b8269_gallery.webp b/uploads/projects/699da361b8269_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699da361b8269_gallery.webp differ diff --git a/uploads/projects/699daa1221be1.webp b/uploads/projects/699daa1221be1.webp new file mode 100644 index 0000000..a58a521 Binary files /dev/null and b/uploads/projects/699daa1221be1.webp differ diff --git a/uploads/projects/699daa122cd7e_gallery.webp b/uploads/projects/699daa122cd7e_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699daa122cd7e_gallery.webp differ diff --git a/uploads/projects/699daa1237170_gallery.webp b/uploads/projects/699daa1237170_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699daa1237170_gallery.webp differ diff --git a/uploads/projects/699daa1240e76_gallery.webp b/uploads/projects/699daa1240e76_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699daa1240e76_gallery.webp differ diff --git a/uploads/projects/699daaaa3ad2f_gallery.webp b/uploads/projects/699daaaa3ad2f_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699daaaa3ad2f_gallery.webp differ diff --git a/uploads/projects/699daaaa465e2_gallery.webp b/uploads/projects/699daaaa465e2_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699daaaa465e2_gallery.webp differ diff --git a/uploads/projects/699daaaa508c2_gallery.webp b/uploads/projects/699daaaa508c2_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699daaaa508c2_gallery.webp differ diff --git a/uploads/projects/699daab323eba_gallery.webp b/uploads/projects/699daab323eba_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699daab323eba_gallery.webp differ diff --git a/uploads/projects/699daab32e68b_gallery.webp b/uploads/projects/699daab32e68b_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699daab32e68b_gallery.webp differ diff --git a/uploads/projects/699daab3382c9_gallery.webp b/uploads/projects/699daab3382c9_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699daab3382c9_gallery.webp differ diff --git a/uploads/projects/699daad12bbd3_gallery.webp b/uploads/projects/699daad12bbd3_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699daad12bbd3_gallery.webp differ diff --git a/uploads/projects/699daad137975_gallery.webp b/uploads/projects/699daad137975_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699daad137975_gallery.webp differ diff --git a/uploads/projects/699daad141d4f_gallery.webp b/uploads/projects/699daad141d4f_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699daad141d4f_gallery.webp differ diff --git a/uploads/projects/699daad14c4c0_gallery.webp b/uploads/projects/699daad14c4c0_gallery.webp new file mode 100644 index 0000000..bd69290 Binary files /dev/null and b/uploads/projects/699daad14c4c0_gallery.webp differ diff --git a/uploads/projects/699daae1accb0_gallery.webp b/uploads/projects/699daae1accb0_gallery.webp new file mode 100644 index 0000000..bd69290 Binary files /dev/null and b/uploads/projects/699daae1accb0_gallery.webp differ diff --git a/uploads/projects/699daae1b71a4_gallery.webp b/uploads/projects/699daae1b71a4_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699daae1b71a4_gallery.webp differ diff --git a/uploads/projects/699daae1c14d4_gallery.webp b/uploads/projects/699daae1c14d4_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699daae1c14d4_gallery.webp differ diff --git a/uploads/projects/699daae1cb709_gallery.webp b/uploads/projects/699daae1cb709_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699daae1cb709_gallery.webp differ diff --git a/uploads/projects/699daaee31689_gallery.webp b/uploads/projects/699daaee31689_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699daaee31689_gallery.webp differ diff --git a/uploads/projects/699daaee3cfe3_gallery.webp b/uploads/projects/699daaee3cfe3_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699daaee3cfe3_gallery.webp differ diff --git a/uploads/projects/699daaee4725f_gallery.webp b/uploads/projects/699daaee4725f_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699daaee4725f_gallery.webp differ diff --git a/uploads/projects/699dadac0af45_gallery.webp b/uploads/projects/699dadac0af45_gallery.webp new file mode 100644 index 0000000..bd69290 Binary files /dev/null and b/uploads/projects/699dadac0af45_gallery.webp differ diff --git a/uploads/projects/699dadac15713_gallery.webp b/uploads/projects/699dadac15713_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699dadac15713_gallery.webp differ diff --git a/uploads/projects/699dadac202e2_gallery.webp b/uploads/projects/699dadac202e2_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699dadac202e2_gallery.webp differ diff --git a/uploads/projects/699db11d01cb6_gallery.webp b/uploads/projects/699db11d01cb6_gallery.webp new file mode 100644 index 0000000..ab526bb Binary files /dev/null and b/uploads/projects/699db11d01cb6_gallery.webp differ diff --git a/uploads/projects/699db11d0d418_gallery.webp b/uploads/projects/699db11d0d418_gallery.webp new file mode 100644 index 0000000..76941cd Binary files /dev/null and b/uploads/projects/699db11d0d418_gallery.webp differ diff --git a/uploads/projects/699db11d1741e_gallery.webp b/uploads/projects/699db11d1741e_gallery.webp new file mode 100644 index 0000000..88d37ae Binary files /dev/null and b/uploads/projects/699db11d1741e_gallery.webp differ diff --git a/uploads/projects/699db11d21c20_gallery.webp b/uploads/projects/699db11d21c20_gallery.webp new file mode 100644 index 0000000..bd69290 Binary files /dev/null and b/uploads/projects/699db11d21c20_gallery.webp differ diff --git a/uploads/projects/taskmanager-thumb.jpg b/uploads/projects/taskmanager-thumb.jpg deleted file mode 100644 index 051578c..0000000 Binary files a/uploads/projects/taskmanager-thumb.jpg and /dev/null differ diff --git a/views/_partial/footer.tpl b/views/_partial/footer.tpl index 9eaa238..bde1b20 100644 --- a/views/_partial/footer.tpl +++ b/views/_partial/footer.tpl @@ -5,7 +5,7 @@
  • Découvrir
  • Customisation
  • Emploi -
  • A propos +
  • A propos
    @@ -19,7 +19,7 @@
    @@ -31,4 +31,4 @@ - \ No newline at end of file + diff --git a/views/_partial/header.tpl b/views/_partial/header.tpl index cb8df32..67ef10d 100644 --- a/views/_partial/header.tpl +++ b/views/_partial/header.tpl @@ -7,7 +7,7 @@ - Folliow + Folliow{block name="title"}{/block}
    diff --git a/views/about.tpl b/views/about.tpl new file mode 100644 index 0000000..6b43f89 --- /dev/null +++ b/views/about.tpl @@ -0,0 +1,160 @@ +{extends file="views/layout.tpl"} + +{block name="title" append} - À propos{/block} + +{block name="h2"}À propos de FOLLIOW{/block} +{block name="p"}Plateforme de partage de projets – Projet pédagogique{/block} + +{block name="content"} + +
    +
    + + +
    + +
    +

    + + Présentation du projet +

    + +

    + FOLLIOW est une plateforme web développée dans le cadre d’un projet pédagogique. + Elle permet aux utilisateurs de publier, consulter et partager des projets numériques + à travers une interface simple et structurée. +

    + +

    + Ce projet a été conçu afin de mettre en pratique les compétences acquises en + développement web, notamment l’architecture MVC, la gestion des bases de données + et la sécurisation des échanges. +

    +
    + +
    +

    + + Fonctionnalités principales +

    + +
      +
    • Création et gestion de projets
    • +
    • Affichage dynamique des contenus
    • +
    • Gestion des utilisateurs
    • +
    • Partage d’un projet par email
    • +
    • Interface responsive et accessible
    • +
    +
    + +
    +

    + + Objectifs pédagogiques +

    + +

    + L’objectif principal de FOLLIOW est de démontrer la capacité à concevoir + une application web complète, structurée et sécurisée. +

    + +
      +
    • Structuration d’un projet en architecture MVC
    • +
    • Manipulation de bases de données relationnelles
    • +
    • Validation et sécurisation des données
    • +
    • Implémentation d’un système d’envoi d’emails
    • +
    • Respect des bonnes pratiques (RGPD, accessibilité, organisation du code)
    • +
    +
    + +
    +

    + + Technologies utilisées +

    + +
    +
    +
    +
    + Backend +

    + PHP orienté objet – Architecture MVC – MySQL +

    +
    +
    +
    + +
    +
    +
    + Frontend +

    + HTML5 – CSS3 – Bootstrap – Smarty +

    +
    +
    +
    + +
    +
    +
    + Emails +

    + PHPMailer – SMTP – Brevo +

    +
    +
    +
    + +
    +
    +
    + Sécurité +

    + Validation des données – Protection des formulaires – Gestion des sessions +

    +
    +
    +
    +
    +
    + +
    + + +
    +
    + +

    + + Projet pédagogique +

    + +

    + FOLLIOW a été réalisé dans le cadre d’une formation en développement web. + Il s’agit d’un projet démonstratif à visée éducative. +

    + +
    + +

    + + Contact +

    + +

    + Pour toute question : +

    + + + projet.folliow@hotmail.com + + +
    +
    + +
    +
    + +{/block} \ No newline at end of file diff --git a/views/addedit_project.tpl b/views/addedit_project.tpl index 38a0dae..2aadc89 100644 --- a/views/addedit_project.tpl +++ b/views/addedit_project.tpl @@ -40,14 +40,56 @@ {if $objProject && $objProject->getId()} - Miniature + Miniature {/if}
    - - -
    + + {assign var="nbActuel" value=$arrImages|@count} + {assign var="disponible" value=20 - $nbActuel} + + {if $disponible > 0} +

    Il vous reste {$disponible} emplacement(s) libre(s).

    + + {else} +
    + Quota de 20 photos atteint. +
    + {* On désactive l'input si le quota est plein *} + + {/if} + + + {* Affichage de Images du projet (s'il y en a)*} +
    + + {foreach $arrImages as $image} +
    +
    + {$image.image_alt} + +
    + + {*Permet de remplacer certains character par d'autre*} + {$image.image_status|replace:'_':' '} + + +
    + Supprimer +
    +
    +
    +
    + {foreachelse} +

    Aucune photo dans la galerie pour le moment.

    + {/foreach} +
    diff --git a/views/inscription.tpl b/views/inscription.tpl deleted file mode 100644 index 7b82e77..0000000 --- a/views/inscription.tpl +++ /dev/null @@ -1,197 +0,0 @@ -{extends file="views/layout.tpl"} - -{block name="content"} - - - -
    - - -
    -
    - - -
    - - -

    Inscription

    - - -

    - Créez votre compte utilisateur. -

    - {if (isset($arrError) && count($arrError) > 0) } -
    - {foreach $arrError as $strError} -

    {$strError}

    - {/foreach} -
    - {/if} - - -
    - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    - @ - -
    -
    - - -
    - - -
    - - -
    - - -
    - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    - - -
    - - Déjà un compte ? - Se connecter - -
    - - -
    - - -
    - -
    -
    -
    -{/block} \ No newline at end of file diff --git a/views/login.tpl b/views/login.tpl index 2ea1286..02f9390 100644 --- a/views/login.tpl +++ b/views/login.tpl @@ -1,116 +1,84 @@ {extends file="views/layout.tpl"} +{block name="title" append} - Connexion{/block} {block name="content"}
    - {* Affichage des erreurs *} - {if $arrError|count > 0} -
    - {foreach from=$arrError item=strError} -

    {$strError}

    - {/foreach} -
    - {/if} - -
    - -
    - -
    +
    + +
    +
    - -
    -
    + +
    - -
    + +

    Connexion

    - -

    Connexion

    + +

    + Connectez-vous à votre compte. +

    - -

    - Connectez-vous à votre compte. -

    + + +
    +
    - - - + +
    + + +
    -
    + +
    + + +
    - -
    - - -
    + +
    + +
    - -
    - - -
    + +
    + + Pas encore de compte ? + + Créer un compte + + +
    - -
    -
    - - -
    -
    +
    + - -
    - -
    +
    - -
    - - Pas encore de compte ? - Créer un compte - -
    +
    +
    +
    - - - -
    - - -
    - -
    -
    -
    -{/block} \ No newline at end of file +{/block} diff --git a/views/mail_message.tpl b/views/mail_message.tpl index 4d4a618..fd5574e 100644 --- a/views/mail_message.tpl +++ b/views/mail_message.tpl @@ -1,26 +1,26 @@ -

    Bonjour,

    - -

    - Un projet a été partagé avec vous via la plateforme Folliow. -

    - -

    {$projectTitle}

    - -

    - {$projectDescription} -

    - -

    - Vous pouvez consulter le projet en cliquant sur le lien ci-dessous : -

    - -

    - - {$projectUrl} - -

    - -

    - Cordialement,
    - L’équipe Folliow -

    +

    Bonjour,

    + +

    + Un projet a été partagé avec vous via la plateforme Folliow. +

    + +

    {$projectTitle}

    + +

    + {$projectDescription} +

    + +

    + Vous pouvez consulter le projet en cliquant sur le lien ci-dessous : +

    + +

    + + {$projectUrl} + +

    + +

    + Cordialement,
    + L’équipe Folliow +

    diff --git a/views/mentions.tpl b/views/mentions.tpl index ad5d4c9..9e23a03 100644 --- a/views/mentions.tpl +++ b/views/mentions.tpl @@ -1,6 +1,7 @@ {extends file="views/layout.tpl"} -{block name="title" append}Mentions légales{/block} +{block name="title" append} - Mentions légales{/block} + {block name="h2"}Mentions légales{/block} {block name="p"}Informations légales et politique de confidentialité{/block} @@ -284,4 +285,4 @@
    -{/block} \ No newline at end of file +{/block} diff --git a/views/project.tpl b/views/project.tpl new file mode 100644 index 0000000..1e88fab --- /dev/null +++ b/views/project.tpl @@ -0,0 +1,75 @@ +{extends file="views/layout.tpl"} + +{block name="content"} + +
    +
    +

    Alimenter votre projet

    +
    + + {if isset($smarty.post.toContinue)} + + {/if} +
    + + {* Affichage d'un formulaire en cas d'appuie sur le bouton "+" *} + {if isset($smarty.post.showForm) || isset($smarty.post.showFormContinue)} + {if isset($smarty.session.user)} +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +

    Image thumbnail

    + +
    +
    +

    Image du projet

    + +
    +
    + + +
    +
    + {else} +
    +

    Vous devez vous connecter pour accéder à cette fonctionnalité

    +
    + {/if} + {/if} + +
    +
    +

    Description

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    +
    +

    Photos behind the scene

    +
    + +
    +
    +
    +

    Other projects

    +
    + {foreach $arrProjectToDisplay as $objProject} + {include file="../app/views/partials/preview.tpl"} + {/foreach} +
    +
    + +
    + +{/block} \ No newline at end of file diff --git a/views/project_display.tpl b/views/project_display.tpl index 046b5c3..574c6ad 100644 --- a/views/project_display.tpl +++ b/views/project_display.tpl @@ -34,7 +34,47 @@ {$objProject->getContent()} + + + +
    +

    Galerie du projet

    +
    + {foreach $arrImages as $image} + + {* On affiche l'image si elle est approuvée OU si l'utlilisateur possède le projet OU si l'utlilisateur est Modérateur*} + {if ($image.image_status == 'approuvé') || + (isset($smarty.session.user) && $smarty.session.user.user_status == 2) || + (isset($smarty.session.user) && $smarty.session.user.user_id == $objProject->getUser_id())} + +
    +
    + + {$image.image_alt} + {* Visible uniquement par le modérateur *} + {if isset($smarty.session.user.user_status) && $smarty.session.user.user_status == 2} +
    +
    + Valider + + Supprimer +
    +
    + {/if} +
    +
    + {/if} + {foreachelse} +

    Aucune image disponible pour ce projet.

    + {/foreach} +
    +
    + +
    @@ -59,7 +99,7 @@
    - @@ -67,7 +107,6 @@

    Publié le {$objProject->getCreation_date()} -

    @@ -97,7 +136,6 @@
    -
    -{/block} +{/block} \ No newline at end of file diff --git a/views/search.tpl b/views/search.tpl index ea255b6..8f459c4 100644 --- a/views/search.tpl +++ b/views/search.tpl @@ -1,4 +1,5 @@ {extends file="views/layout.tpl"} +{block name="title" append} - Rechercher{/block} {block name="content"}
    @@ -186,4 +187,4 @@ // Initialisation au chargement toggleDateFields(); -{/block} \ No newline at end of file +{/block} diff --git a/views/signup.tpl b/views/signup.tpl new file mode 100644 index 0000000..21ec90a --- /dev/null +++ b/views/signup.tpl @@ -0,0 +1,202 @@ +{extends file="views/layout.tpl"} +{block name="title" append} - Inscription{/block} + +{block name="content"} + + +
    + + +
    +
    + + +
    + + +

    Inscription

    + + +

    + Créez votre compte utilisateur. +

    + + + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + +
    + @ + +
    +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + +
    + + +
    + + Déjà un compte ? + + Se connecter + + +
    + +
    + + +
    + +
    +
    + +
    +{/block} \ No newline at end of file diff --git a/views/user.tpl b/views/user.tpl index 45a78e5..d7e5016 100644 --- a/views/user.tpl +++ b/views/user.tpl @@ -5,7 +5,7 @@