diff --git a/core/includes/path.inc b/core/includes/path.inc index f60292b..e88aa6d 100644 --- a/core/includes/path.inc +++ b/core/includes/path.inc @@ -107,15 +107,13 @@ function current_path() { */ function path_load($conditions) { if (is_numeric($conditions)) { - $conditions = array('pid' => $conditions); + return \Drupal::service('path.alias_storage')->load($conditions); } elseif (is_string($conditions)) { - $conditions = array('source' => $conditions); + return \Drupal::service('path.alias_storage')->loadByPath($conditions); } - elseif (!is_array($conditions)) { - return FALSE; - } - return \Drupal::service('path.alias_storage')->load($conditions); + + return FALSE; } /** diff --git a/core/lib/Drupal/Core/Path/AliasStorage.php b/core/lib/Drupal/Core/Path/AliasStorage.php index aa6989c..3c5fd67 100644 --- a/core/lib/Drupal/Core/Path/AliasStorage.php +++ b/core/lib/Drupal/Core/Path/AliasStorage.php @@ -81,13 +81,10 @@ public function save($source, $alias, $langcode = Language::LANGCODE_NOT_SPECIFI /** * {@inheritdoc} */ - public function load($conditions) { - $select = $this->connection->select('url_alias'); - foreach ($conditions as $field => $value) { - $select->condition($field, $value); - } - return $select + public function load($pid) { + return $this->connection->select('url_alias') ->fields('url_alias') + ->condition('pid', $pid) ->execute() ->fetchAssoc(); } @@ -95,12 +92,79 @@ public function load($conditions) { /** * {@inheritdoc} */ - public function delete($conditions) { - $path = $this->load($conditions); - $query = $this->connection->delete('url_alias'); - foreach ($conditions as $field => $value) { - $query->condition($field, $value); + public function loadByPath($path, $langcode = NULL) { + $query = $this->connection->select('url_alias') + ->fields('url_alias') + ->condition('source', $path); + + if (isset($langcode)) { + $query->condition('langcode', $langcode); + } + + return $query->execute() + ->fetchAssoc(); + } + + /** + * {@inheritdoc} + */ + public function loadByAlias($alias, $langcode = NULL) { + $query = $this->connection->select('url_alias') + ->fields('url_alias') + ->condition('alias', $alias); + + if (isset($langcode)) { + $query->condition('langcode', $langcode); + } + + return $query->execute() + ->fetchAssoc(); + } + + /** + * {@inheritdoc} + */ + public function delete($pid) { + $path = $this->load($pid); + $deleted = $this->connection->delete('url_alias') + ->condition('pid', $pid) + ->execute(); + // @todo Switch to using an event for this instead of a hook. + $this->moduleHandler->invokeAll('path_delete', array($path)); + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function deleteByPath($path, $langcode = NULL) { + $path = $this->loadByPath($path, $langcode); + $query = $this->connection->delete('url_alias') + ->condition('source', $path); + + if (isset($langcode)) { + $query->condition('langcode', $langcode); } + + $deleted = $query->execute(); + // @todo Switch to using an event for this instead of a hook. + $this->moduleHandler->invokeAll('path_delete', array($path)); + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function deleteByAlias($alias, $langcode = NULL) { + $path = $this->loadByAlias($alias, $langcode); + + $query = $this->connection->delete('url_alias') + ->condition('alias', $alias); + + if (isset($langcode)) { + $query->condition('langcode', $langcode); + } + $deleted = $query->execute(); // @todo Switch to using an event for this instead of a hook. $this->moduleHandler->invokeAll('path_delete', array($path)); diff --git a/core/lib/Drupal/Core/Path/AliasStorageInterface.php b/core/lib/Drupal/Core/Path/AliasStorageInterface.php index 68c7cdd..e1280d2 100644 --- a/core/lib/Drupal/Core/Path/AliasStorageInterface.php +++ b/core/lib/Drupal/Core/Path/AliasStorageInterface.php @@ -37,28 +37,71 @@ public function save($source, $alias, $langcode = Language::LANGCODE_NOT_SPECIFIED, $pid = NULL); /** - * Fetches a specific URL alias from the database. + * Fetches a specific URL alias from the database using a pid. * - * @param $conditions - * An array of query conditions. + * @param int $pid + * Unique path alias identifier. + * + * @return mixed[]|bool + * FALSE if no alias was found or an associative array containing the + */ + public function load($pid); + + /** + * Fetches a specific URL alias from the database based on path. + * + * @param string $source + * The internal system path. + * @param string|null $langcode + * The language code of the alias. * * @return mixed[]|bool * FALSE if no alias was found or an associative array containing the * following keys: - * - source (string): The internal system path. - * - alias (string): The URL alias. - * - pid (int): Unique path alias identifier. - * - langcode (string): The language code of the alias. */ - public function load($conditions); + public function loadByPath($path, $langcode = NULL); /** - * Deletes a URL alias. + * Fetches a specific URL alias from the database based on alias. + * + * @param string $alias + * The URL alias. + * @param string|null $langcode + * The language code of the alias. * - * @param array $conditions - * An array of criteria. + * @return mixed[]|bool + * FALSE if no alias was found or an associative array containing the + * following keys: + */ + public function loadByAlias($alias, $langcode = NULL); + + /** + * Deletes a URL alias using a pid. + * + * @param int $pid + * Unique path alias identifier. + */ + public function delete($pid); + + /** + * Deletes a specific URL alias from the database based on path. + * + * @param string $source + * The internal system path. + * @param string|null $langcode + * The language code of the alias. + */ + public function deleteByPath($path, $langcode = NULL); + + /** + * Deletes a specific URL alias from the database based on alias. + * + * @param string $alias + * The URL alias. + * @param string|null $langcode + * The language code of the alias. */ - public function delete($conditions); + public function deleteByAlias($alias, $langcode = NULL); /** * Pre-loads path alias information for a given list of source paths. diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php b/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php index 07acc16..6e730cc 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php @@ -82,8 +82,7 @@ public function submitForm(array &$form, array &$form_state) { // @todo This should be taken care of by the Path module. if (\Drupal::moduleHandler()->moduleExists('path')) { $path = $this->entity->getSystemPath(); - $conditions = array('source' => $path, 'langcode' => $this->language->id); - \Drupal::service('path.alias_storage')->delete($conditions); + \Drupal::service('path.alias_storage')->deleteByPath($path, $this->language->id); } $form_state['redirect_route'] = $this->getCancelRoute(); diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php index aacf2e4..4f4da8e 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocalePathTest.php @@ -114,7 +114,7 @@ function testPathLanguageConfiguration() { // Same check for language 'xx'. $lookup_path = $this->container->get('path.alias_manager')->getPathAlias('node/' . $node->id(), $prefix); $this->assertEqual($custom_language_path, $lookup_path, 'Custom language alias has priority.'); - $this->container->get('path.alias_storage')->delete($edit); + $this->container->get('path.alias_storage')->deleteByPath($edit['source'], $edit['langcode']); // Create language nodes to check priority of aliases. $first_node = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1, 'langcode' => 'en')); diff --git a/core/modules/path/lib/Drupal/path/Form/DeleteForm.php b/core/modules/path/lib/Drupal/path/Form/DeleteForm.php index e7b3307..fafc317 100644 --- a/core/modules/path/lib/Drupal/path/Form/DeleteForm.php +++ b/core/modules/path/lib/Drupal/path/Form/DeleteForm.php @@ -73,7 +73,7 @@ public function getCancelRoute() { * Overrides \Drupal\Core\Form\ConfirmFormBase::buildForm(). */ public function buildForm(array $form, array &$form_state, $pid = NULL) { - $this->pathAlias = $this->aliasStorage->load(array('pid' => $pid)); + $this->pathAlias = $this->aliasStorage->load($pid); $form = parent::buildForm($form, $form_state); @@ -86,7 +86,7 @@ public function buildForm(array $form, array &$form_state, $pid = NULL) { * Implements \Drupal\Core\Form\FormInterface::submitForm(). */ public function submitForm(array &$form, array &$form_state) { - $this->aliasStorage->delete(array('pid' => $this->pathAlias['pid'])); + $this->aliasStorage->delete($this->pathAlias['pid']); $form_state['redirect'] = 'admin/config/search/path'; } diff --git a/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php b/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php index e43efb2..c50d841 100644 --- a/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php +++ b/core/modules/path/lib/Drupal/path/Plugin/Field/FieldType/PathItem.php @@ -70,7 +70,7 @@ public function insert() { public function update() { // Delete old alias if user erased it. if ($this->pid && !$this->alias) { - \Drupal::service('path.alias_storage')->delete(array('pid' => $this->pid)); + \Drupal::service('path.alias_storage')->delete($this->pid); } // Only save a non-empty alias. elseif ($this->alias) { @@ -89,7 +89,7 @@ public function update() { public function delete() { // Delete all aliases associated with this entity. $entity = $this->getEntity(); - \Drupal::service('path.alias_storage')->delete(array('source' => $entity->getSystemPath())); + \Drupal::service('path.alias_storage')->deleteByPath($entity->getSystemPath()); } } diff --git a/core/modules/path/path.module b/core/modules/path/path.module index ee852a2..8a51211 100644 --- a/core/modules/path/path.module +++ b/core/modules/path/path.module @@ -63,11 +63,11 @@ function path_form_node_form_alter(&$form, $form_state) { $node = $form_state['controller']->getEntity(); $path = array(); if (!$node->isNew()) { - $conditions = array('source' => 'node/' . $node->id()); + $langcode = NULL; if ($node->language()->id != Language::LANGCODE_NOT_SPECIFIED) { - $conditions['langcode'] = $node->language()->id; + $langcode = $node->language()->id; } - $path = \Drupal::service('path.alias_storage')->load($conditions); + $path = \Drupal::service('path.alias_storage')->loadByPath('node/' . $node->id(), $langcode); if ($path === FALSE) { $path = array(); } @@ -145,7 +145,7 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) { // Make sure this does not show up on the delete confirmation form. if (empty($form_state['confirm_delete'])) { $term = $form_state['controller']->getEntity(); - $path = ($term->id() ? \Drupal::service('path.alias_storage')->load(array('source' => 'taxonomy/term/' . $term->id())) : array()); + $path = ($term->id() ? \Drupal::service('path.alias_storage')->loadByPath('taxonomy/term/' . $term->id()) : array()); if ($path === FALSE) { $path = array(); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php index 07bf006..81c8614 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php @@ -52,7 +52,7 @@ function testCRUD() { //Load a few aliases foreach ($aliases as $alias) { $pid = $alias['pid']; - $loadedAlias = $aliasStorage->load(array('pid' => $pid)); + $loadedAlias = $aliasStorage->load($pid); $this->assertEqual($loadedAlias, $alias, format_string('Loaded the expected path with pid %pid.', array('%pid' => $pid))); } @@ -69,7 +69,7 @@ function testCRUD() { //Delete a few aliases foreach ($aliases as $alias) { $pid = $alias['pid']; - $aliasStorage->delete(array('pid' => $pid)); + $aliasStorage->delete($pid); $result = $connection->query('SELECT * FROM {url_alias} WHERE pid = :pid', array(':pid' => $pid)); $rows = $result->fetchAll(); @@ -142,9 +142,19 @@ function testLookupPath() { $this->assertEqual($aliasManager->getPathAlias($path['source']), $path['alias'], 'Recently created English alias returned.'); $this->assertEqual($aliasManager->getSystemPath($path['alias']), $path['source'], 'Recently created English source returned.'); - // Remove the English aliases, which should cause a fallback to the most - // recently created language-neutral alias, 'bar'. - $aliasStorage->delete(array('langcode' => 'en')); + $path_item = $aliasStorage->loadByAlias($path['alias']); + $this->assertEqual($path_item['source'], $path['source'], 'Load by alias works.'); + $aliasManager->cacheClear(); + + // Remove the new English alias. This should fall back to the alias of + // users/Dries. + $aliasStorage->deleteByAlias($path['alias'], 'en'); + $aliasManager->cacheClear(); + $this->assertEqual($aliasManager->getPathAlias($path['source']), 'users/Dries', 'Path lookup falls back to original English alias.'); + + // Remove the remaining English aliases, which should cause a fallback to + // the most recently created language-neutral alias, 'bar'. + $aliasStorage->deleteByPath($path['source'], 'en'); // Hook that clears cache is not executed with unit tests. $aliasManager->cacheClear(); $this->assertEqual($aliasManager->getPathAlias($path['source']), 'bar', 'Path lookup falls back to recently created language-neutral alias.'); @@ -195,7 +205,7 @@ function testWhitelist() { $this->assertNull($whitelist->get($this->randomName())); // Remove the user alias again, whitelist entry should be removed. - $aliasStorage->delete(array('source' => 'user/1')); + $aliasStorage->deleteByPath('user/1'); $aliasManager->cacheClear(); $this->assertNull($whitelist->get('user')); $this->assertTrue($whitelist->get('admin'));