From 0f7d46f9ffed77eef8e782bdb87d48857e6ba07d Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 16 Dec 2023 16:58:44 +0000 Subject: [PATCH] Issue #3397575 by kim.pepper, sourabhjain, alexpott, longwave: Deprecate file_progress_implementation() and replace with extension_loaded('uploadprogress') --- core/modules/file/file.install | 80 ++++++++----------- core/modules/file/file.module | 6 ++ .../Controller/FileWidgetAjaxController.php | 3 +- core/modules/file/src/Element/ManagedFile.php | 20 +++-- .../Plugin/Field/FieldWidget/FileWidget.php | 2 +- .../tests/src/Kernel/LegacyFileModuleTest.php | 30 +++++++ .../tests/src/Kernel/RequirementsTest.php | 80 +++++++++++++++++++ core/phpstan-baseline.neon | 5 -- 8 files changed, 162 insertions(+), 64 deletions(-) create mode 100644 core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php create mode 100644 core/modules/file/tests/src/Kernel/RequirementsTest.php diff --git a/core/modules/file/file.install b/core/modules/file/file.install index de86c7bca84..7745a54041f 100644 --- a/core/modules/file/file.install +++ b/core/modules/file/file.install @@ -65,53 +65,43 @@ function file_schema() { function file_requirements($phase) { $requirements = []; - // Check the server's ability to indicate upload progress. - if ($phase == 'runtime') { - $description = NULL; - $implementation = file_progress_implementation(); - // The environment variable might be missing. Fallback to an empty string to - // prevent passing NULL to preg_match(), a few lines later. - $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE', ''); - - // Test the web server identity. - if (preg_match("/Nginx/i", $server_software)) { - $is_nginx = TRUE; - $is_apache = FALSE; - $fastcgi = FALSE; - } - elseif (preg_match("/Apache/i", $server_software)) { - $is_nginx = FALSE; - $is_apache = TRUE; - $fastcgi = str_contains($server_software, 'mod_fastcgi') || str_contains($server_software, 'mod_fcgi'); - } - else { - $is_nginx = FALSE; - $is_apache = FALSE; - $fastcgi = FALSE; - } - - if (!$is_apache && !$is_nginx) { - $value = t('Not enabled'); - $description = t('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php or Nginx with PHP-FPM.'); - } - elseif ($fastcgi) { - $value = t('Not enabled'); - $description = t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php or PHP-FPM and not as FastCGI.'); - } - elseif (!$implementation) { - $value = t('Not enabled'); - $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library.'); - } - elseif ($implementation == 'uploadprogress') { - $value = t('Enabled (PECL uploadprogress)'); - } - $requirements['file_progress'] = [ - 'title' => t('Upload progress'), - 'value' => $value, - 'description' => $description, - ]; + if ($phase != 'runtime') { + return $requirements; } + $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE', ''); + + // Get the web server identity. + $is_nginx = preg_match("/Nginx/i", $server_software); + $is_apache = preg_match("/Apache/i", $server_software); + $fastcgi = $is_apache && ((str_contains($server_software, 'mod_fastcgi') || str_contains($server_software, 'mod_fcgi'))); + + // Check the uploadprogress extension is loaded. + if (extension_loaded('uploadprogress')) { + $value = t('Enabled (PECL uploadprogress)'); + $description = NULL; + } + else { + $value = t('Not enabled'); + $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library.'); + } + + // Adjust the requirement depending on what the server supports. + if (!$is_apache && !$is_nginx) { + $value = t('Not enabled'); + $description = t('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php or Nginx with PHP-FPM.'); + } + elseif ($fastcgi) { + $value = t('Not enabled'); + $description = t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php or PHP-FPM and not as FastCGI.'); + } + + $requirements['file_progress'] = [ + 'title' => t('Upload progress'), + 'value' => $value, + 'description' => $description, + ]; + return $requirements; } diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 605add68df7..997879636e8 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -723,8 +723,14 @@ function file_save_upload($form_field_name, $validators = [], $destination = FAL * @return string|false * A string indicating which upload progress system is available. Either "apc" * or "uploadprogress". If neither are available, returns FALSE. + * + * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use + * extension_loaded('uploadprogress') instead. + * + * @see https://www.drupal.org/node/3397577 */ function file_progress_implementation() { + @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use extension_loaded(\'uploadprogress\') instead. See https://www.drupal.org/node/3397577', E_USER_DEPRECATED); static $implementation; if (!isset($implementation)) { $implementation = FALSE; diff --git a/core/modules/file/src/Controller/FileWidgetAjaxController.php b/core/modules/file/src/Controller/FileWidgetAjaxController.php index 098337887a9..f27836c2154 100644 --- a/core/modules/file/src/Controller/FileWidgetAjaxController.php +++ b/core/modules/file/src/Controller/FileWidgetAjaxController.php @@ -27,8 +27,7 @@ class FileWidgetAjaxController { 'percentage' => -1, ]; - $implementation = file_progress_implementation(); - if ($implementation == 'uploadprogress') { + if (extension_loaded('uploadprogress')) { $status = uploadprogress_get_info($key); if (isset($status['bytes_uploaded']) && !empty($status['bytes_total'])) { $progress['message'] = t('Uploading... (@current of @total)', [ diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php index 8056c16da9e..a27740b6b86 100644 --- a/core/modules/file/src/Element/ManagedFile.php +++ b/core/modules/file/src/Element/ManagedFile.php @@ -276,19 +276,17 @@ class ManagedFile extends FormElement { ]; // Add progress bar support to the upload if possible. - if ($element['#progress_indicator'] == 'bar' && $implementation = file_progress_implementation()) { + if ($element['#progress_indicator'] == 'bar' && extension_loaded('uploadprogress')) { $upload_progress_key = mt_rand(); - if ($implementation == 'uploadprogress') { - $element['UPLOAD_IDENTIFIER'] = [ - '#type' => 'hidden', - '#value' => $upload_progress_key, - '#attributes' => ['class' => ['file-progress']], - // Uploadprogress extension requires this field to be at the top of - // the form. - '#weight' => -20, - ]; - } + $element['UPLOAD_IDENTIFIER'] = [ + '#type' => 'hidden', + '#value' => $upload_progress_key, + '#attributes' => ['class' => ['file-progress']], + // Uploadprogress extension requires this field to be at the top of + // the form. + '#weight' => -20, + ]; // Add the upload progress callback. $element['upload_button']['#ajax']['progress']['url'] = Url::fromRoute('file.ajax_progress', ['key' => $upload_progress_key]); diff --git a/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php b/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php index c97a4d20b38..458d4234bc5 100644 --- a/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php +++ b/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php @@ -72,7 +72,7 @@ class FileWidget extends WidgetBase { '#default_value' => $this->getSetting('progress_indicator'), '#description' => $this->t('The throbber display does not show the status of uploads but takes up less space. The progress bar is helpful for monitoring progress on large uploads.'), '#weight' => 16, - '#access' => file_progress_implementation(), + '#access' => extension_loaded('uploadprogress'), ]; return $element; } diff --git a/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php b/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php new file mode 100644 index 00000000000..88eb01bdc67 --- /dev/null +++ b/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php @@ -0,0 +1,30 @@ +expectDeprecation('file_progress_implementation() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use extension_loaded(\'uploadprogress\') instead. See https://www.drupal.org/node/3397577'); + $this->assertFalse(\file_progress_implementation()); + } + +} diff --git a/core/modules/file/tests/src/Kernel/RequirementsTest.php b/core/modules/file/tests/src/Kernel/RequirementsTest.php new file mode 100644 index 00000000000..4d472644dc4 --- /dev/null +++ b/core/modules/file/tests/src/Kernel/RequirementsTest.php @@ -0,0 +1,80 @@ +markTestSkipped('We are testing only when the uploadprogress extension is not loaded.'); + } + + /** @var \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler */ + $moduleHandler = $this->container->get('module_handler'); + $moduleHandler->loadInclude('file', 'install'); + + // Test unspecified server software. + $this->setServerSoftware(NULL); + $requirements = \file_requirements('runtime'); + $this->assertNotEmpty($requirements); + + $this->assertEquals('Upload progress', (string) $requirements['file_progress']['title']); + $this->assertEquals('Not enabled', (string) $requirements['file_progress']['value']); + $this->assertEquals('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php or Nginx with PHP-FPM.', (string) $requirements['file_progress']['description']); + + // Test Apache + mod_php. + $this->setServerSoftware('Apache mod_php'); + $requirements = \file_requirements('runtime'); + $this->assertNotEmpty($requirements); + $this->assertEquals('Not enabled', (string) $requirements['file_progress']['value']); + $this->assertEquals('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library.', (string) $requirements['file_progress']['description']); + + // Test Apache + mod_fastcgi. + $this->setServerSoftware('Apache mod_fastcgi'); + $requirements = \file_requirements('runtime'); + $this->assertNotEmpty($requirements); + $this->assertEquals('Not enabled', (string) $requirements['file_progress']['value']); + $this->assertEquals('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php or PHP-FPM and not as FastCGI.', (string) $requirements['file_progress']['description']); + + // Test Nginx. + $this->setServerSoftware('Nginx'); + $requirements = \file_requirements('runtime'); + $this->assertNotEmpty($requirements); + $this->assertEquals('Not enabled', (string) $requirements['file_progress']['value']); + $this->assertEquals('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library.', (string) $requirements['file_progress']['description']); + + } + + /** + * Sets the server software attribute in the request. + */ + private function setServerSoftware(?string $software): void { + $request = new Request(); + if (is_string($software)) { + $request->server->set('SERVER_SOFTWARE', $software); + } + $requestStack = new RequestStack(); + $requestStack->push($request); + $this->container->set('request_stack', $requestStack); + } + +} diff --git a/core/phpstan-baseline.neon b/core/phpstan-baseline.neon index a37bb883d88..5079add152b 100644 --- a/core/phpstan-baseline.neon +++ b/core/phpstan-baseline.neon @@ -1446,11 +1446,6 @@ parameters: count: 1 path: modules/field_ui/src/Form/FieldStorageConfigEditForm.php - - - message: "#^Variable \\$value might not be defined\\.$#" - count: 1 - path: modules/file/file.install - - message: "#^Variable \\$file_upload in empty\\(\\) always exists and is not falsy\\.$#" count: 1