From bd8c94a569898516d16f3fd02c3d082782cd66c4 Mon Sep 17 00:00:00 2001
From: "g.oechsler" <g.oechsler@744070.no-reply.drupal.org>
Date: Thu, 18 Oct 2012 21:16:33 +0200
Subject: [PATCH] 1705488 - prototype of DrupalUrlGenerator

---
 core/includes/common.inc                           |  106 +++-------------
 .../Drupal/Core/Routing/DrupalRouteCollection.php  |   14 +++
 .../lib/Drupal/Core/Routing/DrupalUrlGenerator.php |  131 ++++++++++++++++++++
 .../Symfony/Component/Routing/RouteCollection.php  |    2 +-
 4 files changed, 160 insertions(+), 93 deletions(-)
 create mode 100644 core/lib/Drupal/Core/Routing/DrupalRouteCollection.php
 create mode 100644 core/lib/Drupal/Core/Routing/DrupalUrlGenerator.php

diff --git a/core/includes/common.inc b/core/includes/common.inc
index 0f252ca..503fe33 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3,9 +3,12 @@
 use Symfony\Component\DependencyInjection\Container;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\Routing\RequestContext;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Database;
+use Drupal\Core\Routing\DrupalRouteCollection;
+use Drupal\Core\Routing\DrupalUrlGenerator;
 use Drupal\Core\Template\Attribute;
 
 /**
@@ -2115,98 +2118,17 @@ function _format_date_callback(array $matches = NULL, $new_langcode = NULL) {
  *   A string containing a URL to the given path.
  */
 function url($path = NULL, array $options = array()) {
-  // Merge in defaults.
-  $options += array(
-    'fragment' => '',
-    'query' => array(),
-    'absolute' => FALSE,
-    'alias' => FALSE,
-    'prefix' => '',
-    'script' => $GLOBALS['script_path'],
-  );
-
-  if (!isset($options['external'])) {
-    // Return an external link if $path contains an allowed absolute URL. Only
-    // call the slow drupal_strip_dangerous_protocols() if $path contains a ':'
-    // before any / ? or #. Note: we could use url_is_external($path) here, but
-    // that would require another function call, and performance inside url() is
-    // critical.
-    $colonpos = strpos($path, ':');
-    $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && drupal_strip_dangerous_protocols($path) == $path);
-  }
-
-  // Preserve the original path before altering or aliasing.
-  $original_path = $path;
-
-  // Allow other modules to alter the outbound URL and options.
-  drupal_alter('url_outbound', $path, $options, $original_path);
-
-  if (isset($options['fragment']) && $options['fragment'] !== '') {
-    $options['fragment'] = '#' . $options['fragment'];
-  }
-
-  if ($options['external']) {
-    // Split off the fragment.
-    if (strpos($path, '#') !== FALSE) {
-      list($path, $old_fragment) = explode('#', $path, 2);
-      // If $options contains no fragment, take it over from the path.
-      if (isset($old_fragment) && !$options['fragment']) {
-        $options['fragment'] = '#' . $old_fragment;
-      }
-    }
-    // Append the query.
-    if ($options['query']) {
-      $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . drupal_http_build_query($options['query']);
-    }
-    if (isset($options['https']) && variable_get('https', FALSE)) {
-      if ($options['https'] === TRUE) {
-        $path = str_replace('http://', 'https://', $path);
-      }
-      elseif ($options['https'] === FALSE) {
-        $path = str_replace('https://', 'http://', $path);
-      }
-    }
-    // Reassemble.
-    return $path . $options['fragment'];
-  }
-
-  global $base_url, $base_secure_url, $base_insecure_url;
-
-  // The base_url might be rewritten from the language rewrite in domain mode.
-  if (!isset($options['base_url'])) {
-    if (isset($options['https']) && variable_get('https', FALSE)) {
-      if ($options['https'] === TRUE) {
-        $options['base_url'] = $base_secure_url;
-        $options['absolute'] = TRUE;
-      }
-      elseif ($options['https'] === FALSE) {
-        $options['base_url'] = $base_insecure_url;
-        $options['absolute'] = TRUE;
-      }
-    }
-    else {
-      $options['base_url'] = $base_url;
-    }
-  }
-
-  // The special path '<front>' links to the default front page.
-  if ($path == '<front>') {
-    $path = '';
-  }
-  elseif (!empty($path) && !$options['alias']) {
-    $langcode = isset($options['language']) && isset($options['language']->langcode) ? $options['language']->langcode : '';
-    $alias = drupal_get_path_alias($original_path, $langcode);
-    if ($alias != $original_path) {
-      $path = $alias;
-    }
-  }
-
-  $base = $options['absolute'] ? $options['base_url'] . '/' : base_path();
-  $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
-
-  $path = drupal_encode_path($prefix . $path);
-  $query = $options['query'] ? ('?' . drupal_http_build_query($options['query'])) : '';
-  return $base . $options['script'] . $path . $query . $options['fragment'];
+  //This is just glue code to make the DrupalUrlGenerator run
+  $generator = &drupal_static(__FUNCTION__ );
+  
+  if ($generator === NULL) {
+    $routes = new DrupalRouteCollection();
+    $context = new RequestContext($_SERVER['REQUEST_URI']);
+    
+    $generator = new DrupalUrlGenerator($routes, $context);
+  }
+  
+  return $generator->url($path, $options);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Routing/DrupalRouteCollection.php b/core/lib/Drupal/Core/Routing/DrupalRouteCollection.php
new file mode 100644
index 0000000..dd20f07
--- /dev/null
+++ b/core/lib/Drupal/Core/Routing/DrupalRouteCollection.php
@@ -0,0 +1,14 @@
+<?php
+namespace Drupal\Core\Routing;
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+
+class DrupalRouteCollection extends RouteCollection {
+
+  public function add($name, Route $route) {
+    $this->remove($name);
+
+    $this->routes[$name] = $route;
+  }
+}
diff --git a/core/lib/Drupal/Core/Routing/DrupalUrlGenerator.php b/core/lib/Drupal/Core/Routing/DrupalUrlGenerator.php
new file mode 100644
index 0000000..2d5006a
--- /dev/null
+++ b/core/lib/Drupal/Core/Routing/DrupalUrlGenerator.php
@@ -0,0 +1,131 @@
+<?php
+namespace Drupal\Core\Routing;
+
+use Symfony\Component\Routing\Generator\UrlGenerator;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\LoggerInterface;
+use Symfony\Component\Routing\Route;
+
+class DrupalUrlGenerator extends UrlGenerator{
+  
+  public function url($path = NULL, $options = array()) {
+    if (null === $route = $this->routes->get($path)) {
+      $original_url = original_url($path, $options);
+      $this->routes->add($path, new Route($original_url));
+    }
+    
+    try {
+      $url = $this->generate($path);
+    }
+    catch (Exception $e) {
+      _drupal_render_exception_safe($e);
+    }
+
+    return $url;
+  }
+  
+  protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) {
+    $url = '';
+    foreach ($tokens as $token) {
+      if ($token[0] === 'text') {
+        $url = $token[1].$url;
+      }
+    }
+    return $url;
+  }
+}
+
+function original_url($path = NULL, array $options = array()) {
+  // Merge in defaults.
+  $options += array(
+    'fragment' => '',
+    'query' => array(),
+    'absolute' => FALSE,
+    'alias' => FALSE,
+    'prefix' => '',
+    'script' => $GLOBALS['script_path'],
+  );
+
+  if (!isset($options['external'])) {
+    // Return an external link if $path contains an allowed absolute URL. Only
+    // call the slow drupal_strip_dangerous_protocols() if $path contains a ':'
+    // before any / ? or #. Note: we could use url_is_external($path) here, but
+    // that would require another function call, and performance inside url() is
+    // critical.
+    $colonpos = strpos($path, ':');
+    $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && drupal_strip_dangerous_protocols($path) == $path);
+  }
+
+  // Preserve the original path before altering or aliasing.
+  $original_path = $path;
+
+  // Allow other modules to alter the outbound URL and options.
+  drupal_alter('url_outbound', $path, $options, $original_path);
+
+  if (isset($options['fragment']) && $options['fragment'] !== '') {
+    $options['fragment'] = '#' . $options['fragment'];
+  }
+
+  if ($options['external']) {
+    // Split off the fragment.
+    if (strpos($path, '#') !== FALSE) {
+      list($path, $old_fragment) = explode('#', $path, 2);
+      // If $options contains no fragment, take it over from the path.
+      if (isset($old_fragment) && !$options['fragment']) {
+        $options['fragment'] = '#' . $old_fragment;
+      }
+    }
+    // Append the query.
+    if ($options['query']) {
+      $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . drupal_http_build_query($options['query']);
+    }
+    if (isset($options['https']) && variable_get('https', FALSE)) {
+      if ($options['https'] === TRUE) {
+        $path = str_replace('http://', 'https://', $path);
+      }
+      elseif ($options['https'] === FALSE) {
+        $path = str_replace('https://', 'http://', $path);
+      }
+    }
+    // Reassemble.
+    return $path . $options['fragment'];
+  }
+
+  global $base_url, $base_secure_url, $base_insecure_url;
+
+  // The base_url might be rewritten from the language rewrite in domain mode.
+  if (!isset($options['base_url'])) {
+    if (isset($options['https']) && variable_get('https', FALSE)) {
+      if ($options['https'] === TRUE) {
+        $options['base_url'] = $base_secure_url;
+        $options['absolute'] = TRUE;
+      }
+      elseif ($options['https'] === FALSE) {
+        $options['base_url'] = $base_insecure_url;
+        $options['absolute'] = TRUE;
+      }
+    }
+    else {
+      $options['base_url'] = $base_url;
+    }
+  }
+
+  // The special path '<front>' links to the default front page.
+  if ($path == '<front>') {
+    $path = '';
+  }
+  elseif (!empty($path) && !$options['alias']) {
+    $langcode = isset($options['language']) && isset($options['language']->langcode) ? $options['language']->langcode : '';
+    $alias = drupal_get_path_alias($original_path, $langcode);
+    if ($alias != $original_path) {
+      $path = $alias;
+    }
+  }
+
+  $base = $options['absolute'] ? $options['base_url'] . '/' : base_path();
+  $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
+
+  $path = drupal_encode_path($prefix . $path);
+  $query = $options['query'] ? ('?' . drupal_http_build_query($options['query'])) : '';
+  return $base . $options['script'] . $path . $query . $options['fragment'];
+}
diff --git a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php
index 7a0e4c9..cc5dcd8 100644
--- a/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php
+++ b/core/vendor/symfony/routing/Symfony/Component/Routing/RouteCollection.php
@@ -26,7 +26,7 @@
  */
 class RouteCollection implements \IteratorAggregate, \Countable
 {
-    private $routes;
+    protected $routes;
     private $resources;
     private $prefix;
     private $parent;
-- 
1.7.9.5

