From 6f1646023efa72f802f2b6abd4f8e6388e61575c Mon Sep 17 00:00:00 2001
From: James Sansbury <james.sansbury@lullabot.com>
Date: Fri, 28 Jun 2013 16:01:14 -0400
Subject: [PATCH] Issue #1499532: Allow programmatic altering of the node path
 alias language.

---
 modules/path/path.module |   23 ++++++++++++++++++-----
 modules/path/path.test   |   30 ++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/modules/path/path.module b/modules/path/path.module
index 81c7bb2..22c8c8c 100644
--- a/modules/path/path.module
+++ b/modules/path/path.module
@@ -112,9 +112,12 @@ function path_form_node_form_alter(&$form, $form_state) {
     'pid' => NULL,
     'source' => isset($form['#node']->nid) ? 'node/' . $form['#node']->nid : NULL,
     'alias' => '',
-    'language' => isset($langcode) ? $langcode : LANGUAGE_NONE,
   );
 
+  // Force the path language to NULL here. It will be set in the validate
+  // handler if not set programmatically by a form alter or other means.
+  $path['language'] = NULL;
+
   $form['path'] = array(
     '#type' => 'fieldset',
     '#title' => t('URL path settings'),
@@ -160,8 +163,13 @@ function path_form_element_validate($element, &$form_state, $complete_form) {
     // the originally assigned URL alias language.
     // @todo Remove this after converting Path module to a field, and, after
     //   stopping Locale module from abusing the content language system.
-    if (isset($form_state['values']['language'])) {
-      form_set_value($element['language'], $form_state['values']['language'], $form_state);
+    // We only set the language if it isn't explicitly set on the path. Since
+    // the path's language is set to NULL in the form, the value would only be
+    // set by a form alter or other means.
+    if (!isset($form_state['values']['path']['language'])) {
+      // If the node's language isn't set, use LANGUAGE_NONE.
+      $language = isset($form_state['values']['language']) ? $form_state['values']['language'] : LANGUAGE_NONE;
+      form_set_value($element['language'], $language, $form_state);
     }
 
     $path = $form_state['values']['path'];
@@ -191,9 +199,14 @@ function path_node_insert($node) {
     // Only save a non-empty alias.
     if (!empty($path['alias'])) {
       // Ensure fields for programmatic executions.
-      $langcode = entity_language('node', $node);
+      // The node's language will be used for the path's language if it wasn't
+      // set. It's possible entity_language() returns NULL.
+      $node_language = entity_language('node', $node);
+      // If the node's language is NULL, use LANGUAGE_NONE.
+      $node_language = isset($node_language) ? $node_language : LANGUAGE_NONE;
       $path['source'] = 'node/' . $node->nid;
-      $path['language'] = isset($langcode) ? $langcode : LANGUAGE_NONE;
+      // If the path language is not specified, use the node's language.
+      $path['language'] = isset($path['language']) ? $path['language'] : $node_language;
       path_save($path);
     }
   }
diff --git a/modules/path/path.test b/modules/path/path.test
index edecff5..f4b21a2 100644
--- a/modules/path/path.test
+++ b/modules/path/path.test
@@ -395,6 +395,36 @@ class PathLanguageTestCase extends DrupalWebTestCase {
     // Second call should return the same alias.
     $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->language);
     $this->assertEqual($french_node_alias, $french_alias, 'Alias is the same.');
+
+    // Test that the alias language is the same as the node language by default.
+    // We do this by creating an english node with a path alias, then loading
+    // the alias directly to be sure it matches.
+    $test_node = $this->drupalCreateNode(array('type' => 'page'));
+    $test_alias = $this->randomName();
+
+    $edit = array();
+    $edit['language'] = 'en';
+    $edit['path[alias]'] = $test_alias;
+    $this->drupalPost('node/' . $test_node->nid . '/edit', $edit, t('Save'));
+
+    // Now load the path and ensure the languages match.
+    $conditions = array(
+      'source' => 'node/' . $test_node->nid,
+      'language' => $edit['language'],
+    );
+    $path = path_load($conditions);
+    $this->assertEqual($path['language'], $edit['language'],
+      t('Alias language is equivalent to node language by default.'));
+
+    // Test that a node path alias language can be changed programmatically.
+    $test_node = $this->drupalGetNodeByTitle($test_node->title);
+    $test_node->path = $path;
+    $test_node->path['language'] = LANGUAGE_NONE;
+    node_save($test_node);
+    $conditions['language'] = LANGUAGE_NONE;
+    $path = path_load($conditions);
+    $this->assertEqual($path['language'], LANGUAGE_NONE,
+      t('Alias language can be altered independently of node language.'));
   }
 }
 
-- 
1.7.10.4

