You are here

public function FeaturesEditForm::buildForm in Features 8.3

Same name and namespace in other branches
  1. 8.4 modules/features_ui/src/Form/FeaturesEditForm.php \Drupal\features_ui\Form\FeaturesEditForm::buildForm()

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form structure.

Overrides FormInterface::buildForm

File

modules/features_ui/src/Form/FeaturesEditForm.php, line 154

Class

FeaturesEditForm
Defines the features settings form.

Namespace

Drupal\features_ui\Form

Code

public function buildForm(array $form, FormStateInterface $form_state, $featurename = '') {
  $session = $this
    ->getRequest()
    ->getSession();
  $trigger = $form_state
    ->getTriggeringElement();
  if (isset($trigger['#name']) && $trigger['#name'] == 'package') {

    // Save current bundle name for later ajax callback.
    $this->oldBundle = $this->bundle;
  }
  elseif (isset($trigger['#name']) && $trigger['#name'] == 'conflicts') {
    if (isset($session)) {
      $session
        ->set('features_allow_conflicts', $form_state
        ->getValue('conflicts'));
    }
  }
  if (!$form_state
    ->isValueEmpty('package')) {
    $bundle_name = $form_state
      ->getValue('package');
    $bundle = $this->assigner
      ->getBundle($bundle_name);
  }
  else {
    $bundle = $this->assigner
      ->loadBundle();
  }

  // Only store bundle name, not full object.
  $this->bundle = $bundle
    ->getMachineName();
  $this->allowConflicts = FALSE;
  if (isset($session)) {
    $this->allowConflicts = $session
      ->get('features_allow_conflicts', FALSE);
  }

  // Pass the $force argument as TRUE because we want to include any excluded
  // configuration items. These should show up as automatically assigned, but
  // not selected, thus allowing the admin to reselect if desired.
  // @see FeaturesManagerInterface::assignConfigPackage()
  $this->assigner
    ->assignConfigPackages(TRUE);
  $packages = $this->featuresManager
    ->getPackages();
  if (empty($packages[$featurename])) {
    $featurename = str_replace([
      '-',
      ' ',
    ], '_', $featurename);
    $this->package = $this->featuresManager
      ->initPackage($featurename, NULL, '', 'module', $bundle);
  }
  else {
    $this->package = $packages[$featurename];
  }
  if (!empty($packages[$featurename]) && $this->package
    ->getBundle() !== $this->bundle && $form_state
    ->isValueEmpty('package')) {

    // Make sure the current bundle matches what is stored in the package.
    // But only do this if the Package value hasn't been manually changed.
    $bundle = $this->assigner
      ->getBundle($this->package
      ->getBundle());
    if (empty($bundle)) {

      // Create bundle if it doesn't exist yet.
      $bundle = $this->assigner
        ->createBundleFromDefault($this->package
        ->getBundle());
    }
    $this->bundle = $bundle
      ->getMachineName();
    $this->assigner
      ->reset();
    $this->assigner
      ->assignConfigPackages(TRUE);
    $packages = $this->featuresManager
      ->getPackages();
    $this->package = $packages[$featurename];
  }
  $form = [
    '#show_operations' => FALSE,
    '#prefix' => '<div id="features-edit-wrapper" class="features-edit-wrapper clearfix">',
    '#suffix' => '</div>',
  ];
  $form['info'] = [
    '#type' => 'fieldset',
    '#title' => $this
      ->t('General Information'),
    '#tree' => FALSE,
    '#weight' => 2,
    '#prefix' => '<div id="features-export-info" class="features-export-info">',
    '#suffix' => '</div>',
  ];
  $form['info']['name'] = [
    '#title' => $this
      ->t('Name'),
    '#description' => $this
      ->t('Example: Image gallery') . ' (' . $this
      ->t('Do not begin name with numbers.') . ')',
    '#type' => 'textfield',
    '#default_value' => $this->package
      ->getName(),
  ];
  if (!$bundle
    ->isDefault()) {
    $form['info']['name']['#description'] .= '<br/>' . $this
      ->t('The namespace "@name_" will be prepended to the machine name', [
      '@name' => $bundle
        ->getMachineName(),
    ]);
  }
  $form['info']['machine_name'] = [
    '#type' => 'machine_name',
    '#title' => $this
      ->t('Machine-readable name'),
    '#description' => $this
      ->t('Example: image_gallery') . ' ' . $this
      ->t('May only contain lowercase letters, numbers and underscores.'),
    '#required' => TRUE,
    '#default_value' => $bundle
      ->getShortName($this->package
      ->getMachineName()),
    '#machine_name' => [
      'source' => [
        'info',
        'name',
      ],
      'exists' => [
        $this,
        'featureExists',
      ],
    ],
  ];
  if (!$bundle
    ->isDefault()) {
    $form['info']['machine_name']['#description'] .= '<br/>' . $this
      ->t('NOTE: Do NOT include the namespace prefix "@name_"; it will be added automatically.', [
      '@name' => $bundle
        ->getMachineName(),
    ]);
  }
  $form['info']['description'] = [
    '#title' => $this
      ->t('Description'),
    '#description' => $this
      ->t('Provide a short description of what users should expect when they install your feature.'),
    '#type' => 'textarea',
    '#rows' => 3,
    '#default_value' => $this->package
      ->getDescription(),
  ];
  $form['info']['package'] = [
    '#title' => $this
      ->t('Bundle'),
    '#type' => 'select',
    '#options' => $this->assigner
      ->getBundleOptions(),
    '#default_value' => $bundle
      ->getMachineName(),
    '#ajax' => [
      'callback' => '::updateBundle',
      'wrapper' => 'features-export-info',
    ],
  ];
  $form['info']['version'] = [
    '#title' => $this
      ->t('Version'),
    '#description' => $this
      ->t('Examples: 8.x-1.0, 3.1.4'),
    '#type' => 'textfield',
    '#required' => FALSE,
    '#default_value' => $this->package
      ->getVersion(),
    '#size' => 30,
  ];
  [
    $full_name,
    $path,
  ] = $this->featuresManager
    ->getExportInfo($this->package, $bundle);
  $form['info']['directory'] = [
    '#title' => $this
      ->t('Path'),
    '#description' => $this
      ->t('Path to export package using Write action, relative to root directory.'),
    '#type' => 'textfield',
    '#required' => FALSE,
    '#default_value' => $path,
    '#size' => 30,
  ];
  $require_all = $this->package
    ->getRequiredAll();
  $form['info']['require_all'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Mark all config as required'),
    '#default_value' => $this->package
      ->getRequiredAll(),
    '#description' => $this
      ->t('Required config will be assigned to this feature regardless of other assignment plugins.'),
  ];
  $form['conflicts'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Allow conflicts'),
    '#default_value' => $this->allowConflicts,
    '#description' => $this
      ->t('Allow configuration to be exported to more than one feature.'),
    '#weight' => 8,
    '#ajax' => [
      'callback' => '::updateForm',
      'wrapper' => 'features-edit-wrapper',
    ],
    '#wrapper_attributes' => [
      'class' => [
        'features-ui-conflicts',
      ],
    ],
  ];
  $generation_info = [];
  if (\Drupal::currentUser()
    ->hasPermission('export configuration')) {

    // Offer available generation methods.
    $generation_info = $this->generator
      ->getGenerationMethods();

    // Sort generation methods by weight.
    uasort($generation_info, '\\Drupal\\Component\\Utility\\SortArray::sortByWeightElement');
  }
  $form['actions'] = [
    '#type' => 'actions',
    '#tree' => TRUE,
  ];
  foreach ($generation_info as $method_id => $method) {
    $form['actions'][$method_id] = [
      '#type' => 'submit',
      '#name' => $method_id,
      '#value' => $this
        ->t('@name', [
        '@name' => $method['name'],
      ]),
      '#attributes' => [
        'title' => Html::escape($method['description']),
      ],
    ];
  }

  // Build the Component Listing panel on the right.
  $form['export'] = $this
    ->buildComponentList($form_state);
  if (!empty($this->missing)) {
    if ($this->allowConflicts) {
      $form['actions']['#prefix'] = '<strong>' . $this
        ->t('WARNING: Package contains configuration missing from site.') . '<br>' . $this
        ->t('This configuration will be removed if you export it.') . '</strong>';
    }
    else {
      foreach ($generation_info as $method_id => $method) {
        unset($form['actions'][$method_id]);
      }
      $form['actions']['#prefix'] = '<strong>' . $this
        ->t('Package contains configuration missing from site.') . '<br>' . $this
        ->t('Import the feature to create the missing config before you can export it.') . '<br>' . $this
        ->t('Or, enable the Allow Conflicts option above.') . '</strong>';
    }
    $form['actions']['import_missing'] = [
      '#type' => 'submit',
      '#name' => 'import_missing',
      '#value' => $this
        ->t('Import Missing'),
      '#attributes' => [
        'title' => $this
          ->t('Import only the missing configuration items.'),
      ],
    ];
  }
  $form['#attached'] = [
    'library' => [
      'features_ui/drupal.features_ui.admin',
    ],
    'drupalSettings' => [
      'features' => [
        'excluded' => $this->excluded,
        'required' => $this->required,
        'conflicts' => $this->conflicts,
        'autodetect' => TRUE,
      ],
    ],
  ];
  return $form;
}