<?php
/*======================================================================*\
|| #################################################################### ||
|| # ---------------------------------------------------------------- # ||
|| # Copyright ©2013 Fillip Hannisdal AKA Revan/NeoRevan/Belazor 	  # ||
|| # All Rights Reserved. 											  # ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------------------------------------------------------- # ||
|| # You are not allowed to use this on your server unless the files  # ||
|| # you downloaded were done so with permission.					  # ||
|| # ---------------------------------------------------------------- # ||
|| #################################################################### ||
\*======================================================================*/

if (!class_exists('vB_DataManager', false))
{
	exit;
}

/**
* Class to do data save/delete operations for feedbacks
*
* @package	vbshop
*/
class vBShop_DataManager_Feedback extends vB_DataManager
{
	/**
	* Array of recognised and required fields for feedbacks, and their types
	*
	* @var	array
	*/
	var $validfields = array(
		'feedbackid' 	=> array(TYPE_UINT, 	REQ_INCR, 	VF_METHOD, 	'verify_nonzero'),
		'userid' 		=> array(TYPE_UINT, 	REQ_YES, 	VF_METHOD, 	'verify_userid'),
		'purchaseid' 	=> array(TYPE_UINT, 	REQ_YES),
		'dateline' 		=> array(TYPE_UNIXTIME, REQ_AUTO),
		'rating' 		=> array(TYPE_UINT, 	REQ_YES),
		'feedback'		=> array(TYPE_STR, 		REQ_NO),
	);

	/**
	* Array of field names that are bitfields, together with the name of the variable in the registry with the definitions.
	*
	* @var	array
	*/
	//var $bitfields = array('adminpermissions' => 'bf_ugp_adminpermissions');

	/**
	* The main table this class deals with
	*
	* @var	string
	*/
	var $table = 'dbtech_vbshop_feedback';

	/**
	* Condition for update query
	*
	* @var	array
	*/
	var $condition_construct = array('feedbackid = %1$d', 'feedbackid');

	/**
	* Constructor - checks that the registry object has been passed correctly.
	*
	* @param	vB_Registry	Instance of the vBulletin data registry object - expected to have the database object as one of its $this->db member.
	* @param	integer		One of the ERRTYPE_x constants
	*/
	function vBShop_DataManager_Transactionlog(&$registry, $errtype = ERRTYPE_STANDARD)
	{
		parent::vB_DataManager($registry, $errtype);

		($hook = vBulletinHook::fetch_hook('dbtech_vbshop_feedbackdata_start')) ? eval($hook) : false;
	}

	/**
	* Any checks to run immediately before saving. If returning false, the save will not take place.
	*
	* @param	boolean	Do the query?
	*
	* @return	boolean	True on success; false if an error occurred
	*/
	function pre_save($doquery = true)
	{
		if ($this->presave_called !== null)
		{
			return $this->presave_called;
		}
		
		if ($this->condition === null)
		{
			// Set the stats temporarily
			$timenow = TIMENOW;
			$this->do_set('dateline', $timenow);
		}
		
		$return_value = true;
		($hook = vBulletinHook::fetch_hook('dbtech_vbshop_feedbackdata_presave')) ? eval($hook) : false;

		$this->presave_called = $return_value;
		return $return_value;
	}
	
	/**
	* Additional data to update before a delete call (such as denormalized values in other tables).
	*
	* @param	boolean	Do the query?
	*/
	function pre_delete($doquery = true)
	{
		$return_value = true;
		($hook = vBulletinHook::fetch_hook('dbtech_vbshop_feedbackdata_predelete')) ? eval($hook) : false;

		$this->presave_called = $return_value;
		return $return_value;
	}

