You are here

class RoleFeatureForm in Ubercart 8.4

Creates or edits a role feature for a product.

Hierarchy

Expanded class hierarchy of RoleFeatureForm

File

uc_role/src/Form/RoleFeatureForm.php, line 18

Namespace

Drupal\uc_role\Form
View source
class RoleFeatureForm extends FormBase {

  /**
   * The datetime.time service.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * The date.formatter service.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * Form constructor.
   *
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The datetime.time service.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date.formatter service.
   */
  public function __construct(TimeInterface $time, DateFormatterInterface $date_formatter) {
    $this->time = $time;
    $this->dateFormatter = $date_formatter;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('datetime.time'), $container
      ->get('date.formatter'));
  }

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, NodeInterface $node = NULL, $feature = NULL) {
    $roles_config = $this
      ->config('uc_role.settings');
    $models = uc_product_get_models($node
      ->id());

    // Check if editing or adding to set default values.
    if (!empty($feature)) {
      $product_role = \Drupal::database()
        ->query('SELECT * FROM {uc_roles_products} WHERE pfid = :pfid', [
        ':pfid' => $feature['pfid'],
      ])
        ->fetchObject();
      $default_model = $product_role->model;
      $default_role = $product_role->rid;
      $default_qty = $product_role->duration;
      $default_granularity = $product_role->granularity;
      $default_shippable = $product_role->shippable;
      $default_by_quantity = $product_role->by_quantity;
      if ($product_role->end_time) {
        $end_time = $product_role->end_time;
        $default_end_type = 'abs';
      }
      else {
        $end_time = _uc_role_get_expiration($default_qty, $default_granularity);
        $default_end_type = 'rel';
      }
      $form['pfid'] = [
        '#type' => 'value',
        '#value' => $feature['pfid'],
      ];
      $form['rpid'] = [
        '#type' => 'value',
        '#value' => $product_role->rpid,
      ];
      $default_end_override = $product_role->end_override;
    }
    else {
      $default_model = 0;
      $default_role = $roles_config
        ->get('default_role');
      $default_qty = $roles_config
        ->get('default_granularity') == 'never' ? NULL : $roles_config
        ->get('default_length');
      $default_granularity = $roles_config
        ->get('default_granularity');
      $default_shippable = $node->shippable->value;
      $default_by_quantity = $roles_config
        ->get('default_by_quantity');
      $end_time = (int) $roles_config
        ->get('default_end_time');
      $default_end_type = $roles_config
        ->get('default_end_expiration');
      $default_end_override = FALSE;
    }
    $roles = _uc_role_get_choices();
    if (!count($roles)) {

      // No actions can be done. Remove submit buttons.
      unset($form['buttons']);
      $form['no_roles'] = [
        '#markup' => $this
          ->t('You need to <a href=":url">create new roles</a> before any can be added as product features.', [
          ':url' => Url::fromRoute('user.role_add', [], [
            'query' => [
              'destination' => 'admin/store/config/products',
            ],
          ])
            ->toString(),
        ]),
        '#prefix' => '<p>',
        '#suffix' => '</p>',
      ];
      return $form;
    }
    $form['nid'] = [
      '#type' => 'value',
      '#value' => $node
        ->id(),
    ];
    $form['model'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('SKU'),
      '#default_value' => $default_model,
      '#description' => $this
        ->t('This is the SKU of the product that will grant the role.'),
      '#options' => $models,
    ];
    $form['role'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Role'),
      '#default_value' => $default_role,
      '#description' => $this
        ->t('This is the role the customer will receive after purchasing the product.'),
      '#options' => $roles,
    ];
    $form['shippable'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Shippable product'),
      '#default_value' => $default_shippable,
      '#description' => $this
        ->t('Check if this product SKU that uses role assignment is associated with a shippable product.'),
    ];
    $form['end_override'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Override the <a href=":url">default role expiration</a>.', [
        ':url' => Url::fromRoute('uc_product.settings')
          ->toString(),
      ]),
      '#default_value' => $default_end_override,
    ];
    $form['role_lifetime'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Role expiration'),
      '#states' => [
        'visible' => [
          'input[name="end_override"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    $form['role_lifetime']['expiration'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Expiration type'),
      '#options' => [
        'rel' => $this
          ->t('Relative to purchase date'),
        'abs' => $this
          ->t('Fixed date'),
      ],
      '#default_value' => $default_end_type,
    ];
    $form['role_lifetime']['expire_relative_duration'] = [
      '#type' => 'textfield',
      '#default_value' => $default_qty,
      '#size' => 4,
      '#maxlength' => 4,
      '#prefix' => '<div class="expiration">',
      '#suffix' => '</div>',
      '#states' => [
        'visible' => [
          'select[name="expiration"]' => [
            'value' => 'rel',
          ],
        ],
        'invisible' => [
          'select[name="expire_relative_granularity"]' => [
            'value' => 'never',
          ],
        ],
      ],
    ];
    $form['role_lifetime']['expire_relative_granularity'] = [
      '#type' => 'select',
      '#options' => [
        'never' => $this
          ->t('never'),
        'day' => $this
          ->t('day(s)'),
        'week' => $this
          ->t('week(s)'),
        'month' => $this
          ->t('month(s)'),
        'year' => $this
          ->t('year(s)'),
      ],
      '#default_value' => $default_granularity,
      '#description' => $this
        ->t('From the time the role was purchased.'),
      '#prefix' => '<div class="expiration">',
      '#suffix' => '</div>',
      '#states' => [
        'visible' => [
          'select[name="expiration"]' => [
            'value' => 'rel',
          ],
        ],
      ],
    ];
    $form['role_lifetime']['absolute'] = [
      '#type' => 'container',
      '#states' => [
        'visible' => [
          'select[name="expiration"]' => [
            'value' => 'abs',
          ],
        ],
      ],
    ];
    $date = empty($end_time) ? DrupalDateTime::createFromTimestamp($this->time
      ->getRequestTime()) : DrupalDateTime::createFromTimestamp($end_time);
    $form['role_lifetime']['absolute']['expire_absolute'] = [
      '#type' => 'datetime',
      '#description' => $this
        ->t('Expire the role at the beginning of this day.'),
      '#date_date_element' => 'date',
      '#date_time_element' => 'none',
      '#default_value' => $date,
    ];
    $form['role_lifetime']['by_quantity'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Multiply by quantity'),
      '#default_value' => $default_by_quantity,
      '#description' => $this
        ->t('Check if the role duration should be multiplied by the quantity purchased.'),
    ];
    $form['actions'] = [
      '#type' => 'actions',
    ];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Save feature'),
    ];
    return $form;
  }

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

    // Invalid quantity?
    if ($form_state
      ->getValue('expiration') === 'abs') {
      $this
        ->messenger()
        ->addMessage(var_export($form_state
        ->getValue('expire_absolute'), TRUE));
      if ($form_state
        ->getValue('expire_absolute')
        ->getTimestamp() <= $this->time
        ->getRequestTime()) {
        $form_state
          ->setErrorByName('expire_absolute', $this
          ->t('The specified date @date has already occurred. Please choose another.', [
          '@date' => $this->dateFormatter
            ->format($form_state
            ->getValue('expire_absolute')
            ->getTimestamp()),
        ]));
      }
    }
    else {
      if ($form_state
        ->getValue('expire_relative_granularity') != 'never' && intval($form_state
        ->getValue('expire_relative_duration')) < 1) {
        $form_state
          ->setErrorByName('expire_relative_duration', $this
          ->t('The amount of time must be a positive integer.'));
      }
    }

    // No roles?
    if ($form_state
      ->isValueEmpty('role')) {
      $form_state
        ->setErrorByName('role', $this
        ->t('You must have a role to assign. You may need to <a href=":role_url">create a new role</a> or perhaps <a href=":feature_url">set role assignment defaults</a>.', [
        ':role_url' => Url::fromRoute('user.role_add')
          ->toString(),
        ':feature_url' => Url::fromRoute('uc_product.settings')
          ->toString(),
      ]));
    }

    // This role already set on this SKU?
    if (!$form_state
      ->hasValue('pfid') && ($product_roles = \Drupal::database()
      ->query('SELECT * FROM {uc_roles_products} WHERE nid = :nid AND model = :model AND rid = :rid', [
      ':nid' => $form_state
        ->getValue('nid'),
      ':model' => $form_state
        ->getValue('model'),
      ':rid' => $form_state
        ->getValue('role'),
    ])
      ->fetchObject())) {
      $form_state
        ->setErrorByName('role', $this
        ->t('The combination of SKU and role already exists for this product.'));
      $form_state
        ->setErrorByName('model');
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $product_role = [
      'pfid' => $form_state
        ->getValue('pfid'),
      'rpid' => $form_state
        ->getValue('rpid'),
      'nid' => $form_state
        ->getValue('nid'),
      'model' => $form_state
        ->getValue('model'),
      'rid' => $form_state
        ->getValue('role'),
      'duration' => $form_state
        ->getValue('expire_relative_granularity') != 'never' ? $form_state
        ->getValue('expire_relative_duration') : NULL,
      'granularity' => $form_state
        ->getValue('expire_relative_granularity'),
      'by_quantity' => $form_state
        ->getValue('by_quantity'),
      'shippable' => $form_state
        ->getValue('shippable'),
      // We should be setting NULL, but drupal_write_record() ...
      'end_override' => $form_state
        ->getValue('end_override'),
      'end_time' => $form_state
        ->getValue('expiration') === 'abs' ? $form_state
        ->getValue('expire_absolute')
        ->getTimestamp() : NULL,
    ];
    $description = empty($product_role['model']) ? $this
      ->t('<strong>SKU:</strong> Any<br />') : $this
      ->t('<strong>SKU:</strong> @sku<br />', [
      '@sku' => $product_role['model'],
    ]);
    $description .= $this
      ->t('<strong>Role:</strong> @role_name<br />', [
      '@role_name' => _uc_role_get_name($product_role['rid']),
    ]);
    if ($product_role['end_override']) {
      if ($product_role['end_time']) {
        $description .= $this
          ->t('<strong>Expiration:</strong> @date<br />', [
          '@date' => $this->dateFormatter
            ->format($product_role['end_time']),
        ]);
      }
      else {
        switch ($product_role['granularity']) {
          case 'never':
            $description .= $this
              ->t('<strong>Expiration:</strong> never<br />');
            break;
          case 'day':
            $description .= $this
              ->t('<strong>Expiration:</strong> @qty day(s)<br />', [
              '@qty' => $product_role['duration'],
            ]);
            break;
          case 'week':
            $description .= $this
              ->t('<strong>Expiration:</strong> @qty week(s)<br />', [
              '@qty' => $product_role['duration'],
            ]);
            break;
          case 'month':
            $description .= $this
              ->t('<strong>Expiration:</strong> @qty month(s)<br />', [
              '@qty' => $product_role['duration'],
            ]);
            break;
          case 'year':
            $description .= $this
              ->t('<strong>Expiration:</strong> @qty year(s)<br />', [
              '@qty' => $product_role['duration'],
            ]);
            break;
          default:
            break;
        }
      }
    }
    else {
      $description .= $this
        ->t('<strong>Expiration:</strong> @link (not overridden)<br />', [
        '@link' => Link::createFromRoute($this
          ->t('Global expiration'), 'uc_product.settings')
          ->toString(),
      ]);
    }
    $description .= $product_role['shippable'] ? $this
      ->t('<strong>Shippable:</strong> Yes<br />') : $this
      ->t('<strong>Shippable:</strong> No<br />');
    $description .= $product_role['by_quantity'] ? $this
      ->t('<strong>Multiply by quantity:</strong> Yes') : $this
      ->t('<strong>Multiply by quantity:</strong> No');
    $data = [
      'pfid' => $product_role['pfid'],
      'nid' => $product_role['nid'],
      'fid' => 'role',
      'description' => $description,
    ];
    uc_product_feature_save($data);
    $product_role['pfid'] = $data['pfid'];

    // Insert or update uc_file_product table.
    foreach ([
      'duration',
      'granularity',
      'end_time',
    ] as $property) {
      $product_role[$property] = $product_role[$property] === NULL ? 0 : $product_role[$property];
    }
    if (!isset($product_role['rpid'])) {
      unset($product_role['rpid']);
      $product_role['rpid'] = \Drupal::database()
        ->insert('uc_roles_products')
        ->fields($product_role)
        ->execute();
    }
    else {
      \Drupal::database()
        ->update('uc_roles_products')
        ->fields($product_role)
        ->condition('rpid', $product_role['rpid'])
        ->execute();
    }
    $form_state
      ->setRedirect('uc_product.features', [
      'node' => $data['nid'],
    ]);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
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
FormBase::$configFactory protected property The config factory. 1
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 1
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
RoleFeatureForm::$dateFormatter protected property The date.formatter service.
RoleFeatureForm::$time protected property The datetime.time service.
RoleFeatureForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
RoleFeatureForm::create public static function Instantiates a new instance of this class. Overrides FormBase::create
RoleFeatureForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
RoleFeatureForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
RoleFeatureForm::validateForm public function Form validation handler. Overrides FormBase::validateForm
RoleFeatureForm::__construct public function Form constructor.
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.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.