<?php

class FrontEndUserListing extends CMSModule
{
	var $devdebug = 0;
	
	function GetName()
	{
		return 'FrontEndUserListing';
	}
	
	function GetFriendlyName()
	{
		return $this->Lang('friendlyname');
	}
	
	function GetVersion()
	{
		return '0.3';
	}
	
	function GetHelp()
	{
		return $this->Lang('help');
	}
	
	function GetAuthor()
	{
		return 'Katon';
	}
	
	function GetAuthorEmail()
	{
		return 'katonchik@gmail.com';
	}
	
	function GetChangeLog()
	{
		return $this->Lang('changelog');
	}
	
	function IsPluginModule()
	{
		return true;
	}
	
	function HasAdmin()
	{
		return true;
	}
	
	function GetAdminSection()
	{
		return 'usersgroups';
	}
	
	
	function GetAdminDescription()
	{
		return $this->Lang('moddescription');
	}
	
	
	function VisibleToAdminUser()
	{
		return $this->CheckPermission('Use FrontEndUserListing');
	}
	
	function GetDependencies()
	{
		return array( 'FrontEndUsers' => '0.1.3' );
	}
	
	
	function Install()
	{
		$this->CreatePermission('Use FrontEndUserListing', 'Use FrontEndUserListing');
		$this->SetTemplate('displaysummary', $this->GetSummaryHtmlTemplate());
		$this->SetTemplate('displaydetails', $this->GetDetailsHtmlTemplate());
		$this->Audit( 0, $this->Lang('friendlyname'), $this->Lang('installed',$this->GetVersion()));
	}
	
	function InstallPostMessage()
	{
		return $this->Lang('postinstall');
	}
	
	function Upgrade($oldversion, $newversion) 
	{
		switch( $oldversion )
		{
			case '0.1':
			$this->SetTemplate('displaydetails', $this->GetDetailsHtmlTemplate());
		}
	}
	
	function UninstallPostMessage()
	{
		return $this->Lang('postuninstall');
	}
	
	
	function Uninstall()
	{
		$this->RemovePermission('Use FrontEndUserListing');
		$this->Audit( 0, $this->Lang('friendlyname'), $this->Lang('uninstalled'));
	}
	

	function DoAction($action, $id, $params, $returnid=-1)
	{
		switch ($action)
		{
			case 'default':
			{
				$this->DisplayUsersInGroup( $id, $params, $returnid );
				break;
			}
			case 'viewdetails':
			{
				$this->DisplayUserDetails( $id, $params, $returnid );
				break;
			}
			case 'defaultadmin':
			{
				// only let people access module preferences if they have permission
				if ($this->CheckPermission('Use FrontEndUserListing'))
				{
				    $this->DisplayAdminPanel($id, $params, $returnid);
				} else {
				    $this->_DisplayErrorPage($id, $params, $returnid,
					    $this->Lang('accessdenied'));
				}
				break;
			}
			case "updatesummarytemplate":
			{
				$this->SetTemplate('displaysummary', $params['templatecontent']);
				$this->myRedirectToTab($id, 'defaultadmin', 'summary_template');
//				$this->Redirect($id, 'defaultadmin');
				break;
			}
			case "updatedetailstemplate":
			{
				$this->SetTemplate('displaydetails', $params['templatecontent']);
				$this->myRedirectToTab($id, 'defaultadmin', 'details_template');
//				$this->Redirect($id, 'defaultadmin');
				break;
			}
		}
	}



	/*---------------------------------------------------------
	DisplayUsersInGroup($id, $params, $returnid, $message)
	NOT PART OF THE MODULE API
	---------------------------------------------------------*/
	function DisplayUsersInGroup( $id, &$params, $returnid )
	{
	
		$this->debugarray($params);
		
		$feusers = $this->GetModuleInstance('FrontEndUsers');
		if( !$feusers )
		{
			$this->_DisplayErrorPage( $id, $params, $returnid,
					      $this->Lang('error_nofeusersmodule'));
			return;
		}
		
		$cmsmailer = $this->GetModuleInstance('CMSMailer');
		if( !$cmsmailer )
		{
			$this->_DisplayErrorPage( $id, $params, $returnid,
					      $this->Lang('error_nofeusersmodule'));
			return;
		}
		
		// yep, all the modules are here, now we
		// have to check if the group is specified
		if( !isset($params['group']) )
		{
			$this->_DisplayErrorPage( $id, $params, $returnid,
					      $this->Lang('error_nogroupspecified'));
			return;
		}
		
		// The group is specified, now we 
		// have to convert the groupname into an id
		$grpid = $feusers->GetGroupID($params['group']);
		if( $grpid == false )
		{
			$this->_DisplayErrorPage( $id, $params, $returnid,
					      $this->Lang('error_nosuchgroup'));
			return;
		}
		
		// now we have an id... have to get a list of the groups properties
		$relations = $feusers->GetGroupPropertyRelations( $grpid );
		if( $relations[0] == false )
		{
			$this->_DisplayErrorPage( $id, '', $returnid, $relations[1] );
			return;
		}
		uasort( $relations, 'compare_elements_by_sortorder_key' );
		
		// now we have the properties, gotta show something to the user
		if( isset( $params['error'] ) )
		{
			$this->smarty->assign('error', $params['error']);
		}
		if( isset( $params['message'] ) )
		{
			$this->smarty->assign('message', $params['message']);
		}
		
		// now we're ready to populate the template
		// first we put in stuff that is required (username, password, etc, etc)
		$listheader = array();
		
		foreach( $relations as $reln )
		{
			// don't process hidden fields here
			if( $reln['required'] == 3 ) continue;
			
			// get the property definition
			// Is $defn a string or an array?
			$name = $reln['name'];
			$defn = $feusers->GetPropertyDefn( $name );
			$onerow = new StdClass();
			
			$listheader[$name] = $defn['prompt'];
		}
		
		$db = $this->GetDb();
		$entryarray = array();
		$query = "SELECT p.*, b.groupid FROM "
		.cms_db_prefix()."module_feusers_properties p, "
		.cms_db_prefix()."module_feusers_belongs b, "
		.cms_db_prefix()."module_feusers_groups g "
		."WHERE b.userid = p.userid "
		."AND b.groupid = g.id";
		if (isset($grpid))
		{
			$query .= " AND g.id=" . $grpid;
		}
		$dbresult=$db->Execute($query);
		
		$rawdata = array();
		while ($row = $dbresult->FetchRow())
		{
			array_push( $rawdata, $row );
		}
		$sortkey = (isset($params['sortkey']) ? $params['sortkey'] : 'userid'); 
		$data = $this->SortUsers($rawdata, $listheader, $id, $returnid, $sortkey);
		$this->debugarray($data, "Processed user data");
		
		$this->smarty->assign_by_ref ('listheader', $listheader);
		$this->smarty->assign_by_ref('items', $data);
		echo "<!-- Displaying FEUserListing Module -->\n";
		if (isset($params['summarytemplate']))
		{
			echo $this->ProcessTemplate($params['summarytemplate']);
		}
		else
		{
			#$log->debug($this->ProcessTemplateFromDatabase('displaysummary'));
			echo $this->ProcessTemplateFromDatabase('displaysummary');
		}
	
	}
	
    
	/*---------------------------------------------------------
	DisplayUserDetails($id, $params, $returnid, $message)
	NOT PART OF THE MODULE API
	---------------------------------------------------------*/
	function DisplayUserDetails( $id, &$params, $returnid )
	{
	
		$this->debugarray($params);
		
		$feusers = $this->GetModuleInstance('FrontEndUsers');
		if( !$feusers )
		{
			$this->_DisplayErrorPage( $id, $params, $returnid,
					      $this->Lang('error_nofeusersmodule'));
			return;
		}
		
		$cmsmailer = $this->GetModuleInstance('CMSMailer');
		if( !$cmsmailer )
		{
			$this->_DisplayErrorPage( $id, $params, $returnid,
					      $this->Lang('error_nofeusersmodule'));
			return;
		}
		
		// yep, all the modules are here, now we
		// have to check if the group is specified
		if( !isset($params['uid']) )
		{
			$this->_DisplayErrorPage( $id, $params, $returnid,
					      $this->Lang('error_nouserspecified'));
			return;
		}
		$uid = $params['uid'];
		
		// get the users member groups
		$groups = $feusers->GetMemberGroupsArray( $uid );
		if( !$groups )
		{
			// this user is not a member of any gruops...
			// handle this later todo
			$this->_DisplayErrorPage( $id, $params, $returnid, 
					  $feusers->Lang('error_nogroups'));
			return;
		}
		
		// now we have the groups, we build a union of all of the groups properties
		$properties = array();
		foreach( $groups as $grprecord )
		{
			$gid = $grprecord['groupid'];
			$proprelations = $feusers->GetGroupPropertyRelations( $gid );
			$properties = array_merge_by_name_required( $properties, $proprelations );
			uasort( $properties, 'compare_elements_by_sortorder_key' );
		}
		
		if( count($properties) == 0 )
		{
			if( $feusers->GetPreference('require_onegroup') == 1 )
			{
				// this user is not a member of any gruops...
				// handle this later todo
				$this->_DisplayErrorPage( $id, $params, $returnid, 
						      $this->Lang('error_onegrouprequired'));
				return;
			}
		}
		
		// now we have the properties, gotta show something to the user
		if( isset( $params['error'] ) )
		{
			$this->smarty->assign('error', $params['error']);
		}
		if( isset( $params['message'] ) )
		{
			$this->smarty->assign('message', $params['message']);
		}
		
		
		// now we're ready to populate the template
		// first we put in stuff that is required (username, password, etc, etc)
		$listheader = array();
		
		foreach( $properties as $reln )
		{
			// don't process hidden fields here
			if( $reln['required'] == 3 ) continue;
			
			// get the property definition
			// Is $defn a string or an array?
			$name = $reln['name'];
			$defn = $feusers->GetPropertyDefn( $name );
			$onerow = new StdClass();
			
			$listheader[$name] = $defn['prompt'];
		}
		
		$db = $this->GetDb();
		$entryarray = array();
		$query = "SELECT p.* FROM "
		.cms_db_prefix()."module_feusers_properties p "
		."WHERE p.userid = $uid";
		$dbresult=$db->Execute($query);
		
		$rawdata = array();
		while ($row = $dbresult->FetchRow())
		{
			array_push( $rawdata, $row );
		}
		$data = $this->PrepareUserDetails($rawdata, $listheader);
		
		$this->smarty->assign_by_ref('items', $data);
		echo "<!-- Displaying FEUserListing Module -->\n";
		
		if (isset($params['detailstemplate']))
		{
			echo $this->ProcessTemplate($params['detailstemplate']);
		}
		else
		{
			echo $this->ProcessTemplateFromDatabase('displaydetails');
		}
	}
    
    
	function PrepareUserDetails($rawdata, $listheader)
	{
		$this->debugarray($rawdata, "rawdata");
		$this->debugarray($listheader, "listheader");
		$ret = array();
		foreach ($listheader as $lcode => $prompt){
			foreach($rawdata as $row){
				if($lcode == $row['title'] && $row['data'] != ''){
					$record = new stdClass();
					$record->prompt = $prompt;
					$record->data = $row['data'];
					$ret[$lcode] = $record;
				}
			}
		}
		$this->debugarray($ret, "Sorted data");
		$this->SortAsDefs($ret, $listheader);
		return $ret;
	}
		
		
	function SortUsers($rawdata, $listheader, $id, $returnid, $sortkey)
	{
		$this->debugarray($rawdata, "rawdata");
		$users = array();

		// create the user array from the raw data
		foreach ($rawdata as $row)
		{
			$userid = $row['userid']; // user id of the current data bit
			$users[$userid][$row['title']] = $row['data'];
		}
        
   		// sort the array
		$users = $this->DoUserSort($users, $sortkey);

		$users = $this->SortUserData($users, $listheader, $ret, $id, $returnid);
		
		return $users;
	}
		
