Commit 6af33a4b authored by Drew Webber's avatar Drew Webber
Browse files

Issue #2749245 by poker10, rafalB, mcdruid, David_Rothstein, vijaycs85,...

Issue #2749245 by poker10, rafalB, mcdruid, David_Rothstein, vijaycs85, morbiD: (backport) Incorrect handling of file upload limit exceeded - file widget disappears
parent e15ccfbf
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -246,7 +246,15 @@ function file_ajax_upload() {
    // Invalid request.
    drupal_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error');
    $commands = array();
    $commands[] = ajax_command_replace(NULL, theme('status_messages'));
    $commands[] = ajax_command_prepend(NULL, theme('status_messages'));

    // Unset the problematic file from the input so that user can submit the
    // form without reloading the page.
    // @see https://www.drupal.org/project/drupal/issues/2749245
    $field_name = (string) reset($form_parents);
    $wrapper_id = drupal_html_id('edit-' . $field_name);
    $commands[] = ajax_command_invoke('#' . $wrapper_id . ' .form-type-managed-file input[type="file"]', 'val', array(''));

    return array('#type' => 'ajax', '#commands' => $commands);
  }

@@ -256,7 +264,7 @@ function file_ajax_upload() {
    // Invalid form_build_id.
    drupal_set_message(t('An unrecoverable error occurred. Use of this form has expired. Try reloading the page and submitting again.'), 'error');
    $commands = array();
    $commands[] = ajax_command_replace(NULL, theme('status_messages'));
    $commands[] = ajax_command_prepend(NULL, theme('status_messages'));
    return array('#type' => 'ajax', '#commands' => $commands);
  }

+51 −0
Original line number Diff line number Diff line
@@ -381,6 +381,20 @@ class FileManagedFileElementTestCase extends FileFieldTestCase {
    );
  }

  public function setUp() {
    parent::setUp();

    // Disable the displaying of errors, so that the AJAX responses are not
    // contaminated with error messages about exceeding the maximum POST size.
    $this->originalDisplayErrorsValue = ini_set('display_errors', '0');
  }

  public function tearDown() {
    ini_set('display_errors', $this->originalDisplayErrorsValue);

    parent::tearDown();
  }

  /**
   * Tests the managed_file element type.
   */
@@ -473,6 +487,43 @@ class FileManagedFileElementTestCase extends FileFieldTestCase {
      }
    }
  }

  /**
   * Tests uploading a file that exceeds the maximum file size.
   */
  function testManagedFileExceedMaximumFileSize() {
    $path = 'file/test/0/0';
    $this->drupalGet($path);

    // Create a test file that exceeds the maximum POST size with 1 kilobyte.
    $post_max_size = $this->_postMaxSizeToInteger(ini_get('post_max_size'));
    $filename = 'text-exceeded';
    simpletest_generate_file($filename, ceil(($post_max_size + 1024) / 1024), 1024, 'text');
    $uri = 'public://' . $filename . '.txt';
    $input_base_name = 'file';
    $edit = array('files[' . $input_base_name . ']' => drupal_realpath($uri));
    $this->drupalPostAJAX(NULL, $edit, $input_base_name . '_upload_button');
    $this->assertFieldByXpath('//input[@type="submit"]', t('Upload'), 'After uploading a file that exceeds the maximum file size, the "Upload" button is displayed.');
    $this->drupalPost($path, array(), t('Save'));
    $this->assertRaw(t('The file id is %fid.', array('%fid' => 0)), 'Submitted without a file.');
  }

  /**
   * Converts php.ini post_max_size value to integer.
   *
   * @param $string
   *   The value from php.ini.
   *
   * @return int
   *   Converted value.
   */
  protected function _postMaxSizeToInteger($string) {
    sscanf($string, '%u%c', $number, $suffix);
    if (isset($suffix)) {
      $number = $number * pow(1024, strpos(' KMG', strtoupper($suffix)));
    }
    return $number;
  }
}

/**