freelock → created an issue.
Yikes, this is extremely confusing -- is the 2.x branch going to get deprecated? That's certainly the impression from the project page... is there an upgrade path from 2 to 3? Should anybody upgrade from 2 to 3?
I think the smarts incorporated in 2 are a big improvement over 1 -- if 3 is just about adding Drupal core compatibility I wonder why it didn't stay on the 1.x branch?
Almost seems like there should be two different modules.
Ok addressed the issues with the test failures.
Regarding removing from the buildEventData, seems like we should do that -- I was wondering if the annotations in the PHP attributes should be copied up to the getData ones? Specifically it has classes, and properties on the flaggings annotation -- are these correct, things we should add?
Not sure if this is the correct approach -- but it's working at least for getting "entity" passed. I'm not seeing "flag" or "flagging" showing up in the logs -- however, using [flag:name] did appear to resolve and work correctly.
I did try wrapping these in DataTransferObject::create(), but that did not work.
This does appear to fix my models?
Looks like in https://git.drupalcode.org/project/eca_flag/-/commit/8ba776511c935bb0032... , the tokens used to be defined in a BeforeInitialExecutionEvent hook, which added them directly to the token service -- this code got removed/moved into a BuildEventData() method on the event plugin.
I'm not exactly sure how this is supposed to be different -- do we need to add a getData() method, and return a DTO for the request key?
freelock → created an issue.
Just applied to another site... changes look and work fine to me!
FWIW, Reroute Email uses this pattern, as do a bunch of commerce module -- a global "enable" config that can act as a kill switch. It's a really handy pattern.
Config Split introduces a ton of complexity and confusion to managing configuration -- which means opportunities to make mistakes. We highly prefer a global config with specific environment overrides -- this allows us to have sane settings in the database for all dev environments, and hard-code specific overrides for production in a production-specific environment file.
Even better is being able to set these with environment variables, but that's an entirely different topic...
The only concern that comes to mind, if the exception is not temporary but permanent, e.g. due to a misconfigured ECA model, then the item remains in the queue forever, and we don't have any mechanism, to clean up such an issue. Should there be something that controls the max number of retries?
Hmm there are existing mechanisms for clearing out the queue -- drush, queue ui module.
Are the exception classes that were already being rethrown indicate things that we should pass along as is, instead of using a requeue exception?
I do think another consideration might be whether the user/developer considers the queue to be a reliable one or not -- if it's reliable, we need to make sure items get requeued regardless of what else happens... if not, it's not as big a deal to absorb the exception and continue.
We're often using queues so that API calls to remote services are reliable on otherwise unreliable connections (or unreliable services).
See https://www.php.net/manual/en/function.unserialize.php - after recreating the object, the __wakeup or __unserialize method on the object is called, if one exists.
Hi,
First cut at a fix for this -- it turns out that if we use a try/catch block on the event plugin, it never catches an exception because the EcaAction object catches it first.
Not wanting to hard-code a list of events to bypass exception handling, I was looking at the plugin tags to see if we could leverage that, not something I see implemented anywhere other than just tags on events.
So I ended up extending the Event plugin interface and base class with a new method, "handleExceptions", which the EcaAction can use to determine whether or not to rethrow exceptions.
For now I picked the DelayedRequeueException with a 10 minute delay -- this could certainly get more configurable with other exception types and more handling, but this solves what I need for a few different sites already.
Does this seem like an appropriate solution? Are there event plugins that do not extend the EventBase class?
I think it does fix queue processing to be reliable, at least more so than ECA does today.
Cheers,
John
Removing myself from assigned -- the site in question is now on 2.x.
Ok that should at least not break anything else...
Took a look at the other two classes in the chunk of code related to the fix.
Looks like the "FilterVariationsEvent" class does use getVariations() -- the other two classes use getProductVariation().
Fixed in MR........
freelock → created an issue.
Fix for product variation method name. I have not checked that the method name is the same in the other event classes -- this might need more work if the method name varies depending on which event class is used...
freelock → created an issue.
Sorry to mess up the branches -- I created two issue branchs, because the first one was against 1.x, not 2.x. So I created the second one.
It looks like @lukas_w added to the 1.x branch -- but it also looks like the same code is present already on 2.x, presumably for 📌 Add support for cache collector for state in core Active .
So I un-hid the branch with the fix, this looks like just be a backport of the other issue.
freelock → changed the visibility of the branch 3460404-event-eca-cron to active.
Note that this was introduced in the 2.x branch, does not affect 1.x.
MR created.
freelock → created an issue.
freelock → changed the visibility of the branch 3460404-event-eca-cron to hidden.
Can confirm it's an issue with jobs starting with cron. I'm seeing 📌 Add support for cache collector for state in core Active , which I initially thought might mean it's fixed in 2.0? But this looks like only affects eca_state plugins, which I'm not using in the affected module.
This is causing major issues on one of our sites -- I'll be figuring out a fix shortly (if changes in 2.x didn't fix it already).
MR contains my patch for allowing this config to get upgraded.
freelock → created an issue.
Setting to NR.
Hi,
I just ran into this issue on a site -- the Structure, Configuration, and Reports menu items were all gone from the admin toolbar, making it difficult to administer the site. This happened on all our site copies after updating to 10.3.0.
I went through in a debugger and found that it was checking the menu items to see if they were enabled, and if they were not, it was throwing an access denied (403) error.
Turns out this site had a bunch of unpublished menu items in the admin menu, which duplicated the ones that actually had children -- and the check was failing on these unpublished menu items.
I'm not sure if this is the right behavior -- seems like in some cases this could block admin access to unpublished pages. But the fix for this particular site was simple -- just delete the inactive duplicate menu links, and then suddenly the admin items reappeared. I think this is the fix for what everybody on this thread is seeing -- if you have an inactive logout link, that might make the logout link invisible on other menus...
Updated patch for 10.3.0.
Hi,
Was just going through this module -- we have an automatic importer that creates an event every day -- but also a "restrictions" system that allows admins to create date restrictions. We were trying to hook this up using ECA to find events that already exist when a restriction is added, close registrations for that event, and notify the admin if there were any existing registrations. And found this just about impossible!
I added our previous code from ✨ Integrate with Rules module including host entity methods Active -- but that gets you a token for registration_settings (host entity) from a registration, NOT from the entity that the host entity is attached to. So I dug in trying to find how to get a host entity/registration settings from a node it's attached to --only to find it doesn't exist until somebody registers or changes the settings. Am I understanding this correctly?
If so, I'm thinking this is something we need -- a method added to the RegistrationManager that fetches an existing registration_settings entity if it exists, or creates it from the entity type/field settings if it doesn't. I'm thinking if this is added as a service, it can be maintained through whatever changes come from ✨ Allow admins to change host entity for existing registration Active and ✨ Establish host variations as an architectural concept Active , and would be generally useful for anyone trying to integrate this from other modules.
And then add an ECA action plugin that calls it to load a RegistrationSettings entity that could then be interacted with using normal content entity conditions/actions.
Are there other scenarios that need to be considered? I'm thinking what we're talking about would be
- Action: Load Registration Settings from Entity -- I guess this could also just be a token, [node:registration_settings] - or [node:field_registrations:entity] or whatever makes the most sense.
- Token: [registration:host_entity] - entity that a registration is associated with
- Token: [registration:registration_settings] - registration settings entity associated with a registration
There could certainly be other convenience actions and conditions, but really all that's required at a baseline are making some tokens work...
Thoughts?
freelock → created an issue.
We created this plugin for a client, and have had it in production for a year now!
namespace Drupal\qcyc_roster\Plugin\Action;
use Drupal\Component\Utility\DiffArray;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\eca\Plugin\Action\ConfigurableActionBase;
/**
* Provides a Load Diffs action.
*
* @Action(
* id = "qcyc_roster_load_diffs",
* label = @Translation("Load Diffs"),
* description = @Translation("Compare 2 entities and return a list of fields that differ"),
* type = "entity"
* )
*
*/
class LoadDiffs extends ConfigurableActionBase {
/**
* {@inheritDoc}
*/
public function defaultConfiguration(): array
{
return [
'token_name' => '',
'compare' => null,
'return_values' => FALSE,
'exclude_fields' => [],
'include_fields' => [],
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$form['token_name'] = [
'#type' => 'textfield',
'#title' => $this->t('Name of token'),
'#default_value' => $this->configuration['token_name'],
'#description' => $this->t('Provide the name of a token that holds the new list.'),
'#weight' => -60,
];
$form['compare'] = [
'#type' => 'textfield',
'#title' => $this->t('Compare'),
'#description' => $this->t('Provide the name of a token that holds the original entity.'),
'#default_value' => $this->configuration['compare'],
'#weight' => 30,
];
$form['return_values'] = [
'#type' => 'checkbox',
'#title' => $this->t('Return values'),
'#default_value' => $this->configuration['return_values'],
'#description' => $this->t('If checked, the list will return values. If unchecked, it will only return the different machine names of changed fields.'),
];
$form['exclude_fields'] = [
'#type' => 'textarea',
'#title' => 'Exclude fields',
'#description' => $this->t('List field machine names to remove from difference/ignore'),
'#default_value' => implode("\n", $this->configuration['exclude_fields']),
'#weight' => 40,
];
$form['include_fields'] = [
'#type' => 'textarea',
'#title' => 'Include fields',
'#description' => $this->t('List field machine names to include in difference -- all others will be ignored.'),
'#default_value' => implode("\n", $this->configuration['include_fields']),
'#weight' => 40,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void
{
$this->configuration['token_name'] = $form_state->getValue('token_name');
$this->configuration['compare'] = $form_state->getValue('compare');
$this->configuration['return_values'] = $form_state->getValue('return_values');
$this->configuration['exclude_fields'] = explode("\n", $form_state->getValue('exclude_fields'));
$this->configuration['include_fields'] = explode("\n", $form_state->getValue('include_fields'));
parent::submitConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
/** @var ContentEntityInterface $object */
$access = $object->access('view', $account, TRUE);
return $return_as_object ? $access : $access->isAllowed();
}
/**
* {@inheritdoc}
*/
public function execute($entity = NULL) {
$compare = $this->tokenServices->getTokenData($this->configuration['compare']);
$diff = DiffArray::diffAssocRecursive($entity->toArray(), $compare->toArray());
$exclude_fields = $this->configuration['exclude_fields'];
if (count($exclude_fields)) {
foreach ($exclude_fields as $field) {
unset($diff[$field]);
}
}
$include_fields = $this->configuration['include_fields'];
if (count($include_fields)) {
$included = [];
foreach ($include_fields as $field) {
if (isset ($diff[$field])) {
$included[$field] = $diff[$field];
}
}
$diff = $included;
}
if (!$this->configuration['return_values']) {
$diff = array_keys($diff);
}
$this->tokenServices->addTokenData($this->configuration['token_name'], $diff);
}
}
freelock → created an issue.
freelock → made their first commit to this issue’s fork.
freelock → created an issue.
My comment in #15 turned out to actually be a bug in Smart Date module, which is fixed in their version 4.1.0.
freelock → created an issue.
I think what you're looking for is not block "access", but rather a "condition" plugin. This section of the manage block display shows core condition plugins that control block visibility.
As I understand it, we could implement entity access for "content_block" entities that might allow you to show/hide blocks anywhere they appear -- but this would only apply to content_block entities, not any other type of block, or custom block plugins, or anything else.
To control whether or not a block appears on a particular page, there are several different ways of showing blocks -- the core block system (which uses condition plugins), Layout Builder (which currently doesn't have any way to add conditions), Context, Display Suite, Panels, Twig Tweak, Ctools... Each of these has its own way of controlling whether or not to show a block.
So maybe I'm conflating things here, but to me having a module enabled/disabled is not a feature flag.
When I'm thinking of feature flags, I'm thinking of this: https://launchdarkly.com/blog/what-are-feature-flags/ ... specifically NOT config. Disabling a module is a config change, it's not a feature flag that can be done for some users and not others.
I think for 📌 Replace "Expose all fields as blocks to Layout Builder" configuration with feature flag Active having a module to enable/disable functionality seems like a reasonable approach -- but can we please not call it a feature flag? If we do, we're going to confuse a whole lotta devops folks that have an entirely different definition, when they need to work with Drupal.
Great to hear this is working!
I subscribed to this case looking for more modern CSS support than was available in wkhtmltopdf, and thought WeasyPrint might be a good option. However, since then we've started using headless Chrome, which has fairly decent PDF support.
And there is now an entity_print_chrome module → , which has basic functionality working, with the chrome_pdf library.
So now I'm wondering: Should WeasyPrint go into another module, and this module just needs some pointers to the other entity print plugins available?
Or should entity_print_chrome get pulled into this module as a submodule?
I think the big issue here is discoverability -- it took quite some digging to find entity_print_chrome, and I think it should have more visibility, along with WeasyPrint.
If Weasyprint is added to the existing module, will anyone notice and discover it? I'm thinking it will be more noticeable on the project page for entity print...
I did find myself needing a new feature flag just this week -- for a decoupled website that is getting a design refresh on the front end. I implemented it as a custom condition that I applied to two different blocks, each associated with a different library getting sent to the browser.
The new front end in this case depends upon new fields we needed to deploy so the site owners could populate content and preview it before going live.
So it does seem like there are 3 parts to making a feature flag work:
1. A service that indicates whether a particular feature flag is active or not
2. Code that is controlled by a specific feature flag -- a condition plugin makes this easy ,to show or hide a block, to enable/disable something, etc
3. Mechanisms for enabling/disabling a feature flag.
For #3, having something that can be enabled/disabled as an anonymous user is crucial for the scenarios I've been doing so far. I ended up using a query argument to toggle a feature on or off, and then set a cookie to persist this status across requests.
I think this is an important scenario, to allow testing in production.
Also need to have ways to toggle feature flags per user, per role, site-wide, and perhaps to log places in code where each flag is used, so the code can be cleaned up when the feature is live for everyone if desired...
The patch is currently working for many tokens, but I have one scenario we need still broken -- trying to get a particular date format on a Smart Date. Haven't had a chance to circle back to fix that.
Otherwise I think it still needs help for non-string props -- I'm wondering if we should attempt to automatically cast whatever is in Fixed Values to a numeric or boolean type? This might be a different issue...
Cheers,
John
Hi,
I have a different scenario we've started implementing just in the browser -- feature-flags that can be enabled in the browser with a GET param.
We've done this so far for two features:
- Enabling a "control" for toggling dark mode and growing/shrinking text
- Disabling a headless widget so we can more easily test a fallback experience
To do this, I just added some JS at the top of the page to look for a particular query param, and if found/set, store in the browser LocalStorage. Also a remove value. Then, if the localstorage value is enabled, apply a class or do something different in the JS bootstrapping of the widget.
So I was thinking of generalizing this, and found this issue.
Main point: I think there are different scopes to consider for feature flags, and obviously these have different implementations for the developers -- and I wanted to add this browser scope to the list. I'm thinking the base scopes here should include:
- Site-wide -- config and/or state to enable site-wide
- User -- user can enable a feature individually
- Some sort of plugin along the lines of @jurgenhaas mentions, that might be activated through ECA or similar -- which could be extended to support individual groups, roles, etc
- Browser - sessionless -- this can only work client-side, because otherwise it would have an impact on caching
- Browser - cookie/session-based
... a "feature flag" at its base would be one of these types, with a service making it easy to check if a feature is active, and perhaps a lightweight Javascript version for client-side flags.
Then, the feature flag system could provide plugins for reacting to flags -- condition plugins for use in blocks, something to wrap the Javascript attach() behavior, a default CSS class to apply to the body if a feature is active, an ECA condition (not in core, obviously, but if there's a plugin that could be provided)...
Just spit-balling here, expanding the scope slightly, perhaps in a direction that could go in contrib for part of...
Is this relevant?
We also see this on a site with > 50K links. Sometimes it generates 3 sitemap pages with exactly 10K links each, sometimes 2, sometimes none. When run manually from drush, it generates 6 pages, the first 5 10K links and the remainder on the 6th. But doing this today took 1 hour 24 minutes to complete...
We might try the workaround suggested -- disabling the cron generation and adding our own drush cron job... or give simple_sitemap a try.
I've spent about 10 hours on this in the past couple days, and I don't think it's possible with the current entity types.
I got quite far down this path -- I did manage to get the field ui showing up on individual group menus, content saving, and more -- which took patches all over the place, all in menu_item_extras.
However, the final thing needed involves loading the bundle from the menu_link_content entity -- and I'm hitting a hard blocker here. Each entity type can define a single "Bundle Entity Type." This gets stored in the entity type definitions, and looked up directly in \Drupal\Core\Entity\EntityType->getBundleEntityType() -- and I don't see any way to override this to allow either "menu" or "group_content_menu" (or anything else) -- menu_item_extras sets this to "menu" in menu_item_extras_entity_type_build(), which stores it in the entity type definition -- and there's nowhere to change it before it gets loaded.
If I remove the bundle_entity_type and add a provider instead, it doesn't load the bundle-specific field configs at all.
So this looks like a hard blocker to making this work at all -- if the menu_link_content could set a bundle_entity_type to one of the entities in this module, I think the rest would fall into place -- but you can't get there from here! At least not with that entity type.
I'm thinking the "correct" solution is to have group_content_menu module define its own menu_link_content entity -- can probably extend the original from core, and set the bundle entity type to the group_content_menu_type -- which would be far better than what I have, trying to jam it onto individual group_content_menus -- I don't see a reason the group_content_menu should be fieldable, I think it makes a lot more sense for the existing field_ui on the group_content_menu_type to apply to its menu_links, not the menu itself.
Fix pushed.
The original code was checking for an empty value, and replacing with the token name if it is empty. There are clearly values that evaluate to empty that should be posted.
After that, it assumes the value can be evaluated as a string. I'm not sure what other types are being checked here -- if it wasn't a string, then this code wouldn't function at all, unless the substituted value was null, an empty array, or an object that somehow evaluates to empty.
I changed this check to simply check for null. Is there another scenario that needs to be tested here?
freelock → created an issue.
Took the code from @e0ipso's link, for recursive token replacement.
I have this working with fixed_value props -- I did have an issue destructuring the output of the token replacement where my scenario used it, so I think there might be another spot or two where this needs to get fixed as well (the token replacement was wrapped with an extra array).
Still in progress, but partially working...
I don't understand at this point what the data types for each SDC parameter types are allowed to be -- I patched this as an experiment to see if I could get it to work -- and it does work fine for strings.
I've had a tough time finding any documentation for the SDC interface -- but got errors when declaring a prop as a number so I just changed everything to be a string (aside from the slots).
I've gone through the documentation in this section: https://www.drupal.org/docs/develop/theming-drupal/using-single-director... → ... but there's nothing there describing how to use the various prop types, or examples of how to use these effectively...
Is there a good resource describing these types?
`drush generate sdc` prompts for properties and lets you pick among these types:
- String
- Number
- Boolean
- Array
- Object
- Always Null
... I'm thinking if we can detect the prop type here, we can then do some casting (for numeric types) or wrapping (e.g. for array, if the resolved token is a string)
(not sure why there would be an "Always Null" prop -- should this ignore anything assigned, or throw an exception?)
Merging in for further review and testing, thanks for your work on this!
Creating a new major version, since Drupal 9 is no longer supported with this change.
freelock → created an issue.
Hi,
Does this change require Drupal 10 only? I see you've removed the 8 and 9 compatibility from the info file...
Cheers,
John
Maybe something to add to ECA Commerce → ?
Hi,
I solved this problem a few years ago using an arbitrary field to hold the absolute stock level (synchronized from another system using an update migration we run every 15 minutes). I added a presave hook to add a stock level adjustment based on the difference between the stock level and my custom field:
/**
* Implements hook_ENTITY_TYPE_update().
*/
function mymodule_commerce_product_variation_presave(EntityInterface $entity) {
// Sync up stock level with last imported MAS stock level
/** @var \Drupal\commerce_stock\StockServiceManagerInterface $stockManager */
$stockManager = \Drupal::service('commerce_stock.service_manager');
$currentLevel = $stockManager->getStockLevel($entity);
if (round($currentLevel, 3) != round($entity->field_absolute_stock_level->value, 3)) {
$diff = $entity->field_absolute_stock_level->value - $currentLevel;
$entity->field_stock_level->setValue($diff);
}
}
Not sure whether this makes sense to turn into an ECA action...
freelock → created an issue.
Added the current entity type to the token browser, and expanded the token replacement to cover view modes -- previously it only applied on field formatters.
freelock → made their first commit to this issue’s fork.
Super stoked to see this committed!
@quietone @jwilson3 this issue is not strictly related to Views, though views is the easiest place to reproduce the issue.
It requires a query (or view) with a relationship to another table/entity where entity access of some kind is used to filter out rows. I've hit it most often with OG or Group module. In this scenario, the query filters out the wrong items -- usually hiding rows the user should be able to see.
Has anyone actually benchmarked performance regressions with this change? I'm not sure why that belongs in the change record -- using a node access module implies slower performance, but we use this on sites with tens of thousands of affected entities without anything being noticeably slow... I think the change record should focus on it returning correct results.
I've needed to add this patch to dozens of sites over the years...
@mmatsoo the previous patch may apply, but I don't think it actually works.
We have entirely moved over to Layout Builder Component Attributes for block classes within layouts (we still use Block Class with core block system placements).
On #3395068: Migration from block_class → , I've posted code we successfully used to update block_class usage inside all node and taxonomy term layout overrides. This doesn't update block_class usage on "manage display" pages (the templates) -- for those we just searched our config for usage of block_class, moved the classes from the block_class field to the manage attributes field, and then we could export the config. The update function is for content with layout overrides.
Hope that helps anyone else stuck on this!
Circling back to this, here's code we've used to successfully move block_class classes to layout_builder_component_attributes, for anyone who might need it, wired into hook_update_N() in a custom module install file:
/**
* Move block_class in custom layouts to layout_builder_custom_attributes.
*/
function mymodule_update_9035(&$sandbox) {
// we have both taxonomy term and node updates to do:
$query = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->getQuery();
$query->condition('layout_builder__layout', '%block_class%', 'LIKE')
->accessCheck(FALSE);
$results = $query->execute();
foreach ($results as $tid) {
$term = \Drupal\taxonomy\Entity\Term::load($tid);
_cgrace_site_bc_to_lbca($term);
}
// Now nodes
$query = \Drupal::entityTypeManager()->getStorage('node')->getQuery();
$query->condition('layout_builder__layout', '%block_class%', 'LIKE')
->accessCheck(FALSE);
$results = $query->execute();
foreach ($results as $nid) {
$node = \Drupal\node\Entity\Node::load($nid);
_mymodule_bc_to_lbca($node);
}
}
function _mymodule_bc_to_lbca(\Drupal\Core\Entity\ContentEntityInterface $entity) {
$changed = FALSE;
foreach($entity->layout_builder__layout as $delta => $item) {
/** @var \Drupal\layout_builder\Section $section */
$section = $item->section;
$array = $section->toArray();
foreach ($section->getComponents() as $uuid => $component) {
$classes = $component->getThirdPartySetting('block_class', 'classes');
if ($classes) {
$additional_settings = [
'block_attributes' => [
'id' => '',
'class' => $classes,
'style' => '',
'data' => '',
],
'block_title_attributes' => [
'id' => '',
'class' => '',
'style' => '',
'data' => '',
],
'block_content_attributes' => [
'id' => '',
'class' => '',
'style' => '',
'data' => '',
],
];
$component->set('component_attributes', $additional_settings);
$component->unsetThirdPartySetting('block_class', 'classes');
$changed = TRUE;
}
}
}
if ($changed) {
$entity->save();
$message = t('Migrated block class on %type - %id',[
'%type' => $entity->getEntityTypeId(),
'%bundle' => $entity->bundle(),
'%id' => $entity->id(),
]);
\Drupal::messenger()->addMessage($message);
\Drupal::logger('cgrace')->notice($message);
}
}
freelock → created an issue.
I was looking into this for a few annoying instances in our sites, and am not finding PHP differences. I'm thinking perhaps database differences? SELECTs with no ORDER BY...
We most often hit this issue on text format filters and static menu overrides. Today I'm seeing it on an entity_view_display layout builder settings.
> FYI: Herodevs is offering "never ending support" as a vendor . They will be forking the Drupal 7 codebase, providing security vulnerability coverage , compatibility support and have a reporting system.
Huh. Isn't this exactly what Backdrop is?
@klausi
> How do I turn this issue around? I could use some support and positive interaction now, anyone still listening that is supportive of the initiative and wants to leave a comment?
... I'm entirely onboard with your initiative. I'm not a huge fan of D7, but we have a dozen D7 sites we are still supporting, and may get more clients going forward with some of our marketing initiatives -- we're committed to supporting the actual modules our customers are using and still need, until we've moved them off to another platform -- Backdrop, WordPress, or hopefully Drupal 10/11.
I would be interested in participating/helping out with this initiative, as long as we continue to have Drupal 7 clients. We're down to 11 at the moment, but may pick up some new ones.
Two core action plugins and one ECA condition plugin are pushed to this issue's fork:
- Action: Add Item to subqueue
- Action: Remove item from subqueue
- ECA Condition: Entity is in subqueue
... I implemented them for a customer's site, and they are working in ECA just fine for us now!
Note that you do need to know the subqueue ID to make use of them (I found it in the database, in entity_subqueue_field_data.queue)
Cheers,
John
Hi,
Came here looking for ECA plugins to add/remove items from a subqueue... hopefully nobody minds me hijacking the issue....
freelock → made their first commit to this issue’s fork.
Removing assigned.
Fixes committed, is working for us now in Drupal 10.1.
Still throwing an entityQuery missing accessCheck exception. Fix to come shortly.
Several places missing -- added to the issue fork fixes for the taxonomy_place_example submodule, a removed core function in the SettingsForm, and the composer.json core requirement.
freelock → made their first commit to this issue’s fork.
I would think it's fine to close this, I'm not hearing any substantive disagreements here...
To clarify, the one thing I would not want to see is adopting some big heavy framework that forces us all into a particular way of doing things -- e.g. React.
I'm all for webcomponents, single-directory components, Svelte and Vue and whatever other components people would like to build in -- I think most of these can coexist and/or complement each other. Let each module choose what's best for their needs -- generally more of this can be done using vanilla js and native browser functionality, keeping the JS layer lean and mean.
I do think there are many admin user stories that would benefit from a rich client layer, though, and I personally greatly prefer JSON:API or a simple JSON endpoint over Drupal's Ajax layer...
Ha, I've been promoting and using Vue.js for years as a much better, lighter, faster, easier alternative to React. But if there's one JS framework that I see as possibly better than Vue, it's Svelte.
I think React would be a mistake to put in core. If you want reasons, follow Alex Russell -- here's a representative post outlining why the proliferation of front-end frameworks is bad: https://infrequently.org/2023/02/the-market-for-lemons/ -- and see he lists both Svelte and Vue as having the right motivations of putting the end user's experience first, ahead of the developer experience.
Some clearer posts about why: https://thenewstack.io/too-much-javascript-why-the-frontend-needs-to-bui... , https://www.spicyweb.dev/the-great-gaslighting-of-the-js-age/ .
So that said, I would hope that SDCs would support using any of these libraries, and that modules can choose whatever front-end framework makes the most sense to them. That's how this all works, anyway -- the people doing the work make the choices. I'm all in favor of making it easy to make good choices here, and if there is support added for particular frameworks, that choice needs to support goals we all have -- making a great user experience, keep the performance high, stick as close to standards as practical, get wide testing and review before anything happens that might make it exclude other approaches...
Yes, it can be confusing, which syntax to use where. Mine would look like this:
Method: set only when empty
Strip tags: no
Trim: no
Field name: field_volledig_adres
Save entity: yes
Field value: [node:field_straatnaam:value] [node:field_huisnummer:value]
Entity: [node:content-type:locatie]
... if you had another token set to the correct entity you want to set field_volledig_adres on, you would use that without square brackets for Entity.
The token browser lets you see what tokens are available on each entity type -- but the first part of that token needs to be replaced with the actual token you want to operate on. Many events do create a "node" token for you -- almost all create an "entity" token plus a token with the entity type id.
I highly recommend reading https://ecaguide.org/eca/concepts/tokens/ , and the other docs there, it will help you come up to speed quickly...
freelock → created an issue.
freelock → created an issue.
@SirClickalot is the result you expect in the "main" views table, or in the "relationship" table?
From your results, I'm guessing that argument you're passing in is for the "main" table, and you're using the views relationship to get the related nodes.
If so, you should be able to flip this around -- make the main content type the ones you want to return, make the relationship go the other direction, and then in the argument handler, tell it to use the relationship. This should give ECA the related node instead of the original node...
What is the entity you want to set the field on?
field name: name of the field
entity: entity with that field
value: value to set
Thanks for the feedback, I'm quite familiar with Commerce.
I set up Commerce Registration as suggested, but I'm thinking this is entirely too much for this site -- they want as simple as possible of a signup -- a simple "select how many people", collect an email address and name for the registration, and send them a confirmation mail.
With Commerce Registration, it looks like you need to supply an email for each attendee, and it's a bunch more steps to first add one seating type and then the next -- and then go through a full commerce checkout to get confirmed.
I did start on this -- adding a config option to work like a "feature flag" to enable multiple registration fields on an entity. I think it would not be too hard to adjust for the scenario we are trying to build -- much of it related to the HostEntity becoming aware of multiple registration fields, and showing the unique info for each of them (we would only want to change the capacity, all other fields would be the same).
It looks like the registration table stores enough info to get the context, as long as each registration field is associated with a unique registration bundle.
That said, after talking with our client, they are going to make a decision on whether or not to move forward to this -- they might opt to keep things simple and just do a single registration type. So we're paused on this at the moment...
I'm looking at this now -- we have a project for reserving up to 4 slots per person, for a museum. They have 2 accessible seats (wheelchair) per showing, and 25 regular seats.
I'm thinking that most of the work involved looks like changes to the HostEntity wrapper -- creating the ability to manage multiple registration fields, each tied to a registration bundle. For this particular scenario, we want to put a limit on the combined total registered on a single registration, but have distinct capacity, etc.
Anybody have a good alternative to doing this?
freelock → created an issue.
Moving back to needs review...
On most of our newer sites, we've switched over to using Layout Builder Component Attributes → instead of applying this patch, and that works fine without requiring a core patch -- and does more than this, allowing you to specify id, data- attributes, inline styles on not just the block but also the wrapper and the title (if your theme injects the attributes correctly).
So we're now planning to convert our older sites that used this patch to use that module instead. I've opened an issue #3395068: Migration from block_class → there to provide an upgrade path using a custom Drush command, if anyone else is interested.
freelock → created an issue.
Any reason not to bring this into the simple_oauth module?
Looks like there's a module that provides this for the OAuth2 server module: https://www.drupal.org/project/openid_connect_autodiscovery →
Hi,
This looks like a good fix for the issue, allows you to support this need.
I'm wondering about consistency and user expectations, though, particularly around how these are chained together.
We know that if we're inside a token, you walk these relationships with : (colon) characters. However, if you're not inside a token -- if you're in a Twig context, or Javascript, or other places in ECA that refer to sub-fields, the separator is a . (period).
order_item:purchased_entity:entity:weight:number
vs
order_item.purchased_entity.entity.weight.number
And of course PHP is entirely different, depending on whether you're looking at an array or object, and declaring or assigning...
How is a non-developer supposed to know what to use?
I'm not sure I can justify this, but at least the way I think about it currently, I think we should use : as the separator ONLY INSIDE tokens with square brackets, and if there's no brackets, use dots.
That would just mean adding a string replacement inside your MR to replace colons with dots... This wouldn't actually break the colon syntax, but I think it's a pattern that might be more familiar?
freelock → created an issue.
I have this warning on several sites, and so far have ignored it without any apparent consequences...
We're hitting this too -- however, in our case, you can't actually set the link attribute to a field -- it only affected layouts with that already set. In our case, this was not saved on the node, but in the State field for layout builder.
Deleting the layout override and avoiding the use of the setting to get the link from a different field allowed us to continue editing...
I'm hitting this as well -- I've debugged to find that the node lookup is successful, and it returns a double-array as the transformed value after finding the result. However, this does not successfully save in the entity reference.
I tried expanding the definition using a sub_process to set the target_id directly, and didn't get it working at first -- but that's because I didn't map the source field in the sub_process. Once I did that, it's working fine! So this is how you do it -- map the target_id using a subprocess, along these lines:
field_library:
-
plugin: sub_process
source: field_library_name
process:
target_id:
plugin: entity_generate
source: value
value_key: title
default_values:
status: 1
values:
uid: node_uid
body: field_library_description
field_library_type: field_library_type
field_city: field_city
field_state: field_state
It looks like it's just the singe file, src/Plugin/WebformHandler/RestWebformHandler.php, that has CRLF line endings. The rest are all already LF.
freelock → created an issue.
As far as I can tell, it's a very similar situation to CKEditor Accordion, except they chose to make an inline template instead of a modal. I am seeing other examples of modals, though.
Hmm not sure I have time to take this on, maybe there will be some somewhere.
I wonder if it helps to look at how other modules did it? E.g. I see CKEditor Accordion → has a version working for both CKEditor 4 and 5...