Projekt - část 12

Projekt - část 12

V tomto úkolu si zprovozníme ukládání zpráv z kontaktního formuláře do databáze.

1. Ve složce s projektem si vytvoř složku Class a uvnitř ní tři souboru Connection.php, Message.php a MessageRepository.php s následujícím obsahem:

<?php

class Connection
{
  private const DBNAME = 'mujblog';
  private const HOST = 'localhost';
  private const USERNAME = 'mujblog';
  private const PASSWORD = 'mujblog1';
  private PDO $pdo;

  public function __construct()
  {
    $dsn = 'mysql:dbname=' . self::DBNAME . ';host=' . self::HOST . ';charset=utf8mb4';

    try {
      $this->pdo = new PDO($dsn, self::USERNAME, self::PASSWORD);
      $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
      die('Connection failed: ' . $e->getMessage());
    }
  }

  public function getPdo(): PDO
  {
    return $this->pdo;
  }
}
<?php

class Message
{
  private ?int $id;

  private string $name;

  private string $email;

  private string $text;

  public function __construct(string $name, string $email, string $text, ?int $id = null)
  {
    $this->id = $id;
    $this->name = $name;
    $this->email = $email;
    $this->text = $text;
  }


  public function getId(): int|null
  {
    return $this->id;
  }

  public function setId(int|null $id): void
  {
    $this->id = $id;
  }

  public function getName(): string
  {
    return $this->name;
  }

  public function setName(string $name): void
  {
    $this->name = $name;
  }

  public function getEmail(): string
  {
    return $this->email;
  }

  public function setEmail(string $email): void
  {
    $this->email = $email;
  }

  public function getText(): string
  {
    return $this->text;
  }

  public function setText(string $text): void
  {
    $this->text = $text;
  }
}
<?php

class MessageRepository
{
  private PDO $pdo;

  public function __construct()
  {
    $this->pdo = (new Connection())->getPdo();
  }

  public function findMessageById(int $id): ?Message
  {
    $stmt = $this->pdo->prepare('SELECT * FROM message WHERE id = :id');

    $stmt->execute([':id' => $id]);
    $message = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($message) {
      return new Message($message['name'], $message['email'], $message['text'], $message['id']);
    }

    return null;
  }

  public function findMessages(): array
  {
    $stmt = $this->pdo->prepare('SELECT * FROM zprava');
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $messages = [];
    foreach ($result as $message) {
      $messages[] = new Message($message['name'], $message['email'], $message['text'], $message['id']);
    }

    return $messages;
  }

  public function saveMessage(Message $message): Message
  {
    if (!$message->getId()) {
      $stmt = $this->pdo->prepare('INSERT INTO message (name, email, text) VALUES (:name, :email, :text)');
      $stmt->execute([
        ':name' => $message->getName(),
        ':email' => $message->getEmail(),
        ':text' => $message->getText(),
      ]);

      return $this->findMessageById($this->pdo->lastInsertId());
    } else {
      $stmt = $this->pdo->prepare('UPDATE message SET name = :name, email = :email, text = :text WHERE id = :id');
      $stmt->execute([
        ':name' => $message->getName(),
        ':email' => $message->getEmail(),
        ':text' => $message->getText(),
        ':id' => $message->getId(),
      ]);

      return $this->findMessageById($message->getId());
    }
  }
}

2. Soubor Connection.php bude naše obecná třída pro spojení s databází. Soubor Message.php je třída, která nese vlastnosti a metody zprávy zaslané z formuláře. A soubor MessageRepository.php je třída, která slouží pro ukládání a čtení zpráv z databáze. V tuto chvíli není důležité, aby si chápala všechen kód, který je ve třídách obsažení, stačí nám, když třídy dokážeme použít.

3. Aby se nám třídy automaticky načítaly a nemuseli jsme stále všude dělat include nebou require pro každý soubor s třídami, přidáme nahoru do index.php hned za nastartování session následující kód:

spl_autoload_register(function ($className) {
  $class = __DIR__ . '/Class/' . $className . '.php';
  include_once($class);
});

4. Upravíme soubor controller/kontakt.php takto:

<?php

$jmeno = $_POST['jmeno'] ?? null;
$email = $_POST['email'] ?? null;
$text = $_POST['zprava'] ?? null;

if ($jmeno && $email && $text) {
  $messageRepository = new MessageRepository();
  $message = new Message($jmeno, $email, $text);
  $messageRepository->saveMessage($message);

  header("location: ?stranka=kontaktOdeslano");
  exit();
}

$sablona = 'kontakt';

5. Controller nyní funguje tak, že pokud je odeslaný formulář, tak se použijí metody z našich nových tříd pro uložení zprávy do databáze a následně je uživatel přesměrování na stránku kontaktOdeslano. Pokud formulář odeslaný není, tak se jako dříve zobrazí šablona s formulářem.

6. Nyní už nám stačí pouze vytvořit controller kontaktOdeslano.php a šablonu kontaktOdeslano.php s následujícím obsahem:

<?php

$sablona = 'kontaktOdeslano';
<!-- Page Header-->
<header class="masthead" style="background-image: url('assets/img/contact-bg.jpg')">
  <div class="container position-relative px-4 px-lg-5">
    <div class="row gx-4 gx-lg-5 justify-content-center">
      <div class="col-md-10 col-lg-8 col-xl-7">
        <div class="page-heading">
          <h1>Kontakt</h1>
          <span class="subheading">Děkujeme za odeslání zprávy</span>
        </div>
      </div>
    </div>
  </div>
</header>
<!-- Main Content-->
<main class="mb-4">
  <div class="container px-4 px-lg-5">
    <div class="row gx-4 gx-lg-5 justify-content-center">
      <div class="col-md-10 col-lg-8 col-xl-7">
        <div class="my-5 text-center">
          <h2>Vaše zpráva byla uložena.</h2>
        </div>
      </div>
    </div>
  </div>
</main>