Webbserverprogrammering 1

Show sourcecode

The following files exists in this folder. Click to view.

webbsrvprg/projects/slutprojekt/

class/
create-categories.php
create-recipe.php
css/
db_content.php
forgot_password.php
include/
login.php
logout.php
recipe-search.php
recipe.php
reset_password.php
signin.php
start.php
tabeller/
verify.php

recipe.php

319 lines UTF-8 Windows (CRLF)
<?php
session_start
();
include(
'../../dbconnection.php');
ob_clean();

include(
'include/session-variables.php');


if (isset(
$_GET['recipe'])) {
  
$recipe_number $_GET['recipe'];

  
$stmt $dbconn->prepare("SELECT * FROM recipes WHERE recipe_id = :num");
  
$stmt->bindParam(':num'$recipe_number);
  
$stmt->execute();

  
$res $stmt->fetch(PDO::FETCH_ASSOC);
  
$title $res["title"];
  
$ingredients $res["ingredients"];
  
$instructions $res["instructions"];
  
$img $res["image"];
  if (empty(
$img)) {
    
$img '../../../filhantering/no-image.jpg'
  }
  
$creator_id $res["user_id"];
  
$current_user_id $_SESSION["userId"];
  if (
$_SESSION["loggedin"] == true ) {
    
$isLoggedIn true;
  }

  try {
  
    if (
$_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['rating'])) {
      
$rating $_POST['rating'];
  
      
$stmt $dbconn->prepare("SELECT * FROM ratings WHERE user_id = :num AND recipe_id = :recipe_id");
      
$stmt->bindParam(':num'$current_user_id);
      
$stmt->bindParam(':recipe_id'$recipe_number);
      
$stmt->execute();
    
      if(
$stmt->rowCount() > 0) {
        
$stmt $dbconn->prepare("UPDATE ratings SET rating = :rating WHERE user_id = :user_id AND recipe_id = :recipe_id");
        
$stmt->bindParam(':rating'$rating);
        
$stmt->bindParam(':user_id'$current_user_id);
        
$stmt->bindParam(':recipe_id'$recipe_number);
  
        
$stmt->execute();
      } else {
        
$insert $dbconn->prepare("INSERT INTO ratings (recipe_id, user_id, rating) VALUES (:recipe_id, :user_id, :rating)");
        
$insert->execute([':recipe_id' => $recipe_number':user_id' => $current_user_id':rating' => $rating]);
      }
    }

    if (
$_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['comment'])) {
      
$comment $_POST['comment'];

      
$insert $dbconn->prepare("INSERT INTO comments (recipe_id, user_id, comment) VALUES (:recipe_id, :user_id, :comment)");
      
$insert->execute([':recipe_id' => $recipe_number':user_id' => $current_user_id':comment' => $comment]);
    } 

  
  }
  catch(
PDOException $e) {
    echo 
"Error: " "<br />" $e->getMessage();
  }

  try {
    
$stmt $dbconn->prepare("SELECT * FROM favorites WHERE user_id = :num AND recipe_id = :recipe_id");
    
$stmt->bindParam(':num'$current_user_id);
    
$stmt->bindParam(':recipe_id'$recipe_number);
    
$stmt->execute();

    if(
$stmt->rowCount() > 0) {
      
$is_favorite true;
    }
    else {
      
$is_favorite false;
    }

    if (
$_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['favorite'])) {
      
$stmt $dbconn->prepare("SELECT * FROM favorites WHERE user_id = :num AND recipe_id = :recipe_id");
      
$stmt->bindParam(':num'$current_user_id);
      
$stmt->bindParam(':recipe_id'$recipe_number);
      
$stmt->execute();
  
      if(
$stmt->rowCount() > 0) {
        
$is_favorite false;
        
$stmt $dbconn->prepare("DELETE FROM favorites WHERE user_id = :user_id AND recipe_id =:recipe_id");
        
$stmt->bindParam(':user_id'$current_user_id);
        
$stmt->bindParam(':recipe_id'$recipe_number);
        
$stmt->execute();
      }
      else {
        
$is_favorite true;

        
$insert $dbconn->prepare("INSERT INTO favorites (recipe_id, user_id) VALUES (:recipe_id, :user_id)");
        
$insert->execute([':recipe_id' => $recipe_number':user_id' => $current_user_id]);
        
      }

    }
  
  }
  catch(
PDOException $e) {
    echo 
"Error: " "<br />" $e->getMessage();
  }

  
$stmt $dbconn->prepare("SELECT COUNT(rating) as rating_count, AVG(rating) as average_rating FROM ratings WHERE recipe_id = :num");
  
$stmt->bindParam(':num'$recipe_number);
  
$stmt->execute();
  
  
$result $stmt->fetch(PDO::FETCH_ASSOC);
  
  
$rating_count $result['rating_count'] ?? 0;
  
$average_rating $result['average_rating'] ?? 0;

  
$stmt $dbconn->prepare("SELECT username FROM users WHERE user_id = :num");
  
$stmt->bindParam(':num'$creator_id);
  
$stmt->execute();

  
$res $stmt->fetch(PDO::FETCH_ASSOC);
  
$creator $res["username"];


  
$stmt $dbconn->prepare("SELECT COUNT(comment) as comment_count FROM comments WHERE recipe_id = :num");
  
$stmt->bindParam(':num'$recipe_number);
  
$stmt->execute();
  
  
$result $stmt->fetch(PDO::FETCH_ASSOC);
  
  
$comment_count $result['comment_count'] ?? 0;


} else {
  echo 
"Receptet finns inte";
}


?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="css/styles.css">
  <link rel="stylesheet" href="css/recipe.css">
  <title>Recept</title>
</head>
<body>
  <div id="page-container">
    <div id="content-wrap">
      <?php include('include/header.php'); ?>

      <div id="container-1">

        <div class="title-container">
          <h1><?php echo $title?></h1>

          <div class="recipe-info">
            <div class="ratings-info">
              <div><svg class="star-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="#FFD43B" d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"/></svg></div>
              <div class="ratings-separation">
              <div> <span class="bold"><?php echo round($average_rating1); ?></span> /5 </div>
                <div class="rating-count">(<?php echo $rating_count;?>)</div>
              </div>
              <div class="user-rating-container">
                <button id="openBtn">
                  <div class="rate-star-icon">
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="#1263a1" d="M287.9 0c9.2 0 17.6 5.2 21.6 13.5l68.6 141.3 153.2 22.6c9 1.3 16.5 7.6 19.3 16.3s.5 18.1-5.9 24.5L433.6 328.4l26.2 155.6c1.5 9-2.2 18.1-9.7 23.5s-17.3 6-25.3 1.7l-137-73.2L151 509.1c-8.1 4.3-17.9 3.7-25.3-1.7s-11.2-14.5-9.7-23.5l26.2-155.6L31.1 218.2c-6.5-6.4-8.7-15.9-5.9-24.5s10.3-14.9 19.3-16.3l153.2-22.6L266.3 13.5C270.4 5.2 278.7 0 287.9 0zm0 79L235.4 187.2c-3.5 7.1-10.2 12.1-18.1 13.3L99 217.9 184.9 303c5.5 5.5 8.1 13.3 6.8 21L171.4 443.7l105.2-56.2c7.1-3.8 15.6-3.8 22.6 0l105.2 56.2L384.2 324.1c-1.3-7.7 1.2-15.5 6.8-21l85.9-85.1L358.6 200.5c-7.8-1.2-14.6-6.1-18.1-13.3L287.9 79z"/></svg>                  </div>
                  <div>Betygsätt</div>
                </button>

                <div id="popupBox" class="modal">
                  <div class="modal-content">
                    <span class="close">&times;</span>
                    <?php if($_SESSION['loggedin'] == true ) {  ?>
                    <h3>Betygsätt receptet</h3> <br>
                    <form id="ratingForm" method="post">
                      <label for="rating">Betyg:</label><br>
                      <select id="rating" name="rating" required>
                        <option value="">Välj...</option>
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        <option value="4">4</option>
                        <option value="5">5</option>
                      </select><br><br>
                      <button type="submit">Skicka</button>
                    </form>
                    <?php } else {?>
                      <p>Du måste <a href="login.php">logga in</a> för att ge betyg</p>
                    <?php ?>
                  </div>
                </div>

              </div>
            </div>
            <div class="comments-info">
              <br>
              <p>Komentarer: <?php echo $comment_count;?></p>
            </div> 
          </div>  

          <div class="favorite">
            <?php if($_SESSION['loggedin'] == true ) { ?>
            <form action="" method="post">
            <button type="submit" name="favorite" id="favorite-btn">
              <?php if($is_favorite == false) { ?>
                <div class="heart-icon" title="Gilla"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="#e60000" d="M225.8 468.2l-2.5-2.3L48.1 303.2C17.4 274.7 0 234.7 0 192.8l0-3.3c0-70.4 50-130.8 119.2-144C158.6 37.9 198.9 47 231 69.6c9 6.4 17.4 13.8 25 22.3c4.2-4.8 8.7-9.2 13.5-13.3c3.7-3.2 7.5-6.2 11.5-9c0 0 0 0 0 0C313.1 47 353.4 37.9 392.8 45.4C462 58.6 512 119.1 512 189.5l0 3.3c0 41.9-17.4 81.9-48.1 110.4L288.7 465.9l-2.5 2.3c-8.2 7.6-19 11.9-30.2 11.9s-22-4.2-30.2-11.9zM239.1 145c-.4-.3-.7-.7-1-1.1l-17.8-20-.1-.1s0 0 0 0c-23.1-25.9-58-37.7-92-31.2C81.6 101.5 48 142.1 48 189.5l0 3.3c0 28.5 11.9 55.8 32.8 75.2L256 430.7 431.2 268c20.9-19.4 32.8-46.7 32.8-75.2l0-3.3c0-47.3-33.6-88-80.1-96.9c-34-6.5-69 5.4-92 31.2c0 0 0 0-.1 .1s0 0-.1 .1l-17.8 20c-.3 .4-.7 .7-1 1.1c-4.5 4.5-10.6 7-16.9 7s-12.4-2.5-16.9-7z"/></svg></div>
                <div class="heart-text">Gilla</div>
              <?php } else { ?>
                <div class="heart-icon" title="Sluta Gilla"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="#e60000" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg></div>
              <?php ?>
            </button>
            </form>
            <?php ?>
          </div>
        </div>

        <div class="recipe-img">
          <img src="<?php echo $img?>" alt="Bild på receptet">
        </div>
      </div>

      <div id="container-2">
        <div class="ingredients">
          <h2>Ingredienser</h2>
          <div class="ing-inst-text"><?php echo nl2br($ingredients); ?></div>
        </div>
        <div class="instructions">
          <h2>Gör så här</h2>
          <div class="ing-inst-text"><?php echo nl2br($instructions); ?></div>
        </div>
      </div>

      <div class="comment">
        <h2>Kommentarer</h2>
        <form action="" method="post">
          <textarea class="comment-textarea" style="resize: vertical;" 
          placeholder="<?php if (!$isLoggedIn) {
            echo 
'Du måste logga in för att kommentera';
          } else { 
            echo 
'Skriv din kommentar';
          }  
          
?>" name="comment" <?php if (!$isLoggedIn) echo 'readonly'?> required></textarea>
          <br>
          <?php if ($isLoggedIn) {?>
          <input type="submit" value="Kommentera" class="comment-input"> 
          <?php ?>
        </form>
        <div class="comments-container">
        <?php
        date_default_timezone_set
('Europe/Stockholm');
        
setlocale(LC_TIME'sv_SE.UTF-8');

        
$stmt $dbconn->prepare("
          SELECT c.*, u.username 
          FROM comments c
          JOIN users u ON c.user_id = u.user_id
          WHERE c.recipe_id = :recipe_id 
          ORDER BY c.created_at ASC
        "
);          
        
$stmt->bindParam(':recipe_id'$recipe_number);
        
$stmt->execute();

        function 
time_ago($timestamp) {
          
$now = new DateTime();
          
$then = new DateTime($timestamp);
          
$diff $now->diff($then);
            
          if (
$diff->0) return $diff->' år sedan';
          if (
$diff->0) return $diff->' månader sedan';
          if (
$diff->0) {
            if (
$diff->== 1) return 'igår';
            return 
$diff->' dagar sedan';
          }
          if (
$diff->0) return $diff->' timmar sedan';
          if (
$diff->0) return $diff->' minuter sedan';
          return 
'just nu';
        }

        while (
$res $stmt->fetch(PDO::FETCH_ASSOC)) {
          echo 
"<div class='user-comment'>";
          echo 
"<div class='comment-author'>" htmlspecialchars($res['username']) . "</div>";
          echo 
"<div class='comment-time'>" time_ago($res['created_at']) . "</div>";
          echo 
"<div class='comment-text'>" htmlspecialchars($res['comment']) . "</div>";
          echo 
"</div>";
        }
        
?>
        </div>
      </div>


      <?php include('include/footer.php'); ?>
    </div> 
  </div>
  <script>
    const modal = document.getElementById("popupBox");
    const btn = document.getElementById("openBtn");
    const span = document.querySelector(".close");
    const form = document.getElementById("ratingForm");

    btn.onclick = function () {
      modal.style.display = "block";
    }

    span.onclick = function () {
      modal.style.display = "none";
    }

    window.onclick = function (event) {
      if (event.target === modal) {
        modal.style.display = "none";
      }
    }

  </script>    
</body>
</html>