	/**
	 * Sort the users by the sortkey
	 */
    function DoUserSort ($array, $sortkey) 
    {
        if(is_array($array) && count($array)> 0)
        {
            // add userid index
            foreach ($array as $key => $value)
            {
                $array[$key]['userid'] = $key;
            }
            
            foreach(array_keys($array) as $key) 
            {
                $temp[$key] = $array[$key][$sortkey];
            }
            asort($temp);
    
            foreach(array_keys($temp) as $key)
            { 
                $sorted[] = $array[$key];
            }
    
            return $sorted;
        }
        return $array;
    }

	
	/**
	 * Sort data for each user and add links to details
	 */
	function SortUserData($users, $listheader, &$ret, $id, $returnid)
	{
		$ret = array();
		foreach ($users as $sortkey => $userdata)
		{
			$sorteduser = $this->SortAsDefs($userdata, $listheader);
			$detlink = $this->CreateLink(
									$id, 
									'viewdetails', 
									$returnid, 
									'',
									array('uid'=>$userdata['userid']),
									'', //warn message
									true //only href section
									);
			//Link to user details is used as a key for compatibility with v.0.1. template.
			$sorteduser['detlink'] = $detlink;
			$ret[$sortkey] = $sorteduser;
		}
		$this->debugarray($ret, "sorted user data");
		return $ret;
	}
	
	
	function GetDetailsHtmlTemplate()
	{
		return '<!-- Start FrontEndUserListing Details Template -->

<!-- To access properties, use dots, not arrows.  E.g.: prop.first_name -->

<table width="100%" border="1">

{foreach from=$items item=entry}

<tr>

<td>{$entry->prompt}</td>

<td>{$entry->data}</td>

</tr>

{/foreach}

</table>
		
<!-- End FrontEndUserListing Details Template -->';
	}
		

	function GetSummaryHtmlTemplate()
	{
		return '<!-- Start FrontEndUserListing Summary Template -->

<!-- To access properties, use dots, not arrows.  E.g.: prop.first_name -->

<table width="100%" border="1">

<tr>

{foreach from=$listheader item=hprop}

<th>{$hprop}</th>

{/foreach}

</tr>

{foreach from=$items item=entry}

<tr>

<!-- Link to user details is used as a key for compatibility with v.0.1. -->
{foreach from=$entry item=prop key=key}

<td><a href="{$entry.detlink}">{$prop}</a></td>

{/foreach}

</tr>

{/foreach}

</table>
		
<!-- End FrontEndUserListing Summary Template -->';
	}
		
		
		
/*		
	function GetSummaryHtmlTemplate()
	{
		return '<!-- Start FrontEndUserListing Display Template -->
<table width="100%" border="1">
{foreach from=$items item=entry}
<tr>
<td>
{$entry.first_name} {$entry.last_name}<br>
<a href="mailto:{$entry.Email}">{$entry.last_name}</a><br>
</td>
<td>
{$entry.home_phone}<br> {$entry.cell_phone}
</td>
<td>
{$entry.icq}
</td>
<td>
{$entry.ip}
</td>
</tr>		
{/foreach}
</table>		
		
<!-- End FrontEndUserListing Display Template -->';		
}
*/
/*		
	function GetSummaryHtmlTemplate()
	{
		return '<!-- Start FrontEndUserListing Display Template -->
<table width="100%" border="1">
{foreach from=$items item=entry}
<tr>
<td>
{$entry.first_name} {$entry.last_name}
</td>
<td>
{$entry.email}
</td>
</tr>		
{/foreach}
</table>		
		
<!-- End FrontEndUserListing Display Template -->';		
}
*/
		
		
	function _DisplayErrorPage($id, $params, $returnid, $message='')
	{
		$this->smarty->assign('title_error', $this->Lang('error'));
		if ($message != '')
		{
			$this->smarty->assign_by_ref('message', $message);
		}
		
		echo $this->ProcessTemplate('error.tpl');
	}

    
    
	function DisplayAdminPanel($id, &$params, $returnid, $message='')
	{
	    $active_tab = -1;
	    if( isset($params['active_tab'])) {
			$active_tab = $params['active_tab'];
		}
		echo $this->StartTabHeaders();
		echo $this->SetTabHeader('summary_template',$this->Lang('summarytemplate'),
				($active_tab == 'summary_template'));
		echo $this->SetTabHeader('details_template',$this->Lang('detailstemplate'),
				($active_tab == 'details_template'));
		echo $this->EndTabHeaders();
		echo $this->StartTabContent();
		
		echo $this->StartTab('summary_template');
		echo $this->CreateFormStart($id, 'updatesummarytemplate');
		echo '<p>'.$this->CreateTextArea(false, $id, $this->GetTemplate('displaysummary'), 'templatecontent', '').'</p>';
		echo $this->CreateInputSubmit($id, 'submitbutton', $this->Lang('submit'));
		echo $this->CreateFormEnd();
		echo $this->EndTab();
		
		echo $this->StartTab('details_template');
		echo $this->CreateFormStart($id, 'updatedetailstemplate');
		echo '<p>'.$this->CreateTextArea(false, $id, $this->GetTemplate('displaydetails'), 'templatecontent', '').'</p>';
		echo $this->CreateInputSubmit($id, 'submitbutton', $this->Lang('submit'));
		echo $this->CreateFormEnd();
		echo $this->EndTab();
		
		echo $this->EndTabContent();
	}

	/*--------------------------------------------------------
	orig_array contains pairs like 'home_phone' => '276-2650'
	sample_array contains pairs like 'home_phone' => 'Home Phone'
	----------------------------------------------------------*/
	
	function SortAsDefs($orig_array, $sample_array)
	{
		$sorted_array = array();
		foreach ($sample_array as $key => $value) {
			if (isset($orig_array[$key])){
				$sorted_array[$key] = $orig_array[$key];
			} else {
				$sorted_array[$key] = "&nbsp;";
			}
		}
		return $sorted_array;
	}

	function debugarray($debugarray, $message=''){
		if ($this->devdebug == 1){
			echo "\n\n<br><br>------------- Debug info: ----------------<br>\n";
			$stacktrace = debug_backtrace();
			if (count($stacktrace) > 1 && $stacktrace[1]['function'] != ''){
				echo "Inside " . $stacktrace[1]['function'] . "<br>\n";
				echo "Called from "
						. $stacktrace[3]['function'] . ", "
						. $stacktrace[2]['function'] . "<br>\n";
			}
			if ($message != ''){
				echo $message . "<br>";
			}
			echo "\n<table cellpadding=10 border=0>\n<tr>\n<td>";
			foreach( $debugarray as $key => $val ){
//				echo "<b>$key</b><br>";
				if(is_array($val)){
					echo "</td>\n<td>";
					echo "<b>Array $key</b><br>";
					$this->debugsubarray($val);
				} else if (is_object($val)){
					echo "</td>\n<td>";
					echo "<b>Object $key</b><br>";
					$this->debugsubarray(get_object_vars($val));
				} else {
					echo "<b>Vector</b>";
					echo "\t<span style=\padding-left:20px\">"
							. $key . ": " . $val . "</span><br>\n";
				}
			};
			echo "</td>\n</tr>\n</table>\n";
			echo "------------- End debug info ----------------<br><br>\n\n";
		}
	}

	function debugsubarray($debugarray){
		foreach( $debugarray as $key => $val ){
			if(is_array($val)){
				echo "\t" . $key . ": " . print_r($val) . "<br>\n";
			} else {
				echo "\t" . $key . ": " . $val . "<br>\n";
			}
		}
	}

	function myRedirectToTab( $id, $action, $tab, $params = '', $message = '' )
	{
		$parms = array();
		if( is_array( $params ) )
		{
			$parms = $params;
		}
		$parms['active_tab'] = $tab;
		$parms['message'] = $message;
		$this->myRedirect( $id, $action, $parms );
	}

	function myRedirect( $id, $action, $params = '' )
	{
		unset( $params['action'] );
		$this->Redirect( $id, $action, '', $params );
	}

	
}

?>
