You are here

function gutenberg_form_node_form_alter in Gutenberg 8

Same name and namespace in other branches
  1. 8.2 gutenberg.module \gutenberg_form_node_form_alter()

Implements hook_form_node_form_alter().

File

./gutenberg.module, line 259
Provides integration with the Gutenberg editor.

Code

function gutenberg_form_node_form_alter(&$form, FormStateInterface $form_state) {
  $config = \Drupal::service('config.factory')
    ->getEditable('gutenberg.settings');
  $node = $form_state
    ->getFormObject()
    ->getEntity();
  $node_type = $node->type
    ->getString();
  $gutenberg_enabled = $config
    ->get($node_type . '_enable_full');

  // Leave early if Gutenberg not enabled.
  if (!$gutenberg_enabled) {
    return;
  }

  // Set template options to global var.
  $form['#attached']['drupalSettings']['gutenberg']['template'] = json_decode($config
    ->get($node_type . '_template'));
  $form['#attached']['drupalSettings']['gutenberg']['template-lock'] = $config
    ->get($node_type . '_template_lock');

  /*
   * DEPRECATED >>>
   */
  $mapped_fields = _gutenberg_get_mapped_fields(json_decode($config
    ->get($node_type . '_template')));
  foreach ($mapped_fields as $item) {
    $form[$item['field']]['#access'] = FALSE;
  }

  /*
   * <<< DEPRECATED
   */
  $mapped_fields = _gutenberg_get_mapping_fields(json_decode($config
    ->get($node_type . '_template')));
  foreach ($mapped_fields as $item) {
    $form[$item['field']]['#access'] = FALSE;
  }
  $module_settings = _gutenberg_get_all_modules_settings();
  foreach ($module_settings as $settings) {
    if (isset($settings['libraries-edit'])) {
      foreach ($settings['libraries-edit'] as $library) {
        $form['#attached']['library'][] = $library;
      }
    }
  }
  $theme_settings = _gutenberg_get_default_theme_settings();
  if (isset($theme_settings['libraries-edit'])) {
    foreach ($theme_settings['libraries-edit'] as $value) {
      $form['#attached']['library'][] = $value;
    }
  }
  if (isset($theme_settings['theme-support'])) {
    $form['#attached']['drupalSettings']['gutenberg']['theme-support'] = $theme_settings['theme-support'];
  }

  // Set available image sizes for editor.
  $styles = ImageStyle::loadMultiple();
  $sizes = [
    [
      'slug' => 'full',
      'name' => t('Original'),
    ],
  ];
  foreach ($styles as $style) {
    $sizes[] = [
      'slug' => $style
        ->getName(),
      'name' => $style
        ->label(),
    ];
  }
  $form['#attached']['drupalSettings']['gutenberg']['image-sizes'] = $sizes;
  $text_fields = [];

  // Iterate over all node fields and apply gutenberg text format
  // on first text field found.
  $field_names = array_keys($node
    ->getFields());
  foreach ($field_names as $value) {
    $field_properties = array_keys($node
      ->getFieldDefinition($value)
      ->getFieldStorageDefinition()
      ->getPropertyDefinitions());
    if (in_array('format', $field_properties)) {
      $text_fields[] = $value;
    }
  }

  // No point going forward when no text fields on the form.
  if (count($text_fields) === 0) {
    return;
  }
  $form['#attributes']['class'][] = 'metabox-base-form';
  $form[$text_fields[0]]['widget'][0]['#format'] = 'gutenberg';
  $form[$text_fields[0]]['#attributes']['class'][] = 'field--gutenberg';

  // Hide the field label.
  $form[$text_fields[0]]['widget'][0]['#title_display'] = 'hidden';

  // Disable the summary field.
  if (isset($form[$text_fields[0]]['widget'][0]['summary'])) {
    $form[$text_fields[0]]['widget'][0]['summary']['#access'] = FALSE;
  }
  foreach ($text_fields as $fieldname) {

    // For the rest of the text fields call after build to remove
    // Gutenberg from text format options.
    if ($gutenberg_enabled) {
      if ($text_fields[0] !== $fieldname) {
        $form[$fieldname]['widget']['#after_build'][] = 'gutenberg_form_node_form_after_build';
      }
    }
    else {
      $form[$fieldname]['widget']['#after_build'][] = 'gutenberg_form_node_form_after_build';
    }
  }

  // Let's move the remaining fields to a "special"
  // form group that can be used later by JS to move to
  // Gutenberg's sidebar.
  $form['metabox_fields'] = [
    '#type' => 'details',
    '#access' => TRUE,
    '#title' => t('More settings'),
    '#weight' => 99,
    // Group fallback in case JS fails to move to metaboxes.
    '#group' => 'advanced',
  ];

  // Some other module might have already init this container.
  if (!isset($form['additional_fields'])) {
    $form['additional_fields'] = [
      '#type' => 'container',
      '#title' => 'Additional',
      '#weight' => -100,
    ];
  }

  // Move title to Published/meta pane.
  $form['title']['#group'] = 'meta';

  // Move status to Published/meta pane.
  $form['status']['#group'] = 'meta';

  // Move langcode to Published/meta pane.
  if (isset($form['langcode'])) {
    $form['langcode']['#group'] = 'meta';
  }
  $excluded_fields = [
    'status',
    'title',
    'uid',
    'created',
    'changed',
    'promote',
    'sticky',
    'path',
    'comment',
    'revision_log',
    'langcode',
  ];

  /*
   * Rationale behind this "messy" algo:
   * If there's any details fieldset on the form, add it to a special array
   * and then, on the form after build, add its #id to a JS array.
   * For any other type of fields, group them on the metabox_fields fieldset.
   * This fieldset will also move to metaboxes area.
   */
  $metabox_has_fields = FALSE;
  $fields_with_details = [];
  foreach ($field_names as $value) {
    if (array_key_exists($value, $form) && $value !== $text_fields[0] && !in_array($value, $excluded_fields)) {
      if (isset($form[$value]['widget']) && isset($form[$value]['widget'][0]) && isset($form[$value]['widget'][0]['#type']) && $form[$value]['widget'][0]['#type'] === 'details') {
        $fields_with_details[] = $value;
      }
      else {
        $form[$value]['#group'] = 'metabox_fields';
        $metabox_has_fields = TRUE;
      }
    }
  }
  $form['#after_build'][] = 'gutenberg_form_node_form_details_after_build';
  $form['#fields_with_details'] = $fields_with_details;
  if (!$metabox_has_fields) {
    unset($form['metabox_fields']);
  }

  // Is Bartik the default theme? Add some custom styles
  // to look even better.
  $default_theme = \Drupal::config('system.theme')
    ->get('default');
  if ($default_theme === 'bartik') {
    $form['#attached']['library'][] = 'gutenberg/bartik';
  }

  // Check if current theme is Seven (admin)
  $theme = \Drupal::theme()
    ->getActiveTheme();
  if ($theme
    ->getName() === 'seven') {
    $form['#attached']['library'][] = 'gutenberg/seven';
  }
  $form['#attached']['drupalSettings']['gutenberg']['metaboxes'][] = 'edit-metabox-fields';

  /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
  $module_handler = \Drupal::service('module_handler');
  $form['#attached']['drupalSettings']['gutenberg']['media-enabled'] = $module_handler
    ->moduleExists('media');
  if ($form['#attached']['drupalSettings']['gutenberg']['media-library-enabled'] = $module_handler
    ->moduleExists('media_library')) {
    $form['#attached']['library'][] = 'media_library/ui';
  }
}