Post by Qphoria » Fri Aug 28, 2009 12:13 am

Currently product options are pulled from getProductOptions function in the model/catalog/product.php file

This returns a "massaged" array of option and option values, consisting of statically specified values
Then the product controller massages it again with no real purpose, as the end result is the same.

I have made 2 adjustments.
1. let the model file handle ALL massaging so that the controller file only needs to call
$this->data['options'] = $this->model_catalog_product->getProductOptions();
and be done with it. No use in double massaging the same data.

2. Inside the model file, don't massage the returned array to only show a limited number of values. This makes it hell to expand on option values for mods like option plus that adds weight, image, info, sku, etc. The model should return ALL values by select * and return the resulting array with language based name included already.

I have this done and I will post it up shortly. This will allow using options in other places to be much easier and expanding option values much easier. It will also standardize the model returns, as product and category already do it this way, only options is getting special massaging that it shouldn't be.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Qphoria » Sat Jan 16, 2010 12:39 am

Ok. I've commented the new model function very well to explain how it works. This will prevent double massaging and return ALL option values to the controller dynamically, just like how product is returned. It cuts the code into a third of the size and makes it completely dynamic.

Step 1. Replace the catalog/model/catalog/product.php getProductOptions() function with this:

Code: Select all

public function getProductOptions($product_id) {
               
        // Get all product options associated with this product id
        $product_option_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_option po LEFT JOIN " . DB_PREFIX . "product_option_description pod ON (po.product_option_id = pod.product_option_id) WHERE po.product_id = '" . (int)$product_id . "' AND pod.language_id = '" . (int)((method_exists($this->language, 'getId')) ? (int)$this->language->getId() : (int)$this->config->get('config_language_id')) . "' ORDER BY sort_order");
         
        // Loop through each product option to get the product option values
        foreach ($product_option_query->rows as $k1 => $product_option) {
                                
            // Get the product option values for this product option
            $product_option_value_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "product_option_value_description povd ON (pov.product_option_value_id = povd.product_option_value_id) WHERE pov.product_option_id = '" . (int)$product_option['product_option_id'] . "' AND povd.language_id = '" . (int)((method_exists($this->language, 'getId')) ? (int)$this->language->getId() : (int)$this->config->get('config_language_id')) . "' ORDER BY sort_order");
                        
            // Merge the product_option_values into the main product options
            $product_option_query->rows[$k1]['option_value'] = $product_option_value_query->rows;
                        
        }    
        
        return $product_option_query->rows;
    }//
Step 2: Change the option code in catalog/controller/product/product.php from this:

Code: Select all

$options = $this->model_catalog_product->getProductOptions($this->request->get['product_id']);
					
			foreach ($options as $option) { 
				$option_value_data = array();
				
				foreach ($option['option_value'] as $option_value) {
					$option_value_data[] = array(
            			'option_value_id' => $option_value['product_option_value_id'],
            			'name'            => $option_value['name'],
            			'price'           => (float)$option_value['price'] ? $this->currency->format($this->tax->calculate($option_value['price'], $product_info['tax_class_id'], $this->config->get('config_tax'))) : FALSE,
            			'prefix'          => $option_value['prefix']
          			);
				}
				
				$this->data['options'][] = array(
          			'option_id'    => $option['product_option_id'],
          			'name'         => $option['name'],
          			'option_value' => $option_value_data
				);
			}
to simply this:

Code: Select all

$options = $this->model_catalog_product->getProductOptions($this->request->get['product_id']);

// Remove +0.0000 prices
foreach ($options as $k => $option) {
	foreach ($option['option_value'] as $j => $option_value) {
		if ((float)$option_value['price']) {
			$options[$k]['option_value'][$j]['price'] = $this->currency->format($this->tax->calculate($option_value['price'], $product_info['tax_class_id'], $this->config->get('config_tax')));
		} else {
			$options[$k]['option_value'][$j]['price'] = FALSE;
		}
	}
}

$this->data['options'] = $options;
STEP 3: EDIT: view/theme/default/template/product/product.tpl
CHANGE "option_id" to "product_option_id"
CHANGE "option_value_id" to "product_option_value_id"

This will make the product options dynamic and no more double massaging.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by flightoffancy » Mon Feb 01, 2010 5:02 am

Is this for 1.4.0 or earlier versions?

New member

Posts

Joined
Fri Jan 22, 2010 9:34 pm

Post by Qphoria » Mon Feb 01, 2010 11:31 am

its for all versions. But is meant more for the developer to add to the core. It doesn't impact the normal user until they start trying to work mods into it.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Johnathan » Tue Feb 09, 2010 12:54 am

Thanks for this mod; hopefully it gets incorporated into the core. I think there's one small error in your suggested code in Step 2:

Code: Select all

$options = $this->getProductOptions($this->request->get['product_id']);
should be:

Code: Select all

$options = $this->model_catalog_product->getProductOptions($this->request->get['product_id']);

Image
Image Image Image Image


User avatar
Global Moderator

Posts

Joined
Fri Dec 18, 2009 3:08 am


Post by Qphoria » Tue Feb 09, 2010 1:21 am

Ah.. yea.. sorry.. when making this I originally made it my own mod so I used my own localized function. But you are correct, for a core fix it should be your way. I've updated the original code to include it now.

Image
Donate!|OpenCart Basics|GeoZones
Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am
Who is online

Users browsing this forum: No registered users and 3 guests