This commit is contained in:
Simon Vieille 2021-03-30 21:16:52 +02:00
parent 5ff1acb093
commit e93419eafd
10 changed files with 188 additions and 55 deletions

View file

@ -11,15 +11,17 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use App\Repository\Blog\PostRepositoryQuery;
class MigrateDataCommand extends Command
{
protected static $defaultName = 'app:migrate-data';
protected static $defaultDescription = '';
public function __construct(EntityManager $entityManager)
public function __construct(EntityManager $entityManager, PostRepositoryQuery $postRepo)
{
$this->entityManager = $entityManager;
$this->postRepo = $postRepo;
parent::__construct();
}
@ -35,6 +37,14 @@ class MigrateDataCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): int
{
/*
foreach ($this->postRepo->create()->find() as $post)
{
$tags = $post->getTags();
$post->setTags($tags);
$this->entityManager->update($post);
}
require 'data/category.php';
require 'data/comment.php';
require 'data/post.php';
@ -103,6 +113,7 @@ class MigrateDataCommand extends Command
$this->entityManager->create($comment);
}
*/
return Command::SUCCESS;
}

View file

@ -95,10 +95,11 @@ class PostController extends PageController
public function search(Request $request, int $page = 1): Response
{
$query = $request->query->get('query');
$tag = $request->query->get('tag');
if ($query) {
if ($query || $tag) {
$entities = $this->createQuery()
->search($query)
->search($query, $tag)
->paginate($page, 5)
;
}

View file

@ -257,7 +257,21 @@ class Post implements EntityInterface
public function getTags(): ?array
{
return $this->tags;
$tags = [];
foreach ($this->tags as $tag) {
if (is_string($tag)) {
$tags[] = ['label' => $tag];
} else {
$tags[] = $tag;
}
}
usort($tags, function($a, $b) {
return $a['label'] < $b['label'] ? -1 : 1;
});
return $tags;
}
public function setTags(?array $tags): self

View file

@ -0,0 +1,35 @@
<?php
namespace App\Form\Blog;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Validator\Constraints\NotBlank;
class PostTagType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'label',
TextType::class,
[
'label' => 'Libellé',
'required' => true,
'attr' => [
],
'constraints' => [
new NotBlank(),
],
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
]);
}
}

View file

@ -20,6 +20,7 @@ use Symfony\Component\Validator\Constraints\Image;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Range;
use Symfony\Component\Validator\Constraints\Url;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class PostType extends AbstractType
{
@ -156,14 +157,17 @@ class PostType extends AbstractType
]
);
// $builder->add(
// 'tags',
// 'text',
// [
// 'constraints' => [
// ],
// ]
// );
$builder->add(
'tags',
CollectionType::class,
[
'entry_type' => PostTagType::class,
'by_reference' => false,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
]
);
$builder->add(
'isQuick',

View file

@ -63,59 +63,69 @@ class PostRepositoryQuery extends RepositoryQuery
return $this;
}
public function search(string $keywords)
public function search(?string $keywords, ?string $tag)
{
$conn = $this->repository->getEm()->getConnection();
if ($keywords) {
$conn = $this->repository->getEm()->getConnection();
$statement = $conn->prepare(
'SELECT
post.id,
post.title,
MATCH(post.title) AGAINST(:search) AS MATCH_TITLE,
MATCH(post.content) AGAINST(:search) AS MATCH_CONTENT
FROM post
WHERE
post.status = 1 AND
post.published_at < :date
ORDER BY
MATCH_TITLE DESC,
MATCH_CONTENT DESC
');
$statement = $conn->prepare(
'SELECT
post.id,
post.title,
MATCH(post.title) AGAINST(:search) AS MATCH_TITLE,
MATCH(post.content) AGAINST(:search) AS MATCH_CONTENT
FROM post
WHERE
post.status = 1 AND
post.published_at < :date
ORDER BY
MATCH_TITLE DESC,
MATCH_CONTENT DESC
');
$statement->execute([
':search' => $keywords,
':date' => (new \DateTime())->format('Y-m-d H:i:s'),
]);
$statement->execute([
':search' => $keywords,
':date' => (new \DateTime())->format('Y-m-d H:i:s'),
]);
$results = $statement->fetchAll();
$ids = [];
$results = $statement->fetchAll();
$ids = [];
foreach ($results as $k => $v) {
$rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
if ($rate >= 7) {
$ids[] = $v['id'];
}
}
if (0 == count($ids)) {
foreach ($results as $k => $v) {
$rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
if ($rate >= 6) {
if ($rate >= 7) {
$ids[] = $v['id'];
}
}
if (0 == count($ids)) {
foreach ($results as $k => $v) {
$rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
if ($rate >= 6) {
$ids[] = $v['id'];
}
}
}
if (!$ids) {
$ids = [-1];
}
$this
->orderBy('FIELD(p.id, :ids)')
->andWhere('.id IN(:ids)')
->setParameter(':ids', $ids)
;
}
if (!$ids) {
$ids = [-1];
if ($tag) {
$this
->andWhere('.tags LIKE :tag')
->setParameter(':tag', '%'.$tag.'%');
}
return $this
->orderBy('FIELD(p.id, :ids)')
->andWhere('.id IN(:ids)')
->setParameter(':ids', $ids)
;
return $this;
}
}

View file

@ -75,8 +75,8 @@
{% for tag in post.tags %}
<li>
<a href="{{ safe_path('blog_menu_search', {tag: tag}) }}">
{{- '#' ~ tag -}}
<a href="{{ safe_path('blog_menu_search', {tag: tag.label}) }}">
{{- '#' ~ tag.label -}}
</a>
</li>
{% endfor %}

View file

@ -25,8 +25,8 @@
{% for tag in post.tags %}
<li>
<a href="{{ safe_path('blog_menu_search', {tag: tag}) }}">
{{- '#' ~ tag -}}
<a href="{{ safe_path('blog_menu_search', {tag: tag.value}) }}">
{{- '#' ~ tag.value -}}
</a>
</li>
{% endfor %}

View file

@ -6,6 +6,37 @@
{{ form_row(form[item]) }}
</div>
{% endfor %}
<div class="col-12 accordion mb-3" data-collection="collection-tags" id="form-tags-collection">
{% for item in form.tags %}
<div class="card" data-collection-item="{{ loop.index }}">
<div class="card-header p-0">
<span class="btn btn-link btn-block text-left" data-toggle="collapse" data-target="#form-tag-{{ loop.index }}">
{{ item.vars.data.label }}
</span>
</div>
<div class="collapse" data-parent="#form-tags-collection" id="form-tag-{{ loop.index }}">
<div class="card-body">
{{ form_row(item.label) }}
<div class="text-right">
<span data-collection-delete-container class="btn btn-sm btn-danger">
<span data-collection-delete="{{ loop.index }}" class="fa fa-trash"></span>
</span>
</div>
{{ form_rest(item) }}
</div>
</div>
</div>
{% endfor %}
</div>
<div data-collection-add="collection-tags" class="collection-add">
<span class="btn btn-primary" data-collection-add="collection-tags">
<span class="fa fa-plus"></span>
{{ 'Nouveau tag'|trans }}
</span>
</div>
</div>
</div>
<div class="col-7 p-3">
@ -59,3 +90,23 @@
</div>
</div>
<template type="text/template" id="collection-tags">
<div class="card" data-collection-item="__name__">
<div class="card-header p-0">
<span class="btn btn-link btn-block text-left" data-toggle="collapse" data-target="#form-tag-__name__">
{{ 'Nouveau tag'|trans }}
</span>
</div>
<div class="collapse show" id="form-tag-__name__" data-parent="#form-tags-collection">
<div class="card-body">
{{ form_row(form.tags.vars.prototype.label) }}
<div class="text-right">
<span data-collection-delete-container class="btn btn-sm btn-danger"></span>
</div>
{{ form_rest(form.tags.vars.prototype) }}
</div>
</div>
</div>
</template>

View file

@ -41,6 +41,13 @@
<a class="d-block" href="{{ path('admin_blog_post_show', {entity: category.id}) }}">{{ category.title }}</a>
{% endfor %}
</li>
<li class="list-group-item">
<span class="font-weight-bold pb-2 d-block">Tags</span>
{% for tag in entity.tags %}
<span class="d-block">{{ tag.label }}</span>
{% endfor %}
</li>
<li class="list-group-item">
<span class="font-weight-bold pb-2 d-block">Slug</span>