summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxjm2017-08-14 20:09:44 -0500
committerxjm2017-08-14 20:10:24 -0500
commit8bee0483491d2a902692e1b78ca7417eae3ee18e (patch)
treea9baf80838492871d62d2419a83d8b5dc1562a87
parentd9bfe43f185ba64fd9f15dd8ace46213344fc093 (diff)
Issue #2896480 by mpdonadio, dawehner, Berdir, martin107: Allow to reference permanent files with 0 usages
(cherry picked from commit fdef8555ac3b90321cd2ab308369554c44fb0af6)
-rw-r--r--core/modules/file/src/Element/ManagedFile.php16
-rw-r--r--core/modules/file/src/Tests/FileManagedFileElementTest.php51
2 files changed, 63 insertions, 4 deletions
diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php
index 45c8aa7..ca4e887 100644
--- a/core/modules/file/src/Element/ManagedFile.php
+++ b/core/modules/file/src/Element/ManagedFile.php
@@ -398,15 +398,23 @@ class ManagedFile extends FormElement {
* Render API callback: Validates the managed_file element.
*/
public static function validateManagedFile(&$element, FormStateInterface $form_state, &$complete_form) {
- // If referencing an existing file, only allow if there are existing
- // references. This prevents unmanaged files from being deleted if this
- // item were to be deleted.
$clicked_button = end($form_state->getTriggeringElement()['#parents']);
if ($clicked_button != 'remove_button' && !empty($element['fids']['#value'])) {
$fids = $element['fids']['#value'];
foreach ($fids as $fid) {
if ($file = File::load($fid)) {
- if ($file->isPermanent()) {
+ // If referencing an existing file, only allow if there are existing
+ // references. This prevents unmanaged files from being deleted if
+ // this item were to be deleted. When files that are no longer in use
+ // are automatically marked as temporary (now disabled by default),
+ // it is not safe to reference a permanent file without usage. Adding
+ // a usage and then later on removing it again would delete the file,
+ // but it is unknown if and where it is currently referenced. However,
+ // when files are not marked temporary (and then removed)
+ // automatically, it is safe to add and remove usages, as it would
+ // simply return to the current state.
+ // @see https://www.drupal.org/node/2891902
+ if ($file->isPermanent() && \Drupal::config('file.settings')->get('make_unused_managed_files_temporary')) {
$references = static::fileUsage()->listUsage($file);
if (empty($references)) {
// We expect the field name placeholder value to be wrapped in t()
diff --git a/core/modules/file/src/Tests/FileManagedFileElementTest.php b/core/modules/file/src/Tests/FileManagedFileElementTest.php
index 8abff25..1ff00b9 100644
--- a/core/modules/file/src/Tests/FileManagedFileElementTest.php
+++ b/core/modules/file/src/Tests/FileManagedFileElementTest.php
@@ -194,4 +194,55 @@ class FileManagedFileElementTest extends FileFieldTestBase {
$file->delete();
}
+ /**
+ * Verify that unused permanent files can be used.
+ */
+ public function testUnusedPermanentFileValidation() {
+
+ // Create a permanent file without usages.
+ $file = $this->getTestFile('image');
+ $file->setPermanent();
+ $file->save();
+
+ // By default, unused files are no longer marked temporary, and it must be
+ // allowed to reference an unused file.
+ $this->drupalGet('file/test/1/0/1/' . $file->id());
+ $this->drupalPostForm(NULL, [], 'Save');
+ $this->assertNoText('The file used in the Managed file & butter field may not be referenced.');
+ $this->assertText('The file ids are ' . $file->id());
+
+ // Enable marking unused files as tempory, unused permanent files must not
+ // be referenced now.
+ $this->config('file.settings')
+ ->set('make_unused_managed_files_temporary', TRUE)
+ ->save();
+ $this->drupalGet('file/test/1/0/1/' . $file->id());
+ $this->drupalPostForm(NULL, [], 'Save');
+ $this->assertText('The file used in the Managed file & butter field may not be referenced.');
+ $this->assertNoText('The file ids are ' . $file->id());
+
+ // Make the file temporary, now using it is allowed.
+ $file->setTemporary();
+ $file->save();
+
+ $this->drupalGet('file/test/1/0/1/' . $file->id());
+ $this->drupalPostForm(NULL, [], 'Save');
+ $this->assertNoText('The file used in the Managed file & butter field may not be referenced.');
+ $this->assertText('The file ids are ' . $file->id());
+
+ // Make the file permanent again and add a usage from itself, referencing is
+ // still allowed.
+ $file->setPermanent();
+ $file->save();
+
+ /** @var \Drupal\file\FileUsage\FileUsageInterface $file_usage */
+ $file_usage = \Drupal::service('file.usage');
+ $file_usage->add($file, 'file', 'file', $file->id());
+
+ $this->drupalGet('file/test/1/0/1/' . $file->id());
+ $this->drupalPostForm(NULL, [], 'Save');
+ $this->assertNoText('The file used in the Managed file & butter field may not be referenced.');
+ $this->assertText('The file ids are ' . $file->id());
+ }
+
}