billwerk_subscriptions-1.x-dev/modules/billwerk_subscriptions_manage/src/Controller/BillwerkSubscriptionsManageController.php
modules/billwerk_subscriptions_manage/src/Controller/BillwerkSubscriptionsManageController.php
<?php
declare(strict_types=1);
namespace Drupal\billwerk_subscriptions_manage\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Utility\Error;
use Drupal\billwerk_subscriptions\LogHelper;
use Drupal\billwerk_subscriptions\Subscriber;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Returns responses for Billwerk Subscriptions SubscriptionJS routes.
*/
final class BillwerkSubscriptionsManageController extends ControllerBase {
/**
* The log helper service.
*
* @var \Drupal\billwerk_subscriptions\LogHelper
*/
protected LogHelper $logHelper;
/**
* The controller constructor.
*/
public function __construct(
private readonly BlockManagerInterface $pluginManagerBlock,
LogHelper $logHelper,
private readonly RendererInterface $renderer,
) {
$this->logHelper = $logHelper;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self {
return new self(
$container->get('plugin.manager.block'),
$container->get('billwerk_subscriptions.log_helper'),
$container->get('renderer'),
);
}
/**
* Build the current user subscription plugin block.
*/
public function currentUserSubscription(): array {
try {
// We use the existing block, no need to reinvent the wheel:
$config = $this->config('billwerk_subscriptions_manage.settings');
$plugin_block = $this->pluginManagerBlock->createInstance('billwerk_subscriptions_manage_billwerk_user_subscriptions', [
'source' => $config->get('page.settings.source'),
'show_active_subscription' => $config->get('page.settings.show_active_subscription'),
'show_active_components' => $config->get('page.settings.show_active_components'),
'no_active_components_text' => $config->get('page.settings.no_active_components_text'),
'show_change_plan_variant_button' => $config->get('page.settings.show_change_plan_variant_button'),
'show_cancel_plan_variant_button' => $config->get('page.settings.show_cancel_plan_variant_button'),
'show_components_subscribe_button' => $config->get('page.settings.show_components_subscribe_button'),
'show_components_unsubscribe_button' => $config->get('page.settings.show_components_unsubscribe_button'),
'modal_actions' => $config->get('page.settings.modal_actions'),
]);
$build = $plugin_block->build();
}
catch (\Exception $e) {
// Log exception:
Error::logException($this->getLogger('billwerk_subscriptions_manage'), $e);
// Show error message:
// @improve once https://www.drupal.org/project/drupal/issues/3439618 is fixed:
$build = [
'message' => [
'#theme' => 'status_messages',
'#message_list' => [
'error' => [
$this->t('The website encountered an unexpected error. Try again later.'),
],
],
'#status_headings' => [
'error' => $this
->t('Error message'),
],
],
];
}
return $build;
}
/**
* Confirmation page after a subscription has been changed (return URL).
*
* Executes the required billwerk finalize callback.
*
* @return array
* The render array.
*/
public function finishedChange(): array {
$confirmationMessage = $this->config('billwerk_subscriptions_manage.settings')->get('subscription_changed_message');
if (!empty($confirmationMessage)) {
$message = [
'#type' => 'processed_text',
'#text' => $confirmationMessage['value'],
'#format' => $confirmationMessage['format'],
'#attached' => [
'library' => 'billwerk_subscriptions_manage/billwerk_subscriptions_manage',
'drupalSettings' => [
'billwerk_context' => 'finalize',
],
],
];
$build['content'] =
[
'#theme' => 'status_messages',
'#message_list' => [
'status' => [
$this->renderer->renderInIsolation($message),
],
],
'#status_headings' => [
'status' => $this->t('Status message'),
],
];
}
return $build;
}
/**
* Confirmation page after a subscription has been canceled (return URL).
*
* Executes the required billwerk finalize callback.
*
* @improve: Check if this is ever used / called!
*
* @return array
* The render array.
*/
public function finishedCancel(): array {
$confirmationMessage = $this->config('billwerk_subscriptions_manage.settings')->get('subscription_canceled_message');
if (!empty($confirmationMessage)) {
$message = [
'#type' => 'processed_text',
'#text' => $confirmationMessage['value'],
'#format' => $confirmationMessage['format'],
'#attached' => [
'library' => 'billwerk_subscriptions_manage/billwerk_subscriptions_manage',
'drupalSettings' => [
'billwerk_context' => 'finalize',
],
],
];
$build['content'] =
[
'#theme' => 'status_messages',
'#message_list' => [
'status' => [
$this->renderer->renderInIsolation($message),
],
],
'#status_headings' => [
'status' => $this->t('Status message'),
],
];
}
return $build;
}
/**
* Checks access for a specific request.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The acting user to check access for.
* @param \Drupal\Core\Session\AccountInterface $user
* The subscriber user which is being viewed.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function access(AccountInterface $account, AccountInterface $user) {
if ($account->isAnonymous()) {
// Return early for anonymous:
return AccessResult::forbidden('Anonymous user may never be a subscriber');
}
try {
$subscriber = Subscriber::loadByDrupalUid((int) $user->id());
}
catch (\Exception $e) {
$this->logHelper->logException($e);
return AccessResult::forbidden($e->getMessage());
}
return AccessResult::allowedIf($subscriber->hasUserBillwerkContractId())
->andIf(AccessResult::allowedIfHasPermissions($account, [
'billwerk_subscriptions_manage_change_own_subscription',
'billwerk_subscriptions_manage_cancel_own_subscription',
], 'OR'));
}
}
