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

Do not limit Content language negotiation method to the current entity

$
0
0

Problem/Motivation

A common use case is to be able keep a single interface language for an editor while he works with content in multiple languages.

Not being able to do that is especially annoying in a multi-domain setup, where the editor then has to log in again for every language domain.

Right now, that is surprisingly hard to achieve.

It seems like it should be possible through giving User/Session/Admin Language a higher priority than URL for the interface language and not for content. But there are several problems with that, related to the hidden/special URL language type (#1125428: Modifying node language with a path alias leads to 404 (session language negotiation)) and things like the route normalizer of the redirect.module (and eventually core: #2641118: Route normalizer: Global Redirect in core). So that's not possible and also doesn't really seem solvable.

The alternative is the "Content language" negotiation method that can be enabled for the content language type. That turns it around and instead adds a query argument to the URL that then enforces the content language. First tests show that it works fairly well but it is currently limited to altering outbound links only if the target entity is the "current entity". That means it works on node/1/translate, but it doesn't work on admin/content.

There also seem to be several bug reports about broken language switcher when that is enabled, so that will need to be fixed but is "just" a bug, while this is about a behavior change.

* #2864055: LanguageNegotiationContentEntity: don't break interface language switcher links
* #2867480: LanguageNegotiationContentEntity: make language switch links more robust
* #2666634: Session and content entity switch links do not set the URL language

Proposed resolution

Update \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity::meetsContentEntityRoutesCondition() and remove the current entity check?

IMHO that would make sense, based on how the default admin views now work (listing all translations, expecting that you can directly go to edit any of them).

I also found #2843439: Can't translate a content into a language different than that of the administration pages language setting as a possibly related issue, not quite sure how that affects things.

Remaining tasks

User interface changes

API changes

Data model changes


Fix naming of tests referencing the refactored drupal_set_message() function

$
0
0

Problem/Motivation

A follow up to to #2924538: [META] Remove all usages of drupal_get_message and drupal_set_message fix the naming of:

  • The system_test.drupal_set_message route
  • The /system-test/drupal-set-message path
  • The SystemTestController::drupalSetMessageTest() method
  • The \Drupal\Tests\system\Functional\Bootstrap\DrupalSetMessageTest() test class

None of these things test drupal_set_message() anymore.

Proposed resolution

Update the naming so it no longer directly references the refactored drupal_set_message() function.

Remaining tasks

  1. Write a patch
  2. Review
  3. Commit

User interface changes

None.

API changes

None.

Data model changes

None.

Experimental migrate_drupal_i18n module

$
0
0

Problem/Motivation

Even after we get the last couple i18n issues resolved, there are still many unknowns and areas for i18n could get improved. Rather than rushing and stating all i18n migrations are ready because we just need to get things out the door, let’s take off the pressure. Give us a little more time to do things properly. Having a separate marking module let’s us mark i18n stable when it is really more stable.

Proposed resolution

  • Add a new migrate_drupal_i18n module
  • In all i18n source plugins, add to the existing checkRequirements function a call to \Drupal::service(‘module_handler’)->moduleExists(‘migrate_drupal_i18n’).
  • If the module doesn’t exist (i.e. it isn’t installed) then it fails requirements and will not be available for migrations.
  • Then mark migrate_drupal_i18n as experimental. And mark migrate_drupal as stable.
  • Profit

Remaining tasks

  • Roll a patch.
  • Discuss if this can land as Experimental into 8.5. That way we could mark migrate drupal and the UI as stable sooner.

User interface changes

API changes

Data model changes

Make it possible to retrieve all the last installed entity type definitions at once from the update manager

$
0
0

Problem/Motivation

In many update functions we need a way to get a list of all entity type definitions and then filter them by some criteria (e.g. only revisionable entity type).

At the moment, we can only do this by going through the entity manager, which holds the "live" definitions, and then retrieve the last installed definition manually from the entity definition update manager. However, accessing the live definitions has resulted in many bugs in the past, and sometimes we even forget that we only need to work with the last installed definition, not the live one.

Proposed resolution

To make writing generic update functions easier, add a method to EntityDefinitionUpdateManager which retrieves all the last installed entity type definitions at once.

Remaining tasks

Discuss, review.

User interface changes

Nope.

API changes

API addition.

Data model changes

Nope.

Migrate D6 i18n blocks translated strings

$
0
0

Postponed on #2225587: Migrate D6 i18n menu links

Problem/Motivation

A migration for block translated strings is needed. The block translated strings are in the block table and the language code in the i18n_blocks table.

Proposed resolution

Write a custom source plugin, refer to the existing block source plugin.
Write block translation migrations based on the existing block migrations.
And, of course, tests.

Create generic entity usage tracking service

$
0
0

Split out from #2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder

Problem/Motivation

#2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder will allow placing of custom non-reusable blocks from within the Layout Builder. These blocks should not be available anywhere outside the layout they are placed within. They should be deleted when the parent entity is deleted. Any non-reusable block that is in a previous revision should not be deleted until the entity using the layout is deleted so that if the entity is reverted to that revision the block will be there.

Because a single entity could have 100's(thousands?) of revisions there may be hundreds of individual non-reusable blocks in previous revisions of the entity when it is deleted.

Trying to delete hundreds of block entities may cause performance issues when deleting the parent entity.

Proposed resolution

Introduce an EntityUsage service. The default implementation of this service will be DatabaseBackendEntityUsage. This usage tracking will be similar to FileUsage service except the entity being tracked could be any entity. Once all the uses of any entity have been removed the usage will be zero. This will allow modules to determine which entities had uses that were removed as opposed to entities that will never tracked.

This service will not delete entities that are no longer used. It will be up to the module using the entity tracking service to delete the entities.

Remaining tasks

Write the patch.

User interface changes

None

API changes

The new service

Data model changes

None

Migrate D6 i18n translations of taxonomy vocabulary/terms

$
0
0

Problem/Motivation

In Drupal 6, you can use the I18n Taxonomy module to translate a taxonomy vocabulary and taxonomy terms. What happens when you do this is that:

  • You mark a particular vocabulary as having translatable terms. (In my site, I had one that was marked as translatable and one that wasn't).
  • If you go to the taxonomy page, like admin/content/taxonomy/5, you cannot see the translated taxonomy terms. But you can translate them by going to the central UI (locale) translation page (admin/build/translate), so the translated terms are stored in the same database tables as the UI translation strings. To translate, click on Search, and filter by Taxonomy, and if you have the i18n_taxonomy module enabled, you will see the translatable taxonomy terms there to translate.
  • After translating, if you view a translated node with one of the terms on it, and view it in Spanish, the term will show up in Spanish. Also, I made a block view that lists the tags (the translated vocabulary), and when viewing the site in Spanish, this block shows up in Spanish also.
  • In the D6 database:
    - term_data has the taxonomy term information
    - i18n_strings correlates term IDs to locale string IDs
    - locales_target has the actual translations in it
    Here's a query that illustrates the relationships:
    SELECT td.tid, td.name, lt.language, lt.translation FROM term_data td LEFT JOIN i18n_strings ist ON td.tid = ist.objectid LEFT JOIN locales_target lt ON ist.lid = lt.lid WHERE ist.type = 'term'

At this time, taxonomy terms translated in this way cannot be migrated into Drupal 8. If you have a Drupal 6 site with this setup, you get the English terms migrated in, and the English name for the vocabulary, but the translations are not migrated. The resulting site has the following in the database, after migrating from an actual D6 site with internationalized taxonomy terms (one vocabulary with English/Spanish terms, and one with just English terms):

  • Table migrate_message_d6_taxonomy_term_translation is there but empty, so Migrate thinks it did the translation migration with no messages.
  • Table migrate_map_d6_taxonomy_term_translation has 36 rows. 36 is the total number of taxonomy terms on the d6 site. 23 were from the translated vocabulary. The other 13 from the untranslated vocabulary.
  • Table taxonomy_term_field_data has 36 rows. Each one is an English taxonomy term. The langcode field is blank for all entries. There are no Spanish entries.

Note that #2784371: Migrate D6 i18n taxonomy term language (but not yet translations) migrated term language, and #2225781: Migrate D6 i18n taxonomy vocabularies migrated vocabulary language, but neither of them migrated translations. Also, once this is done, we can look at also making sure the translated nodes get the translated taxonomy terms, on #2859297: Migrate d6 translated nodes with translated taxonomy.

Proposed resolution

Migrate taxonomy vocabulary and term translations.

Remaining tasks

a) Make a patch with tests.
b) Test manually. jhodgdon's test instructions are in comment #12.

User interface changes

Taxonomy term translations will be migrated.

API changes

Probably not.

Data model changes

Probably not.

Migrate D6 i18n custom blocks (boxes)

$
0
0

Follow-up to #2225681: Migrate D6 i18n blocks translated strings

Problem/Motivation

A migration for custom block (D6 boxes) translated strings is needed. The translations for the title and body of custom blocks is in the i18n strings module.

Proposed resolution

Write a custom source plugin. Note the translation for the title and body of custom blocks are on different rows in the locales_target source. The source plugin needs to keep track of what item is being translated on a row.
And, of course, tests.


Merge Admin UI redesign and JavaScript modernization initiatives

$
0
0

Problem/Motivation

Admin UI redesign and JavaScript modernization initiatives share most of their goals and meetings together. Until now, they have been considered separate initiatives even though the initiative teams work on a common roadmap.

Proposed resolution

Merge Admin UI redesign and JavaScript modernization initiatives a single initiative called "Admin UI & JavaScript modernization initiative" which would better communicate the connection between the initiatives. The new initiative includes initiative coordinators from both of the old initiatives.

Alter derived migration definition early in life

$
0
0

Problem/Motivation

While working on #2897114: Products migrated to both nodes and products, we discovered it would be awful nice to change the migration definition very early on in its life. Basically, the derived definition for a node migration needs to be changed to point to a destination of commerce product, instead of node. In more complicated use cases, we need to alter field and field instance config migrations to point to a product as well.

Some description of what a deriver is and why it is important:
Derivers are run when dynamically discovering and registering a plugin. It provides a way to provide a template of the configuration of the plugin. After the deriver runs (one time), it never gets executed again for that plugin. Deriver could also be called a generator.

This is important, because for migrations, we only want to modify the default template of the derived migration a single time. If the migration is run via the core migrate_drupal_ui, there is no difference. Because we never store the migration configuration for any later use. But if you are running a custom migration, this becomes important. Because the migration configuration gets altered every. single. time. the. migration. config. is. read.

Case in point: #2937366: alterations to migrations in commerce_migrate_ubercart_migration_plugins_alter() are too far-reaching
In this issue, a consumer of the commerce_migrate contrib module wants to alter the definition of the commerce migration that was created. But commerce_migrate only had the option of plugin_alter. The definition alters from commerce_migrate are too heavy handed. Because they run every single time. When really we only want the alter to run during discovery/derivation/generation. But there's no other option, so we do it any way.

More cases in point where this is blocking things are being daily added to contrib. Field collections and ECK would all like to use this. Commerce too. Anything that has a custom entity-like thing would benefit from this feature.

Proposed resolution

Add a base migration deriver class that allows us to change the generated/derived migration definitions.

Another question was hooks vs. events. Events are better DX because they are more testable. The main consumers of this alter event are envisioned to be contrib modules. These consumers already know how to write code. The majority prefer to write OO. And they want to be able to run unit and other types of tests. Using an event, testing is easier than using a hook.

Remaining tasks

  • Code it
  • Test and review it.
  • Change Record (link to detailed steps on how to create one).

User interface changes

n/a

API changes

Adds an event and a test for subscribing to and builds a base derive for migration derivers (not to be confused with source, process or destination derivers).

Data model changes

n/a

d6_term_node_revision migration ignores a lot of items that it shouldn't

