Dysponujemy już tabelą, w której będziemy przechowywać nasze komentarze oraz modelem z nią skojarzonym, w którym mamy już zdefiniowane relacje z tabelami artykułów (Posts) i użytkowników (Users). Teraz pora przygotować kontroler, który zapewni nam sprawne dodawanie wpisów do tabeli.

Plik kontrolera został utworzony razem z innymi w chwili, gdy tworzyliśmy model. Znajdziemy go w app/Http/Controllers/CommentController.php, a w nim zadeklarowane wszystkie niezbędne metody. Teraz wystarczy je tylko wypełnić czymś sprytnym. W naszym przypadku realnie będziemy korzystali tylko z jednej metody, którą będziemy zapisywali komentarz w tabeli. Z poniższego zestawu w tej chwili zajmiemy się tylko metodą store().

<?php

namespace App\Http\Controllers;

use App\Models\Comment;
use Illuminate\Http\Request;

class CommentController extends Controller {

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index() {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create() {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request) {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Comment  $comment
     * @return \Illuminate\Http\Response
     */
    public function show(Test $comment) {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Comment  $comment
     * @return \Illuminate\Http\Response
     */
    public function edit(Comment $comment) {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Comment  $comment
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Comment $comment) {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Comment  $comment
     * @return \Illuminate\Http\Response
     */
    public function destroy(Comment $comment) {
        //
    }

}

Zakładamy, że dodawać komentarze będą mogli tylko zalogowani użytkownicy. Zakładamy również, że z formularza na stronie, do metody store() będą trafiały odpowiednie dane. Obowiązkowo muszą to być:

  1. body - treść komentarza,
  2. parent_id - id komentarza, do którego dodawany komentarz jest odpowiedzią, domyślnie null,
  3. post_id - id artykułu, do którego kierowany jest komentarz.

Jeżeli parent_id będzie miał wartość null, to przesłany komentarz będzie początkiem nowego wątku.

    public function store(Request $request) {
        //walidacja wejścia
        $this->validate($request, [
            'body' => 'required',
            'post_id' => 'integer',
            'parent_id' => 'integer|nullable',
        ]);

        $attr['body'] = strip_tags($request->body); //usuwamy tagi html - tylko czysty tekst
        $attr['user_id'] = \Auth::id(); //id zalogowanego użytkownika    
        $attr['post_id'] = $request->post_id; //id komentowanego artykułu

        //Mamy wszystkie dane? Tworzymy nowy rekord…
        $comment = Comment::create($attr);

        //Teraz pora na określenie poziomu komentarza
        if (!is_null($request->parent_id)) {
            $parent = Comment::findOrFail($request->parent_id); //to jest odpowiedź do komentarza $parent
            $comment->appendToNode($parent)->save(); //aktualizacja pozycji w drzewie odpowiedzi
        }

        return Response::json('success', 200);

    }

Jeżeli cały proces opisany w tej metodzie przebiegnie poprawnie, to do przeglądarki klienta zostanie zwrócony kod 200, w przypadku jakiegokolwiek problemu zostanie zwrócony kod błędu (prawdopodbnie 404 lub 500), który należy obsłużyć po stronie klienta.

Realnie całą pracę związaną z ulokowaniem nowego komentarza w drzewie odpowiedzi załatwia $comment->appendToNode($parent)->save() - jeżeli z żądaniem trafia do metody identyfikator parent_id i istnieje dla niego odpowiedni rekord w tabeli, to dzięki temu poleceniu automagicznie aktualizuje się cała struktura wątku powiązanego. Należy pamiętać o tym, że bieżący wpis może być np. odpowiedzią do odpowiedzi do odpowiedzi. Nie okrślając limitu zagłebienia możemy mieć do czynienienia z naprawdę zagmatwanym układem.

Dzięki zastosowaniu pakietu Nested Set cały ten proces został radykalnie uproszczony, chociaż prawdziwe korzyści pojawią się dopiero w procesie pobierania i wyświetlania komentarzy. Ale to już w następnym artykule.


blog comments powered by Disqus