<?php
/**
 * Product export class
 *
 * @package 	CSVIVirtueMart
 * @subpackage 	Export
 * @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: productexport.php 1892 2012-02-11 11:01:09Z RolandD $
 */

defined( '_JEXEC' ) or die( 'Direct Access to this location is not allowed.' );

/**
 * Processor for product exports
 *
 * @package 	CSVIVirtueMart
 * @subpackage 	Export
 */
class CsvivirtuemartModelProductExport extends CsvivirtuemartModelExportfile {

	// Private variables
	private $_sef = null;
	private $_domainname = null;

	/**
	 * Product export
	 *
	 * Exports product data to either csv, xml or HTML format
	 *
	 * @copyright
	 * @author		RolandD
	 * @todo
	 * @see
	 * @access 		public
	 * @param
	 * @return 		void
	 * @since 		3.0
	 */
	public function getStart() {
		// Get some basic data
		$db = JFactory::getDBO();
		$csvidb = new CsviDb();
		$csvilog = JRequest::getVar('csvilog');
		$template = JRequest::getVar('template');
		$exportclass =  JRequest::getVar('export.class');
		$export_fields = JRequest::getVar('export.fields');
		$this->_domainname = CsviHelper::getDomainName();

		// Build something fancy to only get the fieldnames the user wants
		$userfields = array();
		foreach ($export_fields as $column_id => $field) {
			if ($field->process) {
				switch ($field->field_name) {
					case 'attribute_name':
					case 'attribute_value':
						$userfields[] = '#__vm_product_attribute.attribute_name';
						$userfields[] = '#__vm_product_attribute.attribute_value';
						break;
					case 'attribute_with_tax':
						$userfields[] = '#__vm_product.attribute';
						$userfields[] = '#__vm_tax_rate.tax_rate';
						break;
					case 'category_id':
					case 'category_path':
						$userfields[] = '#__vm_product_category_xref.category_id';
						$userfields[] = '#__vm_product.product_id AS main_product_id';
						break;
					case 'cdate':
					case 'product_cdate':
						$userfields[] = '#__vm_product.cdate';
						break;
					case 'manufacturer_id':
						$userfields[] = '#__vm_manufacturer.manufacturer_id AS manufacturer_id';
						break;
					case 'manufacturer_category_id':
						$userfields[] = 'mf_category_id AS manufacturer_category_id';
						break;
					case 'manufacturer_desc':
						$userfields[] = 'mf_desc AS manufacturer_desc';
						break;
					case 'manufacturer_email':
						$userfields[] = 'mf_email AS manufacturer_email';
						break;
					case 'manufacturer_name':
						$userfields[] = 'mf_name AS manufacturer_name';
						break;
					case 'manufacturer_url':
						$userfields[] = 'mf_url AS manufacturer_url';
						break;
					case 'mdate':
					case 'product_mdate':
						$userfields[] = '#__vm_product.mdate';
						break;
					case 'picture_url':
						$userfields[] = '#__vm_product.product_full_image';
						break;
					case 'product_price':
						$userfields[] = '#__vm_product_price.product_price';
						$userfields[] = '#__vm_product_price.product_currency';
						$userfields[] = '#__csvivirtuemart_currency.currency_code';
						$userfields[] = '#__csvivirtuemart_currency.currency_rate';
						break;
					case 'price_with_discount':
						$userfields[] = '#__vm_product_price.product_price';
						$userfields[] = '#__vm_product_price.product_currency';
						$userfields[] = '#__vm_product_discount.amount AS product_discount';
						$userfields[] = '#__vm_product_discount.is_percent AS product_discount_is_percent';
						$userfields[] = '#__vm_tax_rate.tax_rate';
						$userfields[] = '#__csvivirtuemart_currency.currency_code';
						$userfields[] = '#__csvivirtuemart_currency.currency_rate';
						break;
					case 'price_with_tax':
						$userfields[] = '#__vm_product_price.product_price';
						$userfields[] = '#__vm_product_price.product_currency';
						$userfields[] = '#__vm_tax_rate.tax_rate';
						$userfields[] = '#__csvivirtuemart_currency.currency_code';
						$userfields[] = '#__csvivirtuemart_currency.currency_rate';
						break;
					case 'product_box':
						$userfields[] = '#__vm_product.product_packaging';
						break;
					case 'product_tax':
						$userfields[] = '#__vm_tax_rate.tax_rate';
						break;
					case 'product_discount':
						$userfields[] = '#__vm_product_discount.amount AS product_discount';
						$userfields[] = '#__vm_product_discount.is_percent AS product_discount_is_percent';
						break;
					case 'product_discount_date_end':
						$userfields[] = '#__vm_product_discount.end_date AS product_discount_date_end';
						break;
					case 'product_discount_date_start':
						$userfields[] = '#__vm_product_discount.start_date AS product_discount_date_start';
						break;
					case 'product_list':
						$userfields[] = '#__vm_product_category_xref.product_list';
						break;
					case 'product_parent_sku':
					case 'attribute_values':
					case 'attribute':
					case 'attributes':
						$userfields[] = '#__vm_product.product_parent_id';
						$userfields[] = '#__vm_product.attribute';
						break;
					case 'product_id':
					case 'related_products':
						$userfields[] = '#__vm_product.product_id AS main_product_id';
						break;
					case 'product_sku':
						$userfields[] = '#__vm_product.product_id AS main_product_id';
						$userfields[] = '#__vm_product.product_sku';
						break;
					case 'product_url':
						$userfields[] = '#__vm_product.product_id AS main_product_id';
						$userfields[] = '#__vm_product.product_url';
						$userfields[] = '#__vm_product.product_parent_id';
						break;
					case 'shopper_group_name':
						$userfields[] = '#__vm_shopper_group.shopper_group_name';
						break;
					case 'shopper_group_id':
						$userfields[] = '#__vm_shopper_group.shopper_group_id';
						break;
					case 'vendor_id':
						$userfields[] = '#__vm_product.vendor_id';
						break;
					case 'producttypenames':
						$userfields[] = '#__vm_product.product_id AS main_product_id';
						break;
					// Man made fields, do not export them
					case 'custom':
					case 'custom_shipping':
					case 'product_box':
						break;
					default:
						$userfields[] = '`'.$field->field_name.'`';
						break;
				}
			}
		}

		/** Export SQL Query
		 * Get all products - including items
		 * as well as products without a price
		 */
		$userfields = array_unique($userfields);
		$q = "SELECT ".implode(",\n", $userfields);
		$q .= ' FROM #__vm_product
			LEFT JOIN #__vm_product_price
			ON #__vm_product.product_id = #__vm_product_price.product_id
			LEFT JOIN #__vm_product_mf_xref
			ON #__vm_product.product_id = #__vm_product_mf_xref.product_id
			LEFT JOIN #__vm_shopper_group
			ON #__vm_product_price.shopper_group_id = #__vm_shopper_group.shopper_group_id
			LEFT JOIN #__vm_product_discount
			ON #__vm_product.product_discount_id = #__vm_product_discount.discount_id
			LEFT JOIN #__vm_manufacturer
			ON #__vm_product_mf_xref.manufacturer_id = #__vm_manufacturer.manufacturer_id
			LEFT JOIN #__vm_tax_rate
			ON #__vm_product.product_tax_id = #__vm_tax_rate.tax_rate_id
			LEFT JOIN #__vm_product_attribute
			ON #__vm_product.product_id = #__vm_product_attribute.product_id
			LEFT JOIN #__vm_product_attribute_sku
			ON #__vm_product.product_id = #__vm_product_attribute_sku.product_id
			LEFT JOIN #__vm_product_category_xref
			ON #__vm_product.product_id = #__vm_product_category_xref.product_id
			LEFT JOIN #__vm_category
			ON #__vm_product_category_xref.category_id = #__vm_category.category_id
			LEFT JOIN #__csvivirtuemart_currency
			ON #__vm_product_price.product_currency = #__csvivirtuemart_currency.currency_code';


		// Check if there are any selectors
		$selectors = array();

		// Filter by shopper group id
		$shopper_group = $template->getValue('shopper_group_id', 'product', array());
		if ($shopper_group && $shopper_group[0] != 'none') {
			$selectors[] = "#__vm_product_price.shopper_group_id IN ('".implode("','", $shopper_group)."')";
		}

		// Filter by published state
		$product_publish = $template->getValue('publish_state', 'general');
		if (!empty($product_publish)) {
			$selectors[] = '#__vm_product.product_publish = '.$db->Quote($product_publish);
		}

		// Filter by manufacturer
		$manufacturer = $template->getValue('manufacturers', 'product', array());
		if ($manufacturer && $manufacturer[0] != 'none') {
			$selectors[] = "#__vm_manufacturer.manufacturer_id IN ('".implode("','", $manufacturer)."')";
		}

		// Filter by product category
		/**
		 * We are doing a selection on categories, need to redo the query to make sure child products get included
		 * 1. Search all product ID's for that particular category
		 * 2. Search for all child product ID's
		 * 3. Load all products with these ids
		 */
		$productcategories = $template->getValue('productcategories', 'product', false);
		if ($productcategories && $productcategories[0] != '') {
			$product_ids = array();

			// If selected get products of all subcategories as well
			if ($template->getValue('incl_subcategory', 'product', false)) {
				$q_subcat_ids = "SELECT category_child_id
							FROM #__vm_category_xref
							WHERE category_parent_id IN ('".implode("','", $productcategories)."')";
				$db->setQuery($q_subcat_ids);
				$subcat_ids = $db->loadResultArray();
				$productcategories = array_merge($productcategories, $subcat_ids);
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);
			}

			// Get only the parent products and products without children
			if ($template->getValue('parent_only', 'product', 0, 'bool')) {
				// Get all product IDs in the selected categories
				$q_product_ids = "SELECT p.product_id
					FROM #__vm_product p
					LEFT JOIN #__vm_product_category_xref x
					ON p.product_id = x.product_id
					WHERE x.category_id IN ('".implode("','", $productcategories)."')
					AND p.product_parent_id = 0";
				$db->setQuery($q_product_ids);
				$product_ids = $db->loadResultArray();
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);
			}
			// Get only the child products and products without children
			else if ($template->getValue('child_only', 'product', 0, 'bool')) {
				// Load all non child IDs
				$q_child = "SELECT p.product_id
							FROM #__vm_product p
							LEFT JOIN #__vm_product_category_xref x
							ON p.product_id = x.product_id
							WHERE x.category_id IN ('".implode("','", $productcategories)."')";
				$db->setQuery($q_child);
				$allproduct_ids = $db->loadResultArray();
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

				// Get all child product IDs in the selected categories
				$q_child = "SELECT p.product_id
					FROM #__vm_product p
					WHERE p.product_parent_id IN ('".implode("','", $allproduct_ids)."')";
				$db->setQuery($q_child);
				$child_ids = $db->loadResultArray();
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

				// Get all parent product IDs in the selected categories
				$q_child = "SELECT p.product_parent_id
					FROM #__vm_product p
					WHERE p.product_id IN ('".implode("','", $child_ids)."')";
				$db->setQuery($q_child);
				$parent_ids = $db->loadResultArray();
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

				// Combine all the IDs
				$product_ids = array_merge($child_ids, array_diff($allproduct_ids, $parent_ids));
			}
			else {
				// Get all product IDs
				$q_product_ids = "SELECT p.product_id
					FROM #__vm_product p
					LEFT JOIN #__vm_product_category_xref x
					ON p.product_id = x.product_id
					WHERE x.category_id IN ('".implode("','", $productcategories)."')";
				$db->setQuery($q_product_ids);
				$product_ids = $db->loadResultArray();
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

				// Get all child product IDs
				if ($product_ids) {
					$q_childproduct_ids = "SELECT p.product_id
						FROM #__vm_product p
						WHERE p.product_parent_id IN ('".implode("','", $product_ids)."')";
					$db->setQuery($q_childproduct_ids);
					$childproduct_ids = $db->loadResultArray();
					$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

					// Now we have all the product IDs
					$product_ids = array_merge($product_ids, $childproduct_ids);
				}
			}

