Вложенные комментарии в архитектуре MVC

Я создаю сайт с архитектурой MVC и без фреймворка. Есть комментарии как в блоге. Я хотел бы иметь возможность ответить на комментарий. Но функция ответа не работает (когда я хочу ответить на комментарий, это то же самое, что и первый комментарий), и мне трудно понять, почему? Не могли бы вы помочь мне? Вот адрес сайта: cedricjager.com/stream

Вот connection.php:

class Connection {

// Connection
private function getBdd() {
try {
  $bdd = ConfigDB::database();
  $pdo = new PDO("mysql:host = {$bdd['host']}; dbname = {$bdd['db_name']}", "{$bdd['username']}", "{$bdd['password']}");
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
  print "Error!: " . $e->getMessage() . "<br/>";
  die();
}
return $pdo;
}

// Query
public function query($sql, $params = array(), $fetch = null) {
try {
  $req = self::getBdd()->prepare($sql);
  $req->execute($params);

  if ($fetch == 'one') {
    return $req->fetch();
  } else if ($fetch == 'all') {
    return $req->fetchAll();
  } else {
    return $req;
  }

 } catch (PDOException $e) {
  print "Error!: " . $e->getMessage() . "<br/>";
  die();
 }
 }

Вот модель:

<?php
require_once 'Connection.php';

class Critics extends Connection{


//Récupère les critiques selon l'id de l'article.

public function findAllById($post_id) {
  $sql = "SELECT *, DATE_FORMAT(date, '%d/%m/%Y à %H:%i') AS date
          FROM critics
          WHERE id_movie = ?";
  $params = [$post_id];
  $comms = $this->query($sql,$params,'all');
  $critics_by_id = [];
  foreach ($comms as $comm) {
      $critics_by_id[$comm['id']] = $comm;
  }
  return $critics_by_id;
 }


//Récupèrer les critiques qui ont des enfants.

public function findAllWithChildren($post_id, $unset_children = true) {

$comms = $critics_by_id = $this->findAllById($post_id);
foreach ($comms as $id => $comm) {
    if ($comm['parent_id'] != 0) {
        $critics_by_id[$comm->parent_id]->children[] = $comm;
        if ($unset_children) {
            unset($comms[$id]);
        }
    }
}
return $comms;
}


//récupèrer une critique signalée.

public function findCritics() {

$sql = "SELECT *,DATE_FORMAT(date, '%d/%m/%Y à %H:%i') AS date FROM critics WHERE report=1";
$req = $this->query($sql);
return $req;
}

public function noCritic() {
 if ($this->findCritics() == false) {
    $msg = '<div class = "alert alert-warning">Il n\'y a pas de critiques signalées.</div>';
    return $msg;
 }
 }


 //insérer une critique.
 public function insertCritic(){

  if (isset($_POST['content']) && !empty($_POST['content'])){

    $parent_id = isset($_POST['parent_id']) ? $_POST['parent_id'] : 0;
    $depth = 0;

    if ($parent_id != 0){

      $sql = 'SELECT id, depth  FROM critics WHERE  id = ?';
      $params = [$parent_id];
      $comm = $this->query($sql,$params, 'one');
      if ($comm == false) {
        throw new Exception("Ce parent n'existe pas");
      }
      $depth = $comm->depth + 1;
    }
     if ($depth >= 3) {
       echo "Impossible de rajouter une critique";
     }
     else {
       $sql = 'INSERT INTO critics SET content = ?, author = ?, id_movie = ?, parent_id = ?, date = NOW(), depth = ?';
       $params = array($_POST['content'], $_POST['nom'], $_GET['id'], $parent_id, $depth);
       $req = $this->query($sql,$params);
     }
   }
   }
  }
 }

Контроллер:

  public function single() {
  if (isset($_GET['id'])) {
  $id = $_GET['id'];
  $msg = $this->comment->reportCritic();
  $this->comment->insertCritic();
  $critics = $this->comment->findAllWithChildren($_GET['id']);
  $view = require 'Views/single.php';
  } else {
  header('Location:index.php?p=404');
  }
  }

