Documentation for $options in \Drupal\Core\Url methods is wrong / incomplete in many ways

Created on 6 July 2015, about 10 years ago
Updated 15 August 2025, 11 days ago

API page: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/f...

Many of the methods on Url take an $options array as an argument. These are:
__construct()
fromRoute()
fromUserInput()
fromUri()
fromEntityUri()
fromInternalUri()
fromRouteUri()

All these methods have their own documentation blocks, but all of these documentation blocks contain the following description of what can be passed by the $options parameter:

   * @param array $options
   *   (optional) An associative array of additional options, with the following
   *   elements:
   *   - 'query': An array of query key/value-pairs (without any URL-encoding)
   *     to append to the URL. Merged with the parameters array.
   *   - 'fragment': A fragment identifier (named anchor) to append to the URL.
   *     Do not include the leading '#' character.
   *   - 'absolute': Defaults to FALSE. Whether to force the output to be an
   *     absolute link (beginning with http:). Useful for links that will be
   *     displayed outside the site, such as in an RSS feed.
   *   - 'language': An optional language object used to look up the alias
   *     for the URL. If $options['language'] is omitted, it defaults to the
   *     current language for the language type LanguageInterface::TYPE_URL.
   *   - 'https': Whether this URL should point to a secure location. If not
   *     defined, the current scheme is used, so the user stays on HTTP or HTTPS
   *     respectively. TRUE enforces HTTPS and FALSE enforces HTTP.

Problems with this are:
1) Url doesn't do any validation on the $options keys, so *any* key is allowed, whether or not it is used by Url.
2) Url only looks at / uses two of these keys: 'query' and 'fragment'
3) The keys 'absolute', 'language', and 'https' are never used by the Url class. Perhaps they are used by some class that uses Urls, but it's unclear what that class might be or when it's important to include one of these keys in the $options argument. absolute and https are used in UrlGenerator, language is used in LinkGenerator for the hreflang attribute.
4) https is enforced in UrlGenerator::generateFromRoute via this option.
5) The 'set_active_class' $option is not documented in Url - LinkGenerator::generate() looks for the presence of this $option in the Url. (But generate() does not document the $options it uses).
6) The 'attributes' $option is not documented Url, but LinkGenerator::generate() looks for the presence of this $option in the Url.
7) Other classes might use other undocumented $options? I suspect many other classes use values stored in the Url $options for their own purposes.

This points to a problem with the architecture of these classes - here we are again passing around undocumented arrays that may/must have arbitrary values, and any class may arbitrarily make requirements on what gets passed into Url. And there is no good place we can document all the keys that may be used here, because Url just stores all the keys and passes them around without validation.

But it also points to a problem with documentation. If e.g. the documentation says that 'https' enforces the https scheme, then I expect that to be the case, and not only in the situation where the Url gets used by whatever function *really* enforces the https scheme, if any.

πŸ› Bug report
Status

Active

Version

11.0 πŸ”₯

Component

documentation

Created by

πŸ‡ΊπŸ‡ΈUnited States tr Cascadia

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¦πŸ‡ΊAustralia acbramley

    I agree this documentation is never going to be perfect if we continue to use ArrayPI here. Perhaps instead we need to swap to a value object to enforce these keys.

    I tracked down where the absolute and https options are handled:

    - absolute is set to FALSE by default in LinkGenerator and handled in UrlGenerator
    - https is handled in UrlGenerator. It does not have a default value in UrlGenerator because if it's set to FALSE it forces http.

    Agree with #3 that we should move attribute handling out of the Url object first.

Production build 0.71.5 2024