Skip to content

Commit

Permalink
Add case study Ui Element
Browse files Browse the repository at this point in the history
  • Loading branch information
maximehuran committed Aug 22, 2024
1 parent a50ec39 commit 5470906
Show file tree
Hide file tree
Showing 13 changed files with 354 additions and 7 deletions.
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
parameters:
level: max
level: 8
paths:
- %rootDir%/src/

Expand Down
74 changes: 74 additions & 0 deletions src/Form/Type/CaseStudyElementType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

/*
* This file is part of Monsieur Biz's Blog plugin for Sylius.
* (c) Monsieur Biz <[email protected]>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace MonsieurBiz\SyliusBlogPlugin\Form\Type;

use MonsieurBiz\SyliusBlogPlugin\Entity\Article;
use MonsieurBiz\SyliusBlogPlugin\Entity\ArticleInterface;
use MonsieurBiz\SyliusBlogPlugin\Repository\ArticleRepositoryInterface;
use Sylius\Bundle\ResourceBundle\Form\DataTransformer\ResourceToIdentifierTransformer;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\ReversedTransformer;
use Symfony\Component\Validator\Constraints as Assert;

final class CaseStudyElementType extends AbstractType
{
/** @phpstan-ignore-next-line */
public function __construct(
private ArticleRepositoryInterface $articleRepository,
private ChannelContextInterface $channelContext,
private LocaleContextInterface $localeContext,
) {
}

/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$caseStudies = $this->articleRepository->createShopListQueryBuilderByType(
$this->localeContext->getLocaleCode(),
ArticleInterface::CASE_STUDY_TYPE,
$this->channelContext->getChannel(),
null
);

$caseStudies = $caseStudies->orderBy('translation.title')->getQuery()->getResult();

$builder
->add('case_study', EntityType::class, [
'class' => Article::class,
'label' => 'monsieurbiz_blog.ui_element.case_studies_ui_element.fields.case_study',
'choice_label' => fn (Article $caseStudy) => $caseStudy->getTitle(),
'choice_value' => fn (?Article $caseStudy) => $caseStudy ? $caseStudy->getId() : null,
'required' => true,
'choices' => $caseStudies,
])
->add('position', IntegerType::class, [
'label' => 'monsieurbiz_blog.ui_element.case_studies_ui_element.fields.position',
'required' => true,
'constraints' => [
new Assert\NotBlank(),
new Assert\GreaterThan(0),
],
])
;

