recurly-8.x-1.x-dev/src/Form/RecurlyRedeemCouponForm.php

src/Form/RecurlyRedeemCouponForm.php
<?php

namespace Drupal\recurly\Form;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Recurly redeem coupon form.
 */
class RecurlyRedeemCouponForm extends RecurlyNonConfigForm {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'recurly_redeem_coupon_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, RouteMatchInterface $route_match = NULL) {
    $entity_type_id = $this->config('recurly.settings')->get('recurly_entity_type');
    $entity = $route_match->getParameter($entity_type_id);
    $entity_type = $entity->getEntityType()->id();
    $form['#entity_type'] = $entity_type;
    $form['#entity'] = $entity;

    // Check the user's account for any current coupons.
    $account = recurly_account_load([
      'entity_type' => $form['#entity_type'],
      'entity_id' => $entity->id(),
    ]);
    $confirming_replacement_coupon = ($form_state->get('confirm') && $form_state->get('coupon') && $form_state->get('existing_coupon'));
    $form_state->set('account', $account);

    // The output of this form varies based on if the user has an existing
    // coupon, and if they need to confirm replacing their existing coupon with
    // a new one.
    if ($confirming_replacement_coupon) {
      $form_state->set('confirmed', TRUE);
      $help = '<p>' . $this->t('Your account already has a coupon that will be applied to your next invoice. Are you sure you want to replace your existing coupon "@old_coupon" with "@new_coupon"? You may not be able to use your previous coupon again.',
        [
          '@old_coupon' => $this->recurlyFormatter->formatCoupon($form_state->get('existing_coupon'), $form_state->get('existing_redemption')->currency),
          '@new_coupon' => $this->recurlyFormatter->formatCoupon($form_state->get('coupon'), $form_state->getValue('coupon_currency')),
        ]) . '</p>';
    }
    elseif ($account->redemption) {
      $existing_coupon_redemption = $account->redemption->get();
      $form_state->set('existing_redemption', $existing_coupon_redemption);
      $form_state->set('existing_coupon', $existing_coupon_redemption->coupon->get());

      $help = '<p>' . $this->t('Your next invoice will have the following coupon applied:') . ' <strong>' . $this->recurlyFormatter->formatCoupon($form_state->get('existing_coupon'), $form_state->get('existing_redemption')->currency) . '</strong></p>';
      $help .= '<p>' . $this->t('Please note that only one coupon can be redeemed per invoice.') . '</p>';
    }
    else {
      $help = '<p>' . $this->t('Enter a coupon code below and it will be applied to your next invoice.') . '</p>';
    }

    $form['help'] = [
      '#markup' => $help,
    ];
    $form['coupon_code'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Coupon code'),
      '#required' => TRUE,
      '#default_value' => $form_state->get('coupon') ? $form_state->get('coupon')->coupon_code : '',
      '#access' => !$confirming_replacement_coupon,
      '#size' => 20,
    ];
    $form['coupon_currency'] = [
      '#type' => 'select',
      '#title' => $this->t('Coupon currency'),
      '#options' => array_combine(array_keys(recurly_currency_list()), array_keys(recurly_currency_list())),
      '#default_value' => $this->config('recurly.settings')->get('recurly_default_currency'),
      '#description' => $this->t('If your coupon specifies a currency, select it here. Not all coupons work in all currencies.'),
      '#access' => !$confirming_replacement_coupon,
    ];
    $form['actions'] = [
      '#type' => 'actions',
    ];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $confirming_replacement_coupon ? $this->t('Replace previous coupon') : $this->t('Redeem coupon'),
    ];
    $form['actions']['cancel'] = [
      '#type' => 'markup',
      '#markup' => '<a href="' . recurly_url('redeem_coupon', [
        'entity_type' => $entity_type,
        'entity' => $entity,
      ])->toString() . '">' . $this->t('Cancel') . '</a>',
      '#access' => $confirming_replacement_coupon,
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);

    // Query Recurly to make sure this is a valid coupon code.
    try {
      $coupon = \Recurly_Coupon::get($form_state->getValue('coupon_code'), $this->recurlyClient);
      $form_state->set('coupon', $coupon);
    }
    catch (\Recurly_NotFoundError $e) {
      $form_state->setErrorByName('coupon_code', $this->t('The coupon code you have entered is not valid.'));
      return;
    }

    // Check that the coupon is available in the specified currency.
    if ($form_state->get('coupon') &&
        !in_array(
          $form_state->get('coupon')->discount_type,
          ['percent', 'free_trial']
        )
    ) {
      if (!$form_state->get('coupon')->discount_in_cents->offsetExists($form_state->getValue('coupon_currency'))) {
        $form_state->setErrorByName('coupon_currency', $this->t('The coupon code you have entered is not valid in @currency currency.', ['@currency' => $form_state->getValue('coupon_currency')]));
        return;
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $coupon = $form_state->get('coupon');
    $account = $form_state->get('account');
    if (empty($account->redemption)) {
      $account = recurly_account_load([
        'entity_type' => $form['#entity_type'],
        'entity_id' => $form['#entity']->id(),
      ]);
    }
    if ($account && $coupon && $account->redemption) {
      // If the user already has a coupon, rebuild the form and ask for
      // confirmation.
      if (!$form_state->get('confirmed')) {
        $this->messenger()->addWarning($this->t('You already have an active coupon, are you sure you want to replace it?'));
        $form_state->set('confirm', TRUE);
        $form_state->setRebuild(TRUE);
        return;
      }
      // If confirmed, delete the existing coupon before redeeming the new one.
      else {
        if ($existing_coupon_redemption = $form_state->get('existing_redemption')) {
          try {
            $existing_coupon_redemption = $account->redemption->get();
            $existing_coupon_redemption->delete();
          }
          catch (\Recurly_NotFoundError $e) {
            $this->logger('recurly')->error('Unable to remove existing coupon redemption: @error', ['@error' => $e->getMessage()]);
            $this->messenger()->addError('Unable to remove existing coupon.');
            return;
          }
        }
      }
    }

    // Now redeem the new coupon.
    try {
      $response = $coupon->redeemCoupon($account->account_code, $form_state->getValue('coupon_currency'));
    }
    catch (\Exception $e) {
      $this->logger('recurly')->error('@error', ['@error' => $e->getMessage()]);
      $this->messenger()->addError($e->getMessage());
      return;
    }

    // If the response is NULL that means for one reason or another the coupon
    // could not be applied. This is most likely because the code has already
    // reached the maximum number of redemptions or has expired.
    if (is_null($response)) {
      $this->messenger()->addError($this->t('Unable to redeem the coupon @code, the coupon may no longer be valid.', ['@code' => $coupon->coupon_code]));
    }
    else {
      $this->messenger()->addMessage($this->t('The coupon @coupon has been applied to your account and will be redeemed the next time your subscription renews.', [
        '@coupon' => $this->recurlyFormatter->formatCoupon($coupon, $form_state->getValue(['coupon_currency']), FALSE),
      ]));
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc