How to extend Shopware 6 controller action - php

I am building a plugin for Shopware 6 and cannot seem to find any documentation as to how to extend an existing controller action. I found this How to add an Action to Account Controller in Shopware but it seems to refer to Shopware 5 and I am not sure I can use it that way in Shopware 6.
The controller action I want to extend is \Shopware\Storefront\Controller\AddressController::saveAddress - in my case I want to add custom address validation that would use a service in my plugin where a request to 3rd party API would be made, if the address is correct then allow the address, if not then return an error. Perhaps it is better to instead extend \Shopware\Core\Checkout\Customer\SalesChannel\AddressService::save but I have no clue for now (I am new to Shopware in general). Extending the service would mean I do not have to override the whole action logic so that it contains my check in the middle. Or perhaps there is an event I can use for address saving (same thing, can't find a good source/list of events for Shopware6).
There seem to be guides here:
https://docs.shopware.com/en/shopware-platform-dev-en/developer-guide/controller
and here:
https://docs.shopware.com/en/shopware-platform-dev-en/how-to/custom-storefront-controller
but these only describe how to make a new controller and it is not very useful to me since I do not want to add any new routes but use the existing one /account/address/create.
I would be very grateful for a code example of how to register the override in the plugin (config, xml) and how would the extending class look like. If it is not too much to ask the ideal answer would contain an example of:
How to extend an action for existing controller.
How to extend an existing service.
Where to find which event is firing in a controller/service, subscribe to it and make it override default behaviour (like throw Shopware\Core\Framework\Validation\Exception\ConstraintViolationException).

It does not make sense to extend/override action, as action should be as thin as it is possible, and all business logic should be in service.
To extend existing service you can decorate it or subscribe to some events to extend functionality. See https://docs.shopware.com/en/shopware-platform-dev-en/how-to/decorating-a-service
In your case, you can subscribe on framework.validation.address.create or/and framework.validation.address.update events to extend list of constraints. In general all validation events have prefix framework.validation. second part is defined in \Shopware\Core\Framework\Validation\DataValidationFactoryInterface implementation in your case it is \Shopware\Core\Checkout\Customer\Validation\AddressValidationFactory

Related

How to rebuilding a module in PSFS framework correctly?

We have a PHP project built with PSFS framework, but we're stuck trying to rebuilding an existing module.
Which "Controller Type" should I choose when rebuilding the module? Could someone explain to me what each option means?
When you want to regenerate a module, you have to decide the parent class to extend from. In that case you have some options:
Without authentication (normal)
With user authentication (for APIs services or logged html sections)
With admin authentication (that requires the Basic Auth for admins)
You can see another option when you need to extend from your own class that controls all the authentication, in this case you have to complete the input with the fully namespace and PSFS automatically extends the principal module and the API classes from this specific class instead of the PSFS base classes. The selector before will be ignored in case of setting something as custom namespace.

Feature Toggles in Symfony

Our Symfony application is currently one application, that will soon require ability to have multiple sites point to the same Symfony core and have slightly different functionality based on which site it is currently on.
As an example we might have a banner showing on one site but not another. Another example is a payment option that will be enabled/disabled on the different sites. Or another one is different fields on a form on the different sites.
Has anybody had experience structuring Symfony application in this way?
If you want to "theme" your application you can use the LiipThemeBundle, it really works well. For the features activation/deactivation you also have the FeatureToggleBundle bundle (quiet recent).
You could also implement a basic helper like this:
/**
* Check if a feature is activated.
*
* #param string $feature Name of the feature
*
* #throws AccessDeniedHttpException
*/
protected function checkFeature($feature)
{
$features = $this->container->getParameter('app.features')
if (!$features[$feature]) {
throw new AccessDeniedHttpException();
}
}
...
$this->checkFeature('contact_form');
With this kind of configuration:
app.features:
contact_form: false
You have to know that using kernel event listener you can do most of the work.
You can in a 'CoreBundle' for example refer the user to a different template depending on the domain name where he is, using the kernel.request event.
So in your situation it would be easy for a site to showing a banner in a site but not another.
You can look this article that explains it :
Twig templating using event listener
Yess thats the advantage of symfony
symfony use the kernel connected with routing and controller and then response is being created.
If you want to use multiple applications in symfony you can do this very easily and that is an advantage of symfony.For this you just need to add some routing and everything will be done automatically.
You can use symfony form class to add forms and append them to other pages with required field without creating whole form again.
If you want to add or remove some features on/off you can just do this by app class or by creating different controllers.

Overriding Joomla 3.0 components. Possible to override model and controller too? Not just views?

I understand the ability to overide core views in Joomla using overides, but how about the models and controllers? I would like the ability to add a field to the core user registration form, but Joomla pulls all the fields from an xml located in the models folder. I could just create a plugin, but that creates its own section, and I need it to go exclusively in the main registration form, as I am creating a tiered registration.
My question is exactly how the title implies, can you create component overrides of model and controller files in joomla, rather than just views?
Further, I know I "could", but in the event of an update I want to make sure this is an acceptable override solution - not just a hack that will be subject to be overwritten.
Thanks!!
Yes it can, i used MVC Override 1.0.11, is Joomla 3.x compatible.
in my case i used to override /models from component com_tag
structure in your template in this form:
/code/YOUR_COMPONENT/models/tag.php
above is my example
and you can do override correctly. the link is:
http://gruz.org.ua/en/extensions/joomla-mvc-override/1_0_11.html

CakePHP 1.3: Alaxos ACL Plugin not recognizing Pages Plugin

I have been developing with CakePHP and the Alaxos ACL plugin has helped in tremendously.
However, I am facing one issue I am not sure how to fix it?
I added a plugin named 'pages', but I cannot get ACL to see it so it is added to the list of allowed/denied actions.
If I access the plugin thru domain.com/pages/pages I get the following error
DbAcl::check() - Failed ARO/ACO node lookup in permissions check.
When I check thru the ACL plugin display, there is no reference to the pages controller and if I run the ACL build function, it simply says that there is nothing to add.
Is it because this controller is named pages and there is already a pages controller within Cake?
If it is how do I fix it? Is my only option, at this time, adding this manually to the Db? Should I go thru this plugin and rename pages to something else? or is there anything else I should be doing?
Thanks,
I see two things here. First like you suspect, having two classes in your application that share the same name is a bad idea. It will likely give you some problems in one way or another, with the wrong class being instantiated or whatever. As far as Cake does not use namespaces, this is not recommended.
Then, even if you change this name, there will be another problem if the controller you want to manage with ACL is the 'default' controller (a controller that has the same name as the plugin). There was an issue with the ACO nodes retrieval when the path contains twice the same name, which is the case for plugins default controllers.
controllers/Pages/Pages/index
So I decided to just skip the plugins default controllers from the controllers supported by the ACL plugin.
If you are the author of this plugin, you could rename it (because PagesController exists already), and move the actions in some other controller than the default controller.

peer_method in symfony's admin generator

I have a symfony module for my GenericImport class. Rather than the default method symfony uses for the list page, I want to use GenericImportTable::getQueue(). I thought the following would work but it didn't:
config:
actions: ~
fields:
list:
peer_method: getQueue
How can I use a custom query for the list page? (I'm using Doctrine.)
(To be clear, I don't wish to manually create a whole new custom action. I'm going the route I'm going because I want to take advantage of everything that comes with the admin generator like batch actions, the filter, etc.)
Try table_method.
...and read more here: http://www.symfony-project.org/jobeet/1_4/Doctrine/en/12#chapter_12_sub_table_method

Categories