<?php
include_once('nicomodule.inc');
class ControllerModuleNicocustomproducts extends NicoModule
{
	
	private function getViewedProducts()
	{
		$viewed_products = array();
        
        if (isset($this->request->cookie['viewed'])) 
        {
			$viewed_products = '';
			if (preg_match('@[0-9]*,?@', $this->request->cookie['viewed']))
			{
				$viewed_products = explode(',', $this->request->cookie['viewed']);
			}
        } else if (isset($this->session->data['viewed'])) 
        {
      		$viewed_products = $this->session->data['viewed'];
    	}
        
        if (isset($this->request->get['route']) && $this->request->get['route'] == 'product/product') 
        {
            
            $product_id = (int)$this->request->get['product_id'];   
               
            $viewed_products = array_diff($viewed_products, array($product_id));
            
            array_unshift($viewed_products, $product_id);
            
            setcookie('viewed', implode(',',$viewed_products), time() + 60 * 60 * 24 * 30, '/', $this->request->server['HTTP_HOST']);
        
            if (!isset($this->session->data['viewed']) || $this->session->data['viewed'] != $viewed_products) 
            {
          		$this->session->data['viewed'] = $viewed_products;
        	}
        } 
        
        return $viewed_products;
	}
	
	private function getRandomProducts($limit, $cache = true)
	{
		$key = md5($_SERVER['REQUEST_URI']);
		if (!$limit) $limit = 5;
		if ($cache)
		{
			$products = $this->cache->get('productsRandom' . $key);
			if ($products && is_array($products)) return $products = shuffle($products);
		}
		
		$sql = 'SELECT * FROM '. DB_PREFIX . 'product p
					LEFT OUTER JOIN `' . DB_PREFIX . 'product_description` pd
					ON p.product_id = pd.product_id GROUP BY p.product_id ORDER BY rand() LIMIT ' . $limit ;
		
		$random = $this->db->query($sql);
			
		$products = $random->rows;

		if ($cache)
		{
			$this->cache->set('productsRandom' . $key, $products);
		}
		
		return $products;
	}
		
	
	private function getProductAlsoBought($product_id, $max_row)
	{
		$product_data = $this->cache->get('productAlsoBought.' . (int)$product_id);
		
		if (!$product_data) {
			$product_data = array();
	
			$sql = "
				SELECT
					DISTINCT 
					  p.product_id
					, p.tax_class_id
					, pd.name AS name
					, p.image
					, p.price
					, p.model
					, m.name AS manufacturer
					, ss.name AS stock
					, (SELECT 
							AVG(r.rating) 
						FROM `" . DB_PREFIX . "review` r 
						WHERE p.product_id = r.product_id 
						GROUP BY r.product_id) AS rating 
					, COUNT(*) AS cnt
				FROM `" . DB_PREFIX . "order_product` op
				INNER JOIN `" . DB_PREFIX . "order` o
					ON o.order_id = op.order_id
				INNER JOIN `" . DB_PREFIX . "product` p
					ON op.product_id = p.product_id
				LEFT OUTER JOIN `" . DB_PREFIX . "product_description` pd
					ON p.product_id = pd.product_id
				LEFT OUTER JOIN `" . DB_PREFIX . "product_to_store` p2s
					ON p.product_id = p2s.product_id
				LEFT OUTER JOIN `" . DB_PREFIX . "manufacturer` m
					ON p.manufacturer_id = m.manufacturer_id
				LEFT OUTER JOIN `" . DB_PREFIX . "stock_status` ss
					ON p.stock_status_id = ss.stock_status_id
				WHERE o.customer_id IN (
						SELECT
							o.customer_id
						FROM `" . DB_PREFIX . "order_product` op
						INNER JOIN `" . DB_PREFIX . "order` o
							ON o.order_id = op.order_id
						WHERE op.product_id = '" . (int)$product_id . "'
						GROUP BY o.customer_id)
					AND p.product_id != '" . (int)$product_id . "'
					AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "'
					AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'
					AND ss.language_id = '" . (int)$this->config->get('config_language_id') . "'
					AND p.date_available <= NOW()
					AND p.status = '1'
				GROUP BY op.product_id
				ORDER BY COUNT(*) DESC
				LIMIT 0, ".$max_row.";
			";

			$product_also_bought_query = $this->db->query($sql);
			
			$products = $product_also_bought_query->rows;
			
			$this->cache->set('productAlsoBought.' . (int)$product_id, $products);
		}
		
		return $product_data;
	}
		
