<?php
function updateSubAdvsearcherValues( $iValue, $sCurrentValues ){
	$oDB = DataBase::getInstance();
	$oDB->executeSQL( 'UPDATE `' . $oDB->throwTableName( DB_ADVSEARCHER_VALUES ) . '` SET `sParentValues` = \'' . $oDB->escape( $sCurrentValues ) . '\' WHERE `iParentValue` = ' . intval( $iValue ) );
	$aSubValues = $oDB->executeSQL( 'SELECT `iValue`, `sValue` FROM `' . $oDB->throwTableName( DB_ADVSEARCHER_VALUES ) . '` WHERE `iParentValue` = ' . intval( $iValue ), true, DataBase::ASSOCIATIVE );
	foreach( $aSubValues as $iSubValue => $sSubValue ){
		updateSubAdvsearcherValues( $iSubValue, $sCurrentValues . ' &raquo; ' . $sSubValue );
	}
}

function saveAdvsearcherValue( $aValue ){
	$oDB = DataBase::getInstance();
	$iValue = $oDB->save( DB_ADVSEARCHER_VALUES, $aValue, 'iValue' );
	$aValue = $oDB->throwData( DB_ADVSEARCHER_VALUES, $iValue, 'iValue' );
	if( !empty( $aValue['iParentValue'] ) ){
		$aValue['sParentValues'] = $oDB->executeSQL( 'SELECT CONCAT( `sParentValues`, \' &raquo; \', `sValue` ) FROM `' . $oDB->throwTableName( DB_ADVSEARCHER_VALUES ) . '` WHERE `iValue` = ' . intval( $aValue['iParentValue'] ), true, DataBase::SINGLE_VALUE );
		$oDB->update( DB_ADVSEARCHER_VALUES, Array( 'sParentValues' => $aValue['sParentValues'] ), Array( 'iValue' => $iValue ) );
		$sCurrentValues = $aValue['sParentValues'] . ' &raquo; ' . $aValue['sValue'];
	} else{
		$aValue['sParentValues'] = '';
		$oDB->update( DB_ADVSEARCHER_VALUES, Array( 'sParentValues' => $aValue['sParentValues'] ), Array( 'iValue' => $iValue ) );
		$sCurrentValues = $aValue['sValue'];
	}
	updateSubAdvsearcherValues( $iValue, $sCurrentValues );
	return $iValue;
}

