Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.x]: Conditionals for relational fields doesn't work across sites #14989

Closed
mmikkel opened this issue May 14, 2024 · 7 comments
Closed

[5.x]: Conditionals for relational fields doesn't work across sites #14989

mmikkel opened this issue May 14, 2024 · 7 comments
Assignees
Labels

Comments

@mmikkel
Copy link
Contributor

mmikkel commented May 14, 2024

What happened?

Description

Relational field conditionals do not work as expected in cases where the relational field contains elements that doesn't exist in the current/active site (i.e. the site for the element being edited).

In the screencast below, I have added an entries field with the "Show site menu" setting checked, and a field layout UI element with an entry condition [Entries Field] is empty. I have two sites, and a section "News" that doesn't propagate.

First, I add an entry to the "Entries Field" field from the same site as the current entry. The UI element disappears, as expected.

Then, I remove the same-site entry, and select a different entry from another site (this entry does not exist in the site for the entry being edited). At this point, the UI element doesn't disappear as expected; I assume because the entries field is still considered "empty" as it has no relations to elements that exists in the site for the entry being edited.

CleanShot.2024-05-14.at.14.48.51.mp4

Steps to reproduce

  1. Create two sites, and a section that doesn't propagate across sites
  2. Create an entries field. Check the "Show site menu" setting
  3. Add the entries field to a field layout, along with a different field layout element (a custom field or UI element). Create an Entry Condition conditional "(entries field) is empty" for the latter.
  4. Edit an entry in one of the site, and select an entry in the entries field that doesn't exist in the site for the entry being edited.

Expected behavior

Relational field conditionals should work regardless of related elements existing in the current entry's site or not.

Actual behavior

Relational field conditionals seem to disregard related elements that do not exist in the site for the element being edited.

Craft CMS version

5.1.2

PHP version

No response

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions

None

@mmikkel mmikkel added the bug label May 14, 2024
@i-just i-just self-assigned this May 14, 2024
@brandonkelly
Copy link
Member

brandonkelly commented May 14, 2024

The current behavior is consistent with relational fields’ handling of :empty:/:notempty: element query params, as well as the default results you would get when looping through entry.myRelationField (without overriding the site/siteId param on the relation query).

In each case, only relations that exist in the field’s target site will be factored in/queried by default.

If you are always relating entries that only exist in one specific site, you can enable your Entries field’s “Relate entries from a specific site?” setting (under “Advanced”) and select that site. Then your field conditions will work as expected regardless of which site is selected.

Otherwise, we might have to consider adding a new relation field setting, that would be the equivalent of setting .site('*').unique() on its relation queries.

@brandonkelly
Copy link
Member

Multi-site aside, the same “bug” would also exist if you only related entries which are disabled.

  • entry.myRelationField would yield zero results unless you passed .status(null).
  • Passing :notempty: to the field’s element query param when querying for source elements would similarly cause the source element to be filtered out.
  • Therefore, condition rules for the field would also treat the field as empty.

Maybe it makes sense for condition rules to start differing from the :empty;/:notempty: param behavior, since conditions are part of the UI, and relation fields’ UI will always display relations, regardless of status or site…

@mmikkel
Copy link
Contributor Author

mmikkel commented May 14, 2024

The current behavior is consistent with relational fields’ handling of :empty:/:notempty: element query params

Appreciate the clarification!

FTR, this cropped up in building out a larger, multi-site build, with multiple site groups (representing different "sub-brands"); each site group having multiple sites in different languages. Unfortunately relating entries to a specific site isn't feasible in a few spots.

No biggie, I can work around not having conditionals for these cross-site fields (it's just a minor bummer to not be able to use the new and shiny; this is inside a Matrix field btw).

...potentially though, would it be possible to hook into an event like ElementQuery::EVENT_AFTER_PREPARE, and set the necessary query params myself?

Not to go off on a complete tangent here 😅 but I'm actually doing something similar already, in order to have multi-site capable entries fields inside the CP prefer selected entries from sites with the same language as the requested site:

if (
    Craft::$app->getRequest()->getIsCpRequest() &&
    Craft::$app->getRequest()->getIsGet()
) {
    Event::on(
        EntryQuery::class,
        ElementQuery::EVENT_AFTER_PREPARE,
        static function (CancelableEvent $event) {
            $query = $event->sender;
            if (!$query instanceof EntryQuery || empty($query->preferSites) || !$requestedSite = Cp::requestedSite()) {
                return;
            }
            $preferSites = array_unique([
                $requestedSite->id,
                ...array_column(Craft::$app->getSites()->getSitesByLanguage($requestedSite->language, true), 'id'),
                ...$query->preferSites,
            ]);
            $query->preferSites($preferSites);
        }
    );
}

Just for kicks I tried doing something similar with site('*') and unique(), but I couldn't make anything affect the conditional result.

(Btw, the above is a hack I hope is without any unfortunate side effects, because it's a big improvement in AX in the few spots where it makes a difference).

Multi-site aside, the same “bug” would also exist if you only related entries which are disabled.

Good to know. I think that behavior is more obvious compared to the multi-site caveat, and hence less of an issue – maybe aside from the fact that it's a little bit awkward how the "Max Relations" setting counts disabled elements, and the conditional rule doesn't 🙃

Maybe it makes sense for condition rules to start differing from the :empty;/:notempty: param behavior, since conditions are part of the UI, and relation fields’ UI will always display relations, regardless of status or site

I think that would make a lot of sense. As far as the CP goes, in general I don't think there's much point in aiming for parity with default element query behaviors on the front end, in cases where that means a less intuitive AX/DX inside the CP. Expected behavior or not, a field with selected, visible elements is arguably not "empty", regardless of which sites those elements happen to exist in or not 🙂

Anyways, maybe this should've been a FR after all. Pardon the wall of text!

@brandonkelly
Copy link
Member

Maybe it makes sense for condition rules to start differing from the :empty;/:notempty: param behavior, since conditions are part of the UI, and relation fields’ UI will always display relations, regardless of status or site

I think that would make a lot of sense. As far as the CP goes, in general I don't think there's much point in aiming for parity with default element query behaviors on the front end, in cases where that means a less intuitive AX/DX inside the CP. Expected behavior or not, a field with selected, visible elements is arguably not "empty", regardless of which sites those elements happen to exist in or not 🙂

Yeah, after sleeping on it, this felt like the right decision. Just made this change for Craft 4.10 and 5.2!

@mmikkel
Copy link
Contributor Author

mmikkel commented May 15, 2024

That’s awesome, thanks Brandon 🙌

@brandonkelly
Copy link
Member

Craft 4.10.0-beta.1 and 5.2.0-beta.1 are out with that change.

@rob-c-baker
Copy link

This might also fix #13927 - I'm doing some updates to get to the above version soon - I'll try to update the linked issue if I find out one way or another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants