Skip to content

Commit bfc5677

Browse files
author
Zane
committed
ArticleEdit split
1 parent e501cd2 commit bfc5677

File tree

7 files changed

+183
-166
lines changed

7 files changed

+183
-166
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
namespace App\Controller\Editor;
3+
4+
use App\Controller\BaseController;
5+
use App\Service\Cms\Article;
6+
use App\Service\Cms\ArticleEditor;
7+
use App\Service\Factory;
8+
use App\Service\FrontendHelper;
9+
use Symfony\Component\HttpFoundation\JsonResponse;
10+
use Symfony\Component\HttpFoundation\RequestStack;
11+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
12+
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
13+
use Twig\Environment;
14+
15+
16+
abstract class ArticleEditBaseController extends BaseController
17+
{
18+
19+
public function __construct(
20+
protected Factory $factory,
21+
protected ArticleEditor $articleEditor, protected Article $article, RequestStack $requestStack,
22+
protected FrontendHelper $frontendHelper, protected CsrfTokenManagerInterface $csrfTokenManager,
23+
protected Environment $twig
24+
)
25+
{
26+
$this->request = $requestStack->getCurrentRequest();
27+
}
28+
29+
30+
protected function loadArticleEditor(int $articleId) : ArticleEditor
31+
{
32+
$this->ajaxOnly();
33+
34+
if( empty($this->getUser()) ) {
35+
throw $this->createAccessDeniedException('Non sei loggato!');
36+
}
37+
38+
$this->articleEditor->load($articleId);
39+
40+
if( !$this->articleEditor->currentUserCanEdit() ) {
41+
throw $this->createAccessDeniedException('Non sei autorizzato a modificare questo articolo');
42+
}
43+
44+
return $this->articleEditor;
45+
}
46+
47+
48+
protected function jsonOKResponse(string $okMessage) : JsonResponse
49+
{
50+
return $this->json([
51+
"message" => "✅ OK! $okMessage - " . (new \DateTime())->format('Y-m-d H:i:s'),
52+
"path" => $this->articleEditor->getUrl(UrlGeneratorInterface::RELATIVE_PATH),
53+
"title" => $this->articleEditor->getTitleForHTMLAttribute(),
54+
"strip" => $this->twig->render('article/meta-strip.html.twig', [
55+
"Article" => $this->articleEditor,
56+
]),
57+
"bios" => $this->twig->render('article/authors-bio.html.twig', [
58+
"Article" => $this->articleEditor
59+
]),
60+
"tags" => $this->twig->render('article/tags.html.twig', [
61+
"Article" => $this->articleEditor
62+
])
63+
]);
64+
}
65+
}

‎src/Controller/Editor/ArticleEditorController.php

Lines changed: 0 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -2,139 +2,15 @@
22
namespace App\Controller\Editor;
33

44
use App\Controller\BaseController;
5-
use App\Service\Cms\Article;
6-
use App\Service\Cms\ArticleEditor;
7-
use App\Service\Factory;
8-
use App\Service\FrontendHelper;
95
use Error;
106
use Exception;
117
use Symfony\Component\HttpFoundation\JsonResponse;
12-
use Symfony\Component\HttpFoundation\RequestStack;
138
use Symfony\Component\HttpFoundation\Response;
149
use Symfony\Component\Routing\Attribute\Route;
15-
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
16-
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
17-
use Twig\Environment;
1810

1911

