Quantcast
Channel: Issues for Drupal core
Viewing all 292900 articles
Browse latest View live

Deprecate _drupal_flush_css_js() and create a new AssetQueryString cache service

$
0
0

Problem/Motivation

Splitting off a child issue from #3014752: [PP-1] Convert drupal_rebuild(), drupal_flush_all_caches() and _drupal_flush_css_js() functions into cache Rebuilder class where @alexpott suggested in comment #83:

I think this issue could do with coming in 2 parts. One that deals with the new CSS / JS query string service and converting usages of _drupal_flush_css_js() and anything that accesses the 'system.css_js_query_string' state directly. And another that deals with drupal_flush_all_caches() and drupal_rebuild().

This issue is for the first part of that.

Steps to reproduce

Proposed resolution

  • Deprecate _drupal_flush_css_js()
  • Create a new AssetQueryString cache service
  • Convert usages

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet


Comment type form title is confusing

$
0
0

Problem/Motivation

The page title for comment type edit form is just "Edit". This is pretty confusing because it doesn't contextualize the local tasks, but also leads into incorrect breadcrumbs on the subpages as reported in #2587415: Comment types UI confusing and inconsistent.

Proposed resolution

Change the page title to the current comment type.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Prevent registered e-mail address enumeration via user registration form

$
0
0

Problem/Motivation

In #1521996: Password reset form reveals whether an email or username is in use we try to find a solution that stops guests to use the 'Request new password' form to learn that a user with a specific email address is registered on the site.

The same privacy issue exists with the 'Create new account' form (as was pointed out by penyaskito).

Steps to reproduce the issue:

  1. Register an account with the email address me@example.com.
  2. Try to register another account with the email address me@example.com.
  3. You’ll get an error:
    The email address me@example.com is already registered. Have you forgotten your password?

Proposed resolution

  • Instead of displaying an error, display exactly the same success message that is used when registering with an unused email address.
    • If email verification is required:
      • In case the address is unused: No change, send the normal registration confirmation.
      • In case the address is already used: Send an email explaining something like: "You or someone else tried to register an account on example.com with your email address me@example.com. However, you already have an account on this site. Did you forget your password? Then …"
    • If email verificiation is not required (i.e., new users are directly logged in after registration):
      • If the same password is used: Just log the old user in, and maybe show a notification that the account already existed.
      • If a different password is used: This becomes ugly … (we can’t tell if the user is the same or not). What could we do? Maybe we should only provide a solution in case email verification is required?

Remaining tasks

User interface changes

API changes

Limit password reset for recently active users

$
0
0

see: http://www.freedom-to-tinker.com/blog/felten/how-yahoo-could-have-protec...

Yahoo could also have followed Gmail's lead, and disabled the security-question mechanism unless no logged-in user had accessed the account for five days. This clever trick prevents password "recovery" when there is evidence that somebody who knows the password is actively using the account. If the legitimate user loses the password and doesn't have an alternative email account, he has to wait five days before recovering the password, but this seems like a small price to pay for the extra security.

Drupal's password recovery mechanism doesn't have all the weaknesses that Yahoo's does, but given that Word Press's was recently exploited, it seems a pretty reasonable thing to consider limits - or at least a hook through which contrib modules could add limits.

For example - disable one-time link requests for users logged in within the last 24 hours.

Calling Url::fromUri() with an uri having a query part and passing an additional query in the option parameter results in an invalid url

$
0
0

Problem/Motivation

When you call Url::fromUri() with an uri, which already has the query part, and pass an additional query in the second parameter, then the result will be an invalid url.

Steps to reproduce

Here is an example code to reproduce the issue:

// Url with query
$url = 'https://hostname/path/?foo=1&bar=2';

// Pass url and additional query parameter
$url = \Drupal\Core\Url::fromUri(
  $url,
  ['query' => ['baz' => 3]]
)->toUriString();

// Output: https://hostname/path/?foo=1&bar=2?baz=3
echo $url . PHP_EOL;

The result is an invalid url, which has two question marks.

Proposed resolution

Following line within the else condition at the bottom of the fromUri() function should not use the passed $uri parameter, it should use a cleaned version of it, where the query part is removed.

$url = new static($uri, [], $options);

This version would fix it:

$url = new static(trim(strtok($uri, '?')), [], $options);

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Add mechanism to have workspaces skip processing entity types

$
0
0

Problem/Motivation

Developers should have the option to allow specified entities to be ignored by workspaces.

For example, I specifically wanted to allow the manipulation of file and crop entities in a non-default workspace.

Proposed resolution

Move the shouldSkipPreOperations method out of EntityOperations and into the WorkspaceManager service and make it public.

Add a protected array of entity_type ids to WorkspaceManager called $skiplist. This matches the pattern used by blacklist. Developers that wish to add entity_type ids to the $skiplist can do so by decorating the workspaces.manager service.

allow FieldConfigInterface::setDefaultValueCallback() to accept a callback in service notation

$
0
0

FieldConfigInterface::setDefaultValueCallback() accepts a callback for a base of config field's default value, either as a function or method name.

We get this pattern repeated by entity types over and over again for fields where the default value comes from a service, such as the uid and created fields:

Node entity:

    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Authored by'))
      ->setDescription(t('The username of the content author.'))
      ->setRevisionable(TRUE)
      ->setSetting('target_type', 'user')
      ->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId')

...

  public static function getCurrentUserId() {
    return [\Drupal::currentUser()->id()];
  }

Media entity:

    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Authored by'))
      ->setDescription(t('The user ID of the author.'))
      ->setRevisionable(TRUE)
      ->setDefaultValueCallback(static::class . '::getCurrentUserId')
...

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Authored on'))
      ->setDescription(t('The time the media item was created.'))
      ->setTranslatable(TRUE)
      ->setRevisionable(TRUE)
      ->setDefaultValueCallback(static::class . '::getRequestTime')

...

  public static function getCurrentUserId() {
    return [\Drupal::currentUser()->id()];
  }

  public static function getRequestTime() {
    return \Drupal::time()->getRequestTime();
  }

We could remove these wrapper method and save on repeated code and improve DX if we allow setDefaultValueCallback() to accept a callback in service notation the same way that route controllers do, that is, 'service_name:method'.

Convert field_storage_config and field_config's form validation logic to validation constraints

$
0
0

Problem/Motivation

As long as field_storage_config and field_config are not validatable (see #2164373-28: [META] Untie config validation from form validation — enables validatable Recipes, decoupled admin UIs …, it will be difficult to build a "Field UI 2.0" with confidence, and we definitely won't be able to create such a thing as a decoupled JS application.

Proposed resolution

Remove form-coupled validation logic from:

field_storage_config
  • \Drupal\field_ui\Form\FieldStorageAddForm::validateForm()
  • \Drupal\field_ui\Form\FieldStorageAddForm::validateAddNew()
  • \Drupal\field_ui\Form\FieldStorageAddForm::validateAddExisting()
  • \Drupal\field_ui\Form\FieldStorageAddForm::fieldNameExists()
  • \Drupal\field_ui\Form\FieldStorageConfigEditForm::validateCardinality()
field_config
  • \Drupal\field\Entity\FieldConfig::postCreate()
  • \Drupal\field\Entity\FieldConfig::preSave()
  • \Drupal\field_ui\Form\FieldConfigEditForm::validateForm()

… and keep the existing test coverage the same, at most expand it.

Note that additional validation constraints will be necessary beyond what already exists, because a form-based UI only allows certain inputs, not arbitrary inputs, which are possible via an API.

Remaining tasks

TBD

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

TBD


Add a `langcode` data type to config schema

$
0
0

Problem/Motivation

As part of #2164373: [META] Untie config validation from form validation — enables validatable Recipes, decoupled admin UIs …, we are going to want to validate language codes as language codes, with their own constraints, rather than as plain strings.

Steps to reproduce

N/A

Proposed resolution

Add a new langcode data type to config schema, which implements certain validation constraints that are specific to language codes.

Remaining tasks

Figure out how to implement the feature and add robust test coverage.

User interface changes

None.

API changes

TBD, but there will probably be at least one new config data type (langcode) and possibly a new validation constraint or two.

Release notes snippet

TBD

Views UI should offer a 'Treat NULL values as FALSE' on boolean field filtering to expose the already existing code path for handling this

$
0
0

Problem/Motivation

Views provides an option for filtering boolean fields on null/not null, but this is not exposed in the Views UI.

Proposed resolution

Expose this code in the UI (from #2):

      if ($this->accept_null) {
        if ($query_operator == static::EQUAL) {
          $condition = (new Condition('OR'))
            ->condition($field, 0, $query_operator)
            ->isNull($field);
        }
        else {
          $condition = (new Condition('AND'))
            ->condition($field, 0, $query_operator)
            ->isNotNull($field);
        }
        $this->query->addWhere($this->options['group'], $condition);
      }

Possible workaround using a views override in the meantime (from #3):

function MODULENAME_views_pre_build(ViewExecutable $view) {
  if ($view->storage->id() == 'VIEWMACHINENAME') {
    // If reviewed is set to false then we should include NULLs.
    if ($view->filter['FIELDMACHINENAME']->value == 0) {
      $view->filter['FIELDMACHINENAME']->accept_null = TRUE;
    }
  }
}

Remaining tasks

Code, review, documentation.

User interface changes

Adds "is NULL" and "is not NULL" to filtering options in UI on boolean fields.

API changes

None.

Data model changes

None.

Original report by nicxvan

I have a boolean field on a node.

I would like the view to return all nodes that do not have the checked box. (Either never set or selected and unset later)
I set the filter to Is not equal to TRUE.

No nodes with the boolean that is null are returned.

Use PHP attributes for route discovery

$
0
0

Problem/Motivation

Drupal should use modern PHP attributes for route discovery ala Symfony.

This will allow us to add an attribute to a method name and use that for routing information. For example:

  /**
   * The default 401 content.
   *
   * @return array
   *   A render array containing the message to display for 401 pages.
   */
  #[Route(
    path: '/system/401',
    name: 'system.401',
    requirements: ['_access' => 'TRUE'],
    defaults: ['_title' => 'Unauthorized']
  )]
  public function on401() {
    return [
      '#markup' => $this->t('Please log in to access this page.'),
    ];
  }

will replace the following entry in system.routing.yml

system.401:
  path: '/system/401'
  defaults:
    _controller: '\Drupal\system\Controller\Http4xxController:on401'
    _title: 'Unauthorized'
  requirements:
    _access: 'TRUE'

What are the advantages of doing this?

  • The defaults._controller value is determined by the method you add the attribute to
  • The route definition and the controller code live side by side
  • No longer need route names - these can be automatically provided based on the class and method name
  • Less difference between modern Symfony and Drupal

What are the disadvantages?

  • The routing.yml file can give a good overview of what a module does and makes reviewing route access a bit simpler

Mitigations of the disadvantages:

  • Currently the code is scanning all the classes in a module's src/Controllers directory for attributed methods - therefore it's not that difficult to scan this code and you benefit from the controller and route definition being together.
  • We should and can build CLI tools to expose all the routes provided by a module. This would be good not just for routes determined by attributes but also dynamic routes

Proposed resolution

  • Remove yaml discovery from the RouteBuilder into it's own service
  • Add a new static routing event for the yaml discovery to listen to
  • Add a new service for PHP attribute discovery and listen to the same event. This reflects on all classes in a module's src/Controllers directory to find routes

Remaining tasks

  • Add more test coverage
  • Decide which of the Symfony route features to keep in - env, localized_paths, priority, _locale, _canonical_route stuff... not sure what to do with this.

User interface changes

None

API changes

TBD

Data model changes

None

Release notes snippet

@todo

[Ignore] In space (and/or this issue), no one can hear patches scream VII

JavaScript aggregation should account for "async" and "defer" attributes

$
0
0

Problem/Motivation

HTML5 proposes/solidifies asynchronous loading of JavaScript files based on two attributes: defer and async. Drupal has supported defer since at least D6, and support for async is currently in the works (#1140356: Add async, onload property to script tags).

Current behavior (as of 8.6) is that scripts with the defer attribute do not ever get aggregated (even in the case where there are multiple scripts added through one library).

Proposed resolution

Presumably, something will be added to drupal_group_js that groups "async" values with one another and "defer" values with one another, respecting their weights.

Remaining tasks

User interface changes

None

API changes

Though this affects JavaScript aggregation, this should have little-to-no API impact.

Revert and Delete actions should not be available for the current revision

$
0
0

Problem/Motivation

Created as a follow-up to #2350939: Implement a generic revision UI.

There are several problems that result from the Revert and Delete actions being available for the current revision.

  1. The user interface break slightly, with the Revert/Delete split/drop button being directly to the right of the "Current revision" text, all under the single "Operations" column.
  2. Following through the Revert action technically works, in that a new "revert" revision is created, practically nothing has changed because the "current revision" is the current state of the content. In other words, reverting the current revision is illogical because there is nothing to revert to.
  3. Following through the Delete action results in an error and White Screen of Death, which leaves the entity in a broken and unrecoverable state.

Screenshot of the revision list showing the current revision.

The current solution to this is that every entity implementing the Generic Revision UI must include logic in its own access checker to ensure that the Revert and Delete actions cannot be accessed. Example from #1984588: Add Block Content revision UI:

'revert' => AccessResult::allowedIfHasPermissions($account, [
  'administer blocks',
  'revert any ' . $bundle . ' block content revisions',
], 'OR')->orIf(AccessResult::forbiddenIf($entity->isDefaultRevision() && $entity->isLatestRevision())),
'delete revision' => AccessResult::allowedIfHasPermissions($account, [
  'administer blocks',
  'delete any ' . $bundle . ' block content revisions',
], 'OR')->orIf(AccessResult::forbiddenIf($entity->isDefaultRevision() && $entity->isLatestRevision())),

In short, each implementation must include something to the effect of AccessResult::forbiddenIf($entity->isDefaultRevision() && $entity->isLatestRevision() in the access checker, once for the revert operation, and a second time for the delete revision operation.

There are two issues here:

  1. It's reasonable to assume that some developers will forget or not realise they need to include this in their access checkers, resulting in some implementation potentially being buggy.
  2. The fact that every implementation needs to include what is in effect the same lines of code suggests that overall developer effort would be reduced by providing this logic in an access checker out of the box, as well as lowering the barrier to entry and reducing the likelihood of bugs in contrib/custom implementations.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

AJAX breaks in 9.5.x

$
0
0

Problem/Motivation

After upgrading from 9.4.6 to 9.5.10 pages using AJAX functionality, such as clicking a filter checkbox and having the filter applied, fail silently.
I tried upgrading to 9.5.9 instead, and the same result.
In inspecting an example page, and enabling pausing on both uncaught and caught exceptions, clicking a checkbox throws:

"stack": "Error: Failed to execute 'pushState' on 'History': function isInProgress() {\n        return ajax.ajaxing;\n      } could not be cloned.\n    at c.<computed> [as pushState] (https://www.googletagmanager.com/gtag/js?id=G-1234567&l=dataLayer&cx=c:476:265)\n    at addState (https://mysite.ddev.site/modules/contrib/views_ajax_history/js/views_ajax_history.js?v=9.5.10:165:13)\n    at Drupal.Ajax.beforeSubmit (https://mysite.ddev.site/modules/contrib/views_ajax_history/js/views_ajax_history.js?v=9.5.10:310:7)\n    at Object.beforeSubmit (https://mysite.ddev.site/core/misc/ajax.js?v=9.5.10:190:21)\n    at q.fn.ajaxSubmit (https://mysite.ddev.site/core/assets/vendor/jquery-form/jquery.form.min.js?v=4.3.0:22:2557)\n    at Drupal.Ajax.eventResponse (https://mysite.ddev.site/core/misc/ajax.js?v=9.5.10:293:20)\n    at HTMLInputElement.<anonymous> (https://mysite.ddev.site/core/misc/ajax.js?v=9.5.10:247:19)\n    at HTMLInputElement.dispatch (https://mysite.ddev.site/core/assets/vendor/jquery/jquery.min.js?v=3.6.3:2:43336)\n    at y.handle (https://mysite.ddev.site/core/assets/vendor/jquery/jquery.min.js?v=3.6.3:2:41320)\n    at Object.trigger (https://mysite.ddev.site/core/assets/vendor/jquery/jquery.min.js?v=3.6.3:2:71942)"
}

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet


JsOptimizer removes 'async' from functions and break JavaScript

$
0
0

Problem/Motivation

The new JS optimizer added in Drupal 10.1 is now breaking async functions if this keyword is infront of function.

Steps to reproduce

Foo = {
  async bar() {},
  baz: async () => {},
}

Expects to be Foo={async bar(){},baz:async()=>{}}; but Foo={bar(){},baz:async()=>{}}; provided.

bar() lost its async prefix and any await inside will lead to JS error and break aggregated JS file completely.

Proposed resolution

Find out why is that happened and fix it.

Use dependency injection in entity query

$
0
0

Problem/Motivation

Coming from a comment from @plach in #2784921-146: Add Workspaces experimental module, we need to be able to use Dependency Injection in the entity query code.

For example, \Drupal\Core\Entity\Query\Sql\Tables::__construct() currently sets the entity type manager using \Drupal::entityTypeManager().

  /**
   * @param \Drupal\Core\Database\Query\SelectInterface $sql_query
   *   The SQL query.
   */
  public function __construct(SelectInterface $sql_query) {
    $this->sqlQuery = $sql_query;
    $this->entityTypeManager = \Drupal::entityTypeManager();
    $this->entityFieldManager = \Drupal::service('entity_field.manager');
  }

Drupal Usability Meeting 2023-07-14

$
0
0

This meeting takes place every Friday at 14:00 UTC (currently 7:00am PT, 10:00am ET). See Time.is to see what that is in your timezone.

The meetings are held using Zoom, and a link is posted in the #ux Slack channel 10 minutes before the meeting. Agenda is first come, first serve and set by attendees. Use the Needs usability review issue tag for issues that need review and/or suggest issues in comments here.

List of Slack users to ping 10 minutes before the meeting:
@Gábor Hojtsy (he/him), @worldlinemine, @lauriii, @AaronMcHale, @anmolgoyal74, @Antoniya, @Ravi, @shaal, @ckrina, @simohell, @gauravvv, @penyaskito, @Mike Gifford (CivicActions), @April, @Quynh, @yoroy, @EricRubino

Go to the issue for the next meeting to add/remove yourself to/from the list.

Recording of this week's meeting: TODO

Rough transcript of this week's meeting: Drupal Usability Meeting - 2023-07-14.txt

We discussed the following issue:

NR and RTBC issues marked Needs usability review.

Drupal Usability Meeting 2023-07-28

$
0
0

This meeting takes place every Friday at 14:00 UTC (currently 7:00am PT, 10:00am ET). See Time.is to see what that is in your timezone.

The meetings are held using Zoom, and a link is posted in the #ux Slack channel 10 minutes before the meeting. Agenda is first come, first serve and set by attendees. Use the Needs usability review issue tag for issues that need review and/or suggest issues in comments here.

List of Slack users to ping 10 minutes before the meeting:
@Gábor Hojtsy (he/him), @worldlinemine, @lauriii, @AaronMcHale, @anmolgoyal74, @Antoniya, @Ravi, @shaal, @ckrina, @simohell, @gauravvv, @penyaskito, @Mike Gifford (CivicActions), @April, @Quynh, @yoroy, @EricRubino

Go to the issue for the next meeting to add/remove yourself to/from the list.

Recording of this week's meeting: TODO

Rough transcript of this week's meeting: Drupal Usability Meeting - 2023-07-28.txt

We discussed the following issue:

NR and RTBC issues marked Needs usability review.

Views hardcodes exposed filter block form ID's which breaks AJAX when the same form is shown multiple times on one page

$
0
0

Problem/Motivation

When an exposed filter is placed twice on the same page it gets the same html identifier. Every instance of this form needs a unique id.

Proposed resolution

Use Html::getUniqueId() to generate the ID.

Remaining tasks

Review

User interface changes

None

Release notes snippet

Viewing all 292900 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>