science-ation/api.php
james 46b39f81e0 Add copyoriginal, copyparent, and notes(currently unused) to conferences table
Add code in create conference and copy conference to set copyoriginal and copyparent
Add missing json_decode to API (we expect ALL arrays being POSTED to be json encoded)
2010-11-25 20:45:44 +00:00

802 lines
22 KiB
PHP

<?
/*
This file is part of the 'Science Fair In A Box' project
SFIAB Website: http://www.sfiab.ca
Copyright (C) 2010 Youth Science Ontario <info@youthscienceontario.ca>
Copyright (C) 2010 James Grant <james@lightbox.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation, version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
?>
<?
include "common.inc.php";
require_once("account.inc.php");
require_once("user.inc.php");
require_once("schedule.inc.php");
if($_SERVER['HTTPS']!="on") {
$ret['status']="error";
$ret['error']="SSL is required for API access, please access the API over https";
echo json_encode($ret);
exit;
}
$request=explode("/",$_GET['request']);
$ret=array();
switch($request[0]) {
case 'config':
switch($request[1]){
/* APIDOC: config/variables
description(retreives the entire configuration variables, minus ones that cant be included (like passwords)
return(config array)
*/
case 'variables':
$exclude=array("judge_registration_singlepassword","volunteer_registration_singlepassword","participant_registration_singlepassword","fairmanageremail");
$configapi=$config;
foreach($exclude AS $e) {
unset($configapi[$e]);
}
$ret['status']="ok";
$ret['config']=$configapi;
break;
/* APIDOC: config/divisions
description(retreives the list of divisions)
return(divisions array)
*/
case 'divisions':
$divs=projectdivisions_load();
$ret['status']="ok";
$ret['divisions']=$divs;
break;
/* APIDOC: config/subdivisions
description(retreives the list of subdivisions)
return(subdivisions array)
*/
case 'subdivisions':
$subdivs=projectsubdivisions_load();
$ret['status']="ok";
$ret['subdivisions']=$subdivs;
break;
/* APIDOC: config/categories
description(retreives the list of age categories)
return(categories array)
*/
case 'categories':
$cats=projectcategories_load();
$ret['status']="ok";
$ret['categories']=$cats;
break;
}
break;
case 'locations':
switch($request[1]){
case 'list':
/* APIDOC: locations/list
description(lists locations at the current conference)
return(locations array)
*/
$locationData = getLocationList($_SESSION['conferences_id']);
if(is_array($locationData)){
$ret['status'] = 'ok';
$ret['locations'] = $locationData;
}else{
$ret['status'] = 'error';
$ret['error'] = $locationData;
}
break;
default:
$ret['status'] = 'error';
$ret['error']="Invalid API command ({$request[1]})";
}
break;
case "schedule":
$u = user_load($_SESSION['users_id']);
$school_id = null;
if($u['schools_id']) {
$school_id=$u['schools_id'];
}else{
$ret['status'] = 'error';
$ret['error']="Not connected to a school";
break;
}
switch($request[1]){
case 'list':
/* APIDOC: events/list
description(gets a list of all events at the current conference, and team information if applicable)
return(events array)
*/
$eventData = getEventList($_SESSION['conferences_id'], $school_id);
if(is_array($eventData)){
$ret['status'] = 'ok';
$ret['events'] = $eventData;
}else{
$ret['status'] = 'error';
$ret['error'] = $eventData;
}
break;
case 'register':
/* APIDOC: schedule/register
description(register a team for a scheduled event)
post(team_id integer, schedule_id integer)
return(results array)
*/
if(!array_key_exists('team_id', $_POST)){
$ret['status'] = "error";
$ret['error'] = 'team_id (integer) is required';
}else if(!array_key_exists('schedule_id', $_POST)){
$ret['status'] = "error";
$ret['error'] = 'schedule_id (integer) is required';
}else{
$ret['status'] = 'ok';
$ret['registration'] = registerTeamInEvent($_SESSION['conferences_id'], $_POST['schedule_id'], $_POST['team_id']);
}
break;
case 'unregister':
/* APIDOC: schedule/register
description(unregister a team for a scheduled event)
post(team_id integer, schedule_id integer)
return(results array)
*/
if(!array_key_exists('team_id', $_POST)){
$ret['status'] = "error";
$ret['error'] = 'team_id (integer) is required';
}else if(!array_key_exists('schedule_id', $_POST)){
$ret['status'] = "error";
$ret['error'] = 'schedule_id (integer) is required';
}else{
$ret['status'] = 'ok';
$ret['registration'] = unregisterTeamInEvent($_SESSION['conferences_id'], $_POST['schedule_id'], $_POST['team_id']);
}
break;
default:
$ret['status'] = 'error';
$ret['error']="Invalid API command ({$request[1]})";
}
break;
case "conferences":
/* APIDOC: conferences/switch
description(switches the active conference)
post(conferences_id integer)
return(conferences_id integer)
*/
if($request[1]=="switch") {
if($_POST['conferences_id']) {
//this makes sure its valid and sets teh session
switchConference($_POST['conferences_id']);
//get rid of their current roles, and load their record for the new conference
if(is_array($_SESSION['roles'])) {
$_SESSION['roles']=array();
user_conference_load($_SESSION['accounts_id'],$_SESSION['conferences_id']);
}
$ret['status']="ok";
$ret['conferences_id']=$_SESSION['conferences_id'];
} else {
$ret['status']="error";
$ret['error']='conferences_id (integer) is required';
}
}
/* APIDOC: conferences
description(lists all conferences)
return(conferences array)
*/
else {
$ret['status']="ok";
$ret['conferences']=array();
$response=array();
$q=mysql_query("SELECT id,name,type,status FROM conferences ORDER BY id");
while($r=mysql_fetch_assoc($q)) {
$response[]=$r;
}
$ret['conferences']=$response;
}
break;
case "dates":
/* APIDOC: dates
description(list dates for active conference)
return(dates array)
*/
/* APIDOC: dates/<conferences_id integer>
description(list dates for specified conference)
return(dates array)
*/
if($request[1]) {
$cid=intval($request[1]);
}
else
$cid=$_SESSION['conferences_id'];
$ret['status']="ok";
$ret['dates']=array();
$q=mysql_query("SELECT date,name,description FROM dates WHERE conferences_id='$cid' ORDER BY date");
$dates=array();
while($r=mysql_fetch_assoc($q)) {
$dates[]=$r;
}
$ret['conferences_id']=$cid;
$ret['dates']=$dates;
break;
case "account":
switch($request[1]) {
/* APIDOC: account/create
description(creates an account)
post(username varchar(64), password varchar(64), email varchar(64) optional)
return(account array)
*/
case 'create':
$user = trim($_POST['username']);
$pass = trim($_POST['password']);
$email = trim($_POST['email']);
if($user && $pass) {
$a=account_create($user,$pass);
if(is_array($a)) {
if($email)
account_set_email($a['id'],$email);
$account=account_load($a['id']);
$ret['status']="ok";
$ret['account']=$account;
}
else {
$ret['status']="error";
switch($a) {
case -1: $ret['error']="invalid username"; break;
case -2: $ret['error']="username already exists"; break;
case -3: $ret['error']="invalid password"; break;
default: $ret['error']="unknown account creation error"; break;
}
}
} else {
$ret['status']="error";
$ret['error']="username (varchar 64) and password (varchar 64) are required ";
}
break;
/* APIDOC: account/view
description(view account information for currently logged in account)
return(account array)
*/
case 'view':
if(isset($_SESSION['accounts_id'])) {
$a = account_load($_SESSION['accounts_id']);
$ret['status']='ok';
$ret['account']=$a;
}
else {
$ret['status']="error";
$ret['error']="You are not logged in";
}
break;
/* APIDOC: account/edit
notimplemented
description(edits an account)
post(account array)
return(account array)
*/
case 'edit':
if(isset($_SESSION['accounts_id'])) {
// grab the relevant keys from $_POST
$params = array();
foreach($_POST as $key => $value){
if(in_array($key, array('username', 'password', 'email', 'link_username_to_email'))){
$params[$key] = $_POST[$key];
}
}
if(count($params) > 0){
$result = account_update_info($params);
if($result == 'ok'){
$a = account_load($_SESSION['accounts_id']);
$ret['status'] = 'ok';
$ret['account'] = $a;
}else{
$ret['status'] = "error";
$ret['error'] = $result;
}
}else{
$ret['status'] = "error";
$ret['error'] = "No field values passed";
}
}else{
$ret['status']="error";
$ret['error']="You are not logged in";
}
break;
default:
$ret['status']="error";
$ret['error']="invalid account command";
}
break;
case "auth":
/* APIDOC: auth/login
description(login to an account)
post(username varchar(64), password varchar(64), conferences_id integer optional)
return(account array, roles array, conferences_id integer)
*/
if($request[1]=="login") {
$user = $_POST['username'];
$pass = $_POST['password'];
$cid = $_POST['conferences_id'];
$accounts_id = try_login($user, $pass);
if($accounts_id == false) {
$ret['status']="error";
$ret['error']="Invalid Username/Password";
}
else {
$a = account_load($accounts_id);
$_SESSION['username']=$a['username'];
$_SESSION['email']=$a['email'];
$_SESSION['accounts_id']=$accounts_id;
$_SESSION['superuser'] = ($a['superuser'] == 'yes') ? 'yes' : 'no';
$_SESSION['roles']=array();
if(!$cid) $cid=$_SESSION['conferences_id'];
$status=user_conference_load($accounts_id,$cid);
$ret['conferences_id']=$cid;
$ret['status']="ok";
$ret['account']=$a;
//$ret['user']=user_load($_SESSION['users_id']);
$ret['roles']=$_SESSION['roles'];
}
}
/* APIDOC: auth/logout
description(logs out of an account)
return(account array)
*/
else if($request[1]=="logout") {
unset($_SESSION['username']);
unset($_SESSION['email']);
unset($_SESSION['accounts_id']);
unset($_SESSION['superuser']);
unset($_SESSION['roles']);
unset($_SESSION['users_id']);
unset($_SESSION['name']);
$ret['status']="ok";
}
else {
$ret['status']="error";
$ret['error']="invalid auth command";
}
break;
case "testauth":
if($request[1]) {
$ok=api_user_auth_required($request[1]);
}
else {
$ok=api_user_auth_required();
}
if($ok['status']=="ok") {
$ret['status']='ok';
}
else {
$ret['status']="error";
$ret['error']=$ok['error'];
}
break;
case "scienceolympics":
$chk=api_user_auth_required('teacher');
if($chk['status']!="ok") {
$ret['status']="error";
$ret['error']=$chk['error'];
break;
}
$u=user_load($_SESSION['users_id']);
if(!$u['schools_id']) {
$ret['status']="error";
$ret['error']='Your teacher account is not attached to any school';
break;
}
$school_id=$u['schools_id'];
require_once("so_teams.inc.php");
switch($request[1]) {
case "teams":
switch($request[2]) {
/* APIDOC: scienceolympics/teams/list
description(lists the schools science olympics teams)
return(teams array)
*/
case "list":
$q=mysql_query("SELECT id,name FROM so_teams WHERE schools_id='{$u['schools_id']}' AND conferences_id='{$conference['id']}'");
$ret['status']='ok';
$teams=array();
while($r=mysql_fetch_assoc($q)) {
$teams[]=$r;
}
$ret['teams']=$teams;
break;
/* APIDOC: scienceolympics/teams/add
description(add a science olympics team to the logged in teacher's school)
post(teamname varchar(64))
return(team array);
*/
case "add":
if($_POST['teamname']) {
if($team=so_team_add($school_id,$conference['id'],$_POST['teamname'])) {
$ret['team']=$team;
$ret['status']="ok";
}
else {
$ret['status']='error';
$ret['error']='could not add team';
}
} else {
$ret['status']='error';
$ret['error']='teamname (varchar 64) is required';
}
break;
/* APIDOC: scienceolympics/teams/edit
description(edit a science olympics team)
post(id integer, teamname varchar(64))
return(team array);
*/
case "edit":
if($_POST['id'] && $_POST['teamname']) {
if($team=so_team_edit($school_id,$_POST['id'],$_POST['teamname'])) {
$ret['status']="ok";
$ret['team']=$team;
}
else {
$ret['status']='error';
$ret['error']='could not edit team';
}
}
else {
$ret['status']='error';
$ret['error']='id (integer), teamname (varchar 64) are required';
}
break;
/* APIDOC: scienceolympics/teams/delete
description(delete a science olympics team)
post(id integer)
*/
case "delete";
if($_POST['id']) {
if(so_team_delete($school_id,$_POST['id'])) {
$ret['status']="ok";
}
else {
$ret['status']='error';
$ret['error']='could not delete team';
}
} else {
$ret['status']='error';
$ret['error']='id (integer) is required';
}
break;
default:
$ret['status']="error";
$ret['error']="invalid scienceolympics/teams command ({$request[2]})";
break;
}
break;
default:
$ret['status']="error";
$ret['error']="invalid scienceolympics command ({$request[1]})";
break;
}
break;
case 'user':
$chk=api_user_auth_required();
if($chk['status']!="ok") {
$ret['status']="error";
$ret['error']=$chk['error'];
break;
}
switch($request[1]) {
/* APIDOC: user/view
description(view user information for current conference)
return(user array)
*/
case "view":
if($u=user_load($_SESSION['users_id'])) {
//we dont need to send the 'orig' part of it
unset($u['orig']);
$ret['status']="ok";
$ret['user']=$u;
}
else {
$ret['status']="error";
$ret['error']="Error loading user";
}
break;
/* APIDOC: user/edit
description(edit user information for current conference)
post(user array)
return(user array)
*/
case "edit":
if($origu=user_load($_SESSION['users_id'])) {
$u=json_decode($_POST['user'],true);
if(!is_array($u)) {
$ret['status']="error";
$ret['error']="user (array) is required.";
break;
}
if($origu['id']!=$u['id']) {
$ret['status']="error";
$ret['error']="User ID mismatch";
break;
}
$u['orig']=$origu['orig'];
$result = user_save($u);
if($result == 'ok') {
$ret['status']="ok";
$ret['user']=$u;
} else {
$ret['status']="error";
$ret['error']=$result;
}
}
else {
$ret['status']="error";
$ret['error']="Error loading user in order to edit";
}
break;
/* APIDOC: user/connect_to_school
description(connects the current user to the specified school using the school's access code)
post(schools_id integer, accesscode varchar(16))
return(school array)
*/
case 'connect_to_school':
if($u = user_load($_SESSION['users_id'])) {
$schoolId = mysql_real_escape_string($_POST['schools_id']);
$accesscode = mysql_real_escape_string($_POST['accesscode']);
if(user_set_school($u, $schoolId, $accesscode)){
$ret['status'] = "ok";
$ret['school'] = mysql_fetch_assoc(mysql_query("SELECT school, phone, fax, address, city, province_code AS province, postalcode FROM schools WHERE id = $schoolId"));
}else{
$ret['status'] = "error";
$ret['error'] = "Error matching schools_id and accesscode";
}
}else{
$ret['status'] = "error";
$ret['error'] = "Error loading user";
}
break;
/* APIDOC: user/invite
description(invites a user to play a particular role in the conference, creating an account for them, and giving them the specifed role)
post(username varchar(64), password varchar(64), email varchar(64), roles_id integer)
return(user array)
*/
case 'invite':
// let's make sure we have all of the data posted
$ok = true;
foreach(array('username' => 'varchar(64)', 'password' => 'varchar(64)', 'email' => 'varchar(64)', 'roles_id' => 'integer') as $field => $format){
if(!array_key_exists($field, $_POST)){
$ret['status'] == 'error';
$ret['error'] = "$field ($format) is required";
$ok = false;
break;
}
}
if($ok){
$newUser = user_invite($_POST['username'], $_POST['password'], $_POST['email'], $_POST['roles_id']);
if(is_array($newUser)){
$ret['status'] = 'ok';
$ret['user'] = $newUser;
}else{
$ret['status'] = 'error';
$ret['error'] = $newUser;
}
}
break;
}
break;
case "role":
//these ones dont need to be authenticated
switch($request[1]) {
/* APIDOC: role/list
description(list roles and their corresponding registration types)
return(roles array)
*/
case "list":
$q=mysql_query("SELECT * FROM roles ORDER BY name");
$reqroles=array();
while($r=mysql_fetch_assoc($q)) {
if($config[$r['type']."_registration_type"]) {
$r['registration']=$config[$r['type']."_registration_type"];
}
else
$r['registration']="not available";
$reqroles[]=$r;
}
$ret['status']="ok";
$ret['roles']=$reqroles;
break;
/* APIDOC: role/add
post(role_id integer, password varchar(64) optional)
description(add a role for the user to the current conference. Depending on the registraiton type, an optional password (singlepassword, schoolpassword, etc) can be specified)
return(role array)
*/
case "add":
$chk=api_user_auth_required();
if($chk['status']!="ok") {
$ret['status']="error";
$ret['error']=$chk['error'];
break;
}
$role_id=intval($_POST['role_id']);
$password=trim($_POST['password']);
if($password)
$addstatus=account_add_role($_SESSION['accounts_id'],$role_id,$conference['id'],$password);
else
$addstatus=account_add_role($_SESSION['accounts_id'],$role_id,$conference['id']);
switch($addstatus) {
case "ok":
$ret['status']="ok";
updateSessionRoles();
break;
case "invalidrole": $ret['status']="error"; $ret['error']="Invalid role"; break;
case "invalidaccount": $ret['status']="error"; $ret['error']="Invalid account"; break;
case "invalidconference": $ret['status']="error"; $ret['error']="Invalid conference"; break;
case "invalidpassword": $ret['status']="error"; $ret['error']="Invalid password for role"; break;
default: $ret['status']="error"; $ret['error']="unknown role add error";
}
break;
/* APIDOC: role/remove
post(role_id integer)
description(remove a role from the user for the current conference)
return(role array)
*/
case "remove":
$chk=api_user_auth_required();
if($chk['status']!="ok") {
$ret['status']="error";
$ret['error']=$chk['error'];
break;
}
$role_id=intval($_POST['role_id']);
$removestatus=account_remove_role($_SESSION['accounts_id'],$role_id,$conference['id']);
switch($removestatus) {
case "ok":
$ret['status']="ok";
updateSessionRoles();
break;
case "invalidrole": $ret['status']="error"; $ret['error']="Invalid role"; break;
case "invalidaccount": $ret['status']="error"; $ret['error']="Invalid account"; break;
case "invalidconference": $ret['status']="error"; $ret['error']="Invalid conference"; break;
default: $ret['status']="error"; $ret['error']="unknown role remove error";
}
break;
default:
$ret['status']="error";
$ret['error']="invalid role command ({$request[1]})";
}
break;
case 'registration':
switch($request[1]){
/* APIDOC: registration/fields
description(retreives the list of fields to be asked for in order to complete registration for a specific set of roles. If an array of roles is passed in it retrieves the fields for those roles, if no roles are passed in, then it uses the roles from the currently logged in user)
post(roles[] array) optional
return(fields array)
*/
case 'fields':
$reqroles=json_decode($_POST['roles'],true);
if(is_array($reqroles)) {
for($x=0;$x<count($reqroles);$x++) {
if(is_numeric($reqroles[$x]))
$reqroles[$x]=$roles_by_id[$reqroles[$x]]['type'];
if(!array_key_exists($reqroles[$x],$roles))
unset($reqroles[$x]);
}
$ret['status']="ok";
$ret['roles']=$reqroles;
$ret['fields']=user_get_fields($reqroles);
} else {
//load the currently logged in user
if($_SESSION['users_id']) {
$u = user_load($_SESSION['users_id']);
if(is_array($u['roles']) && count($u['roles']>0)) {
$ret['status']="ok";
$ret['roles']=array_keys($u['roles']);
$ret['fields']=user_get_fields(array_keys($u['roles']));
} else {
$ret['status']="error";
$ret['error']="Currently logged in user has no roles";
}
} else {
$ret['status']="error";
$ret['error']="No roles submitted and not logged in";
}
}
break;
/* APIDOC: registration/dictionary
description(retrieves a list of all user fields with their label and category information)
return(dictionary array)
*/
case 'dictionary':
$ret['status'] = 'ok';
if(is_array($conference) && array_key_exists('id', $conference)){
$ret['dictionary'] = user_get_field_info();
}else{
$ret['dictionary'] = user_get_field_info(true);
}
break;
default:
$ret['status']="error";
$ret['error']="invalid registration API command ({$request[1]})";
}
break;
case 'school':
switch($request[1]){
/* APIDOC: school/list
description(list schools)
return(schools array)
*/
case 'list':
$ret['schools'] = get_schools($conference['id']);
$ret['status'] = 'ok';
break;
}
default:
$ret['status']="error";
$ret['error']="invalid API command ({$request[0]})";
}
echo json_encode($ret);
?>