1

I'm creating a text filter that modifies links. I am processing all the hrefs, and I want to load a RouteMatch or Url object for all valid urls like "/node/1". I need this to also handle i18n URLs. How do I convert a string like node/1 into a RouteMatch or Url object?

6
  • Currently working with: $url = URL::fromUserInput($href); However the $href object needs validation first.
    – simesy
    Commented Feb 11, 2016 at 1:17
  • What do you mean by "validation first"? Do you mean it is path that maps to a valid route?
    – mpdonadio
    Commented Feb 11, 2016 at 1:27
  • He likely means that the URL::fromUserInput() will throw an exception under unpredictable circumstances. That whole family of APIs were pretty fragile pre-release of 8.0, and may well still be. Commented Feb 11, 2016 at 1:35
  • @TorenwareNetworks That method is supposed to only throw an exception when the first character isn't a /, #, or ?, or when it is something that parse_url() can't understand. If you have seen other instances, file a bug report in the issue queue, as it probably means there is missing test coverage. And for disclosure, I am one of the people responsible for how Url() and friends ended up, as I worked on a lot of those issues.
    – mpdonadio
    Commented Feb 11, 2016 at 1:44
  • @MPD -- good to know we're talking to right person. It's been a couple of months since I dealt with the issue, but IIRC the path you're referring to was not where I was blowing up. And I'm aware that you folks cleaned up the URL code some time between early October and Nov. 18th. I'd need to look through my work on the File Example module of Examples 8.x-1.x to see how I worked around the problem. But I don't doubt that there's a gap in test coverage hiding there somewhere. Commented Feb 11, 2016 at 2:27

2 Answers 2

2

One way is to use PathValidator::getUrlIfValid(), which returns a Url object, if if the path passed as argument is valid and accessible.

if ($url = \Drupal::service('path.validator')->getUrlIfValid($path)) {
  // The path is valid and it's accessible from the currently logged-in user.
}

I don't think it can handle a URL that prefixed with the language code, if that's what you mean. That's usually handled/stored separately.

1
  • Oh, nice! This would mean I can inject the service and make my tests easier. I've been have trouble with the static constructor Url::fromUserInput().
    – simesy
    Commented Feb 12, 2016 at 1:34
1

You may want to look at a question I asked a few months back.

Berdir had the suggestion to take the URI and first feed it to file_create_url(), which seems to clean up some of the URLs that may make Drupal 8 blow up.

This isn't 100%, since the change record he refers to has since landed. My sense is that URL code is a lot better than it was, but can still occasionally blow up, rather than just give an error.

3
  • The question you reference has to do with an outstanding issue relating to URL objects and file URIs, and not a generic case of URL generation. The underlying cause has to do with the URL class not handling the stream wrapper schemes properly; file_create_url() is what is handling that intermediate step. TBH, I don't recall off the top of my head what that function will do with a non-file URI (the File system is one of the parts I am less familiar with).
    – mpdonadio
    Commented Feb 11, 2016 at 1:57
  • @MPD -- it does, but you're most likely to get bitten by that issue if you're generating a URL or a link. Remember that Drupal uses stream wrappers a lot, especially since public files are accessed via the public:// stream wrapper type. Creating links to public files certainly blew up will into the 8.0rc series. For all I know, it still does. Commented Feb 11, 2016 at 2:17
  • That question was specifically about a file URL. file_create_url() isn't the right tool for a path like that.
    – Berdir
    Commented Feb 11, 2016 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.