Взгляды

      <div class = "sectioncomments" id = "comments">
    <?php foreach($critics as $critic): ?>
        <?php require('comments.php'); ?>
    <?php endforeach; ?>
  </div>
  <hr>
  <div class = "row">
    <div class = "col-lg-12">
      <div id = "form-comment" class = " panel panel-default formComment">
        <div class = "panel panel-heading">
          <h4>Poster une critique</h4>
          <br>
          <a href = "#"><span class = "return"></span></a>
        </div>
        <div class = "panel panel-body">
          <form method = "post"  class = "form-group form-horizontal">
            <div class = "form-group">
              <div class = "col-sm-9">
                <input type = "text" class = "form-control" id = "nom" placeholder = "Votre nom..." name = "nom">
              </div>
            </div>
            <div class = "form-group">
              <div class = "col-sm-9">
                <textarea class = "form-control" id = "content" placeholder = "Votre critique..." name = "content"></textarea>
              </div>
            </div>
            <p class = "text-right"><button type = "submit" class = "btn btn-success">Publier</button></p>
            <input type = "hidden" name = "parent_id" id = "parent_id" value = "0" >
          </form>
        </div>
      </div>
    </div>

  </div>
</div>

Comments.php

<div id = "comment-<?= $critic['id'] ?>">
<p>
<b><?= $critic['author'] ?></b>
<span class = "text-muted">le <?= $critic['date'] ?></span>
</p>
<div class = "blockquote">
<blockquote>
  <?= htmlentities($critic['content']) ?>
</blockquote>
</div>
<div class = "formulaire">
<form class = "form-group"  method = "post">
  <p class = "text-left">
    <input type = "hidden" name = "valeur" value = "<?= $critic['id_movie'] ?>">
    <input type = "hidden" name = "idval" value = "<?= $critic['id'] ?>">
    <?php if ($critic['depth'] <= 1): ?>
      <button  type = "button" class = "reply btn btn-default" data-id = "<?= $critic['id'] ?>"><i class = "fas fa-comments"></i></button>
    <?php endif; ?>
    <button type = "submit" name = "signal" class = "btn btn-default"><i class = "fas fa-bolt"></i></span></button>
  </p>
  </form>
  </div>
  </div>

 <div id = "answer">
<?php if (isset($critic['children'])): ?>
    <?php foreach($critic['children'] as $critic): ?>
        <?php require('comments.php'); ?>
    <?php endforeach; ?>
<?php endif; ?>
</div>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
104
1

Ответы 1

Во-первых, я считаю, что вы никогда не устанавливали индекс children, упомянутый в вашем представлении comment.php:

<?php if (isset($critic['children'])): ?>
    <?php foreach($critic['children'] as $critic): ?>
        <?php require('comments.php'); ?>
    <?php endforeach; ?>
<?php endif; ?>

Тогда вам не следует вызывать findAllById два раза подряд для служебных целей.

Если я там, где вы, возможно, я получу все один раз, а затем построю дерево на основе данных, которые вы получите из своего запроса. Это позволяет получить бесконечные возможности вложенных комментариев. Сделать это можно так:

$critics = $this->getAllById($id);//movie id
$childs = []; //Will contain all childs indexed by parent_id
$index = []; //will contain all root critics (no parent)
foreach($critics as &$v){
     if ($v['parent_id'] === 0){ //if no parent, then add to $index
          $indexes[$v['id']] = $v;
     } else{ //else create an array in $childs at index parent_id
         if (!isset($childs[$v['parent_id']])) $childs[$v['parent_id']] = [];
         $childs[$v['parent_id']][] = $v;
     }
}

//Then you can build your result : 
foreach($childs as $id=>&$child){
    $parent= $index[$id] ?? $child[$id] ?? null; // search for the parent of the current child
    if (is_null($parent)) continue; // a parent doesn't exists anymore, we ignor it, but you can throw an exception instead
    if (!isset($parent['children'])) $parent['children'] = [];
    $parent['children'][] = $child;
}
return $index;

Теперь у критика должен быть указатель «дети», в котором перечислены все дети. Это позволяет вам строить дерево комментариев без ограничений. Все, что вам нужно иметь в виду, это правильно установить parent_id при публикации нового комментария.

Сообщите мне, если это решит вашу проблему.

Другие вопросы по теме