You are here

public function FreelinkingPrepopulate::buildLink in Freelinking 4.0.x

Same name and namespace in other branches
  1. 8.3 modules/freelinking_prepopulate/src/Plugin/freelinking/FreelinkingPrepopulate.php \Drupal\freelinking_prepopulate\Plugin\freelinking\FreelinkingPrepopulate::buildLink()

Build a link with the plugin.

Parameters

array $target: The target array with including the following keys:

  • text: The text to display in the URL.
  • indicator: The indicator string.
  • dest: The destination string for the plugin to turn into a URI.
  • tooltip: An optional tooltip.
  • language: A language object.

Return value

array Link array.

Overrides FreelinkingPluginInterface::buildLink

File

modules/freelinking_prepopulate/src/Plugin/freelinking/FreelinkingPrepopulate.php, line 171

Class

FreelinkingPrepopulate
Freelinking prepopulate plugin.

Namespace

Drupal\freelinking_prepopulate\Plugin\freelinking

Code

public function buildLink(array $target) {
  $config = $this
    ->getConfiguration();
  $title = isset($target['text']) ? $target['text'] : $target['dest'];
  if (isset($target['type']) || isset($target['bundle'])) {
    $bundle_name = isset($target['type']) ? $target['type'] : $target['bundle'];
  }
  else {
    $bundle_name = $config['settings']['default_node_type'];
  }
  $route_params = [
    'node_type' => $bundle_name,
  ];
  $options = [
    'query' => [
      // Don't allow any HTML tags for the title field.
      'edit[title][widget][0][value]' => Xss::filter($title, []),
    ],
  ];

  // Get optional query parameters for prepopulate fields.
  // @todo https://www.drupal.org/project/prepopulate/issues/2849432
  $fields = $this->entityFieldManager
    ->getFieldDefinitions('node', $bundle_name);
  $blacklist = [
    'type',
    'bundle',
    'text',
    'dest',
  ];
  foreach ($fields as $field_name => $field_definition) {
    if (!in_array($field_name, $blacklist) && array_key_exists($field_name, $target) && !$field_definition
      ->isInternal() && !$field_definition
      ->isComputed() && !$field_definition
      ->isReadOnly()) {
      $storage_definition = $field_definition
        ->getFieldStorageDefinition();
      if ($storage_definition instanceof FieldStorageDefinitionInterface) {
        $prop = $storage_definition
          ->getMainPropertyName();
        if ($storage_definition
          ->getType() === 'entity_reference') {
          $key = '[' . $prop . ']';
        }
        else {
          $key = '[0][' . $prop . ']';
        }

        // This won't work for complex field widgets in contributed modules
        // such as select_other lists.
        $query_name = 'edit[' . $field_name . '][widget]' . $key;

        // Use the standard XSS filter for values.
        $options['query'][$query_name] = Xss::filter($target[$field_name]);
      }
    }
  }

  // @todo Implement freelinking_prepopulate_fields_from_page()?
  // @todo Implement freelinking_prepopulate_fields_from_array()?
  // Allow a module to alter query string.
  $this->moduleHandler
    ->alter('freelinking_prepopulate_query', $options['query'], $target);
  $url = Url::fromRoute('node.add', $route_params, $options);
  if ($url
    ->access()) {
    $link = [
      '#type' => 'link',
      '#title' => $title,
      '#url' => $url,
      '#attributes' => [
        'title' => $this
          ->getTip(),
      ],
    ];
  }
  elseif ($config['settings']['failover'] === 'search') {
    $link = [
      '#type' => 'link',
      '#title' => $title,
      '#url' => Url::fromUserInput('/search', [
        'query' => [
          'keys' => $title,
        ],
        'language' => $target['language'],
      ]),
    ];
  }
  else {
    $link = [
      '#theme' => 'freelink_error',
      '#plugin' => 'freelinking_prepopulate',
      '#message' => $this
        ->t('Access denied to create missing content.'),
    ];
  }
  return $link;
}