Skip to content
Snippets Groups Projects
Commit 8ce41b49 authored by Brian Canini's avatar Brian Canini
Browse files

adding patch file for entity embed based on "2511404":...

adding patch file for entity embed based on "2511404": "https://www.drupal.org/files/issues/2018-09-17/entity-embed-link-2511404-68.patch" with the exception of the new window checkbox which has been removed from the patch code
parent 9b99c8e0
No related branches found
No related tags found
No related merge requests found
diff --git a/entity_embed.module b/entity_embed.module
index fbdd994..ee8fbae 100644
--- a/entity_embed.module
+++ b/entity_embed.module
@@ -6,6 +6,9 @@
* format.
*/
+use Drupal\Component\Utility\UrlHelper;
+use Drupal\Core\Url;
+
/**
* Implements hook_theme().
*/
@@ -31,6 +34,25 @@ function template_preprocess_entity_embed_container(&$variables) {
$variables['element'] += ['#attributes' => []];
$variables['attributes'] = $variables['element']['#attributes'];
$variables['children'] = $variables['element']['#children'];
+ if (!empty($variables['element']['#context']['data-entity-embed-display-settings']['link_url'])) {
+ $link = UrlHelper::filterBadProtocol($variables['element']['#context']['data-entity-embed-display-settings']['link_url']);
+ if (!UrlHelper::isExternal($link)) {
+ $link = 'internal:/' . ltrim($link, '/');
+ }
+ $link = Url::fromUri($link);
+ $attributes = [];
+ if (!empty($variables['element']['#context']['data-entity-embed-display-settings']['link_url_target']) && $variables['element']['#context']['data-entity-embed-display-settings']['link_url_target'] == 1) {
+ $attributes = ['attributes' => ['target' => '_blank']];
+ }
+ $variables['children'] = [
+ [
+ '#type' => 'link',
+ '#title' => $variables['children'],
+ '#options' => $attributes,
+ '#url' => $link,
+ ]
+ ];
+ }
}
/**
diff --git a/src/Form/EntityEmbedDialog.php b/src/Form/EntityEmbedDialog.php
index ae0194b..fe16bd9 100644
--- a/src/Form/EntityEmbedDialog.php
+++ b/src/Form/EntityEmbedDialog.php
@@ -8,6 +8,7 @@ use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\SetDialogTitleCommand;
+use Drupal\Core\Entity\Element\EntityAutocomplete;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -434,6 +435,27 @@ class EntityEmbedDialog extends FormBase {
if (is_string($entity_element['data-entity-embed-display-settings'])) {
$entity_element['data-entity-embed-display-settings'] = Json::decode($entity_element['data-entity-embed-display-settings']);
}
+
+ // Supress Drupal's "Link image to" dropdown when embedding an image,
+ // since the 'Link to' option provides this functionality.
+ if (isset($form['attributes']['data-entity-embed-display-settings']['image_link'])) {
+ $form['attributes']['data-entity-embed-display-settings']['image_link']['#type'] = 'hidden';
+ $form['attributes']['data-entity-embed-display-settings']['image_link']['#value'] = '';
+ }
+ $form['attributes']['data-entity-embed-display-settings']['link_url'] = [
+ '#title' => t('Link to'),
+ '#type' => 'entity_autocomplete',
+ '#target_type' => 'node',
+ '#attributes' => [
+ 'data-autocomplete-first-character-blacklist' => '/#?'
+ ],
+ '#element_validate' => [[get_called_class(), 'validateUriElement']],
+ '#process_default_value' => FALSE,
+ '#description' => $this->t('Start typing the title of a piece of content to select it. You can also enter an internal path such as %add-node or an external URL such as %url. Enter %front to link to the front page.', ['%front' => '<front>', '%add-node' => '/node/add', '%url' => 'http://example.com']),
+ '#default_value' => isset($entity_element['data-entity-embed-display-settings']['link_url']) ? $this->getUriAsDisplayableString($entity_element['data-entity-embed-display-settings']['link_url']) : '',
+ '#maxlength' => 2048,
+ ];
+
$display = $this->entityEmbedDisplayManager->createInstance($plugin_id, $entity_element['data-entity-embed-display-settings']);
$display->setContextValue('entity', $entity);
$display->setAttributes($entity_element);
@@ -498,8 +520,120 @@ class EntityEmbedDialog extends FormBase {
}
/**
- * {@inheritdoc}
+ * Gets the URI without the 'internal:' or 'entity:' scheme.
+ *
+ * The following two forms of URIs are transformed:
+ * - 'entity:' URIs: to entity autocomplete ("label (entity id)") strings;
+ * - 'internal:' URIs: the scheme is stripped.
+ *
+ * This method is the inverse of ::getUserEnteredStringAsUri().
+ *
+ * @param string $uri
+ * The URI to get the displayable string for.
+ *
+ * @return string
+ *
+ * @see static::getUserEnteredStringAsUri()
*/
+ protected function getUriAsDisplayableString($uri) {
+ $uri = Html::decodeEntities($uri);
+ $scheme = parse_url($uri, PHP_URL_SCHEME);
+
+ // By default, the displayable string is the URI.
+ $displayable_string = $uri;
+
+ // A different displayable string may be chosen in case of the 'internal:'
+ // or 'entity:' built-in schemes.
+ if ($scheme === 'internal') {
+ $uri_reference = explode(':', $uri, 2)[1];
+
+ // @todo '<front>' is valid input for BC reasons, may be removed by
+ // https://www.drupal.org/node/2421941
+ $path = parse_url($uri, PHP_URL_PATH);
+ if ($path === '/') {
+ $uri_reference = '<front>' . substr($uri_reference, 1);
+ }
+
+ $displayable_string = $uri_reference;
+ }
+ elseif ($scheme === 'entity') {
+ list($entity_type, $entity_id) = explode('/', substr($uri, 7), 2);
+ // Show the 'entity:' URI as the entity autocomplete would.
+ // @todo Support entity types other than 'node'. Will be fixed in
+ // https://www.drupal.org/node/2423093.
+ if ($entity_type == 'node' && $entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity_id)) {
+ $displayable_string = EntityAutocomplete::getEntityLabels([$entity]);
+ }
+ }
+
+ return $displayable_string;
+ }
+
+ /**
+ * Gets the user-entered string as a URI.
+ *
+ * The following two forms of input are mapped to URIs:
+ * - entity autocomplete ("label (entity id)") strings: to 'entity:' URIs;
+ * - strings without a detectable scheme: to 'internal:' URIs.
+ *
+ * This method is the inverse of ::getUriAsDisplayableString().
+ *
+ * @param string $string
+ * The user-entered string.
+ *
+ * @return string
+ * The URI, if a non-empty $uri was passed.
+ *
+ * @see static::getUriAsDisplayableString()
+ */
+ protected static function getUserEnteredStringAsUri($string) {
+ // By default, assume the entered string is an URI.
+ $uri = $string;
+
+ // Detect entity autocomplete string, map to 'entity:' URI.
+ $entity_id = EntityAutocomplete::extractEntityIdFromAutocompleteInput($string);
+ if ($entity_id !== NULL) {
+ // @todo Support entity types other than 'node'. Will be fixed in
+ // https://www.drupal.org/node/2423093.
+ $uri = 'entity:node/' . $entity_id;
+ }
+ // Detect a schemeless string, map to 'internal:' URI.
+ elseif (!empty($string) && parse_url($string, PHP_URL_SCHEME) === NULL) {
+ // @todo '<front>' is valid input for BC reasons, may be removed by
+ // https://www.drupal.org/node/2421941
+ // - '<front>' -> '/'
+ // - '<front>#foo' -> '/#foo'
+ if (strpos($string, '<front>') === 0) {
+ $string = '/' . substr($string, strlen('<front>'));
+ }
+ $uri = 'internal:' . $string;
+ }
+
+ return $uri;
+ }
+
+ /**
+ * Form element validation handler for the 'uri' element.
+ *
+ * Disallows saving inaccessible or untrusted URLs.
+ */
+ public static function validateUriElement($element, FormStateInterface $form_state, $form) {
+ $uri = static::getUserEnteredStringAsUri($element['#value']);
+ $form_state->setValueForElement($element, $uri);
+
+ // If getUserEnteredStringAsUri() mapped the entered value to a 'internal:'
+ // URI , ensure the raw value begins with '/', '?' or '#'.
+ // @todo '<front>' is valid input for BC reasons, may be removed by
+ // https://www.drupal.org/node/2421941
+ if (parse_url($uri, PHP_URL_SCHEME) === 'internal' && !in_array($element['#value'][0], ['/', '?', '#'], TRUE) && substr($element['#value'], 0, 7) !== '<front>') {
+ $form_state->setError($element, t('Manually entered paths should start with /, ? or #.'));
+ return;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment