From c6742dd9f0abe6add06ee2995027a417b3fc48bc Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Thu, 6 Nov 2014 16:34:53 -0800
Subject: [PATCH] Issue #2215507 by Devin Carlson, pfrenssen, SiliconMind:
 Fixed Downloads broken for translated private files.

---
 core/modules/file/file.module                 |   6 +-
 .../PrivateFileOnTranslatedEntityTest.php     | 129 ++++++++++++++++++
 2 files changed, 133 insertions(+), 2 deletions(-)
 create mode 100644 core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php

diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index fdee4baf6d4c..93a49d8fd81b 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1522,8 +1522,10 @@ function file_get_file_references(FileInterface $file, FieldDefinitionInterface
           // name. This will fail if the usage checked is in a non-current
           // revision because field items are from the current
           // revision.
-          if (($items = $entity->get($field_name))) {
-            foreach ($items as $item) {
+          // We also iterate over all translations because a file can be linked
+          // to a language other than the default.
+          foreach ($entity->getTranslationLanguages() as $langcode => $language) {
+            foreach ($entity->getTranslation($langcode)->get($field_name) as $item) {
               if ($file->id() == $item->{$field_column}) {
                 $references[$file->id()][$age][$field_name][$entity_type_id][$entity->id()] = $entity;
                 break;
diff --git a/core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php b/core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php
new file mode 100644
index 000000000000..1b5bef2ce574
--- /dev/null
+++ b/core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\file\Tests\PrivateFileOnTranslatedEntityTest.
+ */
+
+namespace Drupal\file\Tests;
+
+use Drupal\file\Entity\File;
+use Drupal\node\Entity\Node;
+
+/**
+ * Uploads private files to translated node and checks access.
+ *
+ * @group file
+ */
+class PrivateFileOnTranslatedEntityTest extends FileFieldTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = array('language', 'content_translation');
+
+  /**
+   * The name of the file field used in the test.
+   *
+   * @var string
+   */
+  protected $fieldName;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Create the "Basic page" node type.
+    $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
+
+    // Create a file field on the "Basic page" node type.
+    $this->fieldName = strtolower($this->randomMachineName());
+    $this->createFileField($this->fieldName, 'node', 'page', array('uri_scheme' => 'private'));
+
+    // Create and login user.
+    $permissions = array(
+      'access administration pages',
+      'administer content translation',
+      'administer content types',
+      'administer languages',
+      'create content translations',
+      'create page content',
+      'edit any page content',
+      'translate any entity',
+    );
+    $admin_user = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($admin_user);
+
+    // Add a second language.
+    $edit = array();
+    $edit['predefined_langcode'] = 'fr';
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
+
+    // Enable translation for "Basic page" nodes.
+    $edit = array(
+      'entity_types[node]' => 1,
+      'settings[node][page][translatable]' => 1,
+      "settings[node][page][fields][$this->fieldName]" => 1,
+    );
+    $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
+  }
+
+  /**
+   * Tests private file fields on translated nodes.
+   */
+  public function testPrivateLanguageFile() {
+    // Verify that the file field on the "Basic page" node type is translatable.
+    $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
+    $this->assertTrue($definitions[$this->fieldName]->isTranslatable(), 'Node file field is translatable.');
+
+    // Create a default language node.
+    $default_language_node = $this->drupalCreateNode(array('type' => 'page'));
+
+    // Edit the node to upload a file.
+    $edit = array();
+    $name = 'files[' . $this->fieldName . '_0]';
+    $edit[$name] = drupal_realpath($this->drupalGetTestFiles('text')[0]->uri);
+    $this->drupalPostForm('node/' . $default_language_node->id() . '/edit', $edit, t('Save'));
+    $last_fid_prior = $this->getLastFileId();
+
+    // Languages are cached on many levels, and we need to clear those caches.
+    $this->rebuildContainer();
+
+    // Ensure the file can be downloaded.
+    \Drupal::entityManager()->getStorage('node')->resetCache(array($default_language_node->id()));
+    $node = Node::load($default_language_node->id());
+    $node_file = File::load($node->{$this->fieldName}->target_id);
+    $this->drupalGet(file_create_url($node_file->getFileUri()));
+    $this->assertResponse(200, 'Confirmed that the file attached to the English node can be downloaded.');
+
+    // Translate the node into French.
+    $this->drupalGet('node/' . $default_language_node->id() . '/translations');
+    $this->clickLink(t('Add'));
+
+    // Remove the existing file.
+    $this->drupalPostForm(NULL, array(), t('Remove'));
+
+    // Upload a different file.
+    $edit = array();
+    $edit['title[0][value]'] = $this->randomMachineName();
+    $name = 'files[' . $this->fieldName . '_0]';
+    $edit[$name] = drupal_realpath($this->drupalGetTestFiles('text')[1]->uri);
+    $this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
+    $last_fid = $this->getLastFileId();
+
+    // Verify the translation was created.
+    \Drupal::entityManager()->getStorage('node')->resetCache(array($default_language_node->id()));
+    $default_language_node = Node::load($default_language_node->id());
+    $this->assertTrue($default_language_node->hasTranslation('fr'), 'Node found in database.');
+    $this->assertTrue($last_fid > $last_fid_prior, 'New file got saved.');
+
+    // Ensure the file attached to the translated node can be downloaded.
+    $french_node = $default_language_node->getTranslation('fr');
+    $node_file = File::load($french_node->{$this->fieldName}->target_id);
+    $this->drupalGet(file_create_url($node_file->getFileUri()));
+    $this->assertResponse(200, 'Confirmed that the file attached to the French node can be downloaded.');
+  }
+
+}
-- 
GitLab