From 43928984b1cc3c5603c3ef072b31506518490b8d Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <reinhold@kainhofer.com>
Date: Sun, 18 Aug 2013 00:09:43 +0200
Subject: [PATCH] Version 0.1: Adding/removing to/from Joomla/VM groups finally
 works

---
 buyer_assign_group.php                        | 161 ++++++++++--------
 ..._opentools_vm2_buyer_assign_group_v0.1.zip | Bin 0 -> 7308 bytes
 2 files changed, 86 insertions(+), 75 deletions(-)
 create mode 100644 releases/plg_opentools_vm2_buyer_assign_group_v0.1.zip

diff --git a/buyer_assign_group.php b/buyer_assign_group.php
index 2c09322..6bdf051 100644
--- a/buyer_assign_group.php
+++ b/buyer_assign_group.php
@@ -13,7 +13,7 @@ defined('_JEXEC') or 	die( 'Direct Access to ' . basename( __FILE__ ) . ' is not
 if (!class_exists('vmCustomPlugin')) require(JPATH_VM_PLUGINS . DS . 'vmcustomplugin.php');
 
 class plgVmCustomBuyer_Assign_Group extends vmCustomPlugin {
-
+	var $counter=0;
 	function __construct(& $subject, $config) {
 		parent::__construct($subject, $config);
 		$this->_tablepkey = 'id';
@@ -38,8 +38,6 @@ class plgVmCustomBuyer_Assign_Group extends vmCustomPlugin {
 		$html = '';
 		$this->parseCustomParams($field);
 		
-// 		$html .= "<pre>States: ".join(", ", $this->purchased_status)."</pre>";
-		$html .= "<pre>Field: ".print_r($this, 1)."</pre>";
 		$html .= '<table class="admintable">';
 		$html .= VmHTML::row (array('JHTML', '_'),'VMCUSTOM_BUYER_GROUP_JOOMLA', 'access.usergroup', 'custom_param['.$row.'][joomla_groups][]', $field->joomla_groups, ' multiple data-placeholder=" "', false);
 		$html .= VmHTML::row (array('JHTML', '_'),'VMCUSTOM_BUYER_GROUP_JOOMLA_REMOVE', 'access.usergroup', 'custom_param['.$row.'][joomla_groups_remove][]', $field->joomla_groups_remove, ' multiple data-placeholder=" "', true);
@@ -97,22 +95,53 @@ class plgVmCustomBuyer_Assign_Group extends vmCustomPlugin {
 		return $SQLfields;
 	}
 	
+	function setShopperGroups($uid, $groups) {
+		$noError = true;
+		$userModel = VmModel::getModel('user');
+		$userModel->setId($uid);
+		$shoppergroupmodel = VmModel::getModel('ShopperGroup');
+		$defaultgroup = $shoppergroupmodel->getDefault(0);
+
+		if(empty($groups) or ($groups == array($defaultgroup->virtuemart_shoppergroup_id))) {
+			$groups = array();
+		}
+
+		// Bind the form fields to the table
+		$shoppergroupData = array('virtuemart_user_id'=>$uid,
+			'virtuemart_shoppergroup_id'=>$groups);
+		$user_shoppergroups_table = $userModel->getTable('vmuser_shoppergroups');
+		$shoppergroupData = $user_shoppergroups_table -> bindChecknStore($shoppergroupData);
+		$errors = $user_shoppergroups_table->getErrors();
+		foreach($errors as $error){
+			$this->setError($error);
+			vmError('Set shoppergroup '.$error);
+			$noError = false;
+		}
+		return $noError;
+	}
+	
 	function addShopperGroup($user, $group) {
-		# TODO
+		$groups = $user->shopper_groups;
+		if (!in_array($group, $groups)) {
+			$groups[] = $group;
+			return $this->setShopperGroups($user->virtuemart_user_id, $groups);
+		}
+		return false;
 	}
 	function removeShopperGroup($user, $group) {
-		# TODO
+		$groups = $user->shopper_groups;
+		if (in_array($group, $groups)) {
+			$groups=array_diff($groups, array($group));
+			return $this->setShopperGroups($user->virtuemart_user_id, $groups);
+		}
+		return false;
 	}
 	function setModifiedFlag ($entry, $value) {
-JFactory::getApplication()->enqueueMessage("setModifiedFlag: entry=<pre>".print_r($entry,1)."</pre>", 'error');
-			$db = JFactory::getDbo();
-			$db->setQuery("UPDATE `".$this->_tablename."` SET `modified`=".(int)$value." WHERE `id`=".$entry['id']);
-			if (!$db->query()) {
-				JFactory::getApplication()->enqueueMessage("SQL query FAILED: Message: ".$db->getErrorMsg().", SQL: <pre>".$db->getQuery()."</pre>", 'error');
-			}
-			$this->updateOrderStatus($order_id, $order['details']['BT']->order_status, '');
-	
-		# TODO
+		$db = JFactory::getDbo();
+		$db->setQuery("UPDATE `".$this->_tablename."` SET `modified`=".(int)$value." WHERE `id`=".$entry['id']);
+		if (!$db->query()) {
+			JFactory::getApplication()->enqueueMessage("SQL query FAILED: Message: ".$db->getErrorMsg().", SQL: <pre>".$db->getQuery()."</pre>", 'error');
+		}
 	}
 
 	function updateOrderStatus ($order_id, $order_status, $old_order_status) {
@@ -148,78 +177,58 @@ JFactory::getApplication()->enqueueMessage("setModifiedFlag: entry=<pre>".print_
 				$pstates[$cid] = $c->purchased_status;
 			}
 		}
-foreach ($users as $u) {
-JFactory::getApplication()->enqueueMessage("User: Joomla groups <pre>".print_r($u->JUser->groups,1)."</pre>, Shopper Groups: <pre>".print_r($u->shopper_groups,1)."</pre>", 'info');
-}
-// JFactory::getApplication()->enqueueMessage("User: <pre>".print_r($users,1)."</pre>", 'info');
-// JFactory::getApplication()->enqueueMessage("User: <pre>".print_r($users,1)."</pre>", 'info');
 		
 		// 3) Check which custom field entries need some change
 		foreach ($orderEntries as $e) {
 
-try {
-			$uid = $e['virtuemart_user_id'];
-			$cid = $e['virtuemart_custom_id'];
-			$purchased   =  in_array($order_status, $pstates[$cid]) && !in_array($old_order_status, $pstates[$cid]);
-			$unpurchased = !in_array($order_status, $pstates[$cid]) &&  in_array($old_order_status, $pstates[$cid]);
+			try {
+				$uid = $e['virtuemart_user_id'];
+				$cid = $e['virtuemart_custom_id'];
+				$purchased   =  in_array($order_status, $pstates[$cid]) && !in_array($old_order_status, $pstates[$cid]);
+				$unpurchased = !in_array($order_status, $pstates[$cid]) &&  in_array($old_order_status, $pstates[$cid]);
 
-JFactory::getApplication()->enqueueMessage("Order status: $order_status, old order status: $old_order_status, pstates: ".print_r($pstates[$cid],1), 'info');
-JFactory::getApplication()->enqueueMessage("Purchased: $purchased, Unpurchased: $unpurchased", 'info');
-			if ($purchased) {
-				$modified = false;
-				if ($e['group_type']==0) { // Joomla User Group
-// 					$modified = ($e['group_add'] != );
-					if ($e['group_add']==1 && !in_array($e['group_id'], $users[$uid]->JUser->groups)) { // Add to Joomla user group
-JFactory::getApplication()->enqueueMessage("Trying to add user $uid to group ".$e['group_id'], 'info');
-						$res = JUserHelper::addUserToGroup ($uid, $e['group_id']);
-					} elseif ($e['group_add']==0 && in_array($e['group_id'], $users[$uid]->JUser->groups)) { // Remove from Joomla user group
-JFactory::getApplication()->enqueueMessage("Trying to remove user $uid from group ".$e['group_id'], 'info');
-						$res = JUserHelper::removeUserFromGroup ($uid, $e['group_id']);
-					}
-					$modified = $res;
-JFactory::getApplication()->enqueueMessage("Result: ".print_r($res,1), 'info');
-				} elseif ($e['group_type']=1) { // Virtuemart Shopper Group
-					if ($e['group_add']==1) { // Add to Virtuemart Shopper group
-						$res = $this->addShopperGroup($users[$uid], $e['group_id']);
-					} elseif ($e['group_add']==0) { // Remove from Virtuemart Shopper group
-						$res = $this->removeShopperGroup ($users[$uid], $e['group_id']);
+				if ($purchased) {
+					$modified = false;
+					if ($e['group_type']==0) { // Joomla User Group
+						if ($e['group_add']==1 && !in_array($e['group_id'], $users[$uid]->JUser->groups)) { // Add to Joomla user group
+							$modified = JUserHelper::addUserToGroup ($uid, $e['group_id']);
+						} elseif ($e['group_add']==0 && in_array($e['group_id'], $users[$uid]->JUser->groups)) { // Remove from Joomla user group
+							$modified = JUserHelper::removeUserFromGroup ($uid, $e['group_id']);
+						}
+					} elseif ($e['group_type']=1) { // Virtuemart Shopper Group
+						if ($e['group_add']==1) { // Add to Virtuemart Shopper group
+							$modified = $this->addShopperGroup($users[$uid], $e['group_id']);
+						} elseif ($e['group_add']==0) { // Remove from Virtuemart Shopper group
+							$modified = $this->removeShopperGroup ($users[$uid], $e['group_id']);
+						}
 					}
-				}
-				if ($modified) {
-					$this->setModifiedFlag ($e, $modified);
-				}
-			} elseif ($unpurchased && $e['modified']) {
-				// Undo the addition/removal when a product purchase is cancelled
-				if ($e['group_type']==0) { // Joomla User Group
-JFactory::getApplication()->enqueueMessage("Trying to Undo add (".$e['group_add'].") user $uid to group ".$e['group_id'], 'info');
-					if ($e['group_add']==1) { // Remove from Joomla user group again
-						$res = JUserHelper::removeUserFromGroup ($uid, $e['group_id']);
-					} elseif ($e['group_add']==0) { // Add to Joomla user group again
-						$res = JUserHelper::addUserToGroup ($uid, $e['group_id']);
+					if ($modified) {
+						$this->setModifiedFlag ($e, $modified);
 					}
-JFactory::getApplication()->enqueueMessage("Result: ".print_r($res,1), 'info');
-				} elseif ($e['group_type']==1) { // Virtuemart Shopper Group
-					if ($e['group_add']==1) { // Remove from Virtuemart Shopper group again
-						$modified = $this->removeShopperGroup($users[$uid], $e['group_id']);
-					} elseif ($e['group_add']==0) { // Add from Virtuemart Shopper group again
-						$modified = $this->addShopperGroup ($users[$uid], $e['group_id']);
+				} elseif ($unpurchased && $e['modified']) {
+					// Undo the addition/removal when a product purchase is cancelled
+					if ($e['group_type']==0) { // Joomla User Group
+						if ($e['group_add']==1) { // Remove from Joomla user group again
+							$modified = JUserHelper::removeUserFromGroup ($uid, $e['group_id']);
+						} elseif ($e['group_add']==0) { // Add to Joomla user group again
+							$modified = JUserHelper::addUserToGroup ($uid, $e['group_id']);
+						}
+					} elseif ($e['group_type']==1) { // Virtuemart Shopper Group
+						if ($e['group_add']==1) { // Remove from Virtuemart Shopper group again
+							$modified = $this->removeShopperGroup($users[$uid], $e['group_id']);
+						} elseif ($e['group_add']==0) { // Add from Virtuemart Shopper group again
+							$modified = $this->addShopperGroup ($users[$uid], $e['group_id']);
+						}
 					}
+					// Clear the modified flag in the database
+					$this->setModifiedFlag ($e, 0);
 				}
-				// Clear the modified flag in the database
-				$this->setModifiedFlag ($e, 0);
 			}
-}
-catch (Exception $ex) {
-JFactory::getApplication()->enqueueMessage("ERROR:  <pre>".$ex->getMessage()."</pre>", 'info');
-    $ex->getMessage();
-    JLog::add('Unable to add/remove user to/from group');
-}
+			catch (Exception $ex) {
+				JFactory::getApplication()->enqueueMessage("ERROR:  <pre>".$ex->getMessage()."</pre>", 'info');
+				JLog::add('Unable to add/remove user to/from group: '.$ex->getMessage());
+			}
 		}
-		
-		
-// JFactory::getApplication()->enqueueMessage("Order Entries: <pre>".print_r($orderEntries,1)."</pre>", 'info');
-// JFactory::getApplication()->enqueueMessage("Purchased States: <pre>".print_r($pstates,1)."</pre>", 'info');
-
 	}
 	
 	function plgVmCouponUpdateOrderStatus($data, $old_order_status) {
@@ -238,6 +247,8 @@ JFactory::getApplication()->enqueueMessage("ERROR:  <pre>".$ex->getMessage()."</
 		$uid = $user->JUser->id;
 
 		$order_id = $order['details']['BT']->virtuemart_order_id;
+		$orderModel = VmModel::getModel('orders');
+		$order = $orderModel->getOrder($order_id);
 
 		$values = array();
 		$customModel = VmModel::getModel('customfields');
diff --git a/releases/plg_opentools_vm2_buyer_assign_group_v0.1.zip b/releases/plg_opentools_vm2_buyer_assign_group_v0.1.zip
new file mode 100644
index 0000000000000000000000000000000000000000..925051084c99798dec6134b7b811ead03676e994
GIT binary patch
literal 7308
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
HOM-X+Y$>}?

literal 0
HcmV?d00001

-- 
GitLab