add tags
This commit is contained in:
parent
5ff1acb093
commit
e93419eafd
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
35
src/Form/Blog/PostTagType.php
Normal file
35
src/Form/Blog/PostTagType.php
Normal 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([
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in a new issue