-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: Basic membership and things around it
- Loading branch information
Showing
29 changed files
with
862 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Migrations; | ||
|
||
use Doctrine\DBAL\Schema\Schema; | ||
use Doctrine\Migrations\AbstractMigration; | ||
|
||
/** | ||
* Auto-generated Migration: Please modify to your needs! | ||
*/ | ||
final class Version20241230144600 extends AbstractMigration | ||
{ | ||
public function getDescription(): string | ||
{ | ||
return ''; | ||
} | ||
|
||
public function up(Schema $schema): void | ||
{ | ||
// this up() migration is auto-generated, please modify it to your needs | ||
$this->addSql('CREATE TABLE membership (ends_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, card_last4_digits VARCHAR(255) DEFAULT NULL, id UUID NOT NULL, stripe_subscription_id VARCHAR(255) DEFAULT NULL, stripe_plan_id VARCHAR(255) DEFAULT NULL, billing_period_ends_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, player_id UUID NOT NULL, PRIMARY KEY(id))'); | ||
$this->addSql('CREATE INDEX IDX_86FFD28599E6F5DF ON membership (player_id)'); | ||
$this->addSql('ALTER TABLE membership ADD CONSTRAINT FK_86FFD28599E6F5DF FOREIGN KEY (player_id) REFERENCES player (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); | ||
$this->addSql('ALTER TABLE player ADD stripe_customer_id VARCHAR(255) DEFAULT NULL'); | ||
} | ||
|
||
public function down(Schema $schema): void | ||
{ | ||
// this down() migration is auto-generated, please modify it to your needs | ||
$this->addSql('ALTER TABLE membership DROP CONSTRAINT FK_86FFD28599E6F5DF'); | ||
$this->addSql('DROP TABLE membership'); | ||
$this->addSql('ALTER TABLE player DROP stripe_customer_id'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Migrations; | ||
|
||
use Doctrine\DBAL\Schema\Schema; | ||
use Doctrine\Migrations\AbstractMigration; | ||
|
||
/** | ||
* Auto-generated Migration: Please modify to your needs! | ||
*/ | ||
final class Version20241230144632 extends AbstractMigration | ||
{ | ||
public function getDescription(): string | ||
{ | ||
return ''; | ||
} | ||
|
||
public function up(Schema $schema): void | ||
{ | ||
// this up() migration is auto-generated, please modify it to your needs | ||
$this->addSql('DROP INDEX idx_86ffd28599e6f5df'); | ||
$this->addSql('CREATE UNIQUE INDEX UNIQ_86FFD28599E6F5DF ON membership (player_id)'); | ||
} | ||
|
||
public function down(Schema $schema): void | ||
{ | ||
// this down() migration is auto-generated, please modify it to your needs | ||
$this->addSql('DROP INDEX UNIQ_86FFD28599E6F5DF'); | ||
$this->addSql('CREATE INDEX idx_86ffd28599e6f5df ON membership (player_id)'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Migrations; | ||
|
||
use Doctrine\DBAL\Schema\Schema; | ||
use Doctrine\Migrations\AbstractMigration; | ||
|
||
/** | ||
* Auto-generated Migration: Please modify to your needs! | ||
*/ | ||
final class Version20241230165038 extends AbstractMigration | ||
{ | ||
public function getDescription(): string | ||
{ | ||
return ''; | ||
} | ||
|
||
public function up(Schema $schema): void | ||
{ | ||
// this up() migration is auto-generated, please modify it to your needs | ||
$this->addSql('ALTER TABLE membership DROP card_last4_digits'); | ||
$this->addSql('ALTER TABLE membership DROP stripe_plan_id'); | ||
} | ||
|
||
public function down(Schema $schema): void | ||
{ | ||
// this down() migration is auto-generated, please modify it to your needs | ||
$this->addSql('ALTER TABLE membership ADD card_last4_digits VARCHAR(255) DEFAULT NULL'); | ||
$this->addSql('ALTER TABLE membership ADD stripe_plan_id VARCHAR(255) DEFAULT NULL'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Controller; | ||
|
||
use Auth0\Symfony\Models\User; | ||
use SpeedPuzzling\Web\Services\MembershipManagement; | ||
use SpeedPuzzling\Web\Services\RetrieveLoggedUserProfile; | ||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Attribute\Route; | ||
use Symfony\Component\Security\Http\Attribute\CurrentUser; | ||
|
||
final class BillingPortalController extends AbstractController | ||
{ | ||
public function __construct( | ||
readonly private MembershipManagement $membershipManagement, | ||
readonly private RetrieveLoggedUserProfile $retrieveLoggedUserProfile, | ||
) { | ||
} | ||
|
||
#[Route( | ||
path: [ | ||
'cs' => '/clenstvi/platebni-portal', | ||
'en' => '/en/memberstip/billing-portal', | ||
], | ||
name: 'billing_portal', | ||
)] | ||
public function __invoke(#[CurrentUser] User $user): Response | ||
{ | ||
$player = $this->retrieveLoggedUserProfile->getProfile(); | ||
|
||
if ($player === null) { | ||
return $this->redirectToRoute('homepage'); | ||
} | ||
|
||
$customerId = $player->stripeCustomerId; | ||
|
||
if ($customerId === null) { | ||
return $this->redirectToRoute('membership'); | ||
} | ||
|
||
$portalUrl = $this->membershipManagement->getBillingPortalUrl($customerId); | ||
|
||
return $this->redirect($portalUrl, 303); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Controller; | ||
|
||
use Auth0\Symfony\Models\User; | ||
use SpeedPuzzling\Web\Services\MembershipManagement; | ||
use SpeedPuzzling\Web\Services\RetrieveLoggedUserProfile; | ||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Attribute\Route; | ||
use Symfony\Component\Security\Http\Attribute\CurrentUser; | ||
|
||
final class BuyMembershipController extends AbstractController | ||
{ | ||
public function __construct( | ||
readonly private MembershipManagement $membershipManagement, | ||
readonly private RetrieveLoggedUserProfile $retrieveLoggedUserProfile, | ||
) { | ||
} | ||
|
||
#[Route( | ||
path: [ | ||
'cs' => '/koupit-clenstvi', | ||
'en' => '/en/buy-membership', | ||
], | ||
name: 'buy_membership', | ||
)] | ||
public function __invoke(#[CurrentUser] User $user): Response | ||
{ | ||
$player = $this->retrieveLoggedUserProfile->getProfile(); | ||
|
||
if ($player === null) { | ||
return $this->redirectToRoute('homepage'); | ||
} | ||
|
||
$paymentUrl = $this->membershipManagement->getMembershipPaymentUrl(); | ||
|
||
return $this->redirect($paymentUrl, 303); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Controller; | ||
|
||
use Auth0\Symfony\Models\User; | ||
use SpeedPuzzling\Web\Exceptions\MembershipNotFound; | ||
use SpeedPuzzling\Web\Query\GetPlayerMembership; | ||
use SpeedPuzzling\Web\Services\RetrieveLoggedUserProfile; | ||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Attribute\Route; | ||
use Symfony\Component\Security\Http\Attribute\CurrentUser; | ||
|
||
final class MembershipController extends AbstractController | ||
{ | ||
public function __construct( | ||
readonly private GetPlayerMembership $getPlayerMembership, | ||
readonly private RetrieveLoggedUserProfile $retrieveLoggedUserProfile, | ||
) { | ||
} | ||
|
||
#[Route( | ||
path: [ | ||
'cs' => '/clenstvi/', | ||
'en' => '/en/membership', | ||
], | ||
name: 'membership', | ||
)] | ||
public function __invoke(#[CurrentUser] User $user): Response | ||
{ | ||
$player = $this->retrieveLoggedUserProfile->getProfile(); | ||
|
||
if ($player === null) { | ||
return $this->redirectToRoute('homepage'); | ||
} | ||
|
||
try { | ||
$membership = $this->getPlayerMembership->byId($player->playerId); | ||
} catch (MembershipNotFound) { | ||
$membership = null; | ||
} | ||
|
||
return $this->render('membership.html.twig', [ | ||
'membership' => $membership, | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Controller; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Attribute\Route; | ||
|
||
final class StripeCheckoutCancelController extends AbstractController | ||
{ | ||
#[Route( | ||
path: [ | ||
'cs' => '/nakup-clenstvi-zrusen', | ||
'en' => '/en/membership-checkout-cancel', | ||
], | ||
name: 'stripe_checkout_cancel', | ||
)] | ||
public function __invoke(null|string $code): Response | ||
{ | ||
return $this->render('membership-checkout-cancel.html.twig'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Controller; | ||
|
||
use SpeedPuzzling\Web\Message\SubscribeMembership; | ||
use SpeedPuzzling\Web\Services\RetrieveLoggedUserProfile; | ||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Messenger\MessageBusInterface; | ||
use Symfony\Component\Routing\Attribute\Route; | ||
use Symfony\Component\Security\Core\User\UserInterface; | ||
use Symfony\Component\Security\Http\Attribute\CurrentUser; | ||
|
||
final class StripeCheckoutSuccessController extends AbstractController | ||
{ | ||
public function __construct( | ||
readonly private MessageBusInterface $messageBus, | ||
readonly private RetrieveLoggedUserProfile $retrieveLoggedUserProfile, | ||
) { | ||
} | ||
|
||
#[Route( | ||
path: [ | ||
'cs' => '/uspesny-nakup-clenstvi/{sessionId}', | ||
'en' => '/en/membership-checkout-success/{sessionId}', | ||
], | ||
name: 'stripe_checkout_success', | ||
)] | ||
public function __invoke(#[CurrentUser] UserInterface $user, string $sessionId): Response | ||
{ | ||
$player = $this->retrieveLoggedUserProfile->getProfile(); | ||
|
||
if ($player === null) { | ||
return $this->redirectToRoute('my_profile'); | ||
} | ||
|
||
$this->messageBus->dispatch( | ||
new SubscribeMembership( | ||
$player->playerId, | ||
$sessionId, | ||
), | ||
); | ||
|
||
$this->addFlash('success', 'flashes.membership_subscribed_successfully'); | ||
|
||
return $this->redirectToRoute('membership'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace SpeedPuzzling\Web\Controller; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Attribute\Route; | ||
|
||
final class StripeWebhookController extends AbstractController | ||
{ | ||
#[Route( | ||
Check failure on line 12 in src/Controller/StripeWebhookController.php GitHub Actions / phpstan
|
||
path: [ | ||
'cs' => '/scan-puzzli/{code}', | ||
'en' => '/en/scan-puzzle/{code}', | ||
], | ||
name: 'stripe_webhook', | ||
)] | ||
public function __invoke(null|string $code): Response | ||
{ | ||
} | ||
} |
Oops, something went wrong.