<?php
/**
 * Category related functions
 *
 * @package 	CSVIVirtueMart
 * @subpackage 	Import
 * @author 		Roland Dalmulder
 * @link 		http://www.csvimproved.com
 * @copyright 	Copyright (C) 2006 - 2012 RolandD Cyber Produksi
 * @license 	GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
 * @version 	$Id: category.php 1892 2012-02-11 11:01:09Z RolandD $
 */
 
defined( '_JEXEC' ) or die( 'Direct Access to this location is not allowed.' );

/**
 * Processor for product details
 *
 * Main processor for importing categories.
 *
 * @package CSVIVirtueMart
 */
class CsvivirtuemartModelCategory extends JModel {
	
	// Private tables
	/** @var object contains the vm_category table */
	private $_vm_category = null;
	/** @var object contains the vm_category_xref table */
	private $_vm_category_xref = null;
	/** @var object contains the vm_product_category_xref table */
	private $_vm_product_category_xref = null;
	/** @var array contains the category cache */
	private $_category_cache = array();
	/** @var string Category separator */
	private $_catsep = null;
	
	// Public variables
	/** @var integer contains the category path for a product */
	public $category_path = null;
	/** @var integer contains the category ID for a product */
	public $category_id = null;
	/** @var integer contains the category setting for publishing */
	public $category_publish = 'Y';
	
	// Private variables
	/** @var bool contains setting if the database tables have been loaded */
	private $_tables_loaded = false;
	
	/**
	 * Here starts the processing 
	 * 
	 * @copyright 
	 * @author 		RolandD
	 * @todo
	 * @see 
	 * @access 		public
	 * @param 
	 * @return 
	 * @since 		3.0
	 */
	public function getStart() {
		if (!$this->_tables_loaded) $this->_loadTables();
	}
	
	/**
	 * Gets the ID belonging to the category path 
	 * 
	 * @copyright 
	 * @author 		RolandD
	 * @todo 
	 * @see 
	 * @access 		public
	 * @param 
	 * @return		array	containing category_id 
	 * @since 		3.0
	 */
	public function getCategoryIdFromPath($category_path) {
		// Check for any missing categories, otherwise create them
		$category = $this->_csvCategory($category_path);
		
		return array('category_id' => $category[0]);
	}
	
  	/**
  	 * Inserts the category/categories for a product
	 *
	 * Any existing categories will be removed first, after that the new
	 * categories will be imported. 
  	 * 
  	 * @copyright 
  	 * @author		RolandD 
  	 * @todo 
  	 * @see 		_csvCategory()
  	 * @access 
  	 * @param 		integer	$product_id 	contains the product ID the category/categories belong to
	 * @param 		integer	$category_path 	contains the category/categories path for the product
	 * @param 		integer	$category_id 	contains a single or array of category IDs
	 * @param 		integer	$product_list 	the product order in the category
  	 * @return 
  	 * @since 
  	 */
  	public function checkCategoryPath($product_id=false, $category_path=false, $category_id=false, $product_list='NULL') {
		$csvilog = JRequest::getVar('csvilog');
		$template = JRequest::getVar('template');
		
		$csvilog->addDebug('Checking category');
		
		// Check if there is a product ID
		if (!$product_id) return false;
		else {
			// If product_parent_id is true, we have a child product, child products do not have category paths
			// We have a category path, need to find the ID
			if (!$category_id) {
				// Use CsvCategory() method to confirm/add category tree for this product
				// Modification: $category_id now is an array
				$category_id = $this->_csvCategory($category_path);
			}
			// We have a category_id, no need to find the path
			if ($category_id) {
				// Delete old entries only if the user wants us to
				if (!$template->getValue('append_categories', 'category', false)) {
					$db = JFactory::getDBO();
					$q = "DELETE FROM #__vm_product_category_xref WHERE product_id = ".$product_id;
					$db->setQuery($q);
					$db->query();
					$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_DELETE_OLD_CATEGORY_XREF'), true);
				}
				else $csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_NOT_DELETE_OLD_CATEGORY_XREF'));
				
				// Insert new product/category relationships
				$category_xref_values = array('product_id' => $product_id, 'product_list' => $product_list);
				foreach( $category_id as $value ) {
					$category_xref_values['category_id'] = $value;
					$this->_vm_product_category_xref->bind($category_xref_values);
					$this->_vm_product_category_xref->store();
					$this->_vm_product_category_xref->reset();
					$category_xref_values['category_id'] = '';
				}
			}
		}
	}
	
	/**
	 * Load the category related tables 
	 * 
	 * @copyright 
	 * @author		RolandD 
	 * @todo 
	 * @see 
	 * @access 		private
	 * @param 
	 * @return 
	 * @since 		3.0
	 */
	private function _loadTables() {
		$this->_vm_category = $this->getTable('vm_category');
		$this->_vm_category_xref = $this->getTable('vm_category_xref');
		$this->_vm_product_category_xref = $this->getTable('vm_product_category_xref');
		$this->_tables_loaded = true;
	}
	
