Completion of posts
Дорабатываем новости, часть 1
Сейчас новости выводятся из массива, который расположен в PostController
.
Давайте исправим это недоразумение и заполним таблицу. Конечно можно сделать все руками,
но мы воспользуемся библиотекой, которая сделает все за нас. Подключим
composer require fzaninotto/faker
.
Далее, в PostController добавим свойство public $fake_post
, а так же
обновим метод index
этого же контроллера добавив немного кода:
$this->fake_post = Factory::create();
$manager = $this->getDoctrine()->getManager();
for ($i = 1; $i < 20; $i++) {
$post = new Post();
$post->setTitle($this->fake_post->text(100));
$post->setBody($this->fake_post->text(500));
$post->setLikes(rand(100, 500));
$manager->persist($post);
}
$manager->flush();
Обратите внимание на use App\Entity\Post
и
use Faker\Factory
. Массив с постами можно пока оставить.
Что здесь происходит?
-
- с помощью
$manager = $this->getDoctrine()->getManager()
мы инициировали менеджер объекта для конкретной сущности, в нашем случае это Post. Он отвечает за сохранение объектов и выборку объектов из базы данных; -
- метод persist() в контексте
$manager->persist($post)
выполняет подготовку запроса; -
- метод flush() в
$manager->flush()
записывает в базу.
Осталось только обновить страницу, тем самым вызвав код на исполнение. Запустим сервер,
перейдем по маршруту /post
и проверим БД:
Вывод всех новостей
Когда мы генерировали сущность Post, вместе с ней был создан репозиторий PostRepository. Представляет он из себя класс, с помощью которого мы будем общаться с БД. В нем уже заложены стандартные методы для выборки, такие как findBy, findAll, findOneBy и прочие, которые покроют наши нужды с лихвой.
PostController наследуется от AbstractController, и не сразу можно заметить откуда у него метод getDoctrine(). И это отличный пример для демонстрации использования трейтов в php, которые лично мне на практике приходится видеть не часто.
Теперь массив с новостями и код faker'a нам больше не нужны, вместо этого напишем
$repository = $this->getDoctrine()->getRepository(Post::class)
.
Собственно, применим findAll()
к репозиторию и выведем на страницу посты.
Добавляем в код $posts = $repository->findAll()
.
Обновляем страницу и наблюдаем свежесгенерированные новости.
$this->getDoctine()->getRepository(Post::class)
и $this->getDoctine()->getManager()->getRepository(Post::class)
равносильны.
Просмотр одной новости
Ранее, с помощью фильтра "truncate" мы сократили отображаемое количество символов у новости в общем списке.
Для детального просмотра выведем каждую новость на отдельной странице.
Создадим еще один метод в
PostController
, назовем его post
.
/**
* @param Post $post
* @return \Symfony\Component\HttpFoundation\Response
* @Route("/post/{id}", name="post")
*/
public function post(Post $post)
{
return $this->render('post/show.html.twig', [
'post' => $post
]);
}
Сначала обратим внимание на аннотации, а конкретно на @Route
.
После /post
добавился
параметр {id}
, а в выражении
public function post(Post $post)
мы получаем конкретный пост.
Ну и это все, остается только немного поработать над шаблонами.
В папке templates => post
создадим шаблон
show.html.twig
.
Код можно взять здесь.
Теперь обновим ссылки с текстом Read more
в шаблоне index.html.twig
. Добавим в аттрибут
href
следующий код -
{{ path('post', {'id': post.id}) }}
.
Запускаем сервер и проверяем.