billwerk_subscriptions-1.x-dev/src/Plugin/Action/BillwerkContractIdsFetchAndAssignAction.php
src/Plugin/Action/BillwerkContractIdsFetchAndAssignAction.php
<?php
declare(strict_types=1);
namespace Drupal\billwerk_subscriptions\Plugin\Action;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Action\ConfigurableActionBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\billwerk_subscriptions\Api;
use Drupal\billwerk_subscriptions\Subscriber;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a Fetch and assign Billwerk Contract IDs action.
*
* Fetch and assign Billwerk Contract IDs from Billwerk based on ExternalId =
* Drupal user id (UID). Always assigns the FIRST contract ID of the Billwerk
* Customer.
*
* @Action(
* id = "billwerk_subscriptions_fetch_and_assign_billwerk_contract_ids",
* label = @Translation("Fetch and assign Billwerk Contract ID by Billwerk ExternalId = Drupal UID."),
* type = "user",
* category = @Translation("Billwerk Subscriptions"),
* )
*
* @DCG
* For updating entity fields consider extending FieldUpdateActionBase.
* @see \Drupal\Core\Field\FieldUpdateActionBase
*
* @DCG
* In order to set up the action through admin interface the plugin has to be
* configurable.
* @see https://www.drupal.org/project/drupal/issues/2815301
* @see https://www.drupal.org/project/drupal/issues/2815297
*
* @DCG
* The whole action API is subject of change.
* @see https://www.drupal.org/project/drupal/issues/2011038
*/
final class BillwerkContractIdsFetchAndAssignAction extends ConfigurableActionBase implements ContainerFactoryPluginInterface {
/**
* {@inheritdoc}
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
private readonly Api $api,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
return new self(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('billwerk_subscriptions.api'),
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [
'refresh_subscription' => TRUE,
'overwrite_existing' => FALSE,
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$form['refresh_subscription'] = [
'#type' => 'checkbox',
'#title' => $this->t('Refresh subscription'),
'#description' => $this->t('Refresh the subscription after assigning the Billwerk Contract ID. Executes the typical refresh tasks, like updating Drupal Roles, user data, etc.. Typically you want this.'),
'#default_value' => $this->configuration['refresh_subscription'],
];
$form['overwrite_existing'] = [
'#type' => 'checkbox',
'#title' => $this->t('Overwrite existing'),
'#description' => $this->t("If enabled, also users existing Contract ID\'s field values will be overwritten. Be careful, typically you don't want this."),
'#default_value' => $this->configuration['overwrite_existing'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
$this->configuration['overwrite_existing'] = $form_state->getValue('overwrite_existing');
}
/**
* {@inheritdoc}
*/
public function access($entity, ?AccountInterface $account = NULL, $return_as_object = FALSE): AccessResultInterface|bool {
/** @var \Drupal\user\UserInterface $entity */
$access = $entity->access('update', $account, TRUE)
->andIf(AccessResult::allowedIfHasPermission($account, 'billwerk_subscriptions_fetch_assign_contract_ids'));
return $return_as_object ? $access : $access->isAllowed();
}
/**
* {@inheritdoc}
*/
public function execute(?UserInterface $user = NULL): void {
if ($user !== NULL) {
$subscriber = Subscriber::load($user);
if (empty($subscriber->getUserBillwerkContractId()) || $this->configuration['overwrite_existing']) {
$billwerkCustomerDto = $subscriber->billwerkLookupCustomerByUid();
if ($billwerkCustomerDto !== NULL) {
$billwerkCustomerId = $billwerkCustomerDto->getId();
$billwerkContracts = $this->api->getCustomerContracts($billwerkCustomerId);
if (!empty($billwerkContracts)) {
// We currently just use the first contract returned:
$subscriber->setUserBillwerkContractId($billwerkContracts[0]['Id']);
if ($this->configuration['refresh_subscription']) {
// Refresh the subscription.
$subscriber->refreshFromBillwerkContractSubscription();
}
}
}
}
}
}
}
