diff --git a/assets/js/party.manage.js b/assets/js/party.manage.js
index 9d133657..d75aba81 100644
--- a/assets/js/party.manage.js
+++ b/assets/js/party.manage.js
@@ -44,6 +44,11 @@ $(document).ready(function () {
$('.link_remove_participant').attr('disabled', false);
});
+ $('#btn_join').click(function (e) {
+ $('#join-mode').show();
+ $('#btn_join').attr('disabled', true);
+ });
+
if (Modernizr.inputtypes.date == true) {
$("#intracto_secretsantabundle_updatepartydetailstype_eventdate").click(function (e) {
$(this).datepicker({dateFormat: 'dd-mm-yy'});
diff --git a/src/Controller/Participant/JoinController.php b/src/Controller/Participant/JoinController.php
new file mode 100644
index 00000000..1171b3b4
--- /dev/null
+++ b/src/Controller/Participant/JoinController.php
@@ -0,0 +1,64 @@
+findOneBy(['joinurl' => $joinurl, 'joinmode' => 1, 'created' => 0]);
+
+ if (null !== $party) {
+ $addParticipantForm = $this->createForm(AddParticipantType::class, new Participant(), [
+ 'action' => $this->generateUrl('join_party', ['joinurl' => $party->getJoinurl()]),
+ ]);
+ $addParticipantForm->handleRequest($request);
+
+ if ($addParticipantForm->isSubmitted() && $addParticipantForm->isValid()) {
+ /** @var Participant $newParticipant */
+ $newParticipant = $addParticipantForm->getData();
+ $newParticipant->setParty($party);
+ $this->getDoctrine()->getManager()->persist($newParticipant);
+ $this->getDoctrine()->getManager()->flush();
+
+ return $this->redirectToRoute('join_party_joined', ['joinurl' => $party->getJoinurl()]);
+ }
+ }
+
+ return [
+ 'party' => $party,
+ 'form' => isset($addParticipantForm) ? $addParticipantForm->createView() : null,
+ ];
+ }
+
+ /**
+ * @Route("/joined/{joinurl}", name="join_party_joined")
+ * @Template("Participant/show/join.html.twig")
+ */
+ public function joinedAction(string $joinurl, PartyRepository $partyRepository)
+ {
+ /** @var Party $party */
+ $party = $partyRepository->findOneBy(['joinurl' => $joinurl, 'joinmode' => 1, 'created' => 0]);
+
+ return [
+ 'party' => $party,
+ 'form' => null,
+ ];
+ }
+}
diff --git a/src/Controller/Party/ManagementController.php b/src/Controller/Party/ManagementController.php
index b9cad72e..574082be 100644
--- a/src/Controller/Party/ManagementController.php
+++ b/src/Controller/Party/ManagementController.php
@@ -6,6 +6,7 @@
use App\Entity\Party;
use App\Form\Handler\AddParticipantFormHandler;
+use App\Form\Type\SetJoinModeType;
use App\Mailer\MailerService;
use App\Service\PartyService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
@@ -50,6 +51,9 @@ public function validAction(Party $party, Form $excludeForm = null)
$updatePartyDetailsForm = $this->createForm(UpdatePartyDetailsType::class, $party, [
'action' => $this->generateUrl('party_manage_update', ['listurl' => $party->getListurl()]),
]);
+ $setJoinModeForm = $this->createForm(SetJoinModeType::class, $party, [
+ 'action' => $this->generateUrl('party_manage_joinmode', ['listurl' => $party->getListurl()]),
+ ]);
if ($excludeForm === null) {
$excludeForm = $this->createForm(PartyExcludeParticipantType::class, $party, [
@@ -64,6 +68,7 @@ public function validAction(Party $party, Form $excludeForm = null)
'delete_party_csrf_token' => $this->get('security.csrf.token_manager')->getToken('delete_party'),
'delete_participant_csrf_token' => $this->get('security.csrf.token_manager')->getToken('delete_participant'),
'excludeForm' => $excludeForm->createView(),
+ 'setJoinModeForm' => $setJoinModeForm->createView(),
];
}
@@ -144,4 +149,30 @@ public function excludeAction(Request $request, Party $party)
return $this->redirectToRoute('party_manage', ['listurl' => $party->getListurl()]);
}
+
+ /**
+ * @Route("/manage/joinmode/{listurl}", name="party_manage_joinmode", methods={"POST"})
+ */
+ public function joinModeAction(Request $request, Party $party)
+ {
+ $party->setConfirmed(true);
+ $setJoinModeForm = $this->createForm(SetJoinModeType::class, $party, []);
+ $setJoinModeForm->handleRequest($request);
+
+ if ($setJoinModeForm->isSubmitted() && $setJoinModeForm->isValid()) {
+ if (($party->getJoinmode() == 1 && $party->getJoinurl() === null) || $request->request->get('reset', 0) == '1') {
+ // generate join URL
+ $party->setJoinurl(base_convert(sha1(uniqid((string) mt_rand(), true)), 16, 36));
+ }
+
+ $this->getDoctrine()->getManager()->persist($party);
+ $this->getDoctrine()->getManager()->flush();
+
+ $this->addFlash('success', $this->translator->trans('flashes.management.join_mode.success'));
+ } else {
+ $this->addFlash('danger', $this->translator->trans('flashes.management.join_mode.danger'));
+ }
+
+ return $this->redirectToRoute('party_manage', ['listurl' => $party->getListurl()]);
+ }
}
diff --git a/src/Entity/Party.php b/src/Entity/Party.php
index daaf9711..0a4f5cff 100644
--- a/src/Entity/Party.php
+++ b/src/Entity/Party.php
@@ -68,6 +68,12 @@ class Party
*/
private $confirmed;
+ /** @var ?string */
+ private $joinurl;
+
+ /** @var int */
+ private $joinmode = 0;
+
public function __construct($createDefaults = true)
{
$this->participants = new ArrayCollection();
@@ -81,6 +87,7 @@ public function __construct($createDefaults = true)
$this->creationdate = new \DateTime();
$this->message = '';
$this->location = '';
+ $this->joinurl = base_convert(sha1(uniqid((string) mt_rand(), true)), 16, 36);
}
/**
@@ -292,6 +299,26 @@ public function setConfirmed(bool $confirmed)
$this->confirmed = (string) $confirmed;
}
+ public function getJoinurl(): ?string
+ {
+ return $this->joinurl;
+ }
+
+ public function setJoinurl(?string $joinurl): void
+ {
+ $this->joinurl = $joinurl;
+ }
+
+ public function getJoinmode(): int
+ {
+ return $this->joinmode;
+ }
+
+ public function setJoinmode(int $joinmode): void
+ {
+ $this->joinmode = $joinmode;
+ }
+
/**
* @return array
*/
diff --git a/src/Form/Handler/JoinParticipantFormHandler.php b/src/Form/Handler/JoinParticipantFormHandler.php
new file mode 100644
index 00000000..662bdd27
--- /dev/null
+++ b/src/Form/Handler/JoinParticipantFormHandler.php
@@ -0,0 +1,50 @@
+translator = $translator;
+ $this->session = $session;
+ $this->em = $em;
+ }
+
+ public function handle(FormInterface $form, Request $request, Party $party): void
+ {
+ /** @var Participant $newParticipant */
+ $newParticipant = $form->getData();
+
+ if (!$request->isMethod('POST')) {
+ return;
+ }
+
+ if (!$form->handleRequest($request)->isValid()) {
+ $this->session->getFlashBag()->add('danger', $this->translator->trans('flashes.management.add_participant.danger'));
+
+ return;
+ }
+
+ $newParticipant->setParty($party);
+
+ $this->em->persist($newParticipant);
+ $this->em->flush();
+
+ $this->session->getFlashBag()->add('success', $this->translator->trans('flashes.management.add_participant.success'));
+ }
+}
diff --git a/src/Form/Type/SetJoinModeType.php b/src/Form/Type/SetJoinModeType.php
new file mode 100644
index 00000000..def6136d
--- /dev/null
+++ b/src/Form/Type/SetJoinModeType.php
@@ -0,0 +1,35 @@
+add(
+ 'join_mode',
+ ChoiceType::class,
+ [
+ 'attr' => ['data-hj-masked' => ''],
+ 'choices' => ['party_manage_valid.join_mode.mode.no' => '0', 'party_manage_valid.join_mode.mode.yes' => '1'],
+ 'expanded' => true,
+ 'multiple' => false,
+ ]
+ )
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults([
+ 'data_class' => Party::class,
+ ]);
+ }
+}
diff --git a/src/ORM/Mapping/Party.orm.xml b/src/ORM/Mapping/Party.orm.xml
index f50bf4de..c5068cf4 100644
--- a/src/ORM/Mapping/Party.orm.xml
+++ b/src/ORM/Mapping/Party.orm.xml
@@ -34,6 +34,9 @@
+ Instead of manually adding people, you can allow people to join your party by sharing a link.
+
When you start the party, people aren't able to join anymore (but you can still add them manually).
+
+ With the link you were given, you can add yourself to this Secret Santa party! + Please review the party details below, and fill out the form if you want to participate. + If you have questions regarding the party, please contact the person who created this party. +
+ joined: > +
+ We have added you to the party!
+
Note that you will not receive your match until the party is started.
+ If you have any questions regarding the party or want to change your info, you must contact the person who created this party!
+
+ The link you have used is not valid. There could be several reasons for this +