You are here

class FileFeatureForm in Ubercart 8.4

Creates or edits a file feature for a product.

Hierarchy

Expanded class hierarchy of FileFeatureForm

File

uc_file/src/Form/FileFeatureForm.php, line 16

Namespace

Drupal\uc_file\Form
View source
class FileFeatureForm extends FormBase {

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected $fileSystem;

  /**
   * Form constructor.
   *
   * @param \Drupal\Core\File\FileSystemInterface $file_system
   *   The file system service.
   */
  public function __construct(FileSystemInterface $file_system) {
    $this->fileSystem = $file_system;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('file_system'));
  }

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, NodeInterface $node = NULL, $feature = NULL) {
    $file_config = $this
      ->config('uc_file.settings');
    if (!is_dir($file_config
      ->get('base_dir'))) {
      $this
        ->messenger()
        ->addWarning($this
        ->t('A file directory needs to be configured in <a href=":url">product settings</a> under the file download settings tab before a file can be selected.', [
        ':url' => Url::fromRoute('uc_product.settings')
          ->toString(),
      ]));
      return $form;
    }

    // Rescan the file directory to populate {uc_files} with the current list
    // because files uploaded via any method other than the Upload button
    // (e.g. by FTP) won'b be in {uc_files} yet.
    uc_file_refresh();
    if (!\Drupal::database()
      ->queryRange('SELECT 1 FROM {uc_files}', 0, 1)
      ->fetchField()) {
      $form['file']['file_message'] = [
        '#markup' => $this
          ->t('You must add files at the <a href=":url">Ubercart file download administration page</a> in order to attach them to a model.', [
          ':url' => Url::fromRoute('uc_file.downloads', [], [
            'query' => [
              'destination' => 'node/' . $node
                ->id() . '/edit/features/file/add',
            ],
          ])
            ->toString(),
        ]),
      ];
      return $form;
    }

    // Grab all the models on this product.
    $models = uc_product_get_models($node
      ->id());

    // Use the feature's values to fill the form, if they exist.
    if (!empty($feature)) {
      $file_product = \Drupal::database()
        ->query('SELECT * FROM {uc_file_products} p LEFT JOIN {uc_files} f ON p.fid = f.fid WHERE pfid = :pfid', [
        ':pfid' => $feature['pfid'],
      ])
        ->fetchObject();
      $default_feature = $feature['pfid'];
      $default_model = $file_product->model;
      $default_filename = $file_product->filename;
      $default_description = $file_product->description;
      $default_shippable = $file_product->shippable;
      $download_status = $file_product->download_limit != UC_FILE_LIMIT_SENTINEL;
      $download_value = $download_status ? $file_product->download_limit : NULL;
      $address_status = $file_product->address_limit != UC_FILE_LIMIT_SENTINEL;
      $address_value = $address_status ? $file_product->address_limit : NULL;
      $time_status = $file_product->time_granularity != UC_FILE_LIMIT_SENTINEL;
      $quantity_value = $time_status ? $file_product->time_quantity : NULL;
      $granularity_value = $time_status ? $file_product->time_granularity : 'never';
    }
    else {
      $default_feature = NULL;
      $default_model = '';
      $default_filename = '';
      $default_description = '';
      $default_shippable = $node->shippable->value;
      $download_status = FALSE;
      $download_value = NULL;
      $address_status = FALSE;
      $address_value = NULL;
      $time_status = FALSE;
      $quantity_value = NULL;
      $granularity_value = 'never';
    }
    $form['#attached']['library'][] = 'uc_file/uc_file.styles';
    $form['nid'] = [
      '#type' => 'value',
      '#value' => $node
        ->id(),
    ];
    $form['pfid'] = [
      '#type' => 'value',
      '#value' => $default_feature,
    ];
    $form['uc_file_model'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('SKU'),
      '#default_value' => $default_model,
      '#description' => $this
        ->t('This is the SKU that will need to be purchased to obtain the file download.'),
      '#options' => $models,
    ];
    $form['uc_file_filename'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('File download'),
      '#default_value' => $default_filename,
      '#autocomplete_route_name' => 'uc_file.autocomplete_filename',
      '#description' => $this
        ->t('The file that can be downloaded when product is purchased (enter a path relative to the %dir directory).', [
        '%dir' => $file_config
          ->get('base_dir'),
      ]),
      '#maxlength' => 255,
      '#required' => TRUE,
    ];
    $form['uc_file_description'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Description'),
      '#default_value' => $default_description,
      '#maxlength' => 255,
      '#description' => $this
        ->t('A description of the download associated with the product.'),
    ];
    $form['uc_file_shippable'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Shippable product'),
      '#default_value' => $default_shippable,
      '#description' => $this
        ->t('Check if this product model/SKU file download is also associated with a shippable product.'),
    ];
    $form['uc_file_limits'] = [
      '#type' => 'fieldset',
      '#description' => $this
        ->t('Use these options to override any global download limits set at the :url.', [
        ':url' => Link::createFromRoute($this
          ->t('Ubercart product settings page'), 'uc_product.settings', [], [
          'query' => [
            'destination' => 'node/' . $node
              ->id() . '/edit/features/file/add',
          ],
        ])
          ->toString(),
      ]),
      '#title' => $this
        ->t('File limitations'),
    ];
    $form['uc_file_limits']['download_override'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Override download limit'),
      '#default_value' => $download_status,
    ];
    $form['uc_file_limits']['download_limit_number'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Downloads'),
      '#default_value' => $download_value,
      '#description' => $this
        ->t('The number of times this file can be downloaded.'),
      '#maxlength' => 4,
      '#size' => 4,
      '#states' => [
        'visible' => [
          'input[name="download_override"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    $form['uc_file_limits']['location_override'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Override IP address limit'),
      '#default_value' => $address_status,
    ];
    $form['uc_file_limits']['download_limit_addresses'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('IP addresses'),
      '#default_value' => $address_value,
      '#description' => $this
        ->t('The number of unique IPs that a file can be downloaded from.'),
      '#maxlength' => 4,
      '#size' => 4,
      '#states' => [
        'visible' => [
          'input[name="location_override"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    $form['uc_file_limits']['time_override'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Override time limit'),
      '#default_value' => $time_status,
    ];
    $form['uc_file_limits']['download_limit_duration'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'duration',
        ],
      ],
    ];
    $form['uc_file_limits']['download_limit_duration']['duration_qty'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Time'),
      '#default_value' => $quantity_value,
      '#size' => 4,
      '#maxlength' => 4,
      '#states' => [
        'disabled' => [
          'select[name="duration_granularity"]' => [
            'value' => 'never',
          ],
        ],
        'visible' => [
          'input[name="time_override"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    $form['uc_file_limits']['download_limit_duration']['duration_granularity'] = [
      '#type' => 'select',
      '#default_value' => $granularity_value,
      '#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)'),
      ],
      '#description' => $this
        ->t('How long after this product has been purchased until this file download expires.'),
      '#states' => [
        'visible' => [
          'input[name="time_override"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    $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) {

    // Ensure this is actually a file we control...
    if (!\Drupal::database()
      ->query('SELECT fid FROM {uc_files} WHERE filename = :name', [
      ':name' => $form_state
        ->getValue('uc_file_filename'),
    ])
      ->fetchField()) {
      $form_state
        ->setErrorByName('uc_file_filename', $this
        ->t('%file is not a valid file or directory inside file download directory.', [
        '%file' => $form_state
          ->getValue('uc_file_filename'),
      ]));
    }

    // If any of our overrides are set, then we make sure they make sense.
    if ($form_state
      ->getValue('download_override') && $form_state
      ->getValue('download_limit_number') < 0) {
      $form_state
        ->setErrorByName('download_limit_number', $this
        ->t('A negative download limit does not make sense. Please enter a positive integer, or leave empty for no limit.'));
    }
    if ($form_state
      ->getValue('location_override') && $form_state
      ->getValue('download_limit_addresses') < 0) {
      $form_state
        ->setErrorByName('download_limit_addresses', $this
        ->t('A negative IP address limit does not make sense. Please enter a positive integer, or leave empty for no limit.'));
    }
    if ($form_state
      ->getValue('time_override') && $form_state
      ->getValue('duration_granularity') != 'never' && $form_state
      ->getValue('duration_qty') < 1) {
      $form_state
        ->setErrorByName('duration_qty', $this
        ->t('You set the granularity (%gran), but you did not set how many. Please enter a positive non-zero integer.', [
        '%gran' => $form_state
          ->getValue('duration_granularity') . '(s)',
      ]));
    }
  }

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

    // Build the file_product object from the form values.
    $file = uc_file_get_by_name($form_state
      ->getValue('uc_file_filename'));
    $file_product = [
      'fid' => $file->fid,
      'filename' => $file->filename,
      'pfid' => $form_state
        ->getValue('pfid'),
      'model' => $form_state
        ->getValue('uc_file_model'),
      'description' => $form_state
        ->getValue('uc_file_description'),
      'shippable' => $form_state
        ->getValue('uc_file_shippable'),
      // Local limitations... set them if there's an override.
      'download_limit' => $form_state
        ->getValue('download_limit_number') ?: UC_FILE_LIMIT_SENTINEL,
      'address_limit' => $form_state
        ->getValue('download_limit_addresses') ?: UC_FILE_LIMIT_SENTINEL,
      'time_granularity' => $form_state
        ->getValue('duration_granularity') ?: UC_FILE_LIMIT_SENTINEL,
      'time_quantity' => $form_state
        ->getValue('duration_qty') ?: UC_FILE_LIMIT_SENTINEL,
    ];

    // Build product feature descriptions.
    $file_config = $this
      ->config('uc_file.settings');
    $description = $this
      ->t('<strong>SKU:</strong> @sku<br />', [
      '@sku' => empty($file_product['model']) ? 'Any' : $file_product['model'],
    ]);
    if (is_dir($file_config
      ->get('base_dir') . '/' . $file_product['filename'])) {
      $description .= $this
        ->t('<strong>Directory:</strong> @dir<br />', [
        '@dir' => $file_product['filename'],
      ]);
    }
    else {
      $description .= $this
        ->t('<strong>File:</strong> @file<br />', [
        '@file' => $this->fileSystem
          ->basename($file_product['filename']),
      ]);
    }
    $description .= $file_product['shippable'] ? $this
      ->t('<strong>Shippable:</strong> Yes') : $this
      ->t('<strong>Shippable:</strong> No');
    $data = [
      'pfid' => $file_product['pfid'],
      'nid' => $form_state
        ->getValue('nid'),
      'fid' => 'file',
      'description' => $description,
    ];
    uc_product_feature_save($data);
    $file_product['pfid'] = $data['pfid'];
    unset($file_product['filename']);
    $key = NULL;
    if ($fpid = _uc_file_get_fpid($file_product['pfid'])) {
      $key = $fpid;
    }

    // Insert or update (if $key is already in table) uc_file_products table.
    if (empty($key)) {
      $key = \Drupal::database()
        ->insert('uc_file_products')
        ->fields($file_product)
        ->execute();
    }
    else {
      \Drupal::database()
        ->update('uc_file_products')
        ->fields($file_product)
        ->condition([
        'fpid' => $key,
      ])
        ->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
FileFeatureForm::$fileSystem protected property The file system service.
FileFeatureForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
FileFeatureForm::create public static function Instantiates a new instance of this class. Overrides FormBase::create
FileFeatureForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
FileFeatureForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
FileFeatureForm::validateForm public function Form validation handler. Overrides FormBase::validateForm
FileFeatureForm::__construct public function Form constructor.
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.
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.