You are here

class CompletionRegister in Commerce Core 8.2

Provides the registration after checkout pane.

Plugin annotation


@CommerceCheckoutPane(
  id = "completion_register",
  label = @Translation("Guest registration after checkout"),
  display_label = @Translation("Account information"),
  default_step = "complete",
)

Hierarchy

Expanded class hierarchy of CompletionRegister

File

modules/checkout/src/Plugin/Commerce/CheckoutPane/CompletionRegister.php, line 31

Namespace

Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane
View source
class CompletionRegister extends CheckoutPaneBase implements CheckoutPaneInterface, ContainerFactoryPluginInterface {

  /**
   * The credentials check flood controller.
   *
   * @var \Drupal\commerce\CredentialsCheckFloodInterface
   */
  protected $credentialsCheckFlood;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * The user authentication object.
   *
   * @var \Drupal\user\UserAuthInterface
   */
  protected $userAuth;

  /**
   * The client IP address.
   *
   * @var string
   */
  protected $clientIp;

  /**
   * The event dispatcher.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * The order assignment.
   *
   * @var \Drupal\commerce_order\OrderAssignmentInterface
   */
  protected $orderAssignment;

  /**
   * The user storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $userStorage;

  /**
   * Constructs a new CompletionRegister object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowInterface $checkout_flow
   *   The parent checkout flow.
   * @param \Drupal\commerce\CredentialsCheckFloodInterface $credentials_check_flood
   *   The credentials check flood controller.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
   *   The event dispatcher.
   * @param \Drupal\commerce_order\OrderAssignmentInterface $order_assignment
   *   The order assignment.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param \Drupal\user\UserAuthInterface $user_auth
   *   The user authentication object.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, CheckoutFlowInterface $checkout_flow, CredentialsCheckFloodInterface $credentials_check_flood, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, OrderAssignmentInterface $order_assignment, RequestStack $request_stack, UserAuthInterface $user_auth) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $checkout_flow, $entity_type_manager);
    $this->credentialsCheckFlood = $credentials_check_flood;
    $this->currentUser = $current_user;
    $this->clientIp = $request_stack
      ->getCurrentRequest()
      ->getClientIp();
    $this->eventDispatcher = $event_dispatcher;
    $this->orderAssignment = $order_assignment;
    $this->userAuth = $user_auth;
    $this->userStorage = $entity_type_manager
      ->getStorage('user');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, CheckoutFlowInterface $checkout_flow = NULL) {
    return new static($configuration, $plugin_id, $plugin_definition, $checkout_flow, $container
      ->get('commerce.credentials_check_flood'), $container
      ->get('current_user'), $container
      ->get('entity_type.manager'), $container
      ->get('event_dispatcher'), $container
      ->get('commerce_order.order_assignment'), $container
      ->get('request_stack'), $container
      ->get('user.auth'));
  }

  /**
   * {@inheritdoc}
   */
  public function isVisible() {

    // This pane can only be shown at the end of checkout.
    if ($this->order
      ->getState()->value == 'draft') {
      return FALSE;
    }
    if ($this->currentUser
      ->isAuthenticated()) {
      return FALSE;
    }
    $mail = $this->order
      ->getEmail();
    if (!$mail) {

      // An email is required, but wasn't collected.
      return FALSE;
    }
    $existing_user = $this->userStorage
      ->loadByProperties([
      'mail' => $mail,
    ]);
    if ($existing_user) {

      // The anonymous customer already has an account on the site.
      return FALSE;
    }
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
    $pane_form['#theme'] = 'commerce_checkout_completion_register';
    $pane_form['name'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Username'),
      '#maxlength' => UserInterface::USERNAME_MAX_LENGTH,
      '#description' => $this
        ->t("Several special characters are allowed, including space, period (.), hyphen (-), apostrophe ('), underscore (_), and the @ sign."),
      '#required' => FALSE,
      '#attributes' => [
        'class' => [
          'username',
        ],
        'autocorrect' => 'off',
        'autocapitalize' => 'off',
        'spellcheck' => 'false',
      ],
      '#default_value' => '',
    ];
    $pane_form['pass'] = [
      '#type' => 'password_confirm',
      '#size' => 60,
      '#description' => $this
        ->t('Provide a password for the new account.'),
      '#required' => TRUE,
    ];
    $pane_form['actions'] = [
      '#type' => 'actions',
    ];
    $pane_form['actions']['register'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Create account'),
      '#name' => 'checkout_completion_register',
    ];

    /** @var \Drupal\user\UserInterface $account */
    $account = $this->entityTypeManager
      ->getStorage('user')
      ->create([]);
    $form_display = EntityFormDisplay::collectRenderDisplay($account, 'register');
    $form_display
      ->buildForm($account, $pane_form, $form_state);
    return $pane_form;
  }

