diff --git a/Users/ravi/Downloads/menu_link_path_lang_prefix-2462279-127.patch b/Users/ravi/Desktop/contib_patchs/2462279-130.patch index 4829618757..d4ced4c1af 100644 --- a/Users/ravi/Downloads/menu_link_path_lang_prefix-2462279-127.patch +++ b/Users/ravi/Desktop/contib_patchs/2462279-130.patch @@ -1,6 +1,6 @@ diff --git a/core/modules/link/link.install b/core/modules/link/link.install new file mode 100644 -index 000000000..0153aed10 +index 0000000000..0153aed101 --- /dev/null +++ b/core/modules/link/link.install @@ -0,0 +1,69 @@ @@ -74,3 +74,170 @@ index 000000000..0153aed10 + } +} \ No newline at end of file +diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php +index b4dbdd8c36..c300077957 100644 +--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php ++++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php +@@ -50,7 +50,7 @@ public static function defaultSettings() { + * + * @see static::getUserEnteredStringAsUri() + */ +- protected static function getUriAsDisplayableString($uri) { ++ public static function getUriAsDisplayableString($uri) { + $scheme = parse_url($uri, PHP_URL_SCHEME); + + // By default, the displayable string is the URI. +@@ -133,6 +133,76 @@ protected static function getUserEnteredStringAsUri($string) { + return $uri; + } + ++ /** ++ * Checks if a user entered link will end up being processed as entered. ++ * ++ * One example is a user entering /en on a multilingual page and expecting the ++ * link to resolve to the English front page, while it in practice will ++ * resolve to the front page in the current language. ++ * ++ * @param string $user_link ++ * A user entered string, like the one entered in the widget. ++ * ++ * @return bool ++ * Whether the URL will resolve as the user entered it or not. ++ */ ++ public static function urlWillProcessAsUserEntered($user_link) { ++ $language_manager = \Drupal::languageManager(); ++ // Create a URL object from that. ++ $user_url = \Drupal::pathValidator()->getUrlIfValid($user_link); ++ if ($user_url) { ++ // If the user entered the special case "" we must allow this ++ // to not correspond to what Drupal thinks the URL is. ++ $base_path = \Drupal::service('request_stack') ++ ->getCurrentRequest() ++ ->getBasePath(); ++ if (strpos($user_link, '') === 0) { ++ // Need to append the '/' for comparison. ++ $user_link = str_replace('', $base_path . '/', $user_link); ++ } ++ $user_link = $base_path . $user_link; ++ // Compare the generated link with what Drupal thinks this is. We want ++ // to do this without language prefixes, if applicable. We also strip ++ // the fragments and query parameters, because those can confuse path ++ // resolving, and make for false errors. ++ $user_url->setOptions(['language' => $language_manager->getDefaultLanguage()]); ++ // Also, we want to allow the user to enter an aliased or non-aliased ++ // path. ++ $display_url = $user_url->toString(); ++ // On update.php this will end up being prefixed with update.php. ++ if (strpos($display_url, '/update.php') === 0) { ++ $display_url = str_replace('/update.php', '', $display_url); ++ } ++ $non_aliased_path_search = $display_url; ++ // Remove the base path to search for the alias. And for displaying to ++ // the user, if it comes to that. ++ if ($base_path) { ++ $display_url = substr_replace($display_url, '', 0, strlen($base_path)); ++ $non_aliased_path_search = substr_replace($non_aliased_path_search, '', 0, strlen($base_path)); ++ } ++ // Prepend back the base path after resolving the alias. ++ $non_aliased_path = $base_path . \Drupal::service('path.alias_manager') ++ ->getPathByAlias($non_aliased_path_search); ++ // Some times, for example in our tests, the front page can be set to ++ // something else than "/". In that case, our validator will tell the ++ // user that the link is not valid because the link resolves to ++ // something else than "/". So, make sure "/" is fine, if it resolves ++ // to the front page. ++ if (parse_url($user_link, PHP_URL_PATH) == $base_path . '/' || parse_url($user_link, PHP_URL_PATH) == $base_path . '') { ++ // Compare to front page config. ++ $front = \Drupal::config('system.site')->get('page.front'); ++ if ($user_url->toString() == $base_path . $front) { ++ // Just change the comparison user link. This will be allowed. ++ $user_link = $user_url->toString(); ++ } ++ } ++ if (strpos($user_link, $user_url->toString()) !== 0 && strpos($user_link, $non_aliased_path) !== 0) { ++ return FALSE; ++ } ++ } ++ return TRUE; ++ } ++ + /** + * Form element validation handler for the 'uri' element. + * +@@ -146,9 +216,23 @@ public static function validateUriElement($element, FormStateInterface $form_sta + // URI , ensure the raw value begins with '/', '?' or '#'. + // @todo '' 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) !== '') { +- $form_state->setError($element, t('Manually entered paths should start with one of the following characters: / ? #')); +- return; ++ if (parse_url($uri, PHP_URL_SCHEME) === 'internal') { ++ if (!in_array($element['#value'][0], ['/', '?', '#'], TRUE) && substr($element['#value'], 0, 7) !== '') { ++ $form_state->setError($element, t('Manually entered paths should start with one of the following characters: / ? #')); ++ return; ++ } ++ $user_link = $element['#value']; ++ // If the URL is internal, we want to check that the link will resolve in ++ // a way the user expects. ++ // Find the user input and validate that no URL negotiator will end up ++ // changing this URL to something else. For example if a user is ++ // entering a URL with a language prefix. ++ if (!static::urlWillProcessAsUserEntered($user_link)) { ++ $display_url = \Drupal::pathValidator()->getUrlIfValid($user_link)->toString(); ++ $form_state->setError($element, t('The link you entered is not valid. One reason can be that you entered a link with a language prefix. Did you for example mean to link to @url?', [ ++ '@url' => $display_url, ++ ])); ++ } + } + } + +@@ -214,14 +298,21 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen + + // If the field is configured to allow only internal links, add a useful + // element prefix and description. ++ $language_manager = \Drupal::languageManager(); + if (!$this->supportsExternalLinks()) { + $element['uri']['#field_prefix'] = rtrim(Url::fromRoute('', [], ['absolute' => TRUE])->toString(), '/'); + $element['uri']['#description'] = $this->t('This must be an internal path such as %add-node. You can also start typing the title of a piece of content to select it. Enter %front to link to the front page. Enter %nolink to display link text only. Enter %button to display keyboard-accessible link text only.', ['%add-node' => '/node/add', '%front' => '', '%nolink' => '', '%button' => 'route: