Skip to content

Commit 35cad90

Browse files
tstieglerTKsM151
authored andcommitted
Initial sitewide announcements feature (#132)
1 parent 0569006 commit 35cad90

File tree

16 files changed

+349
-12
lines changed

16 files changed

+349
-12
lines changed

assets/less/common.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,11 @@
8585
.forum-group-heading a {
8686
color: @page-color;
8787
}
88+
89+
.text-center {
90+
text-align: center;
91+
}
92+
93+
.text-right {
94+
text-align: right;
95+
}

assets/less/components/alert.less

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,23 @@
2424
from { opacity: 0; }
2525
to { opacity: 1; }
2626
}
27+
28+
.form-message {
29+
30+
display: flex;
31+
flex-direction: column;
32+
margin: 1rem 1rem 1rem 0;
33+
padding: 1rem 1rem 0;
34+
35+
&--primary {
36+
color: @alert-primary-text-color;
37+
border: 1px solid @alert-primary-border-color;
38+
background: @alert-primary-color;
39+
}
40+
41+
&--success {
42+
color: @alert-success-text-color;
43+
border: 1px solid @alert-success-border-color;
44+
background: @alert-success-color;
45+
}
46+
}

assets/less/settings.less

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,14 @@
5050

5151
// Notices
5252
@alert-notice-color: aliceblue;
53-
@alert-success-color: palegreen;
53+
54+
@alert-success-color: #c6f9d3;
55+
@alert-success-border-color: #a1dfb1;
56+
@alert-success-text-color: #002710;
57+
58+
@alert-primary-color: #cfe5fb;
59+
@alert-primary-border-color: #b5cce3;
60+
@alert-primary-text-color: #172a3e;
5461

5562
// Forms
5663
@form-error-color: red;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
frontpageconfig:
2+
controller: App\Controller\FrontPageConfigurationController::frontPageConfig
3+
path: /frontpageconfig
4+
methods: [GET, POST]

config/routes.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ _forum_category:
1616
_front:
1717
resource: app_routes/front.yaml
1818

19+
_frontpageconfig:
20+
resource: app_routes/frontpageconfig.yaml
21+
1922
_message:
2023
resource: app_routes/message.yaml
2124

src/Controller/FrontController.php

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace App\Controller;
44

55
use App\Entity\User;
6+
use App\Entity\ForumConfiguration;
67
use App\Repository\ForumRepository;
8+
use App\Repository\ForumConfigurationRepository;
79
use App\Repository\SubmissionRepository;
810
use App\Utils\PermissionsChecker;
911
use Symfony\Component\HttpFoundation\Response;
@@ -26,9 +28,11 @@
2628
* instead.
2729
*/
2830
final class FrontController extends AbstractController {
29-
public function front(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page) {
31+
public function front(ForumRepository $fr, SubmissionRepository $sr, ForumConfigurationRepository $fcr, string $sortBy, int $page) {
3032
$user = $this->getUser();
3133

34+
$siteConfig = $fcr->findSitewide();
35+
3236
if (!$user instanceof User) {
3337
//$listing = User::FRONT_FEATURED;
3438
$listing = User::FRONT_ALL;
@@ -41,20 +45,20 @@ public function front(ForumRepository $fr, SubmissionRepository $sr, string $sor
4145

4246
switch ($listing) {
4347
case User::FRONT_SUBSCRIBED:
44-
return $this->subscribed($fr, $sr, $sortBy, $page);
48+
return $this->subscribed($fr, $sr, $sortBy, $page, $siteConfig);
4549
case User::FRONT_FEATURED:
46-
return $this->featured($fr, $sr, $sortBy, $page);
50+
return $this->featured($fr, $sr, $sortBy, $page, $siteConfig);
4751
case User::FRONT_ALL:
48-
//return $this->all($sr, $sortBy, $page);
49-
return $this->all($fr, $sr, $sortBy, $page);
52+
//return $this->all($sr, $sortBy, $page, $siteConfig);
53+
return $this->all($fr, $sr, $sortBy, $page, $siteConfig);
5054
case User::FRONT_MODERATED:
51-
return $this->moderated($fr, $sr, $sortBy, $page);
55+
return $this->moderated($fr, $sr, $sortBy, $page, $siteConfig);
5256
default:
5357
throw new \InvalidArgumentException('bad front page selection');
5458
}
5559
}
5660

57-
public function featured(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page) {
61+
public function featured(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page, ForumConfiguration $siteConfig) {
5862
$forums = $fr->findFeaturedForumNames();
5963
$submissions = $sr->findFrontPageSubmissions($forums, $sortBy, $page);
6064

@@ -63,10 +67,11 @@ public function featured(ForumRepository $fr, SubmissionRepository $sr, string $
6367
'listing' => 'featured',
6468
'submissions' => $submissions,
6569
'sort_by' => $sortBy,
70+
'announcement' => $siteConfig->getAnnouncement(),
6671
]);
6772
}
6873

69-
public function subscribed(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page) {
74+
public function subscribed(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page, ForumConfiguration $siteConfig) {
7075
$this->denyAccessUnlessGranted('ROLE_USER');
7176

7277
$forums = $fr->findSubscribedForumNames($this->getUser());
@@ -84,6 +89,7 @@ public function subscribed(ForumRepository $fr, SubmissionRepository $sr, string
8489
'listing' => 'subscribed',
8590
'sort_by' => $sortBy,
8691
'submissions' => $submissions,
92+
'announcement' => $siteConfig->getAnnouncement(),
8793
]);
8894
}
8995

@@ -94,7 +100,7 @@ public function subscribed(ForumRepository $fr, SubmissionRepository $sr, string
94100
*
95101
* @return Response
96102
*/
97-
public function all(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page) {
103+
public function all(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page, ForumConfiguration $siteConfig) {
98104
# Added for v1.
99105
$admin = PermissionsChecker::isAdmin($this->getUser());
100106
$forums = $fr->findAllForumNames();
@@ -105,10 +111,11 @@ public function all(ForumRepository $fr, SubmissionRepository $sr, string $sortB
105111
'listing' => 'all',
106112
'sort_by' => $sortBy,
107113
'submissions' => $submissions,
114+
'announcement' => $siteConfig->getAnnouncement(),
108115
]);
109116
}
110117

111-
public function moderated(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page) {
118+
public function moderated(ForumRepository $fr, SubmissionRepository $sr, string $sortBy, int $page, ForumConfiguration $siteConfig) {
112119
$this->denyAccessUnlessGranted('ROLE_USER');
113120

114121
$forums = $fr->findModeratedForumNames($this->getUser());
@@ -119,6 +126,7 @@ public function moderated(ForumRepository $fr, SubmissionRepository $sr, string
119126
'listing' => 'moderated',
120127
'sort_by' => $sortBy,
121128
'submissions' => $submissions,
129+
'announcement' => $siteConfig->getAnnouncement(),
122130
]);
123131
}
124132

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace App\Controller;
4+
5+
use App\Entity\User;
6+
use App\Entity\ForumConfiguration;
7+
use App\Repository\ForumRepository;
8+
use App\Repository\ForumConfigurationRepository;
9+
use App\Repository\SubmissionRepository;
10+
use Symfony\Component\HttpFoundation\Response;
11+
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
12+
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
13+
use App\Form\ForumConfigurationType;
14+
use App\Form\Model\ForumConfigurationData;
15+
use Doctrine\ORM\EntityManager;
16+
use Symfony\Component\HttpFoundation\Request;
17+
18+
19+
/**
20+
* @IsGranted("ROLE_ADMIN")
21+
*/
22+
final class FrontPageConfigurationController extends AbstractController {
23+
public function frontPageConfig(ForumRepository $fr, SubmissionRepository $sr, ForumConfigurationRepository $fcr, EntityManager $em, Request $request) {
24+
$data = new ForumConfigurationData($fcr->findSitewide());
25+
26+
$form = $this->createForm(ForumConfigurationType::class, $data);
27+
$form->handleRequest($request);
28+
29+
$message = "";
30+
31+
if ($form->isSubmitted() && $form->isValid()) {
32+
$fc = $data->toForumConfiguration();
33+
34+
// For sitewide settings, we need to force this to null.
35+
$fc->setForumId(null);
36+
37+
if($fc->getId() == null || trim($fc->getId()) == "")
38+
$em->persist($fc);
39+
else
40+
$em->merge($fc);
41+
42+
$em->flush();
43+
44+
// After saving, pull the data back down again.
45+
$data = new ForumConfigurationData($fcr->findSitewide());
46+
$form = $this->createForm(ForumConfigurationType::class, $data);
47+
48+
$message = "front_page_configuration_form.message_saved";
49+
}
50+
51+
return $this->render('frontpageconfig/frontpageconfig.html.twig', [
52+
'form' => $form->createView(),
53+
'message' => $message,
54+
]);
55+
}
56+
}

src/Entity/ForumConfiguration.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace App\Entity;
4+
5+
use Doctrine\Common\Collections\ArrayCollection;
6+
use Doctrine\Common\Collections\Collection;
7+
use Doctrine\Common\Collections\Criteria;
8+
use Doctrine\Common\Collections\Selectable;
9+
use Doctrine\ORM\Mapping as ORM;
10+
use Pagerfanta\Adapter\DoctrineCollectionAdapter;
11+
use Pagerfanta\Adapter\DoctrineSelectableAdapter;
12+
use Pagerfanta\Pagerfanta;
13+
14+
/**
15+
* @ORM\Entity(repositoryClass="App\Repository\ForumConfigurationRepository")
16+
* @ORM\Table(name="forum_configuration")
17+
*/
18+
class ForumConfiguration {
19+
/**
20+
* @ORM\Column(type="bigint")
21+
* @ORM\GeneratedValue(strategy="AUTO")
22+
* @ORM\Id()
23+
*
24+
* @var int|null
25+
*/
26+
private $id;
27+
28+
/**
29+
* @ORM\Column(type="bigint", nullable=true)
30+
*
31+
* @var int|null
32+
*/
33+
private $forumId;
34+
35+
/**
36+
* @ORM\Column(type="text", nullable=true)
37+
*
38+
* @var string
39+
*/
40+
private $announcement;
41+
42+
public function __construct($forumId) {
43+
$this->forumId = $forumId;
44+
}
45+
46+
public function getId() {
47+
return $this->id;
48+
}
49+
50+
public function setId($id) {
51+
$this->id = $id;
52+
}
53+
54+
public function getForumId() {
55+
return $this->forumId;
56+
}
57+
58+
public function setForumId($forumId) {
59+
$this->forumId = $forumId;
60+
}
61+
62+
public function getAnnouncement() {
63+
return $this->announcement;
64+
}
65+
66+
public function setAnnouncement($announcement) {
67+
$this->announcement = $announcement;
68+
}
69+
}

src/Form/ForumConfigurationType.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace App\Form;
4+
5+
use App\Form\Model\ForumConfigurationData;
6+
use Symfony\Component\Form\AbstractType;
7+
use App\Form\Type\MarkdownType;
8+
use Symfony\Component\Form\Extension\Core\Type\TextType;
9+
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
10+
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
11+
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
12+
use Symfony\Component\Form\FormBuilderInterface;
13+
use Symfony\Component\OptionsResolver\OptionsResolver;
14+
15+
class ForumConfigurationType extends AbstractType {
16+
public function buildForm(FormBuilderInterface $builder, array $options) {
17+
$builder
18+
->add('announcement', MarkdownType::class, [
19+
'label' => 'front_page_configuration_form.announcement',
20+
'required' => false
21+
])
22+
->add('id', HiddenType::class, [])
23+
->add('forumId', HiddenType::class, [])
24+
->add('submit', SubmitType::class, [
25+
'label' => 'front_page_configuration_form.save',
26+
]);
27+
}
28+
29+
public function configureOptions(OptionsResolver $resolver) {
30+
$resolver->setDefaults([
31+
'data_class' => ForumConfigurationData::class,
32+
]);
33+
}
34+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace App\Form\Model;
4+
5+
use App\Entity\ForumConfiguration;
6+
use Symfony\Component\Validator\Constraints as Assert;
7+
8+
class ForumConfigurationData {
9+
/**
10+
* @var int
11+
*/
12+
public $id;
13+
14+
/**
15+
* @var int|null
16+
*/
17+
public $forumId;
18+
19+
/**
20+
* @var string|null
21+
*/
22+
public $announcement;
23+
24+
public function __construct(ForumConfiguration $fc) {
25+
$this->id = $fc->getId();
26+
$this->forumId = $fc->getForumId();
27+
$this->announcement = $fc->getAnnouncement();
28+
}
29+
30+
public function toForumConfiguration(): ForumConfiguration {
31+
$fc = new ForumConfiguration($this->forumId);
32+
$fc->setId($this->id);
33+
$fc->setAnnouncement($this->announcement);
34+
35+
return $fc;
36+
}
37+
}

0 commit comments

Comments
 (0)