diff --git a/src/Controller/BlogController.php b/src/Controller/BlogController.php
index d4f6b1ae..78e69573 100644
--- a/src/Controller/BlogController.php
+++ b/src/Controller/BlogController.php
@@ -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")
*
diff --git a/src/DataFixtures/ContentFixtures.php b/src/DataFixtures/ContentFixtures.php
new file mode 100644
index 00000000..ac732264
--- /dev/null
+++ b/src/DataFixtures/ContentFixtures.php
@@ -0,0 +1,210 @@
+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;
+ }
+
+}
diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/X_AppFixtures.php
similarity index 99%
rename from src/DataFixtures/AppFixtures.php
rename to src/DataFixtures/X_AppFixtures.php
index 9482715e..239b96fc 100644
--- a/src/DataFixtures/AppFixtures.php
+++ b/src/DataFixtures/X_AppFixtures.php
@@ -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);
}
diff --git a/src/Entity/Content.php b/src/Entity/Content.php
index b93dfa40..30393a88 100644
--- a/src/Entity/Content.php
+++ b/src/Entity/Content.php
@@ -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;
}
diff --git a/src/Entity/Field.php b/src/Entity/Field.php
index 16691430..da6fe808 100644
--- a/src/Entity/Field.php
+++ b/src/Entity/Field.php
@@ -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;
+ }
}
diff --git a/src/Migrations/Version20180912145527.php b/src/Migrations/Version20180912145527.php
deleted file mode 100644
index 3520d4a7..00000000
--- a/src/Migrations/Version20180912145527.php
+++ /dev/null
@@ -1,30 +0,0 @@
-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');
- }
-}
diff --git a/src/Migrations/Version20180913184018.php b/src/Migrations/Version20180916083018.php
similarity index 52%
rename from src/Migrations/Version20180913184018.php
rename to src/Migrations/Version20180916083018.php
index c259523f..422c8741 100644
--- a/src/Migrations/Version20180913184018.php
+++ b/src/Migrations/Version20180916083018.php
@@ -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');
diff --git a/src/Repository/ContentRepository.php b/src/Repository/ContentRepository.php
index a3c8df79..6e276465 100644
--- a/src/Repository/ContentRepository.php
+++ b/src/Repository/ContentRepository.php
@@ -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
// */
diff --git a/templates/blog/listing.html.twig b/templates/blog/listing.html.twig
new file mode 100644
index 00000000..c0424336
--- /dev/null
+++ b/templates/blog/listing.html.twig
@@ -0,0 +1,46 @@
+{% extends 'base.html.twig' %}
+
+{% block body_id 'blog_index' %}
+
+{% block main %}
+ {{ dump(records) }}
+ {% for record in records %}
+ {{ dump(record) }}
+ {% endfor %}
+ {#
+
+
+ {{ post.title }}
+
+
+
+
+
+ {{ post.summary|md2html }}
+
+ {{ include('blog/_post_tags.html.twig') }}
+