From 92980203b13aefb048ad799cf6abac3a44af3a49 Mon Sep 17 00:00:00 2001
From: Kenneth Ezekiel <88850771+KenEzekiel@users.noreply.github.com>
Date: Wed, 4 Oct 2023 14:36:14 +0700
Subject: [PATCH] feat: update film

---
 src/App.php                              |   2 +
 src/Request.php                          |   8 +-
 src/base/BaseRepository.php              |  88 ++++++++--------
 src/controllers/CreateFilmController.php |   4 +-
 src/controllers/UpdateFilmController.php | 124 +++++++++++++++++++++++
 src/repositories/FilmRepository.php      |  39 +++----
 src/services/FilmService.php             |  21 +++-
 views/update_film.php                    |  51 ++++++++++
 8 files changed, 266 insertions(+), 71 deletions(-)
 create mode 100644 src/controllers/UpdateFilmController.php
 create mode 100644 views/update_film.php

diff --git a/src/App.php b/src/App.php
index 77b97de..c3ecd1a 100644
--- a/src/App.php
+++ b/src/App.php
@@ -9,6 +9,7 @@ use app\controllers\LoginController;
 use app\controllers\MainController;
 use app\controllers\ReviewController;
 use app\controllers\RegisterController;
+use app\controllers\UpdateFilmController;
 use app\repositories\UserRepository;
 use app\repositories\ReviewRepository;
 use app\services\UserService;
@@ -34,5 +35,6 @@ class App
     $this->router->addRoute('/logout', LoginController::class);
     $this->router->addRoute('/register', RegisterController::class);
     $this->router->addRoute('/add-film', CreateFilmController::class);
+    $this->router->addRoute('/update-film', UpdateFilmController::class);
   }
 }
