1

I have a script file called 99bill_received.php.

Within that script, I need to call a method update() within a class called ModelCheckoutOrder, which resides in a different path from this PHP script.

The class name of where the update() method resides is called ModelCheckoutOrder.

For most OpenCart extensions, the PHP files are class files, so you can inherently call something like this without initializing an object.

/**
 * Updates an existing order history using the order_id and the updated
 * order_status
 * @param $order_id
 * @param $order_status
 */
function update_order_history($order_id, $order_status)
{
    // load the order.php file
    $this->load->model('checkout/order');

    // Execute update()
    $this->model_checkout_order->update(
        $order_id,
        $order_status,
        "",
        true
    );
}

Notice the $this->load->model() line. You don't need to initialize the ModelCheckoutOrder object in order to use it (correct me if I am wrong here about that).

My question is - how do I access this class method within my PHP script file? I am NOT in an OpenCart .php script at the moment - only calling it since I need to access the function update() which is an OpenCart file.

I have tried to initialize the ModelCheckoutOrder class by using $model = new ModelCheckoutOrder(), but it did not work as I intended (meaning, I have no idea what went right or wrong). Please pardon my ignorance in the OOPHP.

theGreenCabbage
  • 5,197
  • 19
  • 79
  • 169
  • I do not know, is it help you or not, but just check it: http://stackoverflow.com/questions/11276828/codeigniter-this-load-model-not-working – vaso123 Oct 14 '14 at 09:58

2 Answers2

1

First - why is your file only a script? OpenCart is built using a MVC pattern and as such even your script should be a controller, like this:

class ControllerPayment99BillReceived extends Controller {

    public function callback() {
        if ($this->request->server['REQUEST_METHOD'] === 'POST' && isset($this->request->post['order_id'])) {
            $this->update_order_history($this->request->post['order_id'], <ORDER_STATUS_ID>);
        }
    }

    private function update_order_history($order_id, $order_status) {
        // load the order.php file
        $this->load->model('checkout/order');

        // Execute update()
        $this->model_checkout_order->update($order_id, $order_status, "", true);
    }
}

Now with such controller and it's method (in MVC it's called action) it can be accessed via URL like this:

http://example.com/index.php?route=payment/99bill_received/callback

while the necessary values are transfered via POST request. Of course there should be more variables and further validation that the request came as response from the payment gateway so that it cannot be abused by attacker.

Second - you said For most OpenCart extensions, the PHP files are class files - unfortunately this is true. I mean that there are cases when extensions come with scripts and not controllers (thus breaking the MVC). But this is a bad habit and lack of experience/professionality.

So to answer your (hidden) question: if you are inside of OpenCart's MVC (a controller or model) you have access to the OpenCart's implementation of IoC (Inversion of Control) - to a registry - from which you can obtain other system objects (customer, tax, currency, etc.) or models (by loading them).

Therefore you can call

$this->load->model('checkout/order');

but you have to be inside of controller (that is extending the base Controller).

EDIT to answer the questions:

  1. My fault, the callback should be in the URL as well as this one will be invoked during the request (already changed the URL example).
  2. You can have two controllers or only one controller (as is done in all payment modules). In one controller case you have the method index which is invoked for the main functionality and the method callback for the response from payment gateway (could be called after successful payment or in case of error - but then you should handle all the cases there).
  3. While it looks like that this is not the case. PHP has no such main method that is invoked all the time like in Java. But in many MVC frameworks (and we may for now consider OpenCart as a framework even it is not) it is implemented in a way that if you do a request to a URL for which no explicit action (method) is defined (at least controller has to be) the framework tries to invoke (execute) the index method on that controller.
shadyyx
  • 15,825
  • 6
  • 60
  • 95
  • Thank you so much shadyyx. You fully answered my questions. It is true, it is indeed due to my inexperience with the script vs. MVC debacle. I will make these changes now. – theGreenCabbage Oct 14 '14 at 10:55
  • Can you explain to me the purpose of `callback()`? Also, my second question is - for this 99Bill Extension, is it alright having two `Controller` files of in the same class? I have a `bill99.php` Controller file which executes the main functionality of the extension. This `received.php` only gets called after a successful transaction. – theGreenCabbage Oct 14 '14 at 11:00
  • Third question - is the `index()` function the Java-equivalent of a `main()` function? – theGreenCabbage Oct 14 '14 at 11:23
  • Check my edited answer where you may find answers to your questions. – shadyyx Oct 14 '14 at 11:59
  • Man shadyyx - thank you so very much. I've had ran into issues developing for OpenCart because I have been unclear with some of the design pattern concepts, and you cleared them all for me. – theGreenCabbage Oct 14 '14 at 13:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/63069/discussion-between-thegreencabbage-and-shadyyx). – theGreenCabbage Oct 15 '14 at 02:30
0

In opencart use following structure is best one.

For loading ModelCheckoutOrder class

$this->load->model('checkout/order');

$this->model_checkout_order->update(
        $order_id,
        $order_status,
        "",
        true
    );
selva
  • 24
  • 1
  • 1
    This is the exact same code I have in my example. My issue at the moment is about calling it outside of my class. I'm not quite sure how to articulate it. – theGreenCabbage Oct 14 '14 at 10:08