From dc1d13a11a4c49b6e5edfcba5ded92d97c823ba1 Mon Sep 17 00:00:00 2001 From: bmcclure Date: Wed, 1 Mar 2017 18:07:05 -0600 Subject: [PATCH 1/4] Issue #2857157 by bmcclure: Implement registration after guest checkout --- modules/checkout/commerce_checkout.module | 3 + .../Commerce/CheckoutPane/Registration.php | 221 ++++++++++++++++++ .../commerce-checkout-registration.html.twig | 20 ++ 3 files changed, 244 insertions(+) create mode 100644 modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php create mode 100644 modules/checkout/templates/commerce-checkout-registration.html.twig diff --git a/modules/checkout/commerce_checkout.module b/modules/checkout/commerce_checkout.module index ddecb6e2fc..1db0a42088 100755 --- a/modules/checkout/commerce_checkout.module +++ b/modules/checkout/commerce_checkout.module @@ -26,6 +26,9 @@ function commerce_checkout_theme() { 'commerce_checkout_form__with_summary' => [ 'base hook' => 'commerce_checkout_form', ], + 'commerce_checkout_registration' => [ + 'render element' => 'form', + ], ]; return $theme; diff --git a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php new file mode 100644 index 0000000000..7191e4ddb1 --- /dev/null +++ b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php @@ -0,0 +1,221 @@ +credentialsCheckFlood = $credentials_check_flood; + $this->currentUser = $current_user; + $this->entityTypeManager = $entity_type_manager; + $this->userAuth = $user_auth; + $this->clientIp = $request_stack->getCurrentRequest()->getClientIp(); + } + + /** + * {@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('user.auth'), + $container->get('request_stack') + ); + } + + /** + * {@inheritdoc} + */ + public function isVisible() { + return $this->currentUser->isAnonymous(); + } + + /** + * {@inheritdoc} + */ + public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) { + $pane_form = [ + '#type' => 'fieldset', + '#title' => $this->t('Account information'), + ]; + + $pane_form['name'] = [ + '#type' => 'textfield', + '#title' => $this->t('Username'), + '#maxlength' => 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['password'] = [ + '#type' => 'password_confirm', + '#size' => 60, + '#description' => $this->t('Provide a password for the new account in both fields.'), + '#required' => FALSE, + ]; + + $pane_form['register'] = [ + '#type' => 'submit', + '#value' => $this->t('Save details'), + ]; + + return [ + '#theme' => 'commerce_checkout_registration', + 'form' => $pane_form, + ]; + } + + /** + * {@inheritdoc} + */ + public function validatePaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) { + $values = $form_state->getValue($pane_form['#parents']); + + $username = $values['form']['name']; + $password = trim($values['form']['password']); + + if (empty($username)) { + $form_state->setError($pane_form['form']['name'], $this->t('Username field is required.')); + return; + } + if (empty($password)) { + $form_state->setError($pane_form['form']['password'], $this->t('Password field is required.')); + return; + } + + /** @var \Drupal\user\UserInterface $account */ + $account = $this->entityTypeManager->getStorage('user')->create([ + 'mail' => $this->order->getEmail(), + 'name' => $username, + 'pass' => $password, + 'status' => TRUE, + ]); + + // Validate the entity. This will ensure that the username and email + // are in the right format and not already taken. + $violations = $account->validate(); + foreach ($violations->getByFields(['name']) as $violation) { + list($field_name) = explode('.', $violation->getPropertyPath(), 2); + $form_state->setError($pane_form['form'][$field_name], $violation->getMessage()); + } + + if (!$form_state->hasAnyErrors()) { + $account->save(); + $form_state->set('logged_in_uid', $account->id()); + } + } + + /** + * {@inheritdoc} + */ + public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) { + $storage = $this->entityTypeManager->getStorage('user'); + /** @var \Drupal\user\UserInterface $account */ + $account = $storage->load($form_state->get('logged_in_uid')); + user_login_finalize($account); + $this->order->setCustomer($account); + + // Normally advancing steps in the checkout automatically saves the order. + // Since this pane occurs on the last step, manual order saving is needed. + $this->order->save(); + + $this->credentialsCheckFlood->clearAccount($this->clientIp, $account->getAccountName()); + + $form_state->setRedirect('commerce_checkout.form', [ + 'commerce_order' => $this->order->id(), + 'step' => $this->checkoutFlow->getStepId(), + ]); + } + +} diff --git a/modules/checkout/templates/commerce-checkout-registration.html.twig b/modules/checkout/templates/commerce-checkout-registration.html.twig new file mode 100644 index 0000000000..cbd44cd216 --- /dev/null +++ b/modules/checkout/templates/commerce-checkout-registration.html.twig @@ -0,0 +1,20 @@ +{# +/** + * @file + * A layout for the checkout registration form + * + * Available variables: + * - form: The form. + * + * @ingroup themeable + */ +#} +
+
+