$
0
0

While working on a D6 -> D8 migration, I noticed that over 90% of the items for the d6_term_node_revision migration were being ignored, which seemed high. Using xdebug to trace the migration, I identified some specific items that were being ignored that I was pretty sure should be valid. I believe the issue is with the process specification in d6_term_node_revision.yml:

process:
  vid:
    -
      plugin: migration_lookup
      migration: d6_node
      source: vid
    -
      plugin: skip_on_empty
      method: row

It's trying to translate the node revision ID (which doesn't actually need translating (but might in the future)) as a means of ensuring that items for which the node doesn't exist are skipped (https://www.drupal.org/project/drupal/issues/2588945). However, it's specifying d6_node, meaning it looks in migrate_map_d6_node_[content_type], which maps node IDs, not revision IDs. Hence why about 6% of the items, in my case, are getting through - those are the ones that are lucky and happen to have a revision ID that's also a valid node ID.

I thought I could just change the migration parameter for migration_lookup in the above code to d6_node_revision, but that results in all items being ignored (because the migration plugin manager is finding no instances for that migration ID in migration lookup's transform function), so I seem to still be missing a piece of the puzzle.

Prefix Nightwatch commands with a "drupal" namespace

$
0
0

Problem/Motivation

Nightwatch commands that come in from different places (i.e. Nightwatch core commands, commands provided by Drupal core, commands from modules etc) could potentially conflict if they have the same name.

Proposed resolution

Prefix all our commands with "drupal" e.g. relativeURL -> drupalRelativeURL

Option for 'Transform dashes in URL to spaces in term name filter values' on term arguments doesn't affect the query

$
0
0

The term name argument validator has an option to convert dashes to spaces in the argument value, which means that you can have a URL like 'myview/term-name-with-spaces'.

The argument validator handles this correctly, but the query that is run with this by the term name argument is incorrect. With a simple view of article nodes and the tags field that comes OOTB with core, I get this clause in the query:

WHERE (( (taxonomy_term_field_data_node__field_tags.name = 'has-spaces') )AND(( (node_field_data.status = '1') )))
ORDER BY node_field_data_created DESC

Argument validator plugins only return a boolean from validateArgument(), but on D7 the equivalent function views_plugin_argument_validate_taxonomy_term::validate_argument() doctored the argument value on the argument handler like this:

        if ($term && (empty($vocabularies) || !empty($vocabularies[$term->machine_name]))) {
          if ($type == 'convert') {
            $this->argument->argument = $term->tid;
          }

There doesn't seem to be any provision for this in D8 -- argument validator plugins don't seem to be able to influence the argument value that the rest of the view uses.

Add a validation constraint to check if an entity has field(s)

$
0
0

Problem/Motivation

In order to implement the idea in #2976148-5: LayoutBuilderEntityViewDisplay::getRuntimeSections() does not delegate to plugins, it needs to be possible to validate an entity context by checking if it has a specific field, or fields, attached to it.

Proposed resolution

Create a new EntityField validation constraint, which checks if a fieldable entity has certain field(s) attached.

Remaining tasks

Write the patch, write tests, review, commit.

User interface changes

None.

API changes

A new validation constraint will be added to Drupal core.

Data model changes

None.

node_access filters out accessible nodes when node is left joined

$
0
0

Updated: Comment #334

Problem/Motivation

Currently, when a node table is left joined into a query, adding a node_access tag to the query filters out accessible rows from the base table (effectively acting more like an inner join). In particular, rows containing null values are incorrectly filtered out by node_access (i.e., if the base table has null entries for the node ID, node_access denies access to all users based on those null values, even though they should have no relevance to node_access checks). The most common example is a view where rows disappear from the table after adding an optional relationship to the view.

See the tests in patch #326 to reproduce, or more manually in D7:
1. Install Entityreference and Views,
2. Create a field referencing nodes (using entityreference),
3. Create a node having the entityreference field empty,
4. Create a View with a relationship using the entityreference field. Do NOT select "Require this relationship".
5. Expected result is that regular users can see the node in the View. Current result is that regular users cannot see the node.

Proposed resolution

The problems can be fixed by altering how the node_access conditions are added into the query whenever the node table is a joined table. Currently the conditions are added to the overall query conditions; the proposal is to instead add the node_access conditions into the join conditions.

This approach maintains the integrity of the node_access checks: all nodes to which the current user is denied access are removed from the query results. However, it makes as few additional changes as possible to the query results.

The primary effect is that rows containing optional, empty (null node ID) entries are no longer removed. Furthermore, if rows contain optional (left-joined) content from an access-denied node, only the content of the denied node is removed from the results. In the context of a view, this means that any individual cells of a table containing restricted content will be blanked, but non-restricted content in the rest of the row is still visible to the user.

Adding the node_access conditions into the join conditions is made more difficult by limitations of the database API: #2275519: Unable to use Condition objects with joins. The current patch has opted to add this missing feature to the database API, instead of implementing more complex code that tries to work around the limitation.

Both D8 (#326) and D7 (#332) patches implementing this approach have been provided.

Remaining tasks

  1. Patch needs to be reviewed by the community. Earlier patches (in particular D7) were extensively reviewed, but more feedback on the current patch is needed. Some specific recent questions include:
    1. Is the current patch, which avoids an API change, preferable (see #321)?
    2. Is it appropriate for a bug-fix patch to incorporate code for a requested feature (see #319)?
    3. Are there use cases that cannot be handled by patch #326, and would instead require patch #302? (See also Detailed Example)
  2. Write tests.(Patch #326 contains comprehensive tests, including nested joins and all combinations of accessible and restricted content.)
  3. In Postgres with 3 node tables and a count query, placeholders are getting inserted in the wrong sequence.(This was an issue for patch #149 but was reported as fixed by a subsequent patch. The current D8 patch doesn't edit the placeholders, and has been tested successfully using PostgreSQL.)
  4. Address issue of node access with a type of "entity" -- no known cases where this bug is triggered, recommend creating new issue.(The entity-specific query alterations have been removed in D8, making the issue no longer relevant.

User interface changes

None

API changes

None

Data model changes

None

Detailed example

As an example, a site has 'page' nodes containing a field that is a reference to a related 'article' node. A view is created to list the page nodes: the page title is shown in the first column; the related article's title is shown in the second column (using an optional relationship). The following is the view as seen by an admin. Any node with 'public' in the title is visible to everyone; any node with 'private' in the title should not be visible to regular users.

Case A: admin view
Page titleArticle title
Public-page-1Public-article-a
Public-page-2[none]
Public-page-3Private-article-b
Private-page-4Private-article-c


With current code, the table shown to non-admins incorrectly removes some rows containing public pages:

Case B: public view, unpatched
Page titleArticle title
Public-page-1Public-article-a


With patch #326, regular users will see:

Case C: public view, patched
Page titleArticle title
Public-page-1Public-article-a
Public-page-2[none]
Public-page-3[none]

All private pages and private articles have been filtered out. Public-page-3 is still displayed because it is public content; the reference to private-article-b is in an optional column, implying that unavailable content should result in a blank cell instead of removing the entire row.

Some users may prefer to construct a view where the entire row is removed if it contains a reference to an inaccessible article. In many cases, such views will simply want to change the article column into a required column. If, however, it is necessary to keep rows with missing articles, and only filter rows with inaccessible articles, users can add the appropriate filter into the view, for example, "where article_title is null AND article_reference is not null". This would produce:

Case D: public view, alternate
Page titleArticle title
Public-page-1Public-article-a
Public-page-2[none]

Note that one proposed patch, patch #302, uses a different approach that directly produces Case D, without the need for additional filters. However, using patch #302 it is impossible to produce Case C (except by gutting the node_access checks). In other words, patch #326 can be used to handle all reported use cases, but patch #302 cannot.

Original report by [username]

I'm loving the Entity Reference module, but I've come across some weird behavior. It's probably just something I've missed setting.

I have a content type called Album. I've got another content type called Review which has an entity reference to Album.

I've created a View which lists Albums. I wanted to include some fields from my Review content type, but I still want to list each Album, even if a review referencing the album has not been created yet.

In my view, under Relationships, I add an "Entity Reference: Referencing entity" relationship. I make sure "Require this relationship" is NOT checked.

When I'm logged in as an administrator, all Albums are returned, as expected. But when I'm not logged in, or I'm logged in as a regular user, only albums that are referenced by a review are displayed. I'm really puzzled as to why I get different results depending on my user role.

I get the same results regardless of if I add fields from the Review content type or not. I've tried clearing the cache multiple times, and I've tried checking and unchecking the "Require this relationship" box. I've deleted the relationship and tried adding it again, but I always get the same results.


Add support to migrate multilingual revisions

$
0
0

Problem/Motivation

First, a quick tip of the hat to a certain legendary core developer, who shall here remain nameless, for discovering this problem.

Migrate includes an EntityRevision destination, which can migrate data into specific revisions of entities. Because EntityRevision inherits from the EntityContentBase destination, it also supports migrating data into specific translations of specific revisions of entities.

However, there is a critical hole in that functionality: the migrated translation data is keyed only by revision ID, and not by langcode. This can potentially result in data loss -- one language's data being overwritten with data intended for another language. Uh-oh!

It also means that it is impossible to look up the source identifier by destination revision ID and language, since the langcode was not part of the destination identifier.

Proposed resolution

EntityRevision needs to allow migrated data to be keyed by langcode in addition to revision ID.

Remaining tasks

  • Write a patch
  • Review it
  • Improve it
  • Commit it
  • Breathe a big fat sigh of relief

User interface changes

None.

API changes

Nothing user- or developer-facing.

Data model changes

Nothing user- or developer-facing.

Entity query condition count seems off

$
0
0

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21...

The documentation here says that "The size of the conditional is the size of its conditional array minus one, because one element is the conjunction." After getting some unexpected results though I stepped through the code and found that the conjunction is not in the conditions array that the count function is going through (please see screenshot).

As such to get the expected results we had to use the conditions() function to get the array of conditions and pass them through count() ourselves.

Show the Revisions tab/page even when only one revision exists.

$
0
0

_node_revision_access() hides the revisions tab if there's only one revision of a node. pwolanin mentioned at Drupalcon that this had been flagged as confusing (not sure who by so this is a bit anecdotal but it doesn't surprise me) - sometimes the tab is there, sometimes it's not. The page works fine if there's only one revision - just lists a single revision, and that way you know that revisions are enabled / that you have access to them etc.

It also saves us a COUNT() query on the node table when viewing nodes.
screenshot_022.png

No aggregate handling in SortPlugin base

$
0
0

Forgive me if I'm mistaken but this feature seems quite important.
I want to sort my view with an aggregate field and it doesn't work;
Currently Drupal\views\Plugin\views\sort/SortPluginBase::query says

  public function query() {
    $this->ensureMyTable();
    $this->query->addOrderBy($this->tableAlias, $this->realField, $this->options['order']);
  }

Meanwhile over in Drupal\views\Plugin\views\field/FieldPluginBase::query we see that the aggregation function name is transposed from the handler options to the query.

  public function query() {
    $this->ensureMyTable();
    $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : [];
    $this->field_alias = $this->query->addField($this->tableAlias, $this->realField, NULL, $params);
    $this->addAdditionalFields();
  }

Further more, when I adjust the first function accordingly, my sort function works as expected.

  public function query() {
    $this->ensureMyTable();
    $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : [];
    $this->query->addOrderBy($this->tableAlias, $this->realField, $this->options['order'] ,'test_alias', $params);
  }

Is it possible that this feature has been overlooked?

Figure out a way to render fields on top level in templates

$
0
0

Would be nice to be able to:

{{ content.field_name }}

When a node is controlled by lb

Viewing all 291828 articles
Browse latest View live


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