class ProductsAdmin extends Products{
	function throwProduct( $iProduct, $iStatus = true ){
		$oDB = DataBase::getInstance( );
		$aData = parent::throwProduct( $iProduct, $iStatus );
		if( is_array( $aData ) ){
			$sql = 'SELECT `iGroup`, 1-`fMultiply` FROM `' . $oDB->throwTableName( DB_PRODUCTS_DISCOUNTS ) . '` WHERE `iProduct` = ' . intval( $iProduct );
			$aData['aDiscounts'] = $oDB->executeSQL( $sql, true, DataBase::ASSOCIATIVE );
			$sql = 'SELECT `iGroup`, `iVisible`, `iVisiblePrice`, `iCanBuy` FROM `' . $oDB->throwTableName( DB_PRODUCTS_DISCOUNTS ) . '` WHERE `iProduct` = ' . intval( $iProduct );
			$aData['aGroupsInfo'] = $oDB->executeSQL( $sql, true, DataBase::ASSOCIATIVE, 'iGroup' );
			$aData['aPromoted'] = $oDB->executeSQL( 'SELECT `iPromoted`, 1 FROM `' . $oDB->throwTableName( DB_PRODUCTS_PROMOTED ) . '` WHERE `iProduct` = ' . intval( $iProduct ), true, DataBase::ASSOCIATIVE );
			$aData['aPromotedTimes'] = $oDB->executeSQL( 'SELECT `iPromoted`, FROM_UNIXTIME( `iTimeValid` ) FROM `' . $oDB->throwTableName( DB_PRODUCTS_PROMOTED ) . '` WHERE `iProduct` = ' . intval( $iProduct ), true, DataBase::ASSOCIATIVE );
		}
		return $aData;
	}
	function listProductsAdminFinishing( $iList = null ){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `iProduct`
							FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` AS `pv`
								LEFT JOIN `' . $oDB->throwTableName( DB_PRODUCTS ) . '` AS `p` USING( `iProduct` )
							WHERE `pv`.`TiStock` < IFNULL( `p`.`iStockSendAdminMin`, ' . intval( $GLOBALS['config']['stock_send_admin_min'] ) . ' )';
		$aProducts = $oDB->executeSQL( $sql, true, DataBase::SINGLE_COLUMN );
		return $this->listProductsAdmin( $iList, $aProducts );
	}
	function listProductsAdmin( $iList = null, $aProducts = null ){
		global $sUrlExt;
		$oDB = & DataBase::getInstance( );
		$oFile = Files::getInstance( );
		$content = null;
/*		if( isset($GLOBALS['enablity']) && ( $GLOBALS['enablity'] == 'yes' || $GLOBALS['enablity'] == 'no' ) ){
			$sUrlExt.= '&amp;enablity=' . $GLOBALS['enablity'];
		};*/
		if( isset($GLOBALS['sSort']) && $GLOBALS['sSort'] != '' ){
			$sUrlExt.= '&amp;sort=' . $GLOBALS['sSort'];
		};
		if( isset( $GLOBALS['iCategory'] ) && !empty( $GLOBALS['iCategory'] ) ){
			if( is_array( $GLOBALS['iCategory'] ) ){
				$aPages = Array();
				foreach( $GLOBALS['iCategory'] as $iCategoryS ){
					$sUrlExt.= '&amp;iCategory[]=' . $iCategoryS;
					$GLOBALS['oPage']->mData = null;
					$aPagesT = $GLOBALS['oPage']->throwAllChildren( intval( $iCategoryS ) );
					$aPagesT[] = intval( $iCategoryS );
					foreach( $aPagesT as $iPage ){
						if( !in_array( $iPage, $aPages ) ){
							$aPages[] = intval( $iPage );
						}
					}
				}
			} else{
				$sUrlExt.= '&amp;iCategory=' . $GLOBALS['iCategory'];
				$GLOBALS['oPage']->mData = null;
				$aPages = $GLOBALS['oPage']->throwAllChildren( intval( $GLOBALS['iCategory'] ) );
				$aPages[] = intval( $GLOBALS['iCategory'] );
			}
		} else{
			$aPages = null /*array_keys( $GLOBALS['oPage']->aPages )*/; // array_keys było błędem - nie dało się zobaczyć produktów, które z jakiegoś powodu nie należą do żadnej kategorii
		}
		if( isset( $GLOBALS['sPhrase'] ) /*&& !empty( $GLOBALS['sPhrase'] )*/ ){
			$sUrlExt.= '&amp;sPhrase=' . $GLOBALS['sPhrase'];
		};
		if( isset( $GLOBALS['iProducer'] ) && !empty( $GLOBALS['iProducer'] ) ){
			if( is_array( $GLOBALS['iProducer'] ) ){
				foreach( $GLOBALS['iProducer'] as $iProducer ){
					$sUrlExt.= '&amp;iProducer[]=' . $iProducer;
				}
			} else{
				$sUrlExt.= '&amp;iProducer=' . $GLOBALS['iProducer'];
			}
		};
		if( isset( $GLOBALS['iPhoto'] ) ){
			$sUrlExt.= '&amp;iPhoto=' . $GLOBALS['iPhoto'];
		}
		$sql = $this->generateListSQL( null, $aProducts, ( ( isset( $GLOBALS['sPhrase'] ) && !empty( $GLOBALS['sPhrase'] ) ) || isset( $aPages ) || isset( $GLOBALS['iProducer'] ) || isset( $GLOBALS['iProduct'] ) || isset( $GLOBALS['aAttributeValue'] ) ) ? Array( 'sPhrase' => $GLOBALS['sPhrase'], 'aPages' => $aPages, 'iProducer' => $GLOBALS['iProducer'], 'iProduct' => $GLOBALS['iProduct'], 'aAttributeValue' => $GLOBALS['aAttributeValue'] ) : null );
			switch($GLOBALS['sort']){
				case 'id_ASC':
					$sql .= ' ORDER BY `products`.`iProduct` ASC';
					break;
				case 'id_DESC':
					$sql .= ' ORDER BY `products`.`iProduct` DESC';
					break;
				case 'name_ASC':
					$sql .= ' ORDER BY `products`.`sName` ASC';
					break;
				case 'name_DESC':
					$sql .= ' ORDER BY `products`.`sName` DESC';
					break;
				case 'ProductIndex_ASC':
					$sql .= ' ORDER BY `products`.`sProductIndex` ASC';
					break;
				case 'ProductIndex_DESC':
					$sql .= ' ORDER BY `products`.`sProductIndex` DESC';
					break;
				case 'position_ASC':
					$sql .= ' ORDER BY `products`.`iPosition` ASC';
					break;
				case 'position_DESC':
					$sql .= ' ORDER BY `products`.`iPosition` DESC';
					break;
				case 'price_ASC':
					$sql .= ' ORDER BY `products`.`fPrice` ASC';
					break;
				case 'price_DESC':
					$sql .= ' ORDER BY `products`.`fPrice` DESC';
					break;
				case 'stockLevel_ASC':
					$sql .= ' ORDER BY `TiStock` ASC';
					break;
				case 'stockLevel_DESC':
					$sql .= ' ORDER BY `TiStock` DESC';
					break;
				
				default:
					$sql.= ' ORDER BY `iPosition`, `sName`, `iProduct`';
					break;
			}
		
		if( !isset( $iList ) ){
			$iList = $GLOBALS['config']['admin_list'];
		}
		$iPageNumber = $GLOBALS['iPage'];
		if( !isset( $iPageNumber ) || !is_numeric( $iPageNumber ) || $iPageNumber < 1 ) $iPageNumber = 1;
		if( isset( $_POST['sort'] ) || isset( $_POST['productsPerPage'] ) ){
			$iPageNumber = 1;
			$GLOBALS['aActions']['o2'] = 1;
		}
		if( $iList != 'inf' ){
			$iEnd = $iPageNumber * $iList;
			$iStart = $iEnd - $iList;
			$sql.= ' LIMIT ' . $iStart . ',' . $iList;
		}
		$aReturn['aList'] = $oDB->executeSQL( $sql, true );
		$sql = 'SELECT FOUND_ROWS()';
		$iCount = $oDB->executeSQL( $sql, true, DataBase::SINGLE_VALUE );
		foreach( $aReturn['aList'] as &$aProduct ){
			if( isset( $oFile->aImagesDefault[2][$aProduct['iProduct']] ) ){
				$aProduct['aDataImage'] = $oFile->aImagesDefault[2][$aProduct['iProduct']];
			}
			$aProduct['sPrice'] = displayPrice( $aProduct['fPrice'] );
			$aProduct['aPages'] = $this->getPagesTree( $aProduct['iProduct'] );
			$aProduct['iStock'] = $aProduct['TiStock'];
			$aProduct['bNewComments'] = $aProduct['iNewCommentsCount'] > 0;
		}
		if( is_numeric( $iList ) && $iList > 0 ) $aReturn['aPagesCountData'] = Array( 'iCount' => ceil( $iCount / $iList ), 'iPageNumber' => $iPageNumber );
		return $aReturn;
	}
	function saveProducts( $aForm ){
		$oDB = DataBase::getInstance( );
		$sql = 'SELECT `iProduct`, `iStatus`, `iPosition` FROM `' . $oDB->throwTableName( DB_PRODUCTS ) . '`';
		$aProducts = $oDB->executeSQL( $sql, true );
		if( isset( $aForm['aPositions'] ) && is_array( $aForm['aPositions'] ) ){
			foreach( $aProducts as $aData ){
				$iProduct = $aData['iProduct'];
				if( isset( $aForm['aPositions'][$iProduct] ) ){
					$aForm['aPositions'][$iProduct] = trim( $aForm['aPositions'][$iProduct] );
					$iStatus = isset( $aForm['aStatus'][$iProduct] ) ? 1 : 0;
					if( is_numeric( $aForm['aPositions'][$iProduct] ) && $aForm['aPositions'][$iProduct] != $aData['iPosition'] ){
						$aChange[$iProduct]['iPosition'] = $aForm['aPositions'][$iProduct];
					}
					if( $iStatus != $aData['iStatus'] ){
						$aChange[$iProduct]['iStatus'] = $iStatus;
					}
				}
			}
			if( isset( $aChange ) ){
				$this->saveProductsData( $aChange );
			}
		}
	}
	function saveProductsData( $aChange ){
		$oDB = & DataBase::getInstance( );
		foreach( $aChange as $iProduct => $aData ){
			$oDB->update( DB_PRODUCTS, $aData, Array( 'iProduct' => $iProduct ) );
		}
	}
	function throwProductsRelated( $iProduct ){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `pr`.`iBox`, `p`.`iProduct`, `p`.`sName` FROM `' . $oDB->throwTableName( DB_PRODUCTS ) . '` AS `p` INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS_RELATED ) . '` AS `pr` ON( `pr`.`iRelated` = `p`.`iProduct` ) WHERE `pr`.`iProduct` = ' . intval( $iProduct );
		$aProductsRelated = $oDB->executeSQL( $sql, true );
		$aReturn = Array( );
		foreach( $aProductsRelated as $aRelatedProduct ){
			$aReturn[$aRelatedProduct['iBox']][] = Array( 'iProduct' => $aRelatedProduct['iProduct'], 'sName' => $aRelatedProduct['sName'] );
		}
		return $aReturn;
	}
	function saveProduct( $aForm, $bSaveRelated = true ){
		$oDB = & DataBase::getInstance( );
		$oFile = FilesAdmin::getInstance( );
		if( !isset( $aForm['iActiveDiscount'] ) ) $aForm['iActiveDiscount'] = 0;
		if( !isset( $aForm['iComments'] ) ) $aForm['iComments'] = 0;
		if( !isset( $aForm['iCurrencyDependent'] ) ) $aForm['iCurrencyDependent'] = 0;
		if( !isset( $aForm['iFotolia'] ) ) $aForm['iFotolia'] = 0;
		if( !isset( $aForm['iCompare'] ) ) $aForm['iCompare'] = 0;
		if( !isset( $aForm['iNotForSale'] ) ) $aForm['iNotForSale'] = 0;
		if( !isset( $aForm['iPosition'] ) || !is_numeric( $aForm['iPosition'] ) || $aForm['iPosition'] < - 99 || $aForm['iPosition'] > 999 ) $aForm['iPosition'] = 0;
/*		if( !isset( $aForm['iPromoted'] ) ) $aForm['iPromoted'] = 0;
		if( !isset( $aForm['iSellOut'] ) ) $aForm['iSellOut'] = 0;
		if( !isset( $aForm['iTerminating'] ) ) $aForm['iTerminating'] = 0;*/
		if( !isset( $aForm['iStatus'] ) ) $aForm['iStatus'] = 0;
		if( !isset( $aForm['iPriceTimeFrom'] ) ) $aForm['iPriceTimeFrom'] = 0;
		if( !isset( $aForm['iPriceTimeTo'] ) ) $aForm['iPriceTimeTo'] = 0;
		$aForm['iLastModified'] = time( );
		
		if( isset( $aForm['sWeight'] ) && $aForm['sWeight'] != '' ){
			if( !preg_match( '^[0-9]+\\.?[0-9]*$', $aForm['sWeight'] ) ){
				$aForm['sWeight'] = str_replace( ',', '.', $aForm['sWeight'] );
				$aForm['sWeight'] = floatval( $aForm['sWeight'] );
			}
		}
		
		if( isset( $aForm['sWeightDisplayed'] ) && $aForm['sWeightDisplayed'] != '' ){
			if( !preg_match( '/^[0-9]+\\.?[0-9]*$/', $aForm['sWeightDisplayed'] ) ){
				$aForm['sWeightDisplayed'] = str_replace( ',', '.', $aForm['sWeightDisplayed'] );
				$aForm['sWeightDisplayed'] = floatval( $aForm['sWeightDisplayed'] );
			}
		}
		
		if( isset( $aForm['iProduct'] ) && is_numeric( $aForm['iProduct'] ) ){
			$sParam = 'iProduct';
//			$aProductOld = $this->throwProduct( $aForm['iProduct'] );
//			foreach( $aProductOld as $sRowKey => $mField ){
//				if( !isset( $aForm[$sRowKey] ) ) $aForm[$sRowKey] = $mField;
//			}
		} else{
			$sParam = null;
		}
		$aOrgProduct = $this->throwProduct( $aForm['iProduct'] );
		if( empty( $aOrgProduct ) && !$this->checkProductsLimit( ) ){
			die( $GLOBALS['lang']['Products_limit_exceeded'] );
		}
		if( empty( $aOrgProduct ) || ( $aOrgProduct['fPriceTimeValue'] != $aForm['fPriceTimeValue'] ) || ( $aOrgProduct['iPriceTimeFrom'] != $aForm['iPriceTimeFrom'] ) || ( $aOrgProduct['iPriceTimeTo'] != $aForm['iPriceTimeTo'] ) ){
			$aForm['iPriceTimeCount'] = 0;
		} else{
			$aForm['iPriceTimeCount'] = $aOrgProduct['iPriceTimeCount'];
		}
		$aForm['iTime'] = (int)abs( ( !empty( $aForm['sDate'] ) ) ? dateToTime( $aForm['sDate'] ) : time( ) );
		$aForm['fPrice'] = normalizePrice( $aForm['fPrice'] );
		$aForm['fPriceOld'] = !empty( $aForm['fPriceOld'] ) ? normalizePrice( $aForm['fPriceOld'] ) : null;
		$aForm = changeMassTxt( $aForm, '', Array( 'sDescriptionShort', 'Nds' ), Array( 'sDescriptionFull', 'Nds' ), Array( 'sMetaDescription', 'Nds' ) );
		$aForm['iProduct'] = $oDB->save( DB_PRODUCTS, $aForm, $sParam );
		$oDB->save( DB_PRODUCTS_EXT, $aForm, $sParam );
		$oDB->delete( DB_PRODUCTS_TAGS, Array( 'iProduct' => $aForm['iProduct'] ) );
		if( isset( $aForm['Tags'] ) && $aForm['Tags'] != "" ){
			foreach( explode( ',', $aForm['Tags'] ) as $sTag ){
				$sTag = trim( $sTag );
				if( !empty( $sTag ) ){
					$oDB->executeSQL( 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_TAGS ) . '` ( `iProduct`, `sTag` ) VALUES ( ' . intval( $aForm['iProduct'] ) . ', \'' . $oDB->escape( $sTag ) . '\' )' );
				}
			}
		}
		$oDB->deleteInFile( DB_PRODUCTS_TABS, $aForm['iProduct'], 'iProduct' );
		if( is_array( $aForm['aTabs'] ) ) foreach( $aForm['aTabs'] as $iTab => $sTab ){
			$oDB->save( DB_PRODUCTS_TABS, Array( 'iProduct' => $aForm['iProduct'], 'iTab' => $iTab, 'sContent' => $sTab ) );
		}
		if( !isset( $aForm['aPages'] ) || !is_array( $aForm['aPages'] ) ){
			$aForm['aPages'] = Array( $GLOBALS['config']['new_products_page'] );
		}
		if( isset( $aForm['aPages'] ) && is_array( $aForm['aPages'] ) ){
			$oDB->deleteInFile( DB_PRODUCTS_PAGES, $aForm['iProduct'], 'iProduct' );
			foreach( $aForm['aPages'] as $iPage ){
				if( $iPage == $aForm['iMainCategory'] ){
					$oDB->save( DB_PRODUCTS_PAGES, Array( 'iProduct' => $aForm['iProduct'], 'iPage' => $iPage, 'iMainCategory' => 1 ), null );
				} else{
					$oDB->save( DB_PRODUCTS_PAGES, Array( 'iProduct' => $aForm['iProduct'], 'iPage' => $iPage ), null );
				}
			}
		}



