PDO fetch() y fetchall() Override

Antes de continuar con la creación de un formulario para conservar las notas nuevas en la base de datos, tomemos diez minutos para refactorizar nuestro código actual y discutir el cierre de las API que no son de su propiedad.

Que aprenderemos

  • Refactoring
  • API Ownership

Vamos a controllers/note.php personalizar nuestro propio fetch() en

$note = $db->query('SELECT * FROM mis_notas.notes WHERE id = :id', [
                    'id' => $_GET['id']
                ])->fetch();

Para poder ahorrarnos el código

if (! $note){
    abort(Response::NOT_FOUND);
}

Le podríamos llamar findOrAbort().

Después de hacer los tweak correspondientes nos queda el código así:
En controllers/note.php

<?php 

$config = require('config.php');
$db = new Database($config['database']);

$heading = 'Nota';
$currentUserId = 1;

// dd($_GET['id']); // verificar que tenemos el id de la nota correcto
$note = $db->query('SELECT * FROM mis_notas.notes WHERE id = :id', [
                    'id' => $_GET['id']
                ])->findOrFail();

authorize($note['user_id'] === $currentUserId);

require "views/note.view.php";

En Database.php

<?php 

// Conectarnos a la base de datos MySQL $dsn (data source name) y ejecutar un Query
class Database {
    
    public $connection='';
    public $statement;

    public function __construct($config, $username = 'root', $password = ''){
        $dsn = 'mysql:' . http_build_query($config, '', ';');
        $this->connection = new PDO($dsn, $username, $password, [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
    }

    public function query($query, $params = []){
        $this->statement = $this->connection->prepare($query);
        $this->statement->execute($params);
        return $this;
    }

    public function find(){
        return $this->statement->fetch();
    }

    public function findOrFail(){
        $result = $this->find();

        if (! $result) {
            abort(Response::NOT_FOUND);
        }
        return $result;
    }

}

En functions.php

<?php 

// función Dump and Die
function dd($value) {
    echo "<pre>";
    var_dump($value);
    echo "</pre>"; 
    die(); 
}

// Me regresa true or false
function urlIs($value){
    return $_SERVER['REQUEST_URI'] === $value;
}

// check si el usuario esta autorizado
function authorize($condition, $status = Response::FORBIDDEN){
    if (! $condition) {
    abort($status); 
    }
}

Funciona pero aun tenemos un error al visitar: http://localhost:8888/notes nos falta resolver resolver la llamada a fetchAll() en controllers/notes.php, que les parece que en vez de llamarle fetchAll() le llamamos simplemente get(), no olvidar implementar el metodo en Database.php, entonce en controllers/notes.php:

<?php 

$config = require('config.php');
$db = new Database($config['database']);

$heading = 'Mis Notas';

$notes = $db->query('SELECT id, body, user_id FROM mis_notas.notes WHERE user_id = 1')->get();

require "views/notes.view.php";

Y en Database.php:

public function get(){
	return $this->statement->fetchAll();
}

Nota: Como ahora nosotros controlamos los métodos de fetchAll() y fetch() que antes controlaba solo la instancia de PDO, ahora nosotros controlamos estos métodos! usando nuestro propios.