diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php
index 750208b08fe..f14f4a0ae6f 100644
--- a/core/.phpstan-baseline.php
+++ b/core/.phpstan-baseline.php
@@ -36432,12 +36432,6 @@ $ignoreErrors[] = [
'count' => 1,
'path' => __DIR__ . '/modules/navigation/tests/src/FunctionalJavascript/NavigationBlockUiTest.php',
];
-$ignoreErrors[] = [
- // identifier: missingType.return
- 'message' => '#^Method Drupal\\\\Tests\\\\navigation\\\\FunctionalJavascript\\\\NavigationSettingsFormTest\\:\\:testFormSettingsSubmissionHandler\\(\\) has no return type specified\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/modules/navigation/tests/src/FunctionalJavascript/NavigationSettingsFormTest.php',
-];
$ignoreErrors[] = [
// identifier: missingType.return
'message' => '#^Method Drupal\\\\Tests\\\\navigation\\\\Kernel\\\\NavigationMenuBlockTest\\:\\:testHtmlMarkup\\(\\) has no return type specified\\.$#',
diff --git a/core/modules/navigation/config/install/navigation.settings.yml b/core/modules/navigation/config/install/navigation.settings.yml
index ffa4ff79c88..4dd462c26f8 100644
--- a/core/modules/navigation/config/install/navigation.settings.yml
+++ b/core/modules/navigation/config/install/navigation.settings.yml
@@ -1,6 +1,6 @@
logo:
provider: default
- managed: null
+ path: ''
max:
filesize: 1048576
height: 40
diff --git a/core/modules/navigation/config/schema/navigation.schema.yml b/core/modules/navigation/config/schema/navigation.schema.yml
index 0d898740431..fabf40b964f 100644
--- a/core/modules/navigation/config/schema/navigation.schema.yml
+++ b/core/modules/navigation/config/schema/navigation.schema.yml
@@ -18,13 +18,11 @@ navigation.settings:
- default
- hide
- custom
- managed:
- type: integer
- label: 'Custom logo'
- nullable: true
+ path:
+ type: string
+ label: 'Path'
constraints:
- Range:
- min: 0
+ NotNull: [ ]
max:
type: mapping
label: 'Logo maximum settings'
diff --git a/core/modules/navigation/navigation.install b/core/modules/navigation/navigation.install
index 4b39baad172..72b843b23a2 100644
--- a/core/modules/navigation/navigation.install
+++ b/core/modules/navigation/navigation.install
@@ -32,13 +32,34 @@ function navigation_update_11001(array &$sandbox): void {
$settings->setData([
'logo' => [
'provider' => $settings->get('logo_provider'),
- 'managed' => $settings->get('logo_managed'),
+ 'managed' => is_array($settings->get('logo_managed')) ? current($settings->get('logo_managed')) : $settings->get('logo_managed'),
'max' => [
'filesize' => $settings->get('logo_max_filesize'),
- 'height' => $settings->get('logo_height'),
- 'width' => $settings->get('logo_width'),
+ 'height' => $settings->get('logo_height') ?? 40,
+ 'width' => $settings->get('logo_width') ?? 40,
],
],
]);
$settings->save(TRUE);
}
+
+/**
+ * Update for navigation logo to store the file path instead of ID.
+ */
+function navigation_update_11002(array &$sandbox): void {
+ $settings = \Drupal::configFactory()->getEditable('navigation.settings');
+ $logo_path = '';
+ if (!empty($settings->get('logo.managed'))) {
+ $logo_fid = $settings->get('logo.managed');
+ $file = \Drupal::entityTypeManager()->getStorage('file')->load($logo_fid);
+ if (isset($file)) {
+ $logo_path = $file->getFileUri();
+ // Delete file usage reference because they are not being used anymore.
+ \Drupal::service('file.usage')->delete($file, 'navigation');
+ }
+ }
+
+ $settings->set('logo.path', $logo_path);
+ $settings->clear('logo.managed');
+ $settings->save();
+}
diff --git a/core/modules/navigation/navigation.post_update.php b/core/modules/navigation/navigation.post_update.php
index 90e63c6afb2..5c3a0dbf650 100644
--- a/core/modules/navigation/navigation.post_update.php
+++ b/core/modules/navigation/navigation.post_update.php
@@ -31,11 +31,5 @@ function navigation_post_update_update_permissions(array &$sandbox) {
* Defines the values for the default logo dimensions.
*/
function navigation_post_update_set_logo_dimensions_default(array &$sandbox) {
- $settings = \Drupal::configFactory()->getEditable('navigation.settings');
- $settings->set('logo_height', 40)
- ->set('logo_width', 40);
- if (is_array($settings->get('logo_managed'))) {
- $settings->set('logo_managed', current($settings->get('logo_managed')));
- }
- $settings->save();
+ // Empty post_update hook.
}
diff --git a/core/modules/navigation/src/Form/SettingsForm.php b/core/modules/navigation/src/Form/SettingsForm.php
index 4f0cda9273a..7d8ec3c1d21 100644
--- a/core/modules/navigation/src/Form/SettingsForm.php
+++ b/core/modules/navigation/src/Form/SettingsForm.php
@@ -7,15 +7,16 @@ namespace Drupal\navigation\Form;
use Drupal\Component\Utility\Environment;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\File\Exception\FileException;
use Drupal\Core\File\FileSystemInterface;
-use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Image\ImageFactory;
use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\StreamWrapper\PublicStream;
+use Drupal\Core\StreamWrapper\StreamWrapperManager;
+use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\file\Entity\File;
-use Drupal\file\FileUsage\FileUsageInterface;
use Drupal\navigation\NavigationRenderer;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -35,26 +36,20 @@ final class SettingsForm extends ConfigFormBase {
* The typed config manager.
* @param \Drupal\Core\File\FileSystemInterface $fileSystem
* The file system.
- * @param \Drupal\Core\File\FileUrlGeneratorInterface $fileUrlGenerator
- * The file URL generator.
- * @param \Drupal\file\FileUsage\FileUsageInterface $fileUsage
- * The File Usage service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
- * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
- * The entity type manager.
* @param \Drupal\Core\Image\ImageFactory $imageFactory
* The image factory.
+ * @param \Drupal\Core\Theme\ThemeManagerInterface $themeManager
+ * The theme manager.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
TypedConfigManagerInterface $typed_config_manager,
protected FileSystemInterface $fileSystem,
- protected FileUrlGeneratorInterface $fileUrlGenerator,
- protected FileUsageInterface $fileUsage,
protected RendererInterface $renderer,
- protected EntityTypeManagerInterface $entityTypeManager,
protected ImageFactory $imageFactory,
+ protected ThemeManagerInterface $themeManager,
) {
parent::__construct($config_factory, $typed_config_manager);
}
@@ -67,11 +62,9 @@ final class SettingsForm extends ConfigFormBase {
$container->get('config.factory'),
$container->get('config.typed'),
$container->get('file_system'),
- $container->get('file_url_generator'),
- $container->get('file.usage'),
$container->get('renderer'),
- $container->get('entity_type.manager'),
- $container->get('image.factory')
+ $container->get('image.factory'),
+ $container->get('theme.manager')
);
}
@@ -110,7 +103,8 @@ final class SettingsForm extends ConfigFormBase {
],
'#config_target' => 'navigation.settings:logo.provider',
];
- $form['logo']['image'] = [
+
+ $form['logo']['custom'] = [
'#type' => 'container',
'#states' => [
'visible' => [
@@ -118,8 +112,34 @@ final class SettingsForm extends ConfigFormBase {
],
],
];
+
+ // If path is a public:// URI, display the path relative to the files
+ // directory; stream wrappers are not end-user friendly.
+ $original_path = $config->get('logo.path') ?? '';
+ $friendly_path = NULL;
+ $default_path = $original_path;
+ $default = 'logo.png';
+
+ if (StreamWrapperManager::getScheme($original_path) === 'public') {
+ $friendly_path = StreamWrapperManager::getTarget($original_path);
+ $default_path = $friendly_path;
+ }
+
+ // Prepare local file path for description.
+ if ($original_path && isset($friendly_path)) {
+ $local_file = strtr($original_path, ['public:/' => PublicStream::basePath()]);
+ }
+ else {
+ $local_file = $this->themeManager->getActiveTheme()->getPath() . '/' . $default;
+ }
+
+ $description = $this->t('Examples: @implicit-public-file
(for a file in the public filesystem), @explicit-file
, or @local-file
.', [
+ '@implicit-public-file' => $friendly_path ?? $default,
+ '@explicit-file' => StreamWrapperManager::getScheme($original_path) !== FALSE ? $original_path : 'public://' . $default,
+ '@local-file' => $local_file,
+ ]);
+
$allowed = 'png jpg jpeg';
- $current_logo_managed_fid = $config->get('logo.managed') ? [$config->get('logo.managed')] : NULL;
$max_navigation_allowed = $config->get('logo.max.filesize');
$max_system_allowed = Environment::getUploadMaxSize();
$max_allowed = $max_navigation_allowed < $max_system_allowed ? $max_navigation_allowed : $max_system_allowed;
@@ -129,19 +149,27 @@ final class SettingsForm extends ConfigFormBase {
];
$file_upload_help = [
'#theme' => 'file_upload_help',
- '#description' => $this->t('Recommended image dimension 40 x 40 pixels.'),
+ '#description' => $this->t("If you don't have direct file access to the server, use this field to upload your logo. Recommended image dimension %width x %height pixels.", [
+ '%width' => $config->get('logo.max.width'),
+ '%height' => $config->get('logo.max.height'),
+ ]),
'#upload_validators' => $upload_validators,
'#cardinality' => 1,
];
- $form['logo']['image']['logo_managed'] = [
- '#type' => 'managed_file',
- '#title' => t('Choose custom logo'),
- '#upload_validators' => $upload_validators,
- '#upload_location' => 'public://navigation-logo',
- '#description' => $this->renderer->renderInIsolation($file_upload_help),
- '#default_value' => $current_logo_managed_fid,
- '#multiple' => FALSE,
+ $form['logo']['custom']['logo_path'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Path to custom logo'),
+ '#default_value' => $default_path,
+ '#description' => $description,
+ '#config_target' => 'navigation.settings:logo.path',
];
+ $form['logo']['custom']['logo_upload'] = [
+ '#type' => 'file',
+ '#title' => $this->t('Upload logo image'),
+ '#description' => $this->renderer->renderInIsolation($file_upload_help),
+ '#upload_validators' => $upload_validators,
+ ];
+
return parent::buildForm($form, $form_state);
}
@@ -149,128 +177,155 @@ final class SettingsForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
- $logo_managed = $form_state->getValue('logo_managed');
- if ($form_state->getValue('logo_provider') === NavigationRenderer::LOGO_PROVIDER_CUSTOM && empty($logo_managed)) {
- $form_state->setErrorByName('logo_managed', 'An image file is required with the current logo handling option.');
+ // If the upload element is not empty, try to adjust the image dimensions
+ // if needed.
+ if ($form_state->getValue('logo_path')) {
+ $path = $this->validateLogoPath($form_state->getValue('logo_path'));
+ if (!$path) {
+ $form_state->setErrorByName('logo_path', $this->t('The custom logo path is invalid.'));
+ }
}
- // If the upload element is not empty and the image is new, try to adjust
- // the image dimensions.
- $this->validateLogoManaged($form, $form_state);
+ if ($form_state->getValue('logo_provider') !== NavigationRenderer::LOGO_PROVIDER_CUSTOM) {
+ $form_state->setValue('logo_upload', '');
+ $form_state->setValue('logo_path', '');
+ }
+ else {
+ $file = _file_save_upload_from_form($form['logo']['custom']['logo_upload'], $form_state, 0);
+ if ($file) {
+ $logo_dimensions = $this->adjustLogoDimensions($file);
+ if (!$logo_dimensions) {
+ $config = $this->config('navigation.settings');
+ $width = $config->get('logo.width');
+ $height = $config->get('logo.height');
+ $form_state->setErrorByName('logo_upload', $this->t('Image dimensions are bigger than the expected %widthx%height pixels and cannot be used as the navigation logo.',
+ [
+ '%width' => $width,
+ '%height' => $height,
+ ]));
+ }
+ // Put the temporary file in form_values so we can save it on submit.
+ $form_state->setValue('logo_upload', $file);
+ $form_state->setValue('logo_path', $file->getFileUri());
+ $form_state->setValue('logo_dimensions', $logo_dimensions);
+ }
+
+ if (empty($form_state->getValue('logo_path'))) {
+ $form_state->setErrorByName('logo_path', 'An image file is required with the current logo handling option.');
+ }
+ }
+ parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
- $config = $this->config('navigation.settings');
+ // If the user uploaded a new logo, save it to a permanent location
+ // and use it in place of the default navigation-provided file.
+ $default_scheme = $this->config('system.file')->get('default_scheme');
+ $values = $form_state->getValues();
+ try {
+ if (!empty($values['logo_upload'])) {
+ $filename = $this->fileSystem->copy($values['logo_upload']->getFileUri(), $default_scheme . '://');
+ $values['logo_path'] = $filename;
+ if ($values['logo_dimensions']['resize']) {
+ $config = $this->config('navigation.settings');
+ $this->messenger()->addStatus($this->t('The image was resized to fit within the navigation logo expected dimensions of %widthx%height pixels. The new dimensions of the resized image are %new_widthx%new_height pixels.',
+ [
+ '%width' => $config->get('logo.max.width'),
+ '%height' => $config->get('logo.max.height'),
+ '%new_width' => $values['logo_dimensions']['width'],
+ '%new_height' => $values['logo_dimensions']['height'],
+ ]));
+ }
- // Get the previous config settings.
- $previous_logo_provider = $config->get('logo.provider');
- $previous_logo_fid = $config->get('logo.managed');
-
- // Get new values from the form.
- $new_logo_provider = $form_state->getValue('logo_provider');
- $logo = $form_state->getValue('logo_managed');
- $new_logo_fid = !empty($logo) ? reset($logo) : NULL;
-
- // Pre-load files if any for FileUsageInterface.
- $previous_logo_managed = $previous_logo_fid ? File::load($previous_logo_fid) : NULL;
- $new_logo_managed = $new_logo_fid ? File::load($new_logo_fid) : NULL;
-
- // Decrement if previous logo_provider was 'custom' and has changed to a
- // different fid and there's a change in the logo fid.
- if ($previous_logo_provider === NavigationRenderer::LOGO_PROVIDER_CUSTOM
- && ($new_logo_provider !== NavigationRenderer::LOGO_PROVIDER_CUSTOM || $previous_logo_fid !== $new_logo_fid)
- && $previous_logo_managed
- ) {
- $this->fileUsage->delete($previous_logo_managed, 'navigation', 'logo', 1);
+ }
+ }
+ catch (FileException) {
+ $this->messenger()->addError($this->t('The file %file could not be copied to the permanent destination. Contact the site administrator if the problem persists.', ['%file' => $values['logo_upload']->getFilename()]));
+ return;
}
- // Increment usage if different from the previous one.
- if ($new_logo_managed && $new_logo_fid !== $previous_logo_fid) {
- $new_logo_managed->setPermanent();
- $new_logo_managed->save();
- $this->fileUsage->add($new_logo_managed, 'navigation', 'logo', 1);
+ // If the user entered a path relative to the system files directory for
+ // the logo, store a public:// URI so the theme system can handle it.
+ if (!empty($values['logo_path'])) {
+ $form_state->setValue('logo_path', $this->validateLogoPath($values['logo_path']));
}
- $config
- ->set('logo.managed', $new_logo_fid)
- ->save();
parent::submitForm($form, $form_state);
}
- /**
- * Validate the Logo Managed image element.
- *
- * @param array $form
- * An associative array containing the structure of the form.
- * @param \Drupal\Core\Form\FormStateInterface $form_state
- * The current state of the form.
- */
- protected function validateLogoManaged(array $form, FormStateInterface $form_state): void {
- $logo_managed = $form_state->getValue('logo_managed');
- $config = $this->config('navigation.settings');
- if (empty($logo_managed)) {
- return;
- }
-
- $width = $config->get('logo.max.width');
- $height = $config->get('logo.max.height');
-
- // Skip if the fid has not been modified.
- $fid = reset($logo_managed);
- if ($fid == $config->get('logo.managed')) {
- return;
- }
-
- $file = $this->entityTypeManager->getStorage('file')
- ->load($fid);
- if ($fid && !$this->adjustLogoDimensions($file)) {
- $form_state->setErrorByName('logo_managed', $this->t('Image dimensions are bigger than the expected %widthx%height pixels and cannot be used as the navigation logo.',
- [
- '%width' => $width,
- '%height' => $height,
- ]));
- }
- }
-
/**
* Adjusts the custom logo dimensions according to navigation settings.
*
* @param \Drupal\file\Entity\File $file
* The file entity that contains the image.
*
- * @return bool
- * TRUE if the logo image dimensions are properly adjusted. FALSE otherwise.
+ * @return array|null
+ * Array containing the logo dimensions properly adjusted. NULL if fails.
*/
- protected function adjustLogoDimensions(File $file): bool {
+ protected function adjustLogoDimensions(File $file): ?array {
$config = $this->config('navigation.settings');
$image = $this->imageFactory->get($file->getFileUri());
if (!$image->isValid()) {
- return FALSE;
+ return NULL;
}
$width = $config->get('logo.max.width');
$height = $config->get('logo.max.height');
if ($image->getWidth() <= $width && $image->getHeight() <= $height) {
- return TRUE;
+ return [
+ 'width' => $width,
+ 'height' => $width,
+ 'resize' => FALSE,
+ ];
}
if ($image->scale($width, $height) && $image->save()) {
- $this->messenger()->addStatus($this->t('The image was resized to fit within the navigation logo expected dimensions of %widthx%height pixels. The new dimensions of the resized image are %new_widthx%new_height pixels.',
- [
- '%width' => $width,
- '%height' => $height,
- '%new_width' => $image->getWidth(),
- '%new_height' => $image->getHeight(),
- ]));
-
- return TRUE;
+ return [
+ 'width' => $image->getWidth(),
+ 'height' => $image->getHeight(),
+ 'resize' => TRUE,
+ ];
}
- return FALSE;
+ return NULL;
+ }
+
+ /**
+ * Helper function for the navigation settings form.
+ *
+ * Attempts to validate normal system paths, paths relative to the public
+ * files directory, or stream wrapper URIs. If the given path is any of the
+ * above, returns a valid path or URI that the theme system can display.
+ *
+ * @param string $path
+ * A path relative to the Drupal root or to the public files directory, or
+ * a stream wrapper URI.
+ *
+ * @return string|null
+ * A valid path that can be displayed through the theme system, or NULL if
+ * the path could not be validated.
+ */
+ protected function validateLogoPath(string $path): ?string {
+ // Absolute local file paths are invalid.
+ if ($this->fileSystem->realpath($path) == $path) {
+ return NULL;
+ }
+ // A path relative to the Drupal root or a fully qualified URI is valid.
+ if (is_file($path)) {
+ return $path;
+ }
+ // Prepend 'public://' for relative file paths within public filesystem.
+ if (StreamWrapperManager::getScheme($path) === FALSE) {
+ $path = 'public://' . $path;
+ }
+ if (is_file($path)) {
+ return $path;
+ }
+ return NULL;
}
}
diff --git a/core/modules/navigation/src/NavigationRenderer.php b/core/modules/navigation/src/NavigationRenderer.php
index 8613174787b..4aa5bece02d 100644
--- a/core/modules/navigation/src/NavigationRenderer.php
+++ b/core/modules/navigation/src/NavigationRenderer.php
@@ -18,8 +18,6 @@ use Drupal\Core\Menu\LocalTaskManagerInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\file\Entity\File;
-use Drupal\file\FileInterface;
use Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -144,12 +142,11 @@ final class NavigationRenderer {
$page_top['navigation'] = $build;
if ($logo_provider === self::LOGO_PROVIDER_CUSTOM) {
- $logo_managed = File::load($logo_settings->get('logo.managed'));
- if ($logo_managed instanceof FileInterface) {
- $logo_managed_uri = $logo_managed->getFileUri();
- $logo_managed_url = $this->fileUrlGenerator->generateAbsoluteString($logo_managed_uri);
+ $logo_path = $logo_settings->get('logo.path');
+ if (!empty($logo_path) && is_file($logo_path)) {
+ $logo_managed_url = $this->fileUrlGenerator->generateAbsoluteString($logo_path);
+ $image = $this->imageFactory->get($logo_path);
$page_top['navigation'][0]['settings']['logo_path'] = $logo_managed_url;
- $image = $this->imageFactory->get($logo_managed_uri);
if ($image->isValid()) {
$page_top['navigation'][0]['settings']['logo_width'] = $image->getWidth();
$page_top['navigation'][0]['settings']['logo_height'] = $image->getHeight();
diff --git a/core/modules/navigation/tests/assets/image_test_files/test-logo.png b/core/modules/navigation/tests/assets/image_test_files/test-logo.png
deleted file mode 100644
index 853fde8e32e..00000000000
Binary files a/core/modules/navigation/tests/assets/image_test_files/test-logo.png and /dev/null differ
diff --git a/core/modules/navigation/tests/src/Functional/NavigationLogoTest.php b/core/modules/navigation/tests/src/Functional/NavigationLogoTest.php
index f0f65cf471d..377134f07b6 100644
--- a/core/modules/navigation/tests/src/Functional/NavigationLogoTest.php
+++ b/core/modules/navigation/tests/src/Functional/NavigationLogoTest.php
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Drupal\Tests\navigation\Functional;
-use Drupal\Core\Entity\EntityStorageException;
use Drupal\file\Entity\File;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\TestFileCreationTrait;
/**
* Tests for \Drupal\navigation\Form\SettingsForm.
@@ -15,6 +15,8 @@ use Drupal\Tests\BrowserTestBase;
*/
class NavigationLogoTest extends BrowserTestBase {
+ use TestFileCreationTrait;
+
/**
* The file system service.
*
@@ -22,13 +24,6 @@ class NavigationLogoTest extends BrowserTestBase {
*/
protected $fileSystem;
- /**
- * The config factory.
- *
- * @var \Drupal\Core\Config\ConfigFactoryInterface
- */
- protected $configFactory;
-
/**
* A user with administrative permissions.
*
@@ -54,9 +49,8 @@ class NavigationLogoTest extends BrowserTestBase {
protected function setUp(): void {
parent::setUp();
- // Inject the file_system and config.factory services.
+ // Inject the file_system service.
$this->fileSystem = $this->container->get('file_system');
- $this->configFactory = $this->container->get('config.factory');
// Create and log in an administrative user.
$this->adminUser = $this->drupalCreateUser([
@@ -70,6 +64,7 @@ class NavigationLogoTest extends BrowserTestBase {
* Tests Navigation logo configuration base options.
*/
public function testSettingsLogoOptionsForm(): void {
+ $test_files = $this->getTestFiles('image');
// Navigate to the settings form.
$this->drupalGet('/admin/config/user-interface/navigation/settings');
$this->assertSession()->statusCodeEquals(200);
@@ -87,51 +82,44 @@ class NavigationLogoTest extends BrowserTestBase {
$this->assertSession()->elementNotExists('css', 'a.admin-toolbar__logo');
// Option 3: Set the logo provider to custom and upload a logo.
- $logo_file = $this->createFile();
+ $file = reset($test_files);
+ $logo_file = File::create((array) $file + ['status' => 1]);
+ $logo_file->save();
$this->assertNotEmpty($logo_file, 'File entity is not empty.');
- // Preset the configuration to verify a custom image is being seen.
- $config = $this->configFactory->getEditable('navigation.settings');
- $config->set('logo.provider', 'custom');
- $config->set('logo.managed', $logo_file->id());
- $config->save();
+ $edit = [
+ 'logo_provider' => 'custom',
+ 'logo_path' => $logo_file->getFileUri(),
+ ];
+ $this->submitForm($edit, t('Save configuration'));
// Refresh the page to verify custom logo is placed.
$this->drupalGet('/admin/config/user-interface/navigation/settings');
$this->assertSession()->elementExists('css', 'a.admin-toolbar__logo > img');
$this->assertSession()->elementAttributeContains('css', 'a.admin-toolbar__logo > img', 'src', $logo_file->getFilename());
- }
- /**
- * Helper function to create a file entity.
- *
- * @return \Drupal\file\FileInterface
- * The file entity.
- *
- * @throws \Drupal\Core\Entity\EntityStorageException
- */
- protected function createFile() {
- // Define the file URI and path.
- $file_name = 'test-logo.png';
- $temp_dir = $this->fileSystem->getTempDirectory();
- $file_uri = 'public://' . $file_name;
- $logo_path = __DIR__ . '/../../assets/image_test_files/' . $file_name;
- $file_contents = file_get_contents($logo_path);
- file_put_contents($temp_dir . '/' . $file_name, $file_contents);
+ // Option 4: Set the custom logo to an image in the source code.
+ $edit = [
+ 'logo_provider' => 'custom',
+ 'logo_path' => 'core/misc/logo/drupal-logo.svg',
+ ];
+ $this->submitForm($edit, t('Save configuration'));
+ // Refresh the page to verify custom logo is placed.
+ $this->drupalGet('/admin/config/user-interface/navigation/settings');
+ $this->assertSession()->elementExists('css', 'a.admin-toolbar__logo > img');
+ $this->assertSession()->elementAttributeContains('css', 'a.admin-toolbar__logo > img', 'src', 'drupal-logo.svg');
- // Create a file entity for testing.
- $file = File::create([
- 'uri' => $file_uri,
- ]);
-
- try {
- $file->setPermanent();
- $file->save();
- }
- catch (EntityStorageException $e) {
- $this->fail(sprintf('Failed to create file entity: %s', $e->getMessage()));
- }
-
- return $file;
+ // Option 5: Upload custom logo.
+ $file = end($test_files);
+ $edit = [
+ 'logo_provider' => 'custom',
+ 'files[logo_upload]' => $this->fileSystem->realpath($file->uri),
+ ];
+ $this->submitForm($edit, t('Save configuration'));
+ $this->assertSession()->statusMessageContains('The image was resized to fit within the navigation logo expected dimensions of 40x40 pixels. The new dimensions of the resized image are 40x27 pixels.');
+ // Refresh the page to verify custom logo is placed.
+ $this->drupalGet('/admin/config/user-interface/navigation/settings');
+ $this->assertSession()->elementExists('css', 'a.admin-toolbar__logo > img');
+ $this->assertSession()->elementAttributeContains('css', 'a.admin-toolbar__logo > img', 'src', $file->name);
}
}
diff --git a/core/modules/navigation/tests/src/FunctionalJavascript/NavigationSettingsFormTest.php b/core/modules/navigation/tests/src/FunctionalJavascript/NavigationSettingsFormTest.php
deleted file mode 100644
index 746ec4a4be7..00000000000
--- a/core/modules/navigation/tests/src/FunctionalJavascript/NavigationSettingsFormTest.php
+++ /dev/null
@@ -1,83 +0,0 @@
-drupalCreateUser(['administer site configuration']);
- $this->drupalLogin($admin);
-
- // Set expected logo dimensions smaller than core provided test images.
- \Drupal::configFactory()->getEditable('navigation.settings')
- ->set('logo.max.height', 10)
- ->set('logo.max.width', 10)
- ->save();
- }
-
- /**
- * Tests that submission handler works correctly.
- */
- public function testFormSettingsSubmissionHandler() {
- $page = $this->getSession()->getPage();
- $assert_session = $this->assertSession();
-
- $this->drupalGet("/admin/config/user-interface/navigation/settings");
-
- // Add a new managed file.
- $file = current($this->getTestFiles('image'));
- $image_file_path = \Drupal::service('file_system')->realpath($file->uri);
- $page->attachFileToField('files[logo_managed]', $image_file_path);
- $assert_session->waitForButton('logo_managed_remove_button');
-
- // Assert the new file is uploaded as temporary. This file should not be
- // saved as permanent if settings are not submitted.
- $image_field = $this->assertSession()->hiddenFieldExists('logo_managed[fids]');
- $file = File::load($image_field->getValue());
- $this->assertFalse($file->isPermanent());
-
- $page->pressButton('Save configuration');
- \Drupal::entityTypeManager()->getStorage('file')->resetCache();
-
- $this->drupalGet("/admin/config/user-interface/navigation/settings");
-
- // Assert the uploaded file is saved as permanent.
- $image_field = $this->assertSession()->hiddenFieldExists('logo_managed[fids]');
- $file = File::load($image_field->getValue());
- $this->assertTrue($file->isPermanent());
-
- // Ensure that the image has been resized to fit in the expected container.
- $image = \Drupal::service('image.factory')->get($file->getFileUri());
- $this->assertLessThanOrEqual(10, $image->getHeight());
- $this->assertLessThanOrEqual(10, $image->getWidth());
- }
-
-}