	/**
	* Additional data to update after a save call (such as denormalized values in other tables).
	* In batch updates, is executed for each record updated.
	*
	* @param	boolean	Do the query?
	*/
	function post_save_each($doquery = true)
	{
		($hook = vBulletinHook::fetch_hook('dbtech_vbshop_feedbackdata_postsave')) ? eval($hook) : false;

		// Update feedback status
		VBSHOP::$db->update('dbtech_vbshop_purchase', array('feedbackstatus' => 3), 'WHERE purchaseid = ' . $this->fetch_field('purchaseid'));

		if (isset($this->info['shop']))
		{
			// Recalculate shop ratings
			$numFeedback = VBSHOP::$db->fetchOne('
				SELECT COUNT(*) 
				FROM $dbtech_vbshop_feedback AS feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ?
			', array(
				$this->info['shop']['shopid']
			));
			$totalPos = VBSHOP::$db->fetchOne('
				SELECT COUNT(*) 
				FROM $dbtech_vbshop_feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ? 
					AND rating >= 4
			', array(
				$this->info['shop']['shopid']
			));
			$totalNeg = VBSHOP::$db->fetchOne('
				SELECT COUNT(*) 
				FROM $dbtech_vbshop_feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ? 
					AND rating <= 2
			', array(
				$this->info['shop']['shopid']
			));
			$avgRating = VBSHOP::$db->fetchOne('
				SELECT AVG(rating)
				FROM $dbtech_vbshop_feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ?
			', array(
				$this->info['shop']['shopid']
			));

			// Ensure we don't have more than 2 decimals
			$avgRating = round($avgRating, 2);

			// Calculate average positive
			$avgPos = round(($totalPos / $numFeedback) * 100, 2);
			$avgNeg = round(($totalNeg / $numFeedback) * 100, 2);
			$avgNeu = round((($numFeedback - $totalNeg - $totalPos) / $numFeedback) * 100, 2);

			// init data manager
			$dm =& VBSHOP::initDataManager('Shop', $this->registry, ERRTYPE_SILENT);
				$dm->set_existing($this->info['shop']);
				$dm->set('averagerating', 	$avgRating);
				$dm->set('positivepercent', $avgPos);
				$dm->set('negativepercent', $avgNeg);
				$dm->set('neutralpercent', 	$avgNeu);
			$dm->save();
		}

		return true;
	}

	/**
	* Additional data to update after a delete call (such as denormalized values in other tables).
	*
	* @param	boolean	Do the query?
	*/
	function post_delete($doquery = true)
	{
		($hook = vBulletinHook::fetch_hook('dbtech_vbshop_feedbackdata_delete')) ? eval($hook) : false;
		
		if (isset($this->info['shop']))
		{
			// Recalculate shop ratings
			$numFeedback = VBSHOP::$db->fetchOne('
				SELECT COUNT(*) 
				FROM $dbtech_vbshop_feedback AS feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ?
			', array(
				$this->info['shop']['shopid']
			));
			$totalPos = VBSHOP::$db->fetchOne('
				SELECT COUNT(*) 
				FROM $dbtech_vbshop_feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ? 
					AND rating >= 4
			', array(
				$this->info['shop']['shopid']
			));
			$totalNeg = VBSHOP::$db->fetchOne('
				SELECT COUNT(*) 
				FROM $dbtech_vbshop_feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ? 
					AND rating <= 2
			', array(
				$this->info['shop']['shopid']
			));
			$avgRating = VBSHOP::$db->fetchOne('
				SELECT AVG(rating)
				FROM $dbtech_vbshop_feedback
				INNER JOIN $dbtech_vbshop_purchase AS purchase USING(purchaseid)
				WHERE shopid = ?
			', array(
				$this->info['shop']['shopid']
			));

			// Ensure we don't have more than 2 decimals
			$avgRating = round($avgRating, 2);

			// Calculate average positive
			$avgPos = round(($totalPos / $numFeedback) * 100, 2);
			$avgNeg = round(($totalNeg / $numFeedback) * 100, 2);
			$avgNeu = round((($numFeedback - $totalNeg - $totalPos) / $numFeedback) * 100, 2);

			// init data manager
			$dm =& VBSHOP::initDataManager('Shop', $this->registry, ERRTYPE_SILENT);
				$dm->set_existing($this->info['shop']);
				$dm->set('averagerating', 	$avgRating);
				$dm->set('positivepercent', $avgPos);
				$dm->set('negativepercent', $avgNeg);
				$dm->set('neutralpercent', 	$avgNeu);
			$dm->save();
		}

		return true;
	}
}