$builder->get('case_study')->addModelTransformer(
new ReversedTransformer(new ResourceToIdentifierTransformer($this->articleRepository, 'id')),
);
}
}
66 changes: 66 additions & 0 deletions src/Form/Type/UiElement/CaseStudiesUiElementType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/*
* This file is part of Monsieur Biz's Blog plugin for Sylius.
* (c) Monsieur Biz <[email protected]>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace MonsieurBiz\SyliusBlogPlugin\Form\Type\UiElement;

use MonsieurBiz\SyliusBlogPlugin\Form\Type\CaseStudyElementType;
use MonsieurBiz\SyliusRichEditorPlugin\Attribute\AsUiElement;
use MonsieurBiz\SyliusRichEditorPlugin\Attribute\TemplatesUiElement;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints as Assert;

#[AsUiElement(
code: 'monsieurbiz_blog.case_studies_ui_element',
icon: 'crosshairs',
uiElement: 'MonsieurBiz\SyliusBlogPlugin\UiElement\CaseStudiesUiElement',
title: 'monsieurbiz_blog.ui_element.case_studies_ui_element.title',
description: 'monsieurbiz_blog.ui_element.case_studies_ui_element.description',
templates: new TemplatesUiElement(
adminRender: '@MonsieurBizSyliusBlogPlugin/Admin/UiElement/case_studies.html.twig',
frontRender: '@MonsieurBizSyliusBlogPlugin/Shop/UiElement/case_studies.html.twig',
),
tags: [],
wireframe: 'case-studies',
)]
class CaseStudiesUiElementType extends AbstractType
{
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('title', TextType::class, [
'label' => 'monsieurbiz_blog.ui_element.case_studies_ui_element.fields.title',
'required' => false,
])
->add('case_studies', CollectionType::class, [
'label' => 'monsieurbiz_blog.ui_element.case_studies_ui_element.fields.case_studies',
'entry_type' => CaseStudyElementType::class,
'prototype_name' => '__case_study__',
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'delete_empty' => true,
'attr' => [
'class' => 'ui segment secondary collection--flex',
],
'constraints' => [
new Assert\Count(['min' => 1]),
new Assert\Valid(),
],
])
;
}
}
20 changes: 17 additions & 3 deletions src/Repository/ArticleRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public function createShopListQueryBuilderByType(string $localeCode, string $typ

public function findAllEnabledAndPublishedByTag(string $localeCode, string $type, ChannelInterface $channel, TagInterface $tag, int $limit): array
{
/** @phpstan-ignore-next-line */
return $this->createShopListQueryBuilderByType($localeCode, $type, $channel, $tag)
->setMaxResults($limit)
->getQuery()
Expand All @@ -68,7 +67,6 @@ public function findAllEnabledAndPublishedByTag(string $localeCode, string $type

public function findOnePublishedBySlug(string $slug, string $localeCode, string $type, ChannelInterface $channel): ?ArticleInterface
{
/** @phpstan-ignore-next-line */
return $this->createListQueryBuilderByType($localeCode, $type)
->andWhere('translation.slug = :slug')
->andWhere(':channel MEMBER OF ba.channels')
Expand All @@ -84,7 +82,6 @@ public function findOnePublishedBySlug(string $slug, string $localeCode, string

public function findAllEnabledAndPublishedByAuthor(string $localeCode, string $type, ChannelInterface $channel, AuthorInterface $author, int $limit): array
{
/** @phpstan-ignore-next-line */
return $this->createListQueryBuilderByType($localeCode, $type)
->andWhere(':channel MEMBER OF ba.channels')
->andWhere('ba.enabled = true')
Expand All @@ -99,4 +96,21 @@ public function findAllEnabledAndPublishedByAuthor(string $localeCode, string $t
->getResult()
;
}

public function findEnabledAndPublishedByIds(array $articleIds, string $localeCode, string $type, ChannelInterface $channel, ?int $number = null): array
{
$queryBuilder = $this->createShopListQueryBuilderByType($localeCode, $type, $channel, null)
->andWhere('ba.id in (:articleIds)')
->addOrderBy('ba.publishedAt', 'desc')
->setParameter('articleIds', $articleIds)
;

if (null !== $number) {
$queryBuilder->setMaxResults($number);
}

return $queryBuilder->getQuery()
->getResult()
;
}
}
2 changes: 2 additions & 0 deletions src/Repository/ArticleRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ public function findAllEnabledAndPublishedByTag(string $localeCode, string $type
public function findOnePublishedBySlug(string $slug, string $localeCode, string $type, ChannelInterface $channel): ?ArticleInterface;

public function findAllEnabledAndPublishedByAuthor(string $localeCode, string $type, ChannelInterface $channel, AuthorInterface $author, int $limit): array;

public function findEnabledAndPublishedByIds(array $articleIds, string $localeCode, string $type, ChannelInterface $channel, ?int $number = null): array;
}
3 changes: 0 additions & 3 deletions src/Repository/TagRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ final class TagRepository extends EntityRepository implements TagRepositoryInter
{
public function findRootNodes(): array
{
/** @phpstan-ignore-next-line */
return $this->createQueryBuilder('o')
->addOrderBy('o.position')
->getQuery()
Expand Down Expand Up @@ -71,7 +70,6 @@ public function createEnabledListQueryBuilder(string $localeCode): QueryBuilder
*/
public function findOneByName(string $name, string $localeCode): ?TagInterface
{
/** @phpstan-ignore-next-line */
return $this->createListQueryBuilder($localeCode)
->andWhere('translation.name = :name')
->setParameter('name', $name)
Expand All @@ -85,7 +83,6 @@ public function findOneByName(string $name, string $localeCode): ?TagInterface
*/
public function findOneBySlug(string $slug, string $localeCode): ?TagInterface
{
/** @phpstan-ignore-next-line */
return $this->createListQueryBuilder($localeCode)
->andWhere('translation.slug = :slug')
->setParameter('slug', $slug)
Expand Down
10 changes: 10 additions & 0 deletions src/Resources/translations/messages.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,13 @@ monsieurbiz_blog:
read_more: Read more
new_case_study: New case study
edit_case_study: Edit case study
no_results_to_display: No results to display
ui_element:
case_studies_ui_element:
title: Case studies Element
description: Display a list of case studies.
fields:
title: Title
case_studies: Case studies
case_study: Case study
position: Position
10 changes: 10 additions & 0 deletions src/Resources/translations/messages.fr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,13 @@ monsieurbiz_blog:
read_more: Lire la suite
new_case_study: Nouvelle étude de cas
edit_case_study: Modifier l'étude de cas
no_results_to_display: Aucun résultat à afficher
ui_element:
case_studies_ui_element:
title: Lame Études de cas
description: Affiche une liste d'études de cas.
fields:
title: Titre
case_studies: Études de cas
case_study: Étude de cas
position: Position
18 changes: 18 additions & 0 deletions src/Resources/views/Admin/Article/_image.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% set filter = filter|default('monsieurbiz_blog_image_thumbnail') %}
{% set placeholder = placeholder|default('200x200.png') %}

{# Thumbnail display #}
{% if article.thumbnailImage and filter == 'monsieurbiz_blog_image_thumbnail' %}
{% set path = article.thumbnailImage|imagine_filter(filter) %}
{# Image display or thumbnail fallback on image #}
{% elseif article.image %}
{% set path = article.image|imagine_filter(filter) %}
{% else %}
{% if use_webpack %}
{% set path = asset('build/shop/images/' ~ placeholder, 'shop') %}
{% else %}
{% set path = asset('assets/shop/img/' ~ placeholder) %}
{% endif %}
{% endif %}

<img src="{{ path }}" alt="{{ article.title }}">
41 changes: 41 additions & 0 deletions src/Resources/views/Admin/UiElement/case_studies.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{#
UI Element template
type: case_studies
element fields :
title
case_studies
element methods:
getCaseStudies
#}
{% import '@SyliusUi/Macro/messages.html.twig' as messages %}

{% set case_studies = ui_element.getCaseStudies(element) %}

{% if case_studies|length > 0 %}

{% if element.title|default('') is not empty %}
<div class="ui huge header">
{{ element.title }}
</div>
{% endif %}

<div class="ui cards">
{% for case_study in case_studies %}
<div class="ui card">
<div class="image">
{% include '@MonsieurBizSyliusBlogPlugin/Admin/Article/_image.html.twig' with { 'article' : case_study} %}
</div>
<div class="content">
<a class="header">{{ case_study.title }}</a><br />
<div class="extra content">
<a class="ui button" href="{{ path('monsieurbiz_case_studies_article_show', {'slug': case_study.slug}) }}">
{{ 'monsieurbiz_blog.ui.read_more'|trans }}
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
{{ messages.info('monsieurbiz_blog.ui.no_results_to_display') }}
{% endif %}
39 changes: 39 additions & 0 deletions src/Resources/views/Shop/UiElement/case_studies.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{#
UI Element template
type: case_studies
element fields :
title
case_studies
element methods:
getCaseStudies
#}
{% import '@SyliusUi/Macro/messages.html.twig' as messages %}

{% set case_studies = ui_element.getCaseStudies(element) %}

{% if case_studies|length > 0 %}

{% if element.title|default('') is not empty %}
<div class="ui huge header">
{{ element.title }}
</div>
{% endif %}

<div class="ui cards">
{% for case_study in case_studies %}
<div class="ui card">
<div class="image">
{% include '@MonsieurBizSyliusBlogPlugin/Admin/Article/_image.html.twig' with { 'article' : case_study} %}
</div>
<div class="content">
<a class="header">{{ case_study.title }}</a><br />
<div class="extra content">
<a class="ui button" href="{{ path('monsieurbiz_case_studies_article_show', {'slug': case_study.slug}) }}">
{{ 'monsieurbiz_blog.ui.read_more'|trans }}
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
3 changes: 3 additions & 0 deletions src/Resources/views/Wireframe/case-studies.svg.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<svg width="230" height="100" viewBox="0 0 230 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="230" height="100" rx="5" fill="#7A8CCE" fill-opacity="0.1"></rect>
</svg>
Loading

0 comments on commit 5470906

Please sign in to comment.