		$oDB->deleteInFile( DB_PRODUCTS_PROMOTED, $aForm['iProduct'], 'iProduct' );
		if( isset( $aForm['aPromoted'] ) && is_array( $aForm['aPromoted'] ) ){
			foreach( $aForm['aPromoted'] as $iPromoted => $null ){
				$iTimeValid = $aForm['aPromotedTimes'][$iPromoted];
				if( !empty( $iTimeValid ) ){
					$iTimeValid = (int)abs( dateToTime( $iTimeValid ) );
				} else{
					$iTimeValid = null;
				}
				$oDB->save( DB_PRODUCTS_PROMOTED, Array( 'iProduct' => $aForm['iProduct'], 'iPromoted' => $iPromoted, 'iTimeValid' => $iTimeValid ) );
			}
		}

		$oDB->deleteInFile( DB_ADVSEARCHER_PRODUCTS, $aForm['iProduct'], 'iProduct' );
		if( isset( $aForm['aAdvsearcherValues'] ) && is_array( $aForm['aAdvsearcherValues'] ) ){
			foreach( $aForm['aAdvsearcherValues'] as $iValue ){
				$oDB->save( DB_ADVSEARCHER_PRODUCTS, Array( 'iProduct' => $aForm['iProduct'], 'iValue' => $iValue ) );
			}
		}

