Skip to content
Snippets Groups Projects
susignup-admin.php 13.7 KiB
Newer Older
Thomas Lake's avatar
Thomas Lake committed
<?PHP
/***
Thomas Lake's avatar
Thomas Lake committed
 * Allows us to search the SU api for a given student number and checks if they're a SUCS member.
 * If they are - allows account renewal
 * If not - allows signup to be bootstrapped as per susignup component
 ***/

include("../lib/member_functions.php");
include("../lib/date.php");
Thomas Lake's avatar
Thomas Lake committed
include("../suapi.inc.php");

//Restrict access to staff.
Thomas Lake's avatar
Thomas Lake committed
$permission="sucsstaff";
$apibaseurl="https://$suapi_user:$suapi_pass@su-api.sucs.org/memberships/Membership.asmx";
Thomas Lake's avatar
Thomas Lake committed

if (isset($session->groups[$permission])) {
	//Setup smarty magic, step 1
	$smarty->assign("staff", TRUE);

	if(!isset($_REQUEST['mode'])) {
		$mode = 'menu';
	} else {
		$mode = urldecode($_REQUEST['mode']);
	}

	if ($mode == 'search') {
		if (empty($_REQUEST['sid']) || empty($_REQUEST['snsubmit'])) {
			$mode = 'error';
			$smarty->assign("error_text", "Invalid search request");	
		}else{
			$pres=preg_match("/^[0-9]{6}$/",$_REQUEST['sid'],$sid);
			if ($pres!=1) {
				$mode = 'error';
				$smarty->assign("error_text", "Search term doesn't look like a valid student ID");
			} else {
				$url = "$apibaseurl/IsPersonMember?strCriteria=".$sid[0]."&GroupingId=6613";
Thomas Lake's avatar
Thomas Lake committed
				$apiReq = curl_init();
				curl_setopt($apiReq, CURLOPT_URL, $url);
				curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE);

				$apiResult = curl_exec($apiReq);
				if ($apiResult === FALSE) {
					$mode = 'error';
					$smarty->assign("error_text", "An error occurred communicating with the SUSU API.");
Thomas Lake's avatar
Thomas Lake committed
				}else {
					// Ostensibly we now have a valid search result from the SU - go to work
					libxml_use_internal_errors(true);
					$xml=simplexml_load_string($apiResult);
					if (!$xml||isset($xml->head->title)) {
						$mode='error';
						$smarty->assign("error_text", "An error occurred communicating with the SUSU API");
					} else {
						$ismember = $xml[0];
						if ($ismember=="true") {
							//Yay, we have a student who has paid and needs to be signed up.
							//Check they don't have a signup slip already
							$query = "SELECT transactionid, signupid FROM transactions WHERE cardNumber = ?;";
							$qres = $sucsDB->Execute($query, $sid);
							
							if ($qres->RecordCount()==0) {
								// No transaction, but might have unused signup slip. If so, retrieve values.
								$query = "SELECT id, username, password FROM signup WHERE sid=?;";
								$qres = $sucsDB->Execute($query, array($sid[0]));
								if ($qres && $qres->RecordCount() > 0) {
									if ($qres->RecordCount() > 1) {
										$mode='error';
										$smarty->assign("error_text", "Student has multiple signup slips in the DB. Bork! Bork! Bork!");
									} else if (!empty($qres->fields['username'])) {
										$mode='error';
										$smarty->assign("error_text", "Student hasn't tried to use the SU signup component (No transaction in DB), but has a previously used Signup Slip with username ".$qres->fields['username'].".<br />Is this a renewal? If not, ask an admin to generate a new signup slip for this student");
										//TODO: Add option to generate new signup slip?
									} else {
										$id = $qres->fields['id'];
										$pass = $qres->fields['password'];
									}
Thomas Lake's avatar
Thomas Lake committed
								} else {
									$pass = make_password();
									$query = "INSERT INTO signup (password,sid,issuedby) VALUES ( ?, ?, ?) RETURNING id";
									$attribs[]=$sid[0];
									$attribs[]='99999'; //SUCS Magic internal use UID

									$id = $sucsDB->Execute($query,$attribs);
									$id = $id->fields['id'];
									if (!$id) {
										$mode="error";
										$smarty->assign("error_text", "An error occurred generating a signup ID. Report the following message to the admins:<br /><pre>".$sucsDB->ErrorMsg()."</pre>");
									} else {
										$smarty->assign('slipid', $id);
										$smarty->assign('slippass', $pass);
										$smarty->assign('sid', $sid[0]);
									}
Thomas Lake's avatar
Thomas Lake committed
								}
							} else {
								//Retrieve existing slip
								$id = $qres->fields['signupid'];
								$tid = $qres->fields['transactionid'];
								if (empty($id)) {
									$pass = make_password();
									$query = "INSERT INTO signup (password,sid,issuedby) VALUES ( ?, ?, ?) RETURNING id";
									$attribs[]=$sid[0];
									$attribs[]='99999'; //SUCS Magic internal use UID
									$qres = $sucsDB->Execute($query,$attribs);
									if (!$qres) {
										$mode="error";
										$smarty->assign("error_text", "An error occurred generating a signup ID. Report the following message to the admins:<br /><pre>".$sucsDB->ErrorMsg()."</pre>");
									} else {
										$id = $qres->fields['id'];
										$query = "UPDATE transactions SET signupid=? WHERE transactionid=?;";
										$qres = $sucsDB->Execute($query, array($id, $tid));
										$smarty->assign('slipid', $id);
										$smarty->assign('slippass', $pass);
										$smarty->assign('sid', $sid[0]);
									}
								}else {
									$query = "SELECT username, password FROM signup WHERE id=?;";
									$qres = $sucsDB->Execute($query, array($id));
									if (!$qres) {
										$mode="error";
										$smarty->assign("error_text", "The user appears to have generated a signup ID using the SU Signup system (Slip ID: ".$id."), but the password for that slip can't be retrieved.<br />Request assistance.");
									} else if ($qres->fields['username'] !== NULL) {
										$mode="error";
Thomas Lake's avatar
Thomas Lake committed
										$smarty->assign("error_text", "This user appears to have completed signup, with username <strong>".$qres->fields['username']."</strong><br />Check that this user exists, and offer to reset their password if necessary.");
									}
									$pass = $qres->fields['password'];
Thomas Lake's avatar
Thomas Lake committed
									$smarty->assign('slipid', $id);
									$smarty->assign('slippass', $pass);
									$smarty->assign('sid', $sid[0]);
								}
							if(!$mode=='error') {
								//Right, this should be the point where we hand off to signup
Thomas Lake's avatar
Thomas Lake committed
								$smarty->assign('slipid', $id);
								$smarty->assign('slippass', $pass);
								$smarty->assign('sid', $sid[0]);
							}

						}else{
							$mode='error';
							$smarty->assign("error_text", "Student does not appear to have paid. Extract fees");
	} else if ($mode=="renew") {
		if (empty($_REQUEST['member'])){
			$mode='error';
			$smarty->assign('error_text',"Can't renew a member without knowing their username!");
		} else if (!isset($_REQUEST['renewconf'])) {
			//Should be trying to renew $_REQUEST['member']
			$username=urldecode($_REQUEST['member']);
			$q = "SELECT username, typename, sid, paid, email FROM members, member_type WHERE username=?";
			$res = $sucsDB->Execute($q,array($username));
			if (!$res) {
				$mode='error';
				$smarty->assign('error_text', "A database error occurred while trying to retrieve member details");
			} else if ($res->fields['paid'] == paidUntil(time())) {
					$mode='error';
					$smarty->assign('error_text', 'User appears to have been renewed already?');
			} else {
				$smarty->assign('renew_user', $username);
				$smarty->assign('renew_paid', $res->fields['paid']);
				$smarty->assign('renew_type', $res->fields['typename']);
				$url = "$apibaseurl/IsPersonMember?strCriteria=".$res->fields['sid']."&GroupingId=6613";
                                $apiReq = curl_init();
                                curl_setopt($apiReq, CURLOPT_URL, $url);
                                curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE);

                                $apiResult = curl_exec($apiReq);
				libxml_use_internal_errors(true);
				$xml=simplexml_load_string($apiResult);
				if (!$xml || isset($xml->head->title)) {
					$smarty->assign("error_text", "An error occurred communicating with the SUSU API.");
					$ismember = $xml[0];

					$user = posix_getpwnam($session->username);

					if ($ismember!="true") {
						$smarty->assign('error_text', 'Member does not appear to have paid via the SU system. Use the old renewals system if they have paid using some other method');;
					} else {
						if (renew_member($username, $user['uid'], $user['name'])) {
							message_flash("Successfully renewed");
							$mode='menu';
						} else {
							$mode='error';
							$smarty->assign('error_text', 'An error occurred renewing account '.$username);
						}

					}

				}
			}
		}
			
	} else if ($mode == 'renewals') {
		//Get list of members according to the SU
		$url = "$apibaseurl/GetMemberListData?GroupingId=6613";
		$apiReq = curl_init();
		curl_setopt($apiReq, CURLOPT_URL, $url);
		curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE);

		$apiResult = curl_exec($apiReq);
		$sumembers = su_response_decode($apiResult);
		if (!$sumembers) {
			$mode ='error';
			$smarty->assign("error_text", "An error occurred communicating with the SUSU API.");
		} else {
			$matches = array();
			$others=0;
			$paidup=0;
			foreach ($sumembers as $sumem) {
				$sucsmem = get_sucs_record($sumem['uni_card_number']);
				if ($sucsmem && $sucsmem['paid'] != paidUntil(time()) && $sucsmem['type']==1) {
					$matches[]=array($sumem['firstName']." ".$sumem['lastName'], $sucsmem['realname'], $sumem['uni_card_number'], $sucsmem['username'], $sucsmem['paid']);
				} else if ($sucsmem && $sucsmem['paid'] == paidUntil(time())) {
					$others++;
					$paidup++;
				} else {
					$others++;
				}
			$smarty->assign("matches", $matches);
			$smarty->assign("others", $others);
			$smarty->assign("paidup", $paidup);
			$smarty->assign("pending", $others - $paidup);
		}
	} else if ($mode == 'renewals2') {
		$failures = array();
		$successes = array();

		if (empty($_REQUEST['renew'])) {
			$mode='error';
			$smarty->assign("error_text", "Can't renew an empty list!");
		} else {
			foreach($_REQUEST['renew'] as $user) {
				$admin_user=posix_getpwnam($session->username);
				if (renew_member($user, $admin_user['uid'], $admin_user['name'])) {
					$successes[]=$user;
				} else {
					$failures[]=$user;
				}
			}
			$smarty->assign("attempt", count($_REQUEST['renew']));
			$smarty->assign("failures", count($failures));
			$smarty->assign("failusers", $failures);
			$smarty->assign("successes", count($successes));
		}
Thomas Lake's avatar
Thomas Lake committed
	} else if ($mode == 'list') {
		//Get list of members according to the SU
		$url="$apibaseurl/GetMemberListData?GroupingId=6613";
Thomas Lake's avatar
Thomas Lake committed
		$apiReq = curl_init();
		curl_setopt($apiReq, CURLOPT_URL, $url);
		curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE);

		$apiResult = curl_exec($apiReq);
		$sumembers = su_response_decode($apiResult);
		if (!$sumembers) {
			$mode='error';
			$smarty->assign("error_text", "An error occurred communicating with the SUSU API.");
		} else {
			$matches = array();
			foreach ($sumembers as $sumem) {
				$sucsmem = get_sucs_record($sumem['uni_card_number']);
				if ($sucsmem) {
					$matches[]=array($sumem['firstName']." ".$sumem['lastName'], $sucsmem['realname'], $sumem['uni_card_number'], $sucsmem['username'], $sucsmem['paid']);
				} else {
					$matches[]=array($sumem['firstName']." ".$sumem['lastName'], "N/A", $sumem['uni_card_number'], "N/A", "Not signed up");
				}
			function sortbypaid($a, $b) {
				//Lets us array sort by final column ('Paid')
				return ($a[4] < $b[4]) ? -1  : 1;
			}
			usort($matches, 'sortbypaid');
			$smarty->assign("matches", $matches);
Thomas Lake's avatar
Thomas Lake committed
$smarty->assign('renewables', get_renewable_members());
Thomas Lake's avatar
Thomas Lake committed
$smarty->assign('title', 'SU Signup Admin');
$smarty->assign('mode', $mode);
$body = $smarty->fetch("susignup-admin.tpl");
$smarty->assign('body', $body);
$smarty->assign("extra_styles", array("$baseurl/css/susignup-admin.css"));

function su_response_decode($text) {
	global $smarty;
	libxml_use_internal_errors(true);
	$xml=simplexml_load_string($text);
	if (!$xml || isset($xml->head->title)) {
		return false;
	} else {
		return json_decode($xml[0],TRUE);

function get_sucs_record($sid) {
	global $sucsDB;

	$query = "SELECT * FROM members WHERE sid=?;";
	$res  = $sucsDB->Execute($query, array($sid));
	if (!$res || $res->RecordCount()<>1) {
		return FALSE;
	}
        return $res->FetchRow();	
}

function get_renewable_members() {
	global $sucsDB;
	$q = "SELECT username, username||' ('||realname||')' AS display FROM members, member_type WHERE paid != ? AND type=1 AND type=member_type.id ORDER BY paid;";
	$r = $sucsDB->Execute($q, array(paidUntil(time())));
	if(!$r) {
		return FALSE;
	}
	$retvals = array();
	while ($rec=$r->FetchRow()) {
		$retvals[$rec['username']]=$rec['display'];
	}
	return $retvals;
}

function renew_member($renew_name, $admin_uid, $admin_name) {
	global $sucsDB;

	$q="UPDATE members SET paid=?, lastupdate=DEFAULT, lastedit=? WHERE username=?;";
	$r=$sucsDB->Execute($q, array(paidUntil(time()), $admin_uid, $renew_name));
	if (!$r) {
		print $sucsDB->ErrorMsg();
		return FALSE;
	} else {	
		$q="SELECT email, typename FROM members, member_type WHERE username=?  AND type=member_type.id;";
		$r=$sucsDB->Execute($q, array($renew_name));

		$message  = "Account Renewal notification\n\n";
		$message .= "Account   : ".$renew_name."\n";
		$message .= "User Type : ".$r->fields['typename']."\n";
		$message .= "Renewed by: ".$admin_name."\n\n";
		$message .= "**** Payment was made via the SU payments system ****\n";
		$message .= "Regards\n  The SU Renewals script";
		mail("treasurer@sucs.org","Account Renewal",$message);
		
		$message = "Your Swansea University Computer Society (SUCS) membership has been renewed\n\n";
		$message .= "Username: ".$renew_name."\n";
		$message .= "If you do not know or have forgotten your password, please email admin@sucs.org to arrange for it to be changed.\n\n";
		$message .= "Regards\n  The SUCS admin";
		$header = "From: admin@sucs.org\r\n";
		$header .= "Reply-To: admin@sucs.org";
		// Personal account
		mail($r->fields['email'],"SUCS account renewal",$message,$header);
		// sucs account
		mail($renew_name."@sucs.org","SUCS account renewal",$message,$header);
		return TRUE;
	}

}