We could use a Trait, but there are concerns.
PrimitiveBase::setValue uses properties ($name and $parent) defined in the parent TypedData class.
These properties should also be implemented in a new Trait, as the Trait defines the setValue function.
Since it is assumed that the Trait will be used by classes that inherit TypedData, classes that use the Trait will redefine the properties of TypedData.
Currently, there is no problem as the final values are the same and no errors have occurred.
However, if changes $name or $parent in TypedData in the future, the changes will no longer directly follow the properties in the Trait by redefinition, and the values ββof properties in classes that use the Trait may not be set appropriately.
Is this an unnecessary concern?
I created MR that reroll #5 to UserCreationTrait
.
magaki β made their first commit to this issueβs fork.
I removed the methods from TypedData and reimplemented them in TypedData inherited classes that did not implement the method.
And, I removed ignoreErrors item from .phpstan-baseline.php since $value is no longer used in TypedData.
I added deprecations and tests and reverted the commit that removed the functions to deprecation.
However, PHPStan warns of making a deprecated call by adding the deprecations.
The following classes directly inherit TypedData and have no overridden function implementations.
- core/lib/Drupal/Core/TypedData/Plugin/DataType/Any.php
- core/lib/Drupal/Core/Config/Schema/Element.php
- core/modules/layout_builder/src/Plugin/DataType/SectionData.php
- core/modules/system/tests/modules/entity_test/src/TypedData/ComputedString.php
- core/modules/text/src/TextProcessed.php
- core/tests/Drupal/Tests/Core/Plugin/Fixtures/Plugin/DataType/TestDataType.php
If change it to inherit from PrimitiveBase, I should implement PrimitiveInterface::getCastedValue().
How should I fix it?
I will work on this.
I added deprecation to providerTestBlackListMode and created a change record.
https://www.drupal.org/node/3461718 β
I changed the assigned string in the progress bar id attribute to the escaped strings.
And, I checked the work using javascript similar to the steps to reproduce, no dialog appeared.
The test fails, but it doesn't seem to be related to the changes.
https://git.drupalcode.org/issue/drupal-3426514/-/jobs/1233839#L778
Please review it.
magaki β made their first commit to this issueβs fork.
The cause seems that the triggered element refers to a different than the actually pressed element.
A #submit
callbacks will be set to $form_state
in the FormBuilder::doBuildForm()
, line:1111-1113.
if (isset($triggering_element['#submit'])) {
$form_state->setSubmitHandlers($triggering_element['#submit']);
}
This $triggering_element
is the value got from $form_state->getTriggeringElement();
, and the triggered element will be set for form_state
in the FormBuilder::handleInputElement()
, line:1300-1305.
$buttons = $form_state->getButtons();
$buttons[] = $element;
$form_state->setButtons($buttons);
if ($this->buttonWasClicked($element, $form_state)) {
$form_state->setTriggeringElement($element);
}
A triggered buttons is determined using the FormBuilder::buttonWasClicked()
.
The function determines whether the element's #value
value exists in the input
of $form_state
.
However, if a button that is translated by the browser is pressed, input
has the translated value, so buttonWasClicked
returns FALSE
.
protected function buttonWasClicked($element, FormStateInterface &$form_state) {
// First detect normal 'vanilla' button clicks. Traditionally, all standard
// buttons on a form share the same name (usually 'op'), and the specific
// return value is used to determine which was clicked. This ONLY works as
// long as $form['#name'] puts the value at the top level of the tree of
// \Drupal::request()->request data.
$input = $form_state->getUserInput();
// The input value attribute is treated as CDATA by browsers. This means
// that they replace character entities with characters. Therefore, we need
// to decode the value in $element['#value']. For more details see
// http://www.w3.org/TR/html401/types.html#type-cdata.
if (isset($input[$element['#name']]) && $input[$element['#name']] == Html::decodeEntities($element['#value'])) {
return TRUE;
}
// When image buttons are clicked, browsers do NOT pass the form element
// value in \Drupal::request()->Request. Instead they pass an integer
// representing the coordinates of the click on the button image. This means
// that image buttons MUST have unique $form['#name'] values, but the
// details of their \Drupal::request()->request data should be ignored.
elseif (!empty($element['#has_garbage_value']) && isset($element['#value']) && $element['#value'] !== '') {
return TRUE;
}
return FALSE;
}
If the button was not found in the above process, the first button among the elements registered as buttons will be set as the triggered element in the FormBuilder::doBuildForm()
.
$buttons = $form_state->getButtons();
if (!$form_state->isProgrammed() && !$form_state->getTriggeringElement() && !empty($buttons)) {
$form_state->setTriggeringElement($buttons[0]);
}
As a result, when a translated button is pressed,
- if there are one or more buttons, it will refer to the first button and set in $form_state
, and the #submit
will be executed.
- if there is no button, nothing happens.
As a solution, since #element[#value]
will be rewritten by the browser, it may be possible to solve the problem by defining any identifiable values and using them to determine the triggered element.
I checked the work using the following Form class.
Normally, pressing buttons 1, 2, and 3 each show a different message.
However, pressing buttons 2, and 3 will show the message for button 1 when the element has been translated by the browser.
<?php
namespace Drupal\sandbox\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class SandboxForm extends FormBase {
public function getFormId(): string {
return 'sandbox_form';
}
public function buildForm(array $form, FormStateInterface $form_state): array {
$form['button1'] = [
'#type' => 'submit',
'#value' => 'This is button 1',
'#submit' => [
'::callback1',
],
];
$form['button2'] = [
'#type' => 'submit',
'#value' => 'This is button 2',
'#submit' => [
'::callback2',
],
];
$form['button3'] = [
'#type' => 'submit',
'#value' => 'This is button 3',
'#submit' => [
'::callback3',
],
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state): array {
return $form;
}
public function callback1(array $form, FormStateInterface $form_state): void {
\Drupal::service('messenger')->addStatus('Button1 was pressed (callback1)');
}
public function callback2(array $form, FormStateInterface $form_state): void {
\Drupal::service('messenger')->addStatus('Button2 was pressed (callback2)');
}
public function callback3(array $form, FormStateInterface $form_state): void {
\Drupal::service('messenger')->addStatus('Button3 was pressed (callback3)');
}
}
- Added documentation about the deprecation of the Locale
class.
- Removed unnecessary periods.
- About using $localConfigManager
as a temporary variable of Locale::config()
- Removed $localConfigManager
if it was only used once.
- Renamed to $locale_config_manager
if it was used more than once.
Please review it
Thank you for confirming my account.
I could create a new change records.
https://www.drupal.org/node/3437110 β
I made a mistake in rebase once, so I force pushed the pre-rebase, updated the 11.x branch of the repository to the latest, and rebased the branch to on top of that.
I modified the deprecated version to 10.3 and removal version to 11.0.
I could not create change records because I have no permissions.
I modified the documentation according to Drupal deprecation policy and added its test.
Please review it.
The test fails, but it doesn't seem to be related to the changes.
https://git.drupalcode.org/issue/drupal-3422915/-/pipelines/133015/test_...β‘%EF%B8%8F%20PHPUnit%20Unit
magaki β made their first commit to this issueβs fork.