This commit is contained in:
Bob den Otter
2018-09-16 10:39:54 +02:00
parent bbfcfe237f
commit 484ea436b3
9 changed files with 421 additions and 80 deletions

View File

@@ -3,9 +3,11 @@
namespace Bolt\Controller;
use Bolt\Entity\Comment;
use Bolt\Entity\Content;
use Bolt\Entity\Post;
use Bolt\Events;
use Bolt\Form\CommentType;
use Bolt\Repository\ContentRepository;
use Bolt\Repository\PostRepository;
use Bolt\Repository\TagRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
@@ -52,6 +54,24 @@ class BlogController extends AbstractController
return $this->render('blog/index.'.$_format.'.twig', ['posts' => $latestPosts]);
}
/**
* @Route("/content", methods={"GET"}, name="content_listing")
* @param ContentRepository $content
* @param Request $request
* @return Response
*/
public function contentShow(ContentRepository $content, Request $request): Response
{
$tag = null;
$page = 1;
if ($request->query->has('tag')) {
$tag = $tags->findOneBy(['name' => $request->query->get('tag')]);
}
$latestContent = $content->findLatest($page, $tag);
return $this->render('blog/listing.html.twig', ['records' => $latestContent]);
}
/**
* @Route("/posts/{slug}", methods={"GET"}, name="blog_post")
*

View File

@@ -0,0 +1,210 @@
<?php
namespace Bolt\DataFixtures;
use Bolt\Entity\Content;
use Bolt\Entity\Field;
use Bolt\Entity\User;
use Bolt\Utils\Slugger;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class ContentFixtures extends Fixture
{
private $passwordEncoder;
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
$this->passwordEncoder = $passwordEncoder;
}
public function load(ObjectManager $manager)
{
$this->loadUsers($manager);
$this->loadContent($manager);
$manager->flush();
}
private function loadUsers(ObjectManager $manager)
{
foreach ($this->getUserData() as [$fullname, $username, $password, $email, $roles]) {
$user = new User();
$user->setFullName($fullname);
$user->setUsername($username);
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
$user->setEmail($email);
$user->setRoles($roles);
$manager->persist($user);
$this->addReference($username, $user);
}
$manager->flush();
}
private function getUserData(): array
{
return [
// $userData = [$fullname, $username, $password, $email, $roles];
['Jane Doe', 'jane_admin', 'kitten', 'jane_admin@symfony.com', ['ROLE_ADMIN']],
['Tom Doe', 'tom_admin', 'kitten', 'tom_admin@symfony.com', ['ROLE_ADMIN']],
['John Doe', 'john_user', 'kitten', 'john_user@symfony.com', ['ROLE_USER']],
];
}
private function loadContent(ObjectManager $manager)
{
foreach (range(1, 15) as $i) {
$author = $this->getReference(['jane_admin', 'tom_admin'][0 === $i ? 0 : random_int(0, 1)]);
$content = new Content();
$content->setContenttype($this->getRandomContentType());
$content->setAuthor($author);
$content->setStatus($this->getRandomStatus());
$content->setCreatedAt(new \DateTime('now - ' . rand(1, 9000) . 'hours'));
$content->setModifiedAt(new \DateTime('now - ' . rand(1, 9000) . 'hours'));
$content->setPublishedAt(new \DateTime('now - ' . rand(1, 9000) . 'hours'));
$content->setDepublishedAt(new \DateTime('now - ' . rand(1, 9000) . 'hours'));
/**
* * id
* contenttype `['pages', 'entries', 'homepage', 'blocks', 'showcases']`
* author_id
* status `['published', 'held', 'draft', 'timed']`
* created_at
* modified_at
* published_at
* depublished_at
*/
foreach (range(1, 5) as $i) {
$fieldtype = $this->getRandomFieldType();
$field = new Field();
$field->setName('title');
$field->setType($fieldtype);
$field->setValue($this->getValuesforFieldType($fieldtype));
$field->setSortorder($i * 5);
$content->addField($field);
/**
* * id
* content_id
* name
* type `['text', 'textarea', 'html', 'markdown', 'image']`
* value (JSON)
* parent_id
* sortorder
* (later) locale
* (later) version
*/
}
$manager->persist($content);
}
}
private function getRandomContentType()
{
$contentTypes = ['pages', 'entries', 'homepage', 'blocks', 'showcases'];
return $contentTypes[array_rand($contentTypes)];
}
private function getRandomFieldType()
{
$fieldTypes = ['slug', 'text', 'textarea', 'html', 'markdown', 'image'];
return $fieldTypes[array_rand($fieldTypes)];
}
private function getRandomStatus()
{
$statuses = ['published', 'held', 'draft', 'timed'];
return $statuses[array_rand($statuses)];
}
private function getValuesforFieldType($type)
{
switch ($type) {
case 'html':
case 'textarea':
case 'markdown':
$data = ['value' => $this->getRandomText() ];
break;
case 'image':
$data = ['filename' => 'kitten.jpg', 'alt' => 'A cute kitten'];
break;
case 'slug':
$data = ['value' => Slugger::slugify($this->getRandomPhrase()) ];
break;
default :
$data = ['value' => $this->getRandomPhrase() ];
}
return $data;
}
private function getRandomPhrase(): string
{
$phrases = $this->getPhrases();
return $phrases[array_rand($phrases)];
}
private function getPhrases(): array
{
return [
'Lorem ipsum dolor sit amet consectetur adipiscing elit',
'Pellentesque vitae velit ex',
'Mauris dapibus risus quis suscipit vulputate',
'Eros diam egestas libero eu vulputate risus',
'In hac habitasse platea dictumst',
'Morbi tempus commodo mattis',
'Ut suscipit posuere justo at vulputate',
'Ut eleifend mauris et risus ultrices egestas',
'Aliquam sodales odio id eleifend tristique',
'Urna nisl sollicitudin id varius orci quam id turpis',
'Nulla porta lobortis ligula vel egestas',
'Curabitur aliquam euismod dolor non ornare',
'Sed varius a risus eget aliquam',
'Nunc viverra elit ac laoreet suscipit',
'Pellentesque et sapien pulvinar consectetur',
'Ubi est barbatus nix',
'Abnobas sunt hilotaes de placidus vita',
'Ubi est audax amicitia',
'Eposs sunt solems de superbus fortis',
'Vae humani generis',
'Diatrias tolerare tanquam noster caesium',
'Teres talis saepe tractare de camerarius flavum sensorem',
'Silva de secundus galatae demitto quadra',
'Sunt accentores vitare salvus flavum parses',
'Potus sensim ad ferox abnoba',
'Sunt seculaes transferre talis camerarius fluctuies',
'Era brevis ratione est',
'Sunt torquises imitari velox mirabilis medicinaes',
'Mineralis persuadere omnes finises desiderium',
'Bassus fatalis classiss virtualiter transferre de flavum',
];
}
private function getRandomText(int $maxLength = 255): string
{
$phrases = $this->getPhrases();
shuffle($phrases);
while (mb_strlen($text = implode('. ', $phrases).'.') > $maxLength) {
array_pop($phrases);
}
return $text;
}
}

View File

@@ -11,7 +11,7 @@ use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class AppFixtures extends Fixture
class X_AppFixtures extends Fixture
{
private $passwordEncoder;
@@ -22,7 +22,7 @@ class AppFixtures extends Fixture
public function load(ObjectManager $manager)
{
$this->loadUsers($manager);
// $this->loadUsers($manager);
$this->loadTags($manager);
$this->loadPosts($manager);
}

View File

@@ -2,6 +2,8 @@
namespace Bolt\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
@@ -10,6 +12,8 @@ use Doctrine\ORM\Mapping as ORM;
*/
class Content
{
public const NUM_ITEMS = 10;
/**
* @ORM\Id()
* @ORM\GeneratedValue()
@@ -23,9 +27,12 @@ class Content
private $contenttype;
/**
* @ORM\Column(type="integer")
* @var User
*
* @ORM\ManyToOne(targetEntity="Bolt\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
private $author_id;
private $author;
/**
* @ORM\Column(type="string", length=191)
@@ -35,22 +42,42 @@ class Content
/**
* @ORM\Column(type="datetime")
*/
private $created_at;
private $createdAt;
/**
* @ORM\Column(type="datetime")
*/
private $modified_at;
private $modifiedAt;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $published_at;
private $publishedAt;
/**
* @ORM\Column(type="datetime")
*/
private $depublished_at;
private $depublishedAt;
/**
* @ORM\OneToMany(targetEntity="Bolt\Entity\Field", mappedBy="content", orphanRemoval=true, cascade={"persist"})
*/
private $fields;
public function __toString(): string
{
return (string) "Content # " . $this->getId();
}
public function __construct()
{
$this->createdAt = new \DateTime();
$this->modifiedAt = new \DateTime();
$this->publishedAt = new \DateTime();
$this->depublishedAt = new \DateTime();
$this->fields = new ArrayCollection();
}
public function getId(): ?int
{
@@ -69,16 +96,14 @@ class Content
return $this;
}
public function getAuthorId(): ?int
public function getAuthor(): User
{
return $this->author_id;
return $this->author;
}
public function setAuthorId(int $author_id): self
public function setAuthor(?User $author): void
{
$this->author_id = $author_id;
return $this;
$this->author = $author;
}
public function getStatus(): ?string
@@ -95,48 +120,79 @@ class Content
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->created_at = $created_at;
$this->createdAt = $createdAt;
return $this;
}
public function getModifiedAt(): ?\DateTimeInterface
{
return $this->modified_at;
return $this->modifiedAt;
}
public function setModifiedAt(\DateTimeInterface $modified_at): self
public function setModifiedAt(\DateTimeInterface $modifiedAt): self
{
$this->modified_at = $modified_at;
$this->modifiedAt = $modifiedAt;
return $this;
}
public function getPublishedAt(): ?\DateTimeInterface
{
return $this->published_at;
return $this->publishedAt;
}
public function setPublishedAt(?\DateTimeInterface $published_at): self
public function setPublishedAt(?\DateTimeInterface $publishedAt): self
{
$this->published_at = $published_at;
$this->publishedAt = $publishedAt;
return $this;
}
public function getDepublishedAt(): ?\DateTimeInterface
{
return $this->depublished_at;
return $this->depublishedAt;
}
public function setDepublishedAt(\DateTimeInterface $depublished_at): self
public function setDepublishedAt(\DateTimeInterface $depublishedAt): self
{
$this->depublished_at = $depublished_at;
$this->depublishedAt = $depublishedAt;
return $this;
}
/**
* @return Collection|Field[]
*/
public function getFields(): Collection
{
return $this->fields;
}
public function addField(Field $field): self
{
if (!$this->fields->contains($field)) {
$this->fields[] = $field;
$field->setContent($this);
}
return $this;
}
public function removeField(Field $field): self
{
if ($this->fields->contains($field)) {
$this->fields->removeElement($field);
// set the owning side to null (unless already changed)
if ($field->getContent() === $this) {
$field->setContent(null);
}
}
return $this;
}

View File

@@ -38,7 +38,7 @@ class Field
private $value = [];
/**
* @ORM\Column(type="integer")
* @ORM\Column(type="integer", nullable=true)
*/
private $parent_id;
@@ -57,6 +57,17 @@ class Field
*/
private $version;
/**
* @ORM\ManyToOne(targetEntity="Bolt\Entity\Content", inversedBy="fields")
* @ORM\JoinColumn(nullable=false)
*/
private $content;
public function __toString(): string
{
return implode(", " , $this->getValue());
}
public function getId(): ?int
{
return $this->id;
@@ -157,4 +168,16 @@ class Field
return $this;
}
public function getContent(): ?Content
{
return $this->content;
}
public function setContent(?Content $content): self
{
$this->content = $content;
return $this;
}
}

