<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManagerInterface;
use Mollie\Api\MollieApiClient;
use App\Entity\Donations;
use App\Form\DonationsFormType;
use App\Form\DonationsFormType2;
class DonationsController extends AbstractController
{
private function generateRandomString($length = 11) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
$repository = $this->getDoctrine()->getRepository(Donations::class);
$db_result = $repository->findOneBy(array('id' => $randomString ));
if (!empty($db_result)){
$randomString = $this->generateRandomString();
}
return $randomString;
}
public function sidebar(Request $request) {
$form = $this->createForm(DonationsFormType::class);
$form->handleRequest($request);
$monthgoal=50.00;
$repository = $this->getDoctrine()->getRepository(Donations::class);
$donations = $repository->findAllThisMonth();
$donated = 0;
foreach ($donations as $i => $donation) {
$donated = $donated + $donation->getAmount();
}
$percentage = ( $donated * 100 ) / $monthgoal;
if ($percentage >= 100) {
$percentage = 100;
}
return $this->render('donations_sidebar.html.twig', [
'form' => $form->createView(),
'donated' => $donated,
'percentage' => $percentage,
'monthgoal' => $monthgoal
]);
}
/**
* @Route("/donations/make", name="donation_make")
*/
public function make(Request $request, EntityManagerInterface $em) {
if($_ENV['DISABLE_FORMS'] == "true") { return $this->render('maintenance_form_disabled.html.twig'); }
$redirect = array();
$form = $this->createForm(DonationsFormType::class);
$form->handleRequest($request);
if($request->query->get('referrer') != null && $request->query->get('amount') != null ) {
$redirect['referrer'] = $request->query->get('referrer');
$redirect['amount'] = $request->query->get('amount');
}
$donation = $form->getData();
if ($donation == null) {
return $this->render('donations_logon.html.twig', [
'form' => $form->createView(),
'amount' => 5
]);
}
if($donation->getAmount() < 1) {
$this->addFlash('error', $translator->trans("Donaties onder de 1 euro kunnen wij helaas niet in ontvangst nemen."));
return $this->redirectToRoute('frontpage');
}
if($redirect) {
$donation = new Donations;
$donation->setAmount($redirect['amount']);
}
if (!$this->isGranted('ROLE_USER') && $donation->getUserId() === null) {
$donation->setUserId("0");
$form = $this->createForm(DonationsFormType::class, $donation);
return $this->render('donations_logon.html.twig', [
'form' => $form->createView(),
'amount' => $donation->getAmount()
]);
} else {
$mollie = new \Mollie\Api\MollieApiClient();
$mollie->setApiKey($_ENV['MOLLIE_API_KEY']);
$donation->setAmount(number_format(round($donation->getAmount(), 2),2));
$donation->setOrderId("PATP-".$this->generateRandomString());
$donation->setTime(new \DateTime());
$donation->setTimeUpdated(new \DateTime());
if (!empty($this->getUser())) {
$donation->setUserId($this->getUser()->getId());
$donation->setUsername($this->getUser()->getUsername());
}
if ($_ENV['SITE_TYPE'] == 'live') {
$site_type = 'www';
} else {
$site_type = $_ENV['SITE_TYPE'];
}
$payment = $mollie->payments->create([
"amount" => [
"currency" => "EUR",
"value" => $donation->getAmount() // You must send the correct number of decimals, thus we enforce the use of strings
],
"description" => "Donation #".$donation->getOrderId(),
"redirectUrl" => "https://".$site_type.".paleontica.org/donations/checkout/{$donation->getOrderId()}",
"webhookUrl" => "https://".$site_type.".paleontica.org/donations/webhook",
"metadata" => [
"order_id" => $donation->getOrderId(),
"user_id" => $donation->getUserId(),
"username" => $donation->getUsername(),
],
]);
$donation->setStatus($payment->status);
$em->persist($donation);
$em->flush();
return $this->redirect($payment->getCheckoutUrl(),303);
}
}
/**
* @Route("/donations/webhook", name="donation_webhook")
*/
public function webhook(Request $request, EntityManagerInterface $em) {
$mollie = new \Mollie\Api\MollieApiClient();
$mollie->setApiKey($_ENV['MOLLIE_API_KEY']);
$payment = $mollie->payments->get($request->request->get("id"));
$repository = $this->getDoctrine()->getRepository(Donations::class);
$donation = $repository->findOneBy(array('order_id' => $payment->metadata->order_id));
$donation->setTimeUpdated(new \DateTime());
if($donation->getStatus() != 'paid') {
$donation->setStatus($payment->status);
}
$em->persist($donation);
$em->flush();
$response = new Response();
$response->headers->set('Content-Type', 'text/plain');
$response->setStatusCode(Response::HTTP_OK);
return $response;
#if ($payment->isPaid() && !$payment->hasRefunds() && !$payment->hasChargebacks()) {
/*
* The payment is paid and isn't refunded or charged back.
* At this point you'd probably want to start the process of delivering the product to the customer.
*/
#} elseif ($payment->isOpen()) {
/*
* The payment is open.
*/
#} elseif ($payment->isPending()) {
/*
* The payment is pending.
*/
#} elseif ($payment->isFailed()) {
/*
* The payment has failed.
*/
#} elseif ($payment->isExpired()) {
/*
* The payment is expired.
*/
#} elseif ($payment->isCanceled()) {
/*
* The payment has been canceled.
*/
#} elseif ($payment->hasRefunds()) {
/*
* The payment has been (partially) refunded.
* The status of the payment is still "paid"
*/
#} elseif ($payment->hasChargebacks()) {
/*
* The payment has been (partially) charged back.
* The status of the payment is still "paid"
*/
#}
}
/**
* @Route("/donations/checkout/{order_id}", name="donation_checkout")
*/
public function donated(string $order_id) {
$repository = $this->getDoctrine()->getRepository(Donations::class);
if ($this->isGranted('ROLE_USER')) {
$donation = $repository->findOneBy(array('order_id' => $order_id, 'user_id' => $this->getUser()->getId()));
} else {
$donation = $repository->findOneBy(array('order_id' => $order_id, 'user_id' => 0));
}
if($donation) {
return $this->render('donations_checkout.html.twig',[ 'not_authorized' => false, 'donation' => $donation ]);
} else {
return $this->render('donations_checkout.html.twig',[ 'not_authorized' => true, 'donation' => false ]);
}
}
/**
* @Route("/moderate/donations", name="donations_moderate")
*/
public function manage_donations(Request $request)
{
$this->denyAccessUnlessGranted('ROLE_MOD_DONATIONS');
$repository = $this->getDoctrine()->getRepository(Donations::class);
$donations = $repository->findBy(array('status' => 'paid'),array('time' => 'DESC'));
return $this->render('donations_moderate.html.twig', [
'donations' => $donations,
]);
}
}