jeudi 30 juin 2016

Wich code to put in controller/model using code igniter (mvc design pattern)

So I've been reading a lot about MVC but I still can't quite get the right way to do some things, so I am bringing here an example of a quite complex function I have in the application I'm developing (since most examples I find are simple coding) that I believe if I get the correct way of doing it, I will have a much better understanding of it. First I'll present it and then I'll talk a bit of what I understand how it should be done.

Books.php: (controller)

// Cria o registro de um livro novo ou adiciona uma avaliação ao livro encontrado
public function index_post() { // fazer os dados virem direto do google mais tarde para evitar usuários de adicionarem o que quiserem via ajax
    $auth_id = $this->post('auth_id');
    $this->user_model->setAuthId($auth_id);
    $loggedIn = $this->user_model->verifyLogin(); // Verifica se o ID de autenticação passado é válido

    if (!$loggedIn) {
        $this->response(array('response' => 'Você deve estar logado para inserir uma nova avaliação.', 'error' => 'Usuário não está logado!'));
    }

    $user_id        = $loggedIn->id;
    $hash           = $this->post('hash');
    $title          = $this->post('title');
    $subtitle       = $this->post('subtitle');
    $description    = $this->post('description');
    $author         = $this->post('author');
    $publisher      = $this->post('publisher');
    $image          = $this->post('image');
    $rating         = $this->post('rating');
    $comment        = $this->post('comment');

    try {
        $this->book_model->setHash($hash);
        $this->book_model->setTitle($title);
        $this->book_model->setSubtitle($subtitle);
        $this->book_model->setDescription($description);
        $this->book_model->setAuthor($author);
        $this->book_model->setPublisher($publisher);
        $this->book_model->setImage($image);
        $this->book_model->setRating($rating);
        $this->review_model->setUserId($user_id);
        $this->review_model->setComment($comment);
    } catch (Exception $error) {
        $this->response(array('response' => 'Algo deu errado devido ao seguinte erro: ' . $error->getMessage(), 'error' => $error->getMessage()));
    }

    $book = $this->book_model->checkRegister();

    if (is_null($book)) {
        $book->id = new StdClass();
        $book->id = $this->book_model->insert();

        if (is_null($book->id)) {
            $this->response(array('response' => 'Algo deu errado no servidor..', 'error' => 'Erro ao inserir o livro!'), 400);
        }
    }

    $this->review_model->setBookId($book->id);
    $this->review_model->setRating($rating);
    $duplicatedReview = $this->review_model->checkReview();

    if ($duplicatedReview) {
        $this->response(array('response' => 'Você já tem uma avaliação cadastrada neste livro. Use a função de editar para atualizá-la.'), 400);
    }

    $review_id = $this->review_model->insert();

    if (is_null($review_id)) {
        $this->response(array('response' => 'Algo deu errado no servidor..', 'error' => 'Erro ao inserir avaliação!'), 400);
    }

    $total_rating = $this->review_model->calculateRating();
    $this->book_model->updateRating($book->id, $total_rating);

    $this->response(array('response' => 'Avaliação adicionada com sucesso!', 'review_id' => $review_id), 200);
}

Book_model.php:

public function checkRegister() {
    $book = $this->db->where('hash', $this->getHash())->get('books')->row();

    if (!is_null($book)) {
        return $book;
    }

    return null;
}

public function insert() {
    $book = [
        'hash'          => $this->getHash(),
        'title'         => $this->getTitle(),
        'subtitle'      => $this->getSubtitle(),
        'description'   => $this->getDescription(),
        'author'        => $this->getAuthor(),
        'publisher'     => $this->getPublisher(),
        'image'         => $this->getImage(),
        'rating'        => $this->getRating()
    ];

    $this->db->insert('books', $book);

    if ($this->db->affected_rows() === 1) {
        return $this->db->insert_id();
    }

    return null;
}

public function updateRating($id, $total_rating) {
    $data['rating'] = $total_rating;

    $this->db->where('id', $id);
    $this->db->update('books', $data);

    if ($this->db->affected_rows() === 1) {
        return $this->find($id);
    }

    return null;
}

Review_model.php

public function checkReview() {
    $this->db->where('user_id', $this->getUserId());
    $this->db->where('book_id', $this->getBookId());
    $result = $this->db->get('reviews');

    if ($result->num_rows() === 0) {
        return false;
    }

    return true;
}

public function insert() {
    $data = [
        'book_id'       => $this->getBookId(),
        'user_id'       => $this->getUserId(),
        'comment'       => $this->getComment(),
        'rating'        => $this->getRating()
    ];

    $this->db->insert('reviews', $data);

    if ($this->db->affected_rows() === 1) {
        $review_id = $this->db->insert_id();
        return $review_id;
    }

    return null;
}

public function calculateRating() { // funcionando
    $ratings = $this->db->where('book_id', $this->getBookId())->select('rating')->get('reviews')->result();
    $ratingsCount = count($ratings);
    $ratingSum = 0;

    foreach ($ratings as $value) {
        $ratingSum += $value->rating;
    }

    $rating = $ratingSum / $ratingsCount;

    return $rating;
}

What this whole thing does is simply check if that book is already registered, if it is registered, it will only add a review to it, if not registered it will register the book and then register the review. After the review is registered the application must update the final rate of the book because of the new rating that was added in the review. This all works like a charm (don't mind the security issues, that's for another question), but I'm sure it's not the way it should be done.

I see everyone says the business logic should go in the model, while the controller only handles the information from the view to the model, but I can't figure out how to apply that in this real example, so I'm seeking this guidance here, if you can guide me through this function and tell me what and where I should be doing everything I would pay you with all the love I have for programming and technology learning <3

Thanks a lot!!!

Aucun commentaire:

Enregistrer un commentaire