Issue #2896480 by mpdonadio, dawehner, Berdir, martin107: Allow to reference permanent files with 0 usages
							parent
							
								
									f9c65b1160
								
							
						
					
					
						commit
						fdef8555ac
					
				| 
						 | 
				
			
			@ -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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue