<?php
namespace Bidcoz\Bundle\FrontendBundle\Controller;
use Bidcoz\Bundle\CoreBundle\Controller\CoreController;
use Bidcoz\Bundle\CoreBundle\Entity\Campaign;
use Bidcoz\Bundle\CoreBundle\Entity\Organization;
use Bidcoz\Bundle\CoreBundle\Entity\Proxy\RegistrationPurchaseProxy;
use Bidcoz\Bundle\CoreBundle\Entity\User;
use Bidcoz\Bundle\CoreBundle\Entity\Volunteer\Assignment;
use Bidcoz\Bundle\CoreBundle\Entity\Volunteer\Task;
use Bidcoz\Bundle\FrontendBundle\Form\Type\RegistrationPurchaseType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/{orgSlug}/{campaignSlug}/crewup")
* @IsGranted("VIEW", subject="organization")
* @IsGranted("FRONT_END", subject="campaign")
*/
class VolunteerController extends CoreController
{
/**
* @Route("", name="campaign_volunteer")
*/
public function volunteerAction(Organization $organization, Campaign $campaign)
{
$tasks = $this->getRepository('Volunteer\Task')->findAllForCampaign($campaign);
$loggedUser = $this->getUser();
return $this->render('@BidcozFrontend/Campaign/Volunteer/index.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'tasks' => $tasks,
'loggedUser' => $loggedUser
]);
}
/**
* @Route("/task/{taskId}", name="campaign_volunteer_for_task")
*
* @ParamConverter("task", class="Bidcoz\Bundle\CoreBundle\Entity\Volunteer\Task", options={"id" = "taskId"})
*/
public function volunteerForTaskAction(Request $request, Organization $organization, Campaign $campaign, Task $task)
{
$user = $this->getUser();
if (!$user) {
// Redirect unauthenticated users to campaign login with target back to this action
$path = $this->generateUrl('campaign_login_user', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
'_target_path' => $request->getRequestUri(),
]);
return $this->redirect($path);
}
if ('POST' === $request->getMethod()) {
$assignment = $this->getEntityManager()->getRepository(Assignment::class)->findOneBy(['user' => $user, 'task' => $task]);
if ($assignment === null) {
$this->getVolunteerManager()->createTaskAssignment($task, $user);
$this->getEntityManager()->flush();
}
$this->addFlash('success', sprintf('You have been assigned to %s', $task->getTitle()));
}
return $this->redirectToRoute('campaign_volunteer', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
/**
* Unassign the current user from a volunteer task.
*
* @Route("/task/{taskId}/release", name="campaign_volunteer_release_task")
* @ParamConverter("task", class="Bidcoz\Bundle\CoreBundle\Entity\Volunteer\Task", options={"id" = "taskId"})
*/
public function releaseTaskAction(Request $request, Organization $organization, Campaign $campaign, Task $task)
{
$user = $this->getUser();
if (!$user) {
// Redirect unauthenticated users to campaign login with target back to this action
$path = $this->generateUrl('campaign_login_user', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
'_target_path' => $request->getRequestUri(),
]);
return $this->redirect($path);
}
if ('POST' === $request->getMethod()) {
$em = $this->getEntityManager();
// Enforce 24-hour cutoff based on dateNeededFrom; allow if null
$startAt = $task->getDateNeededFrom();
if ($startAt instanceof \DateTimeInterface) {
$now = new \DateTimeImmutable('now');
$diffSeconds = $startAt->getTimestamp() - $now->getTimestamp();
if ($diffSeconds <= 24 * 3600) {
$contactUrl = $this->generateUrl('campaign_contact', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
$this->addFlash('warning', "You're an important part of this crew! Since this tasks starts in less than 24 hours, <a href=\"$contactUrl\" class=\"text-primary\">please contact the event administrator</a> if you need to cancel so we can make sure your role is covered.");
return $this->redirectToRoute('campaign_volunteer', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
}
// Remove all of the user's assignments for this task (in case of duplicates)
$assignments = $em->getRepository(Assignment::class)->findBy(['user' => $user, 'task' => $task]);
if ($assignments) {
foreach ($assignments as $assignment) {
$em->remove($assignment);
}
$em->flush();
// Notify contact administrators that a spot has opened up
$volunteerName = method_exists($user, 'getName') && $user->getName() ? $user->getName() : trim(($user->getFirstName() ?? '') . ' ' . ($user->getLastName() ?? ''));
$this->getEmailManager()->sendEmailToAdmins($campaign, 'signup.cancelled', [
'volunteerName' => $volunteerName,
'taskName' => $task->getTitle(),
]);
$this->addFlash('success', sprintf('You have been unassigned from %s', $task->getTitle()));
} else {
// Not assigned; no action needed, but provide feedback
$this->addFlash('info', 'You were not assigned to this task.');
}
}
return $this->redirectToRoute('campaign_volunteer', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
protected function createRegistrationProxy(Task $task, Campaign $campaign)
{
$user = $this->getUser();
$questions = $this->getRepository('Volunteer\RegistrationQuestion')->findActiveByCampaign($campaign);
$registrationAnswers = array_map(function ($registrationQuestion) use ($user) {
$question = $registrationQuestion->getQuestion();
return $this->getQuestionManager()->createRegistrationAnswer($question, $user);
}, $questions);
$proxy = new RegistrationPurchaseProxy($task);
$proxy->setRegistrationAnswers($registrationAnswers);
return $proxy;
}
protected function getPurchaseRegistrationFormOptions(Campaign $campaign, Task $task, User $user)
{
return [
'require_name' => $task->getRequireName(),
'require_address' => $task->getRequireAddress(),
'require_email' => $task->getRequireEmail(),
'require_phone' => $task->getRequirePhone(),
'require_waiver' => $campaign->getRequireRegistrationWaiver(),
'waiver_text' => $campaign->getRegistrationWaiver(),
'user' => $user,
];
}
protected function getPurchaseRegistrationForm(RegistrationPurchaseProxy $proxy, array $options)
{
return $this->createForm(RegistrationPurchaseType::class, $proxy, $options);
}
}