		if( isset( $aForm['aCarrierPrice'] ) && is_array( $aForm['aCarrierPrice'] ) ){
			$oDB->deleteInFile( DB_PRODUCTS_CARRIERS_PRICES, $aForm['iProduct'], 'iProduct' );
			foreach( $aForm['aCarrierPrice'] as $iCarrier => $fCarrierPrice ){
				if( $fCarrierPrice !== '' ){
					$oDB->save( DB_PRODUCTS_CARRIERS_PRICES, Array( 'iProduct' => $aForm['iProduct'], 'iCarrier' => $iCarrier, 'fPrice' => $fCarrierPrice ), null );
				}
			}
		}
		if( isset( $aForm['aDiscounts'] ) && is_array( $aForm['aDiscounts'] ) ){
			if( !isset( $aForm['aGroupsInfo'] ) ){
				$aForm['aGroupsInfo'] = Array();
			}
			foreach( $aForm['aDiscounts'] as $iGroup => $fDiscount ){
				if( $fDiscount !== '' ){
					$aForm['aGroupsInfo'][$iGroup]['fMultiply'] = 1 - $fDiscount;
				}
			}
			$oDB->deleteInFile( DB_PRODUCTS_DISCOUNTS, $aForm['iProduct'], 'iProduct' );
			foreach( $aForm['aGroupsInfo'] as $iGroup => $aGroupInfo ){
				$aGroupInfo['iProduct'] = $aForm['iProduct'];
				$aGroupInfo['iGroup'] = $iGroup;
				$oDB->save( DB_PRODUCTS_DISCOUNTS, $aGroupInfo, null );
			}
		}
		if( isset( $aForm['aFilesDelete'] ) ) $oFile->deleteSelectedFiles( $aForm['aFilesDelete'], 2 );
		if( isset( $aForm['aFilesDescription'] ) ) $oFile->saveFiles( $aForm, $aForm['iProduct'], 2 );
		if( isset( $_FILES['aNewFiles'] ) ) $oFile->addFilesUploadedMulti( $aForm['iProduct'], 2, 'iProduct' );
		if( isset( $aForm['aDirFiles'] ) ) $oFile->addFilesFromServer( $aForm, $aForm['iProduct'], 2, 'iProduct' );
		if( $bSaveRelated ){
			$oDB->deleteInFile( DB_PRODUCTS_RELATED, $aForm['iProduct'], 'iProduct' );
			if( isset( $aForm['aRelated'] ) && is_array( $aForm['aRelated'] ) ){
				foreach( $aForm['aRelated'] as $aForm['iBox'] => $aRelated ){
					foreach( $aRelated as $aForm['iRelated'] ){
						if( !empty( $aForm['iRelated'] ) && is_numeric( $aForm['iRelated'] ) && ( $aForm['iRelated'] > 0 ) ){
							$oDB->save( DB_PRODUCTS_RELATED, $aForm );
						}
					}
				}
			}
		}
		if( is_array( $aForm['aVariants'] ) ) foreach( $aForm['aVariants'] as $iProductVariant => $aVariant ) if( is_numeric( $iProductVariant ) ){
			if( isset( $aVariant['iDelete'] ) && ( $aVariant['iDelete'] == 1 ) ){
				$oDB->deleteInFile( DB_PRODUCTS_VARIANTS, $iProductVariant, 'iProductVariant' );
				$oDB->deleteInFile( DB_PRODUCTS_ATTRIBUTES, $iProductVariant, 'iProductVariant' );
			} else{
				$aVariant['iProductVariant'] = $iProductVariant;
				$aVariant['iProduct'] = $aForm['iProduct'];
				if( isset( $aVariant['sWeight'] ) && $aVariant['sWeight'] != '' ){
					if( !preg_match( '/^[0-9]+\\.?[0-9]*$/', $aVariant['sWeight'] ) ){
						$aVariant['sWeight'] = str_replace( ',', '.', $aVariant['sWeight'] );
						$aVariant['sWeight'] = floatval( $aVariant['sWeight'] );
					}
				}
				if( !isset( $aVariant['iStatus'] ) ) $aVariant['iStatus'] = 0;
				$aGTPolaWlasne = $oDB->executeSQL( 'SELECT `iAttribute`, `iGTPoleWlasne` FROM `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '` INNER JOIN `' . $oDB->throwTableName( DB_ATTRIBUTES_VALUES ) . '` USING( `iAttributeValue` ) WHERE `iProductVariant` = ' . intval( $iProductVariant ), true, DataBase::ASSOCIATIVE );
				$oDB->deleteInFile( DB_PRODUCTS_ATTRIBUTES, $iProductVariant, 'iProductVariant' );
				$oDB->save( DB_PRODUCTS_VARIANTS, $aVariant, 'iProductVariant' );
				if( is_array( $aVariant['aStore'] ) ) foreach( $aVariant['aStore'] as $iStore => $aStore ){
					if( $aStore['iActive'] ){
						$aStore['iStore'] = $iStore;
						$aStore['iProductVariant'] = $iProductVariant;
						$oDB->save( DB_STORES_PRODUCTS, $aStore, Array( 'iStore', 'iProductVariant' ) );
					} else{
						$oDB->delete( DB_STORES_PRODUCTS, Array( 'iProductVariant' => $iProductVariant, 'iStore' => $iStore ) );
					}
				}
				if( is_array( $aVariant['aAttributes'] ) && !empty( $aVariant['aAttributes'] ) ){
					$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '` ( `iAttributeValue`, `iProductVariant`, `iGTPoleWlasne` ) VALUES ';
					foreach( $aVariant['aAttributes'] as $iAttribute => $iAttributeValue ){
						if( is_array( $iAttributeValue ) ){
							$sql .= '( ' . intval( $iAttributeValue[0] ). ', ' . intval( $iProductVariant ) . ', ' . intval( $iAttributeValue[1] ) . ' ),';
						} else{
							$sql .= '( ' . intval( $iAttributeValue ) . ', ' . intval( $iProductVariant ) . ', ' . intval( $aGTPolaWlasne[$iAttribute] ) . ' ),';
						}
					}
					$oDB->executeSQL( substr( $sql, 0, -1 ) );
				}
			}
		}
		if( is_array( $aForm['aNewVariants'] ) ) foreach( $aForm['aNewVariants'] as $iNewVariant => $aVariant ){
			if( is_numeric( $iNewVariant ) ){
				if( !isset( $aVariant['iDelete'] ) || ( $aVariant['iDelete'] != 1 ) ){
					if( !isset( $aVariant['iStatus'] ) ) $aVariant['iStatus'] = 0;
					$aVariant['iProduct'] = $aForm['iProduct'];
					if( isset( $aVariant['sWeight'] ) && $aVariant['sWeight'] != '' ){
						if( !preg_match( '/^[0-9]+\\.?[0-9]*$/', $aVariant['sWeight'] ) ){
							$aVariant['sWeight'] = str_replace( ',', '.', $aVariant['sWeight'] );
							$aVariant['sWeight'] = floatval( $aVariant['sWeight'] );
						}
					}
					$iProductVariant = $oDB->save( DB_PRODUCTS_VARIANTS, $aVariant );
					if( is_array( $aVariant['aAttributes'] ) ) foreach( $aVariant['aAttributes'] as $iAttributeValue ){
						$oDB->save( DB_PRODUCTS_ATTRIBUTES, Array( 'iAttributeValue' => $iAttributeValue, 'iProductVariant' => $iProductVariant ) );
					}
					if( is_array( $aVariant['aStore'] ) ) foreach( $aVariant['aStore'] as $iStore => $aStore ){
						if( $aStore['iActive'] ){
							$aStore['iStore'] = $iStore;
							$aStore['iProductVariant'] = $iProductVariant;
							$oDB->save( DB_STORES_PRODUCTS, $aStore, Array( 'iStore', 'iProductVariant' ) );
						}
					}
				}
			}
		}
		#var_dump( $aForm['aPaymentBlock'] );
		$this->deletePaymentBlock( $aForm['iProduct'] );
		if( !empty( $aForm['aPaymentBlock'] ) && count( $aForm['aPaymentBlock'] ) > 0 ) $this->savePaymentBlock( $aForm['aPaymentBlock'], $aForm['iProduct'] );
		
