Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save katbailey/3068825 to your computer and use it in GitHub Desktop.
Save katbailey/3068825 to your computer and use it in GitHub Desktop.
Drupal 8 combined bundle and path alias patch
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 0551e56..43f5f1b 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -3,7 +3,8 @@
use Drupal\Core\Database\Database;
use Symfony\Component\ClassLoader\UniversalClassLoader;
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Container;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Language\Language;
@@ -2460,7 +2461,7 @@ function drupal_get_bootstrap_phase() {
* The instance of the Drupal Container used to set up and maintain object
* instances.
*/
-function drupal_container(ContainerBuilder $reset = NULL) {
+function drupal_container(Container $reset = NULL) {
// We do not use drupal_static() here because we do not have a mechanism by
// which to reinitialize the stored objects, so a drupal_static_reset() call
// would leave Drupal in a nonfunctional state.
@@ -2469,7 +2470,14 @@ function drupal_container(ContainerBuilder $reset = NULL) {
$container = $reset;
}
elseif (!isset($container)) {
+ // This will only ever happen if an error has been thrown. Just build a new
+ // ContainerBuilder with only the language_interface service.
$container = new ContainerBuilder();
+
+ // An interface language always needs to be available for t() and other
+ // functions. This default is overridden by drupal_language_initialize()
+ // during language negotiation.
+ $container->register(LANGUAGE_TYPE_INTERFACE, 'Drupal\\Core\\Language\\Language');
}
return $container;
}
@@ -2620,31 +2628,11 @@ function get_t() {
* @see Drupal\Core\Language\Language
*/
function drupal_language_initialize() {
- $types = language_types_get_all();
- $container = drupal_container();
-
- // Ensure a language object is registered for each language type, whether the
- // site is multilingual or not.
if (language_multilingual()) {
- include_once DRUPAL_ROOT . '/core/includes/language.inc';
- foreach ($types as $type) {
- $language = language_types_initialize($type);
- $container->set($type, NULL);
- $container->register($type, 'Drupal\\Core\\Language\\Language')
- ->addMethodCall('extend', array($language));
- }
// Allow modules to react on language system initialization in multilingual
// environments.
bootstrap_invoke_all('language_init');
}
- else {
- $default = language_default();
- foreach ($types as $type) {
- $container->set($type, NULL);
- $container->register($type, 'Drupal\\Core\\Language\\Language')
- ->addMethodCall('extend', array($default));
- }
- }
}
/**
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 8b53cc6..9008849 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2176,7 +2176,7 @@ function url($path = NULL, array $options = array()) {
}
elseif (!empty($path) && !$options['alias']) {
$langcode = isset($options['language']) && isset($options['language']->langcode) ? $options['language']->langcode : '';
- $alias = drupal_get_path_alias($original_path, $langcode);
+ $alias = drupal_container()->get('path_registry')->getPathAlias($original_path, $langcode);
if ($alias != $original_path) {
$path = $alias;
}
@@ -2499,7 +2499,7 @@ function drupal_deliver_html_page($page_callback_result) {
$_GET['destination'] = current_path();
}
- $path = drupal_get_normal_path($site_config->get('page.404'));
+ $path = drupal_container()->get('path_registry')->getSystemPath($site_config->get('page.404'));
if ($path && $path != current_path()) {
// Custom 404 handler. Set the active item in case there are tabs to
// display, or other dependencies on the path.
@@ -2528,7 +2528,7 @@ function drupal_deliver_html_page($page_callback_result) {
$_GET['destination'] = current_path();
}
- $path = drupal_get_normal_path($site_config->get('page.403'));
+ $path = drupal_container()->get('path_registry')->getSystemPath($site_config->get('page.403'));
if ($path && $path != current_path()) {
// Custom 403 handler. Set the active item in case there are tabs to
// display or other dependencies on the path.
@@ -5104,9 +5104,9 @@ function _drupal_bootstrap_code() {
}
/**
- * Temporary BC function for scripts not using HttpKernel.
+ * Temporary BC function for scripts not using DrupalKernel.
*
- * HttpKernel skips this and replicates it via event listeners.
+ * DrupalKernel skips this and replicates it via event listeners.
*
* @see Drupal\Core\EventSubscriber\PathSubscriber;
* @see Drupal\Core\EventSubscriber\LegacyRequestSubscriber;
@@ -5123,9 +5123,6 @@ function _drupal_bootstrap_full($skip = FALSE) {
// current_path().
drupal_language_initialize();
- // Initialize current_path() prior to invoking hook_init().
- drupal_path_initialize();
-
// Let all modules take action before the menu system handles the request.
// We do not want this while running update.php.
if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 581a6ce..91ee47d 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -2992,7 +2992,7 @@ function _menu_delete_item($item, $force = FALSE) {
* @param $item
* An associative array representing a menu link item, with elements:
* - link_path: (required) The path of the menu item, which should be
- * normalized first by calling drupal_get_normal_path() on it.
+ * normalized first by calling drupal_container()->get('path_registry')->getSystemPath() on it.
* - link_title: (required) Title to appear in menu for the link.
* - menu_name: (optional) The machine name of the menu for the link.
* Defaults to 'navigation'.
diff --git a/core/includes/path.inc b/core/includes/path.inc
index 62a58a6..9f37750 100644
--- a/core/includes/path.inc
+++ b/core/includes/path.inc
@@ -1,8 +1,10 @@
<?php
+use Drupal\Core\Path\DrupalPathRegistry;
+
/**
* @file
- * Functions to handle paths in Drupal, including path aliasing.
+ * Functions to handle paths in Drupal.
*
* These functions are not loaded for cached pages, but modules that need
* to use them in hook_boot() or hook exit() can make them available, by
@@ -10,203 +12,12 @@
*/
/**
- * Initializes the current path to the proper normal path.
- */
-function drupal_path_initialize() {
- // At this point, the current path is either the request path (due to
- // drupal_environment_initialize()) or some modified version of it due to
- // other bootstrap code (e.g., language negotiation), but it has not yet been
- // normalized by drupal_get_normal_path().
- $path = _current_path();
-
- // If on the front page, resolve to the front page path, including for calls
- // to current_path() while drupal_get_normal_path() is in progress.
- if (empty($path)) {
- $path = config('system.site')->get('page.front');
- _current_path($path);
- }
-
- // Normalize the path.
- _current_path(drupal_get_normal_path($path));
-}
-
-/**
- * Given an alias, return its Drupal system URL if one exists. Given a Drupal
- * system URL return one of its aliases if such a one exists. Otherwise,
- * return FALSE.
- *
- * @param $action
- * One of the following values:
- * - wipe: delete the alias cache.
- * - alias: return an alias for a given Drupal system path (if one exists).
- * - source: return the Drupal system URL for a path alias (if one exists).
- * @param $path
- * The path to investigate for corresponding aliases or system URLs.
- * @param $langcode
- * Optional language code to search the path with. Defaults to the page language.
- * If there's no path defined for that language it will search paths without
- * language.
- *
- * @return
- * Either a Drupal system path, an aliased path, or FALSE if no path was
- * found.
- */
-function drupal_lookup_path($action, $path = '', $langcode = NULL) {
- // Use the advanced drupal_static() pattern, since this is called very often.
- static $drupal_static_fast;
- if (!isset($drupal_static_fast)) {
- $drupal_static_fast['cache'] = &drupal_static(__FUNCTION__);
- }
- $cache = &$drupal_static_fast['cache'];
-
- if (!isset($cache)) {
- $cache = array(
- 'map' => array(),
- 'no_source' => array(),
- 'whitelist' => NULL,
- 'system_paths' => array(),
- 'no_aliases' => array(),
- 'first_call' => TRUE,
- );
- }
-
- // Retrieve the path alias whitelist.
- if (!isset($cache['whitelist'])) {
- $cache['whitelist'] = variable_get('path_alias_whitelist', NULL);
- if (!isset($cache['whitelist'])) {
- $cache['whitelist'] = drupal_path_alias_whitelist_rebuild();
- }
- }
-
- // If no language is explicitly specified we default to the current URL
- // language. If we used a language different from the one conveyed by the
- // requested URL, we might end up being unable to check if there is a path
- // alias matching the URL path.
- $langcode = $langcode ? $langcode : drupal_container()->get(LANGUAGE_TYPE_URL)->langcode;
-
- if ($action == 'wipe') {
- $cache = array();
- $cache['whitelist'] = drupal_path_alias_whitelist_rebuild();
- }
- elseif ($cache['whitelist'] && $path != '') {
- if ($action == 'alias') {
- // During the first call to drupal_lookup_path() per language, load the
- // expected system paths for the page from cache.
- if (!empty($cache['first_call'])) {
- $cache['first_call'] = FALSE;
-
- $cache['map'][$langcode] = array();
- // Load system paths from cache.
- $cid = current_path();
- if ($cached = cache('path')->get($cid)) {
- $cache['system_paths'] = $cached->data;
- // Now fetch the aliases corresponding to these system paths.
- $args = array(
- ':system' => $cache['system_paths'],
- ':langcode' => $langcode,
- ':langcode_undetermined' => LANGUAGE_NOT_SPECIFIED,
- );
- // Always get the language-specific alias before the language-neutral
- // one. For example 'de' is less than 'und' so the order needs to be
- // ASC, while 'xx-lolspeak' is more than 'und' so the order needs to
- // be DESC. We also order by pid ASC so that fetchAllKeyed() returns
- // the most recently created alias for each source. Subsequent queries
- // using fetchField() must use pid DESC to have the same effect.
- // For performance reasons, the query builder is not used here.
- if ($langcode == LANGUAGE_NOT_SPECIFIED) {
- // Prevent PDO from complaining about a token the query doesn't use.
- unset($args[':langcode']);
- $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode = :langcode_undetermined ORDER BY pid ASC', $args);
- }
- elseif ($langcode < LANGUAGE_NOT_SPECIFIED) {
- $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid ASC', $args);
- }
- else {
- $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid ASC', $args);
- }
- $cache['map'][$langcode] = $result->fetchAllKeyed();
- // Keep a record of paths with no alias to avoid querying twice.
- $cache['no_aliases'][$langcode] = array_flip(array_diff_key($cache['system_paths'], array_keys($cache['map'][$langcode])));
- }
- }
- // If the alias has already been loaded, return it.
- if (isset($cache['map'][$langcode][$path])) {
- return $cache['map'][$langcode][$path];
- }
- // Check the path whitelist, if the top_level part before the first /
- // is not in the list, then there is no need to do anything further,
- // it is not in the database.
- elseif (!isset($cache['whitelist'][strtok($path, '/')])) {
- return FALSE;
- }
- // For system paths which were not cached, query aliases individually.
- elseif (!isset($cache['no_aliases'][$langcode][$path])) {
- $args = array(
- ':source' => $path,
- ':langcode' => $langcode,
- ':langcode_undetermined' => LANGUAGE_NOT_SPECIFIED,
- );
- // See the queries above.
- if ($langcode == LANGUAGE_NOT_SPECIFIED) {
- unset($args[':langcode']);
- $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode = :langcode_undetermined ORDER BY pid DESC", $args)->fetchField();
- }
- elseif ($langcode > LANGUAGE_NOT_SPECIFIED) {
- $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args)->fetchField();
- }
- else {
- $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args)->fetchField();
- }
- $cache['map'][$langcode][$path] = $alias;
- return $alias;
- }
- }
- // Check $no_source for this $path in case we've already determined that there
- // isn't a path that has this alias
- elseif ($action == 'source' && !isset($cache['no_source'][$langcode][$path])) {
- // Look for the value $path within the cached $map
- $source = FALSE;
- if (!isset($cache['map'][$langcode]) || !($source = array_search($path, $cache['map'][$langcode]))) {
- $args = array(
- ':alias' => $path,
- ':langcode' => $langcode,
- ':langcode_undetermined' => LANGUAGE_NOT_SPECIFIED,
- );
- // See the queries above.
- if ($langcode == LANGUAGE_NOT_SPECIFIED) {
- unset($args[':langcode']);
- $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode = :langcode_undetermined ORDER BY pid DESC", $args);
- }
- elseif ($langcode > LANGUAGE_NOT_SPECIFIED) {
- $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args);
- }
- else {
- $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args);
- }
- if ($source = $result->fetchField()) {
- $cache['map'][$langcode][$source] = $path;
- }
- else {
- // We can't record anything into $map because we do not have a valid
- // index and there is no need because we have not learned anything
- // about any Drupal path. Thus cache to $no_source.
- $cache['no_source'][$langcode][$path] = TRUE;
- }
- }
- return $source;
- }
- }
-
- return FALSE;
-}
-
-/**
* Cache system paths for a page.
*
* Cache an array of the system paths available on each page. We assume
* that aliases will be needed for the majority of these paths during
- * subsequent requests, and load them in a single query during
- * drupal_lookup_path().
+ * subsequent requests, and load them in a single query during path alias
+ * lookup.
*/
function drupal_cache_system_paths() {
// Check if the system paths for this page were loaded from cache in this
@@ -215,8 +26,8 @@ function drupal_cache_system_paths() {
if (empty($cache['system_paths']) && !empty($cache['map'])) {
// Generate a cache ID (cid) specifically for this page.
$cid = current_path();
- // The static $map array used by drupal_lookup_path() includes all
- // system paths for the page request.
+ // The static $map array used by the alias lookup logic in path module
+ // includes all system paths for the page request.
if ($paths = current($cache['map'])) {
$data = array_keys($paths);
$expire = REQUEST_TIME + (60 * 60 * 24);
@@ -226,64 +37,6 @@ function drupal_cache_system_paths() {
}
/**
- * Given an internal Drupal path, return the alias set by the administrator.
- *
- * If no path is provided, the function will return the alias of the current
- * page.
- *
- * @param $path
- * An internal Drupal path.
- * @param $langcode
- * An optional language code to look up the path in.
- *
- * @return
- * An aliased path if one was found, or the original path if no alias was
- * found.
- */
-function drupal_get_path_alias($path = NULL, $langcode = NULL) {
- // If no path is specified, use the current page's path.
- if ($path == NULL) {
- $path = current_path();
- }
- $result = $path;
- if ($alias = drupal_lookup_path('alias', $path, $langcode)) {
- $result = $alias;
- }
- return $result;
-}
-
-/**
- * Given a path alias, return the internal path it represents.
- *
- * @param $path
- * A Drupal path alias.
- * @param $langcode
- * An optional language code to look up the path in.
- *
- * @return
- * The internal path represented by the alias, or the original alias if no
- * internal path was found.
- */
-function drupal_get_normal_path($path, $langcode = NULL) {
- $original_path = $path;
-
- // Lookup the path alias first.
- if ($source = drupal_lookup_path('source', $path, $langcode)) {
- $path = $source;
- }
-
- // Allow other modules to alter the inbound URL. We cannot use drupal_alter()
- // here because we need to run hook_url_inbound_alter() in the reverse order
- // of hook_url_outbound_alter().
- foreach (array_reverse(module_implements('url_inbound_alter')) as $module) {
- $function = $module . '_url_inbound_alter';
- $function($path, $original_path, $langcode);
- }
-
- return $path;
-}
-
-/**
* Check if the current page is the front page.
*
* @return
@@ -362,125 +115,6 @@ function current_path() {
}
/**
- * Rebuild the path alias white list.
- *
- * @param $source
- * An optional system path for which an alias is being inserted.
- *
- * @return
- * An array containing a white list of path aliases.
- */
-function drupal_path_alias_whitelist_rebuild($source = NULL) {
- // When paths are inserted, only rebuild the whitelist if the system path
- // has a top level component which is not already in the whitelist.
- if (!empty($source)) {
- $whitelist = variable_get('path_alias_whitelist', NULL);
- if (isset($whitelist[strtok($source, '/')])) {
- return $whitelist;
- }
- }
- // For each alias in the database, get the top level component of the system
- // path it corresponds to. This is the portion of the path before the first
- // '/', if present, otherwise the whole path itself.
- $whitelist = array();
- $result = db_query("SELECT DISTINCT SUBSTRING_INDEX(source, '/', 1) AS path FROM {url_alias}");
- foreach ($result as $row) {
- $whitelist[$row->path] = TRUE;
- }
- variable_set('path_alias_whitelist', $whitelist);
- return $whitelist;
-}
-
-/**
- * Fetch a specific URL alias from the database.
- *
- * @param $conditions
- * A string representing the source, a number representing the pid, or an
- * array of query conditions.
- *
- * @return
- * FALSE if no alias was found or an associative array containing the
- * following keys:
- * - source: The internal system path.
- * - alias: The URL alias.
- * - pid: Unique path alias identifier.
- * - langcode: The language code of the alias.
- */
-function path_load($conditions) {
- if (is_numeric($conditions)) {
- $conditions = array('pid' => $conditions);
- }
- elseif (is_string($conditions)) {
- $conditions = array('source' => $conditions);
- }
- elseif (!is_array($conditions)) {
- return FALSE;
- }
- $select = db_select('url_alias');
- foreach ($conditions as $field => $value) {
- $select->condition($field, $value);
- }
- return $select
- ->fields('url_alias')
- ->execute()
- ->fetchAssoc();
-}
-
-/**
- * Save a path alias to the database.
- *
- * @param $path
- * An associative array containing the following keys:
- * - source: The internal system path.
- * - alias: The URL alias.
- * - pid: (optional) Unique path alias identifier.
- * - langcode: (optional) The language code of the alias.
- */
-function path_save(&$path) {
- $path += array('langcode' => LANGUAGE_NOT_SPECIFIED);
-
- // Load the stored alias, if any.
- if (!empty($path['pid']) && !isset($path['original'])) {
- $path['original'] = path_load($path['pid']);
- }
-
- if (empty($path['pid'])) {
- drupal_write_record('url_alias', $path);
- module_invoke_all('path_insert', $path);
- }
- else {
- drupal_write_record('url_alias', $path, array('pid'));
- module_invoke_all('path_update', $path);
- }
-
- // Clear internal properties.
- unset($path['original']);
-
- // Clear the static alias cache.
- drupal_clear_path_cache($path['source']);
-}
-
-/**
- * Delete a URL alias.
- *
- * @param $criteria
- * A number representing the pid or an array of criteria.
- */
-function path_delete($criteria) {
- if (!is_array($criteria)) {
- $criteria = array('pid' => $criteria);
- }
- $path = path_load($criteria);
- $query = db_delete('url_alias');
- foreach ($criteria as $field => $value) {
- $query->condition($field, $value);
- }
- $query->execute();
- module_invoke_all('path_delete', $path);
- drupal_clear_path_cache($path['source']);
-}
-
-/**
* Determine whether a path is in the administrative section of the site.
*
* By default, paths are considered to be non-administrative. If a path does not
@@ -580,14 +214,3 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) {
return $item && $item['access'];
}
-/**
- * Clear the path cache.
- *
- * @param $source
- * An optional system path for which an alias is being changed.
- */
-function drupal_clear_path_cache($source = NULL) {
- // Clear the drupal_lookup_path() static cache.
- drupal_static_reset('drupal_lookup_path');
- drupal_path_alias_whitelist_rebuild($source);
-}
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php
new file mode 100644
index 0000000..291e54b
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+class RegisterKernelListenersPass implements CompilerPassInterface
+{
+ public function process(ContainerBuilder $container)
+ {
+ if (!$container->hasDefinition('dispatcher')) {
+ return;
+ }
+
+ $definition = $container->getDefinition('dispatcher');
+
+ foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) {
+
+ // We must assume that the class value has been correcly filled, even if the service is created by a factory
+ $class = $container->getDefinition($id)->getClass();
+
+ $refClass = new \ReflectionClass($class);
+ $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
+ if (!$refClass->implementsInterface($interface)) {
+ throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
+ }
+ $definition->addMethodCall('addSubscriberService', array($id, $class));
+ }
+ }
+}
diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
index a82f5b6..786a3a3 100644
--- a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
+++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
@@ -7,113 +7,38 @@
namespace Drupal\Core\DependencyInjection;
-use Drupal\Core\ContentNegotiation;
-use Drupal\Core\EventSubscriber\AccessSubscriber;
-use Drupal\Core\EventSubscriber\FinishResponseSubscriber;
-use Drupal\Core\EventSubscriber\LegacyControllerSubscriber;
-use Drupal\Core\EventSubscriber\LegacyRequestSubscriber;
-use Drupal\Core\EventSubscriber\MaintenanceModeSubscriber;
-use Drupal\Core\EventSubscriber\PathSubscriber;
-use Drupal\Core\EventSubscriber\RequestCloseSubscriber;
-use Drupal\Core\EventSubscriber\RouterListener;
-use Drupal\Core\EventSubscriber\ViewSubscriber;
-use Drupal\Core\ExceptionController;
-use Drupal\Core\LegacyUrlMatcher;
use Symfony\Component\DependencyInjection\ContainerBuilder as BaseContainerBuilder;
-use Symfony\Component\DependencyInjection\Reference;
-use Symfony\Component\EventDispatcher\EventDispatcher;
-use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
+use Symfony\Component\DependencyInjection\Compiler\Compiler;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Compiler\PassConfig;
+use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
/**
* Drupal's dependency injection container.
*/
class ContainerBuilder extends BaseContainerBuilder {
- /**
- * Registers the base Drupal services for the dependency injection container.
- */
- public function __construct() {
- parent::__construct();
+ public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
+ {
+ if (!isset($this->compiler) || null === $this->compiler) {
+ $this->compiler = new Compiler();
+ }
+
+ $this->compiler->addPass($pass, $type);
+ }
+
+ public function compile()
+ {
+ if (null === $this->compiler) {
+ $this->compiler = new Compiler();
+ }
+
+ $this->compiler->compile($this);
+ $this->parameterBag->resolve();
+ // TODO: The line below is commented out because there is code that calls
+ // the set() method on the container after it has been built - that method
+ // throws an exception if the container's parameters have been frozen.
+ //$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
+ }
- // An interface language always needs to be available for t() and other
- // functions. This default is overridden by drupal_language_initialize()
- // during language negotiation.
- $this->register(LANGUAGE_TYPE_INTERFACE, 'Drupal\\Core\\Language\\Language');
-
- // Register the default language content.
- $this->register(LANGUAGE_TYPE_CONTENT, 'Drupal\\Core\\Language\\Language');
-
- // Register configuration storage dispatcher.
- $this->setParameter('config.storage.info', array(
- 'Drupal\Core\Config\DatabaseStorage' => array(
- 'connection' => 'default',
- 'target' => 'default',
- 'read' => TRUE,
- 'write' => TRUE,
- ),
- 'Drupal\Core\Config\FileStorage' => array(
- 'directory' => config_get_config_directory(),
- 'read' => TRUE,
- 'write' => FALSE,
- ),
- ));
- $this->register('config.storage.dispatcher', 'Drupal\Core\Config\StorageDispatcher')
- ->addArgument('%config.storage.info%');
-
- // Register configuration object factory.
- $this->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
- ->addArgument(new Reference('config.storage.dispatcher'));
-
- // Register the HTTP kernel services.
- $this->register('dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher')
- ->addArgument(new Reference('service_container'))
- ->setFactoryClass('Drupal\Core\DependencyInjection\ContainerBuilder')
- ->setFactoryMethod('getKernelEventDispatcher');
- $this->register('resolver', 'Symfony\Component\HttpKernel\Controller\ControllerResolver');
- $this->register('httpkernel', 'Symfony\Component\HttpKernel\HttpKernel')
- ->addArgument(new Reference('dispatcher'))
- ->addArgument(new Reference('resolver'));
- }
-
- /**
- * Creates an EventDispatcher for the HttpKernel. Factory method.
- *
- * @param Drupal\Core\DependencyInjection\ContainerBuilder $container
- * The dependency injection container that contains the HTTP kernel.
- *
- * @return Symfony\Component\EventDispatcher\EventDispatcher
- * An EventDispatcher with the default listeners attached to it.
- */
- public static function getKernelEventDispatcher($container) {
- $dispatcher = new EventDispatcher();
-
- $matcher = new LegacyUrlMatcher();
- $dispatcher->addSubscriber(new RouterListener($matcher));
-
- $negotiation = new ContentNegotiation();
-
- // @todo Make this extensible rather than just hard coding some.
- // @todo Add a subscriber to handle other things, too, like our Ajax
- // replacement system.
- $dispatcher->addSubscriber(new ViewSubscriber($negotiation));
- $dispatcher->addSubscriber(new AccessSubscriber());
- $dispatcher->addSubscriber(new MaintenanceModeSubscriber());
- $dispatcher->addSubscriber(new PathSubscriber());
- $dispatcher->addSubscriber(new LegacyRequestSubscriber());
- $dispatcher->addSubscriber(new LegacyControllerSubscriber());
- $dispatcher->addSubscriber(new FinishResponseSubscriber());
- $dispatcher->addSubscriber(new RequestCloseSubscriber());
-
- // Some other form of error occured that wasn't handled by another kernel
- // listener. That could mean that it's a method/mime-type/error combination
- // that is not accounted for, or some other type of error. Either way, treat
- // it as a server-level error and return an HTTP 500. By default, this will
- // be an HTML-type response because that's a decent best guess if we don't
- // know otherwise.
- $exceptionController = new ExceptionController($negotiation);
- $exceptionController->setContainer($container);
- $dispatcher->addSubscriber(new ExceptionListener(array($exceptionController, 'execute')));
-
- return $dispatcher;
- }
}
diff --git a/core/lib/Drupal/Core/DrupalBundle.php b/core/lib/Drupal/Core/DrupalBundle.php
new file mode 100644
index 0000000..db28f5b
--- /dev/null
+++ b/core/lib/Drupal/Core/DrupalBundle.php
@@ -0,0 +1,218 @@
+<?php
+
+namespace Drupal\Core;
+
+use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\Compiler\PassConfig;
+
+class DrupalBundle extends Bundle
+{
+ public function build(ContainerBuilder $container)
+ {
+ $definitions = $this->getDefinitions();
+
+ foreach ($definitions as $id => $info) {
+ $info += array(
+ 'tags' => array(),
+ 'references' => array(),
+ 'parameters' => array(),
+ 'methods' => array(),
+ 'arguments' => array(),
+ );
+
+ $references = array();
+ foreach ($info['references'] as $ref_id) {
+ $references[] = new Reference($ref_id);
+ }
+
+ $definition = new Definition($info['class'], $references);
+
+ foreach ($info['parameters'] as $key => $param) {
+ $container->setParameter($key, $param);
+ $definition->addArgument("%{$key}%");
+ }
+
+ if (isset($info['factory_class']) && isset($info['factory_method'])) {
+ $definition->setFactoryClass($info['factory_class']);
+ $definition->setFactoryMethod($info['factory_method']);
+ }
+
+ foreach ($info['arguments'] as $argument) {
+ $definition->addArgument($argument);
+ }
+
+ foreach($info['tags'] as $tag) {
+ $definition->addTag($tag);
+ }
+
+ foreach ($info['methods'] as $method => $args) {
+ $definition->addMethodCall($method, $args);
+ }
+
+ $container->setDefinition($id, $definition);
+ }
+
+ $this->registerLanguageServices($container);
+
+ // Add a compiler pass for registering event subscribers.
+ $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
+ }
+
+ /**
+ * Returns an array of definitions for the services we want to register.
+ */
+ function getDefinitions() {
+ return array(
+ // Register configuration storage dispatcher.
+ 'config.storage.dispatcher' => array(
+ 'class' => 'Drupal\Core\Config\StorageDispatcher',
+ 'parameters' => array(
+ 'conifg.storage.info' => array(
+ 'Drupal\Core\Config\DatabaseStorage' => array(
+ 'connection' => 'default',
+ 'target' => 'default',
+ 'read' => TRUE,
+ 'write' => TRUE,
+ ),
+ 'Drupal\Core\Config\FileStorage' => array(
+ 'directory' => config_get_config_directory(),
+ 'read' => TRUE,
+ 'write' => FALSE,
+ ),
+ ),
+ ),
+ ),
+ 'config.factory' => array(
+ 'class' => 'Drupal\Core\Config\ConfigFactory',
+ 'references' => array(
+ 'config.storage.dispatcher'
+ )
+ ),
+ 'dispatcher' => array(
+ 'class' => 'Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher',
+ 'references' => array(
+ 'service_container',
+ ),
+ ),
+ 'resolver' => array(
+ 'class' => 'Symfony\Component\HttpKernel\Controller\ControllerResolver',
+ ),
+ 'http_kernel' => array(
+ 'class' => 'Symfony\Component\HttpKernel\HttpKernel',
+ 'references' => array(
+ 'dispatcher', 'resolver',
+ )
+ ),
+ 'matcher' => array(
+ 'class' => 'Drupal\Core\LegacyUrlMatcher',
+ ),
+ 'router_listener' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\RouterListener',
+ 'references' => array('matcher'),
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'path_registry' => array(
+ 'class' => 'Drupal\Core\Path\PathRegistry'
+ ),
+ 'content_negotiation' => array(
+ 'class' => 'Drupal\Core\ContentNegotiation',
+ ),
+ 'view_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\ViewSubscriber',
+ 'references' => array('content_negotiation'),
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'access_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\AccessSubscriber',
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'maintenance_mode_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\MaintenanceModeSubscriber',
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'path_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\PathSubscriber',
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'legacy_request_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\LegacyRequestSubscriber',
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'legacy_controller_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\LegacyControllerSubscriber',
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'finish_response_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\FinishResponseSubscriber',
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'request_close_subscriber' => array(
+ 'class' => 'Drupal\Core\EventSubscriber\RequestCloseSubscriber',
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'exception_controller' => array(
+ 'class' => 'Drupal\Core\ExceptionController',
+ 'references' => array('content_negotiation'),
+ 'methods' => array('setContainer' => array('service_container'))
+ ),
+ 'exception_listener' => array(
+ 'class' => 'Symfony\Component\HttpKernel\EventListener\ExceptionListener',
+ 'references' => array('exception_controller'),
+ 'tags' => array('kernel.event_subscriber')
+ ),
+ 'database' => array(
+ 'class' => 'Drupal\Core\Database\Connection',
+ 'factory_class' => 'Drupal\Core\Database\Database',
+ 'factory_method' => 'getConnection',
+ 'arguments' => array('default'),
+ ),
+ 'database.slave' => array(
+ 'class' => 'Drupal\Core\Database\Connection',
+ 'factory_class' => 'Drupal\Core\Database\Database',
+ 'factory_method' => 'getConnection',
+ 'arguments' => array('slave'),
+ ),
+ );
+ }
+
+ /**
+ * Registers language-related services to the container.
+ */
+ function registerLanguageServices($container) {
+
+ $types = language_types_get_all();
+
+ // Ensure a language object is registered for each language type, whether the
+ // site is multilingual or not.
+ if (language_multilingual()) {
+ include_once DRUPAL_ROOT . '/core/includes/language.inc';
+ foreach ($types as $type) {
+ $language = language_types_initialize($type);
+ // We cannot pass an object as a parameter to a method on a service.
+ $info = get_object_vars($language);
+ $container->set($type, NULL);
+ $container->register($type, 'Drupal\\Core\\Language\\Language')
+ ->addMethodCall('extend', array($info));
+ }
+ }
+ else {
+ $info = variable_get('language_default', array(
+ 'langcode' => 'en',
+ 'name' => 'English',
+ 'direction' => 0,
+ 'weight' => 0,
+ 'locked' => 0,
+ ));
+ $info['default'] = TRUE;
+ foreach ($types as $type) {
+ $container->set($type, NULL);
+ $container->register($type, 'Drupal\\Core\\Language\\Language')
+ ->addMethodCall('extend', array($info));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
new file mode 100644
index 0000000..b38e950
--- /dev/null
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\DrupalKernel.
+ */
+
+namespace Drupal\Core;
+
+use Drupal\Core\DrupalBundle;
+use Symfony\Component\HttpKernel\Kernel;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
+
+/**
+ * The DrupalKernel class is the core of Drupal itself.
+ */
+class DrupalKernel extends Kernel {
+
+ public function registerBundles()
+ {
+ $bundles = array(
+ new DrupalBundle(),
+ );
+
+ // Rather than bootstrapping to a higher phase prior to booting the Kernel, which
+ // would ensure these files are loaded already, we want to boot the Kernel as
+ // early as possible in the bootstrapping phase.
+ // TODO: Somehow remove the necessity of calling system_list() to find out which
+ // bundles exist.
+ require_once DRUPAL_ROOT . '/core/includes/cache.inc';
+ require_once DRUPAL_ROOT . '/core/includes/module.inc';
+ require_once DRUPAL_ROOT . '/core/includes/database.inc';
+
+ $modules = array_keys(system_list('module_enabled'));
+ foreach ($modules as $module) {
+ $class = "\Drupal\\{$module}\\{$module}Bundle";
+ if (class_exists($class)) {
+ $bundles[] = new $class();
+ }
+ }
+ return $bundles;
+ }
+
+
+ /**
+ * Initializes the service container.
+ */
+ protected function initializeContainer()
+ {
+ $this->container = $this->buildContainer();
+ $this->container->set('kernel', $this);
+ drupal_container($this->container);
+ }
+
+ /**
+ * Builds the service container.
+ *
+ * @return ContainerBuilder The compiled service container
+ */
+ protected function buildContainer()
+ {
+ $container = $this->getContainerBuilder();
+ foreach ($this->bundles as $bundle) {
+ $bundle->build($container);
+ }
+ $container->compile();
+ return $container;
+ }
+
+
+ /**
+ * Gets a new ContainerBuilder instance used to build the service container.
+ *
+ * @return ContainerBuilder
+ */
+ protected function getContainerBuilder()
+ {
+ return new ContainerBuilder(new ParameterBag($this->getKernelParameters()));
+ }
+
+ public function registerContainerConfiguration(LoaderInterface $loader)
+ {
+ // We have to define this method because it's not defined in the base class
+ // but is part of the KernelInterface interface. However, the LoaderInterface
+ // class is part of the config component, which we are not using, so this
+ // is badness :-/
+ }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
index 2e1bece..9ee912f 100644
--- a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
@@ -30,7 +30,7 @@ class PathSubscriber extends PathListenerBase implements EventSubscriberInterfac
$path = $this->extractPath($request);
- $path = drupal_get_normal_path($path);
+ $path = drupal_container()->get('path_registry')->getSystemPath($path);
$this->setPath($request, $path);
}
diff --git a/core/lib/Drupal/Core/ExceptionController.php b/core/lib/Drupal/Core/ExceptionController.php
index 7f71e28..931d88c 100644
--- a/core/lib/Drupal/Core/ExceptionController.php
+++ b/core/lib/Drupal/Core/ExceptionController.php
@@ -82,7 +82,7 @@ class ExceptionController extends ContainerAware {
$system_path = $request->attributes->get('system_path');
watchdog('access denied', $system_path, NULL, WATCHDOG_WARNING);
- $path = drupal_get_normal_path(config('system.site')->get('page.403'));
+ $path = drupal_container()->get('path_registry')->getSystemPath(config('system.site')->get('page.403'));
if ($path && $path != $system_path) {
// Keep old path for reference, and to allow forms to redirect to it.
if (!isset($_GET['destination'])) {
@@ -107,7 +107,7 @@ class ExceptionController extends ContainerAware {
drupal_static_reset('menu_set_active_trail');
menu_reset_static_cache();
- $response = $this->container->get('httpkernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
+ $response = $this->container->get('http_kernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
$response->setStatusCode(403, 'Access denied');
}
else {
@@ -148,7 +148,7 @@ class ExceptionController extends ContainerAware {
$_GET['destination'] = $system_path;
}
- $path = drupal_get_normal_path(config('system.site')->get('page.404'));
+ $path = drupal_container()->get('path_registry')->getSystemPath(config('system.site')->get('page.404'));
if ($path && $path != $system_path) {
// @todo Um, how do I specify an override URL again? Totally not clear. Do
// that and sub-call the kernel rather than using meah().
@@ -172,7 +172,7 @@ class ExceptionController extends ContainerAware {
drupal_static_reset('menu_set_active_trail');
menu_reset_static_cache();
- $response = $this->container->get('httpkernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
+ $response = $this->container->get('http_kernel')->handle($subrequest, HttpKernel::SUB_REQUEST);
$response->setStatusCode(404, 'Not Found');
}
else {
diff --git a/core/lib/Drupal/Core/Language/Language.php b/core/lib/Drupal/Core/Language/Language.php
index e774fa9..9ace41f 100644
--- a/core/lib/Drupal/Core/Language/Language.php
+++ b/core/lib/Drupal/Core/Language/Language.php
@@ -44,8 +44,8 @@ class Language {
*
* @todo Remove this function once $GLOBALS['language'] is gone.
*/
- public function extend($obj) {
- $vars = get_object_vars($obj);
+ public function extend($info) {
+ $vars = is_array($info) ? $info : get_object_vars($info);
foreach ($vars as $var => $value) {
$this->$var = $value;
}
diff --git a/core/lib/Drupal/Core/Path/PathRegistry.php b/core/lib/Drupal/Core/Path/PathRegistry.php
new file mode 100644
index 0000000..c1d9c0d
--- /dev/null
+++ b/core/lib/Drupal/Core/Path/PathRegistry.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Path\PathRegistry.
+ */
+
+namespace Drupal\Core\Path;
+
+use Drupal\Core\Path\PathRegistryInterface;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Database\Connection;
+
+class PathRegistry implements PathRegistryInterface {
+
+ public function save($source, $alias, $langcode = LANGUAGE_NOT_SPECIFIED, $pid = NULL) {
+ return FALSE;
+ }
+
+ public function load($conditions) {
+ return FALSE;
+ }
+
+ public function delete($conditions) {
+ return 0;
+ }
+
+ public function getSystemPath($path, $path_language = NULL) {
+ return $path;
+ }
+
+ public function getPathAlias($path = NULL, $path_language = NULL) {
+ return isset($path) ? $path : NULL;
+ }
+
+ public function cacheClear($source = NULL) {
+
+ }
+}
+
diff --git a/core/lib/Drupal/Core/Path/PathRegistryInterface.php b/core/lib/Drupal/Core/Path/PathRegistryInterface.php
new file mode 100644
index 0000000..251849b
--- /dev/null
+++ b/core/lib/Drupal/Core/Path/PathRegistryInterface.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Path\PathRegistryInterface.
+ */
+
+namespace Drupal\Core\Path;
+
+interface PathRegistryInterface {
+ /**
+ * Save a path alias to the database.
+ *
+ * @param $source
+ * The internal system path.
+ * @param $alias
+ * The URL alias.
+ * @param $langcode
+ * The language of the alias.
+ * @param $pid
+ * Unique path alias identifier.
+ */
+ public function save($source, $alias, $langcode = LANGUAGE_NOT_SPECIFIED, $pid = NULL);
+
+ /**
+ * Fetch a specific URL alias from the database.
+ *
+ * @param $conditions
+ * A string representing the source, a number representing the pid, or an
+ * array of query conditions.
+ *
+ * @return
+ * FALSE if no alias was found or an associative array containing the
+ * following keys:
+ * - source: The internal system path.
+ * - alias: The URL alias.
+ * - pid: Unique path alias identifier.
+ * - language: The language of the alias.
+ */
+ public function load($conditions);
+
+ /**
+ * Delete a URL alias.
+ *
+ * @param $criteria
+ * A number representing the pid or an array of criteria.
+ */
+ public function delete($pid);
+
+ /**
+ * Given a path alias, return the internal path it represents.
+ *
+ * @param $path
+ * A Drupal path alias.
+ * @param $path_language
+ * An optional language code to look up the path in.
+ *
+ * @return
+ * The internal path represented by the alias, or the original alias if no
+ * internal path was found.
+ */
+ public function getSystemPath($path, $path_language = NULL);
+
+ /**
+ * Given an internal Drupal path, return the alias set by the administrator.
+ *
+ * If no path is provided, the function will return the alias of the current
+ * page.
+ *
+ * @param $path
+ * An optional internal Drupal path.
+ * @param $path_language
+ * An optional language code to look up the path in.
+ *
+ * @return
+ * An aliased path if one was found, or the original path if no alias was
+ * found.
+ */
+ public function getPathAlias($path = NULL, $path_language = NULL);
+
+ /**
+ * Clear the path cache.
+ *
+ * @param $source
+ * An optional system path for which an alias is being changed.
+ */
+ public function cacheClear($source = NULL);
+}
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 50bae76..aab2098 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -851,7 +851,7 @@ function block_block_list_alter(&$blocks) {
if ($block->visibility < BLOCK_VISIBILITY_PHP) {
// Compare the lowercase path alias (if any) and internal path.
$path = current_path();
- $path_alias = drupal_strtolower(drupal_get_path_alias($path));
+ $path_alias = drupal_strtolower(drupal_container()->get('path_registry')->getPathAlias($path));
$page_match = drupal_match_path($path_alias, $pages) || (($path != $path_alias) && drupal_match_path($path, $pages));
// When $block->visibility has a value of 0 (BLOCK_VISIBILITY_NOTLISTED),
// the block is displayed on all pages except those listed in $block->pages.
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php
index 5476a7a..9ed5f75 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php
@@ -96,38 +96,23 @@ class LocalePathTest extends WebTestBase {
$custom_path = $this->randomName(8);
// Check priority of language for alias by source path.
- $edit = array(
- 'source' => 'node/' . $node->nid,
- 'alias' => $custom_path,
- 'langcode' => LANGUAGE_NOT_SPECIFIED,
- );
- path_save($edit);
- $lookup_path = drupal_lookup_path('alias', 'node/' . $node->nid, 'en');
+ drupal_container()->get('path_registry')->save('node/' . $node->nid, $custom_path, LANGUAGE_NOT_SPECIFIED);
+ $lookup_path = drupal_container()->get('path_registry')->getPathAlias('node/' . $node->nid, 'en');
$this->assertEqual($english_path, $lookup_path, t('English language alias has priority.'));
// Same check for language 'xx'.
- $lookup_path = drupal_lookup_path('alias', 'node/' . $node->nid, $prefix);
+ $lookup_path = drupal_container()->get('path_registry')->getPathAlias('node/' . $node->nid, $prefix);
$this->assertEqual($custom_language_path, $lookup_path, t('Custom language alias has priority.'));
- path_delete($edit);
+ drupal_container()->get('path_registry')->delete(array('source' => 'node/' . $node->nid, 'alias' => $custom_path, 'langcode' => LANGUAGE_NOT_SPECIFIED));
// Create language nodes to check priority of aliases.
$first_node = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1));
$second_node = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1));
// Assign a custom path alias to the first node with the English language.
- $edit = array(
- 'source' => 'node/' . $first_node->nid,
- 'alias' => $custom_path,
- 'langcode' => 'en',
- );
- path_save($edit);
+ drupal_container()->get('path_registry')->save('node/' . $first_node->nid, $custom_path, 'en');
// Assign a custom path alias to second node with LANGUAGE_NOT_SPECIFIED.
- $edit = array(
- 'source' => 'node/' . $second_node->nid,
- 'alias' => $custom_path,
- 'langcode' => LANGUAGE_NOT_SPECIFIED,
- );
- path_save($edit);
+ drupal_container()->get('path_registry')->save('node/' . $second_node->nid, $custom_path, LANGUAGE_NOT_SPECIFIED);
// Test that both node titles link to our path alias.
$this->drupalGet('<front>');
diff --git a/core/modules/menu/menu.admin.inc b/core/modules/menu/menu.admin.inc
index 496ff88..67213b9 100644
--- a/core/modules/menu/menu.admin.inc
+++ b/core/modules/menu/menu.admin.inc
@@ -369,7 +369,7 @@ function menu_edit_item($form, &$form_state, $type, $item, $menu) {
*/
function menu_edit_item_validate($form, &$form_state) {
$item = &$form_state['values'];
- $normal_path = drupal_get_normal_path($item['link_path']);
+ $normal_path = drupal_container()->get('path_registry')->getSystemPath($item['link_path']);
if ($item['link_path'] != $normal_path) {
drupal_set_message(t('The menu system stores system paths only, but will use the URL alias for display. %link_path has been stored as %normal_path', array('%link_path' => $item['link_path'], '%normal_path' => $normal_path)));
$item['link_path'] = $normal_path;
diff --git a/core/modules/path/lib/Drupal/path/PathBundle.php b/core/modules/path/lib/Drupal/path/PathBundle.php
new file mode 100644
index 0000000..d450fee
--- /dev/null
+++ b/core/modules/path/lib/Drupal/path/PathBundle.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\path;
+
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+class PathBundle extends Bundle
+{
+ public function build(ContainerBuilder $container)
+ {
+ $container->set('path_registry', NULL);
+ $definition = new Definition('Drupal\path\PathRegistry', array(new Reference('database')));
+ $container->setDefinition('path_registry', $definition);
+ }
+}
\ No newline at end of file
diff --git a/core/modules/path/lib/Drupal/path/PathRegistry.php b/core/modules/path/lib/Drupal/path/PathRegistry.php
new file mode 100644
index 0000000..cceaa7c
--- /dev/null
+++ b/core/modules/path/lib/Drupal/path/PathRegistry.php
@@ -0,0 +1,317 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\path\PathRegistry.
+ */
+
+namespace Drupal\path;
+
+use Drupal\Core\Path\PathRegistryInterface;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Database\Connection;
+
+class PathRegistry implements PathRegistryInterface {
+
+ public function __construct(Connection $connection) {
+ $this->connection = $connection;
+ }
+
+ public function save($source, $alias, $langcode = LANGUAGE_NOT_SPECIFIED, $pid = NULL) {
+
+ $fields = array(
+ 'source' => $source,
+ 'alias' => $alias,
+ 'langcode' => $langcode,
+ );
+
+ // Insert or update the alias.
+ if (empty($pid)) {
+ $query = $this->connection->insert('url_alias', array('return' => Database::RETURN_INSERT_ID))
+ ->fields($fields);
+ }
+ else {
+ $fields['pid'] = $pid;
+ $query = $this->connection->update('url_alias')
+ ->fields($fields)
+ ->condition('pid', $pid);
+ }
+ if ($pid = $query->execute()) {
+ $fields['pid'] = $pid;
+ $this->cacheClear($source);
+ return $fields;
+ }
+ return FALSE;
+ }
+
+ public function load($conditions) {
+ if (is_numeric($conditions)) {
+ $conditions = array('pid' => $conditions);
+ }
+ elseif (is_string($conditions)) {
+ $conditions = array('source' => $conditions);
+ }
+ elseif (!is_array($conditions)) {
+ return FALSE;
+ }
+ $select = $this->connection->select('url_alias');
+ foreach ($conditions as $field => $value) {
+ $select->condition($field, $value);
+ }
+ return $select
+ ->fields('url_alias')
+ ->execute()
+ ->fetchAssoc();
+ }
+
+ public function delete($conditions) {
+ if (!is_array($conditions)) {
+ $conditions = array('pid' => $conditions);
+ }
+ $path = $this->load($conditions);
+ $query = $this->connection->delete('url_alias');
+ foreach ($conditions as $field => $value) {
+ $query->condition($field, $value);
+ }
+ $deleted = $query->execute();
+ $this->cacheClear($path['source']);
+ // TODO: figure out where we can invoke hook_path_delete()
+ return $deleted;
+ }
+
+ public function getSystemPath($path, $path_language = NULL) {
+ $original_path = $path;
+
+ // Lookup the path alias first.
+ if ($source = $this->lookup_path('source', $path, $path_language)) {
+ $path = $source;
+ }
+
+ // Allow other modules to alter the inbound URL. We cannot use drupal_alter()
+ // here because we need to run hook_url_inbound_alter() in the reverse order
+ // of hook_url_outbound_alter().
+ foreach (array_reverse(module_implements('url_inbound_alter')) as $module) {
+ $function = $module . '_url_inbound_alter';
+ $function($path, $original_path, $path_language);
+ }
+
+ return $path;
+ }
+
+ public function getPathAlias($path = NULL, $path_language = NULL) {
+ // If no path is specified, use the current page's path.
+ if ($path === NULL) {
+ $path = _current_path();
+ }
+ $result = $path;
+ if ($alias = $this->lookup_path('alias', $path, $path_language)) {
+ $result = $alias;
+ }
+ return $result;
+ }
+
+ public function cacheClear($source = NULL) {
+ drupal_static_reset('drupal_lookup_path');
+ $this->path_alias_whitelist_rebuild($source);
+ }
+
+ /**
+ * Given an alias, return its Drupal system URL if one exists. Given a Drupal
+ * system URL return one of its aliases if such a one exists. Otherwise,
+ * return FALSE.
+ *
+ * @param $action
+ * One of the following values:
+ * - wipe: delete the alias cache.
+ * - alias: return an alias for a given Drupal system path (if one exists).
+ * - source: return the Drupal system URL for a path alias (if one exists).
+ * @param $path
+ * The path to investigate for corresponding aliases or system URLs.
+ * @param $langcode
+ * Optional language code to search the path with. Defaults to the page language.
+ * If there's no path defined for that language it will search paths without
+ * language.
+ *
+ * @return
+ * Either a Drupal system path, an aliased path, or FALSE if no path was
+ * found.
+ */
+ private function lookup_path($action, $path = '', $langcode = NULL) {
+ // Use the advanced drupal_static() pattern, since this is called very often.
+ static $drupal_static_fast;
+ if (!isset($drupal_static_fast)) {
+ $drupal_static_fast['cache'] = &drupal_static('drupal_lookup_path');
+ }
+ $cache = &$drupal_static_fast['cache'];
+
+ if (!isset($cache)) {
+ $cache = array(
+ 'map' => array(),
+ 'no_source' => array(),
+ 'whitelist' => NULL,
+ 'system_paths' => array(),
+ 'no_aliases' => array(),
+ 'first_call' => TRUE,
+ );
+ }
+
+ // Retrieve the path alias whitelist.
+ if (!isset($cache['whitelist'])) {
+ $cache['whitelist'] = variable_get('path_alias_whitelist', NULL);
+ if (!isset($cache['whitelist'])) {
+ $cache['whitelist'] = $this->path_alias_whitelist_rebuild();
+ }
+ }
+
+ // If no language is explicitly specified we default to the current URL
+ // language. If we used a language different from the one conveyed by the
+ // requested URL, we might end up being unable to check if there is a path
+ // alias matching the URL path.
+ $langcode = $langcode ? $langcode : drupal_container()->get(LANGUAGE_TYPE_URL)->langcode;
+
+ if ($action == 'wipe') {
+ $cache = array();
+ $cache['whitelist'] = $this->path_alias_whitelist_rebuild();
+ }
+ elseif ($cache['whitelist'] && $path != '') {
+ if ($action == 'alias') {
+ // During the first call to this function per language, load the expected
+ // system paths for the page from cache.
+ if (!empty($cache['first_call'])) {
+ $cache['first_call'] = FALSE;
+
+ $cache['map'][$langcode] = array();
+ // Load system paths from cache.
+ $cid = current_path();
+ if ($cached = cache('path')->get($cid)) {
+ $cache['system_paths'] = $cached->data;
+ // Now fetch the aliases corresponding to these system paths.
+ $args = array(
+ ':system' => $cache['system_paths'],
+ ':langcode' => $langcode,
+ ':langcode_undetermined' => LANGUAGE_NOT_SPECIFIED,
+ );
+ // Always get the language-specific alias before the language-neutral
+ // one. For example 'de' is less than 'und' so the order needs to be
+ // ASC, while 'xx-lolspeak' is more than 'und' so the order needs to
+ // be DESC. We also order by pid ASC so that fetchAllKeyed() returns
+ // the most recently created alias for each source. Subsequent queries
+ // using fetchField() must use pid DESC to have the same effect.
+ // For performance reasons, the query builder is not used here.
+ if ($langcode == LANGUAGE_NOT_SPECIFIED) {
+ // Prevent PDO from complaining about a token the query doesn't use.
+ unset($args[':langcode']);
+ $result = $this->connection->query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode = :langcode_undetermined ORDER BY pid ASC', $args);
+ }
+ elseif ($langcode < LANGUAGE_NOT_SPECIFIED) {
+ $result = $this->connection->query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid ASC', $args);
+ }
+ else {
+ $result = $this->connection->query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid ASC', $args);
+ }
+ $cache['map'][$langcode] = $result->fetchAllKeyed();
+ // Keep a record of paths with no alias to avoid querying twice.
+ $cache['no_aliases'][$langcode] = array_flip(array_diff_key($cache['system_paths'], array_keys($cache['map'][$langcode])));
+ }
+ }
+ // If the alias has already been loaded, return it.
+ if (isset($cache['map'][$langcode][$path])) {
+ return $cache['map'][$langcode][$path];
+ }
+ // Check the path whitelist, if the top-level part before the first /
+ // is not in the list, then there is no need to do anything further,
+ // it is not in the database.
+ elseif (!isset($cache['whitelist'][strtok($path, '/')])) {
+ return FALSE;
+ }
+ // For system paths which were not cached, query aliases individually.
+ elseif (!isset($cache['no_aliases'][$langcode][$path])) {
+ $args = array(
+ ':source' => $path,
+ ':langcode' => $langcode,
+ ':langcode_undetermined' => LANGUAGE_NOT_SPECIFIED,
+ );
+ // See the queries above.
+ if ($langcode == LANGUAGE_NOT_SPECIFIED) {
+ unset($args[':langcode']);
+ $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode = :langcode_undetermined ORDER BY pid DESC", $args)->fetchField();
+ }
+ elseif ($langcode > LANGUAGE_NOT_SPECIFIED) {
+ $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args)->fetchField();
+ }
+ else {
+ $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args)->fetchField();
+ }
+ $cache['map'][$langcode][$path] = $alias;
+ return $alias;
+ }
+ }
+ // Check $no_source for this $path in case we've already determined that there
+ // isn't a path that has this alias
+ elseif ($action == 'source' && !isset($cache['no_source'][$langcode][$path])) {
+ // Look for the value $path within the cached $map
+ $source = FALSE;
+ if (!isset($cache['map'][$langcode]) || !($source = array_search($path, $cache['map'][$langcode]))) {
+ $args = array(
+ ':alias' => $path,
+ ':langcode' => $langcode,
+ ':langcode_undetermined' => LANGUAGE_NOT_SPECIFIED,
+ );
+ // See the queries above.
+ if ($langcode == LANGUAGE_NOT_SPECIFIED) {
+ unset($args[':langcode']);
+ $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode = :langcode_undetermined ORDER BY pid DESC", $args);
+ }
+ elseif ($langcode > LANGUAGE_NOT_SPECIFIED) {
+ $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args);
+ }
+ else {
+ $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args);
+ }
+ if ($source = $result->fetchField()) {
+ $cache['map'][$langcode][$source] = $path;
+ }
+ else {
+ // We can't record anything into $map because we do not have a valid
+ // index and there is no need because we have not learned anything
+ // about any Drupal path. Thus cache to $no_source.
+ $cache['no_source'][$langcode][$path] = TRUE;
+ }
+ }
+ return $source;
+ }
+ }
+
+ return FALSE;
+ }
+ /**
+ * Rebuild the path alias white list.
+ *
+ * @param $source
+ * An optional system path for which an alias is being inserted.
+ *
+ * @return
+ * An array containing a white list of path aliases.
+ */
+ private function path_alias_whitelist_rebuild($source = NULL) {
+ // When paths are inserted, only rebuild the whitelist if the system path
+ // has a top level component which is not already in the whitelist.
+ if (!empty($source)) {
+ $whitelist = variable_get('path_alias_whitelist', NULL);
+ if (isset($whitelist[strtok($source, '/')])) {
+ return $whitelist;
+ }
+ }
+ // For each alias in the database, get the top level component of the system
+ // path it corresponds to. This is the portion of the path before the first
+ // '/', if present, otherwise the whole path itself.
+ $whitelist = array();
+ $result = $this->connection->query("SELECT DISTINCT SUBSTRING_INDEX(source, '/', 1) AS path FROM {url_alias}");
+ foreach ($result as $row) {
+ $whitelist[$row->path] = TRUE;
+ }
+ variable_set('path_alias_whitelist', $whitelist);
+ return $whitelist;
+ }
+}
+
diff --git a/core/modules/path/lib/Drupal/path/Tests/LookupTest.php b/core/modules/path/lib/Drupal/path/Tests/LookupTest.php
new file mode 100644
index 0000000..4620615
--- /dev/null
+++ b/core/modules/path/lib/Drupal/path/Tests/LookupTest.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\path\Tests\Path\LookupTest.
+ */
+
+namespace Drupal\path\Tests\Path;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests for DrupalPathRegistry.
+ */
+class LookupTest extends WebTestBase {
+ public static function getInfo() {
+ return array(
+ 'name' => t('Path lookup'),
+ 'description' => t('Tests that DrupalPathRegistry returns correct paths.'),
+ 'group' => t('Path API'),
+ );
+ }
+
+ /**
+ * Test that DrupalPathRegistry returns the correct path.
+ */
+ function testDrupalLookupPath() {
+ $account = $this->drupalCreateUser();
+ $uid = $account->uid;
+ $name = $account->name;
+
+ // Test the situation where the source is the same for multiple aliases.
+ // Start with a language-neutral alias, which we will override.
+ $path = array(
+ 'source' => "user/$uid",
+ 'alias' => 'foo',
+ );
+ drupal_container()->get('path_registry')->save($path['source'], $path['alias']);
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias($path['source']), $path['alias'], t('Basic alias lookup works.'));
+ $this->assertEqual(drupal_container()->get('path_registry')->getSystemPath($path['alias']), $path['source'], t('Basic source lookup works.'));
+
+ // Create a language specific alias for the default language (English).
+ $path = array(
+ 'source' => "user/$uid",
+ 'alias' => "users/$name",
+ 'langcode' => 'en',
+ );
+ drupal_container()->get('path_registry')->save($path['source'], $path['alias'], $path['langcode']);
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias($path['source']), $path['alias'], t('English alias overrides language-neutral alias.'));
+ $this->assertEqual(drupal_container()->get('path_registry')->getSystemPath($path['alias']), $path['source'], t('English source overrides language-neutral source.'));
+
+ // Create a language-neutral alias for the same path, again.
+ drupal_container()->get('path_registry')->save("user/$uid", 'bar');
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias("user/$uid"), "users/$name", t('English alias still returned after entering a language-neutral alias.'));
+
+ // Create a language-specific (xx-lolspeak) alias for the same path.
+ drupal_container()->get('path_registry')->save("user/$uid", 'LOL', 'xx-lolspeak');
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias("user/$uid"), "users/$name", t('English alias still returned after entering a LOLspeak alias.'));
+ // The LOLspeak alias should be returned if we really want LOLspeak.
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias("user/$uid", 'xx-lolspeak'), 'LOL', t('LOLspeak alias returned if we specify xx-lolspeak to DrupalPathRegistry.'));
+
+ // Create a new alias for this path in English, which should override the
+ // previous alias for "user/$uid".
+ drupal_container()->get('path_registry')->save("user/$uid", 'users/my-new-path', 'en');
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias("user/$uid"), 'users/my-new-path', t('Recently created English alias returned.'));
+ $this->assertEqual(drupal_container()->get('path_registry')->getSystemPath('users/my-new-path'), "user/$uid", t('Recently created English source returned.'));
+
+ // Remove the English aliases, which should cause a fallback to the most
+ // recently created language-neutral alias, 'bar'.
+ db_delete('url_alias')
+ ->condition('langcode', 'en')
+ ->execute();
+ drupal_container()->get('path_registry')->cacheClear();
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias($path['source']), 'bar', t('Path lookup falls back to recently created language-neutral alias.'));
+
+ // Test the situation where the alias and language are the same, but
+ // the source differs. The newer alias record should be returned.
+ $account2 = $this->drupalCreateUser();
+ drupal_container()->get('path_registry')->save('user/' . $account2->uid, 'bar');
+ $this->assertEqual(drupal_container()->get('path_registry')->getPathAlias('source', 'bar'), 'user/' . $account2->uid, t('Newer alias record is returned when comparing two LANGUAGE_NOT_SPECIFIED paths with the same alias.'));
+ }
+}
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php b/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php
index af8b0c7..457230b 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php
@@ -84,7 +84,7 @@ class PathAliasTest extends PathTestBase {
$this->assertText($node1->title, 'Changed alias works.');
$this->assertResponse(200);
- drupal_static_reset('drupal_lookup_path');
+ drupal_container()->get('path_registry')->cacheClear();
// Confirm that previous alias no longer works.
$this->drupalGet($previous);
$this->assertNoText($node1->title, 'Previous alias no longer works.');
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
index b3dba0e..a297168 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
@@ -70,7 +70,7 @@ class PathLanguageTest extends PathTestBase {
$this->drupalPost(NULL, $edit, t('Save'));
// Clear the path lookup cache.
- drupal_lookup_path('wipe');
+ drupal_container()->get('path_registry')->cacheClear();
// Ensure the node was created.
$french_node = $this->drupalGetNodeByTitle($edit["title"]);
@@ -109,7 +109,7 @@ class PathLanguageTest extends PathTestBase {
// We need to ensure that the user language preference is not taken into
// account while determining the path alias language, because if this
// happens we have no way to check that the path alias is valid: there is no
- // path alias for French matching the english alias. So drupal_lookup_path()
+ // path alias for French matching the english alias. So DrupalPathRegistry
// needs to use the URL language to check whether the alias is valid.
$this->drupalGet($english_alias);
$this->assertText($english_node->title, 'Alias for English translation works.');
@@ -133,20 +133,20 @@ class PathLanguageTest extends PathTestBase {
$this->drupalGet($french_alias);
$this->assertResponse(404, t('Alias for French translation is unavailable when URL language negotiation is disabled.'));
- // drupal_lookup_path() has an internal static cache. Check to see that
+ // DrupalPathRegistry has an internal static cache. Check to see that
// it has the appropriate contents at this point.
- drupal_lookup_path('wipe');
- $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->langcode);
+ drupal_container()->get('path_registry')->cacheClear();
+ $french_node_path = drupal_container()->get('path_registry')->getSystemPath($french_alias, $french_node->langcode);
$this->assertEqual($french_node_path, 'node/' . $french_node->nid, t('Normal path works.'));
// Second call should return the same path.
- $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->langcode);
+ $french_node_path = drupal_container()->get('path_registry')->getSystemPath($french_alias, $french_node->langcode);
$this->assertEqual($french_node_path, 'node/' . $french_node->nid, t('Normal path is the same.'));
// Confirm that the alias works.
- $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->langcode);
+ $french_node_alias = drupal_container()->get('path_registry')->getPathAlias('node/' . $french_node->nid, $french_node->langcode);
$this->assertEqual($french_node_alias, $french_alias, t('Alias works.'));
// Second call should return the same alias.
- $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->langcode);
+ $french_node_alias = drupal_container()->get('path_registry')->getPathAlias('node/' . $french_node->nid, $french_node->langcode);
$this->assertEqual($french_node_alias, $french_alias, t('Alias is the same.'));
}
}
diff --git a/core/modules/path/path.admin.inc b/core/modules/path/path.admin.inc
index 4188eff..b32542e 100644
--- a/core/modules/path/path.admin.inc
+++ b/core/modules/path/path.admin.inc
@@ -76,7 +76,7 @@ function path_admin_overview($keys = NULL) {
// If the system path maps to a different URL alias, highlight this table
// row to let the user know of old aliases.
- if ($data->alias != drupal_get_path_alias($data->source, $data->langcode)) {
+ if ($data->alias != drupal_container()->get('path_registry')->getPathAlias($data->source, $data->langcode)) {
$row['class'] = array('warning');
}
@@ -218,7 +218,7 @@ function path_admin_form_delete_submit($form, &$form_state) {
*/
function path_admin_form_validate($form, &$form_state) {
$source = &$form_state['values']['source'];
- $source = drupal_get_normal_path($source);
+ $source = drupal_container()->get('path_registry')->getSystemPath($source);
$alias = $form_state['values']['alias'];
$pid = isset($form_state['values']['pid']) ? $form_state['values']['pid'] : 0;
// Language is only set if language.module is enabled, otherwise save for all
@@ -250,7 +250,18 @@ function path_admin_form_submit($form, &$form_state) {
// Remove unnecessary values.
form_state_values_clean($form_state);
- path_save($form_state['values']);
+ $pid = isset($form_state['values']['pid']) ? $form_state['values']['pid'] : 0;
+ $source = &$form_state['values']['source'];
+ $source = drupal_container()->get('path_registry')->getSystemPath($source);
+ $alias = $form_state['values']['alias'];
+ // Language is only set if language.module is enabled, otherwise save for all
+ // languages.
+ $langcode = isset($form_state['values']['langcode']) ? $form_state['values']['langcode'] : LANGUAGE_NOT_SPECIFIED;
+
+ $op = $pid ? 'update' : 'insert';
+ if ($path = drupal_container()->get('path_registry')->save($source, $alias, $langcode, $pid)) {
+ module_invoke_all('path_' . $op, $path);
+ }
drupal_set_message(t('The alias has been saved.'));
$form_state['redirect'] = 'admin/config/search/path';
@@ -282,7 +293,7 @@ function path_admin_delete_confirm($form, &$form_state, $path) {
*/
function path_admin_delete_confirm_submit($form, &$form_state) {
if ($form_state['values']['confirm']) {
- path_delete($form_state['path']['pid']);
+ drupal_container()->get('path_registry')->delete($form_state['path']['pid']);
$form_state['redirect'] = 'admin/config/search/path';
}
}
diff --git a/core/modules/path/path.api.php b/core/modules/path/path.api.php
index f2c5ece..09901aa 100644
--- a/core/modules/path/path.api.php
+++ b/core/modules/path/path.api.php
@@ -20,7 +20,7 @@
* - pid: Unique path alias identifier.
* - langcode: The language code of the alias.
*
- * @see path_save()
+ * @see DrupalPathRegistry::save()
*/
function hook_path_insert($path) {
db_insert('mytable')
@@ -41,7 +41,7 @@ function hook_path_insert($path) {
* - pid: Unique path alias identifier.
* - langcode: The language code of the alias.
*
- * @see path_save()
+ * @see DrupalPathRegistry::save()
*/
function hook_path_update($path) {
db_update('mytable')
@@ -60,7 +60,7 @@ function hook_path_update($path) {
* - pid: Unique path alias identifier.
* - langcode: The language code of the alias.
*
- * @see path_delete()
+ * @see DrupalPathRegistry::delete()
*/
function hook_path_delete($path) {
db_delete('mytable')
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index d01c623..cc1e906 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -105,7 +105,7 @@ function path_form_node_form_alter(&$form, $form_state) {
if ($form['#node']->langcode != LANGUAGE_NOT_SPECIFIED) {
$conditions['langcode'] = $form['#node']->langcode;
}
- $path = path_load($conditions);
+ $path = drupal_container()->get('path_registry')->load($conditions);
if ($path === FALSE) {
$path = array();
}
@@ -190,14 +190,15 @@ function path_form_element_validate($element, &$form_state, $complete_form) {
*/
function path_node_insert(Node $node) {
if (isset($node->path)) {
- $path = $node->path;
- $path['alias'] = trim($path['alias']);
+ $alias = trim($node->path['alias']);
// Only save a non-empty alias.
- if (!empty($path['alias'])) {
+ if (!empty($alias)) {
// Ensure fields for programmatic executions.
- $path['source'] = 'node/' . $node->nid;
- $path['langcode'] = isset($node->langcode) ? $node->langcode : LANGUAGE_NOT_SPECIFIED;
- path_save($path);
+ $source = 'node/' . $node->nid;
+ $langcode = isset($node->langcode) ? $node->langcode : LANGUAGE_NOT_SPECIFIED;
+ if ($path = drupal_container()->get('path_registry')->save($source, $alias, $langcode)) {
+ module_invoke_all('path_insert', $path);
+ }
}
}
}
@@ -208,17 +209,19 @@ function path_node_insert(Node $node) {
function path_node_update(Node $node) {
if (isset($node->path)) {
$path = $node->path;
- $path['alias'] = trim($path['alias']);
+ $alias = trim($path['alias']);
// Delete old alias if user erased it.
if (!empty($path['pid']) && empty($path['alias'])) {
- path_delete($path['pid']);
+ drupal_container()->get('path_registry')->delete($path['pid']);
}
// Only save a non-empty alias.
if (!empty($path['alias'])) {
// Ensure fields for programmatic executions.
- $path['source'] = 'node/' . $node->nid;
- $path['langcode'] = isset($node->langcode) ? $node->langcode : LANGUAGE_NOT_SPECIFIED;
- path_save($path);
+ $source = 'node/' . $node->nid;
+ $langcode = isset($node->langcode) ? $node->langcode : LANGUAGE_NOT_SPECIFIED;
+ if ($path = drupal_container()->get('path_registry')->save($source, $alias, $langcode, $path['pid'])) {
+ module_invoke_all('path_update', $path);
+ }
}
}
}
@@ -228,7 +231,7 @@ function path_node_update(Node $node) {
*/
function path_node_predelete(Node $node) {
// Delete all aliases associated with this node.
- path_delete(array('source' => 'node/' . $node->nid));
+ drupal_container()->get('path_registry')->delete(array('source' => 'node/' . $node->nid));
}
/**
@@ -237,7 +240,7 @@ function path_node_predelete(Node $node) {
function path_form_taxonomy_form_term_alter(&$form, $form_state) {
// Make sure this does not show up on the delete confirmation form.
if (empty($form_state['confirm_delete'])) {
- $path = (isset($form['#term']['tid']) ? path_load('taxonomy/term/' . $form['#term']['tid']) : array());
+ $path = (isset($form['#term']['tid']) ? drupal_container()->get('path_registry')->load('taxonomy/term/' . $form['#term']['tid']) : array());
if ($path === FALSE) {
$path = array();
}
@@ -278,7 +281,7 @@ function path_taxonomy_term_insert(Term $term) {
// Ensure fields for programmatic executions.
$path['source'] = 'taxonomy/term/' . $term->tid;
$path['langcode'] = LANGUAGE_NOT_SPECIFIED;
- path_save($path);
+ drupal_container()->get('path_registry')->save($path);
}
}
}
@@ -292,14 +295,14 @@ function path_taxonomy_term_update(Term $term) {
$path['alias'] = trim($path['alias']);
// Delete old alias if user erased it.
if (!empty($path['pid']) && empty($path['alias'])) {
- path_delete($path['pid']);
+ drupal_container()->get('path_registry')->delete($path['pid']);
}
// Only save a non-empty alias.
if (!empty($path['alias'])) {
// Ensure fields for programmatic executions.
$path['source'] = 'taxonomy/term/' . $term->tid;
$path['langcode'] = LANGUAGE_NOT_SPECIFIED;
- path_save($path);
+ drupal_container()->get('path_registry')->save($path);
}
}
}
@@ -309,5 +312,5 @@ function path_taxonomy_term_update(Term $term) {
*/
function path_taxonomy_term_delete(Term $term) {
// Delete all aliases associated with this term.
- path_delete(array('source' => 'taxonomy/term/' . $term->tid));
+ drupal_container()->get('path_registry')->delete(array('source' => 'taxonomy/term/' . $term->tid));
}
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index f567dae..f903daa 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -640,7 +640,7 @@ function search_index($sid, $module, $text) {
if ($tagname == 'a') {
// Check if link points to a node on this site
if (preg_match($node_regexp, $value, $match)) {
- $path = drupal_get_normal_path($match[1]);
+ $path = drupal_container()->get('path_registry')->getSystemPath($match[1]);
if (preg_match('!(?:node|book)/(?:view/)?([0-9]+)!i', $path, $match)) {
$linknid = $match[1];
if ($linknid > 0) {
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php
index 278b1e0..e1c1959 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php
@@ -27,18 +27,15 @@ class ShortcutLinksTest extends ShortcutTestBase {
$set = $this->set;
// Create an alias for the node so we can test aliases.
- $path = array(
- 'source' => 'node/' . $this->node->nid,
- 'alias' => $this->randomName(8),
- );
- path_save($path);
+ $alias = $this->randomName(8);
+ drupal_container()->get('path_registry')->save('node/' . $this->node->nid, $alias);
// Create some paths to test.
$test_cases = array(
array('path' => 'admin'),
array('path' => 'admin/config/system/site-information'),
array('path' => "node/{$this->node->nid}/edit"),
- array('path' => $path['alias']),
+ array('path' => $alias),
);
// Check that each new shortcut links where it should.
@@ -52,7 +49,7 @@ class ShortcutLinksTest extends ShortcutTestBase {
$this->assertResponse(200);
$saved_set = shortcut_set_load($set->set_name);
$paths = $this->getShortcutInformation($saved_set, 'link_path');
- $this->assertTrue(in_array(drupal_get_normal_path($test['path']), $paths), 'Shortcut created: '. $test['path']);
+ $this->assertTrue(in_array(drupal_container()->get('path_registry')->getSystemPath($test['path']), $paths), 'Shortcut created: '. $test['path']);
$this->assertLink($title, 0, 'Shortcut link found on the page.');
}
}
diff --git a/core/modules/shortcut/shortcut.admin.inc b/core/modules/shortcut/shortcut.admin.inc
index 9f1888a..2d43aea 100644
--- a/core/modules/shortcut/shortcut.admin.inc
+++ b/core/modules/shortcut/shortcut.admin.inc
@@ -473,7 +473,7 @@ function _shortcut_link_form_elements($shortcut_link = NULL) {
);
}
else {
- $shortcut_link['link_path'] = drupal_get_path_alias($shortcut_link['link_path']);
+ $shortcut_link['link_path'] = drupal_container()->get('path_registry')->getPathAlias($shortcut_link['link_path']);
}
$form['shortcut_link']['#tree'] = TRUE;
@@ -520,7 +520,7 @@ function shortcut_link_edit_validate($form, &$form_state) {
*/
function shortcut_link_edit_submit($form, &$form_state) {
// Normalize the path in case it is an alias.
- $form_state['values']['shortcut_link']['link_path'] = drupal_get_normal_path($form_state['values']['shortcut_link']['link_path']);
+ $form_state['values']['shortcut_link']['link_path'] = drupal_container()->get('path_registry')->getSystemPath($form_state['values']['shortcut_link']['link_path']);
$shortcut_link = array_merge($form_state['values']['original_shortcut_link'], $form_state['values']['shortcut_link']);
@@ -576,7 +576,7 @@ function shortcut_admin_add_link($shortcut_link, &$shortcut_set, $limit = NULL)
}
// Normalize the path in case it is an alias.
- $shortcut_link['link_path'] = drupal_get_normal_path($shortcut_link['link_path']);
+ $shortcut_link['link_path'] = drupal_container()->get('path_registry')->getSystemPath($shortcut_link['link_path']);
// Add the link to the end of the list.
$shortcut_set->links[] = $shortcut_link;
diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module
index be29dce..83c37e9 100644
--- a/core/modules/shortcut/shortcut.module
+++ b/core/modules/shortcut/shortcut.module
@@ -613,7 +613,7 @@ function shortcut_set_title_exists($title) {
*/
function shortcut_valid_link($path) {
// Do not use URL aliases.
- $normal_path = drupal_get_normal_path($path);
+ $normal_path = drupal_container()->get('path_registry')->getSystemPath($path);
if ($path != $normal_path) {
$path = $normal_path;
}
diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module
index ef1bceb..25bb4eb 100644
--- a/core/modules/statistics/statistics.module
+++ b/core/modules/statistics/statistics.module
@@ -386,7 +386,7 @@ function statistics_block_view($delta = '') {
* A string as a link, truncated to the width, linked to the given $path.
*/
function _statistics_link($path, $width = 35) {
- $title = drupal_get_path_alias($path);
+ $title = drupal_container()->get('path_registry')->getPathAlias($path);
$title = truncate_utf8($title, $width, FALSE, TRUE);
return l($title, $path);
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/LookupTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/LookupTest.php
deleted file mode 100644
index a90b5f4..0000000
--- a/core/modules/system/lib/Drupal/system/Tests/Path/LookupTest.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\system\Tests\Path\LookupTest.
- */
-
-namespace Drupal\system\Tests\Path;
-
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Unit test for drupal_lookup_path().
- */
-class LookupTest extends WebTestBase {
- public static function getInfo() {
- return array(
- 'name' => t('Path lookup'),
- 'description' => t('Tests that drupal_lookup_path() returns correct paths.'),
- 'group' => t('Path API'),
- );
- }
-
- /**
- * Test that drupal_lookup_path() returns the correct path.
- */
- function testDrupalLookupPath() {
- $account = $this->drupalCreateUser();
- $uid = $account->uid;
- $name = $account->name;
-
- // Test the situation where the source is the same for multiple aliases.
- // Start with a language-neutral alias, which we will override.
- $path = array(
- 'source' => "user/$uid",
- 'alias' => 'foo',
- );
- path_save($path);
- $this->assertEqual(drupal_lookup_path('alias', $path['source']), $path['alias'], t('Basic alias lookup works.'));
- $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], t('Basic source lookup works.'));
-
- // Create a language specific alias for the default language (English).
- $path = array(
- 'source' => "user/$uid",
- 'alias' => "users/$name",
- 'langcode' => 'en',
- );
- path_save($path);
- $this->assertEqual(drupal_lookup_path('alias', $path['source']), $path['alias'], t('English alias overrides language-neutral alias.'));
- $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], t('English source overrides language-neutral source.'));
-
- // Create a language-neutral alias for the same path, again.
- $path = array(
- 'source' => "user/$uid",
- 'alias' => 'bar',
- );
- path_save($path);
- $this->assertEqual(drupal_lookup_path('alias', $path['source']), "users/$name", t('English alias still returned after entering a language-neutral alias.'));
-
- // Create a language-specific (xx-lolspeak) alias for the same path.
- $path = array(
- 'source' => "user/$uid",
- 'alias' => 'LOL',
- 'langcode' => 'xx-lolspeak',
- );
- path_save($path);
- $this->assertEqual(drupal_lookup_path('alias', $path['source']), "users/$name", t('English alias still returned after entering a LOLspeak alias.'));
- // The LOLspeak alias should be returned if we really want LOLspeak.
- $this->assertEqual(drupal_lookup_path('alias', $path['source'], 'xx-lolspeak'), 'LOL', t('LOLspeak alias returned if we specify xx-lolspeak to drupal_lookup_path().'));
-
- // Create a new alias for this path in English, which should override the
- // previous alias for "user/$uid".
- $path = array(
- 'source' => "user/$uid",
- 'alias' => 'users/my-new-path',
- 'langcode' => 'en',
- );
- path_save($path);
- $this->assertEqual(drupal_lookup_path('alias', $path['source']), $path['alias'], t('Recently created English alias returned.'));
- $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], t('Recently created English source returned.'));
-
- // Remove the English aliases, which should cause a fallback to the most
- // recently created language-neutral alias, 'bar'.
- db_delete('url_alias')
- ->condition('langcode', 'en')
- ->execute();
- drupal_clear_path_cache();
- $this->assertEqual(drupal_lookup_path('alias', $path['source']), 'bar', t('Path lookup falls back to recently created language-neutral alias.'));
-
- // Test the situation where the alias and language are the same, but
- // the source differs. The newer alias record should be returned.
- $account2 = $this->drupalCreateUser();
- $path = array(
- 'source' => 'user/' . $account2->uid,
- 'alias' => 'bar',
- );
- path_save($path);
- $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], t('Newer alias record is returned when comparing two LANGUAGE_NOT_SPECIFIED paths with the same alias.'));
- }
-}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/SaveTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/SaveTest.php
index a34b384..9654d8d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/SaveTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/SaveTest.php
@@ -10,13 +10,13 @@ namespace Drupal\system\Tests\Path;
use Drupal\simpletest\WebTestBase;
/**
- * Tests the path_save() function.
+ * Tests the drupal_container()->get('path_registry')->save() function.
*/
class SaveTest extends WebTestBase {
public static function getInfo() {
return array(
'name' => t('Path save'),
- 'description' => t('Tests that path_save() exposes the previous alias value.'),
+ 'description' => t('Tests that the save() method of PathRegistry exposes the previous alias value.'),
'group' => t('Path API'),
);
}
@@ -28,7 +28,7 @@ class SaveTest extends WebTestBase {
}
/**
- * Tests that path_save() makes the original path available to modules.
+ * Tests that drupal_container()->get('path_registry')->save() makes the original path available to modules.
*/
function testDrupalSaveOriginalPath() {
$account = $this->drupalCreateUser();
@@ -41,11 +41,11 @@ class SaveTest extends WebTestBase {
'alias' => 'foo',
);
$path_original = $path;
- path_save($path);
+ drupal_container()->get('path_registry')->save($path['source'], $path['alias']);
// Alter the path.
$path['alias'] = 'bar';
- path_save($path);
+ drupal_container()->get('path_registry')->save($path['source'], $path['alias']);
// Test to see if the original alias is available to modules during
// hook_path_update().
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php
index 9188b02..c83d643 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php
@@ -40,8 +40,7 @@ class UrlAlterFunctionalTest extends WebTestBase {
$this->assertUrlOutboundAlter("user/$uid", "user/$name");
// Test that a path always uses its alias.
- $path = array('source' => "user/$uid/test1", 'alias' => 'alias/test1');
- path_save($path);
+ drupal_container()->get('path_registry')->save("user/$uid/test1", 'alias/test1');
$this->assertUrlInboundAlter('alias/test1', "user/$uid/test1");
$this->assertUrlOutboundAlter("user/$uid/test1", 'alias/test1');
@@ -114,7 +113,7 @@ class UrlAlterFunctionalTest extends WebTestBase {
*
* @param $original
* A string with the aliased or un-normal path that is run through
- * drupal_get_normal_path().
+ * drupal_container()->get('path_registry')->getSystemPath().
* @param $final
* A string with the expected result after url().
* @return
@@ -122,7 +121,7 @@ class UrlAlterFunctionalTest extends WebTestBase {
*/
protected function assertUrlInboundAlter($original, $final) {
// Test inbound altering.
- $result = drupal_get_normal_path($original);
+ $result = drupal_container()->get('path_registry')->getSystemPath($original);
$this->assertIdentical($result, $final, t('Altered inbound URL %original, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result)));
}
}
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index a60c3fb..6978549 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -1499,10 +1499,11 @@ function system_site_information_settings($form, &$form_state) {
'#type' => 'fieldset',
'#title' => t('Front page'),
);
+ $front_page = $site_config->get('page.front') != 'user' ? drupal_container()->get('path_registry')->getPathAlias($site_config->get('page.front')) : '';
$form['front_page']['site_frontpage'] = array(
'#type' => 'textfield',
'#title' => t('Default front page'),
- '#default_value' => ($site_config->get('page.front') != 'user' ? drupal_get_path_alias($site_config->get('page.front')) : ''),
+ '#default_value' => $front_page,
'#size' => 40,
'#description' => t('Optionally, specify a relative URL to display as the front page. Leave blank to display the default content feed.'),
'#field_prefix' => url(NULL, array('absolute' => TRUE)),
@@ -1544,7 +1545,7 @@ function system_site_information_settings_validate($form, &$form_state) {
}
else {
// Get the normal path of the front page.
- form_set_value($form['front_page']['site_frontpage'], drupal_get_normal_path($form_state['values']['site_frontpage']), $form_state);
+ form_set_value($form['front_page']['site_frontpage'], drupal_container()->get('path_registry')->getSystemPath($form_state['values']['site_frontpage']), $form_state);
}
// Validate front page path.
if (!drupal_valid_path($form_state['values']['site_frontpage'])) {
@@ -1552,10 +1553,10 @@ function system_site_information_settings_validate($form, &$form_state) {
}
// Get the normal paths of both error pages.
if (!empty($form_state['values']['site_403'])) {
- form_set_value($form['error_page']['site_403'], drupal_get_normal_path($form_state['values']['site_403']), $form_state);
+ form_set_value($form['error_page']['site_403'], drupal_container()->get('path_registry')->getSystemPath($form_state['values']['site_403']), $form_state);
}
if (!empty($form_state['values']['site_404'])) {
- form_set_value($form['error_page']['site_404'], drupal_get_normal_path($form_state['values']['site_404']), $form_state);
+ form_set_value($form['error_page']['site_404'], drupal_container()->get('path_registry')->getSystemPath($form_state['values']['site_404']), $form_state);
}
// Validate 403 error path.
if (!empty($form_state['values']['site_403']) && !drupal_valid_path($form_state['values']['site_403'])) {
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 12428fe..78aba1f 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -3718,7 +3718,7 @@ function hook_system_themes_page_alter(&$theme_groups) {
* @param $path_language
* The language of the path.
*
- * @see drupal_get_normal_path()
+ * @see DrupalPathRegistry::getSystemPath()
*/
function hook_url_inbound_alter(&$path, $original_path, $path_language) {
// Create the path user/me/edit, which allows a user to edit their account.
diff --git a/core/scripts/generate-d7-content.sh b/core/scripts/generate-d7-content.sh
index 7f03846..c769323 100644
--- a/core/scripts/generate-d7-content.sh
+++ b/core/scripts/generate-d7-content.sh
@@ -253,7 +253,7 @@ for ($i = 0; $i < 12; $i++) {
'alias' => "content/poll/$i/results",
'source' => "node/$node->nid/results",
);
- path_save($path);
+ drupal_container()->get('path_registry')->save($path);
// Add some votes
$node = node_load($node->nid);
diff --git a/index.php b/index.php
index 7b99d10..df4b2b6 100644
--- a/index.php
+++ b/index.php
@@ -11,6 +11,7 @@
* See COPYRIGHT.txt and LICENSE.txt files in the "core" directory.
*/
+use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
/**
@@ -29,6 +30,9 @@ $request = Request::createFromGlobals();
// container at some point.
request($request);
+$kernel = new DrupalKernel('prod', FALSE);
+$kernel->boot();
+
// Bootstrap all of Drupal's subsystems, but do not initialize anything that
// depends on the fully resolved Drupal path, because path resolution happens
// during the REQUEST event of the kernel.
@@ -36,6 +40,6 @@ request($request);
// @see Drupal\Core\EventSubscriber\LegacyRequestSubscriber;
drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
-$kernel = drupal_container()->get('httpkernel');
$response = $kernel->handle($request)->prepare($request)->send();
+
$kernel->terminate($request, $response);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment