Dos modos de conseguir la ruta interna de una URL en Drupal
Hace poco encontré un problema en el (excelente) módulo Schemadotorg.
Básicamente, al comparar dos rutas de Drupal la primera resuelve a la ruta fea (interna, node/NID
) y otra al alias, la ruta bonita que solemos autogenerar con módulos como pathauto (/articulos/sección/nombre-del-artículo
).
$url = Url::fromRouteMatch($route_match);
$path = parse_url($url->toString(), PHP_URL_PATH); // <-- /ruta/con/alias
$front_path = $this->configFactory
->get('system.site')
->get('page.front'); // < -- /node/NID
if ($path === $front_path) // <------ FAIL!
Por tanto, al comparar rutas para ver si pertenecen al mismo recurso se podía dar un falso negativo.
Esto se debe a que la segunda ruta usa el método toString()
del objeto Url
de Drupal el cual siempre devuelve la ruta procesada (siendo el alias el procesado más común):
$url->toString(); // Devuelve /alias/al/recurso
¿Cómo podemos conseguir la ruta sin procesar?
La respuesta sencilla es que existe un segundo método:
$url->getInternalPath(); // Devuelve recurso/id
Pero los problemas no iban a acabar aquí. La comparación seguía fallando ya que la primera ruta viene con slash (/node/NID
) mientras que el método getInternalPath(
) devuelve la ruta sin slash (node/NID
).
Esto se podría solucionar concatenando el slash, pero este tipo de soluciones manuales siempre dan algo de miedito porque cualquier actualización de Drupal te lo podría tumbar.
Afortunadamente, existe una segunda vía menos conocida: podemos cambiar la opción path_processing
en el objeto URL para sortear el procesado:
$url->setOption('path_processing', false)->toString()
En este caso, toString()
se ejecuta sin dar permiso a los procesadores de ruta (el alias entre ellos) y el resultado es, ahora sí, /node/NID
.