4

I am trying to override a file in Controller and another in controllers directory of the Amazon Payments module. I have followed several tutorials with no luck at overriding the controllers and I have no idea how to override abstract classes in the Controller folder (capital C). I need to override two methods found in two different files indexAction() in OnepageController.php and _getOnepage() in Checkout.php.

app/code/community/Amazon/Payments/controllers/OnepageController.php

class Amazon_Payments_OnepageController extends Amazon_Payments_Controller_Checkout
{
    ...

    public function indexAction()
    {
        // placeholder required
    }

    ...
}

app/code/community/Amazon/Payments/Controller/Checkout.php

abstract class Amazon_Payments_Controller_Checkout extends Mage_Checkout_Controller_Action
{
    ...

    protected function _getOnepage()
    {
       return Mage::getSingleton('checkout/type_onepage');
    }

    ...
}

Does anyone see what I am doing wrong in my code that would get this working? Also does anyone know how to override the Checkout.php file at the bottom?

app/etc/modules/KNG_Amazon/Payments.xml

<?xml version="1.0"?>
<config>
    <modules>
        <KNG_Amazon_Payments>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Amazon_Payments />
            </depends>
        </KNG_Amazon_Payments>
    </modules>
</config>

app/code/local/KNG/Amazon/Payments/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <KNG_Amazon_Payments>
            <version>1.3.0.1</version>
        </KNG_Amazon_Payments>
    </modules>
    <frontend>
        <routers>
            <amazon_payments>
                <args>
                    <modules>
                        <KNG_Amazon_Payments before="Amazon_Payments">KNG_Amazon_Payments</KNG_Amazon_Payments>
                    </modules>
                </args>
            </amazon_payments>
        </routers>
    </frontend>
</config>

app/code/local/KNG/Amazon/Payments/controllers/OnepageController.php

require_once 'Amazon/Payments/controllers/OnepageController.php';
class KNG_Amazon_Payments_OnepageController extends Amazon_Payments_OnepageController 
{
    public function indexAction()
    {
        $this->_getOnepage()->savePayment(array(
                'method' => 'amazon_payments',
                'additional_information' => array(
                        'order_reference' => $this->getAmazonOrderReferenceId(),
                )
        ));
    }
}

As for this last file I don't have any idea how to override it but the change below to the method is what I am wanting from the result.

app/code/local/KNG/Amazon/Payments/Controller/Checkout.php

abstract class KNG_Amazon_Payments_Controller_Checkout extends Amazon_Payments_Controller_Checkout 
{
    protected function _getOnepage()
    {
        return Mage::getSingleton('amazon_payments/type_checkout');
    }
}

Update: After some research I found out that I no longer need to override Checkout.php file. I like the answer that was given by @fschmengler, explaining the differences so I want to leave it. My problem right now is that my code for OnepageController.php is still not working. Can anyone help with that?

  • Have you checked if your module is actually called? Check in System > Configuration > Advance. If your module name doesn't present there then your naming is wrong ex. KNG_Amazon_Payments. As I have been doing for naming is NameSpace_ModuleName. – Adarsh Khatri Sep 29 '15 at 0:36
  • @AdarshKhatri I didn't actually think of checking that but when I just now checked my plugin does exist. – njm5785 Sep 29 '15 at 16:17
5

As you noticed, these are two different kinds of controller classes. The actual controllers, loaded by the Magento Router, in controllers and abstract controller classes, loaded by the autoloader in Controller

Controller overrides work as follows:

For each route (like amazon_payments in your case), several modules can register their controllers:

  1. The Amazon_Payments module registers their controllers with prefix Amazon_Payments
  2. Your module registers its controllers with prefix KNG_Amazon_Payments and specifies that they should be used before Amazon_Payments.

Now for each request that starts with the front name of amazon_payments, controllers and actions are searched in this order. A request to amazon_payments/onepage/index will:

  1. look for app/code/local/KNG/Amazon/Payments/controllers/OnepageController.php,
  2. if the file exists, load it and check if the class KNG_Amazon_Payments_OnepageController contains a indexAction method, if yes, execute it and stop (if this class is not defined in the file, throw an error)
  3. look for app/code/community/Amazon/Payments/controllers/OnepageController.php
  4. if the file exists, load it and check if the class Amazon_Payments_OnepageController contains a indexAction method, if yes, execute it and stop (if this class is not defined in the file, throw an error)
  5. forward to noroute action (i.e. show 404 page)

Abstract Controller classes:

For abstract controller classes, this override system does not work, you would have to override each single controller and extend the original class, so that all actions use your controllers. This is the same problem that we have with changing methods in abstract model classes. To avoid duplicate code, you could use traits.

But there is another option: Since classes in the Controller directory are loaded by the autoloader, the directory fallback system can be used. Place your modified abstract controller in app/code/local/Amazon/Payments/Controller/Checkout.php. It must be a modified copy of the original class, not a new class that extends it.

Both solutions are not very pretty, but if you really need to make changes there, you have to choose the lesser of the two evils.

Think about it twice, if you can accomplish your goal with a different method. If the code in the question is your real and complete code, maybe you can override the singleton instead?

  • thanks for the detailed answer. I am going to dig into this more. This is the real and complete code and it works when directly modifying the community plugin, but didn't want to leave it that way. What do you mean by overriding the singleton? Wouldn't that be the model? – njm5785 Sep 29 '15 at 15:56
  • Yes but that was just a wild guess. I don't know what the original method looks like, I thought if it's only ` return Mage::getSingleton('amazon_payments/type_checkout'); ` you want to replace the singleton, but on second look, this is probably not the case. – Fabian Schmengler Sep 29 '15 at 16:31
  • I think I found an easier way to do this. I think I only need to override the controllers file (OnepageController.php). The problem is that I can't get mine to work. Ideas on why that is not working? Code is exactly the same as noted in question. – njm5785 Sep 29 '15 at 22:27
-1
app/code/local/KNG/Amazon/Payments/Controller/Checkout.php

use require_once same as you did for

app/code/local/KNG/Amazon/Payments/controllers/OnepageController.php

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.