View File

@@ -1,30 +0,0 @@
<?php declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20180912145527 extends AbstractMigration
{
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('CREATE TABLE content (id INT AUTO_INCREMENT NOT NULL, contenttype VARCHAR(191) NOT NULL, author_id INT NOT NULL, status VARCHAR(191) NOT NULL, created_at DATETIME NOT NULL, modified_at DATETIME NOT NULL, published_at DATETIME DEFAULT NULL, depublished_at DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE field (id INT AUTO_INCREMENT NOT NULL, content_id INT NOT NULL, name VARCHAR(191) NOT NULL, type VARCHAR(191) NOT NULL, value LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\', parent_id INT NOT NULL, sortorder INT NOT NULL, locale VARCHAR(191) DEFAULT NULL, version INT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('DROP TABLE content');
$this->addSql('DROP TABLE field');
}
}

View File

@@ -8,35 +8,27 @@ use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20180913184018 extends AbstractMigration
final class Version20180916083018 extends AbstractMigration
{
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE symfony_demo_comment DROP FOREIGN KEY FK_53AD8F834B89032C');
$this->addSql('ALTER TABLE symfony_demo_post_tag DROP FOREIGN KEY FK_6ABC1CC44B89032C');
$this->addSql('ALTER TABLE symfony_demo_post_tag DROP FOREIGN KEY FK_6ABC1CC4BAD26311');
$this->addSql('ALTER TABLE symfony_demo_comment DROP FOREIGN KEY FK_53AD8F83F675F31B');
$this->addSql('ALTER TABLE symfony_demo_post DROP FOREIGN KEY FK_58A92E65F675F31B');
$this->addSql('CREATE TABLE bolt_post (id INT AUTO_INCREMENT NOT NULL, author_id INT NOT NULL, title VARCHAR(255) NOT NULL, slug VARCHAR(255) NOT NULL, summary VARCHAR(255) NOT NULL, content LONGTEXT NOT NULL, published_at DATETIME NOT NULL, INDEX IDX_807F8D56F675F31B (author_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_post_tag (post_id INT NOT NULL, tag_id INT NOT NULL, INDEX IDX_C7690CD4B89032C (post_id), INDEX IDX_C7690CDBAD26311 (tag_id), PRIMARY KEY(post_id, tag_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_tag (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(190) NOT NULL, UNIQUE INDEX UNIQ_96D0BCE85E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_user (id INT AUTO_INCREMENT NOT NULL, full_name VARCHAR(255) NOT NULL, username VARCHAR(190) NOT NULL, email VARCHAR(190) NOT NULL, password VARCHAR(255) NOT NULL, roles LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\', UNIQUE INDEX UNIQ_57663792F85E0677 (username), UNIQUE INDEX UNIQ_57663792E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_content (id INT AUTO_INCREMENT NOT NULL, contenttype VARCHAR(191) NOT NULL, author_id INT NOT NULL, status VARCHAR(191) NOT NULL, created_at DATETIME NOT NULL, modified_at DATETIME NOT NULL, published_at DATETIME DEFAULT NULL, depublished_at DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_field (id INT AUTO_INCREMENT NOT NULL, content_id INT NOT NULL, name VARCHAR(191) NOT NULL, type VARCHAR(191) NOT NULL, value LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\', parent_id INT NOT NULL, sortorder INT NOT NULL, locale VARCHAR(191) DEFAULT NULL, version INT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_content (id INT AUTO_INCREMENT NOT NULL, author_id INT NOT NULL, contenttype VARCHAR(191) NOT NULL, status VARCHAR(191) NOT NULL, created_at DATETIME NOT NULL, modified_at DATETIME NOT NULL, published_at DATETIME DEFAULT NULL, depublished_at DATETIME NOT NULL, INDEX IDX_F5AB2E9CF675F31B (author_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_field (id INT AUTO_INCREMENT NOT NULL, content_id INT NOT NULL, name VARCHAR(191) NOT NULL, type VARCHAR(191) NOT NULL, value LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\', parent_id INT DEFAULT NULL, sortorder INT NOT NULL, locale VARCHAR(191) DEFAULT NULL, version INT DEFAULT NULL, INDEX IDX_4A2EBBE584A0A3ED (content_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE bolt_comment (id INT AUTO_INCREMENT NOT NULL, post_id INT NOT NULL, author_id INT NOT NULL, content LONGTEXT NOT NULL, published_at DATETIME NOT NULL, INDEX IDX_9F1A4C594B89032C (post_id), INDEX IDX_9F1A4C59F675F31B (author_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
$this->addSql('ALTER TABLE bolt_post ADD CONSTRAINT FK_807F8D56F675F31B FOREIGN KEY (author_id) REFERENCES bolt_user (id)');
$this->addSql('ALTER TABLE bolt_post_tag ADD CONSTRAINT FK_C7690CD4B89032C FOREIGN KEY (post_id) REFERENCES bolt_post (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE bolt_post_tag ADD CONSTRAINT FK_C7690CDBAD26311 FOREIGN KEY (tag_id) REFERENCES bolt_tag (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE bolt_content ADD CONSTRAINT FK_F5AB2E9CF675F31B FOREIGN KEY (author_id) REFERENCES bolt_user (id)');
$this->addSql('ALTER TABLE bolt_field ADD CONSTRAINT FK_4A2EBBE584A0A3ED FOREIGN KEY (content_id) REFERENCES bolt_content (id)');
$this->addSql('ALTER TABLE bolt_comment ADD CONSTRAINT FK_9F1A4C594B89032C FOREIGN KEY (post_id) REFERENCES bolt_post (id)');
$this->addSql('ALTER TABLE bolt_comment ADD CONSTRAINT FK_9F1A4C59F675F31B FOREIGN KEY (author_id) REFERENCES bolt_user (id)');
$this->addSql('DROP TABLE symfony_demo_comment');
$this->addSql('DROP TABLE symfony_demo_post');
$this->addSql('DROP TABLE symfony_demo_post_tag');
$this->addSql('DROP TABLE symfony_demo_tag');
$this->addSql('DROP TABLE symfony_demo_user');
}
public function down(Schema $schema) : void
@@ -48,17 +40,9 @@ final class Version20180913184018 extends AbstractMigration
$this->addSql('ALTER TABLE bolt_comment DROP FOREIGN KEY FK_9F1A4C594B89032C');
$this->addSql('ALTER TABLE bolt_post_tag DROP FOREIGN KEY FK_C7690CDBAD26311');
$this->addSql('ALTER TABLE bolt_post DROP FOREIGN KEY FK_807F8D56F675F31B');
$this->addSql('ALTER TABLE bolt_content DROP FOREIGN KEY FK_F5AB2E9CF675F31B');
$this->addSql('ALTER TABLE bolt_comment DROP FOREIGN KEY FK_9F1A4C59F675F31B');
$this->addSql('CREATE TABLE symfony_demo_comment (id INT AUTO_INCREMENT NOT NULL, post_id INT NOT NULL, author_id INT NOT NULL, content LONGTEXT NOT NULL COLLATE utf8mb4_unicode_ci, published_at DATETIME NOT NULL, INDEX IDX_53AD8F834B89032C (post_id), INDEX IDX_53AD8F83F675F31B (author_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE symfony_demo_post (id INT AUTO_INCREMENT NOT NULL, author_id INT NOT NULL, title VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, slug VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, summary VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, content LONGTEXT NOT NULL COLLATE utf8mb4_unicode_ci, published_at DATETIME NOT NULL, INDEX IDX_58A92E65F675F31B (author_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE symfony_demo_post_tag (post_id INT NOT NULL, tag_id INT NOT NULL, INDEX IDX_6ABC1CC44B89032C (post_id), INDEX IDX_6ABC1CC4BAD26311 (tag_id), PRIMARY KEY(post_id, tag_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE symfony_demo_tag (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(190) NOT NULL COLLATE utf8mb4_unicode_ci, UNIQUE INDEX UNIQ_4D5855405E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE symfony_demo_user (id INT AUTO_INCREMENT NOT NULL, full_name VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, username VARCHAR(190) NOT NULL COLLATE utf8mb4_unicode_ci, email VARCHAR(190) NOT NULL COLLATE utf8mb4_unicode_ci, password VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, roles LONGTEXT NOT NULL COLLATE utf8mb4_unicode_ci COMMENT \'(DC2Type:json)\', UNIQUE INDEX UNIQ_8FB094A1F85E0677 (username), UNIQUE INDEX UNIQ_8FB094A1E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('ALTER TABLE symfony_demo_comment ADD CONSTRAINT FK_53AD8F834B89032C FOREIGN KEY (post_id) REFERENCES symfony_demo_post (id)');
$this->addSql('ALTER TABLE symfony_demo_comment ADD CONSTRAINT FK_53AD8F83F675F31B FOREIGN KEY (author_id) REFERENCES symfony_demo_user (id)');
$this->addSql('ALTER TABLE symfony_demo_post ADD CONSTRAINT FK_58A92E65F675F31B FOREIGN KEY (author_id) REFERENCES symfony_demo_user (id)');
$this->addSql('ALTER TABLE symfony_demo_post_tag ADD CONSTRAINT FK_6ABC1CC44B89032C FOREIGN KEY (post_id) REFERENCES symfony_demo_post (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE symfony_demo_post_tag ADD CONSTRAINT FK_6ABC1CC4BAD26311 FOREIGN KEY (tag_id) REFERENCES symfony_demo_tag (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE bolt_field DROP FOREIGN KEY FK_4A2EBBE584A0A3ED');
$this->addSql('DROP TABLE bolt_post');
$this->addSql('DROP TABLE bolt_post_tag');
$this->addSql('DROP TABLE bolt_tag');

View File

@@ -3,7 +3,11 @@
namespace Bolt\Repository;
use Bolt\Entity\Content;
use Bolt\Entity\Tag;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
@@ -19,6 +23,34 @@ class ContentRepository extends ServiceEntityRepository
parent::__construct($registry, Content::class);
}
public function findLatest(int $page = 1, Tag $tag = null): Pagerfanta
{
$qb = $this->createQueryBuilder('p')
->addSelect('a') //, 't'
->innerJoin('p.author', 'a')
// ->leftJoin('p.tags', 't')
->where('p.publishedAt <= :now')
->orderBy('p.publishedAt', 'DESC')
->setParameter('now', new \DateTime());
// if (null !== $tag) {
// $qb->andWhere(':tag MEMBER OF p.tags')
// ->setParameter('tag', $tag);
// }
return $this->createPaginator($qb->getQuery(), $page);
}
private function createPaginator(Query $query, int $page): Pagerfanta
{
$paginator = new Pagerfanta(new DoctrineORMAdapter($query));
$paginator->setMaxPerPage(Content::NUM_ITEMS);
$paginator->setCurrentPage($page);
return $paginator;
}
// /**
// * @return Content[] Returns an array of Content objects
// */

View File

@@ -0,0 +1,46 @@
{% extends 'base.html.twig' %}
{% block body_id 'blog_index' %}
{% block main %}
{{ dump(records) }}
{% for record in records %}
{{ dump(record) }}
{% endfor %}
{#
<article class="post">
<h2>
<a href="{{ path('blog_post', {slug: post.slug}) }}">
{{ post.title }}
</a>
</h2>
<p class="post-metadata">
<span class="metadata"><i class="fa fa-calendar"></i> {{ post.publishedAt|localizeddate('long', 'medium', null, 'UTC') }}</span>
<span class="metadata"><i class="fa fa-user"></i> {{ post.author.fullName }}</span>
</p>
{{ post.summary|md2html }}
{{ include('blog/_post_tags.html.twig') }}
</article>
{% else %}
<div class="well">{{ 'post.no_posts_found'|trans }}</div>
{% endfor %}
#}
{% if records.haveToPaginate %}
<div class="navigation text-center">
{{ pagerfanta(records, 'twitter_bootstrap3_translated', {routeName: 'blog_index_paginated', routeParams: app.request.query.all}) }}
</div>
{% endif %}
{% endblock %}
{% block sidebar %}
{{ parent() }}
{{ show_source_code(_self) }}
{{ include('blog/_rss.html.twig') }}
{% endblock %}