	/**
	 * Cleaning the product related tables 
	 * 
	 * @copyright 
	 * @author 		RolandD
	 * @todo 
	 * @see 
	 * @access 		private
	 * @param 
	 * @return 
	 * @since 		3.0
	 */
	private function _cleanTables() {
		$this->_vm_category->reset();
		$this->_vm_category_xref->reset();
		
		// Clean the local variables
		$class_vars = get_class_vars(get_class($this));
		foreach ($class_vars as $name => $value) {
			if (substr($name, 0, 1) != '_') $this->$name = $value;
		}
	}
	
	/**
	 * Creates categories from slash delimited line
	 * 
	 * @copyright 
	 * @author 		John Syben, RolandD
	 * @todo 
	 * @see 
	 * @access 
	 * @param 		array	$category_path	contains the category/categories for a product
	 * @return 		array containing category IDs
	 * @since 
	 */
	private function _csvCategory($category_path) {
		$db = JFactory::getDBO();
		$csvilog = JRequest::getVar('csvilog');
		
		// Load the category separator
		if (is_null($this->_catsep)) {
			$template = JRequest::getVar('template');
			$this->_catsep = $template->getValue('category_separator', 'general', '/');
		}
		
		// Check if category_path is an array, if not make it one
		if (!is_array($category_path)) $category_path = array($category_path);
		
		// Get all categories in this field delimited with |
		foreach( $category_path as $line ) {
			$csvilog->addDebug('Checking category path: '.$line);
			
			// Explode slash delimited category tree into array
			$category_list = explode($this->_catsep, $line);
			$category_count = count($category_list);
			
			$category_parent_id = '0';
			
			// For each category in array
			for($i = 0; $i < $category_count; $i++) {
				// Check the cache first
				if (array_key_exists($category_parent_id.'.'.$category_list[$i], $this->_category_cache)) {
					$category_id = $this->_category_cache[$category_parent_id.'.'.$category_list[$i]];
				}
				else {
					// See if this category exists with it's parent in xref
					$q = "SELECT #__vm_category.category_id FROM #__vm_category, #__vm_category_xref ";
					$q .= "WHERE #__vm_category.category_name=".$db->Quote($category_list[$i])." ";
					$q .= "AND #__vm_category_xref.category_child_id=#__vm_category.category_id ";
					$q .= "AND #__vm_category_xref.category_parent_id='".$category_parent_id."'";
					$db->setQuery($q);
					$category_id = $db->loadResult();
					$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_CHECK_CATEGORY_EXISTS'), true);
					
					// Add result to cache
					$this->_category_cache[$category_parent_id.'.'.$category_list[$i]] = $category_id;
				}
				
				// Category does not exist - create it
				if (is_null($category_id)) {
					$timestamp = time();

					// Let's find out the last category in the level of the new category
					$q = "SELECT MAX(list_order) + 1 AS list_order FROM #__vm_category, #__vm_category_xref ";
					$q .= "WHERE category_parent_id='".$category_parent_id."' ";
					$q .= "AND category_child_id=category_id ";
					$db->setQuery($q);
					$list_order = $db->loadResult();
					if (is_null($list_order)) $list_order = 1;
							
					// Find the category and flypage setting
					$vm_config = new CsviVmConfig();
					
					// Add category
					$this->_vm_category->setValue('vendor_id', '1');
					$this->_vm_category->setValue('category_name', $category_list[$i]);
					$this->_vm_category->setValue('cdate', $timestamp);
					$this->_vm_category->setValue('mdate', $timestamp);
					$this->_vm_category->setValue('list_order', $list_order);
					$this->_vm_category->setValue('category_publish', $this->category_publish);
					$this->_vm_category->setValue('category_browsepage', $vm_config->getSetting('category_template'));
					$this->_vm_category->setValue('products_per_row', $vm_config->getSetting('products_per_row'));
					$this->_vm_category->setValue('category_flypage', $vm_config->getSetting('flypage'));
					$this->_vm_category->store();
					
					$csvilog->addDebug('Add new category:', true);
					
					$category_id = $this->_vm_category->getValue('category_id');
					
					// Add result to cache
					$this->_category_cache[$category_parent_id.'.'.$category_list[$i]] = $category_id;
					
					// Create xref with parent
					$this->_vm_category_xref->setValue('category_parent_id', $category_parent_id);
					$this->_vm_category_xref->setValue('category_child_id', $category_id);
					$this->_vm_category_xref->store();
					
					$csvilog->addDebug('Add new category xref:', true);
					
					// Clean for the next row
					$this->_vm_category->reset();
					$this->_vm_category_xref->reset();
					
				}
				// Set this category as parent of next in line
				$category_parent_id = $category_id;
			}
			$category[] = $category_id;
		}
		// Return an array with the last category_ids which is where the product goes
		return $category;
	}
}
?>