Save Your Details

+

Complete your account registration now to be able to access your order information at any time.

+
+
+ {{ form }} +
+
From 952c575e971e011df87839a2f4e02e6113c57787 Mon Sep 17 00:00:00 2001 From: Ben McClure Date: Wed, 1 Mar 2017 18:10:00 -0600 Subject: [PATCH 2/4] by bmcclure: Fix comment --- .../checkout/src/Plugin/Commerce/CheckoutPane/Registration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php index 7191e4ddb1..b547ceda64 100644 --- a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php +++ b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php @@ -13,7 +13,7 @@ use Symfony\Component\HttpFoundation\RequestStack; /** - * Provides the login pane. + * Provides the registration pane. * * @CommerceCheckoutPane( * id = "registration", From 9bc808f4cd32a306931e42337831c0d66927ae31 Mon Sep 17 00:00:00 2001 From: Ben McClure Date: Sun, 2 Apr 2017 14:20:15 -0500 Subject: [PATCH 3/4] by bmcclure: Fix for recent constructor argument change in base class --- .../Plugin/Commerce/CheckoutPane/Registration.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php index b547ceda64..f32ac37fb2 100644 --- a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php +++ b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php @@ -69,23 +69,22 @@ class Registration extends CheckoutPaneBase implements CheckoutPaneInterface, Co * The plugin implementation definition. * @param \Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowInterface $checkout_flow * The parent checkout flow. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. * @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 \Drupal\user\UserAuthInterface $user_auth * The user authentication object. * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * The request stack. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, CheckoutFlowInterface $checkout_flow, CredentialsCheckFloodInterface $credentials_check_flood, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, UserAuthInterface $user_auth, RequestStack $request_stack) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $checkout_flow); + public function __construct(array $configuration, $plugin_id, $plugin_definition, CheckoutFlowInterface $checkout_flow, EntityTypeManagerInterface $entity_type_manager, CredentialsCheckFloodInterface $credentials_check_flood, AccountInterface $current_user, UserAuthInterface $user_auth, RequestStack $request_stack) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $checkout_flow, $entity_type_manager); $this->credentialsCheckFlood = $credentials_check_flood; $this->currentUser = $current_user; - $this->entityTypeManager = $entity_type_manager; $this->userAuth = $user_auth; $this->clientIp = $request_stack->getCurrentRequest()->getClientIp(); } @@ -99,9 +98,9 @@ public static function create(ContainerInterface $container, array $configuratio $plugin_id, $plugin_definition, $checkout_flow, + $container->get('entity_type.manager'), $container->get('commerce.credentials_check_flood'), $container->get('current_user'), - $container->get('entity_type.manager'), $container->get('user.auth'), $container->get('request_stack') ); @@ -219,3 +218,4 @@ public function submitPaneForm(array &$pane_form, FormStateInterface $form_state } } + From 41d89919aaad5b26cf7444bffbfd79a67a66353c Mon Sep 17 00:00:00 2001 From: Ben McClure Date: Fri, 7 Apr 2017 02:05:20 -0500 Subject: [PATCH 4/4] Fix error with missing getStepId() method being called --- .../checkout/src/Plugin/Commerce/CheckoutPane/Registration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php index f32ac37fb2..c52c585b1f 100644 --- a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php +++ b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Registration.php @@ -213,7 +213,7 @@ public function submitPaneForm(array &$pane_form, FormStateInterface $form_state $form_state->setRedirect('commerce_checkout.form', [ 'commerce_order' => $this->order->id(), - 'step' => $this->checkoutFlow->getStepId(), + 'step' => $complete_form['#step_id'], ]); }