Index: trunk/kernel/include/usersession.php =================================================================== diff -u -N -r2000 -r2082 --- trunk/kernel/include/usersession.php (.../usersession.php) (revision 2000) +++ trunk/kernel/include/usersession.php (.../usersession.php) (revision 2082) @@ -442,9 +442,10 @@ FROM '.$prefix.'PortalUser pu LEFT JOIN '.$prefix.'UserGroup ug USING (PortalUserId) LEFT JOIN '.$prefix.'PortalGroup pg ON ug.GroupId = pg.GroupId - WHERE ('.$key_clause.') AND (pu.Status = 1) AND (pu.Password = %2$s OR MD5(pu.Password) = %2$s OR pu.Password = MD5(%2$s) ) + WHERE ('.$key_clause.') AND (pu.Status = 1) AND (pu.Password = %2$s OR MD5(pu.Password) = %2$s OR pu.Password = MD5(%2$s) ) AND + ( (ug.MembershipExpires IS NULL) OR ( ug.MembershipExpires >= UNIX_TIMESTAMP() ) ) ORDER BY ug.PrimaryGroup DESC, pg.Personal DESC'; - + $result = $db->Execute( sprintf($sql, $db->qstr($userLogin), $db->qstr($userPassword) ) ); if($result === false) Index: trunk/kernel/include/parseditem.php =================================================================== diff -u -N -r1566 -r2082 --- trunk/kernel/include/parseditem.php (.../parseditem.php) (revision 1566) +++ trunk/kernel/include/parseditem.php (.../parseditem.php) (revision 2082) @@ -943,36 +943,52 @@ return $this->Items[$index]; } - function &GetItemByField($Field,$Value,$LoadFromDB=TRUE) + function &GetItemByField($Field, $Value, $LoadFromDB = true) { - $found=FALSE; - if(is_array($this->Items)) - { - foreach($this->Items as $i) - { - if($i->Get($Field)==$Value) - { - $found = TRUE; - break; - } - } - } - if(!$found && $LoadFromDB==TRUE) - { - $sql = 'SELECT * FROM '.$this->SourceTable.' WHERE '.$Field.' = "'.addslashes($Value).'"'; -// $sql = 'SELECT * FROM '.$this->SourceTable.' WHERE '.$Field.' = "'.($Value).'"'; - $res = $this->adodbConnection->Execute($sql); + if( !is_array($Field) ) $Field = Array($Field); + if( !is_array($Value) ) $Value = Array($Value); - if($res && !$res->EOF) - { - $i = $this->AddItemFromArray($res->fields); - $i->tablename = $this->SourceTable; - $i->Clean(); - } - else - $i = FALSE; - } - return $i; + $found = false; + if( is_array($this->Items) ) + { + foreach($this->Items as $i) + { + $sub_found = true; + foreach($Field as $key_index => $field_name) + { + $sub_found = $sub_found && ( $i->Get($field_name) == $Value[$key_index] ); + } + + if($sub_found) + { + $found = true; + break; + } + } + } + + if( !$found && $LoadFromDB == true ) + { + $sql = 'SELECT * FROM '.$this->SourceTable.' WHERE '; + foreach($Field as $key_index => $field_name) + { + $sql .= '(`'.$field_name.'` = '.$this->adodbConnection->qstr($Value[$key_index]).') AND '; + } + $sql = preg_replace('/(.*) AND $/', '\\1', $sql); + $res = $this->adodbConnection->Execute($sql); + + if($res && !$res->EOF) + { + $i = $this->AddItemFromArray($res->fields); + $i->tablename = $this->SourceTable; + $i->Clean(); + } + else + { + $i = false; + } + } + return $i; } function GetPage($Page, $ItemsPerPage) Index: trunk/admin/install/upgrades/inportal_upgrade_v1.1.1.sql =================================================================== diff -u -N -r2052 -r2082 --- trunk/admin/install/upgrades/inportal_upgrade_v1.1.1.sql (.../inportal_upgrade_v1.1.1.sql) (revision 2052) +++ trunk/admin/install/upgrades/inportal_upgrade_v1.1.1.sql (.../inportal_upgrade_v1.1.1.sql) (revision 2082) @@ -14,3 +14,5 @@ INSERT INTO StylesheetSelectors VALUES (173, 8, 'Calendar''s control buttons', '.calendar .calendar_button', 'a:0:{}', '', 1, 'color: black;\r\nfont-size: 12px;\r\nbackground-color: #eeeeee;', 0); INSERT INTO StylesheetSelectors VALUES (174, 8, 'Calendar''s day names', '.calendar thead .name', 'a:0:{}', '', 1, 'background-color: #DEEEF6;\r\nborder-bottom: 1px solid #000000;', 0); INSERT INTO StylesheetSelectors VALUES (175, 8, 'Calendar''s days', '.calendar tbody .day', 'a:0:{}', '', 1, 'text-align: right;\r\npadding: 2px 4px 2px 2px;\r\nwidth: 2em;\r\nborder: 1px solid #fefefe;', 0); + +ALTER TABLE UserGroup ADD MembershipExpires INT UNSIGNED DEFAULT NULL AFTER GroupId; \ No newline at end of file Index: trunk/kernel/units/users/users_event_handler.php =================================================================== diff -u -N -r2070 -r2082 --- trunk/kernel/units/users/users_event_handler.php (.../users_event_handler.php) (revision 2070) +++ trunk/kernel/units/users/users_event_handler.php (.../users_event_handler.php) (revision 2082) @@ -36,7 +36,9 @@ $object->Load($user_id); if( $object->GetDBField('Status') == STATUS_ACTIVE ) { - $sql = 'SELECT DISTINCT GroupId FROM '.TABLE_PREFIX.'UserGroup WHERE PortalUserId = '.$user_id; + $sql = 'SELECT GroupId FROM %s WHERE (PortalUserId = %s) AND ( (MembershipExpires IS NULL) OR ( MembershipExpires >= UNIX_TIMESTAMP() ) )'; + $sql = sprintf($sql, TABLE_PREFIX.'UserGroup', $user_id); + $groups = $this->Conn->GetCol($sql); if(!$groups) $groups = Array(); array_push($groups, $this->Application->ConfigValue('User_LoggedInGroup') ); Index: trunk/core/units/users/users_event_handler.php =================================================================== diff -u -N -r2070 -r2082 --- trunk/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 2070) +++ trunk/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 2082) @@ -36,7 +36,9 @@ $object->Load($user_id); if( $object->GetDBField('Status') == STATUS_ACTIVE ) { - $sql = 'SELECT DISTINCT GroupId FROM '.TABLE_PREFIX.'UserGroup WHERE PortalUserId = '.$user_id; + $sql = 'SELECT GroupId FROM %s WHERE (PortalUserId = %s) AND ( (MembershipExpires IS NULL) OR ( MembershipExpires >= UNIX_TIMESTAMP() ) )'; + $sql = sprintf($sql, TABLE_PREFIX.'UserGroup', $user_id); + $groups = $this->Conn->GetCol($sql); if(!$groups) $groups = Array(); array_push($groups, $this->Application->ConfigValue('User_LoggedInGroup') ); Index: trunk/admin/install/inportal_schema.sql =================================================================== diff -u -N -r2052 -r2082 --- trunk/admin/install/inportal_schema.sql (.../inportal_schema.sql) (revision 2052) +++ trunk/admin/install/inportal_schema.sql (.../inportal_schema.sql) (revision 2082) @@ -529,6 +529,7 @@ CREATE TABLE UserGroup ( PortalUserId int(11) NOT NULL default '0', GroupId int(11) NOT NULL default '0', + MembershipExpires int(10) unsigned default NULL, PrimaryGroup tinyint(4) NOT NULL default '1', PRIMARY KEY (PortalUserId,GroupId), KEY GroupId (GroupId), Index: trunk/kernel/admin/include/navmenu.php =================================================================== diff -u -N -r1607 -r2082 --- trunk/kernel/admin/include/navmenu.php (.../navmenu.php) (revision 1607) +++ trunk/kernel/admin/include/navmenu.php (.../navmenu.php) (revision 2082) @@ -324,6 +324,11 @@ "javascript:edit_submit('edituser','UserEditStatus','".$admin."/users/user_addimage.php',0);", $admin."/icons/icon46_community.gif", $admin."/icons/icon24_users.gif", NULL, NULL, NULL,NULL,-1); + +$objSections->AddSection("in-portal:edituser_group","la_tab_Images","la_title_edit_user",$admin."/category/", + "javascript:edit_submit('edituser','UserEditStatus','".$admin."/users/user_editgroup.php',0);", + $admin."/icons/icon46_community.gif", $admin."/icons/icon24_users.gif", + NULL, NULL, NULL,NULL,-1,'',1); $objSections->AddSection("in-portal:edituser_permission","la_tab_Permissions","la_title_edit_user",$admin."/category/", "javascript:edit_submit('edituser','UserEditStatus','".$admin."/users/user_addpermission.php',0);", Index: trunk/kernel/include/portalgroup.php =================================================================== diff -u -N -r1606 -r2082 --- trunk/kernel/include/portalgroup.php (.../portalgroup.php) (revision 1606) +++ trunk/kernel/include/portalgroup.php (.../portalgroup.php) (revision 2082) @@ -209,15 +209,28 @@ function parsetag($tag) { - global $var_list_update, $objConfig; - if(is_object($tag)) - { - $tagname = $tag->name; - } - else - $tagname = $tag; + global $var_list_update, $objConfig, $objSession; + $tagname = is_object($tag) ? $tag->name : $tag; + + $is_temp = strpos($this->SourceTable, $objSession->Get('SessionKey') ) !== false; + switch($tagname) { + case 'GroupName': + $db =& GetADODBConnection(); + $table = $is_temp ? $objSession->GetEditTable('PortalGroup') : GetTablePrefix().'PortalGroup'; + $sql = 'SELECT Name FROM '.$table.' WHERE GroupId = '.$this->Get('GroupId'); + return $db->GetOne($sql); + break; + + case 'membership_expires_date': + return $this->Get('MembershipExpires') <= 0 ? '' : LangDate( $this->Get('MembershipExpires') ); + break; + + case 'membership_expires_time': + return $this->Get('MembershipExpires') <= 0 ? '' : LangTime( $this->Get('MembershipExpires') ); + break; + case "group_id": return $this->Get("GroupId"); break; @@ -502,35 +515,49 @@ function CopyFromEditTable($idfield) { - global $objSession; - $GLOBALS['_CopyFromEditTable']=1; + global $objSession; + $GLOBALS['_CopyFromEditTable']=1; - $edit_table = $objSession->GetEditTable($this->SourceTable); - $sql = "SELECT * FROM $edit_table"; - $rs = $this->adodbConnection->Execute($sql); - - //echo $sql."
"; - - $clear_old = true; - while($rs && !$rs->EOF) - { - $data = $rs->fields; - - if ($clear_old) { - $sql = "DELETE FROM ".$this->SourceTable." WHERE $idfield = ".$data[$idfield]; - @$this->adodbConnection->Execute($sql); - $clear_old = false; - } - - $sql = "INSERT INTO ".$this->SourceTable." (PortalUserId, GroupId, PrimaryGroup) VALUES (".$data['PortalUserId'].", ".$data['GroupId'].", ".$data['PrimaryGroup'].")"; - @$this->adodbConnection->Execute($sql); - - $rs->MoveNext(); - } - - @$this->adodbConnection->Execute("DROP TABLE IF EXISTS $edit_table"); - unset($GLOBALS['_CopyFromEditTable']); - } + $edit_table = $objSession->GetEditTable($this->SourceTable); + $sql = "SELECT * FROM $edit_table"; + $rs = $this->adodbConnection->Execute($sql); + + //echo $sql."
"; + + $clear_old = true; + $insert_sql = 'INSERT INTO %s (PortalUserId,GroupId,MembershipExpires,PrimaryGroup) VALUES (%s,%s,%s,%s)'; + while($rs && !$rs->EOF) + { + $data = $rs->fields; + + if($clear_old) + { + $sql = "DELETE FROM ".$this->SourceTable." WHERE $idfield = ".$data[$idfield]; + @$this->adodbConnection->Execute($sql); + $clear_old = false; + } + + if(!$data['MembershipExpires']) $data['MembershipExpires'] = 'NULL'; + $sql = sprintf($insert_sql, $this->SourceTable, $data['PortalUserId'], $data['GroupId'], $data['MembershipExpires'], $data['PrimaryGroup'] ); + + @$this->adodbConnection->Execute($sql); + + $rs->MoveNext(); + } + + @$this->adodbConnection->Execute("DROP TABLE IF EXISTS $edit_table"); + unset($GLOBALS['_CopyFromEditTable']); + } + + function &Edit_UserGroup($group_id, $user_id, $membership_expires) + { + $ug =& $this->GetItemByField( Array('GroupId','PortalUserId'), Array($group_id,$user_id) ); + if($membership_expires == 0) $membership_expires = null; + + $ug->Set('MembershipExpires', $membership_expires); + $ug->Update(); + return $ug; + } } ?> Index: trunk/kernel/action.php =================================================================== diff -u -N -r1894 -r2082 --- trunk/kernel/action.php (.../action.php) (revision 1894) +++ trunk/kernel/action.php (.../action.php) (revision 2082) @@ -224,6 +224,17 @@ $objEditItems->SourceTable = $objSession->GetEditTable("PortalGroup"); $objEditItems->Edit_Group($_POST["group_id"], $_POST["group_name"],$_POST["group_comments"]); break; + + + case 'm_group_edit': // when editing user membership in group + $membership_expires = DateTimestamp( $_POST['membership_expires_date'], GetDateFormat() ); + $membership_expires += SecondsSinceMidnight( $_POST['membership_expires_time'] ); + + $objEditItems = new clsUserGroupList(); + $objEditItems->SourceTable = $objSession->GetEditTable('UserGroup'); + $objEditItems->Edit_UserGroup($_POST['GroupId'], $_POST['PortalUserId'], $membership_expires); + break; + case "m_add_group": $objEditItems = new clsGroupList(); $objEditItems->SourceTable = $objSession->GetEditTable("PortalGroup"); Index: trunk/admin/users/adduser_groups.php =================================================================== diff -u -N -r1566 -r2082 --- trunk/admin/users/adduser_groups.php (.../adduser_groups.php) (revision 1566) +++ trunk/admin/users/adduser_groups.php (.../adduser_groups.php) (revision 2082) @@ -167,6 +167,12 @@ "OpenGroupSelector('$envar&source=adduser_groups&UserId=".$c->Get("PortalUserId")."&destform=group&destfield=grouplist');", "tool_usertogroup.gif"); +$objListToolBar->Add("group_edit","Edit","#", "if (GroupChecks.itemChecked()) swap('group_edit','toolbar/tool_edit_f2.gif');", + "if (GroupChecks.itemChecked()) swap('group_edit', 'toolbar/tool_edit.gif');","if (GroupChecks.itemChecked()) GroupChecks.check_submit('user_editgroup', '');", + "tool_edit.gif",TRUE,TRUE); +$listImages[] = "GroupChecks.addImage('group_edit','$imagesURL/toolbar/tool_edit.gif','$imagesURL/toolbar/tool_edit_f3.gif',1); "; + + $objListToolBar->Add("user_del","la_ToolTip_DeleteFromGroup","#", "if (GroupChecks.itemChecked()) swap('user_del','toolbar/tool_delete_f2.gif');", "if (GroupChecks.itemChecked()) swap('user_del', 'toolbar/tool_delete.gif');","if (GroupChecks.itemChecked()) GroupChecks.check_submit('adduser_groups', 'm_user_removegroup');", "tool_delete.gif",FALSE,TRUE); @@ -242,9 +248,11 @@ /* ------------------------------------ Build the SQL statement to populate the list ---------------------------*/ $orderBy = trim($objConfig->Get($SortFieldVar)." ".$order); + +$phrase_never = language('la_NeverExpires'); if(strlen($orderBy)) $orderBy = " ORDER BY ".$orderBy; -$sql = "SELECT g.GroupId as GroupId, g.name as GroupName, count(u.PortalUserId) as UserCount FROM ".GetTablePrefix()."PortalGroup as g "; +$sql = "SELECT g.GroupId as GroupId, g.name as GroupName, count(u.PortalUserId) as UserCount, IF(MembershipExpires IS NOT NULL, DATE_FORMAT( FROM_UNIXTIME(MembershipExpires) ,'%m/%d/%y %h:%i:%s %p'), '".$phrase_never."') AS MembershipExpires FROM ".GetTablePrefix()."PortalGroup as g "; $sql .="INNER JOIN ".$objSession->GetEditTable("UserGroup")." as u ON g.GroupId=u.GroupId WHERE u.PortalUserId=".$c->Get("PortalUserId")." $where GROUP BY g.name".$orderBy; if($objSession->HasSystemPermission("DEBUG.LIST")) @@ -257,7 +265,8 @@ $objListView->IdField = "GroupId"; $objListView->ColumnHeaders->Add("GroupName", admin_language("la_prompt_GroupName"),1,0,$order,"width=\"50%\"",$SortFieldVar,$SortOrderVar,"GroupName"); -$objListView->ColumnHeaders->Add("UserCount",admin_language("la_prompt_UserCount"),1,0,$order,"width=\"50%\"",$SortFieldVar,$SortOrderVar,"UserCount"); +$objListView->ColumnHeaders->Add("UserCount",admin_language("la_prompt_UserCount"),1,0,$order,"width=\"10%\"",$SortFieldVar,$SortOrderVar,"UserCount"); +$objListView->ColumnHeaders->Add("MembershipExpires",admin_language("la_prompt_MembershipExpires"),1,0,$order,"width=\"40%\"",$SortFieldVar,$SortOrderVar,"MembershipExpires"); $objListView->ColumnHeaders->SetSort($objConfig->Get("UserGroup_SortField"),$order); $objListView->PrintToolBar = FALSE; Index: trunk/kernel/include/itemdb.php =================================================================== diff -u -N -r1566 -r2082 --- trunk/kernel/include/itemdb.php (.../itemdb.php) (revision 1566) +++ trunk/kernel/include/itemdb.php (.../itemdb.php) (revision 2082) @@ -279,59 +279,44 @@ return true; } - function Update($UpdatedBy=NULL,$modificationDate = null) - { - global $Errors, $objSession; - - if(count($this->m_dirtyFieldsMap) == 0) - return true; + function Update($UpdatedBy=NULL,$modificationDate = null) + { + global $Errors, $objSession; - $this->SetModified($UpdatedBy,$modificationDate); - $sql = "UPDATE ".$this->tablename ." SET "; - $first = 1; + if( count($this->m_dirtyFieldsMap) == 0 ) return true; - foreach ($this->m_dirtyFieldsMap as $key => $value) - { - if(!is_numeric($key) && $key != $this->IdField() && $key!='ResourceId') - { - if($first) - { - if(isset($GLOBALS['_CopyFromEditTable'])) - $sql = sprintf("%s %s=%s",$sql,$key,$this->adodbConnection->qstr(($value))); - else - $sql = sprintf("%s %s=%s",$sql,$key,$this->adodbConnection->qstr(stripslashes($value))); - $first = 0; - } - else - { - if(isset($GLOBALS['_CopyFromEditTable'])) - $sql = sprintf("%s, %s=%s",$sql,$key,$this->adodbConnection->qstr(($value))); - else - $sql = sprintf("%s, %s=%s",$sql,$key,$this->adodbConnection->qstr(stripslashes($value))); - } - } - } + $this->SetModified($UpdatedBy, $modificationDate); + $sql = 'UPDATE '.$this->tablename .' SET '; - $sql = sprintf("%s WHERE %s = '%s'",$sql, $this->IdField(), $this->UniqueId()); + foreach ($this->m_dirtyFieldsMap as $key => $value) + { + if(!is_numeric($key) && $key != $this->IdField() && $key!='ResourceId') + { + if( is_null($value) ) + { + $value = 'NULL'; + } + else + { + $value = $this->adodbConnection->qstr( isset($GLOBALS['_CopyFromEditTable']) ? $value : stripslashes($value) ); + } + $sql .= '`'.$key.'` = '.$value.', '; + } + } + $sql = preg_replace('/(.*), $/','\\1',$sql); + + $sql .= ' WHERE '.$this->IdField().' = '.$this->adodbConnection->qstr( $this->UniqueId() ); - if($this->debuglevel>0) - echo $sql."
"; - if ($this->adodbConnection->Execute($sql) === false) - { - $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"Update"); - return false; - } - - if ($objSession->GetVariable("HasChanges") == 2) { - $objSession->SetVariable("HasChanges", 1); - } - -/* if ($this->adodbConnection->Affected_Rows() > 0) { - $objSession->SetVariable("HasChanges", 1); - }*/ - - return true; - } + if( $this->debuglevel > 0 ) echo $sql.'
'; + if( $this->adodbConnection->Execute($sql) === false ) + { + $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"Update"); + return false; + } + + if( $objSession->GetVariable('HasChanges') == 2 ) $objSession->SetVariable('HasChanges', 1); + return true; + } function ReplaceID($new_id) {