			// Check if the user want child products
			if (!empty($product_ids)) $selectors[] = '#__vm_product.product_id IN (\''.implode("','", $product_ids).'\')';
		}
		else {
			// Filter by published category state
			$category_publish = $template->getValue('publish_state_categories', 'product');

			// Filter on parent products and products without children
			if ($template->getValue('parent_only', 'product', 0, 'bool')) {
				$selectors[] = '#__vm_product.product_parent_id = 0';
				if (!empty($category_publish)) {
					$selectors[] = '#__vm_category.category_publish = '.$db->Quote($category_publish);
				}
			}

			// Filter on child products and products without children
			else if ($template->getValue('child_only', 'product', 0, 'bool')) {
				// Load all non child IDs
				$q_nonchild = 'SELECT #__vm_product.product_id FROM #__vm_product ';
				$state = ($category_publish == 'Y') ? 'N' : 'Y';
				if (!empty($category_publish)) {
					$q_nonchild .= 'LEFT JOIN #__vm_product_category_xref
						ON #__vm_product.product_id = #__vm_product_category_xref.product_id
						LEFT JOIN #__vm_category
						ON #__vm_product_category_xref.category_id = #__vm_category.category_id
						WHERE #__vm_category.category_publish = '.$db->Quote($state);
				}
				$db->setQuery($q_nonchild);
				$nonchild_ids = $db->loadResultArray();
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

				// Get the child IDs from the filtered category
				if (!empty($category_publish)) {
					$q_nonchild = 'SELECT #__vm_product.product_id FROM #__vm_product ';
					$q_nonchild .= 'LEFT JOIN #__vm_product_category_xref
						ON #__vm_product.product_id = #__vm_product_category_xref.product_id
						LEFT JOIN #__vm_category
						ON #__vm_product_category_xref.category_id = #__vm_category.category_id
						WHERE #__vm_product.product_parent_id IN (\''.implode("','", $nonchild_ids).'\')';
					$q_nonchild .= ' GROUP BY product_id';
					$db->setQuery($q_nonchild);
					$child_ids = $db->loadResultArray();
					$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);
					if (is_array($child_ids)) $nonchild_ids = array_merge($nonchild_ids, $child_ids);
				}

				$selectors[] = '#__vm_product.product_id NOT IN (\''.implode("','", $nonchild_ids).'\')';
			}
			else {
				if (!empty($category_publish)) {
					// Get all product IDs
					$q_product_ids = "SELECT p.product_id
						FROM #__vm_product p
						LEFT JOIN #__vm_product_category_xref x
						ON p.product_id = x.product_id
						LEFT JOIN #__vm_category c
						ON x.category_id = c.category_id
						WHERE c.category_publish = ".$db->Quote($category_publish);
					$db->setQuery($q_product_ids);
					$product_ids = $db->loadResultArray();
					$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

					// Get all child product IDs
					if ($product_ids) {
						$q_childproduct_ids = "SELECT p.product_id
							FROM #__vm_product p
							WHERE p.product_parent_id IN ('".implode("','", $product_ids)."')";
						$db->setQuery($q_childproduct_ids);
						$childproduct_ids = $db->loadResultArray();
						$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);

						// Now we have all the product IDs
						$product_ids = array_merge($product_ids, $childproduct_ids);
					}

					// Check if the user want child products
					if (!empty($product_ids)) $selectors[] = '#__vm_product.product_id IN (\''.implode("','", $product_ids).'\')';
				}
			}
		}

		// Filter by stocklevel start
		$stocklevelstart = $template->getValue('stocklevelstart', 'product');
		if (strlen($stocklevelstart) > 0) {
			$selectors[] = '#__vm_product.product_in_stock >= '.$stocklevelstart;
		}

		// Filter by stocklevel end
		$stocklevelend = $template->getValue('stocklevelend', 'product');
		if (strlen($stocklevelend) > 0) {
			$selectors[] = '#__vm_product.product_in_stock <= '.$stocklevelend;
		}

		// Filter by product SKU
		$productskufilter = $template->getValue('productskufilter', 'product');
		if ($productskufilter) {
			if (strpos($productskufilter, ',')) {
				$skus = explode(',', $productskufilter);
				$wildcard = '';
				$normal = array();
				foreach ($skus as $sku) {
					if (strpos($sku, '%')) {
						$wildcard .= "#__vm_product.product_sku LIKE '".$sku."' OR ";
					}
					else $normal[] = "'".$sku."'";
				}
				//if (substr($wildcard, -3) == 'OR ') $wildcard = substr($wildcard, 0, -4);
				$selectors[] = "(".$wildcard." #__vm_product.product_sku IN (".implode(',', $normal)."))";
			}
			else {
				$wildcard = '';
				$normal = array();
				if (strpos($productskufilter, '%')) {
					$wildcard .= "#__vm_product.product_sku LIKE '".$productskufilter."' OR ";
				}
				else $normal = "'".$productskufilter."'";
				if (!empty($wildcard)  && empty($normal)) {
					if (substr($wildcard, -3) == 'OR ') $wildcard = substr($wildcard, 0, -4);
					$selectors[] = "(".$wildcard.")";
				}
				else if (empty($wildcard) && !empty($normal)) {
					$selectors[] = "(#__vm_product.product_sku = ".$normal.")";
				}
			}
		}

		// Filter on price from
		$priceoperator = $template->getValue('priceoperator', 'product', 'gt');
		$pricefrom = $template->getValue('pricefrom', 'product', 0, 'float');
		$priceto = $template->getValue('priceto', 'product', 0, 'float');
		if (!empty($pricefrom)) {
			switch ($priceoperator) {
				case 'gt':
					$selectors[] = "ROUND(#__vm_product_price.product_price, ".$template->getValue('export_price_format_decimal', 'general', 2, 'int').") > ".$pricefrom;
					break;
				case 'eq':
					$selectors[] = "ROUND(#__vm_product_price.product_price, ".$template->getValue('export_price_format_decimal', 'general', 2, 'int').") = ".$pricefrom;
					break;
				case 'lt':
					$selectors[] = "ROUND(#__vm_product_price.product_price, ".$template->getValue('export_price_format_decimal', 'general', 2, 'int').") < ".$pricefrom;
					break;
				case 'bt':
					$selectors[] = "ROUND(#__vm_product_price.product_price, ".$template->getValue('export_price_format_decimal', 'general', 2, 'int').") BETWEEN ".$pricefrom." AND ".$priceto;
					break;
			}
		}

		// Filter on price to
		$pricequantityendfrom = $template->getValue('pricequantityendfrom', 'product', 0, 'int');
		if ($pricequantityendfrom) {
			$pricequantityendto = $template->getValue('pricequantityendto', 'product', 0, 'int');
			if ($pricequantityendto < $pricequantityendfrom) $pricequantityendto = $pricequantityendfrom;
			$selectors[] = "#__vm_product_price.price_quantity_end BETWEEN ".$pricequantityendfrom." AND ".$pricequantityendto;
		}

		// Filter on price quantity start
		$pricequantitystartfrom = $template->getValue('pricequantitystartfrom', 'product', 0, 'int');
		if ($pricequantitystartfrom) {
			$pricequantitystartto = $template->getValue('pricequantitystartto', 'product', 0, 'int');
			if ($pricequantitystartto < $pricequantitystartfrom) $pricequantitystartto = $pricequantitystartfrom;
			$selectors[] = "#__vm_product_price.price_quantity_start BETWEEN ".$pricequantitystartfrom." AND ".$pricequantitystartto;
		}

		// Filter on price quantity end
		$pricequantityendfrom = $template->getValue('pricequantityendfrom', 'product', 0, 'int');
		if ($pricequantityendfrom) {
			$pricequantityendto = $template->getValue('pricequantityendto', 'product', 0, 'int');
			if ($pricequantityendto < $pricequantityendfrom) $pricequantityendto = $pricequantityendfrom;
			$selectors[] = "#__vm_product_price.price_quantity_end BETWEEN ".$pricequantityendfrom." AND ".$pricequantityendto;
		}

		// Filter on featured products
		$featured = $template->getValue('featured', 'product', false);
		if ($featured) {
			$selectors[] = "#__vm_product.product_special = 'Y'";
		}

		// Filter on cdate
		// Filter on cdate start
		$cdatefrom = $this->convertDate($template->getValue('cdatefrom', 'product', 0));
		$cdateend = $this->convertDate($template->getValue('cdateend', 'product', 0));
		if ($cdatefrom && $cdateend) {
			if ($cdateend < $cdatefrom) $cdateto = $cdatefrom;
			$selectors[] = "#__vm_product.cdate BETWEEN ".$cdatefrom." AND ".$cdateto;
		}
		else if ($cdatefrom) {
			$selectors[] = "#__vm_product.cdate >= ".$cdatefrom;
		}
		else if ($cdateend) {
			$selectors[] = "#__vm_product.cdate <=".$cdateend;
		}

		// Check if we need to attach any selectors to the query
		if (count($selectors) > 0 ) $q .= "\n WHERE ".implode("\n AND ", $selectors)."\n";

		// Ingore fields
		$ignore = array('attribute_list', 'attribute_values', 'attributes', 'attribute_with_tax', 'category_path', 'category_id',
					'picture_url', 'price_with_discount', 'price_with_tax', 'product_box', 'product_parent_sku', 'product_tax',
					'related_products', 'producttypenames', 'custom_shipping');

		// Special fields
		$special = array();
		$special['product_cdate'] = $db->nameQuote('#__vm_product').'.'.$db->nameQuote('cdate');
		$special['product_mdate'] = $db->nameQuote('#__vm_product').'.'.$db->nameQuote('mdate');
		$special['product_id'] = $db->nameQuote('#__vm_product').'.'.$db->nameQuote('product_id');
		$special['manufacturer_category_id'] = $db->nameQuote('#__vm_manufacturer').'.'.$db->nameQuote('mf_category_id');
		$special['manufacturer_desc'] = $db->nameQuote('#__vm_manufacturer').'.'.$db->nameQuote('mf_desc');
		$special['manufacturer_email'] = $db->nameQuote('#__vm_manufacturer').'.'.$db->nameQuote('mf_email');
		$special['manufacturer_name'] = $db->nameQuote('#__vm_manufacturer').'.'.$db->nameQuote('mf_name');
		$special['manufacturer_url'] = $db->nameQuote('#__vm_manufacturer').'.'.$db->nameQuote('mf_url');
		$special['shopper_group_id'] = $db->nameQuote('#__vm_shopper_group').'.'.$db->nameQuote('shopper_group_id');

		// Check if we need to group the orders together
		$groupby = $template->getValue('groupby', 'general', false, 'bool');
		if ($groupby) $q .= $this->getFilterBy('groupby', $ignore, $special);

		// Order by set field
		$q .= $this->getFilterBy('sort', $ignore, $special);

		// Add export limits
		$q .= $this->getExportLimit();

		// Execute the query
		$csvidb->setQuery($q);
		$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_EXPORT_QUERY'), true);
		// There are no records, write SQL query to log
		if ($csvidb->getErrorNum() > 0) {
			$this->addExportContent(JText::sprintf('COM_CSVIVIRTUEMART_ERROR_RETRIEVING_DATA', $csvidb->getErrorMsg()));
			$this->writeOutput();
			$csvilog->AddStats('incorrect', $csvidb->getErrorMsg());
		}
		else {
			$logcount = $csvidb->getNumRows();
			JRequest::setVar('logcount', array('export' => $logcount));
			if ($logcount > 0) {
				while ($record = $csvidb->getRow()) {
					// Start the XML/HTML output
					if ($template->getValue('export_file', 'general') == 'xml' || $template->getValue('export_file', 'general') == 'html') $this->addExportContent($exportclass->NodeStart());
					// Load JoomFish translation if needed
					$joomfish = array();
					if ($template->getValue('use_joomfish', 'product', false)) {
						$jfdb = JFactory::getDBO();
						// Get the product details
						$q = "SELECT value, reference_field
							FROM #__jf_content
							WHERE reference_table = 'vm_product'
							AND language_id = ".$template->getValue('joomfish_language', 'product')."
							AND reference_id = ".$record->main_product_id;
						$jfdb->setQuery($q);
						$joomfish = $jfdb->loadObjectList('reference_field');
					}
					// Process all the export fields
					foreach ($export_fields as $column_id => $field) {
						if ($field->process) {
							$fieldname = $field->field_name;
							$fieldreplace = $field->field_name.$field->column_header;
							// Add the replacement & JoomFish
							if (isset($record->$fieldname)) {
								// Get the JoomFish data
								if (array_key_exists($fieldname, $joomfish)) $fieldvalue = $joomfish[$fieldname]->value;
								else $fieldvalue = $record->$fieldname;
								$fieldvalue = CsviHelper::replaceValue($fieldreplace, $fieldvalue);
							}
							else $fieldvalue = '';
							switch ($fieldname) {
								case 'category_id':
								case 'category_path':
									if ($fieldname == 'category_id') {
										$category_path = trim($this->getCategoryPathId($record->main_product_id));
									}
									else $category_path = trim($this->getCategoryPath($record->main_product_id));
									if (strlen(trim($category_path)) == 0) $category_path = $field->default_value;
									$category_path = CsviHelper::replaceValue($fieldreplace, $category_path);
									$this->addExportField($field->combine, $category_path, $fieldname, $field->column_header, true);
									break;
								case 'attributes':
									if ($record->product_parent_id == 0) {
										$attributes = $export_sku = "";
										$db->setQuery("SELECT attribute_name, attribute_list FROM #__vm_product_attribute_sku WHERE product_id = '".$record->main_product_id."' ORDER BY attribute_list");
										$attr_records = $db->loadObjectList();
										if (count($attr_records) >  0) {
											$has_attributes = true;
											// Get the last array key
											$lastkey = end(array_keys($attr_records));
											foreach ($attr_records as $attr_key => $attr_record) {
												$attributes .= $attr_record->attribute_name. "::". $attr_record->attribute_list;
												if ($lastkey != $attr_key) $attributes .= "|";
											}
										}
									}
									else $attributes = $field->default_value;
									$attributes = trim(CsviHelper::replaceValue($fieldreplace, $attributes));
									$this->addExportField($field->combine, $attributes, $fieldname, $field->column_header);
									break;
								case 'attribute_values':
									$attribute_values = $export_sku = "";
									$db->setQuery( "SELECT attribute_name, attribute_value FROM #__vm_product_attribute WHERE product_id = '".$record->main_product_id."'" );
									$attr_records = $db->loadObjectList();
									if (count($attr_records) >  0) {
										// Get the last array key
										$lastkey = end(array_keys($attr_records));
										foreach ($attr_records as $attr_key => $attr_record) {
											$attribute_values .= $attr_record->attribute_name."::". $attr_record->attribute_value;
											if ($lastkey != $attr_key) $attribute_values .= "|";
										}
									}
									else $attribute_values = $field->default_value;
									$attribute_values = CsviHelper::replaceValue($fieldreplace, $attribute_values);
									$this->addExportField($field->combine, trim($attribute_values), $fieldname, $field->column_header);
									break;
								case 'attribute_with_tax':
									$attribute_with_tax = $record->attribute;
									$matches = array();
									$pattern = '/\[.*?]/';
									// Get all matches
									preg_match_all($pattern, $record->attribute, $matches);

									$find = array('[', ']', '+', '-', '=');
									if (isset($matches[0])) {
										foreach ($matches[0] as $key => $match) {
											// Remove all obsolete characters
											$attribute_price = str_replace($find, '', $match);
											// Remove the tax
											 $attribute_with_tax = str_replace($match, str_replace($attribute_price, number_format($this->ProductPrice(($attribute_price/100)*(100+($record->tax_rate*100))), $template->getValue('export_price_format_decimal', 'general', 2, 'int'), $template->getValue('export_price_format_decsep', 'general'), $template->getValue('export_price_format_thousep', 'general')), $match), $attribute_with_tax);
										}
										if (strlen(trim($attribute_with_tax)) == 0) $attribute_with_tax = $field->default_value;
										$attribute_with_tax = CsviHelper::replaceValue($fieldreplace, $attribute_with_tax);
										$this->addExportField($field->combine, $attribute_with_tax, $fieldname, $field->column_header);
									}
									break;
								case 'product_parent_sku':
									$db->setQuery( "SELECT product_sku FROM #__vm_product WHERE product_id='".$record->product_parent_id."'" );
									$product_parent_sku = $db->loadResult();
									$product_parent_sku = CsviHelper::replaceValue($fieldreplace, $product_parent_sku);
									$this->addExportField($field->combine, $product_parent_sku, $fieldname, $field->column_header);
									break;
								case 'product_discount_date_start':
								case 'product_discount_date_end':
								case 'product_available_date':
									$$fieldname = trim($fieldvalue);
									if (strlen($$fieldname) == 0 || $$fieldname == 0) {
										// Check if we have a default value
										if (strlen(trim($field->default_value)) > 0) {
											$$fieldname = $field->default_value;
										}
										else $$fieldname = '';
									}
									else {
										$$fieldname = date($template->getValue('export_date_format', 'general'), $$fieldname);
									}
									$this->addExportField($field->combine, $$fieldname, $fieldname, $field->column_header);
									break;
								case 'related_products':
									$related_products = "";
									$db_related = JFactory::getDBO();
									$db_related->setQuery("SELECT related_products FROM #__vm_product_relations WHERE product_id='".$record->main_product_id."'" );
									$products = explode("|", $db_related->loadResult());
									$q = "SELECT product_sku FROM #__vm_product WHERE product_id in (";
									foreach ($products as $id => $productid) {
										$q .= $db_related->Quote($productid).',';
									}
									$q = substr($q, 0 , -1).")";
									$db_related->setQuery($q);
									$related_records = $db_related->loadObjectList();
									$lastkey = end(array_keys($related_records));
									foreach ($related_records as $related_key => $related_record) {
										$related_products .= $related_record->product_sku;
										if ($lastkey != $related_key) $related_products .= "|";
									}
									if (strlen(trim($related_products)) == 0) $related_products = $field->default_value;
									$related_products = CsviHelper::replaceValue($fieldreplace, $related_products);
									$this->addExportField($field->combine, $related_products, $fieldname, $field->column_header);
									break;
								case 'product_discount':
									if (!is_null($record->product_discount)) {
										$product_discount = trim($record->product_discount);
										if ($record->product_discount_is_percent) $product_discount .= '%';
										else $product_discount = number_format($product_discount, $template->getValue('export_price_format_decimal', 'general', 2, 'int'), $template->getValue('export_price_format_decsep', 'general'), $template->getValue('export_price_format_thousep', 'general'));
										if (strlen(trim($product_discount)) == 0) $product_discount = $field->default_value;
										$product_discount = CsviHelper::replaceValue($fieldreplace, $product_discount);
									}
									else $product_discount = '';
									$this->addExportField($field->combine, $product_discount, $fieldname, $field->column_header);
									break;
								case 'product_currency':
									// Check if we have any content otherwise use the default value
									if ($template->getValue('targetcurrency', 'product') != '') {
										$fieldvalue = $template->getValue('targetcurrency', 'product');
									}
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header);

									break;
								case 'product_price':
									$product_price = $this->_convertPrice($record->product_price, $record->product_currency);
									$product_price =  number_format($product_price, $template->getValue('export_price_format_decimal', 'general', 2, 'int'), $template->getValue('export_price_format_decsep', 'general'), $template->getValue('export_price_format_thousep', 'general'));
									if (strlen(trim($product_price)) == 0) $product_price = $field->default_value;
									if ($template->getValue('add_currency_to_price', 'general')) {
										if ($template->getValue('targetcurrency', 'product') != '') {
											$product_price = $template->getValue('targetcurrency', 'product').' '.$product_price;
										}
										else $product_price = $record->product_currency.' '.$product_price;
									}
									$product_price = CsviHelper::replaceValue($fieldreplace, $product_price);
									$this->addExportField($field->combine, $product_price, $fieldname, $field->column_header);
									break;
								case 'product_url':
									// Check if there is already a product URL
									if (is_null($record->product_url) || strlen(trim($record->product_url)) == 0) {
										// Check if we have a child product
										if (isset($record->product_parent_id) && $record->product_parent_id > 0) $child = true;
										else $child = false;

										// There is no product URL, create it
										// Get the flypage
										if ($child) $flypage = $this->GetFlypage($record->product_parent_id);
										else $flypage = $this->GetFlypage($record->main_product_id);

										// Get the category id
										// Check to see if we have a child product
										if ($child) $category_id = $this->getCategoryId($record->product_parent_id);
										else $category_id = $this->getCategoryId($record->main_product_id);

										if ($category_id > 0) {
											// Let's create a SEF URL
											$_SERVER['QUERY_STRING'] = 'option=com_virtuemart&Itemid='.$template->getValue('vm_itemid', 'general', 1, 'int').'&page=shop.product_details&flypage='.$flypage.'&product_id='.$record->main_product_id.'&category_id='.$category_id;
											$product_url = $this->_getSiteRoute('index.php?'.$_SERVER['QUERY_STRING']);
										}
										else $product_url = "";
									}
									// There is a product URL, use it
									else $product_url = $record->product_url;

									// Add the suffix
									$product_url .= $template->getValue('producturl_suffix', 'product');

									// Check for https, replace with http. https has unnecessary overhead
									if (substr($product_url, 0, 5) == 'https') $product_url = 'http'.substr($product_url, 5);
									$product_url = CsviHelper::replaceValue($fieldreplace, $product_url);
									$this->addExportField($field->combine, $product_url, $fieldname, $field->column_header, true);
									break;
								case 'picture_url':
									// Check if there is already a product full image
									if (strlen(trim($record->product_full_image)) > 0) {
										// Create picture url
										if (substr($record->product_full_image, 0, 4) == 'http') $picture_url = $record->product_full_image;
										else $picture_url = $this->_domainname.'/components/com_virtuemart/shop_image/product/'.$record->product_full_image;
									}
									// There is no product full image, use default value
									else $picture_url = $field->default_value;
									$picture_url = CsviHelper::replaceValue($fieldreplace, $picture_url);
									$this->addExportField($field->combine, $picture_url, $fieldname, $field->column_header);
									break;
								case 'price_with_tax':
									$price_with_tax = number_format($this->ProductPrice(($record->product_price/100)*(100+($record->tax_rate*100))), $template->getValue('export_price_format_decimal', 'general', 2, 'int'), $template->getValue('export_price_format_decsep', 'general'), $template->getValue('export_price_format_thousep', 'general'));
									// Check if we have any content otherwise use the default value
									if (strlen(trim($price_with_tax)) == 0) $price_with_tax = $field->default_value;
									if ($template->getValue('add_currency_to_price', 'general')) $price_with_tax = $record->product_currency.' '.$price_with_tax;
									$price_with_tax = CsviHelper::replaceValue($fieldreplace, $price_with_tax);
									$this->addExportField($field->combine, $price_with_tax, $fieldname, $field->column_header);
									break;
								case 'price_with_discount':
									/**
									 * Apply the discount
									 * 0 = value
									 * 1 = percentage
									 */
									switch($record->product_discount_is_percent) {
										case 0:
											$price_with_discount = (($record->product_price-trim($record->product_discount))/100)*(100+($record->tax_rate*100));
											break;
										case 1:
											$price_with_discount = ($record->product_price/100)*(100+($record->tax_rate*100));
											$price_with_discount *= (100 - trim($record->product_discount))/100;
											break;
									}
									// Check if we have any content otherwise use the default value
									if (strlen(trim($price_with_discount)) == 0) $price_with_discount = $field->default_value;
									$price_with_discount = number_format($price_with_discount, $template->getValue('export_price_format_decimal', 'general', 2, 'int'), $template->getValue('export_price_format_decsep', 'general'), $template->getValue('export_price_format_thousep', 'general'));
									if ($template->getValue('add_currency_to_price', 'general')) $price_with_discount = $record->product_currency.' '.$price_with_discount;
									$price_with_discount = CsviHelper::replaceValue($fieldreplace, $price_with_discount);
									$this->addExportField($field->combine, $price_with_discount, $fieldname, $field->column_header);
									break;
								case 'product_packaging':
									$product_packaging = $record->product_packaging & 0xFFFF;
									$product_packaging = CsviHelper::replaceValue($fieldreplace, $product_packaging);
									$this->addExportField($field->combine, $product_packaging, $fieldname, $field->column_header);
									break;
								case 'product_box':
									$product_box = $record->product_packaging>>16&0xFFFF;
									$product_box = CsviHelper::replaceValue($fieldreplace, $product_box);
									$this->addExportField($field->combine, $product_box, $fieldname, $field->column_header);
									break;
								case 'product_name':
									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header, true);
									break;
								case 'product_s_desc':
									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header, true);
									break;
								case 'product_desc':
									// Check if the field is empty
									if (strlen(trim($fieldvalue)) == 0) {
										// Check if we are doing a Google Base export
										if (isset($record->product_s_desc) && $template->getValue('export_file', 'general') == 'xml' && $template->getValue('export_site', 'general') == 'froogle') {
											// Check if the short description has data
											if (strlen(trim($record->product_s_desc)) == 0) {
												// Let's use the product name
												$fieldvalue = $record->product_name;
											}
											else $fieldvalue = $record->product_s_desc;
										}
										else {
											// Check if we have any content otherwise use the default value
											$fieldvalue = $field->default_value;
										}

									}
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header, true);
									break;
								case 'product_full_image':
									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header, true);
									break;
								case 'product_thumb_image':
									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header, true);
									break;
								case 'product_id':
									$fieldvalue = $record->main_product_id;
									$fieldvalue = CsviHelper::replaceValue($fieldreplace, $fieldvalue);
									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header, true);
									break;
								case 'product_tax':
									// Check if we have any content otherwise use the default value
									if (strlen(trim($record->tax_rate)) == 0) $product_tax = $field->default_value;
									else $product_tax = number_format(($record->tax_rate*100), $template->getValue('export_price_format_decimal', 'general', 2, 'int'), $template->getValue('export_price_format_decsep', 'general'), $template->getValue('export_price_format_thousep', 'general'));
									$product_tax = CsviHelper::replaceValue($fieldreplace, $product_tax);
									$this->addExportField($field->combine, $product_tax, $fieldname, $field->column_header);
									break;
								case 'mdate':
								case 'cdate':
									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									else $fieldvalue = date($template->getValue('export_date_format', 'general'), $fieldvalue);
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header);
									break;
								case 'producttypenames':
									$this->addExportField($field->combine, $this->_getProductTypeNames($record->main_product_id), $fieldname, $field->column_header);
									// for a product type called prod with fields one, two, three it would create fields producttype:field:value,producttype:field:value
									break;
								case 'custom_shipping':
									// Check the shipping cost
									$price_with_tax = $this->ProductPrice(($record->product_price/100)*(100+($record->tax_rate*100)));
									$result = CsviHelper::shippingCost($price_with_tax);
									if ($result) $fieldvalue = $result;

									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;

									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header);
									break;
								default:
									// Check if we have any content otherwise use the default value
									if (strlen(trim($fieldvalue)) == 0) $fieldvalue = $field->default_value;
									$this->addExportField($field->combine, $fieldvalue, $fieldname, $field->column_header);
									break;
							}
						}
					}
					if ($template->getValue('export_file', 'general') == 'xml' || $template->getValue('export_file', 'general') == 'html') {
						$this->addExportContent($exportclass->NodeEnd());
					}

					// Output the contents
					$this->writeOutput();
				}
			}
			else {
				$this->addExportContent(JText::_('COM_CSVIVIRTUEMART_NO_DATA_FOUND'));
				// Output the contents
				$this->writeOutput();
			}
		}
	}

	/**
	* Convert prices to the new currency
	 */
	private function _convertPrice($product_price, $product_currency) {
		if (empty($product_price)) return $product_price;
		else {
			$template = JRequest::getVar('template');
			/* See if we need to convert the price */
			if ($template->getValue('targetcurrency', 'product', '') != '') {
				$db_exrate = JFactory::getDBO();
				$q = "SELECT currency_code, currency_rate
					FROM #__csvivirtuemart_currency
					WHERE currency_code IN (".$db_exrate->Quote($product_currency).", ".$db_exrate->Quote($template->getValue('targetcurrency', 'product', 'EUR')).")";
				$db_exrate->setQuery($q);
				$rates = $db_exrate->loadObjectList('currency_code');

				/* Convert to base price */
				$baseprice = $product_price / $rates[strtoupper($product_currency)]->currency_rate;

				/* Convert to destination currency */
				return $baseprice * $rates[strtoupper($template->getValue('targetcurrency', 'product', 'EUR'))]->currency_rate;
			}
			else return $product_price;
		}
	}

	/**
	 * Create a SEF URL
	 *
	 * @copyright
	 * @author		RolandD
	 * @todo		Change exportsef to template
	 * @see
	 * @access 		private
	 * @param 		string	$url	The url to change to SEF
	 * @return 		string	the new url
	 * @since 		3.0
	 */
	private function _getSiteRoute($url) {
		$template = JRequest::getVar('template');
		$csvilog = JRequest::getVar('csvilog');
		$parsed_url = null;
		// Check which SEF component is installed
		if (empty($this->_sef)) {
			if ($template->getValue('exportsef', 'product', false)) {
				// Joomla SEF
				if (JPluginHelper::isEnabled('system', 'sef')) $this->_sef = 'joomla';

				// sh404SEF check
				if (JPluginHelper::isEnabled('system', 'shsef')) $this->_sef = 'sh404sef';

				// JoomSEF check
				if (JPluginHelper::isEnabled('system', 'joomsef')) $this->_sef = 'joomsef';

				// AceSEF check
				if (JPluginHelper::isEnabled('system', 'acesef')) $this->_sef = 'acesef';

				// YagendooSEF check
				if (JPluginHelper::isEnabled('system', 'yagendoorouter')) $this->_sef = 'yagendoo';

				// There is no SEF enabled
				if (empty($this->_sef)) $this->_sef = 'nosef';
			 }
			 else $this->_sef = 'nosef';
		}

		switch ($this->_sef) {
			case 'sh404sef':
				$parsed_url = $this->_sh404Sef($url);
				break;
			case 'joomsef':
				$parsed_url = $this->_joomSef($url);
				break;
			case 'joomla':
				$parsed_url = $this->_joomlaSef($url);
				break;
			case 'acesef':
				$parsed_url = $this->_aceSef($url);
				break;
			case 'yagendoo':
				$parsed_url = $this->_yagendooSef($url);
				break;
			case 'nosef':
			default:
				// No SEF router found, returning regular URL
				return $this->_domainname.'/'.JRoute::_($url);
				break;
		}

		// Clean up the parsed SEF URL
		if (!empty($parsed_url)) {
			// Clean up the parsed SEF URL
			if (substr($parsed_url, 4) == 'http') return $parsed_url;
			else {
				// Check for administrator in the domain
				$adminpos = strpos($parsed_url,'/administrator/');
				if ($adminpos !== false) $parsed_url = substr($parsed_url,$adminpos+15);

				// Check if we have a domain name in the URL
				if (!empty($this->_domainname)) {
					$check_domain = str_replace('https', 'http', $this->_domainname);
					$domain = strpos($parsed_url, $check_domain);
					if ($domain === false) {
						if (substr($parsed_url, 0, 1) == '/') $parsed_url = $this->_domainname.$parsed_url;
						else $parsed_url = $this->_domainname.'/'.$parsed_url;
					}
					return $parsed_url;
				}
				else {
					$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_NO_DOMAINNAME_SET'));
					return $url;
				}
			}
		}
	}

	/**
	 * Create sh404SEF URLs
	 *
	 * @copyright
	 * @author 		RolandD
	 * @todo
	 * @see 		http://dev.anything-digital.com/sh404SEF/
	 * @see			_getSiteRoute()
	 * @access 		private
	 * @param 		string	$url	the original URL to turn into SEF
	 * @return 		string SEF URL
	 * @since 		3.0
	 */
	private function _sh404Sef($url) {
		// Load sh404SEF
		require_once(JPATH_ADMINISTRATOR.'/components/com_sh404sef/sh404sef.class.php');
		$sefConfig = shRouter::shGetConfig();

		// Turn off any security and flooding setting
		$sefConfig->shSecEnableSecurity = 0;
		$sefConfig->shSecActivateAntiFlood = 0;

		// Require some necessary files
		require_once(JPATH_ROOT.'/components/com_sh404sef/shCache.php');
		require_once(JPATH_ROOT.'/components/com_sh404sef/shSec.php');

		// Start the sh404sef Router
		if (class_exists('shRouter')) $shRouter = new shRouter();
		else return $this->_domainname.'/'.$url;

		// Force the domain name
		$GLOBALS['shConfigLiveSite'] = $this->_domainname;

		// Initialize sh404sef
		include_once(JPATH_ROOT.'/components/com_sh404sef/shInit.php');

		// Build the SEF URL
		$uri = $shRouter->build($url);
		$sefurl = $uri->toString();
		if (strpos($sefurl, 'http://') === false) {
			$sefurl = str_ireplace('http:/', 'http://', $sefurl);
		}
		return $sefurl;
	}

	/**
	 * Create JoomSEF URLs
	 *
	 * @copyright
	 * @author 		RolandD
	 * @todo
	 * @see 		http://www.artio.net/joomla-extensions/joomsef
	 * @see			_getSiteRoute()
	 * @access 		private
	 * @param 		string	$url	the original URL to turn into SEF
	 * @return 		string SEF URL
	 * @since 		3.0
	 */
	private function _joomSef($url) {
		// Include Joomla files
		jimport('joomla.application.router');
		require_once(JPATH_ROOT.'/includes/application.php');

		// Include JoomSEF
		require_once(JPATH_ROOT.'/components/com_sef/sef.router.php');
		$shRouter = new JRouterJoomSef();

		// Build the SEF URL
		$uri = $shRouter->build($url);
		return $uri->toString();
	}

	/**
	 * Create Joomla SEF URLs
	 *
	 * @copyright
	 * @author 		RolandD
	 * @todo
	 * @see 		http://www.joomla.org/
	 * @see			_getSiteRoute()
	 * @access 		private
	 * @param 		string	$url	the original URL to turn into SEF
	 * @return 		string SEF URL
	 * @since 		3.0
	 */
	private function _joomlaSef($url) {
		// Load Joomla core files for SEF
		jimport('joomla.application.router');
		require_once(JPATH_ROOT.'/includes/application.php');
		require_once(JPATH_ROOT.'/includes/router.php');
		$router = new JRouterSite(array('mode' => 1));
		$uri = $router->build($url);
		return $uri->toString();
	}

	/**
	 * Create aceSEF URLs
	 *
	 * @copyright
	 * @author 		RolandD
	 * @todo
	 * @see 		http://www.joomace.net/joomla-extensions/acesef
	 * @see			_getSiteRoute()
	 * @access 		private
	 * @param 		string	$url	the original URL to turn into SEF
	 * @return 		string SEF URL
	 * @since 		3.0
	 */
	private function _aceSef($url) {
		jimport('joomla.application.router');
		require_once(JPATH_ROOT.'/includes/application.php');
		require_once(JPATH_ADMINISTRATOR.'/components/com_acesef/library/router.php');
		require_once(JPATH_ADMINISTRATOR.'/components/com_acesef/library/loader.php');



		$router = new JRouterAcesef();
		$uri = $router->build($url);
		return $uri->toString();
	}

	/**
	 * Collect the product type names for this product
	 *
	 * @copyright
	 * @author 		RolandD
	 * @todo
	 * @see
	 * @access 		private
	 * @param 		int	$product_id	the database ID of the product
	 * @return 		string	the product type names list
	 * @since 		3.0
	 */
	private function _getProductTypeNames($product_id) {
		$db = JFactory::getDBO();
		$csvilog = JRequest::getVar('csvilog');
		$names = array();
		// Find the product types the product is linked to
		$q = "SELECT x.".$db->nameQuote('product_type_id').", ".$db->nameQuote('product_type_name')."
			FROM ".$db->nameQuote('#__vm_product_product_type_xref')." x
			LEFT JOIN ".$db->nameQuote('#__vm_product_type')." t
			ON t.".$db->nameQuote('product_type_id')." = x.".$db->nameQuote('product_type_id')."
			WHERE ".$db->nameQuote('product_id')." = ".$product_id;
		$db->setQuery($q);
		$producttypes = $db->loadObjectList();
		$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_LOAD_PRODUCT_TYPES'), true);
		// Get the userfields
		if (!empty($producttypes)) {
			foreach ($producttypes as $type) {
				$q = "SELECT *
					FROM ".$db->nameQuote('#__vm_product_type_'.$type->product_type_id)."
					WHERE ".$db->nameQuote('product_id')." = ".$product_id;
				$db->setQuery($q);
				$data = $db->loadObject();
				$csvilog->addDebug(JText::_('COM_CSVIVIRTUEMART_LOAD_PRODUCT_TYPE_NAME_DATA'), true);
				if (!empty($data)) {
					foreach ($data as $name => $value) {
						if ($name != 'product_id') $names[] = $type->product_type_name.':'.$name.':'.$value;
					}
				}
			}
		}

		// Return what we found
		return  implode(',', $names);
	}

	/**
	 * Create Yagendoo URLs
	 *
	 * @copyright
	 * @author 		RolandD

	 * @todo
	 * @see 		http://www.joomace.net/joomla-extensions/acesef
	 * @see			_getSiteRoute()
	 * @access 		private
	 * @param 		string	$url	the original URL to turn into SEF

	 * @return 		string SEF URL
	 * @since 		3.0
	 */
	private function _yagendooSef($url) {
		jimport('joomla.application.router');
   		require_once (JPATH_ROOT . DS . 'includes' . DS . 'router.php');
		require_once (JPATH_ROOT . DS . 'includes' . DS . 'application.php');
		require_once (JPATH_ROOT . DS . 'plugins' . DS . 'system' . DS . 'yagendoorouter.php');
		require_once (JPATH_ROOT . DS . 'plugins' . DS . 'system' . DS . 'yagendoorouter' . DS . 'com_virtuemartrouter.php');

 		if(function_exists("VirtuemartYBuildRoute")){
			$arQuery     = explode("&", $url);
       		$arFullQuery = array();
       		foreach($arQuery as $intKey => $strPart){
           		$arQuery[$intKey]                  = explode("=", $strPart);
           		$arFullQuery[$arQuery[$intKey][0]] = $arQuery[$intKey][1];
       		}
       		$arSegments = VirtuemartYBuildRoute($arFullQuery);

       		$strURL = $this->_getYagendooVMComponentURLAlias();
       		foreach($arSegments as $intKey => $strSegment) {
				$strURL .= "/".$strSegment;
       		}
       		$strURL .= ".html";
       		$strURL = str_replace(':', '-', $strURL);

			return $strURL;
		}
		else{
  			return $url;
		}
	}

   /**
    * Get the VM URL alias
    *
    * @copyright
    * @author 		Yagendoo
    * @todo
    * @see
    * @access 		private
    * @param
    * @return 		string	VM Component alias
    * @since 		3.9
    */
   private function _getYagendooVMComponentURLAlias(){
       $objComponentHelper = new JComponentHelper();
       $objComponent       = $objComponentHelper->getComponent("com_virtuemart");
       $objMenu            = JApplication::getMenu('site', array());
       $arItems            = $objMenu->getItems('componentid', $objComponent->id);
       $arVMItems          = array();
       foreach($arItems as $intKey => $objItem){
           $arParams = explode("\n", $objItem->params);
           foreach($arParams as $intKey => $strParam)
               $arParams[$intKey] = trim($strParam);
           if(in_array("product_id=", $arParams) AND in_array("category_id=", $arParams))
               $arVMItems[$objItem->id] = $objItem->alias;
       }
       ksort($arVMItems);
       $intI=0;
       foreach($arVMItems as $intKey => $strAlias){
           $arVMItems[$intI] = $strAlias;
           $intI++;
       }
       if(!empty($arVMItems[0]))
           return $arVMItems[0];
   }
}
?>