		//Aktualizacjia ceny produktu do najniższej ceny wariantu, jeśli wszystkie wariatny mają ustaloną konkretnie cenę
		$oDB->executeSQL( 'UPDATE `' . $oDB->throwTableName( DB_PRODUCTS ) . '` `p` INNER JOIN(
												SELECT IF( MIN( IFNULL( `pv`.`fPrice`, -1 ) ) = -1, `p1`.`fPrice`, MIN( IFNULL( `pv`.`fPrice`, -1 ) ) ) AS `fPrice`, `p1`.`iProduct`
													FROM `' . $oDB->throwTableName( DB_PRODUCTS ) . '` `p1` INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` `pv` USING( `iProduct` )
													WHERE `p1`.`iProduct` = ' . intval( $aForm['iProduct'] ) . ' AND `pv`.`iStatus` >= 1
													GROUP BY `p1`.`iProduct`
												) AS `pv1` USING( `iProduct` )
												SET `p`.`fPrice` = `pv1`.`fPrice`;' );
		return $aForm['iProduct'];
	}
	function getProductIdAndVariantIdByProductIndex( $sProductIndex ){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `iProduct`, `iProductVariant`
							FROM `' . $oDB->throwTableName( DB_PRODUCTS ) . '`
								LEFT JOIN `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` USING( `iProduct` )
							WHERE `sProductIndex` = \'' . $oDB->escape( $sProductIndex ) . '\'
							LIMIT 1';
		return $oDB->executeSQL( $sql, true, DataBase::SINGLE_RECORD );
	}
	function getProductIdAndVariantIdByEan( $sEan ){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `iProduct`, `iProductVariant`
							FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` AS `pv`
							WHERE `pv`.`sEan` = \'' . $oDB->escape( $sEan ) . '\'
							LIMIT 1';
		return $oDB->executeSQL( $sql, true, DataBase::SINGLE_RECORD );
	}
	function getProductIdAndVariantIdByOuter( $sOuter ){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `iProduct`, `iProductVariant`
							FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` AS `pv`
							WHERE `pv`.`sOuterId` = \'' . $oDB->escape( $sOuter ) . '\'
							LIMIT 1';
		return $oDB->executeSQL( $sql, true, DataBase::SINGLE_RECORD );
	}
	function updateVariant( $aForm, $iStore = null ){
		$oDB = & DataBase::getInstance( );
		$bVar = $oDB->update( DB_PRODUCTS_VARIANTS, $aForm, Array( 'iProductVariant' => $aForm['iProductVariant'] ) );
		if( isset( $iStore ) ){
			if( is_numeric( $aForm['iStock'] ) ){
				if( !$oDB->update( DB_STORES_PRODUCTS, Array( 'iStock' => intval( $aForm['iStock'] ) ), Array( 'iProductVariant' => intval( $aForm['iProductVariant'] ), 'iStore' => intval( $iStore ) ) ) ){
					$oDB->save( DB_STORES_PRODUCTS, Array( 'iStock' => intval( $aForm['iStock'] ), 'iProductVariant' => intval( $aForm['iProductVariant'] ), 'iStore' => intval( $iStore ) ) );
				}
			} else{
				$oDB->executeSQL( 'DELETE FROM `' . $oDB->throwTableName( DB_STORES_PRODUCTS ) . '` WHERE `iStore` = ' . intval( $iStore ) . ' AND `iProductVariant` = ' . intval( $aForm['iProductVariant'] ) );
			}
			$bSt = true;
		} else{
			$bSt = false;
		}
		return $bVar || $bSt;
	}
	function deleteProduct( $iProduct ){
		$oFile = FilesAdmin::getInstance( );
		$oDB = & DataBase::getInstance( );
		$oDB->deleteInFile( DB_PRODUCTS, $iProduct, 'iProduct' );
		$oDB->deleteInFile( DB_PRODUCTS_EXT, $iProduct, 'iProduct' );
		$this->deleteVariants( null, $iProduct );
		$oFile->deleteFiles( Array( $iProduct => $iProduct ), 2, 'iProduct' );
		$oDB->deleteInFile( DB_PRODUCTS_PAGES, $iProduct, 'iProduct' );
		$oDB->deleteInFile( DB_PRODUCTS_TABS, $iProduct, 'iProduct' );
		$oDB->deleteInFile( DB_PRODUCTS_STATS, $iProduct, 'iProduct' );
		$oDB->deleteInFile( DB_PRODUCTS_COMMENTS, $iProduct, 'iLink' );
		$oDB->deleteInFile( DB_PRODUCTS_DISCOUNTS, $iProduct, 'iProduct' );
		$oDB->deleteInFile( DB_PRODUCTS_RELATED, $iProduct, 'iProduct' );
		$oDB->deleteInFile( DB_ADVSEARCHER_PRODUCTS, $iProduct, 'iProduct' );
		$oDB->deleteInFile( DB_PRODUCTS_RELATED, $iProduct, 'iRelated' );
		$oDB->deleteInFile( DB_PRODUCTS_CARRIERS_PRICES, $iProduct, 'iProduct' );
	}
	function deleteVariants( $iVariant, $iProduct = null ){
		$oDB = & DataBase::getInstance( );
		if( isset( $iVariant ) && is_numeric( $iVariant ) ){
			$oDB->deleteInFile( DB_PRODUCTS_VARIANTS, $iVariant, 'iProductVariant' );
			$oDB->deleteInFile( DB_ORDERS_TEMP, $iVariant, 'iProductVariant' );
			$oDB->deleteInFile( DB_PRODUCTS_ATTRIBUTES, $iVariant, 'iProductVariant' );
			//$oDB->deleteInFile( DB_ORDERS_PRODUCTS, $iVariant, 'iProductVariant' );
		} else{
			$sql = 'SELECT `iProductVariant` FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` WHERE `iProduct` = ' . intval( $iProduct );
			$aPVs = $oDB->executeSQL( $sql, true );
			foreach( $aPVs as $aProductVariant ){
				$this->deleteVariants( $aProductVariant['iProductVariant'] );
			}
		}
	}
	function cloneProduct( $iProduct, $iStatus = 0 ){
		$oDB = & DataBase::getInstance( );
		$oFile = & FilesAdmin::getInstance( );
		if( !$this->checkProductsLimit( ) ){
			die( $GLOBALS['lang']['Products_limit_exceeded'] );
		}
		$sql = 'SELECT * FROM `' . $oDB->throwTableName( DB_PRODUCTS ) . '` NATURAL JOIN `' . $oDB->throwTableName( DB_PRODUCTS_EXT ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$aData = $oDB->executeSQL( $sql, true, DataBase::SINGLE_RECORD );
		$aData['iProduct'] = null;
		if( isset( $iStatus ) ){
			$aData['iStatus'] = $iStatus;
		}
		foreach( $aData as $sKey => $sValue ){
			if( substr( $sKey, 0, 1 ) == 'T' ) unset( $aData[$sKey] );
		}
		$aData['iProduct'] = $oDB->save( DB_PRODUCTS, $aData );
		$oDB->save( DB_PRODUCTS_EXT, $aData );
		//Pages
		$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_PAGES ) . '` ( `iProduct`, `iPage` ) SELECT ' . intval( $aData['iProduct'] ) . ', `iPage` FROM `' . $oDB->throwTableName( DB_PRODUCTS_PAGES ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$oDB->executeSQL( $sql );
		//Tabs
		$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_TABS ) . '` ( `iProduct`, `iTab`, `sContent` ) SELECT ' . intval( $aData['iProduct'] ) . ', `iTab`, `sContent` FROM `' . $oDB->throwTableName( DB_PRODUCTS_TABS ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$oDB->executeSQL( $sql );
		//Carrier prices
		$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_CARRIERS_PRICES ) . '` ( `iProduct`, `iCarrier`, `fPrice` ) SELECT ' . intval( $aData['iProduct'] ) . ', `iCarrier`, `fPrice` FROM `' . $oDB->throwTableName( DB_PRODUCTS_CARRIERS_PRICES ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$oDB->executeSQL( $sql );
		//Product discounts for user groups
		$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_DISCOUNTS ) . '` ( `iProduct`, `iGroup`, `fMultiply` ) SELECT ' . intval( $aData['iProduct'] ) . ', `iGroup`, `fMultiply` FROM `' . $oDB->throwTableName( DB_PRODUCTS_DISCOUNTS ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$oDB->executeSQL( $sql );
		//Products related (one-side only!)
		$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_RELATED ) . '` ( `iProduct`, `iRelated`, `iBox` ) SELECT ' . intval( $aData['iProduct'] ) . ', `iRelated`, `iBox` FROM `' . $oDB->throwTableName( DB_PRODUCTS_RELATED ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$oDB->executeSQL( $sql );
		//Products files and photos (without copying files, only copies links, for new file manager)
		$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_FILES ) . '` ( `iProduct`, `sFileName`, `sDescription`, `iPhoto`, `iPosition`, `iType`, `iSize` ) SELECT ' . intval( $aData['iProduct'] ) . ', `sFileName`, `sDescription`, `iPhoto`, `iPosition`, `iType`, `iSize` FROM `' . $oDB->throwTableName( DB_PRODUCTS_FILES ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$oDB->executeSQL( $sql );
		//Advsearcher
		$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_ADVSEARCHER_PRODUCTS ) . '` ( `iProduct`, `iValue` ) SELECT ' . intval( $aData['iProduct'] ) . ', `iValue` FROM `' . $oDB->throwTableName( DB_ADVSEARCHER_PRODUCTS ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$oDB->executeSQL( $sql );
		//Variants
		$sql = 'SELECT `iProductVariant`, ' . intval( $aData['iProduct'] ) . ' AS `iProduct`, `fPrice`, `iActiveDiscount`, `fPriceOld`, `iVat`, 0 AS `iStock`, `iStatus` FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` WHERE `iProduct` = ' . intval( $iProduct );
		$aVariants = $oDB->executeSQL( $sql, true );
		if( is_array( $aVariants ) ) foreach( $aVariants as $aVariant ){
			foreach( $aVariant as $sKey => $sValue ){
				if( substr( $sKey, 0, 1 ) == 'T' ) unset( $aVariant[$sKey] );
			}
			$iOldVariant = $aVariant['iProductVariant'];
			$aVariant['iProductVariant'] = null;
			$iNewVariant = $oDB->save( DB_PRODUCTS_VARIANTS, $aVariant );
			$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '` ( `iProductVariant`, `iAttributeValue` ) SELECT ' . intval( $iNewVariant ) . ', `iAttributeValue` FROM `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '` WHERE `iProductVariant` = ' . intval( $iOldVariant );
			$oDB->executeSQL( $sql );
			$sql = 'INSERT INTO `' . $oDB->throwTableName( DB_STORES_PRODUCTS ) . '` ( `iProductVariant`, `iStore`, `iStock`, `iAvailableOnStock`, `iAvailableOutOfStock` ) SELECT ' . intval( $iNewVariant ) . ', `iStore`, 0, `iAvailableOnStock`, `iAvailableOutOfStock` FROM `' . $oDB->throwTableName( DB_STORES_PRODUCTS ) . '` WHERE `iProductVariant` = ' . intval( $iOldVariant );
			$oDB->executeSQL( $sql );
		}
		return $aData['iProduct'];
	}
	function throwAvailabilityForSelect( ){
		$oDB = & DataBase::getInstance( );
		return $oDB->throwFileArraySmall( DB_PRODUCTS_AVAILABLE, 'iAvailable', 'sText', 'iAvailable' );
	}
	function throwAvailabilityForSelectOnStock( ){
		$oDB = & DataBase::getInstance( );
		return $oDB->throwFileArraySmall( DB_PRODUCTS_AVAILABLE, 'iAvailable', 'sText', 'iAvailable', Array( 'iCanBuy' => 1 ) );
	}
	function throwAdminVariants( $iProduct, $bGTPolaWlasne = false ){
		$oDB = & DataBase::getInstance( );
		$content = null;
		if( !empty( $iProduct ) ){
			$sql = 'SELECT * FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` LEFT JOIN `' . $oDB->throwTableName( DB_V_PRODUCTS_VARIANTS_NAMES ) . '` USING( `iProductVariant` ) WHERE `iProduct` = ' . intval( $iProduct ) . ' ORDER BY `sOuterId` ASC, `sEan` ASC';
			$aVariants = $oDB->executeSQL( $sql, true, DataBase::ASSOCIATIVE, 'iProductVariant' );
			$sql = 'SELECT COUNT( `iElement` ) AS `iCount`, `iAttribute`
								FROM `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '`
									INNER JOIN `' . $oDB->throwTableName( DB_ATTRIBUTES_VALUES ) . '` USING( `iAttributeValue` )
									INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` USING( `iProductVariant` )
								WHERE `iProduct` = ' . intval( $iProduct ) . '
								GROUP BY `iAttribute`';
			$sql = 'SELECT `a`.*, `av`.*, `c`.`iCount`
								FROM `' . $oDB->throwTableName( DB_ATTRIBUTES ) . '` AS `a`
									INNER JOIN `' . $oDB->throwTableName( DB_ATTRIBUTES_VALUES ) . '` AS `av` USING( `iAttribute` )
									INNER JOIN ( ' . $sql . ' ) AS `c` USING( `iAttribute` )
								ORDER BY `a`.`iPosition`, `a`.`iAttribute`, `av`.`iPosition`, `av`.`iAttributeValue`';
			$aAttributesValues = $oDB->executeSQL( $sql, true );
			$aAttributes = Array( );
			foreach( $aAttributesValues as $aAttributeValue ){
				if( !isset( $aAttributes[$aAttributeValue['iAttribute']] ) ){
					$aAttributes[$aAttributeValue['iAttribute']] = Array( 'iAttribute' => $aAttributeValue['iAttribute'], 'sName' => $aAttributeValue['sName'], 'iPosition' => $aAttributeValue['iPosition'], 'bActive' => ( $aAttributeValue['iCount'] > 0 ? true : false ) );
				}
				$aAttributes[$aAttributeValue['iAttribute']]['aValues'][$aAttributeValue['iAttributeValue']] = $aAttributeValue['sValue'];
			}
			$bFirst = true;
			foreach( $aVariants as &$aVariant ){
				$sql = 'SELECT `iAttribute`, `iAttributeValue`' . ( $bGTPolaWlasne ? ', `iGTPoleWlasne`' : null ) . ' FROM `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '` NATURAL JOIN `' . $oDB->throwTableName( DB_ATTRIBUTES_VALUES ) . '` WHERE `iProductVariant` = ' . intval( $aVariant['iProductVariant'] );
				if( $bGTPolaWlasne ){
					$aVariant['aValues'] = $oDB->executeSQL( $sql, true, DataBase::ASSOCIATIVE, 'iAttribute' );
					foreach( $aVariant['aValues'] as &$aValue ){
						$aValue = Array( $aValue['iAttributeValue'], $aValue['iGTPoleWlasne'] );
					}
				} else{
					$aVariant['aValues'] = $oDB->executeSQL( $sql, true, DataBase::ASSOCIATIVE );
				}
				$sql = 'SELECT `iStore`, 1 AS `iActive`, `iStock`, `iAvailableOnStock`, `iAvailableOutOfStock` FROM `' . $oDB->throwTableName( DB_STORES_PRODUCTS ) . '` WHERE `iProductVariant` = ' . $aVariant['iProductVariant'];
				$aVariant['aStore'] = $oDB->executeSQL( $sql, true, DataBase::ASSOCIATIVE, 'iStore' );
				$bFirst = false;
			}
		}
		return Array( $aVariants, $aAttributes );
	}
	function moveVariant( $iVariant, $iProduct ){
		$oDB = DataBase::getInstance( );
		$sql = 'SELECT DISTINCTROW `av`.`iAttribute`
							FROM `' . $oDB->throwTableName( DB_ATTRIBUTES_VALUES ) . '` AS `av`
								INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '` AS `pa` USING( `iAttributeValue` )
								INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` AS `pv` USING( `iProductVariant` )
							WHERE `pv`.`iProduct` = ' . intval( $iProduct ) . '
							ORDER BY `av`.`iAttribute`';
		$aProductAttribs = $oDB->executeSQL( $sql, true, DataBase::SINGLE_COLUMN );
		$sql = 'SELECT DISTINCTROW `av`.`iAttribute`
							FROM `' . $oDB->throwTableName( DB_ATTRIBUTES_VALUES ) . '` AS `av`
								INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS_ATTRIBUTES ) . '` AS `pa` USING( `iAttributeValue` )
							WHERE `pa`.`iProductVariant` = ' . intval( $iVariant ) . '
							ORDER BY `av`.`iAttribute`';
		$aVariantAttribs = $oDB->executeSQL( $sql, true, DataBase::SINGLE_COLUMN );
		if( $aVariantAttribs == $aProductAttribs ){
			$sql = 'UPDATE `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` SET `iProduct` = ' . intval( $iProduct ) . ' WHERE `iProductVariant` = ' . intval( $iVariant ) . ' LIMIT 1';
			$oDB->executeSQL( $sql );
			return true;
		} else{
			return false;
		}
	}
	function getProductIdAndVariantIdBySubiekt( $iSubiekt ){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `iProduct`, `iProductVariant`
							FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` AS `pv`
							WHERE `pv`.`iSubiekt` = \'' . $oDB->escape( $iSubiekt ) . '\'
							LIMIT 1';
		return $oDB->executeSQL( $sql, true, DataBase::SINGLE_RECORD );
	}
	function getProductIdByVariantId( $iVariant ){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `iProduct`, `iProductVariant`
							FROM `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` AS `pv`
							WHERE `pv`.`iProductVariant` = \'' . $oDB->escape( $iVariant ) . '\'
							LIMIT 1';
		return $oDB->executeSQL( $sql, true, DataBase::SINGLE_RECORD );
	}
	function sendAvailNewsletter(){
		$oDB = & DataBase::getInstance( );
		$sql = 'SELECT `n`.`iElement`, `n`.`sEmail`, `n`.`sPhone`, `p`.`iProduct`, `p`.`sName` FROM `' . $oDB->throwTableName( DB_PRODUCTS_AVAIL_NEWSLETTER ) . '` `n` INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS ) . '` `p` USING( `iProduct` ) WHERE `TiCanBuy` > 0 AND `n`.`iTimeSent` IS NULL AND `n`.`iProductVariant` IS NULL';
		$aProducts = $oDB->executeSQL( $sql, true );
		$sql = 'SELECT `n`.`iElement`, `n`.`sEmail`, `n`.`sPhone`, `p`.`iProduct`, `p`.`sName`, `pvn`.`sName` AS `sAttributes` FROM `' . $oDB->throwTableName( DB_PRODUCTS_AVAIL_NEWSLETTER ) . '` `n` INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS ) . '` `p` USING( `iProduct` ) INNER JOIN `' . $oDB->throwTableName( DB_PRODUCTS_VARIANTS ) . '` `pv` USING( `iProductVariant` ) LEFT JOIN `' . $oDB->throwTableName( DB_V_PRODUCTS_VARIANTS_NAMES ) . '` `pvn` USING( `iProductVariant` ) WHERE `pv`.`TiCanBuy` > 0 AND `n`.`iTimeSent` IS NULL';
		$aProductsVariants = $oDB->executeSQL( $sql, true );

		$aUrl = parse_url( 'http' . ( $_SERVER['HTTPS'] ? 's' : null ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
		if( !empty( $aUrl['path'] ) ){
			$aUrl['path'] = dirname( $aUrl['path'] );
			if( $aUrl['path'] !== "/" ){
				$aUrl['path'] .= '/';
			}
		}

		$aLangOld = $GLOBALS['lang'];
		include( DIR_LANG . LANGUAGE . '.php' );
		$GLOBALS['lang'] = $lang;

		foreach( $aProducts as $aProduct ){
			$aProduct['sLinkName'] = throwPageUrl( $aProduct['iProduct'] . ',' . change2Url( $aProduct['sName'] ) );
			$bSent = false;
			if( !empty( $aProduct['sEmail'] ) ){
				//mail
				if( sendEmail( Array( 'sTopic' => $lang['Avail_newsletter_email_title'], 'sMailContent' => str_replace( Array( '%sName%', '%sLinkName%' ), Array( $aProduct['sName'], $aUrl['scheme'] . '://' . $aUrl['host'] . $aUrl['path'] . $aProduct['sLinkName'] ), $lang['Avail_newsletter_email'] ), 'sSender' => $GLOBALS['config']['orders_email'] ), $aProduct['sEmail'] ) ){
					$bSent = true;
				}
			}
			if( !empty( $aProduct['sPhone'] ) && $GLOBALS['config']['sms_send_avail_newsletter'] ){
				//sms
				$sText = str_replace( Array( '%sShopName%', '%sName%', '%sLinkName%', '|n|' ), Array( $GLOBALS['config']['website_name'], $aProduct['sName'], $aProduct['sLinkName'], "\n" ), $lang['Avail_newsletter_sms'] );
				$oSMS = new SMS( $GLOBALS['config']['serwersms_login'], $GLOBALS['config']['serwersms_password'] );
				if( $oSMS->sendSMS_delay( $aProduct['sPhone'], $sText ) ){
					$bSent = true;
				}
			}
			if( $bSent ) $oDB->executeSQL( 'UPDATE `' . $oDB->throwTableName( DB_PRODUCTS_AVAIL_NEWSLETTER ) . '` SET `iTimeSent` = UNIX_TIMESTAMP() WHERE `iElement` = ' . $aProduct['iElement'] );
		}

		foreach( $aProductsVariants as $aProduct ){
			$aProduct['sLinkName'] = throwPageUrl( $aProduct['iProduct'] . ',' . change2Url( $aProduct['sName'] ) );
			if( !empty( $aProduct['sAttributes'] ) ) $aProduct['sName'] .= ', ' . $aProduct['sAttributes'];
			$bSent = false;
			if( !empty( $aProduct['sEmail'] ) ){
				//mail
				if( sendEmail( Array( 'sTopic' => $lang['Avail_newsletter_email_title'], 'sMailContent' => str_replace( Array( '%sName%', '%sLinkName%' ), Array( $aProduct['sName'], $aUrl['scheme'] . '://' . $aUrl['host'] . $aUrl['path'] . $aProduct['sLinkName'] ), $lang['Avail_newsletter_email'] ), 'sSender' => $GLOBALS['config']['orders_email'] ), $aProduct['sEmail'] ) ){
					$bSent = true;
				}
			}
			if( !empty( $aProduct['sPhone'] ) && $GLOBALS['config']['sms_send_avail_newsletter'] ){
				//sms
				$sText = str_replace( Array( '%sShopName%', '%sName%', '%sLinkName%', '|n|' ), Array( $GLOBALS['config']['website_name'], $aProduct['sName'], $aProduct['sLinkName'], "\n" ), $lang['Avail_newsletter_sms'] );
				$oSMS = new SMS( $GLOBALS['config']['serwersms_login'], $GLOBALS['config']['serwersms_password'] );
				if( $oSMS->sendSMS_delay( $aProduct['sPhone'], $sText ) ){
					$bSent = true;
				}
			}
			if( $bSent ) $oDB->executeSQL( 'UPDATE `' . $oDB->throwTableName( DB_PRODUCTS_AVAIL_NEWSLETTER ) . '` SET `iTimeSent` = UNIX_TIMESTAMP() WHERE `iElement` = ' . $aProduct['iElement'] );
		}
		$GLOBALS['lang'] = $aLangOld;
	}
	function checkProductsLimit( ){
		if( !defined( 'PRODUCTS_LIMIT' ) || PRODUCTS_LIMIT == 0 ){
			return true;
		} else{
			$oDB = & DataBase::getInstance( );
			return ( $oDB->executeSQL( 'SELECT COUNT( `iProduct` ) FROM `' . $oDB->throwTableName( DB_PRODUCTS ) . '`', true, DataBase::SINGLE_VALUE ) < PRODUCTS_LIMIT );
		}
	}
	
	function deletePaymentBlock( $iProduct ){
		$oDB = & DataBase::getInstance( );
		$oDB->executeSQL( 'DELETE FROM `' . $oDB->throwTableName( DB_PRODUCTS_PAYMENTS_BLOCK ) . '` WHERE `iProduct` = ' . $iProduct );
	}
	
	function savePaymentBlock( $aForm, $iProduct ){
		$oDB = & DataBase::getInstance( );
		foreach( $aForm as $iPayment ){
			$oDB->executeSQL( 'INSERT INTO `' . $oDB->throwTableName( DB_PRODUCTS_PAYMENTS_BLOCK ) . '` ( `iProduct`, `iPayment` ) VALUES ( ' . $iProduct . ', ' . $iPayment . ' ) ' );
		}
	}
	
	function getPaymentBlock( $iProduct ){
		$oDB = & DataBase::getInstance( );
		return $oDB->executeSQL( 'SELECT `iPayment` FROM `' . $oDB->throwTableName( DB_PRODUCTS_PAYMENTS_BLOCK ) . '` WHERE `iProduct` = ' . $iProduct, true, DataBase::SINGLE_COLUMN );
	}
}
?>