How to override a Plone event subscriber - overriding

I need to extend a Plone product (Products.Poi) with a second product.
In the extension product i need to override a subscriber event of the original.
I tried to subscribe in an override.zcml an event with the same name but the second event don't override the first but all two are execute.
Here http://plone.org/products/dexterity/documentation/manual/five.grok/core-components/events seem that is not possible:
Unlike adapters, you cannot override an event subscriber by using a more specific interface. Each and every applicable event subscriber will be executed when an event is fired.
Someone has a trick?
Thanks Alex

Simone Orsi gave me a solution: z3c.unconfigure.
This product permit to disable zcml configuration.
To use it, I executed this step on my extented Poi product:
Added "z3c.unconfigure" as install_requires in the setup.py
Create event.py with the new definition of update_tracker_watchers
In the overrides.zcml add this line to unconfigure Products.Poi.events.update_tracker_watchers and to register my new event
<include package="z3c.unconfigure" file="meta.zcml" />
<unconfigure>
<subscriber
for="Products.Poi.interfaces.ITracker
Products.Archetypes.interfaces.IObjectEditedEvent"
handler="Products.Poi.events.update_tracker_watchers"
/>
</unconfigure>
<subscriber
for="Products.Poi.interfaces.ITracker
Products.Archetypes.interfaces.IObjectEditedEvent"
handler=".events.update_tracker_watchers"
/>

When you specified the overrides.zcml, you also need to register the zcml override in buildout? Take a look at: http://developer.plone.org/components/zcml.html?highlight=zcml#overrides It'd be something like: zcml = my.package-overrides
Additionally, you can try using the z3c.unconfigure package: http://pypi.python.org/pypi/z3c.unconfigure

Related

How to override function from core service

The plan is to remove some fields from the default Shopware 6 registration form.
I've copied some twig-templates to my plugin and removed the fields like billingaddress etc ...
An error occurred in the validateRegistrationData function because the field value for billingaddress is null (sounds logic because I've deleted the field in the twig-template)
in vendor/shopware/platform/src/Core/Checkout/Customer/SalesChannel/RegisterRoute.php (line 259)
In my module I would like to override below function in the RegisterRoute.php file (service)
private function validateRegistrationData(...) { ... }
What steps are needed to properly override above function from within my custom shopware 6 plugin.
IMHO validateRegistrationData is only the first place where you have an issue, even you change the validation billing address variable is required below in \Shopware\Core\Checkout\Customer\SalesChannel\RegisterRoute::register() method.
Some my suggestion to you is implementing your own RegisterRoute in your plugin and decorate or even override existing core service.
So steps:
implement own RegisterRoute in your plugin
Register it in service container with the same id as core route:
<service id="Shopware\Core\Checkout\Customer\SalesChannel\RegisterRoute"
class="YourPlugin\Core\Checkout\Customer\SalesChannel\RegisterRoute" public="true">
<!-- your own arguments -->
</service>
Also I think you need to implement your own CustomerValidationFactory and AddressValidationFactory if it is needed by your business logic.
Anyway, you can also face the issue that some fields are required by Customer DAL definition, but you don't set them. So most probably you also need to change a bit CustomerDefinition, i mean override of course.

How to check if table have action handler

in my vaadin/spring application i have a table which can have added action handler. Is there any option how to chcek if table already have an action handler ?
I checked source code of com.vaadin.ui.Table class and how it deals with Action handlers - and unfortunately, I didn't find any direct way how to check how many action handlers there are in the Table (Vaadin version 7.7.6) - thats because the only exposed methods which deal with action handles are these:
addActionHandler - for adding action handlers
removeActionHandler - for removing specific action handler
removeAllActionHandlers - for removing all action handlers
However, good news is that the addActionHandler method will add the new handler only if it wasn't already added. So if you just want to be sure that you haven't added your handler twice, just impelment the equals() method in your handler and it shouldn't be added twice. See code of method com.vaadin.ui.Table#addActionHandler and maybe set some debug points there...

how to implement source filter property page?

I have followed the instructions at http://msdn.microsoft.com/en-us/library/windows/desktop/dd375010%28v=vs.85%29.aspx to create a property page for my CSourceStream based stream.
When testing with amcap I can see that amcap now shows the menu item to show the capture pin properties (ISpecifyPropertyPages::GetPages is queried). The problem is that when amcap calls OleCreatePropertyFrame it returns with E_FAIL and I am not sure why, it does not seem to even get to the stage of quering my dll for the factory method to instantiate the CBasePropertyPage based property class.
The problem was my DllRegisterServer only registered my filter.
I can use AMovieDllRegisterServer2 to register all components in g_Templates but that function does not register source filters properly so for the moment I am just calling AMovieDllRegisterServer2 and then re-registering my filter with source filter specific code.

Event handlers base on user action in Plone

I want to do something programatically when user is created.
When user Is there any specific event to subscribe to ? It'd be great if I can do:
<subscriber
for="IUserRegisteredEvent"
handler=".registration.welcome_email"
/>
Also: Is IMemberData correct Interface that represents an user in Plone ? So that I can adapt it and do things like this:
user_activity = IUserActivityStream(member)
user_activity.log(event)
This question is nearly identical to this.
So the correct interface for the subscriber is:
Products.PluggableAuthService.interfaces.events.IPrincipalCreatedEvent

GenericSetup: What does toolset.xml accomplish if ToolInit still has to be called from initialize()

It seems that toolset.xml goes only half way. Ideally it should be able to do away with the ToolInit call in initialize() in __init__.py. But I could not get the tool icon to show in the ZMI without the ToolInit call.
The ToolInit call in the initialize function registers the tool class as something that can be added to OFS based folders in the database - primarily it register a factory for creating instances of the class. This is basically the same that ContentInit does for normal content classes.
Once the class is registered and its meta_type is known, instances of the class can be added to OFS based Folders. GenericSetup steps are responsible for managing persistent content and can be used to add tool instances to the database.
If we wanted to avoid the code in the initialize function, we would need to create some custom ZCML directives instead and use these in a configure.zcml to register the type and its factory. Dexterity has gone this route, but its not available for Archetypes based content types or general classes like tools.
The goal of toolset.xml is to instantiate tools into the database. It can also be used to remove tools; this is very useful in upgrade steps for example.
Example toolset.xml:
<?xml version="1.0"?>
<tool-setup>
<required tool_id="portal_foo" class="dotted.path.to.FooTool" />
<forbidden tool_id="portal_spam" />
</tool-setup>
This example toolset.xml would instantiate the FooTool class as portal_foo in it's context, and remove any object with id portal_spam if present.
Note that you can use a toolset.xml in any GenericSetup profile, not just in the package that defines the tool in the first place, for example, in general policy packages for a site you develop.

Resources