diff --git a/src/Request.php b/src/Request.php
index ca8c5c3..44027e7 100644
--- a/src/Request.php
+++ b/src/Request.php
@@ -16,11 +16,9 @@ class Request
 
   public static function getParams()
   {
-    $params = $_SERVER['REQUEST_URI'];
-    $params = explode("?", $params);
-    $params = array_slice($params, 1);
-    if (empty($params)) {
-      return [];
+    $params = [];
+    foreach ($_GET as $key => $value) {
+      $params[$key] = $value;
     }
     return $params;
   }
diff --git a/src/base/BaseRepository.php b/src/base/BaseRepository.php
index c152e77..a276a5e 100644
--- a/src/base/BaseRepository.php
+++ b/src/base/BaseRepository.php
@@ -49,20 +49,19 @@ abstract class BaseRepository
     // Mapping where
     if (count($where) > 0) {
       foreach ($where as $key => $value) {
-          $columns = [$key];
-          if (isset($value[3]) and is_array(($value[3]))) {
-              $columns = [$key] + $value[3];
-          }
-          $subConditions = [];
-          foreach ($columns as $column) {
-              if (isset($value[2]) and $value[2] == 'LIKE') {
-                  $subConditions[] = "LOWER($column) LIKE LOWER(:$column)";
-              }
-              else {
-                  $subConditions[] = "$column = :$column";
-              }
+        $columns = [$key];
+        if (isset($value[3]) and is_array(($value[3]))) {
+          $columns = [$key] + $value[3];
+        }
+        $subConditions = [];
+        foreach ($columns as $column) {
+          if (isset($value[2]) and $value[2] == 'LIKE') {
+            $subConditions[] = "LOWER($column) LIKE LOWER(:$column)";
+          } else {
+            $subConditions[] = "$column = :$column";
           }
-          $conditions[] = "(" . implode(" OR ", $subConditions) . ")";
+        }
+        $conditions[] = "(" . implode(" OR ", $subConditions) . ")";
       }
 
       $sql .= " WHERE " . implode(" AND ", $conditions);
@@ -74,14 +73,14 @@ abstract class BaseRepository
     foreach ($where as $key => $value) {
       $columns = [$key];
       if (isset($value[3]) and is_array(($value[3]))) {
-          $columns = [$key] + $value[3];
+        $columns = [$key] + $value[3];
       }
       foreach ($columns as $column) {
-          if (isset($value[2]) and $value[2] == 'LIKE') {
-              $stmt->bindValue(":$column", "%$value[0]%", $value[1]);
-          } else {
-              $stmt->bindValue(":$column", $value[0], $value[1]);
-          }
+        if (isset($value[2]) and $value[2] == 'LIKE') {
+          $stmt->bindValue(":$column", "%$value[0]%", $value[1]);
+        } else {
+          $stmt->bindValue(":$column", $value[0], $value[1]);
+        }
       }
     }
 
@@ -102,22 +101,21 @@ abstract class BaseRepository
 
     // Mapping where
     if (count($where) > 0) {
-        foreach ($where as $key => $value) {
-            $columns = [$key];
-            if (isset($value[3]) and is_array(($value[3]))) {
-                $columns = [$key] + $value[3];
-            }
-            $subConditions = [];
-            foreach ($columns as $column) {
-                if (isset($value[2]) and $value[2] == 'LIKE') {
-                    $subConditions[] = "LOWER($column) LIKE LOWER(:$column)";
-                }
-                else {
-                    $subConditions[] = "$column = :$column";
-                }
-            }
-            $conditions[] = "(" . implode(" OR ", $subConditions) . ")";
+      foreach ($where as $key => $value) {
+        $columns = [$key];
+        if (isset($value[3]) and is_array(($value[3]))) {
+          $columns = [$key] + $value[3];
         }
+        $subConditions = [];
+        foreach ($columns as $column) {
+          if (isset($value[2]) and $value[2] == 'LIKE') {
+            $subConditions[] = "LOWER($column) LIKE LOWER(:$column)";
+          } else {
+            $subConditions[] = "$column = :$column";
+          }
+        }
+        $conditions[] = "(" . implode(" OR ", $subConditions) . ")";
+      }
 
       $sql .= " WHERE " . implode(" AND ", $conditions);
     }
@@ -139,17 +137,17 @@ abstract class BaseRepository
     $stmt = $this->pdo->prepare($sql);
 
     foreach ($where as $key => $value) {
-        $columns = [$key];
-        if (isset($value[3]) and is_array(($value[3]))) {
-            $columns = [$key] + $value[3];
-        }
-        foreach ($columns as $column) {
-            if (isset($value[2]) and $value[2] == 'LIKE') {
-                $stmt->bindValue(":$column", "%$value[0]%", $value[1]);
-            } else {
-                $stmt->bindValue(":$column", $value[0], $value[1]);
-            }
+      $columns = [$key];
+      if (isset($value[3]) and is_array(($value[3]))) {
+        $columns = [$key] + $value[3];
+      }
+      foreach ($columns as $column) {
+        if (isset($value[2]) and $value[2] == 'LIKE') {
+          $stmt->bindValue(":$column", "%$value[0]%", $value[1]);
+        } else {
+          $stmt->bindValue(":$column", $value[0], $value[1]);
         }
+      }
     }
 
     if ($pageSize && $pageNo) {
@@ -181,7 +179,6 @@ abstract class BaseRepository
 
     // Hydrating statement, for sanitizing
     // echo $sql;
-    // var_dump($where);
 
     $stmt = $this->pdo->prepare($sql);
 
@@ -224,7 +221,6 @@ abstract class BaseRepository
     $sql .= implode(", ", array_map(function ($key, $value) {
       return "$key = :$key";
     }, array_keys($arrParams), array_values($arrParams)));
-    $sql .= ")";
     $primaryKey = $model->get('_primary_key');
     $sql .= " WHERE $primaryKey = :primaryKey";
 
diff --git a/src/controllers/CreateFilmController.php b/src/controllers/CreateFilmController.php
index a910e76..dbd9825 100644
--- a/src/controllers/CreateFilmController.php
+++ b/src/controllers/CreateFilmController.php
@@ -38,7 +38,7 @@ class CreateFilmController extends BaseController
 
   protected function get($urlParams)
   {
-    if ($_SESSION['role'] != 'Admin') {
+    if (!isset($_SESSION['role']) or $_SESSION['role'] != 'admin') {
       // TODO: make error controller
       parent::redirect("/error", 401);
       return;
@@ -48,7 +48,7 @@ class CreateFilmController extends BaseController
 
   protected function post($urlParams)
   {
-    if ($_SESSION['role'] != 'Admin') {
+    if (!isset($_SESSION['role']) or $_SESSION['role'] != 'admin') {
       parent::redirect("/error", 401);
       return;
     }
diff --git a/src/controllers/UpdateFilmController.php b/src/controllers/UpdateFilmController.php
new file mode 100644
index 0000000..5d82e55
--- /dev/null
+++ b/src/controllers/UpdateFilmController.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace app\controllers;
+
+use app\base\BaseController;
+use app\exceptions\BadRequestException;
+use app\models\FilmModel;
+use app\Request;
+use app\services\FilmService;
+use Exception;
+
+class UpdateFilmController extends BaseController
+{
+  protected $film;
+
+  public function __construct()
+  {
+    parent::__construct(FilmService::getInstance());
+  }
+
+  private function is_image($filename)
+  {
+    $extension = pathinfo($filename, PATHINFO_EXTENSION);
+    $imgExtArr = ['jpg', 'jpeg', 'png'];
+    if (in_array($extension, $imgExtArr)) {
+      return true;
+    }
+    return false;
+  }
+
+  private function is_trailer($filename)
+  {
+    $extension = pathinfo($filename, PATHINFO_EXTENSION);
+    $trailerExt = ['mp4'];
+    if (in_array($extension, $trailerExt)) {
+      return true;
+    }
+    return false;
+  }
+
+  protected function get($urlParams)
+  {
+    if (!isset($_SESSION['role']) or $_SESSION['role'] != 'admin') {
+      // TODO: make error controller
+      parent::redirect("/error", 401);
+      return;
+    }
+
+    $film_id = $urlParams['film-id'];
+    $film = $this->service->getById($film_id);
+
+    parent::render($film, "update_film", "layouts/base");
+  }
+
+  protected function post($urlParams)
+  {
+    if (!isset($_SESSION['role']) or $_SESSION['role'] != 'admin') {
+      parent::redirect("/error", 401);
+      return;
+    }
+    try {
+      $film_id = $urlParams['film-id'];
+      $film = $this->service->getById($film_id);
+
+      // Get data
+      $film['title'] = $_POST['title'];
+      $film['released_year'] = $_POST['released-year'];
+      $film['director'] = $_POST['director'];
+      $film['description'] = $_POST['description'];
+      $film['cast'] = $_POST['cast'];
+      $film['genre'] = $_POST['genre'];
+
+      // Check if file is valid
+      if ($_FILES['image-path']['error'] == UPLOAD_ERR_NO_FILE) {
+        $image_path = $film['image_path'];
+      } else {
+        if ($_FILES['image-path']['error'] == UPLOAD_ERR_OK) {
+          $image_tmp = $_FILES['image-path']['tmp_name'];
+          $image_name = $_FILES['image-path']['name'];
+          move_uploaded_file($image_tmp, __DIR__ . "/../../public/files/images/" . $image_name);
+          $image_path = "/public/files/images/" . $image_name;
+
+          if (!$this->is_image($image_name)) {
+            throw new BadRequestException("Image file format is not valid");
+          }
+        } else {
+          throw new BadRequestException("Image file is not valid");
+        }
+      }
+
+      if ($_FILES['trailer-path']['error'] == UPLOAD_ERR_NO_FILE) {
+        $trailer_path = $film['trailer_path'];
+      } else {
+        if ($_FILES['trailer-path']['error'] == UPLOAD_ERR_OK) {
+          $trailer_tmp = $_FILES['trailer-path']['tmp_name'];
+          $trailer_name = $_FILES['trailer-path']['name'];
+          move_uploaded_file($trailer_tmp, __DIR__ . "/../../public/files/trailers/" . $trailer_name);
+          $trailer_path = "/public/files/trailers/" . $trailer_name;
+
+          if (!$this->is_trailer($trailer_name)) {
+            throw new BadRequestException("Trailer file format is not valid");
+          }
+        } else {
+          throw new BadRequestException("Trailer Format is not valid");
+        }
+      }
+
+      // Call service
+      $filmModel = new FilmModel();
+      $filmModel->constructFromArray($film);
+      $response = $this->service->update($filmModel);
+      if ($response) {
+        var_dump($response);
+        $msg = "Successfully updated film!";
+      }
+
+      // Render response
+      parent::render(["Msg" => $msg], "home", "layouts/base");
+    } catch (Exception $e) {
+      $msg = $e->getMessage();
+      parent::render(["errorMsg" => $msg], "create_film", "layouts/base");
+    }
+  }
+}
diff --git a/src/repositories/FilmRepository.php b/src/repositories/FilmRepository.php
index b26f78f..3cdbf7a 100644
--- a/src/repositories/FilmRepository.php
+++ b/src/repositories/FilmRepository.php
@@ -28,27 +28,32 @@ class FilmRepository extends BaseRepository
     return $this->findOne(['film_id' => [$film_id, PDO::PARAM_INT]]);
   }
 
-  public function getAllBySearchAndFilter($word, $order = 'title', $isDesc= false, $genre = 'all',
-                                          $released_year = 'all', $pageNo = 1, $limit = PAGINATION_LIMIT)
-  {
-      $where = [];
-
-      if (isset($genre) and !empty($genre) and $genre != 'all') {
-          $where['genre'] = [$genre, PDO::PARAM_STR, 'LIKE'];
-      }
-      if (isset($released_year) and !empty($released_year) and $released_year != 'all') {
-          $where['released_year'] = [$released_year, PDO::PARAM_INT];
-      }
-      if (isset($word) and !empty($word)) {
-          $where['title'] = [$genre, PDO::PARAM_STR, 'LIKE', ['director']];
-      }
-
-      return $this->findAll($where, $order, $pageNo, $limit, $isDesc);
+  public function getAllBySearchAndFilter(
+    $word,
+    $order = 'title',
+    $isDesc = false,
+    $genre = 'all',
+    $released_year = 'all',
+    $pageNo = 1,
+    $limit = PAGINATION_LIMIT
+  ) {
+    $where = [];
+
+    if (isset($genre) and !empty($genre) and $genre != 'all') {
+      $where['genre'] = [$genre, PDO::PARAM_STR, 'LIKE'];
+    }
+    if (isset($released_year) and !empty($released_year) and $released_year != 'all') {
+      $where['released_year'] = [$released_year, PDO::PARAM_INT];
+    }
+    if (isset($word) and !empty($word)) {
+      $where['title'] = [$genre, PDO::PARAM_STR, 'LIKE', ['director']];
+    }
 
+    return $this->findAll($where, $order, $pageNo, $limit, $isDesc);
   }
 
   public function getAllCategoryValues($category)
   {
-      return $this->getDistinctValues($category);
+    return $this->getDistinctValues($category);
   }
 }
diff --git a/src/services/FilmService.php b/src/services/FilmService.php
index 3311411..e90743a 100644
--- a/src/services/FilmService.php
+++ b/src/services/FilmService.php
@@ -47,7 +47,6 @@ class FilmService extends BaseService
       'title' => PDO::PARAM_STR,
       'released_year' => PDO::PARAM_INT,
       'director' => PDO::PARAM_STR,
-      'trailer_path' => PDO::PARAM_STR,
       'description' => PDO::PARAM_STR,
       'cast' => PDO::PARAM_STR,
       'genre' => PDO::PARAM_STR,
@@ -57,4 +56,24 @@ class FilmService extends BaseService
 
     return $film->constructFromArray($response);
   }
+
+  public function getById($film_id)
+  {
+    return $this->repository->getById($film_id);
+  }
+
+  public function update($film)
+  {
+    $arrParams = [];
+    $arrParams['image_path'] = PDO::PARAM_STR;
+    $arrParams['trailer_path'] = PDO::PARAM_STR;
+    $arrParams['title'] = PDO::PARAM_STR;
+    $arrParams['released_year'] = PDO::PARAM_INT;
+    $arrParams['director'] = PDO::PARAM_STR;
+    $arrParams['description'] = PDO::PARAM_STR;
+    $arrParams['cast'] = PDO::PARAM_STR;
+    $arrParams['genre'] = PDO::PARAM_STR;
+
+    return $this->repository->update($film, $arrParams);
+  }
 }
diff --git a/views/update_film.php b/views/update_film.php
new file mode 100644
index 0000000..19bf090
--- /dev/null
+++ b/views/update_film.php
@@ -0,0 +1,51 @@
+<div class="form-container">
+  <h2 class="header-title">Add Film</h2>
+  <p class="error-msg"><?php if (isset($errorMsg)) {
+                          echo "$errorMsg";
+                        } ?></p>
+  <form class="form" method="post" enctype="multipart/form-data">
+    <div class="form-group">
+      <label for="title">Title</label>
+      <br>
+      <input class="input" type="text" id="title" name="title" value="<?= $title ?>" required>
+    </div>
+    <div class="form-group">
+      <label for="released-year">Released Year</label>
+      <br>
+      <input class="input" type="text" id="released-year" name="released-year" value="<?= $released_year ?>" required>
+    </div>
+    <div class="form-group">
+      <label for="director">Director</label>
+      <br>
+      <input class="input" type="text" id="director" name="director" value="<?= $director ?>" required>
+    </div>
+    <div class="form-group">
+      <label for="description">Description</label>
+      <br>
+      <textarea class="input" type="text" id="description" name="description" required><?= $description ?></textarea>
+    </div>
+    <div class="form-group">
+      <label for="cast">Cast</label>
+      <br>
+      <input class="input" type="text" id="cast" name="cast" value="<?= $cast ?>" required>
+    </div>
+    <div class="form-group">
+      <label for="genre">Genre</label>
+      <br>
+      <input class="input" type="text" id="genre" name="genre" value="<?= $genre ?>" required>
+    </div>
+    <div class="form-group">
+      <label for="image-path">Image</label>
+      <br>
+      <input class="input" type="file" id="image-path" name="image-path">
+    </div>
+    <div class="form-group">
+      <label for="trailer-path">Trailer</label>
+      <br>
+      <input class="input" type="file" id="trailer-path" name="trailer-path">
+    </div>
+    <div class="form-group">
+      <button class="button" ctype="submit">Add</button>
+    </div>
+  </form>
+</div>
\ No newline at end of file
-- 
GitLab