diff --git a/redirect.module b/redirect.module index 8c47b75..a6bab37 100644 --- a/redirect.module +++ b/redirect.module @@ -394,6 +394,8 @@ function redirect_path_update(array $path) { } if (!empty($path['original']['pid']) && $path['original']['pid'] == $path['pid'] && $path['original']['alias'] != $path['alias']) { + // Delete all redirects that would redirect the alias. + redirect_free_source($path['alias']); $redirect = new stdClass(); redirect_object_prepare($redirect); $redirect->source = $path['original']['alias']; @@ -401,10 +403,41 @@ function redirect_path_update(array $path) { $redirect->language = $path['original']['language']; // Check if the redirect exists before saving. $hash = redirect_hash($redirect); - if (!redirect_load_by_hash($hash)) { - redirect_save($redirect); - } + redirect_save($redirect); + } +} + +/** + * Implements hook_path_insert(). + */ +function redirect_path_insert(array $path) { + if (!empty($path['alias'])) { + // Delete all redirects having the same source as this alias. + redirect_free_source($path['alias']); + } +} + +/** + * Ensures that a source path is available. + * + * Similar to redirect_delete_by_path(), but doesn't recurse sub-paths. This is + * called on redirect_path_*() to make sure we don't duplicate the work of an + * alias (which would cause an internal loop). + * + * @param $source + * The redirect source path. + * + * @return + * The deleted redirect object, or FALSE if nothing found. + * + * @ingroup redirect_api + */ +function redirect_free_source($source) { + $redirect_record = redirect_load_by_source($source); + if ($redirect_record) { + redirect_delete($redirect_record->rid); } + return $redirect_record; } /**