  /**
   * {@inheritdoc}
   */
  public function validatePaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {

    // Validate the entity. This will ensure that the username and email are in
    // the right format and not already taken.
    $values = $form_state
      ->getValue($pane_form['#parents']);
    $account = $this->userStorage
      ->create([
      'mail' => $this->order
        ->getEmail(),
      'name' => $values['name'],
      'pass' => $values['pass'],
      'status' => TRUE,
    ]);

    /** @var \Drupal\user\UserInterface $account */
    $form_display = EntityFormDisplay::collectRenderDisplay($account, 'register');
    $form_display
      ->extractFormValues($account, $pane_form, $form_state);
    $form_display
      ->validateFormValues($account, $pane_form, $form_state);

    // Manually flag violations of fields not handled by the form display. This
    // is necessary as entity form displays only flag violations for fields
    // contained in the display.
    // @see \Drupal\user\AccountForm::flagViolations
    $violations = $account
      ->validate();
    foreach ($violations
      ->getByFields([
      'name',
      'pass',
    ]) as $violation) {
      list($field_name) = explode('.', $violation
        ->getPropertyPath(), 2);
      $form_state
        ->setError($pane_form[$field_name], $violation
        ->getMessage());
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {
    $values = $form_state
      ->getValue($pane_form['#parents']);
    $account = $this->userStorage
      ->create([
      'pass' => $values['pass'],
      'mail' => $this->order
        ->getEmail(),
      'name' => $values['name'],
      'status' => TRUE,
    ]);

    /** @var \Drupal\user\UserInterface $account */
    $form_display = EntityFormDisplay::collectRenderDisplay($account, 'register');
    $form_display
      ->extractFormValues($account, $pane_form, $form_state);
    $account
      ->save();
    user_login_finalize($account);
    $this->credentialsCheckFlood
      ->clearAccount($this->clientIp, $account
      ->getAccountName());
    $this->orderAssignment
      ->assign($this->order, $account);

    // Notify other modules.
    $event = new CheckoutCompletionRegisterEvent($account, $this->order);
    $this->eventDispatcher
      ->dispatch(CheckoutEvents::COMPLETION_REGISTER, $event);

    // Event subscribers are allowed to set a redirect url, to send the
    // customer to their orders page, for example.
    if ($url = $event
      ->getRedirectUrl()) {
      $form_state
        ->setRedirectUrl($url);
    }
    $this
      ->messenger()
      ->addStatus($this
      ->t('Registration successful. You are now logged in.'));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CheckoutPaneBase::$checkoutFlow protected property The parent checkout flow.
CheckoutPaneBase::$entityTypeManager protected property The entity type manager.
CheckoutPaneBase::$order protected property The current order.
CheckoutPaneBase::buildConfigurationForm public function Form constructor. Overrides PluginFormInterface::buildConfigurationForm 6
CheckoutPaneBase::buildConfigurationSummary public function Builds a summary of the pane configuration. Overrides CheckoutPaneInterface::buildConfigurationSummary 5
CheckoutPaneBase::buildPaneSummary public function Builds a summary of the pane values. Overrides CheckoutPaneInterface::buildPaneSummary 3
CheckoutPaneBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies
CheckoutPaneBase::defaultConfiguration public function Gets default configuration for this plugin. Overrides ConfigurableInterface::defaultConfiguration 6
CheckoutPaneBase::getConfiguration public function Gets this plugin's configuration. Overrides ConfigurableInterface::getConfiguration
CheckoutPaneBase::getDisplayLabel public function Gets the pane display label. Overrides CheckoutPaneInterface::getDisplayLabel
CheckoutPaneBase::getId public function Gets the pane ID. Overrides CheckoutPaneInterface::getId
CheckoutPaneBase::getLabel public function Gets the pane label. Overrides CheckoutPaneInterface::getLabel
CheckoutPaneBase::getStepId public function Gets the pane step ID. Overrides CheckoutPaneInterface::getStepId
CheckoutPaneBase::getWeight public function Gets the pane weight. Overrides CheckoutPaneInterface::getWeight
CheckoutPaneBase::getWrapperElement public function Gets the pane wrapper element. Overrides CheckoutPaneInterface::getWrapperElement
CheckoutPaneBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurableInterface::setConfiguration
CheckoutPaneBase::setOrder public function Sets the current order. Overrides CheckoutPaneInterface::setOrder
CheckoutPaneBase::setStepId public function Sets the pane step ID. Overrides CheckoutPaneInterface::setStepId
CheckoutPaneBase::setWeight public function Sets the pane weight. Overrides CheckoutPaneInterface::setWeight
CheckoutPaneBase::submitConfigurationForm public function Form submission handler. Overrides PluginFormInterface::submitConfigurationForm 6
CheckoutPaneBase::validateConfigurationForm public function Form validation handler. Overrides PluginFormInterface::validateConfigurationForm
CompletionRegister::$clientIp protected property The client IP address.
CompletionRegister::$credentialsCheckFlood protected property The credentials check flood controller.
CompletionRegister::$currentUser protected property The current user.
CompletionRegister::$eventDispatcher protected property The event dispatcher.
CompletionRegister::$orderAssignment protected property The order assignment.
CompletionRegister::$userAuth protected property The user authentication object.
CompletionRegister::$userStorage protected property The user storage.
CompletionRegister::buildPaneForm public function Builds the pane form. Overrides CheckoutPaneInterface::buildPaneForm
CompletionRegister::create public static function Creates an instance of the plugin. Overrides CheckoutPaneBase::create
CompletionRegister::isVisible public function Determines whether the pane is visible. Overrides CheckoutPaneBase::isVisible
CompletionRegister::submitPaneForm public function Handles the submission of an pane form. Overrides CheckoutPaneBase::submitPaneForm
CompletionRegister::validatePaneForm public function Validates the pane form. Overrides CheckoutPaneBase::validatePaneForm
CompletionRegister::__construct public function Constructs a new CompletionRegister object. Overrides CheckoutPaneBase::__construct
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.