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\InputInterface;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use App\Repository\Blog\PostRepositoryQuery;
|
||||||
|
|
||||||
class MigrateDataCommand extends Command
|
class MigrateDataCommand extends Command
|
||||||
{
|
{
|
||||||
protected static $defaultName = 'app:migrate-data';
|
protected static $defaultName = 'app:migrate-data';
|
||||||
protected static $defaultDescription = '';
|
protected static $defaultDescription = '';
|
||||||
|
|
||||||
public function __construct(EntityManager $entityManager)
|
public function __construct(EntityManager $entityManager, PostRepositoryQuery $postRepo)
|
||||||
{
|
{
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
|
$this->postRepo = $postRepo;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
@ -35,6 +37,14 @@ class MigrateDataCommand extends Command
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
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/category.php';
|
||||||
require 'data/comment.php';
|
require 'data/comment.php';
|
||||||
require 'data/post.php';
|
require 'data/post.php';
|
||||||
|
@ -103,6 +113,7 @@ class MigrateDataCommand extends Command
|
||||||
|
|
||||||
$this->entityManager->create($comment);
|
$this->entityManager->create($comment);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,10 +95,11 @@ class PostController extends PageController
|
||||||
public function search(Request $request, int $page = 1): Response
|
public function search(Request $request, int $page = 1): Response
|
||||||
{
|
{
|
||||||
$query = $request->query->get('query');
|
$query = $request->query->get('query');
|
||||||
|
$tag = $request->query->get('tag');
|
||||||
|
|
||||||
if ($query) {
|
if ($query || $tag) {
|
||||||
$entities = $this->createQuery()
|
$entities = $this->createQuery()
|
||||||
->search($query)
|
->search($query, $tag)
|
||||||
->paginate($page, 5)
|
->paginate($page, 5)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,21 @@ class Post implements EntityInterface
|
||||||
|
|
||||||
public function getTags(): ?array
|
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
|
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\NotBlank;
|
||||||
use Symfony\Component\Validator\Constraints\Range;
|
use Symfony\Component\Validator\Constraints\Range;
|
||||||
use Symfony\Component\Validator\Constraints\Url;
|
use Symfony\Component\Validator\Constraints\Url;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||||
|
|
||||||
class PostType extends AbstractType
|
class PostType extends AbstractType
|
||||||
{
|
{
|
||||||
|
@ -156,14 +157,17 @@ class PostType extends AbstractType
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
// $builder->add(
|
$builder->add(
|
||||||
// 'tags',
|
'tags',
|
||||||
// 'text',
|
CollectionType::class,
|
||||||
// [
|
[
|
||||||
// 'constraints' => [
|
'entry_type' => PostTagType::class,
|
||||||
// ],
|
'by_reference' => false,
|
||||||
// ]
|
'allow_add' => true,
|
||||||
// );
|
'allow_delete' => true,
|
||||||
|
'prototype' => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
$builder->add(
|
$builder->add(
|
||||||
'isQuick',
|
'isQuick',
|
||||||
|
|
|
@ -63,59 +63,69 @@ class PostRepositoryQuery extends RepositoryQuery
|
||||||
return $this;
|
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(
|
$statement = $conn->prepare(
|
||||||
'SELECT
|
'SELECT
|
||||||
post.id,
|
post.id,
|
||||||
post.title,
|
post.title,
|
||||||
MATCH(post.title) AGAINST(:search) AS MATCH_TITLE,
|
MATCH(post.title) AGAINST(:search) AS MATCH_TITLE,
|
||||||
MATCH(post.content) AGAINST(:search) AS MATCH_CONTENT
|
MATCH(post.content) AGAINST(:search) AS MATCH_CONTENT
|
||||||
FROM post
|
FROM post
|
||||||
WHERE
|
WHERE
|
||||||
post.status = 1 AND
|
post.status = 1 AND
|
||||||
post.published_at < :date
|
post.published_at < :date
|
||||||
ORDER BY
|
ORDER BY
|
||||||
MATCH_TITLE DESC,
|
MATCH_TITLE DESC,
|
||||||
MATCH_CONTENT DESC
|
MATCH_CONTENT DESC
|
||||||
');
|
');
|
||||||
|
|
||||||
$statement->execute([
|
$statement->execute([
|
||||||
':search' => $keywords,
|
':search' => $keywords,
|
||||||
':date' => (new \DateTime())->format('Y-m-d H:i:s'),
|
':date' => (new \DateTime())->format('Y-m-d H:i:s'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$results = $statement->fetchAll();
|
$results = $statement->fetchAll();
|
||||||
$ids = [];
|
$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) {
|
foreach ($results as $k => $v) {
|
||||||
$rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
|
$rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
|
||||||
|
|
||||||
if ($rate >= 6) {
|
if ($rate >= 7) {
|
||||||
$ids[] = $v['id'];
|
$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) {
|
if ($tag) {
|
||||||
$ids = [-1];
|
$this
|
||||||
|
->andWhere('.tags LIKE :tag')
|
||||||
|
->setParameter(':tag', '%'.$tag.'%');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this
|
return $this;
|
||||||
->orderBy('FIELD(p.id, :ids)')
|
|
||||||
->andWhere('.id IN(:ids)')
|
|
||||||
->setParameter(':ids', $ids)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,8 +75,8 @@
|
||||||
|
|
||||||
{% for tag in post.tags %}
|
{% for tag in post.tags %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ safe_path('blog_menu_search', {tag: tag}) }}">
|
<a href="{{ safe_path('blog_menu_search', {tag: tag.label}) }}">
|
||||||
{{- '#' ~ tag -}}
|
{{- '#' ~ tag.label -}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
{% for tag in post.tags %}
|
{% for tag in post.tags %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ safe_path('blog_menu_search', {tag: tag}) }}">
|
<a href="{{ safe_path('blog_menu_search', {tag: tag.value}) }}">
|
||||||
{{- '#' ~ tag -}}
|
{{- '#' ~ tag.value -}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -6,6 +6,37 @@
|
||||||
{{ form_row(form[item]) }}
|
{{ form_row(form[item]) }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% 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>
|
</div>
|
||||||
<div class="col-7 p-3">
|
<div class="col-7 p-3">
|
||||||
|
@ -59,3 +90,23 @@
|
||||||
</div>
|
</div>
|
||||||
</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>
|
<a class="d-block" href="{{ path('admin_blog_post_show', {entity: category.id}) }}">{{ category.title }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</li>
|
</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">
|
<li class="list-group-item">
|
||||||
<span class="font-weight-bold pb-2 d-block">Slug</span>
|
<span class="font-weight-bold pb-2 d-block">Slug</span>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue