V tomto úkolu si zprovozníme načítání článků na blog z databáze.
1. Nejprve si v admineru vytvoříme tabulku s názvem blog_post s následující strukturou:
2. Dále ve složce Class vytvoříme soubory BlogPost.php a BlogPostRepository.php s následujícím obsahem:
<?php
class BlogPost
{
private ?int $id;
private string $title;
private string $subtitle;
private string $text;
private string $image;
private string $author;
private DateTime $createdAt;
public function __construct(string $title, string $subtitle, string $text, string $image, string $author, DateTime $createdAt, ?int $id = null)
{
$this->id = $id;
$this->title = $title;
$this->subtitle = $subtitle;
$this->text = $text;
$this->image = $image;
$this->author = $author;
$this->createdAt = $createdAt;
}
public function getId(): int|null
{
return $this->id;
}
public function setId(int|null $id): void
{
$this->id = $id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): void
{
$this->title = $title;
}
public function getSubtitle(): string
{
return $this->subtitle;
}
public function setSubtitle(string $subtitle): void
{
$this->subtitle = $subtitle;
}
public function getText(): string
{
return $this->text;
}
public function setText(string $text): void
{
$this->text = $text;
}
public function getImage(): string
{
return $this->image;
}
public function setImage(string $image): void
{
$this->image = $image;
}
public function getAuthor(): string
{
return $this->author;
}
public function setAuthor(string $author): void
{
$this->author = $author;
}
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
public function setCreatedAt(DateTime $createdAt): void
{
$this->createdAt = $createdAt;
}
}
<?php
class BlogPostRepository
{
private PDO $pdo;
public function __construct()
{
$this->pdo = (new Connection())->getPdo();
}
public function findBlogPostById(int $id): ?BlogPost
{
$stmt = $this->pdo->prepare('SELECT * FROM blog_post WHERE id = :id');
$stmt->execute([':id' => $id]);
$blogPost = $stmt->fetch(PDO::FETCH_ASSOC);
if ($blogPost) {
return new BlogPost($blogPost['title'], $blogPost['subtitle'], $blogPost['text'], $blogPost['image'], $blogPost['author'], new DateTime($blogPost['created_at']), $blogPost['id']);
}
return null;
}
public function findBlogPosts(?int $limit = null): array
{
if ($limit) {
$stmt = $this->pdo->prepare('SELECT * FROM blog_post ORDER BY created_at DESC limit :limit');
$stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
} else {
$stmt = $this->pdo->prepare('SELECT * FROM blog_post ORDER BY created_at DESC');
}
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$blogPosts = [];
foreach ($result as $blogPost) {
$blogPosts[] = new BlogPost($blogPost['title'], $blogPost['subtitle'], $blogPost['text'], $blogPost['image'], $blogPost['author'], new DateTime($blogPost['created_at']), $blogPost['id']);
}
return $blogPosts;
}
public function saveBlogPost(BlogPost $blogPost): BlogPost
{
if (!$blogPost->getId()) {
$stmt = $this->pdo->prepare('INSERT INTO blog_post (title, subtitle, text, image, author, created_at) VALUES (:title, :subtitle, :text, :image, :author, :created_at)');
$stmt->execute([
':title' => $blogPost->getTitle(),
':subtitle' => $blogPost->getSubtitle(),
':text' => $blogPost->getText(),
':image' => $blogPost->getImage(),
':author' => $blogPost->getAuthor(),
':created_at' => $blogPost->getCreatedAt()->format('Y-m-d H:i:s'),
]);
return $this->findBlogPostById($this->pdo->lastInsertId());
} else {
$stmt = $this->pdo->prepare('UPDATE blog_post SET title = :title, subtitle = :subtitle, text = :text, image = :image, author = :author, created_at = :created_at WHERE id = :id');
$stmt->execute([
':title' => $blogPost->getTitle(),
':subtitle' => $blogPost->getSubtitle(),
':text' => $blogPost->getText(),
':image' => $blogPost->getImage(),
':author' => $blogPost->getAuthor(),
':created_at' => $blogPost->getCreatedAt()->format('Y-m-d H:i:s'),
':id' => $blogPost->getId(),
]);
return $this->findBlogPostById($blogPost->getId());
}
}
public function getBlogPostsTotalCount(): int
{
$stmt = $this->pdo->prepare('SELECT count(*) FROM blog_post');
$stmt->execute();
return (int) $stmt->fetchColumn();
}
public function deleteBlogPost(BlogPost $blogPost): int
{
$stmt = $this->pdo->prepare('DELETE FROM blog_post WHERE id = :id');
$stmt->execute([':id' => $blogPost->getId()]);
return $blogPost->getId();
}
}
3. Dále vytvoříme ve složce controller soubor blog.php s následujícím obsahem:
<?php
$blogPostRepository = new BlogPostRepository();
$id = $_GET['id'] ?? null;
if ($id) {
$clanek = $blogPostRepository->findBlogPostById($id);
if ($clanek) {
$sablona = 'blogDetail';
} else {
$sablona = '404';
}
} else {
$sablona = 'blog';
$clanky = $blogPostRepository->findBlogPosts();
}
4. Controller pro blog funguje tak, že se pokusí najít GET parametr id, pokud jej najde, tak bude zobrazovat šablonu pro detail článku a pokud ne, tak vypíše všechny články. Nyní si teda ve složce sablony vytvoříme soubory blog.php a blogDetail.php
<!--blog.php-->
<!-- Page Header-->
<header class="masthead" style="background-image: url('assets/img/home-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="site-heading">
<h1>Blog</h1>
<span class="subheading">Moje články na blogu</span>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content-->
<div class="container px-4 px-lg-5 mt-4">
<div class="row gx-4 gx-lg-5 justify-content-center">
<!-- Blog section -->
<section class="col-md-10 m-a">
<h2>Blog</h2>
<?php
/** @var BlogPost $clanek */
foreach ($clanky as $clanek) :
?>
<!-- Post preview-->
<article class="post-preview">
<a href="?stranka=blog&id=<?php echo $clanek->getId(); ?>">
<div class="row">
<div class="col-md-4">
<img src="<?php echo $clanek->getImage(); ?>" class="img-fluid" />
</div>
<div class="col-md-8">
<h3 class="post-title">
<?php echo $clanek->getTitle(); ?>
</h3>
</div>
<div class="col-12 mt-3">
<h4 class="post-subtitle">
<?php echo $clanek->getSubtitle(); ?>
</h4>
</div>
</div>
</a>
<p class="post-meta">
Posted by
<em><?php echo $clanek->getAuthor(); ?></em>
on <?php echo $clanek->getCreatedAt()->format('j. n. Y'); ?>
</p>
</article>
<!-- Divider-->
<hr class="my-4" />
<?php endforeach; ?>
</section>
</div>
</div>
<!--blogDetail.php-->
<?php
/** @var BlogPost $clanek */
?>
<!-- Page Header-->
<header class="masthead" style="background-image: url('<?php echo $clanek->getImage(); ?>')">
<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="post-heading">
<h1><?php echo $clanek->getTitle(); ?></h1>
<h2 class="subheading">
<?php echo $clanek->getSubtitle(); ?>
</h2>
<span class="meta">
Posted by
<?php echo $clanek->getAuthor(); ?>
dne <?php echo $clanek->getCreatedAt()->format('j. n. Y'); ?>
</span>
</div>
</div>
</div>
</div>
</header>
<!-- Post Content-->
<article 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">
<?php echo $clanek->getText(); ?>
</div>
</div>
</div>
</article>
5. Poslední tři články z blogu zobrazujeme i na domovské stránce, upravíme tedy i controller domů a část šablony s výpisem článků:
<?php
$sablona = 'domu';
$blogPostRepository = new BlogPostRepository();
$pocetClanku = $blogPostRepository->getBlogPostsTotalCount();
$clanky = $blogPostRepository->findBlogPosts(3);
<!-- ! Jedná se pouze o část šablony domu.php (section pro Blog)-->
<!-- Blog section -->
<section class="col-md-10 col-lg-8">
<h2>Blog</h2>
<p>
<?php
echo preloz('homepage.countArticles');
echo $pocetClanku;
?>.
</p>
<?php
/** @var BlogPost $clanek */
foreach ($clanky as $clanek) :
?>
<!-- Post preview-->
<article class="post-preview">
<a href="?stranka=blog&id=<?php echo $clanek->getId(); ?>">
<div class="row">
<div class="col-md-4">
<img src="<?php echo $clanek->getImage(); ?>" class="img-fluid" />
</div>
<div class="col-md-8">
<h3 class="post-title">
<?php echo $clanek->getTitle(); ?>
</h3>
</div>
<div class="col-12 mt-3">
<h4 class="post-subtitle">
<?php echo $clanek->getSubtitle(); ?>
</h4>
</div>
</div>
</a>
<p class="post-meta">
Posted by
<em><?php echo $clanek->getAuthor(); ?></em>
on <?php echo $clanek->getCreatedAt()->format('j. n. Y'); ?>
</p>
</article>
<!-- Divider-->
<hr class="my-4" />
<?php endforeach; ?>
<!-- Pager-->
<div class="d-flex justify-content-end mb-4">
<a class="btn btn-primary text-uppercase" href="?stranka=blog">Starší články →</a>
</div>
</section>