You are here

class FieldsForm in Feed Import 8

Hierarchy

Expanded class hierarchy of FieldsForm

File

src/Form/FieldsForm.php, line 15
Contains \Drupal\feed_import\Form\FieldsForm

Namespace

Drupal\feed_import\Form
View source
class FieldsForm extends FormBase {

  /**
   * The feed being edited.
   *
   * @var object containing feed settings.
   */
  protected $feed;

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $fid = NULL) {
    $this->feed = FeedImport::loadFeed($fid);

    // Set uniq path.
    $form['uniq'] = array(
      '#type' => 'textfield',
      '#default_value' => $this->feed->settings['uniq_path'],
      '#title' => t('Enter path to unique id'),
      '#description' => t('Used to monitor items for updates.'),
    );

    // Fields list
    $form['fields'] = array(
      '#type' => 'container',
      '#attributes' => array(
        'id' => 'feed_import_path_fields',
      ),
      '#tree' => TRUE,
    );
    $paths = $fields = array();
    $current_item = $form_state
      ->get('current_item');
    if (!is_null($current_item)) {
      $fv = $form_state
        ->getValue('fields');
      for ($i = 0; $i <= $current_item; $i++) {
        if (!isset($fv['container_' . $i])) {
          continue;
        }
        $field =& $fv['container_' . $i];
        $fields[] = $field['field'];
        $paths += $this
          ->generatePathItem($i, $field);
        unset($field);
      }
      unset($fv);
    }
    else {
      $current_item = -1;
      foreach ($this->feed->settings['fields'] as &$field) {
        $current_item++;
        $fields[] = $field['field'];
        $paths += $this
          ->generatePathItem($current_item, $field, TRUE);
      }
      unset($field);
    }
    $fv = $form_state
      ->getValues();
    $trigger = $form_state
      ->getTriggeringElement();
    if ($trigger) {
      if ($trigger['#name'] == 'add_new_item') {
        $form_state
          ->set('field_added', FALSE);
        $field = $fv['add_new_item_mode'] ? 'add_new_item_field' : 'add_new_item_manual';
        if ($field = Unicode::strtolower($fv[$field])) {
          $i = -1;
          $exists = FALSE;
          while (++$i <= $form_state
            ->get('current_item')) {
            if (isset($fv['fields']['container_' . $i]['field']) && $fv['fields']['container_' . $i]['field'] == $field) {
              $exists = TRUE;
              break;
            }
          }
          if (!$exists) {
            $form_state
              ->set('field_added', TRUE);
            $current_item++;
            $paths += $this
              ->generatePathItem($current_item, array(
              'field' => $field,
              'default_value' => '',
              'default_action' => FeedImportProcessor::ACTION_DEFAULT_VALUE,
              'update_mode' => FeedImportProcessor::UPDATE_COMBINE,
              'paths' => '',
            ));
          }
        }
      }
      elseif (preg_match('/remove_container_([0-9]{1,9})/', $trigger['#name'], $match)) {

        // Delete container.
        unset($paths['container_' . $match[1]]);
      }
    }
    $form_state
      ->set('current_item', $current_item);

    // Add fields.
    $form['fields'] += $paths;
    unset($paths);

    // Generate field options.
    $opts = FeedImport::getEntityInfo($this->feed->entity);
    $opts = array_merge($opts->properties, array_keys($opts->fields));
    $opts = array_diff($opts, $fields);
    $opts = array_combine($opts, $opts);

    // Add new field mode.
    $form['add_new_item_mode'] = array(
      '#type' => 'checkbox',
      '#title' => t('Use defined fields'),
      '#default_value' => TRUE,
      '#id' => 'add-new-item-mode',
    );

    // Add entity fields.
    $form['add_new_item_field'] = array(
      '#type' => 'select',
      '#options' => $opts,
      '#title' => t('Select defined field'),
      '#description' => t('Select field name and click "' . t('Add field') . '" button'),
      '#id' => 'add-new-item-field',
      '#states' => array(
        'visible' => array(
          ':input[name=add_new_item_mode]' => array(
            'checked' => TRUE,
          ),
        ),
      ),
    );

    // Manual field.
    $form['add_new_item_manual'] = array(
      '#type' => 'textfield',
      '#title' => t('Enter field name'),
      '#description' => t('Write field name and click "@name" button', array(
        '@name' => t('Add field'),
      )),
      '#id' => 'add-new-item-manual',
      '#states' => array(
        'visible' => array(
          ':input[name=add_new_item_mode]' => array(
            'checked' => FALSE,
          ),
        ),
      ),
    );

    // Add new field button.
    $form['add_new_item'] = array(
      '#type' => 'button',
      '#name' => 'add_new_item',
      '#value' => t('Add field'),
      '#inline' => TRUE,
      '#ajax' => array(
        'event' => 'click',
        'callback' => array(
          $this,
          'ajaxAddItem',
        ),
        'wrapper' => 'feed_import_path_fields',
        'method' => 'append',
      ),
    );

    // Submit buttons.
    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Save feed'),
    );

    // Add js.
    $form['#attached'] = array(
      'library' => array(
        'feed_import/behaviors',
      ),
    );
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $v = $form_state
      ->getValues();
    if (!$this->feed) {
      return;
    }
    $e = FeedImport::getEntityInfo($this->feed->entity);
    $fields = array();
    for ($i = 0; $i <= $form_state
      ->get('current_item'); $i++) {
      if (empty($v['fields']['container_' . $i]['field'])) {
        continue;
      }
      $f =& $v['fields']['container_' . $i];
      $fields[$f['field']] = array(
        'field' => $f['field'],
        'column' => isset($e->fields[$f['field']]),
        'paths' => array_filter(preg_split('/\\r?\\n/', $f['paths']), 'strlen'),
        'default_action' => (int) $f['default_action'],
        'default_value' => $f['default_value'],
        'update_mode' => (int) $f['update_mode'],
        'filters' => isset($this->feed->settings['fields'][$f['field']]['filters']) ? $this->feed->settings['fields'][$f['field']]['filters'] : array(),
        'prefilters' => isset($this->feed->settings['fields'][$f['field']]['prefilters']) ? $this->feed->settings['fields'][$f['field']]['prefilters'] : array(),
      );
      unset($f);
    }
    $this->feed->settings['uniq_path'] = $v['uniq'];
    $this->feed->settings['fields'] = $fields;

    // Save feed.
    if (FeedImport::saveFeed($this->feed)) {
      drupal_set_message(t('Feed saved'));
    }
  }

  /**
   * Generate field
   *
   * @param int $pos
   *   Fieldset number
   * @param array $values
   *   Array containing default values
   * @param bool $collapsed
   *   Inicates if fieldset is collapsed
   *
   * @return array
   *   Fieldset containing xpath inputs
   */
  protected function generatePathItem($pos, array $values, $collapsed = FALSE) {
    $container = 'container_' . $pos;
    $item[$container] = array(
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => $collapsed,
      '#title' => isset($values['field']) ? $values['field'] : t('Unspecified field'),
      '#attributes' => array(
        'id' => 'item_container_' . $pos,
      ),
    );
    $container =& $item[$container];
    $container['field'] = array(
      '#type' => 'value',
      '#value' => $values['field'],
    );
    $container['paths'] = array(
      '#type' => 'textarea',
      '#default_value' => is_array($values['paths']) ? implode(PHP_EOL, $values['paths']) : $values['paths'],
      '#title' => t('Paths'),
      '#description' => t('Enter path to item. You can enter multiple paths (one per line) until one passes pre-filter.'),
    );
    $container['default_action'] = array(
      '#type' => 'select',
      '#options' => array(
        FeedImportProcessor::ACTION_DEFAULT_VALUE => t('Provide a default value'),
        FeedImportProcessor::ACTION_DEFAULT_FILTERED_VALUE => t('Provide a filtered default value'),
        FeedImportProcessor::ACTION_IGNORE_FIELD => t('Ignore this field'),
        FeedImportProcessor::ACTION_SKIP_ITEM => t('Skip importing this entity'),
      ),
      '#default_value' => $values['default_action'],
      '#title' => t('Action when filtered result is empty'),
      '#description' => t('If the filtered result is empty you can choose what action to take next.'),
      '#id' => 'default_action_' . $pos,
    );
    $container['default_value'] = array(
      '#type' => 'textarea',
      '#rows' => 2,
      '#default_value' => $values['default_value'],
      '#title' => t('Default value'),
      '#description' => t('If no path passes pre-filter then use a default value.'),
      '#prefix' => '<div style="display: none;" rel="default_action_' . $pos . '">',
      '#suffix' => '</div>',
    );
    $options = \Drupal::moduleHandler()
      ->invokeAll('feed_import_field_merge_classes');
    foreach ($options as &$option) {
      $option = $option['title'];
    }
    $container['update_mode'] = array(
      '#type' => 'select',
      '#options' => $options,
      '#default_value' => $values['update_mode'],
      '#title' => t('Field update mode'),
      '#description' => t('How to update existing entities.'),
    );
    $container['remove_container_' . $pos] = array(
      '#type' => 'button',
      '#name' => 'remove_container_' . $pos,
      '#value' => t('Remove field'),
      '#ajax' => array(
        'event' => 'click',
        'wrapper' => 'item_container_' . $pos,
        'method' => 'replace',
        'callback' => array(
          $this,
          'ajaxRemoveItem',
        ),
      ),
    );
    return $item;
  }

  /**
   * Ajax callback to add a new item
   */
  public function ajaxAddItem(array &$form, FormStateInterface $form_state) {
    if ($form_state
      ->get('field_added')) {
      return $form['fields']['container_' . $form_state
        ->get('current_item')];
    }
    return NULL;
  }

  /**
   * Ajax callback to remove an item
   */
  public function ajaxRemoveItem(array &$form, FormStateInterface $form_state) {

    // Send empty string to remove container.
    return array(
      '#markup' => '',
    );
  }

}

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
FieldsForm::$feed protected property The feed being edited.
FieldsForm::ajaxAddItem public function Ajax callback to add a new item
FieldsForm::ajaxRemoveItem public function Ajax callback to remove an item
FieldsForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
FieldsForm::generatePathItem protected function Generate field
FieldsForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
FieldsForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
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::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create 87
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.
FormBase::validateForm public function Form validation handler. Overrides FormInterface::validateForm 62
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.