-
Notifications
You must be signed in to change notification settings - Fork 1
API - Basic API calls #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: gsoc2014
Are you sure you want to change the base?
Changes from all commits
9c0bc1b
d1e0c92
7c2689d
327d861
5142bb4
d4a792d
cf742ac
d512f8c
14e13a9
3548a5c
9b9846e
a16fb46
680c76c
cd16789
7bcb69d
8167505
0a298a3
300a46f
c4d88eb
705c392
f3b65d4
3bf92f7
0685d5e
44da3b5
6260d29
fbebd80
a5170ca
aef08df
0a1cccc
5fe2117
3a1abd8
bd9eea9
ac68736
55b7dac
7968cf9
8c505af
791e17b
1ef7899
7b1e6e1
b6601c9
9ab9556
65b0d82
9c77f84
2956a59
06684c8
df9c0ad
604f1a2
6159144
a41c372
102e527
697b7b0
50a5947
069bd09
ab93eb9
11686cb
dec7a49
b6c7dbe
74481a6
03f080c
7f51065
20f5d5d
6944421
942797b
b2d530e
68085d4
9ff0e2a
78dc07f
0df3280
c86c89f
8009936
dcdf6be
00e1bef
2c36ac7
39481db
9965262
84c15d9
3b746f0
303d805
2ecaa98
cd866d1
7d5e254
cf51fb5
2397990
4a7ee20
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
RewriteEngine On | ||
RewriteCond %{ENV:REDIRECT_STATUS} ^$ | ||
#RewriteCond %{REQUEST_FILENAME} !-f | ||
#RewriteCond %{REQUEST_FILENAME} !-d | ||
RewriteRule ^(.*)$ index.php/$1 [L] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<?php | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not see sql_clause() function anywhere. It is VERY important function when you pass query parameters but not sure if all of them are present. Where is explanation for that? |
||
class BoilerplateClass { | ||
function get() { | ||
// Make a call to the API function like this | ||
// Specify a request type, access level and query to be executed. | ||
|
||
// You may want to add certain WHERE parameters to your query (which may or may not be present) | ||
// An associative array is an argument - the keys are the names of the db columns as they appear in the query | ||
// - the values are the variables that may or may not exist in the call | ||
// Uncomment the following call to generate the clause according to the variables that are present | ||
|
||
// create_SQL_clause(array( | ||
// "title" => $_GET["title"], | ||
// "language" => $_GET["language"] | ||
// )); | ||
|
||
// Uncomment the following for a sample call (make sure you set the variables first) | ||
|
||
/* api_backbone(array( | ||
* "request_type" => HTTP_GET, | ||
* "access_level" => INSTRUCTOR_ACCESS_LEVEL, | ||
* "query" => $query, | ||
* "query_array" => $array | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still believe that you need to pass "referece_id". If the value is passed then it is compare against member_id which is associated with the token which is passed in request |
||
* )); | ||
*/ | ||
print "You are at the boilerplate home!"; | ||
} | ||
|
||
function post() { | ||
// Make a call to the API function like this | ||
// Specify a request type, access level and query to be executed. | ||
// We create an object and return the ID with this call. | ||
// To get the ID of the newly created object, set returned_id_name to true | ||
|
||
// Uncomment the following for a sample call (make sure you set the variables first) | ||
/* api_backbone(array( | ||
* "request_type" => HTTP_POST, | ||
* "access_level" => INSTRUCTOR_ACCESS_LEVEL, | ||
* "query" => $query, | ||
* "query_array" => $array, | ||
* "returned_id_name" => true | ||
* )); | ||
*/ | ||
print "You are at the boilerplate home! Creating an object."; | ||
} | ||
} | ||
|
||
class BoilerplateClassWithUrlParameter{ | ||
function get($boilerplate_id) { | ||
// Make a call to the API function like this | ||
// Since we want a single object, we specify one_row to be true | ||
/* api_backbone(array( | ||
* "request_type" => HTTP_GET, | ||
* "access_level" => ADMIN_ACCESS_LEVEL, | ||
* "query" => $query, | ||
* "query_array" => $array, | ||
* "one_row" => true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is this option : "one_row" what is it for ? |
||
* )); | ||
*/ | ||
print "Checking boilerplace with id - ".$boilerplate_id; | ||
} | ||
|
||
function put($boilerplate_id) { | ||
// Make a call to the API function like this | ||
// We update an object here, so we need to check if it exists first, which is accomplished by query_id_existence | ||
// No need to specify one_row because we perform an update operation here | ||
// Uncomment the following for a sample call (make sure you set the variables first) | ||
/* api_backbone(array( | ||
* "request_type" => HTTP_PUT, | ||
* "access_level" => ADMIN_ACCESS_LEVEL, | ||
* "query_id_existence" => $query_id_existence, | ||
* "query_id_existence_array" => $query_id_existence_array, | ||
* "query" => $query, | ||
* "query_array" => $array | ||
* )); | ||
*/ | ||
print "Updating boilerplace object with id - ".$boilerplate_id; | ||
} | ||
|
||
function delete($boilerplate_id) { | ||
// Make a call to the API function like this | ||
// We delete an object here, so we need to check if it exists first, which is accomplished by query_id_existence | ||
// Uncomment the following for a sample call (make sure you set the variables first) | ||
/* api_backbone(array( | ||
* "request_type" => HTTP_DELETE, | ||
* "access_level" => ADMIN_ACCESS_LEVEL, | ||
* "query_id_existence" => $query_id_existence, | ||
* "query_id_existence_array" => $query_id_existence_array, | ||
* "query" => $query, | ||
* "query_array" => $array | ||
* )); | ||
*/ | ||
|
||
// There are chances where you might want to execute something after the API call | ||
// For example, after you delete a course, you want to clear the enrollment tables | ||
// For this you need to manually use queryDB after you complete the call to api_backbone | ||
|
||
// queryDB($second_query, $second_query_array); | ||
|
||
print "Deleting boilerplace with id - ".$boilerplate_id; | ||
} | ||
} | ||
|
||
?> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
if (!defined('AT_INCLUDE_PATH')) { | ||
exit; | ||
} | ||
|
||
// The prefix common to all URLs in this boilerplate example app | ||
$boilerplate_url_prefix = "/boilerplate"; | ||
|
||
$boilerplate_base_urls = array( | ||
"/" => "BoilerplateClass", | ||
"/:number" => "BoilerplateClassWithUrlParameter" | ||
); | ||
|
||
$boilerplate_urls = generate_urls($boilerplate_base_urls, $boilerplate_url_prefix); | ||
|
||
?> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
<?php | ||
|
||
if (!defined('AT_INCLUDE_PATH')) { | ||
exit; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do you use exit instead of return ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So that if someone opens that in a browser, it doesn't open. I have noticed the same block of code in many other ATutor files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
} | ||
|
||
/* | ||
* Support for PHP < 5.4 | ||
* More info - http://stackoverflow.com/questions/3258634/php-how-to-send-http-response-code | ||
*/ | ||
|
||
if (!function_exists('http_response_code')) | ||
{ | ||
function http_response_code($newcode = NULL) | ||
{ | ||
static $code = 200; | ||
if($newcode != NULL) | ||
{ | ||
header('X-PHP-Response-Code: '.$newcode, true, $newcode); | ||
if(!headers_sent()) | ||
$code = $newcode; | ||
} | ||
return $code; | ||
} | ||
} | ||
|
||
function api_module_status() { | ||
// To check if the module is activated/activated | ||
$enabled = queryDB("SELECT | ||
* | ||
FROM | ||
%smodules | ||
WHERE | ||
dir_name = '%s' | ||
AND | ||
status = %d", | ||
array(TABLE_PREFIX, | ||
"_standard/api", | ||
2)); | ||
|
||
return count($enabled)?true:false; | ||
} | ||
|
||
function generate_urls($old_array, $prefix) { | ||
// Add prefix to all indices of old array | ||
$new_array = array(); | ||
foreach($old_array as $key => $value) { | ||
$new_array[$prefix.$key] = $value; | ||
} | ||
return $new_array; | ||
} | ||
|
||
function check_token($token, $minimum_access_level){ | ||
$check = queryDB("SELECT | ||
access_level | ||
, member_id | ||
FROM | ||
%sapi | ||
WHERE | ||
token = '%s' | ||
AND | ||
expiry > CURRENT_TIMESTAMP", | ||
array(TABLE_PREFIX, | ||
$token), true); | ||
|
||
if (!$check) { | ||
http_response_code(401); | ||
print_message(ERROR, TOKEN_DOES_NOT_EXIST); | ||
exit; | ||
} else if ($check["access_level"] > $minimum_access_level) { | ||
http_response_code(401); | ||
print_message(ERROR, YOU_ARE_NOT_AUTHORIZED_TO_ACCESS_THIS_RESOURCE); | ||
exit; | ||
} | ||
|
||
$query = "UPDATE | ||
%sapi | ||
SET | ||
modified = CURRENT_TIMESTAMP | ||
, expiry = NOW() + INTERVAL %d DAY | ||
WHERE | ||
token = '%s'"; | ||
|
||
$query_array = array(TABLE_PREFIX, | ||
TOKEN_EXPIRY, | ||
$token); | ||
|
||
if (DEBUG) { | ||
print vsprintf($query, $query_array); | ||
print "\n\n"; | ||
} | ||
|
||
// Update modified timestamp | ||
queryDB($query, $query_array); | ||
|
||
return $check["member_id"]; | ||
} | ||
|
||
function check_access_level($token, $access_level = ADMIN_ACCESS_LEVEL) { | ||
$check = queryDB("SELECT | ||
COUNT(*) | ||
FROM | ||
%sapi | ||
WHERE | ||
token = '%s' | ||
AND | ||
access_level <= %d", | ||
array(TABLE_PREFIX, | ||
$token, | ||
$access_level), true); | ||
|
||
return $check > 0 ? true : false; | ||
} | ||
|
||
function get_access_token($headers, $minimum_access_level = ADMIN_ACCESS_LEVEL, | ||
$return_member_id = false) { | ||
|
||
/** | ||
* $headers - assoc array of headers | ||
* $minimum_access_level - the user with the lowest permissions that can access this | ||
* $return_member_id - whether to return a tuple or token and member_id | ||
*/ | ||
|
||
$token = addslashes($headers[TOKEN_NAME]); | ||
$member_id = check_token($token, $minimum_access_level); | ||
|
||
if ($member_id && $return_member_id){ | ||
return array($token, $member_id); | ||
} else if ($member_id) { | ||
return $token; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
function print_message($type, $message, $log = array(), $http_method = HTTP_GET) { | ||
if (!$log) { | ||
$log = generate_basic_log($_SERVER); | ||
$headers = getallheaders(); | ||
$log["token"] = $headers[TOKEN_NAME]; | ||
} | ||
$key = $type == ERROR ? "errorMessage" : "successMessage"; | ||
$response = json_encode(array( | ||
$key => $message | ||
)); | ||
$log["response"] = $response; | ||
log_request($log, $http_method, $type == ERROR); | ||
echo $response; | ||
exit; | ||
} | ||
|
||
function generate_basic_log($request) { | ||
$log = array(); | ||
$log["ip_address"] = $request["REMOTE_ADDR"]; | ||
$log["request_uri"] = $request["REQUEST_URI"]; | ||
$log["http_method"] = $request["REQUEST_METHOD"]; | ||
$log["user_agent"] = $request["HTTP_USER_AGENT"]; | ||
return $log; | ||
} | ||
|
||
function log_request($log = array(), $http_method = HTTP_GET, $error = false) { | ||
if ((LOGGING_LEVEL == NO_LOGGING) || | ||
($http_method == HTTP_GET && LOGGING_LEVEL == LOGGING_EXCEPT_GET && !$error)) { | ||
return; | ||
} | ||
|
||
$query = "INSERT INTO %sapi_logs( | ||
ip_address | ||
, user_agent | ||
, request_uri | ||
, http_method | ||
, token | ||
, response) | ||
VALUES( | ||
'%s' | ||
, '%s' | ||
, '%s' | ||
, '%s' | ||
, '%s' | ||
, '%s')"; | ||
|
||
$query_array = array(TABLE_PREFIX, | ||
$log["ip_address"], | ||
$log["user_agent"], | ||
$log["request_uri"], | ||
$log["http_method"], | ||
$log["token"], | ||
$log["response"] | ||
); | ||
|
||
if (DEBUG) { | ||
print vsprintf($query, $query_array); | ||
print "\n\n"; | ||
} | ||
|
||
queryDB($query, $query_array); | ||
|
||
|
||
} | ||
|
||
function return_created_id($id, $log) { | ||
$response = json_encode(array( | ||
"successMessage" => ACTION_COMPLETED_SUCCESSFULLY, | ||
"id" => $id | ||
)); | ||
echo $response; | ||
} | ||
|
||
function create_SQL_clause($terms, $prefix = "WHERE", $sanitize = true) { | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function should run addslashes on every passed argument. Also you need to make this configurable just like queryDB (by default the function applies to every argument but use can say that no need to apply it) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function should not look into requests object. You need to pass array of "name" => value type of thing. There will be moments when some arguments come from URL, some from URL query and some from body. So just make function more dumb enough to work with simple name, value pairs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function should be smart enough to add WHERE clause is needed. (I guess add an extra argument. By default it is false but if it is specified as true then the string will start with WHERE ... ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure addslashes is not run within queryDB? Because this cause will run through queryDB later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this function you assemble a full string where you put values as well. Since you put values in then you might want to run addslashes for every value. |
||
* Function to create SQL clause | ||
* $terms is an associative array | ||
* The keys of $terms represent the column names as they appear in the SQL | ||
* For example, create_SQL_clause(array( | ||
* "title" => "My Course", | ||
* "language" => "en")) should return | ||
* "WHERE c.title = 'My Course' AND c.language = 'en'" | ||
*/ | ||
$query = ""; | ||
$prefix = $prefix ? $prefix . " " : ""; | ||
foreach ($terms as $key => $value) { | ||
if ($value) { | ||
if ($query != "") | ||
$query = $query."AND "; | ||
$query = $sanitize ? $query.$key." = '". addslashes($value) ."' " : $query.$key." = '". $value ."' "; | ||
} | ||
} | ||
if ($query != ""){ | ||
$query = $prefix . $query; | ||
} | ||
return $query; | ||
} | ||
|
||
?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is an example when a custom field is returned back (e.g. after POST you return ID of the freshly created entity) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is an example where you show how extra logic is being execute right after api_backbone() function?