Improve error message for people trying to log in to the Patrons Circle

This commit is contained in:
Alex Cabal 2024-12-13 10:10:07 -06:00
parent 95d1b9e02e
commit cf5f488cae
9 changed files with 104 additions and 11 deletions

View file

@ -0,0 +1,7 @@
<?
namespace Enums;
enum ExceptionMessageType{
case Html;
case Text;
}

View file

@ -2,4 +2,5 @@
namespace Exceptions;
class AppException extends \Exception{
public \Enums\ExceptionMessageType $MessageType = \Enums\ExceptionMessageType::Text;
}

View file

@ -4,6 +4,7 @@ use function Safe\preg_replace;
class Formatter{
private static Transliterator $_Transliterator;
private static Parsedown $_MarkdownParser;
private static NumberFormatter $_NumberFormatter;
/**
* Remove diacritics from a string, leaving the now-unaccented characters in place.
@ -122,4 +123,32 @@ class Formatter{
return $output;
}
/**
* Format a float into a USD currency string. The result is prepended with `$`.
*
* @param ?float $amount The amount to format.
* @param bool $trimZeroCents If `$amount` has zero cents, don't include the cents value.
*/
public static function FormatCurrency(?float $amount, bool $trimZeroCents = false): string{
if($amount === null){
$amount = 0;
}
if(!isset(Formatter::$_NumberFormatter)){
Formatter::$_NumberFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
}
$output = Formatter::$_NumberFormatter->formatCurrency($amount, 'USD');
if($output === false){
$output = '$0.00';
}
if($trimZeroCents){
$output = preg_replace('/\.00$/u', '', $output);
}
return $output;
}
}

View file

@ -1,4 +1,6 @@
<?
use Exceptions\InvalidLoginException;
use Ramsey\Uuid\Uuid;
use Safe\DateTimeImmutable;
@ -72,7 +74,21 @@ class Session{
self::SetSessionCookie($this->SessionId);
}
catch(Exceptions\UserNotFoundException){
throw new Exceptions\InvalidLoginException();
// We couldn't find a *registered * `User`. But, often people make a small donation assuming it automatically adds them to the Patrons Circle. So, check if they made a donation less than 7 days ago, and if so, notify them about the requirements to join the Patrons Circle.
$ex = new Exceptions\InvalidLoginException();
try{
$user = User::GetByIdentifier($identifier);
/** @throws void */
if($user->LastPayment !== null && $user->LastPayment->Created > new DateTimeImmutable('7 days ago')){
$ex = new InvalidLoginException('<p>We couldnt find you in the Patrons Circle, but you recently ' . ($user->LastPayment->IsRecurring ? 'started a recurring' : 'made a one-time') . ' donation of ' . Formatter::FormatCurrency($user->LastPayment->Amount) . '.</p><p>To join the Patrons Circle, supporters must <a href="/donate#patrons-circle">start a recurring donation</a> of ' . Formatter::FormatCurrency(PATRONS_CIRCLE_MONTHLY_COST, true) . '/month or more, or <a href="/donate#patrons-circle">make a one-time donation</a> of ' . Formatter::FormatCurrency(PATRONS_CIRCLE_YEARLY_COST, true) . ' or more to join for one year.</p><p>Once you join the Patrons Circle, youll be able to log in and access member benefits.</p>');
$ex->MessageType = Enums\ExceptionMessageType::Html;
}
}
catch(Exceptions\UserNotFoundException){
// Pass.
}
throw $ex;
}
}

View file

@ -11,6 +11,7 @@ use function Safe\preg_match;
* @property string $Url
* @property ?Patron $Patron
* @property ?NewsletterSubscription $NewsletterSubscription
* @property ?Payment $LastPayment
*/
class User{
use Traits\Accessor;
@ -27,6 +28,7 @@ class User{
protected bool $_IsRegistered;
/** @var array<Payment> $_Payments */
protected array $_Payments;
protected ?Payment $_LastPayment;
protected Benefits $_Benefits;
protected string $_Url;
protected ?Patron $_Patron;
@ -87,6 +89,20 @@ class User{
return $this->_Payments;
}
protected function GetLastPayment(): ?Payment{
if(!isset($this->_LastPayment)){
$this->_LastPayment = Db::Query('
SELECT *
from Payments
where UserId = ?
order by Created desc
limit 1
', [$this->UserId], Payment::class)[0] ?? null;
}
return $this->_LastPayment;
}
protected function GetBenefits(): Benefits{
if(!isset($this->_Benefits)){
if(isset($this->UserId)){