Need Some Event Guidance

Created on 28 August 2023, about 1 year ago
Updated 2 April 2024, 7 months ago

Problem/Motivation

Hi!
I've been working with the samples in the library and I'm sort of at a stand-still. I've built an Event Subscriber for H5P which listens for the specific event h5p.finished. The subscriber, upon the event being deployed, will look at two tables in the database and return the values (quiz title, quiz number, quiz taker uid, points earned, max points) as tokens utilizing machine state (all of which I got help writing). I can use the event subscriber to add a record to the Drupal log with the correct information, so I know the event subscriber is working as intended. I can see the tokens as available tokens in the BPMN modeler, but I'm stuck trying to figure out which action will listen for the event and then utilize the tokens to compare the earned points to the max points for the quiz title.

I sort of have a controller written, but it's currently half-abandoned, mostly because I wasn't sure if the action "Controller found to handle request" was the right one to use. I've also tried custom event using the callable event h5p.finished, and all three "response" actions. I'm pretty sure once I get the Event to be recognized, I can use the load token, like in your Route Request example, after which I can use the flow control to compare two values (token vs string and token vs token).

Another thing to note is that H5P uses an AJAX request to submit the quiz form before firing the h5p.finished event, meaning any sort of built-in form actions don't really work since the page never refreshes. The event simply populates the database, after which my subscriber reads the database to create tokens.

Thanks!!

💬 Support request
Status

Closed: outdated

Version

2.0

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @duqtape
  • 🇩🇪Germany jurgenhaas Gottmadingen

    An ECA model only gets triggered, if you have an ECA event plugin, one for each system event that you want ECA to subscribe to. Do you have such an ECA event plugin in your custom code?

    I can see the tokens as available tokens in the BPMN modeler

    The tokens displayed in the token browser are all the tokens being provided by all modules that are enabled on your site. But it doesn't mean, that their data is available at all times. Your model has to make sure, that the respective data is being loaded in the ECA model to make it available to the token system for replacement. The token chapter in the ECA Guide explains the logic behind that.

    but I'm stuck trying to figure out which action will listen for the event

    Actions are not listening to events. Ad mentioned above, you need ECA event plugins to trigger an ECA model to then take action on the data.

  • Do you have such an ECA event plugin in your custom code?

    I do not. I don't think I knew that was the path I needed to take, but now I do.

    (hours later) ...

    I've spent a good part of today trying to emulate the other plugins (like User Events) and oh dang, is it not working. Is there any chance you have a Plugin skeleton? I've tried to look at the documentation and copy what I'm seeing, but it's throwing PHP errors at me.

    TypeError: Drupal\h5p_eca\EventSubscriber\H5PFinishedSubscriber::__construct(): Argument #1 ($ecaTriggerEvent) must be of type Drupal\h5p_eca\EventSubscriber\Drupal\eca\Processor, Drupal\eca\Processor given, called in /web/core/lib/Drupal/Component/DependencyInjection/Container.php on line 259 in Drupal\h5p_eca\EventSubscriber\H5PFinishedSubscriber->__construct() (line 17 of /web/modules/custom/h5p_eca/src/EventSubscriber/H5PFinishedSubscriber.php)

  • 🇩🇪Germany jurgenhaas Gottmadingen

    There is a hidden submodule called eca_development which can be enabled with Drush. This provides plugin templates for the code generator that is part of Drush. With that you can build the boilerplate files and code for your e.g. ECA event, that you need to implement.

    There is also a video in our ECA TV channel, where we built ECA events for Drupal Commerce, this might be a good sample for you to see how you can integrate ECA with e.g. h5p: https://tube.tchncs.de/w/9t1vYAvWVJ4boYQoNWcvHr

  • Thanks! With the video and drush (and a fair amount of help), I got the event working. However, it took quite a bit and I could only get it to work if I changed line 106 in Processor.php (from the ECA module) to:

    if (!(($event instanceof Event) || ($event instanceof \Symfony\Component\EventDispatcher\Event)) && !($event instanceof ContractsEvent)) {
        throw new \InvalidArgumentException(sprintf('Passed $event parameter is not of an expected event object type, %s given', get_class($event)));
    }
    

    Even though H5P does indeed create an event and I was able to write other Event Subscribers, the explicit call to \Symfony\Component ... was the only way I could get it to work. Up next is tackling a Condition. I can get a Configuration form to work if I make it part of the event, but not part of the configuration. My best guess is I'm not creating the evaluation function correctly. I did use the drush gen to get the condition directory/file, but now I'm a bit lost. I'll keep plugging away, I just thought I'd post an update about the event.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    I can't find anything in line 106 of the Processor which is anywhere close to what you changed that to. What was that line looking like before? What version of ECA are you developing against (the issue indicates 2.0.x, but I doubt that)? And what is the event class, that the subscriber forwards to the Processor? ECA is built to work with Symfony events, maybe that h5p has some special events that are not Symfony events?

    Are you developing that code in a repository that you can share? That would help, as we could have a look into your code to see what's going on.

  • Okay, after another day of attacking it, it does seem that because the H5P module's event specifically calls use Symfony\Component\EventDispatcher\Event and not use Drupal\Component\EventDispatcher\Event;, the ECA event throws an error where it says: InvalidArgumentException: Passed $event parameter is not of an expected event object type, Drupal\h5p\Event\FinishedEvent given in Drupal\eca\Processor->execute() (line 107 of /web/modules/contrib/eca/src/Processor.php).. I could fix the error by either changing the H5P module's event to be of the Drupal type, or the Processor.php to read like I had above, but neither is the best way. So instead, I managed to write a new event that reacts to the H5P event (which also creates some handy tokens) and has use Drupal\Component\EventDispatcher\Event; along with a separate event subscriber, then have ECA respond to the new event instead of directly to the H5P created event, and everything seems to be working fine now. At least on the event side. The Condition part is still a mystery to me, but I'll keep plugging away on it. I can get a condition inside the event, like you mention in the video about 3/4 of the way through, but not as a separate condition. I can probably get away with it being a part of the event, but since there will be many H5P quizzes in the end and each will have a different action (mostly changing roles or adding points to a user integer field), I need the condition to work either as part of the event or as part of a condition.

    I'm not developing in a repository, but I could. Like in GitHub? I have no problem sharing what I create after this much work.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    So, it looks like you're working with ECA 1.1.x and Drupal 9? There it is general practice that events extend \Drupal\Component\EventDispatcher\Event and not the Symfony event yet, as that wasn't available in Symfony before version 5. In ECA 2.0.x and Drupal 10, this will change a lot, and if you're doing a fresh development, you may want to consider using the new environment since Drupal 9 is EOL in a couple of months anyway.

    When it comes to conditions, I don't see how that should be difficult. There is also a code generator available for condition plugins, and building configuration forms for them should be no issue when using the form API. And there are a lot of condition plugins available in ECA from which you can copy and paste code to achieve similar things as those, already available. Do you want to tell us, what you've done, how your code looks and what exactly the problem is, you're facing?

  • Drupal 9: Yes, I'm using Drupal 9, but that is because both H5P and A11Y (accessibility) are both stuck on 9 for the time being. If they move to 10 before January, I'll do the same, otherwise, I'll have to wait until June (academic semesters). Everything else is luxury modules, but not the quizzes and font for dyslexic readers.

    I was using the Compare Two Scalar values as a starting point. I'll put some more work in this weekend coming and post my struggles/successes with getting the condition and/or action to work correctly.

    Thanks for everything! When it's all working correctly (at least for Drupal 9), I'll happily give you the whole lot. I'm not too sad I had to write another event since it makes new, usable tokens that are not provided by H5P, it was just a learning adventure.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    I was using the Compare Two Scalar values as a starting point. I'll put some more work in this weekend coming and post my struggles/successes with getting the condition and/or action to work correctly.

    That's probably one of the most complex condition plugins around. Maybe an unfortunate choice as a reference for your own condition plugin.

    What condition do you need to implement that isn't covered yet? Perhaps we can point you to a better example?

  • Oh really?! Dang.
    Here is what I have so far (I haven't gotten anything more accomplished since I posted last):
    1. My new event pulls the quiz taker uid, the quiz score, and the max score from the database and makes tokens (if that makes a difference in the condition/action)
    2. It pulls the quiz name based on the quiz ID from another database table based on a join. This makes a token, too.

    I would like to be able to make two conditions:
    1. Select the quiz name from a drop down (I do have a working dropdown)
    2. Select a passing percentage (I do have percentages as 10's (100, 90, 80, etc) in a working dropdown)

    Then if both conditions pass, execute the next action. It doesn't really matter to me if this is done with the flow arrow or an action rectangle, just that the two conditions can be executed together.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    Well, you can compare values that you have access to through tokens with existing conditions already. No need to build your own conditions if it's only about comparison. Just use those that are already there. OK, we don't have name drop-downs, but building an ECA model is a one-off process for a technical person, not an end-user, so that should be possible without a drop-down.

  • Status changed to Postponed: needs info 10 months ago
  • 🇩🇪Germany jurgenhaas Gottmadingen

    Is this being fixed or do you need more support on it?

  • Status changed to Closed: outdated 7 months ago
  • 🇩🇪Germany jurgenhaas Gottmadingen
Production build 0.71.5 2024