Problem/Motivation

When loading an entity display configuration page (like `admin/structure/types/manage/page/display`) that uses Layout Builder, if the entity has an options field that has no options available, the page cannot be loaded due to a PHP error.

Steps to reproduce

First noted on PHP 8.1 and core 9.5.

Enable layout_builder. Configure your entity display to use Layout Builder.

Add a list_string field to your entity that uses an allowed_values_function. Have the allowed_values_function return an empty array. (you can also just install and enable the scheduler_content_moderation_integration module which provides two of these via hook_entity_base_field_info().) Or, just create an options field with no options.

Load the configuration page for your display mode. See:

`ValueError: array_rand(): Argument #1 ($array) cannot be empty in array_rand() (line 68 of /code/web/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php)`

Proposed resolution

The error is caused by this code in `core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php`:

  public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
    $allowed_options = options_allowed_values($field_definition->getFieldStorageDefinition());
    $values['value'] = array_rand($allowed_options);
    return $values;
  }

Because array_rand does not accept empty arrays.

I propose we check if the `$allowed_options` is empty, and if it is, return an empty value rather than invoking `array_rand()`.

(There seem to be a couple issues attempting to resolve similar problems from the Layout Builder side, but this seems like an issue with this specific piece of code. "no options available" isn't an ideal result, but it is sensible in some use cases, and this code should handle those cases without crashing.)

Remaining tasks

May need a test.

User interface changes

None.

API changes

None?

Data model changes

N/A

Release notes snippet

Allow sample content to be generated for options fields with no valid options.

Issue fork drupal-3331397

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

gcb created an issue. See original summary.

Tatsiana’s picture

Hi all,
I have apllied a patch, looks like it works, thanks

Attaching a static patch file with those changes, to make it possible to use in composer until #3204538: GitLab Merge Requests Unable to Generate Incremental Patch Files is resolved.

DanielVeza’s picture

Status: Active » Needs review
FileSize
1.54 KB
1.27 KB

I was able to replicate this, attached a patch that removes the else from the original patch and adds a test.

arisen’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
646.79 KB
396.78 KB

Reviewed the patch in #4 on drupal 9.5.4 with php 8.1.

The patch applies cleanly:

Checking patch core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php...
Checking patch core/modules/options/tests/src/Kernel/OptionsFieldTest.php...
Applied patch core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php cleanly.
Applied patch core/modules/options/tests/src/Kernel/OptionsFieldTest.php cleanly.

Testing steps:

  • Setup drupal 9.5.4 site
  • Enabled Layout builder for default display of basic page.
  • Added text list field with no options.
  • Tried to edit the layout. It throws the error as mentioned
  • Applied the patch and verified the layout edit functionality. It works fine
kleiton_rodrigues’s picture

The #4 patch applies cleanly and works as expected.
LGTM.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 4: 3331397-4.patch, failed testing. View results

DanielVeza’s picture

Status: Needs work » Reviewed & tested by the community

Random fail. Requeing and restoring status

Anybody’s picture

Same issue here!

Anybody’s picture

larowlan’s picture

Confirming the test failed as expected

phpunit -c app/core app/core/modules/options/tests/src/Kernel/OptionsFieldTest.php 
⏳️ Bootstrapped tests in 0 seconds.
🐘 PHP Version 8.1.16.
💧 Drupal Version 10.1.0-dev.
🗄️  Database engine mysql.
PHPUnit 9.6.6 by Sebastian Bergmann and contributors.
Testing Drupal\Tests\options\Kernel\OptionsFieldTest
.E                                                                  2 / 2 (100%)

Time: 00:02.241, Memory: 10.00 MB

There was 1 error:

1) Drupal\Tests\options\Kernel\OptionsFieldTest::testGenerateSampleItemsWithNoAllowedValues
ValueError: array_rand(): Argument #1 ($array) cannot be empty

/data/app/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php:68
/data/app/core/lib/Drupal/Core/Field/FieldItemList.php:253
/data/app/core/modules/options/tests/src/Kernel/OptionsFieldTest.php:107

  • larowlan committed 3e82115d on 10.0.x
    Issue #3331397 by gcb, DanielVeza, Tatsiana, arisen: ListItemBase::...

  • larowlan committed 52fbc9ad on 10.1.x
    Issue #3331397 by gcb, DanielVeza, Tatsiana, arisen: ListItemBase::...

  • larowlan committed f8a0d181 on 9.5.x
    Issue #3331397 by gcb, DanielVeza, Tatsiana, arisen: ListItemBase::...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +Bug Smash Initiative

Committed to 10.1.x and backported to 10.0.x and 9.5.x

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.