Post by Qphoria » Wed Jul 07, 2010 9:55 pm

I've been talking with daniel and we are going to try passing all data through directly from the model query so that ALL data is available to the tpl pages.

For example...

The Current way
1. The controller calls the model function for getProductsByCategoryId()
2. The model function does a select * for all products in that category and returns ALL DATA to the controller
3. The controller then makes a SUBSET of what we assumed to be "relevant" parts of that data.
4. The controller makes that smaller subset available to the view.

Code: Select all

$results = $this->model_catalog_product->getProductsByCategoryId($category_id);
$this->data['products'][] = array(
    'name'    => $result['name'],
    'model'   => $result['model'],
    'sku'       => $result['sku'],
    'href'      => HTTP_SERVER . 'index.php?route=product/product&product_id=' . $result['product_id']),
);  
This is very limiting as it requires you to edit the controller to add fields to the subset to make them visible on the view. The above, for example, wouldn't support showing the location field on the view since its not in the subset.


Instead we will try
1. The controller calls the model function for getProductsByCategoryId()
2. The model function does a select * for all products in that category and returns ALL DATA to the controller
3. The controller passes that full array of ALL DATA to the view.

Then you will be able to simply echo the name of the field:

Code: Select all

$this->data['products'] = $this->model_catalog_product->getProductsByCategoryId($category_id);  
Then you can simply add to the tpl file wherever you want:
<?php echo $products[$j]['location']; ?>
<?php echo $products[$j]['price']; ?>
<?php echo $products[$j]['weight']; ?>
<?php echo $products[$j]['any_field']; ?>
etc

Even new custom db fields will be available automatically with no controller changes.

This change would be made in all places that display product info:
category, search, manufacturer, modules, homepage, etc

This will cut down on some code and the lack of subset array creation might even improve performance slightly

This is related to my earlier discussions on this topic
http://forum.opencart.com/viewtopic.php ... ata#p53453

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Johnathan » Wed Jul 07, 2010 11:34 pm

Sounds like a great idea. It'll save time for those of us that add fields in the template and then have to find the relevant data in the controller. Thanks!

Image Image Image Image Image


User avatar
Administrator

Posts

Joined
Fri Dec 18, 2009 3:08 am


Post by JAY6390 » Wed Jul 07, 2010 11:50 pm

one suggestion for this would be to have the data passed by reference to the tpl file rather than by value, since at present you're creating the same data three times from what I can tell (ie $products in the controller, then $this->data['products'] and then again with $products in the view. It would make sense to unset the values once they're extracted to conserve memory usage, and also to pass $products to $this->data['products'] using

Code: Select all

$this->data['products'] = &$products; 
I would also like to see a way of getting language files loaded automatically into a template, as it's a huge waste of code loading each line individually and setting the data

Image


User avatar
Guru Member

Posts

Joined
Wed May 26, 2010 11:47 pm
Location - United Kingdom

Post by Qphoria » Thu Jul 08, 2010 12:07 am

One undocumented feature I added to 1.4.8 was automatic language loading support. It's not in effect, but can easily be used in any custom modules.

Basically it was simply a matter of returning the output of language load

So instead of:

Code: Select all

$this->language->load('checkout/cart');

$this->data['text_select'] = $this->language->get('text_select');
$this->data['text_sub_total'] = $this->language->get('text_sub_total');
$this->data['text_discount'] = $this->language->get('text_discount');
$this->data['text_weight'] = $this->language->get('text_weight');

$this->data['column_remove'] = $this->language->get('column_remove');
$this->data['column_image'] = $this->language->get('column_image');
$this->data['column_name'] = $this->language->get('column_name');
$this->data['column_model'] = $this->language->get('column_model');
$this->data['column_quantity'] = $this->language->get('column_quantity');
$this->data['column_price'] = $this->language->get('column_price');
$this->data['column_total'] = $this->language->get('column_total'); 
You can simply use:

Code: Select all

$this->data = array_merge($this->data, $this->language->load('checkout/cart')); 
From this point on, any new language entries will be pulled in automatically without having to define it in the controller.
It is completely transparent from the old way so choose whichever way you prefer.

For the rare case that you have a sprintf needed for a language entry, you can still add that line after the initial merge like:

Code: Select all

$this->data = array_merge($this->data, $this->language->load('checkout/cart'));
$this->data['text_welcome'] = sprintf($this->language->get(text_welcome), $this->customer->getFirstName()); 
But for all standard language entries, they will all be dynamic

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by JAY6390 » Thu Jul 08, 2010 12:20 am

Yeah I was thinking more of an auto loading into the $this->data array, perhaps adding a new optional boolean parameter to the load language method that would just copy it straight over to the array

it would be nice to have this rolled out in future versions (the array merge method if you don't go with the auto load) just to save disk space and upload/download sizes of the cart, and keeping the cart cleaner and less likely to have errors from misspelt vars etc

Image


User avatar
Guru Member

Posts

Joined
Wed May 26, 2010 11:47 pm
Location - United Kingdom

Post by Qphoria » Thu Jul 08, 2010 12:25 am

The reason we don't autoload it into this->data (aka the controller) is because we are trying to keep the framework separate from the application and libraries. I did at one point add a language option to the controller but we dont want that in the engine files. This keeps the two levels separate by passing the data back from a model load call.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by JAY6390 » Thu Jul 08, 2010 12:38 am

I see. What if the controller was to have a new method like $this->getLanguageVars('checkout/cart'); which did the same thing. I understand that keeping the different parts separate is how mvc works, but frameworks have helpers and so on that make something like this less trivial. It's just an idea really to make development quicker and more reliable

Image


User avatar
Guru Member

Posts

Joined
Wed May 26, 2010 11:47 pm
Location - United Kingdom

Post by fido-x » Thu Jul 08, 2010 10:11 am

This all sounds like good stuff. The only concern I would have relates to "cleaning" the data. The way the system currently works, all the "cleaning" of data is done in the controller, so that what is passed to the template is "clean".

What do I mean by "cleaning" you all ask? I'm referring specifically to the description field which is "html_entity_decoded" in the controller. By passing ALL data to the template file as proposed, this "html_entity_decoding" would then have to be done in the template. I'm not sure whether that aspect of this proposal is a good idea.

Image
Modules for OpenCart 2.3.0.2
Homepage Module [Free - since OpenCart 0.7.7]
Multistore Extensions
Store Manager Multi-Vendor/Multi-Store management tool

If you're not living on the edge ... you're taking up too much space!


User avatar
Expert Member

Posts

Joined
Sat Jun 28, 2008 1:09 am
Location - Tasmania, Australia

Post by Qphoria » Thu Jul 08, 2010 1:17 pm

Yes Fido, I'm glad you brought that up.

Price, for example, needs to be formatted before it reaches the view. I was thinking about either updating the array element:

Code: Select all

$products = $this->model_catalog_product->getProductsByCategoryId($category_id); 

foreach ($products as $key => $value) {
    $products[$key]['price'] = $this->currency->format($value, $this->currency->getValue());
}

$this->data['products'] = &$products; 
Or, perhaps it is useful to have "raw" data for unforeseen features. So instead of replacing the raw price with the formatted price, just add a new element:

Code: Select all

$products = $this->model_catalog_product->getProductsByCategoryId($category_id); 

foreach ($products as $key => $value) {
    $products[$key]['formatted_price'] = $this->currency->format($products[$key]['price'], $this->currency->getValue());
}

$this->data['products'] = &$products; 

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by i2Paq » Thu Jul 08, 2010 3:19 pm

I also like the idea, I've read your previous topic/discussion with great interest.

It will make live easier and templates more flexible.

Norman in 't Veldt
Moderator OpenCart Forums

_________________ READ and Search BEFORE POSTING _________________

Our FREE search: Find your answer FAST!.

[How to] BTW + Verzend + betaal setup.


User avatar
Global Moderator

Posts

Joined
Mon Nov 09, 2009 7:00 pm
Location - Winkel - The Netherlands

Post by fido-x » Thu Jul 08, 2010 4:47 pm

Qphoria wrote:Yes Fido, I'm glad you brought that up.
You're glad I brought something up? That makes a change.
Price, for example, needs to be formatted before it reaches the view. I was thinking about either updating the array element:

Code: Select all

$products = $this->model_catalog_product->getProductsByCategoryId($category_id); 

foreach ($products as $key => $value) {
    $products[$key]['price'] = $this->currency->format($value, $this->currency->getValue());
}

$this->data['products'] = &$products;  
Don't forget the product description.

Code: Select all

$products = $this->model_catalog_product->getProductsByCategoryId($category_id); 

foreach ($products as $key => $value) {
    $products[$key]['price'] = $this->currency->format($value, $this->currency->getValue());
    $products[$key]['description'] = html_entity_decode($value, ENT_QUOTES, 'UTF-8');
}

$this->data['products'] = &$products;  

Image
Modules for OpenCart 2.3.0.2
Homepage Module [Free - since OpenCart 0.7.7]
Multistore Extensions
Store Manager Multi-Vendor/Multi-Store management tool

If you're not living on the edge ... you're taking up too much space!


User avatar
Expert Member

Posts

Joined
Sat Jun 28, 2008 1:09 am
Location - Tasmania, Australia

Post by JAY6390 » Thu Jul 08, 2010 6:14 pm

I much rather the formatted price being separate than merged into the price field, as that makes calculations with the number more difficult which is a nightmare when you just want to do some simple math

Image


User avatar
Guru Member

Posts

Joined
Wed May 26, 2010 11:47 pm
Location - United Kingdom

Post by Qphoria » Thu Jul 08, 2010 9:45 pm

JAY6390 wrote:I much rather the formatted price being separate than merged into the price field, as that makes calculations with the number more difficult which is a nightmare when you just want to do some simple math
Right.. but we also need to have to unformatted, but tax and currency converted price

There are 3 prices
The price from the database which is in your currency without tax (10.00) or Gross Price
Then what you are asking for is the non-formatted, but still converted and taxed price (14.24) or Net price
Then the price that is shown on the store front which includes tax, conversion, and formatting ($14.24) or formatted Net Price.

So do we need all 3? or can the converted and taxed but non-formatted amount replace the database amount? I guess its just better to offer all 3 options for future modders that might want to use that data

Code: Select all

$products = $this->model_catalog_product->getProductsByCategoryId($category_id); 

foreach ($products as $key => $value) {
    $products[$key]['formatted_price'] = $this->currency->format($products[$key]['price'], $this->currency->getValue(), False, True);
    $products[$key]['net_price'] = $this->currency->format($products[$key]['price'], $this->currency->getValue(), False, False);
}

$this->data['products'] = &$products;  
and description, etc

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by marc_cole » Thu Feb 03, 2011 7:10 am

Qphoria wrote:I've been talking with Daniel and we are going to try passing all data through directly from the model query so that ALL data is available to the tpl pages.
Just wanting to see if we are any closer to having this implemented in the core. It sounds like a fantastic addition.

OpenCart v1.4.9.4
VQMod | Categories Home | Cleaner By Default - 2 Column | Speak Good English


Active Member

Posts

Joined
Tue Dec 14, 2010 11:26 am
Location - Seattle, WA

Post by Qphoria » Thu Feb 03, 2011 9:02 am

it will be after 1.5.0.. there's a whole optimization sweep that needs to run through all the code when it is finished

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by InnoSite » Wed Jun 29, 2011 6:47 am

Hey there, has this been implemented yet? Is it available?

New member

Posts

Joined
Wed Jun 15, 2011 8:33 am

Post by Xsecrets » Wed Jun 29, 2011 9:34 am

InnoSite wrote:Hey there, has this been implemented yet? Is it available?
unfortunately no it's actually gotten worse as now you can't even pass all the language variables through like you used to be able to.

OpenCart commercial mods and development http://spotonsolutions.net
Layered Navigation
Shipment Tracking
Vehicle Year/Make/Model Filter


Guru Member

Posts

Joined
Sun Oct 25, 2009 3:51 am
Location - FL US

Post by InnoSite » Fri Jul 01, 2011 9:39 am

I've been copying the functions and adding them to the array via the controller, that seems to work. Bit of a pain to do tho for everything I want to display somewhere else on the site.

New member

Posts

Joined
Wed Jun 15, 2011 8:33 am

Post by Xsecrets » Fri Jul 01, 2011 11:32 am

InnoSite wrote:I've been copying the functions and adding them to the array via the controller, that seems to work. Bit of a pain to do tho for everything I want to display somewhere else on the site.
what functions are you talking about? as far as I can tell this is simply about passing model data straight through to the view instead of building an array with a limited subset of the data returned.

OpenCart commercial mods and development http://spotonsolutions.net
Layered Navigation
Shipment Tracking
Vehicle Year/Make/Model Filter


Guru Member

Posts

Joined
Sun Oct 25, 2009 3:51 am
Location - FL US
Who is online

Users browsing this forum: No registered users and 1 guest