	public function index($setting) 
	{
		if (!$this->is_filter_ok($setting)) return false;

		$opencart_version = (int)str_replace('.','',VERSION);
		
		if ($opencart_version >= 2000)
		{
			$this->load->language('module/nicocustomproducts');
		} else
		{
			$this->language->load('module/nicocustomproducts'); 
		}
		
		$resize_method = 0;
		if (isset($setting['resize_method']) && $setting['resize_method'] == 'cropresize')
		{
			$resize_method = 1;
		}

				
		$lang_code = $this->language->get('code');		
		$data = $setting;
		if (!isset($data['position'])) $data['position'] = rand(0, 10);
		if (!isset($data['layout_id'])) $data['layout_id'] = 0;
		if (!isset($data['sort_order'])) $data['sort_order'] = rand(0, 10);

      	$data['heading_title'] = $this->language->get('heading_title');
		
		$data['button_cart'] = $this->language->get('button_cart');
		
		$this->load->model('design/banner');

		$this->load->model('catalog/product'); 
		
		$this->load->model('tool/image');
		
		$this->load->model('tool/nicoimage');
	

		$data['products'] = array();

		
		$data['title'] = isset($setting['title'][$lang_code])?$setting['title'][$lang_code]:isset($setting['title']['en'])?$setting['title']['en']:'';
		$data['cols_xs'] = isset($setting['module_cols_xs'])?$setting['module_cols_xs']:1;
		$data['cols_sm'] = isset($setting['module_cols_sm'])?$setting['module_cols_sm']:2;
		$data['cols_md'] = isset($setting['module_cols_md'])?$setting['module_cols_md']:4;
		$data['cols_lg'] = isset($setting['module_cols_lg'])?$setting['module_cols_lg']:4;
		
		$data['type'] = isset($setting['type'])?$setting['type']:'list';
		
		//var_dump($setting);
		
		if (isset($setting['section'])) foreach ($setting['section'] as $nr => $section)
		{
			$data['section'][$nr]['title'] = isset($section['title'][$lang_code])?$section['title'][$lang_code]:$section['title']['en'];
			$products = array();
			switch($section['section_type'])
			{
				case 'autocomplete':
					$products_list = explode(',', $section['product_list']);

					foreach ($products_list as $product_id) 
					{
						$products[] = $this->model_catalog_product->getProduct((int)$product_id);
					}
					break;
				case 'latest':
					$opt = array(
					'sort'  => 'p.date_added',
					'order' => 'DESC',
					'start' => 0,
					'limit' => $section['latest_limit']
					);

					//$products = $this->model_catalog_product->getProducts($data);
					$products = $this->model_catalog_product->getLatestProducts($section['latest_limit']);
					break;
				case 'bestsellers':
					$products = $this->model_catalog_product->getBestSellerProducts($section['bestsellers_limit']);
					break;
				case 'specials':
					$opt = array(
						'sort'  => 'pd.name',
						'order' => 'ASC',
						'start' => 0,
						'limit' => $section['specials_limit']
					);

					$products = $this->model_catalog_product->getProductSpecials($opt);
					break;
				case 'category':
					$opt = array(
						'filter_category_id' => $section['category'],
						'sort'               => 'p.product_id',
						'order'              => $section['category_sort'],
						'start'              => 0,
						'limit'              => $section['category_limit']
					);
							
					$products = $this->model_catalog_product->getProducts($opt);
					break;
				case 'manufacturer':
					$opt = array(
						'filter_manufacturer_id' => $section['manufacturer'], 
						'sort'               => 'p.product_id',
						'order'              => $section['manufacturer_sort'],
						'start'              => 0,
						'limit'              => $section['manufacturer_limit']
					);
							
					$products = $this->model_catalog_product->getProducts($opt);
					break;
					
				case 'popular':

					$products = $this->model_catalog_product->getPopularProducts($section['popular_limit']);
					break;
				case 'recentlyviewed':

					$products_list = $this->getViewedProducts();
					
					foreach ($products_list as $product_id) 
					{
						$products[] = $this->model_catalog_product->getProduct((int)$product_id);
					}
					break;
				case 'random':

					$products = $this->getRandomProducts($section['random_limit'], $section['random_cache'] === 'true'? true: false);
					break;
				case 'related':

					if (isset($this->request->get['product_id']))
					//$products = $this->model_catalog_product->getProductRelated($this->request->get['product_id'])
					$products = $this->getProductAlsoBought($this->request->get['product_id'], $section['related_limit']);
					break;
				case 'alsobought':

					if (isset($this->request->get['product_id']))
					$products = $this->getProductAlsoBought($this->request->get['product_id'], $section['alsobought_limit']);
					break;
			}
			
			
			if (isset($products) && is_array($products)) foreach ($products as $product_info) 
			{
				if ($product_info) 
				{
					if ($product_info['image']) 
					{
						if ($resize_method)
						$image = $this->model_tool_nicoimage->cropsize($product_info['image'], $setting['image_width'], $setting['image_height']);
						else 
						$image = $this->model_tool_image->resize($product_info['image'], $setting['image_width'], $setting['image_height']);
					} else {
						$image = false;
					}
					
					$additional_image = '';
					
					if ($setting['additional_image'] == '1')
					{
						$product_images = $this->model_catalog_product->getProductImages($product_info['product_id']);
						if (isset($product_images[1]))
						{
							if ($resize_method)
							$additional_image = $this->model_tool_nicoimage->cropsize($product_images[1]['image'], $setting['image_width'], $setting['image_height']);
							else 
							$additional_image = $this->model_tool_image->resize($product_images[1]['image'], $setting['image_width'], $setting['image_height']);
						}
					}

					if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) 
					{
						$price = $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')));
					} else {
						$price = false;
					}
							
					if (isset($product_info['special']) && (float)$product_info['special']) 
					{
						$special = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')));
					} else {
						$special = false;
					}
					
					if ($this->config->get('config_review_status') && isset($product_info['rating'])) 
					{
						$rating = $product_info['rating'];
					} else {
						$rating = false;
					}
					
					$product = 
					array(
						'product_id' => $product_info['product_id'],
						'thumb'   	 => $image,
						'name'    	 => $product_info['name'],
						
						'price'   	 => $price,
						'special' 	 => $special,
						'rating'     => $rating,
						'href'    	 => $this->url->link('product/product', 'product_id=' . $product_info['product_id']),
						'additional_image' 	 => $additional_image
					);
					
					if (isset($product_info['description']))  $product['description'] = utf8_substr(strip_tags(html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8')), 0, 100) . '..';
					if (isset($product_info['reviews']))  $product['reviews'] = sprintf($this->language->get('text_reviews'), (int)$product_info['reviews']);

					$data['products'][$nr][] = $product;
				}
			}
		}

		if ($opencart_version >= 2000)
		{
			if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/nicocustomproducts.tpl')) 
			{
				return $this->load->view($this->config->get('config_template') . '/template/module/nicocustomproducts.tpl', $data);
			} else {
				return $this->load->view('default/template/module/nicocustomproducts.tpl', $data);
			}
		} else
		{
			$this->data = $data;
			if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/nicocustomproducts.tpl')) 
			{
				$this->template = $this->config->get('config_template') . '/template/module/nicocustomproducts.tpl';
			} else {
				$this->template = 'default/template/module/nicocustomproducts.tpl';
			}

			$this->render();
		}
	}
}
?>