2012
class ArticleEditorController extends BaseController
2113
{
22-
const string TITLE_FIELD_NAME = 'new-article-title';
23-
const string FORMAT_FIELD_NAME = 'new-article-format';
24-
const string CSRF_TOKEN_ID = self::TITLE_FIELD_NAME;
25-
26-
27-
public function __construct(
28-
protected Factory $factory,
29-
protected ArticleEditor $articleEditor, protected Article $article, RequestStack $requestStack,
30-
protected FrontendHelper $frontendHelper, protected CsrfTokenManagerInterface $csrfTokenManager,
31-
protected Environment $twig
32-
)
33-
{
34-
$this->request = $requestStack->getCurrentRequest();
35-
}
36-
37-
38-
//<editor-fold defaultstate="collapsed" desc="*** 🆕 /scrivi ***">
39-
#[Route('/scrivi', name: 'app_editor_new', methods: ['GET'])]
40-
public function new() : Response
41-
{
42-
$currentUser = $this->factory->getCurrentUser();
43-
44-
if( empty($currentUser) ) {
45-
46-
$templateFilename = 'new-logged-out';
47-
$arrSideArticlesSlices = null;
48-
49-
} else {
50-
51-
$templateFilename = 'new';
52-
53-
$sideArticles = $this->factory->createArticleCollection()->loadLatestUpdatedListable();
54-
55-
$numArticlesPerSlide = 7;
56-
$numSlides = ceil( $sideArticles->count() / $numArticlesPerSlide );
57-
58-
$arrSideArticlesSlices = [];
59-
for($i = 0; $i < $numSlides; $i++) {
60-
61-
$arrSideArticlesSlices[$i] =
62-
$sideArticles->getItems($numArticlesPerSlide, $numArticlesPerSlide*$i, false, false);
63-
}
64-
}
65-
66-
return $this->render("article/editor/$templateFilename.html.twig", [
67-
'metaTitle' => 'Scrivi nuovo articolo',
68-
'metaCanonicalUrl' => $this->generateUrl('app_editor_new', [], UrlGeneratorInterface::ABSOLUTE_URL),
69-
'activeMenu' => '',
70-
'FrontendHelper' => $this->frontendHelper,
71-
'ArticleHowTo' => $this->factory->createArticle()->load(Article::ID_PUBLISH_ARTICLE),
72-
'currentUserUrl' => $currentUser?->getUrl(),
73-
'CurrentUserDraftArticles' => $currentUser?->getArticlesDraft(),
74-
'CurrentUserInReviewArticles' => $currentUser?->getArticlesInReview(),
75-
'CurrentUserPublishedArticles' => $currentUser?->getArticlesLatestPublished(),
76-
'CurrentUserKoArticles' => $currentUser?->getArticlesKo(),
77-
'SideArticlesSlices' => $arrSideArticlesSlices,
78-
'Views' => $this->frontendHelper->getViews()->get(['bozze', 'finiti']),
79-
//
80-
'titleFieldName' => static::TITLE_FIELD_NAME,
81-
'formatFieldName' => static::FORMAT_FIELD_NAME,
82-
'formatArticle' => Article::FORMAT_ARTICLE,
83-
'formatNews' => Article::FORMAT_NEWS,
84-
'csrfTokenFieldName' => static::CSRF_TOKEN_PARAM_NAME,
85-
'csrfToken' => $this->csrfTokenManager->getToken(static::CSRF_TOKEN_ID)->getValue()
86-
]);
87-
}
88-
89-
90-
#[Route('/scrivi/salva', name: 'app_editor_new_submit', methods: ['POST'])]
91-
public function submit() : Response
92-
{
93-
$currentUser = $this->factory->getCurrentUser();
94-
95-
if( empty($currentUser) ) {
96-
97-
throw $this->createAccessDeniedException(
98-
'Non sei loggato! Solo gli utenti registrati possono creare nuovi articoli.'
99-
);
100-
}
101-
102-
$this->validateCsrfToken();
103-
104-
// TODO zaneee! Rate limiting on new article
105-
106-
$newArticleTitle = $this->request->get(static::TITLE_FIELD_NAME);
107-
108-
$this->articleEditor->setTitle($newArticleTitle);
109-
110-
$articles =
111-
$this->factory->createArticleCollection()->loadByComparableSearch(
112-
$this->articleEditor->getTitleComparable(), 'title'
113-
);
114-
115-
if( $articles->count() ) {
116-
return $this->redirect( $articles->first()->getUrl() );
117-
}
118-
119-
$newArticleFormat = $this->request->get(static::FORMAT_FIELD_NAME);
120-
121-
/*
122-
* $currentUser is unknown to Doctrine: if we try to set it as Author directly:
123-
* A new entity was found through the relationship 'App\Entity\Cms\ArticleAuthor#user' that was not configured to cascade persist operations for entity: App\Entity\PhpBB\User@--
124-
*/
125-
$currentUserId = $currentUser->getId();
126-
$author = $this->factory->createUser()->load($currentUserId);
127-
128-
$this->articleEditor
129-
->setFormat($newArticleFormat)
130-
->addAuthor($author)
131-
->autotag($author)
132-
->save();
133-
134-
return $this->redirect( $this->articleEditor->getUrl() );
135-
}
136-
//</editor-fold>
137-
13814
//<editor-fold defaultstate="collapsed" desc="*** 📜 Title and Body ***">
13915
#[Route('/ajax/editor/article/{articleId<[1-9]+[0-9]*>}', name: 'app_editor_article_update', methods: ['POST'])]
14016
public function update(int $articleId) : JsonResponse|Response
@@ -266,42 +142,4 @@ public function setTags(int $articleId) : JsonResponse|Response
266142
} catch(Exception|Error $ex) { return $this->textErrorResponse($ex); }
267143
}
268144
//</editor-fold>
269-
270-
//<editor-fold defaultstate="collapsed" desc="*** ⛑️ Helpers ***">
271-
protected function loadArticleEditor(int $articleId) : ArticleEditor
272-
{
273-
$this->ajaxOnly();
274-
275-
if( empty($this->getUser()) ) {
276-
throw $this->createAccessDeniedException('Non sei loggato!');
277-
}
278-
279-
$this->articleEditor->load($articleId);
280-
281-
if( !$this->articleEditor->currentUserCanEdit() ) {
282-
throw $this->createAccessDeniedException('Non sei autorizzato a modificare questo articolo');
283-
}
284-
285-
return $this->articleEditor;
286-
}
287-
288-
289-
protected function jsonOKResponse(string $okMessage) : JsonResponse
290-
{
291-
return $this->json([
292-
"message" => "✅ OK! $okMessage - " . (new \DateTime())->format('Y-m-d H:i:s'),
293-
"path" => $this->articleEditor->getUrl(UrlGeneratorInterface::RELATIVE_PATH),
294-
"title" => $this->articleEditor->getTitleForHTMLAttribute(),
295-
"strip" => $this->twig->render('article/meta-strip.html.twig', [
296-
"Article" => $this->articleEditor,
297-
]),
298-
"bios" => $this->twig->render('article/authors-bio.html.twig', [
299-
"Article" => $this->articleEditor
300-
]),
301-
"tags" => $this->twig->render('article/tags.html.twig', [
302-
"Article" => $this->articleEditor
303-
])
304-
]);
305-
}
306-
//</editor-fold>
307145
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
namespace App\Controller\Editor;
3+
4+
use App\Service\Cms\Article;
5+
use Symfony\Component\HttpFoundation\Response;
6+
use Symfony\Component\Routing\Attribute\Route;
7+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
8+
9+
10+
class ArticleNewController extends ArticleEditBaseController
11+
{
12+
const string TITLE_FIELD_NAME = 'new-article-title';
13+
const string FORMAT_FIELD_NAME = 'new-article-format';
14+
const string CSRF_TOKEN_ID = self::TITLE_FIELD_NAME;
15+
16+
17+
#[Route('/scrivi', name: 'app_article_new', methods: ['GET'])]
18+
public function new() : Response
19+
{
20+
$currentUser = $this->factory->getCurrentUser();
21+
22+
if( empty($currentUser) ) {
23+
24+
$templateFilename = 'new-logged-out';
25+
$arrSideArticlesSlices = null;
26+
27+
} else {
28+
29+
$templateFilename = 'new';
30+
31+
$sideArticles = $this->factory->createArticleCollection()->loadLatestUpdatedListable();
32+
33+
$numArticlesPerSlide = 7;
34+
$numSlides = ceil( $sideArticles->count() / $numArticlesPerSlide );
35+
36+
$arrSideArticlesSlices = [];
37+
for($i = 0; $i < $numSlides; $i++) {
38+
39+
$arrSideArticlesSlices[$i] =
40+
$sideArticles->getItems($numArticlesPerSlide, $numArticlesPerSlide*$i, false, false);
41+
}
42+
}
43+
44+
return $this->render("article/editor/$templateFilename.html.twig", [
45+
'metaTitle' => 'Scrivi nuovo articolo',
46+
'metaCanonicalUrl' => $this->generateUrl('app_article_new', [], UrlGeneratorInterface::ABSOLUTE_URL),
47+
'activeMenu' => '',
48+
'FrontendHelper' => $this->frontendHelper,
49+
'ArticleHowTo' => $this->factory->createArticle()->load(Article::ID_PUBLISH_ARTICLE),
50+
'currentUserUrl' => $currentUser?->getUrl(),
51+
'CurrentUserDraftArticles' => $currentUser?->getArticlesDraft(),
52+
'CurrentUserInReviewArticles' => $currentUser?->getArticlesInReview(),
53+
'CurrentUserPublishedArticles' => $currentUser?->getArticlesLatestPublished(),
54+
'CurrentUserKoArticles' => $currentUser?->getArticlesKo(),
55+
'SideArticlesSlices' => $arrSideArticlesSlices,
56+
'Views' => $this->frontendHelper->getViews()->get(['bozze', 'finiti']),
57+
//
58+
'titleFieldName' => static::TITLE_FIELD_NAME,
59+
'formatFieldName' => static::FORMAT_FIELD_NAME,
60+
'formatArticle' => Article::FORMAT_ARTICLE,
61+
'formatNews' => Article::FORMAT_NEWS,
62+
'csrfTokenFieldName' => static::CSRF_TOKEN_PARAM_NAME,
63+
'csrfToken' => $this->csrfTokenManager->getToken(static::CSRF_TOKEN_ID)->getValue()
64+
]);
65+
}
66+
67+
68+
#[Route('/scrivi/salva', name: 'app_article_new_submit', methods: ['POST'])]
69+
public function submit() : Response
70+
{
71+
$currentUser = $this->factory->getCurrentUser();
72+
73+
if( empty($currentUser) ) {
74+
75+
throw $this->createAccessDeniedException(
76+
'Non sei loggato! Solo gli utenti registrati possono creare nuovi articoli.'
77+
);
78+
}
79+
80+
$this->validateCsrfToken();
81+
82+
// TODO zaneee! Rate limiting on new article
83+
84+
$newArticleTitle = $this->request->get(static::TITLE_FIELD_NAME);
85+
86+
$this->articleEditor->setTitle($newArticleTitle);
87+
88+
$articles =
89+
$this->factory->createArticleCollection()->loadByComparableSearch(
90+
$this->articleEditor->getTitleComparable(), 'title'
91+
);
92+
93+
if( $articles->count() ) {
94+
return $this->redirect( $articles->first()->getUrl() );
95+
}
96+
97+
$newArticleFormat = $this->request->get(static::FORMAT_FIELD_NAME);
98+
99+
/*
100+
* $currentUser is unknown to Doctrine: if we try to set it as Author directly:
101+
* A new entity was found through the relationship 'App\Entity\Cms\ArticleAuthor#user' that was not configured to cascade persist operations for entity: App\Entity\PhpBB\User@--
102+
*/
103+
$currentUserId = $currentUser->getId();
104+
$author = $this->factory->createUser()->load($currentUserId);
105+
106+
$this->articleEditor
107+
->setFormat($newArticleFormat)
108+
->addAuthor($author)
109+
->autotag($author)
110+
->save();
111+
112+
return $this->redirect( $this->articleEditor->getUrl() );
113+
}
114+
}

