mirror of
https://github.com/standardebooks/web.git
synced 2025-07-06 06:40:33 -04:00
Improve error message for people trying to log in to the Patrons Circle
This commit is contained in:
parent
95d1b9e02e
commit
cf5f488cae
9 changed files with 104 additions and 11 deletions
7
lib/Enums/ExceptionMessageType.php
Normal file
7
lib/Enums/ExceptionMessageType.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum ExceptionMessageType{
|
||||
case Html;
|
||||
case Text;
|
||||
}
|
|
@ -2,4 +2,5 @@
|
|||
namespace Exceptions;
|
||||
|
||||
class AppException extends \Exception{
|
||||
public \Enums\ExceptionMessageType $MessageType = \Enums\ExceptionMessageType::Text;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 couldn’t 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, you’ll be able to log in and access member benefits.</p>');
|
||||
$ex->MessageType = Enums\ExceptionMessageType::Html;
|
||||
}
|
||||
}
|
||||
catch(Exceptions\UserNotFoundException){
|
||||
// Pass.
|
||||
}
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
lib/User.php
16
lib/User.php
|
@ -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)){
|
||||
|
|
|
@ -56,7 +56,7 @@ $digits = str_split(str_pad((string)$current, 3, "0", STR_PAD_LEFT))
|
|||
</div>
|
||||
<p>Our fiscal sponsor, <a href="https://www.fracturedatlas.org">Fractured Atlas</a>, is celebrating the twenty-year anniversary of their fiscal sponsorship program by <a href="https://media.fracturedatlas.org/what-would-you-do-with-an-extra-1000">distributing $1,000 to twenty different projects</a>.</p>
|
||||
<p><strong>Each one-time donation of any amount to Standard Ebooks through <?= $deadline ?> gives us one entry in this $1,000 giveaway.</strong> The more donations we receive through <?= $deadline ?>, the more chances we have to win!</p>
|
||||
<p><strong>This is a great time to <a href="/donate#patrons-circle">join our Patrons Circle</a> with a donation of $<?= number_format(PATRONS_CIRCLE_YEARLY_COST) ?>.</strong> Not only will your donation support us directly, but it’ll give us one more entry in this big giveaway.</p>
|
||||
<p><strong>This is a great time to <a href="/donate#patrons-circle">join our Patrons Circle</a> with a donation of <?= Formatter::FormatCurrency(PATRONS_CIRCLE_YEARLY_COST, true) ?>.</strong> Not only will your donation support us directly, but it’ll give us one more entry in this big giveaway.</p>
|
||||
<p>Will you show your support for free, beautiful digital literature?</p>
|
||||
<? if($showDonateButton){ ?>
|
||||
<p class="donate-button">
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* @var ?Exception $exception
|
||||
*/
|
||||
|
||||
use Exceptions\AppException;
|
||||
|
||||
if($exception === null){
|
||||
return;
|
||||
}
|
||||
|
@ -18,8 +20,18 @@ else{
|
|||
?>
|
||||
<ul class="message error">
|
||||
<? foreach($exceptions as $ex){ ?>
|
||||
<?
|
||||
$message = $ex->getMessage();
|
||||
if($message == ''){
|
||||
$message = 'An error occurred.';
|
||||
}
|
||||
|
||||
if(!($ex instanceof AppException) || $ex->MessageType == Enums\ExceptionMessageType::Text){
|
||||
$message = '<p>' . str_replace('CAPTCHA', '<abbr class="acronym">CAPTCHA</abbr>', Formatter::EscapeHtml($message)) . '</p>';
|
||||
}
|
||||
?>
|
||||
<li>
|
||||
<p><? $message = $ex->getMessage(); if($message == ''){ $message = 'An error occurred.'; } ?><?= str_replace('CAPTCHA', '<abbr class="acronym">CAPTCHA</abbr>', Formatter::EscapeHtml($message)) ?></p>
|
||||
<?= $message ?>
|
||||
</li>
|
||||
<? } ?>
|
||||
</ul>
|
||||
|
|
|
@ -34,10 +34,10 @@ $newsletterSubscriberCount = floor(Db::QueryInt('
|
|||
<p>Membership in the Patrons Circle is limited to individuals only. Organizations, please see <a href="#corporate-sponsors">corporate sponsorship</a> instead.</p>
|
||||
<div class="join-patrons-circle-callout">
|
||||
<h3>Join now</h3>
|
||||
<p><i>Join the Patrons Circle by starting a recurring donation of $<?= number_format(PATRONS_CIRCLE_MONTHLY_COST) ?>/month or more, or join for one year with a one-time donation of $<?= number_format(PATRONS_CIRCLE_YEARLY_COST) ?> or more.</i></p>
|
||||
<p><i>Join the Patrons Circle by starting a recurring donation of <?= Formatter::FormatCurrency(PATRONS_CIRCLE_MONTHLY_COST, true) ?>/month or more, or join for one year with a one-time donation of <?= Formatter::FormatCurrency(PATRONS_CIRCLE_YEARLY_COST, true) ?> or more.</i></p>
|
||||
<p class="button-row">
|
||||
<a href="https://fundraising.fracturedatlas.org/standard-ebooks/monthly_support" class="button">Donate $<?= number_format(PATRONS_CIRCLE_MONTHLY_COST) ?>/month or more</a>
|
||||
<a href="https://fundraising.fracturedatlas.org/standard-ebooks/general_support" class="button">Donate $<?= number_format(PATRONS_CIRCLE_YEARLY_COST) ?> or more</a>
|
||||
<a href="https://fundraising.fracturedatlas.org/standard-ebooks/monthly_support" class="button">Donate <?= Formatter::FormatCurrency(PATRONS_CIRCLE_MONTHLY_COST, true) ?>/month or more</a>
|
||||
<a href="https://fundraising.fracturedatlas.org/standard-ebooks/general_support" class="button">Donate <?= Formatter::FormatCurrency(PATRONS_CIRCLE_YEARLY_COST, true) ?> or more</a>
|
||||
</p>
|
||||
<p><strong>Important:</strong> We need to know your email address to be able to log you in to the Patrons Circle. Make sure to select either “List my name publicly” or “Don’t list publicly, but reveal to project” during checkout to be able to log in to the Patrons Circle.</p>
|
||||
</div>
|
||||
|
|
|
@ -87,11 +87,23 @@ catch(Exceptions\SeeOtherException $ex){
|
|||
</tr>
|
||||
<tr>
|
||||
<td>Cycle type:</td>
|
||||
<td><?= ucfirst($user->Patron->CycleType->value) ?></td>
|
||||
<td>
|
||||
<? if($user->Patron->CycleType !== null){ ?>
|
||||
<?= ucfirst($user->Patron->CycleType->value) ?>
|
||||
<? }else{ ?>
|
||||
<i>Not set</i>
|
||||
<? } ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Base cost:</td>
|
||||
<td>$<?= number_format($user->Patron->BaseCost) ?></td>
|
||||
<td>
|
||||
<? if($user->Patron->BaseCost !== null){ ?>
|
||||
<?= Formatter::FormatCurrency($user->Patron->BaseCost) ?>
|
||||
<? }else{ ?>
|
||||
<i>Not set</i>
|
||||
<? } ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Is anonymous:</td>
|
||||
|
@ -193,13 +205,13 @@ catch(Exceptions\SeeOtherException $ex){
|
|||
<? } ?>
|
||||
</td>
|
||||
<td>
|
||||
$<?= number_format($payment->Amount, 2) ?>
|
||||
<?= Formatter::FormatCurrency($payment->Amount) ?>
|
||||
</td>
|
||||
<td>
|
||||
$<?= number_format($payment->Fee, 2) ?>
|
||||
<?= Formatter::FormatCurrency($payment->Fee) ?>
|
||||
</td>
|
||||
<td>
|
||||
$<?= number_format($payment->Amount - $payment->Fee, 2) ?>
|
||||
<?= Formatter::FormatCurrency($payment->Amount - $payment->Fee) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?= $payment->ProcessorUrl ?>"><?= Formatter::EscapeHtml($payment->TransactionId) ?></a>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue