This commit is contained in:
Bob den Otter
2018-09-16 21:07:01 +02:00
parent 04fb4e7a5f
commit 77df2df539
8 changed files with 62 additions and 322 deletions

View File

@@ -14,14 +14,14 @@ final class ContentTypeFactory
/**
* @param string $name
* @param Bag $config
* @param Bag $contenttypesconfig
*
* @return ContentType
*/
public static function get(string $name, Bag $config)
public static function get(string $name, Bag $contenttypesconfig)
{
$ct = ContentType::from($config[$name]);
$contentType = ContentType::from($contenttypesconfig[$name]);
return $ct;
return $contentType;
}
}

View File

@@ -59,13 +59,10 @@ final class BlogController extends AbstractController
*/
public function contentListing(ContentRepository $content, Request $request): Response
{
$tag = null;
$page = 1;
if ($request->query->has('tag')) {
$tag = $tags->findOneBy(['name' => $request->query->get('tag')]);
}
$page = (int) $request->query->get('page', 1);
/** @var Content $records */
$records = $content->findLatest($page, $tag);
$records = $content->findLatest($page);
return $this->render('blog/listing.html.twig', ['records' => $records]);
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Bolt\DataFixtures;
use Bolt\Configuration\Config;
use Bolt\Entity\Content;
use Bolt\Entity\Field;
use Bolt\Entity\User;
@@ -21,10 +22,14 @@ class ContentFixtures extends Fixture
/** @var \Faker\Generator */
private $faker;
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
/** @var Config */
private $config;
public function __construct(UserPasswordEncoderInterface $passwordEncoder, Config $config)
{
$this->passwordEncoder = $passwordEncoder;
$this->faker = Factory::create();
$this->config = $config->get('contenttypes');
}
public function load(ObjectManager $manager)
@@ -64,81 +69,47 @@ class ContentFixtures extends Fixture
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)]);
foreach ($this->config as $contentType) {
$amount = $contentType['singleton'] ? 1 : 15;
$content = new Content();
$content->setContenttype($this->getRandomContentType());
$content->setAuthor($author);
$content->setStatus($this->getRandomStatus());
$content->setCreatedAt($this->faker->dateTimeBetween('-1 year'));
$content->setModifiedAt($this->faker->dateTimeBetween('-1 year'));
$content->setPublishedAt($this->faker->dateTimeBetween('-1 year'));
$content->setDepublishedAt($this->faker->dateTimeBetween('-1 year'));
foreach (range(1, $amount) as $i) {
$author = $this->getReference(['jane_admin', 'tom_admin'][0 === $i ? 0 : random_int(0, 1)]);
/*
* * id
* contenttype `['pages', 'entries', 'homepage', 'blocks', 'showcases']`
* author_id
* status `['published', 'held', 'draft', 'timed']`
* created_at
* modified_at
* published_at
* depublished_at
*/
$content = new Content();
$content->setContenttype($contentType['slug']);
$content->setAuthor($author);
$content->setStatus($this->getRandomStatus());
$content->setCreatedAt($this->faker->dateTimeBetween('-1 year'));
$content->setModifiedAt($this->faker->dateTimeBetween('-1 year'));
$content->setPublishedAt($this->faker->dateTimeBetween('-1 year'));
$content->setDepublishedAt($this->faker->dateTimeBetween('-1 year'));
foreach (range(1, 5) as $i) {
$fieldtype = $this->getRandomFieldType();
$sortorder = 1;
foreach ($contentType->fields as $name => $fieldType) {
$field = new Field();
$field->setName($name);
$field->setType($fieldType['type']);
$field->setValue($this->getValuesforFieldType($fieldType));
$field->setSortorder($sortorder++ * 5);
$field = new Field();
$field->setName($this->faker->word());
$field->setType($fieldtype);
$field->setValue($this->getValuesforFieldType($fieldtype));
$field->setSortorder($i * 5);
$content->addField($field);
}
$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);
}
$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'];
$statuses = ['published', 'published', 'published', 'held', 'draft', 'timed'];
return $statuses[array_rand($statuses)];
}
private function getValuesforFieldType($type)
private function getValuesforFieldType($field)
{
switch ($type) {
switch ($field['type']) {
case 'html':
case 'textarea':
case 'markdown':

View File

@@ -1,232 +0,0 @@
<?php
declare(strict_types=1);
namespace Bolt\DataFixtures;
use Bolt\Entity\Comment;
use Bolt\Entity\Post;
use Bolt\Entity\Tag;
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 X_AppFixtures extends Fixture
{
private $passwordEncoder;
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
$this->passwordEncoder = $passwordEncoder;
}
public function load(ObjectManager $manager)
{
// $this->loadUsers($manager);
$this->loadTags($manager);
$this->loadPosts($manager);
}
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 loadTags(ObjectManager $manager)
{
foreach ($this->getTagData() as $index => $name) {
$tag = new Tag();
$tag->setName($name);
$manager->persist($tag);
$this->addReference('tag-' . $name, $tag);
}
$manager->flush();
}
private function loadPosts(ObjectManager $manager)
{
foreach ($this->getPostData() as [$title, $slug, $summary, $content, $publishedAt, $author, $tags]) {
$post = new Post();
$post->setTitle($title);
$post->setSlug($slug);
$post->setSummary($summary);
$post->setContent($content);
$post->setPublishedAt($publishedAt);
$post->setAuthor($author);
$post->addTag(...$tags);
foreach (range(1, 5) as $i) {
$comment = new Comment();
$comment->setAuthor($this->getReference('john_user'));
$comment->setContent($this->getRandomText(random_int(255, 512)));
$comment->setPublishedAt(new \DateTime('now + ' . $i . 'seconds'));
$post->addComment($comment);
}
$manager->persist($post);
}
$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 getTagData(): array
{
return [
'lorem',
'ipsum',
'consectetur',
'adipiscing',
'incididunt',
'labore',
'voluptate',
'dolore',
'pariatur',
];
}
private function getPostData()
{
$posts = [];
foreach ($this->getPhrases() as $i => $title) {
// $postData = [$title, $slug, $summary, $content, $publishedAt, $author, $tags, $comments];
$posts[] = [
$title,
Slugger::slugify($title),
$this->getRandomText(),
$this->getPostContent(),
new \DateTime('now - ' . $i . 'days'),
// Ensure that the first post is written by Jane Doe to simplify tests
$this->getReference(['jane_admin', 'tom_admin'][0 === $i ? 0 : random_int(0, 1)]),
$this->getRandomTags(),
];
}
return $posts;
}
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;
}
private function getPostContent(): string
{
return <<<'MARKDOWN'
Lorem ipsum dolor sit amet consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et **dolore magna aliqua**: Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
* Ut enim ad minim veniam
* Quis nostrud exercitation *ullamco laboris*
* Nisi ut aliquip ex ea commodo consequat
Praesent id fermentum lorem. Ut est lorem, fringilla at accumsan nec, euismod at
nunc. Aenean mattis sollicitudin mattis. Nullam pulvinar vestibulum bibendum.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Fusce nulla purus, gravida ac interdum ut, blandit eget ex. Duis a
luctus dolor.
Integer auctor massa maximus nulla scelerisque accumsan. *Aliquam ac malesuada*
ex. Pellentesque tortor magna, vulputate eu vulputate ut, venenatis ac lectus.
Praesent ut lacinia sem. Mauris a lectus eget felis mollis feugiat. Quisque
efficitur, mi ut semper pulvinar, urna urna blandit massa, eget tincidunt augue
nulla vitae est.
Ut posuere aliquet tincidunt. Aliquam erat volutpat. **Class aptent taciti**
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi
arcu orci, gravida eget aliquam eu, suscipit et ante. Morbi vulputate metus vel
ipsum finibus, ut dapibus massa feugiat. Vestibulum vel lobortis libero. Sed
tincidunt tellus et viverra scelerisque. Pellentesque tincidunt cursus felis.
Sed in egestas erat.
Aliquam pulvinar interdum massa, vel ullamcorper ante consectetur eu. Vestibulum
lacinia ac enim vel placerat. Integer pulvinar magna nec dui malesuada, nec
congue nisl dictum. Donec mollis nisl tortor, at congue erat consequat a. Nam
tempus elit porta, blandit elit vel, viverra lorem. Sed sit amet tellus
tincidunt, faucibus nisl in, aliquet libero.
MARKDOWN;
}
private function getRandomTags(): array
{
$tagNames = $this->getTagData();
shuffle($tagNames);
$selectedTags = \array_slice($tagNames, 0, random_int(2, 4));
return array_map(function ($tagName) {
return $this->getReference('tag-' . $tagName);
}, $selectedTags);
}
}

View File

@@ -83,11 +83,6 @@ class Content
*/
private $contentTypeDefinition;
public function __toString(): string
{
return (string) 'Content # ' . $this->getId();
}
public function __construct()
{
$this->createdAt = new \DateTime();
@@ -97,6 +92,22 @@ class Content
$this->fields = new ArrayCollection();
}
public function __toString(): string
{
return (string) 'Content # ' . $this->getId();
}
public function __call($name, $arguments)
{
foreach ($this->fields as $field) {
if ($field->getName() === $name) {
return $field;
}
}
return $this->fields->get($name);
}
public function getId(): ?int
{
return $this->id;
@@ -125,7 +136,7 @@ class Content
public function setContenttype(string $contenttype): self
{
$this->contentType = $contenttype . 'foo';
$this->contentType = $contenttype;
return $this;
}

View File

@@ -84,7 +84,7 @@ class Field
{
$contentTypeDefinition = $this->getContent()->getDefinition();
$this->fieldTypeDefinition = FieldTypeFactory::get($this->getType(), $contentTypeDefinition);
$this->fieldTypeDefinition = FieldTypeFactory::get($this->getName(), $contentTypeDefinition);
}
public function getDefinition(): FieldType

View File

@@ -5,7 +5,6 @@ declare(strict_types=1);
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;
@@ -25,21 +24,15 @@ class ContentRepository extends ServiceEntityRepository
parent::__construct($registry, Content::class);
}
public function findLatest(int $page = 1, Tag $tag = null): Pagerfanta
public function findLatest(int $page = 1): Pagerfanta
{
$qb = $this->createQueryBuilder('p')
->addSelect('a') //, 't'
->addSelect('a')
->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);
}

View File

@@ -6,14 +6,15 @@
{% for record in records %}
<hr>
<b>Record:</b><br>
<h2>{{ record.id }}. {{ record.title }}</h2>
<p><code>{{ record.slug }}</code></p>
{#{{ dump(record.definition) }}#}
{#{{ dump(record.contenttype) }}#}
{% for field in record.fields %}
<b>Field name:</b>
{{ field.sortorder }}. {{ field.name }} / {{ field.type }}
<p>{{ field }}</p>
{{ dump(field.definition) }}
{#{{ dump(field.definition) }}#}
{% endfor %}
<hr>
{% endfor %}
@@ -40,13 +41,12 @@
#}
{#
{% if records.haveToPaginate %}
<div class="navigation text-center">
{{ pagerfanta(records, 'twitter_bootstrap3_translated', {routeName: 'content_listing', routeParams: app.request.query.all}) }}
</div>
{% endif %}
#}
{% endblock %}
{% block sidebar %}