OpenCart load Model outside Controller
Asked Answered
S

4

17

I'm working on an OpenCart project, that requires a lot of customization. for my project I have to change something in the cart library (system/library/cart.php).

I would have to call a custom function that's defined inside the product model (catalog/model/catalog/product.php).

In a controller, loading a Model and using its functions is easy:

    $this->load->model("catalog/product");
    $this->model_catalog_product->customFunction();

But how do you load a model outside a controller? You can't create a new instance of the model, I already tried that:

    require_once("catalog/model/catalog/product.php");
    $a_model = new ModelCatalogProduct();

This obviously doesn't work cause models weren't intended to be used in such a way.

I also tried to use the scope resolution operator ( ModelCatalogProduct::customFunction()) It doesn't work either.

I could pass all the required info as arguments, but I would rather use the model inside the cart library class, cause the changes would be global.

Is it even possible to load a model outside a controller in OpenCart?

Streamy answered 22/11, 2012 at 12:34 Comment(3)
What reason do you have for needing to do this exactly?Arrears
I joined the project when it was about 70% complete. The price calculation is completely custom and it's implemented only for the front end (The site uses AJAX to get the info on how much it's gonna cost). The problem is, that these changes weren't implemented in backend. So the price is being calculated ok, but when the user adds a product to the cart, it uses the default openCart price calculation. I have to change the getProducts() function so the price will be ok.Streamy
The custom price is being calculated in the product model. So now I have the choice of going through all the files and finding where I have to change the code, or I add about 10 lines to the Cart library and it would be done. That's why I'm asking.Streamy
A
23

If it's only one method that you need to copy, you would be best adding a method to the Cart class itself. The Cart class will work with the $this->db->query() calls as it already has $db assigned to it even though it's not a Controller/Model

Edit

Should you wish to do this, you could do something similar to the following

public function test() {
    global $loader, $registry;
    $loader->model('catalog/product');
    $model = $registry->get('model_catalog_product');
    $result = $model->getProduct(123);
}
Arrears answered 22/11, 2012 at 13:3 Comment(3)
Actually it's about 5 functions. I gave it a try and copied all the needed functions to the cart class (through vqmod) and it's working. Thank you for your answer. However, I'll keep this question open for a while to see if there will be other answers. I'm sure there will be other people with a simmilar problem and they deserve to have as much info as possible.Streamy
I've put a method that you could use above. It's a bit hackish, but will do what you need. Just use $model instead of $this->model_catalog_productArrears
Thanks, this even worked in OC 4 system/cartTableland
B
7

You are able to load a model outside a controlled.

If You need to load a model inside of another model, You could load it the very same way using $this->load->model('my_module/my_model');.

If You need to load a model inside of template file or other custom PHP script, look at the index.php file where the Registry is instanciated - You would need to instanciate it the same way. So Your custom code could look like:

$registry = new Registry();
$my_model = $registry->load->model('my_module/my_model');
$my_model->customFunction();

Anyway I highly recommend not to edit/change the core library files unless You are sure there is no other way how to implement/do what You need.

As Jay Gilford proposed I would implement that function or it's call to the catalog/checkout/cart.php, potentially confirm or success depending on the scope and functionality You would like to implement.

Brandling answered 22/11, 2012 at 16:22 Comment(4)
Does this apply to OC 1.5.6.4? I tried and it didn't work for me.Mongoloid
I tried this in OC 4 and get Error: Class "Opencart\System\Library\Cart\Registry" not foundTableland
Well, @HaydenThring, OC was at a different version back then in 2012 :rofl: I don't work with PHP nor OpenCart for ages now, sorry I can't help you more.Brandling
Its fine, im just leaving note for others, didnt expect you to do anything. the accepted answer worked for me luckilyTableland
C
0

In OpenCart parts of the model layer are dependent on the libraries. One example is that the ID of the current customer (frontend) or the current user (backend) is needed.

To keep the structure clear and clean and to reduce code duplication, you should not introduce a dependency in the other direction. If a model is dependent on the class user and the class user is dependent on the model, you created a vicious circle.

I would recommend to move the functions into the library layer and remove their implementations in the model layer. To minimize the impact, you can wrap the function call within the model.

library/myClass

function getValue($id){ 
 $sql = "select ..."; 
 $query = $this->db->query($sql); 
 return $query->rows;
}

admin/model/catalog/myModel

function getValue($id){
 return $this->myClass->getValue();
}
Choker answered 18/1, 2013 at 15:29 Comment(0)
F
-1

In the file "cart.php" in function add() calling function "getProduct" is used in this way:

$this->load->model('catalog/product');
$product_info = $this->model_catalog_product->getProduct($product_id);

So using same way in any other part the file for example in function index() is possible and works.

As an example to warn if entered quantity is more then stock. Accessing quantity using above.

Faltboat answered 3/9, 2021 at 6:47 Comment(1)
This will not work in system/cartTableland

© 2022 - 2025 — McMap. All rights reserved.