‎templates/article/editor/new.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
Dopo aver cercato, potrai iniziare a scrivere il tuo articolo da qui 👇
138138
</p>
139139

140-
<form action="{{ path('app_editor_new_submit') }}" method="POST" class="mb-3">
140+
<form action="{{ path('app_article_new_submit') }}" method="POST" class="mb-3">
141141

142142
<div class="mb-3 d-flex justify-content-center">
143143
<div style="max-width: 600px; width: 100%;">

‎templates/user/author.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
</div>
100100
<div class="text-center">
101101
Puoi trovare gli altri tuoi articoli alla pagina
102-
<a href="{{ path('app_editor_new') }}"><i class="fa-solid fa-pen"></i> Nuovo
102+
<a href="{{ path('app_article_new') }}"><i class="fa-solid fa-pen"></i> Nuovo
103103
articolo</a>.
104104
</div>
105105
{% endblock %}

‎templates/user/userbar-anonymous.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<strong>Iscriviti ora (gratis!)</strong>
1313
</a>
1414
per <a href="{{ path('app_home') }}forum">partecipare al forum</a>,
15-
<a href="{{ path('app_editor_new') }}">pubblicare articoli sul sito</a> e
15+
<a href="{{ path('app_article_new') }}">pubblicare articoli sul sito</a> e
1616
<a href="{{ newsletterUrl }}">ricevere la newsletter</a>!
1717

1818
{% endblock %}

‎templates/user/userbar-logged.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</a>
2626
</li>
2727
<li class="nav-item">
28-
<a href="{{ path('app_editor_new') }}"><i class="fa-solid fa-pen"></i> Scrivi nuovo articolo</a>
28+
<a href="{{ path('app_article_new') }}"><i class="fa-solid fa-pen"></i> Scrivi nuovo articolo</a>
2929
</li>
3030
<li class="nav-item">
3131
<a href="{{ User.url }}"><i class="fa-solid fa-list"></i> La tua pagina di Autore</a>

0 commit comments

Comments
 (0)