├── .gitignore ├── API ├── .htaccess ├── AccessTools │ └── _APIRequest.php ├── Actions.php ├── Actions │ └── examples │ │ ├── CacheTest.php │ │ ├── CookieTest.php │ │ ├── DescribeActions.php │ │ ├── DescribeTables.php │ │ ├── LobbyAdd.php │ │ ├── LobbyAuthenticate.php │ │ ├── LobbyView.php │ │ ├── LogIn.php │ │ ├── MessageAdd.php │ │ ├── MessageView.php │ │ ├── ObjectTest.php │ │ ├── PrivateAction.php │ │ ├── SlowAction.php │ │ ├── UserAdd.php │ │ ├── UserDelete.php │ │ ├── UserEdit.php │ │ └── UserView.php ├── CACHE.php ├── CONFIG.php.example ├── CRON.php ├── CheckAPIKey.php ├── CommonFunctions.php ├── DB │ ├── DRIVERS │ │ ├── MONGO │ │ │ ├── ConnectToDatabase.php │ │ │ ├── DAVE.php │ │ │ ├── DirectDBFunctions.php │ │ │ ├── TableConfig.php │ │ │ └── init.php │ │ └── MYSQL │ │ │ ├── ConnectToDatabase.php │ │ │ ├── DAVE.php │ │ │ ├── DirectDBFunctions.php │ │ │ ├── TableConfig.php │ │ │ └── init.php │ ├── SCHEMA.php.example.mongo │ └── SCHEMA.php.example.mySQL ├── GetPostVars.php ├── LoadEnv.php ├── Objects │ ├── User.php │ └── _BASE.php ├── Output.php ├── TASKS.php ├── Tasks │ ├── CleanCache.php │ ├── CleanLog.php │ ├── CleanSessions.php │ ├── CreateDBSaveState.php │ ├── RemoveLargeLogs.php │ ├── RestoreDBSaveState.php │ ├── TruncateTable.php │ └── _BASE.php ├── crossdomain.xml ├── helper_functions │ ├── AES.php │ ├── CURL_POST.php │ ├── ValidStateZip.php │ ├── colors.php │ ├── formatBytes.php │ ├── http.php │ ├── microtime_float.php │ ├── parseArgs.php │ └── secondsToWords.php ├── index.php └── static.html ├── BaseDBs ├── API_BASIC.sql └── API_WITH_USER_TABLE.sql ├── SERVER ├── SERVER.php ├── script_runner.php └── server_config.php ├── SPEC ├── TEST.php ├── actions │ ├── CacheTest_spec.php │ └── DescribeActions_spec.php ├── end_to_end │ ├── messages_and_lobbies_spec.php │ └── users_spec.php ├── spec_helper.php └── system │ ├── general.php │ └── output_types.php ├── examples ├── api_explorer.html ├── chat.html └── describe_actions.html ├── humans.txt ├── index.php ├── license.txt ├── readme.markdown └── script ├── api ├── cron ├── server ├── spec └── task /.gitignore: -------------------------------------------------------------------------------- 1 | favicon.gif 2 | favicon.ico 3 | API/CONFIG.php 4 | API/DB/SCHEMA.php 5 | API/log/* 6 | SPEC/log/* 7 | SERVER/log/* 8 | -------------------------------------------------------------------------------- /API/.htaccess: -------------------------------------------------------------------------------- 1 | Options +FollowSymLinks 2 | RewriteEngine On 3 | RewriteBase /API/ 4 | RewriteCond %{REQUEST_FILENAME} !-f 5 | RewriteCond %{REQUEST_FILENAME} !-d 6 | RewriteRule . /API/index.php [L] -------------------------------------------------------------------------------- /API/AccessTools/_APIRequest.php: -------------------------------------------------------------------------------- 1 | "A_DUMMY_ACTION", 13 | "OutputType" => "PHP" 14 | ); 15 | 16 | $API_URL = "127.0.0.1/API/"; // local host 17 | $APIRequest = new APIRequest($API_URL, $PostArray, $IP); 18 | $APIDATA = $APIRequest->DoRequest(); 19 | if ($APIDATA != false) 20 | { 21 | echo "Your request came from ".$APIDATA['IP']." and took ".$APIDATA['ComputationTime']." seconds."; 22 | } 23 | else 24 | { 25 | echo 'Something is wrong with your URL or DAVE API configuration'; 26 | } 27 | echo "\r\n\r\n"; 28 | 29 | ***********************************************/ 30 | class APIRequest 31 | { 32 | protected $PostArray, $response, $API_URL; 33 | 34 | public function __construct($API_URL="", $PostArray=array(), $IP="") 35 | { 36 | if (!is_array($PostArray)){ $PostArray = array(); } 37 | $this->PostArray = $PostArray; 38 | $this->IP = $IP; 39 | $this->API_URL = $API_URL; 40 | } 41 | 42 | private function httpsPost($Url, $PostRequest, $HTTP_headers) 43 | { 44 | $ch=curl_init(); 45 | curl_setopt($ch, CURLOPT_URL, $Url); 46 | curl_setopt($ch, CURLOPT_HEADER, 0); 47 | curl_setopt($ch, CURLOPT_HTTPHEADER, array($HTTP_headers)); 48 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 49 | curl_setopt($ch, CURLOPT_POST, 1) ; 50 | curl_setopt($ch, CURLOPT_POSTFIELDS, $PostRequest); 51 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 52 | $result = curl_exec($ch); 53 | curl_close($ch); 54 | return $result; 55 | } 56 | 57 | // I make the actual request 58 | public function DoRequest() 59 | { 60 | $PostString = ""; 61 | foreach ($this->PostArray as $var => $val) 62 | { 63 | $PostString .= $var."=".$val."&"; 64 | } 65 | 66 | $return = array(); 67 | 68 | $PostRequest = ""; 69 | $PostRequest .= ("IP=".$this->IP."&"); 70 | $PostRequest .= $PostString; 71 | $PostRequest = utf8_encode($PostRequest); 72 | $Response = $this->httpsPost($this->API_URL, $PostRequest, ""); 73 | $this->response = $Response; 74 | $return = unserialize($Response); 75 | return $return; 76 | } 77 | 78 | // return again 79 | public function ShowResponse() 80 | { 81 | return unserialize($this->response); 82 | } 83 | 84 | public function ShowRawResponse() 85 | { 86 | return $this->response; 87 | } 88 | } 89 | 90 | ?> -------------------------------------------------------------------------------- /API/Actions.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/Actions/examples/CacheTest.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/Actions/examples/CookieTest.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/Actions/examples/DescribeActions.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/Actions/examples/DescribeTables.php: -------------------------------------------------------------------------------- 1 | 0) 33 | { 34 | $HumanizedTables[$CurTable]["Columns"][] = array("name" => $col_name, "unique" => $unique, "required" => $required); 35 | } 36 | } 37 | $i++; 38 | } 39 | 40 | $OUTPUT["Tables"] = $HumanizedTables; 41 | } 42 | 43 | ?> 44 | -------------------------------------------------------------------------------- /API/Actions/examples/LobbyAdd.php: -------------------------------------------------------------------------------- 1 | $PARAMS['LobbyName'], "LobbyKey" => $LobbyKey)); 16 | if ($resp[0] == false){$ERROR = $resp[1];} 17 | else 18 | { 19 | $LobbyID = $resp[1]["LobbyID"]; 20 | $details = _VIEW("lobbies",array("LobbyID" => $LobbyID)); 21 | $OUTPUT["LobbyID"] = $LobbyID; 22 | $OUTPUT["LobbyName"] = $details[1][0]["LobbyName"]; 23 | $OUTPUT["LobbyKey"] = $details[1][0]["LobbyKey"]; 24 | } 25 | } 26 | 27 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/LobbyAuthenticate.php: -------------------------------------------------------------------------------- 1 | $PARAMS['LobbyName'], "LobbyKey" => $PARAMS["LobbyKey"])); 22 | if ($resp[0] == false){$ERROR = $resp[1];} 23 | if (count($resp[1]) == 0){ $OUTPUT["LobbyAuthentication"] = "FALSE"; } 24 | else 25 | { 26 | $OUTPUT["LobbyDetails"] = $resp[1][0]; 27 | $OUTPUT["LobbyAuthentication"] = "TRUE"; 28 | } 29 | } 30 | 31 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/LobbyView.php: -------------------------------------------------------------------------------- 1 | true, "sort" => "ORDER BY TimeStamp DESC")); 12 | if ($resp[0] == false){$ERROR = $resp[1];} 13 | else 14 | { 15 | foreach($resp[1] as $lobby) 16 | { 17 | $OUTPUT["Lobbies"][] = array( 18 | "LobbyID" => $lobby["LobbyID"], 19 | "LobbyName" => $lobby["LobbyName"], 20 | "TimeStamp" => $lobby["TimeStamp"] 21 | ); 22 | } 23 | } 24 | } 25 | 26 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/LogIn.php: -------------------------------------------------------------------------------- 1 | $v) 29 | { 30 | $SessionData[$k] = $v; 31 | } 32 | update_session($OUTPUT['SessionKey'], $SessionData); 33 | $OUTPUT['SESSION'] = get_session_data($OUTPUT['SessionKey']); 34 | } 35 | } 36 | 37 | 38 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/MessageAdd.php: -------------------------------------------------------------------------------- 1 | $PARAMS['LobbyKey'])); 25 | if ($resp[0] == false){$ERROR = $resp[1];} 26 | if (count($resp[1]) != 1){ $ERROR = "That Lobby cannot be found"; } 27 | else 28 | { 29 | $LobbyID = $resp[1][0]["LobbyID"]; 30 | } 31 | } 32 | if ($ERROR == 100) 33 | { 34 | $resp = _ADD("messages", array( 35 | "LobbyID" => $LobbyID, 36 | "Speaker" => $PARAMS["Speaker"], 37 | "Message" => $PARAMS["Message"], 38 | )); 39 | $OUTPUT["MessageID"] = $resp["1"]["MessageID"]; 40 | } 41 | 42 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/MessageView.php: -------------------------------------------------------------------------------- 1 | $PARAMS['LobbyKey'])); 22 | if ($resp[0] == false){$ERROR = $resp[1];} 23 | if (count($resp[1]) != 1){ $ERROR = "That Lobby cannot be found"; } 24 | else 25 | { 26 | $LobbyID = $resp[1][0]["LobbyID"]; 27 | $LobbyName = $resp[1][0]["LobbyName"]; 28 | $OUTPUT["LobbyID"] = $LobbyID; 29 | $OUTPUT["LobbyName"] = $LobbyName; 30 | } 31 | } 32 | if ($ERROR == 100) 33 | { 34 | $UpperLimit = $PARAMS["UpperLimit"]; 35 | $LowerLimit = $PARAMS["LowerLimit"]; 36 | if (empty($UpperLimit)){ $UpperLimit = 10; } 37 | if (empty($LowerLimit)){ $LowerLimit = 0; } 38 | 39 | // null values for some of these are OK 40 | $resp = _VIEW("messages", array( 41 | "LobbyID" => $LobbyID, 42 | "Speaker" => $PARAMS["Speaker"], 43 | ),array( 44 | "SQL_Override" => true, 45 | "sort" => "ORDER BY Timestamp DESC", 46 | "UpperLimit" => $UpperLimit, 47 | "LowerLimit" => $LowerLimit 48 | )); 49 | 50 | $OUTPUT["Messages"] = array(); 51 | foreach($resp[1] as $message) 52 | { 53 | $OUTPUT["Messages"][] = $message; 54 | } 55 | } 56 | 57 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/ObjectTest.php: -------------------------------------------------------------------------------- 1 | rand().time()."_name", 19 | "EMail" => rand().time()."@test.com" 20 | ); 21 | 22 | // how many users are there now? 23 | $TestResults["A_How_Many_Initial_Users"] = $UsersTable->count(); 24 | 25 | // what are thier screen names and join dates? 26 | $screen_names = array(); 27 | $Users = $UsersTable->all(); // you can also use find() and pass no params 28 | foreach($Users as $User) 29 | { 30 | $screen_names[$User->DATA("ScreenName")] = $User->DATA("Joined"); 31 | } 32 | $TestResults["B_User_ScreenNames_and_join_dates"] = $screen_names; 33 | 34 | // add a new user 35 | $OurUserData = array( 36 | "FirstName" => "John", 37 | "LastName" => "Doe", 38 | "EMail" => $TestValues["EMail"], 39 | "ScreenName" => $TestValues["ScreenName"], 40 | "Password" => "password" 41 | ); 42 | $OurUser = new User($UsersTable, $OurUserData); 43 | $OurUser->validate_and_configure_new_user(); 44 | $TestResults["C_Add_User_Response"] = $OurUser->ADD(); 45 | 46 | // how many users now? 47 | $TestResults["D_How_Many_Users_After_Create"] = $UsersTable->count(); 48 | 49 | // try to add the same user again, and note the error about these unique params already existing 50 | $TestResults["E_Existance_Error_When_Add_Again"] = $OurUser->ADD(); 51 | 52 | // view that user by the user object 53 | $TestResults["F_User_Details_From_User_Object"] = $OurUser->VIEW(); 54 | 55 | // view that user by a find on the Table Object 56 | $FoundUserObjects = $UsersTable->find(array("ScreenName" => $TestValues["ScreenName"])); 57 | $FoundUserHashes = array(); 58 | foreach ($FoundUserObjects as $FoundUser) 59 | { 60 | $FoundUserHashes[] = $FoundUser->DATA(); 61 | } 62 | $TestResults["G_User_Details_From_Find_On_Table_Object"] = $FoundUserHashes; 63 | 64 | // edit that user 65 | $NewUserData = array( 66 | "ScreenName" => "NewDaveAPI", 67 | "EMail" => "new_email@test.com" 68 | ); 69 | $EditResp = $OurUser->EDIT($NewUserData); 70 | $TestResults["H_Edited_User_Data"] = $EditResp; 71 | 72 | // delete that user 73 | $delete_resp = $OurUser->DELETE(); 74 | if ($delete_resp === true){$delete_resp = "OK";} 75 | $TestResults["I_Delete_User"] = $delete_resp; 76 | 77 | // how many users now? 78 | $TestResults["J_Final_User_Count"] = $UsersTable->count(); 79 | 80 | 81 | 82 | 83 | $OUTPUT["TestResults"] = $TestResults; 84 | } 85 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/PrivateAction.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/Actions/examples/SlowAction.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/Actions/examples/UserAdd.php: -------------------------------------------------------------------------------- 1 | 0 && $ERROR == 100) 11 | { 12 | $func_out = validate_EMail($PARAMS["EMail"]); 13 | if ($func_out != 100){ $ERROR = $func_out; } 14 | } 15 | 16 | if ($ERROR == 100 && strlen($PARAMS["PhoneNumber"]) > 0) 17 | { 18 | list($fun_out, $PARAMS["PhoneNumber"]) = validate_PhoneNumber($PARAMS["PhoneNumber"]); // baisc format checking 19 | if ($func_out != 100){ $ERROR = $func_out; } 20 | } 21 | 22 | if ($ERROR == 100) 23 | { 24 | if (strlen($PARAMS["Password"]) > 0) 25 | { 26 | $Salt = md5(rand(1,999).(microtime()/rand(1,999)).rand(1,999)); 27 | $PasswordHash = md5($PARAMS["Password"].$Salt); 28 | } 29 | else 30 | { 31 | $ERROR = "Please provide a Password"; 32 | } 33 | } 34 | 35 | // use the DAVE Add to take care of the actual DB checks and adding 36 | if ($ERROR == 100) 37 | { 38 | $UserData = only_table_columns($PARAMS, "users"); 39 | $UserData["PasswordHash"] = $PasswordHash; 40 | $UserData["Salt"] = $Salt; 41 | 42 | list($pass,$result) = _ADD("users", $UserData); 43 | if (!$pass) 44 | { 45 | $ERROR = $result; 46 | } 47 | else 48 | { 49 | $OUTPUT[$TABLES['users']['META']['KEY']] = $result[$TABLES['users']['META']['KEY']]; 50 | } 51 | } 52 | 53 | 54 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/UserDelete.php: -------------------------------------------------------------------------------- 1 | $PARAMS['UserID'], 20 | "ScreenName" => $PARAMS['ScreenName'], 21 | "EMail" => $PARAMS['EMail'] 22 | )); 23 | if($resp[0] == false){$ERROR = $resp[1];} 24 | } 25 | } 26 | 27 | 28 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/UserEdit.php: -------------------------------------------------------------------------------- 1 | 0 && $ERROR == 100) 11 | { 12 | $func_out = validate_EMail($PARAMS["EMail"]); 13 | if ($func_out != 100){ $ERROR = $func_out; } 14 | } 15 | 16 | if ($ERROR == 100 && strlen($PARAMS["PhoneNumber"]) > 0) 17 | { 18 | list($func_out, $PARAMS["PhoneNumber"]) = validate_PhoneNumber($PARAMS["PhoneNumber"]); 19 | if ($func_out != 100){ $ERROR = $func_out; } 20 | } 21 | 22 | if ($ERROR == 100) 23 | { 24 | $AuthResp = AuthenticateUser(); 25 | if ($AuthResp[0] !== true) 26 | { 27 | $ERROR = $AuthResp[1]; 28 | } 29 | else 30 | { 31 | list($msg, $ReturnedUsers) = _VIEW("users",array( 32 | "UserID" => $PARAMS['UserID'], 33 | "ScreenName" => $PARAMS['ScreenName'], 34 | "EMail" => $PARAMS['EMail'], 35 | )); 36 | if ($msg == false) 37 | { 38 | $ERROR = $ReturnedUsers; 39 | } 40 | elseif(count($ReturnedUsers) == 1) 41 | { 42 | $UserData = only_table_columns($PARAMS, "users"); 43 | $UserData["PasswordHash"] = $ReturnedUsers[0]["PasswordHash"]; // no change 44 | if(strlen($PARAMS["NewPassword"]) > 0) // user is trying to change password 45 | { 46 | $UserData["PasswordHash"] = md5($PARAMS["NewPassword"].$ReturnedUsers[0]['Salt']); 47 | } 48 | 49 | list($pass,$result) = _EDIT("users", $UserData); 50 | if (!$pass){ $ERROR = $result; } 51 | elseif (count($result) == 1) 52 | { 53 | foreach( $result[0] as $key => $val) 54 | { 55 | $OUTPUT["User"][$key] = $val; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | 62 | ?> -------------------------------------------------------------------------------- /API/Actions/examples/UserView.php: -------------------------------------------------------------------------------- 1 | $PARAMS['UserID'], 14 | "ScreenName" => $PARAMS['ScreenName'], 15 | "EMail" => $PARAMS['EMail'], 16 | )); 17 | if ($msg == false) 18 | { 19 | $ERROR = $ReturnedUsers; 20 | } 21 | elseif(count($ReturnedUsers) == 1) 22 | { 23 | if(!empty($PARAMS["PasswordHash"]) || !empty($PARAMS["Password"])) 24 | { 25 | $OUTPUT["User"]['InformationType'] = "Private"; 26 | $AuthResp = AuthenticateUser(); 27 | if ($AuthResp[0] !== true) 28 | { 29 | $ERROR = $AuthResp[1]; 30 | } 31 | else 32 | { 33 | foreach( $ReturnedUsers[0] as $key => $val) 34 | { 35 | $OUTPUT["User"][$key] = $val; 36 | } 37 | } 38 | } 39 | else // Public Data Request 40 | { 41 | $OUTPUT["User"]['InformationType'] = "Public"; 42 | $OUTPUT["User"]['ScreenName'] = $ReturnedUsers[0]['ScreenName']; 43 | $OUTPUT["User"]['Joined'] = $ReturnedUsers[0]['Joined']; 44 | } 45 | } 46 | else 47 | { 48 | $ERROR = "User cannot be found"; 49 | } 50 | } 51 | 52 | 53 | ?> -------------------------------------------------------------------------------- /API/CACHE.php: -------------------------------------------------------------------------------- 1 | connect($CONFIG['MemCacheHost'], 11211); 20 | 21 | function SetCache($Key, $Value, $ThisCacheTime = null) 22 | { 23 | global $CONFIG; 24 | if ($ThisCacheTime == null) { $ThisCacheTime = $CONFIG['CacheTime']; } 25 | 26 | $memcache->set($Key, $Value, false, $ThisCacheTime); 27 | } 28 | 29 | function GetCache($Key) 30 | { 31 | $memcache_result = $memcache->get($Key); 32 | return $memcache_result; 33 | } 34 | } 35 | 36 | /***********************************************/ 37 | 38 | elseif($CONFIG['CacheType'] == "DB") 39 | { 40 | // Look in DirectDBFunctions for this DB Driver 41 | function SetCache($Key, $Value, $ThisCacheTime = null) 42 | { 43 | return _DBSetCache($Key, $Value, $ThisCacheTime); 44 | } 45 | 46 | // Look in DirectDBFunctions for this DB Driver 47 | function GetCache($Key) 48 | { 49 | return _DBGetCache($Key); 50 | } 51 | } 52 | 53 | /***********************************************/ 54 | 55 | elseif($CONFIG['CacheType'] == "FlatFile") 56 | { 57 | function SetCache($Key, $Value, $ThisCacheTime = null) 58 | { 59 | global $CONFIG; 60 | if ($ThisCacheTime == null) { $ThisCacheTime = $CONFIG['CacheTime']; } 61 | 62 | $COUNTAINER = array((time() + $ThisCacheTime),$Value); 63 | $TheFile = $CONFIG['CacheFolder'].$Key.".cache"; 64 | $fh = fopen($TheFile, 'w') or die("can't open cache file for write"); 65 | fwrite($fh, serialize($COUNTAINER)); 66 | fclose($fh); 67 | chmod($TheFile,0777); 68 | 69 | return true; 70 | } 71 | 72 | function GetCache($Key) 73 | { 74 | global $CONFIG; 75 | clearstatcache(); 76 | $TheFile = $CONFIG['CacheFolder'].$Key.".cache"; 77 | if (!file_exists($TheFile)) 78 | { 79 | return false; 80 | } 81 | else 82 | { 83 | $fh = fopen($TheFile, 'r'); 84 | $theData = fread($fh, filesize($TheFile)); 85 | fclose($fh); 86 | $Result = unserialize($theData); 87 | if ($Result[0] < time()) 88 | { 89 | unlink($TheFile); 90 | return false; 91 | } 92 | else 93 | { 94 | return $Result[1]; 95 | } 96 | } 97 | } 98 | } 99 | 100 | /***********************************************/ 101 | 102 | else 103 | { 104 | function SetCache($Key, $Value, $ThisCacheTime = null) 105 | { 106 | global $CONFIG; 107 | if ($ThisCacheTime == null) { $ThisCacheTime = $CONFIG['CacheTime']; } 108 | 109 | return true; 110 | } 111 | 112 | function GetCache($Key) 113 | { 114 | return false; 115 | } 116 | } 117 | 118 | ?> -------------------------------------------------------------------------------- /API/CONFIG.php.example: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/CRON.php: -------------------------------------------------------------------------------- 1 | /path/to/CRON_LOG.txt 12 | 13 | $parts = explode("/",__FILE__); 14 | $ThisFile = $parts[count($parts) - 1]; 15 | chdir(substr(__FILE__,0,(strlen(__FILE__) - strlen($ThisFile)))); 16 | require_once("LoadEnv.php"); unset($parts); unset($ThisFile); 17 | 18 | load_tasks(); 19 | 20 | $CRON_OUTPUT = "STARTING CRON @ ".date("m-d-Y H:i:s")."\r\n\r\n"; 21 | 22 | ///////////////////////////////////////////////////////////////////////// 23 | // Do Tasks 24 | 25 | $CRON_OUTPUT .= run_task("CleanCache"); 26 | $CRON_OUTPUT .= run_task("CleanLog"); 27 | $CRON_OUTPUT .= run_task("CleanSessions"); 28 | $CRON_OUTPUT .= run_task("RemoveLargeLogs"); 29 | 30 | ///////////////////////////////////////////////////////////////////////// 31 | // End the log output 32 | echo $CRON_OUTPUT; 33 | $fh = fopen($CONFIG['CronLogFile'], 'a'); 34 | fwrite($fh, $CRON_OUTPUT); 35 | fclose($fh); 36 | 37 | exit; 38 | ?> -------------------------------------------------------------------------------- /API/CheckAPIKey.php: -------------------------------------------------------------------------------- 1 | $PARAMS["APIKey"])); 21 | } 22 | 23 | if (count($Results[1]) == 1) 24 | { 25 | $DeveloperID_ = $Results[1][0]['DeveloperID']; 26 | $APIKey_ = $Results[1][0]['APIKey']; 27 | $UserActions = $Results[1][0]['UserActions']; 28 | $IsAdmin = $Results[1][0]['IsAdmin']; 29 | } 30 | else 31 | { 32 | $ERROR = "API Key not found"; 33 | } 34 | } 35 | // Check that the API Key has admin rights for user Actions 36 | if ($ERROR == 100) 37 | { 38 | if($UserActions == 1){ $UserAction = true; } 39 | else if($UserActions == 0){ $UserAction = false; } 40 | } 41 | 42 | // Check that the sequrity HASH worked out 43 | // the hash should be md5($DeveloperID{secret}.$APIKey.$Rand), IN THIS ORDER!!!! 44 | if ($CONFIG['SafeMode'] == true) 45 | { 46 | if ($ERROR == 100) { if ($PARAMS["Rand"] == ""){ $ERROR = "You need to provide a Rand to authenticate with"; } } 47 | if ($ERROR == 100) { if ($PARAMS["Hash"] == ""){ $ERROR = "You need to provide a Hash to authenticate with"; } } 48 | if ($ERROR == 100) 49 | { 50 | $TestHash = md5(($DeveloperID_.$APIKey_.$PARAMS["Rand"])); 51 | $OUTPUT["DeveloperID_"] = $DeveloperID_; 52 | $OUTPUT["APIKey_"] = $APIKey_; 53 | $OUTPUT["rand_"] = $PARAMS["Rand"]; 54 | if (!($TestHash == $PARAMS["Hash"])) 55 | { 56 | $ERROR = "Developer Authentication Failed"; 57 | } 58 | } 59 | } 60 | 61 | if ($ERROR == 100) 62 | { 63 | $OUTPUT["DeveloperAuthentication"] = "TRUE"; 64 | } 65 | else 66 | { 67 | $OUTPUT["DeveloperAuthentication"] = "FALSE"; 68 | } 69 | 70 | 71 | ?> -------------------------------------------------------------------------------- /API/CommonFunctions.php: -------------------------------------------------------------------------------- 1 | $action[0], 19 | "Access" => $action[2] 20 | ); 21 | } 22 | return $HumanActions; 23 | } 24 | 25 | function load_tasks() 26 | { 27 | global $CONFIG; 28 | require_once($CONFIG['App_dir']."Tasks/_BASE.php"); 29 | $TaskFiles = glob($CONFIG['App_dir']."Tasks/*.php"); 30 | foreach($TaskFiles as $task_file){require_once($task_file); } 31 | 32 | $TaskNames = array(); 33 | foreach($TaskFiles as $class_name) 34 | { 35 | $parts = explode("/",$class_name); 36 | $parts = explode(".",$parts[(count($parts) - 1)]); 37 | $class_name = $parts[0]; 38 | if ($class_name != "task" && class_exists($class_name)) 39 | { 40 | $TaskNames[] = $class_name; 41 | } 42 | } 43 | 44 | return $TaskNames; 45 | } 46 | 47 | function run_task($TaskName, $PARAMS = array()) 48 | { 49 | // assumes that tasks have been properly loaded in with load_tasks() 50 | $TaskLog = "Running Task: ".$TaskName."\r\n\r\n"; 51 | if (!(is_string($TaskName)) || strlen($TaskName) == 0){return "No task provided.\r\n";} 52 | $_TASK = new $TaskName(true, $PARAMS); 53 | $TaskLog .= $_TASK->get_task_log(); 54 | return $TaskLog."\r\n"; 55 | } 56 | 57 | function reload_tables() 58 | { 59 | global $ERROR, $DBOBJ, $CONFIG, $TABLES; 60 | 61 | $Status = $DBOBJ->GetStatus(); 62 | if ($Status === true) 63 | { 64 | $TABLES = array(); 65 | $ToReloadTables = true; 66 | require($CONFIG['App_dir']."DB/DRIVERS/".$CONFIG["DBType"]."/TableConfig.php"); // requiring again will force a re-load 67 | } 68 | else 69 | { 70 | $ERROR = "DB Cannot be reached: ".$Status; 71 | } 72 | } 73 | 74 | function _tableCheck($Table) 75 | { 76 | global $TABLES; 77 | // does this table exist? 78 | $Keys = array_keys($TABLES); 79 | if( in_array($Table, $Keys)) 80 | { 81 | return true; 82 | } 83 | else 84 | { 85 | return false; 86 | } 87 | } 88 | 89 | function _getAllTableCols($Table) 90 | { 91 | global $TABLES; 92 | $Vars = array(); 93 | $i = 0; 94 | while ($i < count($TABLES[$Table])) 95 | { 96 | $Vars[] = $TABLES[$Table][$i][0]; 97 | // 98 | $i++; 99 | } 100 | return $Vars; 101 | } 102 | 103 | function _getRequiredTableVars($Table) 104 | { 105 | global $TABLES; 106 | $RequiredVars = array(); 107 | $i = 0; 108 | while ($i < count($TABLES[$Table])) 109 | { 110 | if ($TABLES[$Table][$i][2] == true && $TABLES[$Table]["META"]["KEY"] != $TABLES[$Table][$i][0]) 111 | { 112 | $RequiredVars[] = $TABLES[$Table][$i][0]; 113 | } 114 | // 115 | $i++; 116 | } 117 | return $RequiredVars; 118 | } 119 | 120 | function _getUniqueTableVars($Table) 121 | { 122 | global $TABLES; 123 | $UniqueVars = array(); 124 | $i = 0; 125 | while ($i < count($TABLES[$Table])) 126 | { 127 | if ($TABLES[$Table][$i][1] == true) 128 | { 129 | $UniqueVars[] = $TABLES[$Table][$i][0]; 130 | } 131 | // 132 | $i++; 133 | } 134 | return $UniqueVars; 135 | } 136 | 137 | function _isSpecialString($string) 138 | { 139 | global $CONFIG; 140 | $found = false; 141 | foreach ($CONFIG['SpecialStrings'] as $term) 142 | { 143 | if (stristr($string,$term[0]) !== false) 144 | { 145 | $found = true; 146 | break; 147 | } 148 | } 149 | return $found; 150 | } 151 | 152 | function create_session() 153 | { 154 | $key = md5( uniqid() ); 155 | _ADD("sessions", array( 156 | "KEY" => $key, 157 | "DATA" => serialize(array()), 158 | "created_at" => date("Y-m-d H:i:s"), 159 | "updated_at" => date("Y-m-d H:i:s") 160 | )); 161 | return $key; 162 | } 163 | 164 | function update_session($SessionKey, $SessionData) 165 | { 166 | // this function is destructive and will replace the entire array of session data previously stored 167 | $resp = _EDIT("sessions",array( 168 | "KEY" => $SessionKey, 169 | "updated_at" => date("Y-m-d H:i:s"), 170 | "DATA" => serialize($SessionData) 171 | )); 172 | return($resp[0]); 173 | } 174 | 175 | function get_session_data($SessionKey) 176 | { 177 | global $OUTPUT; 178 | $results = _VIEW("sessions", 179 | array('KEY' => $SessionKey) 180 | ); 181 | if ($results[0] != 1) 182 | { 183 | $OUTPUT["SessionError"] = "Session cannot be found by this key"; 184 | return false; 185 | } 186 | else 187 | { 188 | return unserialize($results[1][0]["DATA"]); 189 | } 190 | } 191 | 192 | function only_table_columns($DATA, $Table) 193 | { 194 | $CleanData = array(); 195 | foreach($DATA as $param=>$val) 196 | { 197 | if(in_array($param,_getAllTableCols($Table))) { $CleanData[$param] = $val ;} 198 | } 199 | return $CleanData; 200 | } 201 | 202 | function SessionAutenticate($DATA = null){ 203 | global $PARAMS; 204 | if ($DATA == null){$DATA = $PARAMS;} 205 | 206 | if($DATA["KEY"]==null){ 207 | return "KEY is required for this action"; 208 | }else{ 209 | list($msg, $ReturnedUsers) = _VIEW("sessions",array( 210 | "KEY" => $DATA['KEY'], 211 | )); 212 | } 213 | if($msg != true || count($ReturnedUsers) != 1){ 214 | return "KEY not found"; 215 | }else{ 216 | return true; 217 | } 218 | } 219 | 220 | function AuthenticateUser($DATA = null) 221 | { 222 | // (UserID || ScreenName || EMail) + (Password || PasswordHash) || (Hash + Rand + UserID) 223 | // Hash = md5(UserID.Password.Rand) 224 | // returns arrray(status, note || user_details) 225 | 226 | global $PARAMS; 227 | $OUT = array(false, ""); 228 | if ($DATA == null){$DATA = $PARAMS;} 229 | 230 | if (empty($DATA['UserID']) && empty($DATA['EMail']) && empty($DATA['ScreenName'])) 231 | { 232 | $OUT[1] = "Authentication: Provide either UserID, EMail, or ScreenName"; 233 | } 234 | 235 | list($msg, $ReturnedUsers) = _VIEW("users",array( 236 | "UserID" => $DATA['UserID'], 237 | "ScreenName" => $DATA['ScreenName'], 238 | "EMail" => $DATA['EMail'] 239 | )); 240 | 241 | if($msg != true) 242 | { 243 | $OUT[1] = "Authentication: ".$ReturnedUsers; 244 | } 245 | else 246 | { 247 | if (count($ReturnedUsers) != 1) 248 | { 249 | $OUT[1] = "Authentication: User not found"; 250 | } 251 | elseif (!empty($DATA['Hash'])) 252 | { 253 | if (empty($DATA['Rand'])){$OUT[1] = "Authentication: Rand is required";} 254 | else 255 | { 256 | $LocalHash = md5($ReturnedUsers[0]['UserID'].$ReturnedUsers[0]['Password'].$DATA['Rand']); 257 | if ($DATA['Hash'] == $LocalHash){$OUT = true;} 258 | else{$OUT[1] = "Authentication: Hash does not match expected";} 259 | } 260 | } 261 | elseif(!empty($DATA['Password']) || !empty($DATA['PasswordHash'])) 262 | { 263 | if(empty($DATA['PasswordHash'])){$DATA['PasswordHash'] = md5($DATA['Password'].$ReturnedUsers[0]['Salt']);} 264 | if ($DATA['PasswordHash'] == $ReturnedUsers[0]['PasswordHash']){$OUT[0] = true; $OUT[1] = $ReturnedUsers[0];} 265 | else{$OUT[1] = "Authentication: Password or PasswordHash does not match";} 266 | } 267 | else 268 | { 269 | $OUT[1] = "Authentication: Send either Hash [ md5(UserID.Password.Rand) ], Password, or PasswordHash "; 270 | } 271 | } 272 | return $OUT; 273 | } 274 | 275 | function validate_EMail($EMail) 276 | { 277 | if (preg_match("/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i",$EMail)) 278 | { 279 | $OUT = 100; 280 | } 281 | else { 282 | $OUT = "That is not a valid EMail address"; 283 | } 284 | return $OUT; 285 | } 286 | 287 | function validate_PhoneNumber($PhoneNumber) 288 | { 289 | $ERROR = 100; 290 | $PhoneNumber = preg_replace("[^A-Za-z0-9]", "", $PhoneNumber ); 291 | $PhoneNumber = str_replace(".", "", $PhoneNumber); 292 | $PhoneNumber = str_replace("-", "", $PhoneNumber); 293 | $PhoneNumber = str_replace(" ", "", $PhoneNumber); 294 | if (strlen($PhoneNumber) == 10) 295 | { 296 | $PhoneNumber = "1".$PhoneNumber; 297 | } 298 | if (strlen($PhoneNumber) != 11) 299 | { 300 | $ERROR = "This phone number is not formatted properly"; 301 | } 302 | return array($ERROR,$PhoneNumber); 303 | } 304 | 305 | 306 | /*************************************************************/ 307 | 308 | ?> -------------------------------------------------------------------------------- /API/DB/DRIVERS/MONGO/ConnectToDatabase.php: -------------------------------------------------------------------------------- 1 | Status 14 | - mongo_log(): Will log "queries" to file 15 | - CheckForSpecialStrings(): Will inspect queries for special strings ($CONFIG['SpecialStrings']) and replace. This is to fix situations where user might post "0" as input, etc 16 | - GetConnection(): returns the connction object if applicable 17 | - GetStatus(): returns the last status message 18 | - close(): closes the DB connection 19 | 20 | ////////////// 21 | 22 | Example useage: 23 | 24 | $DBOBJ = new DBConnection(); 25 | $Status = $DBOBJ->GetStatus(); 26 | if ($Status === true) 27 | { 28 | $DBOBJ->Query($SQL); 29 | $Status = $DBOBJ->GetStatus(); 30 | if ($Status === true){ 31 | $Results = $DBOBJ->GetResults(); 32 | // Do stuff with the $Results array 33 | } 34 | else{ $ERROR = $Status; } 35 | } 36 | else { $ERROR = $Status; } 37 | $DBOBJ->close(); 38 | 39 | use the GetLastInsert() function to get the deatils of an entry you just added. 40 | 41 | ***********************************************/ 42 | 43 | class DBConnection 44 | { 45 | protected $Connection, $Status, $OUT, $DataBase, $MongoDB; 46 | 47 | public function __construct($OtherDB = "") 48 | { 49 | global $CONFIG; 50 | $this->Status = true; 51 | 52 | if ($OtherDB != "") { $DataBase = $this->DataBase = $OtherDB ; } 53 | else { $DataBase = $this->DataBase = $CONFIG['DB']; } 54 | 55 | $this->Connection = new Mongo($CONFIG['dbhost']); 56 | 57 | if(!empty($this->Connection)) 58 | { 59 | $this->MongoDB = $this->Connection->$DataBase; 60 | if (!empty($this->MongoDB)) 61 | { 62 | return true; 63 | } 64 | else 65 | { 66 | $this->Status = "Database Selection Error (Mongo)"; 67 | return false; 68 | } 69 | } 70 | else 71 | { 72 | $this->Status = "Connection Error (Mongo) | Connection Access or permission error"; 73 | return false; 74 | } 75 | } 76 | 77 | private function mongo_log($line) 78 | { 79 | global $IP, $CONFIG; 80 | 81 | $host = $IP; 82 | if ($host == ""){$host = "local_system";} 83 | 84 | $line = date("Y-m-d H:i:s")." | ".$host." | ".$line; 85 | if (strlen($CONFIG['DBLogFile']) > 0) 86 | { 87 | $LogFileHandle = fopen($CONFIG['DBLogFile'], 'a'); 88 | if($LogFileHandle) 89 | { 90 | fwrite($LogFileHandle, ($line."\r\n")); 91 | } 92 | fclose($LogFileHandle); 93 | } 94 | } 95 | 96 | private function CheckForSpecialStrings($string) 97 | { 98 | global $CONFIG; 99 | foreach ($CONFIG['SpecialStrings'] as $term) 100 | { 101 | $string = str_replace($term[0],$term[1],$string); 102 | } 103 | $string = str_replace(" "," ",$string); 104 | return $string; 105 | } 106 | 107 | public function GetConnection() 108 | { 109 | return $this->Connection; 110 | } 111 | 112 | public function GetMongoDB() 113 | { 114 | return $this->MongoDB; 115 | } 116 | 117 | public function GetStatus() 118 | { 119 | return $this->Status; 120 | } 121 | 122 | public function close() 123 | { 124 | // @mysql_close($this->Connection); 125 | unset($this->Connection); 126 | $this->Status = "Disconnected. (Mongo)"; 127 | } 128 | } 129 | 130 | ?> -------------------------------------------------------------------------------- /API/DB/DRIVERS/MONGO/DAVE.php: -------------------------------------------------------------------------------- 1 | GetStatus(); 29 | if ($Status !== true) 30 | { 31 | return array(false,$Status); 32 | } 33 | 34 | $MongoDB = $DBOBJ->GetMongoDB(); 35 | $Collection = $MongoDB->$Table; 36 | 37 | foreach($RequiredVars as $req) 38 | { 39 | if(strlen($VARS[$req]) == 0) 40 | { 41 | return array(false,$req." is a required value and you must provide a value"); 42 | } 43 | } 44 | 45 | foreach($VARS as $var => $val) 46 | { 47 | if (in_array($var, $UniqueVars) && strlen($val) > 0) // unique 48 | { 49 | $FIND = array( $var => $val); 50 | $count = $Collection->count($FIND); 51 | if ($count > 0) 52 | { 53 | return array(false,"There is already an entry of '".$val."' for ".$var); 54 | } 55 | else // var OK! 56 | { 57 | $attrs[$var] = $val; 58 | } 59 | 60 | } 61 | elseif (strlen($val) > 0) // non-unique 62 | { 63 | $attrs[$var] = $val; 64 | } 65 | } 66 | 67 | $Collection->insert($attrs); 68 | $new_obj = $Collection->findOne($attrs); 69 | $new_id = (string)$new_obj['_id']; 70 | 71 | return array(true,array( $TABLES['users']['META']['KEY'] => $new_id)); 72 | } 73 | 74 | /***********************************************/ 75 | 76 | /* 77 | Table should be defned in $TABLES 78 | $VARS will be the params of the row to be added. VARS should include a key/value pair which includes the primary key for the DB. If unspecified, $PARAMS is used by default) 79 | */ 80 | function _EDIT($Table, $VARS = null) 81 | { 82 | Global $TABLES, $DBOBJ, $Connection, $PARAMS; 83 | 84 | if ($VARS == null){$VARS = $PARAMS;} 85 | 86 | $UniqueVars = _getUniqueTableVars($Table); 87 | $RequiredVars = _getRequiredTableVars($Table); 88 | $attrs = array(); 89 | 90 | $Status = $DBOBJ->GetStatus(); 91 | if ($Status !== true) 92 | { 93 | return array(false,$Status); 94 | } 95 | $MongoDB = $DBOBJ->GetMongoDB(); 96 | $Collection = $MongoDB->$Table; 97 | 98 | $resp = _VIEW($Table, $VARS); 99 | if($resp[0] == false){ return array(false,$resp[1]) ;} 100 | if (count($resp[1]) > 1){return array(false,"You need to supply the META KEY for this table, ".$TABLES[$Table]['META']['KEY']) ;} 101 | if (count($resp[1]) == 0) 102 | { 103 | $msg = "You have supplied none of the required parameters to make this edit. At least one of the following is required: "; 104 | foreach($UniqueVars as $var) 105 | { 106 | $msg .= $var." "; 107 | } 108 | return array(false,$msg); 109 | } 110 | if ($VARS[$TABLES[$Table]['META']['KEY']] == "") 111 | { 112 | $VARS[$TABLES[$Table]['META']['KEY']] = $resp[1][0][$TABLES[$Table]['META']['KEY']]; 113 | } 114 | $current_values = $resp[1][0]; 115 | 116 | $new_data = false; 117 | foreach($VARS as $var => $val) 118 | { 119 | if ($var != $TABLES[$Table]['META']['KEY']) 120 | { 121 | if (in_array($var, $UniqueVars) && strlen($val) > 0 && $val != $current_values[$var]) // unique 122 | { 123 | $count = $Collection->count(array($var => $val)); 124 | if ($count > 0) 125 | { 126 | return array(false,"There is already an entry of '".$val."' for ".$var); 127 | } 128 | else // var OK! 129 | { 130 | $attrs[$var] = $val; 131 | } 132 | } 133 | elseif (strlen($val) > 0) // non-unique 134 | { 135 | $attrs[$var] = $val; 136 | } 137 | if($attrs[$var] != $current_values[$var] && $var != $TABLES[$Table]['META']['KEY']) 138 | { 139 | $new_data = true; 140 | } 141 | } 142 | } 143 | 144 | // fill in old values 145 | foreach($current_values as $var=>$val) 146 | { 147 | if(empty($attrs[$var])) 148 | { 149 | if(is_object($val) == false) 150 | $attrs[$var] = $val; 151 | } 152 | } 153 | if (count($attrs) > 0 && $new_data) 154 | { 155 | $MongoId = new MongoID($VARS[$TABLES[$Table]['META']['KEY']]); 156 | $resp = $Collection->update(array("_id" => $MongoId), $attrs); 157 | if ($resp === true) 158 | { 159 | return _VIEW($Table, $VARS); // do a view again to return fresh data 160 | } 161 | else{ return array(false,$Status); } 162 | } 163 | else 164 | { 165 | return array(false,"There is nothing to change"); 166 | } 167 | } 168 | 169 | /***********************************************/ 170 | 171 | /* 172 | Table should be defned in $TABLES 173 | $VARS will be the params of the row to be added. VARS should include a key/value pair which includes either the primary key for the DB or one of the unique cols for the table. If unspecified, $PARAMS is used by default) 174 | Settins is an array that can contain: 175 | - $Settings["where_additions"]: Specific where statement. Array() for mongo. Example: Birtday = "1984-08-27" 176 | - $Settings["SQL_Override"]: normally, DAVE wants to only view a single row, and will error unless that row can be defined properly with unique values. set this true to bypass these checks, and view many rows at once 177 | - $Settings["UpperLimit"]: used for LIMIT statement. Defaults to 100 178 | - $Settings["LowerLimit"]: used for LIMIT statement. Defaults to 0 179 | */ 180 | function _VIEW($Table, $VARS = null, $Settings = null ) 181 | { 182 | Global $TABLES, $DBOBJ, $Connection, $PARAMS; 183 | if ($VARS == null){$VARS = $PARAMS;} 184 | 185 | // Additonal _VIEW Options and Configurations 186 | if ($Settings == null){ $Settings = array(); } 187 | $where_additions = $Settings["where_additions"]; 188 | $UpperLimit = $Settings["UpperLimit"]; 189 | $LowerLimit = $Settings["LowerLimit"]; 190 | $SQL_Override = $Settings["SQL_Override"]; 191 | 192 | if ($UpperLimit == ""){$UpperLimit = $PARAMS["UpperLimit"];} 193 | if ($LowerLimit == ""){$LowerLimit = $PARAMS["LowerLimit"];} 194 | 195 | $UniqueVars = _getUniqueTableVars($Table); 196 | $attrs = array(); 197 | $NeedAnd = false; 198 | if (strlen($VARS[$TABLES[$Table]['META']['KEY']]) > 0) // if the primary key is given, use JUST this 199 | { 200 | $attrs[$TABLES[$Table]['META']['KEY']] = new MongoID($VARS[$TABLES[$Table]['META']['KEY']]); 201 | $NeedAnd = true; 202 | } 203 | else 204 | { 205 | foreach($VARS as $var => $val) 206 | { 207 | if (strlen($val) > 0 && in_array($var,$UniqueVars)) 208 | { 209 | $attrs[$var] = $val; 210 | $NeedAnd = true; 211 | } 212 | } 213 | if ($NeedAnd == false) 214 | { 215 | foreach($VARS as $var => $val) 216 | { 217 | if (strlen($val) > 0) 218 | { 219 | $attrs[$var] = $val; 220 | } 221 | } 222 | } 223 | } 224 | if (count($where_additions) > 0) 225 | { 226 | foreach($where_additions as $var=>$val) 227 | { 228 | $attrs[$var] = $val; 229 | } 230 | $NeedAnd = true; 231 | } 232 | if($NeedAnd == false && $SQL_Override != true) 233 | { 234 | $msg = "You have supplied none of the required parameters for this Action. At least one of the following is required: "; 235 | foreach($UniqueVars as $var) 236 | { 237 | $msg .= $var." "; 238 | } 239 | return array(false,$msg); 240 | } 241 | if ($UpperLimit < $LowerLimit) { return array(false,"UpperLimit must be greater than LowerLimit"); } 242 | $limit = null; 243 | $skip = null; 244 | if ($UpperLimit != "" && $LowerLimit != "") 245 | { 246 | $skip = (int)$LowerLimit; 247 | $limit = (int)$UpperLimit - (int)$LowerLimit; 248 | } 249 | // 250 | $Status = $DBOBJ->GetStatus(); 251 | if ($Status === true) 252 | { 253 | $MongoDB = $DBOBJ->GetMongoDB(); 254 | $Collection = $MongoDB->$Table; 255 | 256 | $cursor = $Collection->find($attrs)->skip($skip)->limit($limit); 257 | $results = array(); 258 | foreach($cursor as $obj) 259 | { 260 | $results[] = $obj; 261 | } 262 | return array(true, $results); 263 | } 264 | else { return array(false,$Status); } 265 | } 266 | 267 | /***********************************************/ 268 | 269 | /* 270 | Table should be defned in $TABLES 271 | $VARS will be the params of the row to be added. If unspecified, $PARAMS is used by default) 272 | */ 273 | function _DELETE($Table, $VARS = null) 274 | { 275 | Global $TABLES, $DBOBJ, $Connection, $PARAMS; 276 | 277 | if ($VARS == null){$VARS = $PARAMS;} 278 | 279 | $MongoDB = $DBOBJ->GetMongoDB(); 280 | $Collection = $MongoDB->$Table; 281 | 282 | $UniqueVars = _getUniqueTableVars($Table); 283 | $attrs = array(); 284 | $NeedAnd = false; 285 | foreach($VARS as $var => $val) 286 | { 287 | if($var == $TABLES[$Table]['META']['KEY']) 288 | { 289 | $attrs[$TABLES[$Table]['META']['KEY']] = new MongoID($VARS[$TABLES[$Table]['META']['KEY']]); 290 | $NeedAnd = true; 291 | } 292 | elseif (in_array($var, $UniqueVars) && strlen($val) > 0) 293 | { 294 | $attrs[$var] = $val; 295 | $NeedAnd = true; 296 | } 297 | } 298 | if($NeedAnd == false) 299 | { 300 | $msg = "You have supplied none of the required parameters to make this delete. At least one of the following is required: "; 301 | foreach($UniqueVars as $var) 302 | { 303 | $msg .= $var." "; 304 | } 305 | return array(false,$msg); 306 | } 307 | 308 | $Status = $DBOBJ->GetStatus(); 309 | if ($Status === true) 310 | { 311 | $count = $Collection->count($attrs); 312 | if ($count > 1) 313 | { 314 | return array(false,"More than one item matches these parameters. Only one row can be deleted at a time."); 315 | } 316 | elseif($count < 1) { return array(false,"The item you are requesting to delete is not found"); } 317 | 318 | $resp = $Collection->remove($attrs); 319 | if ($resp === true){ return array(true, true); } 320 | else{ return array(false,$resp); } 321 | } 322 | else {return array(false,$Status); } 323 | 324 | } 325 | 326 | ?> -------------------------------------------------------------------------------- /API/DB/DRIVERS/MONGO/DirectDBFunctions.php: -------------------------------------------------------------------------------- 1 | "'.date('Y-m-d H:i:s',time()-(60*60)).'") ;'; 30 | */ 31 | function _GetAPIRequestsCount() 32 | { 33 | global $IP, $CONFIG, $DBOBJ; 34 | 35 | $Status = $DBOBJ->GetStatus(); 36 | if($Status === true) 37 | { 38 | $Connection = $DBOBJ->GetConnection(); 39 | $LogsDB = $Connection->$CONFIG['LOG_DB']; 40 | $Logs = $LogsDB->$CONFIG['LogTable']; 41 | $count = $Logs->count(array( 42 | 'IP' => $IP, 43 | 'TimeStamp' => array('$gt' => date('Y-m-d H:i:s',time()-(60*60))) 44 | )); 45 | return $count; 46 | } 47 | else{ return $Status; } 48 | } 49 | 50 | /* 51 | I insert a record for an API requset for a given $IP, and log important information: 52 | - Action 53 | - APIKey 54 | - DeveloperID 55 | - ERROR 56 | - IP 57 | - Params (JSON or PHP-serailized hash) 58 | 59 | $SQL= 'INSERT INTO `'.$CONFIG['LOG_DB'].'`.`'.$CONFIG['LogTable'].'` (`Action`, `APIKey`, `DeveloperID`, `ERROR`, `IP`, `Params`) VALUES ("'.mysql_real_escape_string($PARAMS["Action"],$Connection).'", "'.mysql_real_escape_string($PARAMS["APIKey"],$Connection).'", "'.mysql_real_escape_string($PARAMS["DeveloperID"],$Connection).'", "'.mysql_real_escape_string($ERROR,$Connection).'", "'.mysql_real_escape_string($IP,$Connection).'" , "'.mysql_real_escape_string(json_encode($PARAMS),$Connection).'");'; 60 | */ 61 | function _LogAPIRequest() 62 | { 63 | global $CONFIG, $PARAMS, $DBOBJ, $IP; 64 | if (count($CONFIG) > 0) 65 | { 66 | $Status = $DBOBJ->GetStatus(); 67 | if($Status === true) 68 | { 69 | $Connection = $DBOBJ->GetConnection(); 70 | $LogsDB = $Connection->$CONFIG['LOG_DB']; 71 | $Logs = $LogsDB->$CONFIG['LogTable']; 72 | $log = array( 73 | "Action" => $PARAMS["Action"], 74 | "APIKey" => $PARAMS["APIKey"], 75 | "DeveloperID" => $PARAMS["DeveloperID"], 76 | "ERROR" => $ERROR, 77 | "IP" => $IP, 78 | "Params" => json_encode($PARAMS), 79 | "TimeStamp" => date('Y-m-d H:i:s',time()) 80 | ); 81 | return $Logs->insert($log); 82 | } 83 | else{ return $Status; } 84 | } 85 | else{ return false; } 86 | } 87 | 88 | /* 89 | I am the DB-based method of storing CACHE objects. I will be used in definitions found in CACHE.php 90 | */ 91 | function _DBSetCache($Key, $Value, $ThisCacheTime = null) 92 | { 93 | global $CONFIG, $DBOBJ; 94 | if ($ThisCacheTime == null) { $ThisCacheTime = $CONFIG['CacheTime']; } 95 | 96 | $ExpireTime = time() + $ThisCacheTime; 97 | 98 | $Status = $DBOBJ->GetStatus(); 99 | if($Status === true) 100 | { 101 | $MongoDB = $DBOBJ->GetMongoDB(); 102 | $Caches = $MongoDB->$CONFIG['CacheTable']; 103 | $entry = array( 104 | "Key" => $Key, 105 | "Value" => $Value, 106 | "ExpireTime" => $ExpireTime 107 | ); 108 | return $Caches->insert($entry); 109 | } 110 | else{ return false; } 111 | } 112 | 113 | /* 114 | I am the DB-based method of getting back CACHE objects. I will be used in definitions found in CACHE.php 115 | */ 116 | function _DBGetCache($Key) 117 | { 118 | global $CONFIG, $DBOBJ; 119 | 120 | $Status = $DBOBJ->GetStatus(); 121 | if($Status === true) 122 | { 123 | $MongoDB = $DBOBJ->GetMongoDB(); 124 | $Caches = $MongoDB->$CONFIG['CacheTable']; 125 | $cursor = $Caches->find(array( 126 | 'Key' => $Key, 127 | 'ExpireTime' => array('$gt' => time()) 128 | )); 129 | $newest_obj = array("ExpireTime" => 0); 130 | foreach ($cursor as $obj) 131 | { 132 | if ($obj['ExpireTime'] > $newest_obj["ExpireTime"]) 133 | { 134 | $newest_obj = $obj; 135 | } 136 | } 137 | 138 | return $newest_obj['Value']; 139 | } 140 | else{ return $Status; } 141 | } 142 | 143 | /* 144 | If your database type supports it, start a transaction for this connection 145 | */ 146 | function _StartTransaction() 147 | { 148 | return true; 149 | } 150 | 151 | /* 152 | I create a restorable copy of the entire working database. This may be the creation of "backup" tables, a file-based dump of the database, etc. This backup will be restored with RestoreDBSveState. This backup should leave the current state of the data and schema (if applicable) available in the "normal" tables, as well as copy it to the backup. For mySQL, we create backup tables denoted with ~~ before the table name. 153 | */ 154 | function _CreateDBSaveState($PARAMS = array()) 155 | { 156 | global $CONFIG, $TABLES, $DBOBJ; 157 | 158 | reload_tables(); 159 | $MongoDB = $DBOBJ->GetMongoDB(); 160 | 161 | $output = array(); 162 | $TablesToSave = array(); 163 | if (strlen($PARAMS['table']) > 0) 164 | { 165 | $TablesToSave[] = $PARAMS['table']; 166 | } 167 | else 168 | { 169 | $list = $MongoDB->listCollections(); 170 | $TableList = array(); 171 | foreach ($list as $sub) 172 | { 173 | $name = $sub->getName(); 174 | if ($name != "cache" && $name != "log" && substr($name,0,2) != "~~") { $TablesToSave[] = $name; } 175 | } 176 | } 177 | 178 | foreach($TablesToSave as $table) 179 | { 180 | $Status = $DBOBJ->GetStatus(); 181 | if ($Status === true) 182 | { 183 | $Connection = $DBOBJ->GetConnection(); 184 | $adminMongoDB = $Connection->admin; //connect to admin DB to force authentication 185 | 186 | $output[] = "saving `".$table."` to `~~".$table."`"; 187 | $oldName = "~~".$table; 188 | $MongoDB->$oldName->drop(); 189 | $adminMongoDB->command(array( "renameCollection" => $CONFIG["DB"].".".$table, "to" => $CONFIG["DB"].".".$oldName )); 190 | } 191 | else 192 | { 193 | $output[] = "DB Error: ".$Status; 194 | break; 195 | } 196 | } 197 | 198 | return $output; 199 | } 200 | 201 | /* 202 | I restore a copy of the entire working database (creted with CreateDBSaveState). I will erase any modifications (D's,A's,V's, or E's) since the backup state was created. For mySQL, we look for any tables with the ~~ name indicating that they are a backup. We then drop the existing table, and rename the backup. 203 | */ 204 | function _RestoreDBSaveState($PARAMS = array()) 205 | { 206 | global $CONFIG, $TABLES, $DBOBJ; 207 | 208 | reload_tables(); 209 | $MongoDB = $DBOBJ->GetMongoDB(); 210 | 211 | $output = array(); 212 | $TablesToRestore = array(); 213 | if (strlen($PARAMS['table']) > 0) 214 | { 215 | $TablesToRestore[] = "~~".$PARAMS['table']; 216 | } 217 | else 218 | { 219 | $list = $MongoDB->listCollections(); 220 | $TableList = array(); 221 | foreach ($list as $sub) 222 | { 223 | $name = $sub->getName(); 224 | if ($name != "cache" && $name != "log" && substr($name,0,2) == "~~") { $TablesToRestore[] = $name; } 225 | } 226 | } 227 | 228 | foreach($TablesToRestore as $table) 229 | { 230 | $Status = $DBOBJ->GetStatus(); 231 | if ($Status === true) 232 | { 233 | $Connection = $DBOBJ->GetConnection(); 234 | $adminMongoDB = $Connection->admin; //connect to admin DB to force authentication 235 | 236 | $output[] = "restoring `".$table."` to `".substr($table,2)."`"; 237 | $origName = substr($table,2); 238 | $MongoDB->$origName->drop(); 239 | $adminMongoDB->command(array( "renameCollection" => $CONFIG["DB"].".".$table, "to" => $CONFIG["DB"].".".$origName )); 240 | $MongoDB->$table->drop(); 241 | } 242 | else 243 | { 244 | $output[] = "DB Error: ".$Status; 245 | break; 246 | } 247 | } 248 | 249 | return $output; 250 | } 251 | 252 | /* 253 | I will clear out all rows/objects from a table. I will also reset any auto-incrament counters to 0. In mySQL, this is the truncate command. 254 | */ 255 | function _TruncateTable($PARAMS = array()) 256 | { 257 | global $CONFIG, $DBOBJ; 258 | 259 | $resp = ""; 260 | $stop = false; 261 | if (strlen($PARAMS['table']) == 0) 262 | { 263 | $resp = 'Provide a table name with --table'; 264 | $stop = true; 265 | } 266 | 267 | if (strlen($PARAMS['DB']) > 0) 268 | { 269 | $ThisDB = $PARAMS['DB']; 270 | } 271 | else 272 | { 273 | $ThisDB = $CONFIG['DB']; 274 | } 275 | 276 | $Status = $DBOBJ->GetStatus(); 277 | if ($stop == false && !($Status === true)) 278 | { 279 | $resp = "DB Error: ".$Status; 280 | $stop = true; 281 | } 282 | 283 | if ($stop == false) 284 | { 285 | $Connection = $DBOBJ->GetConnection(); 286 | $MongoDB = $Connection->$ThisDB; 287 | $Collection = $MongoDB->$PARAMS['table']; 288 | $FIND = array(); 289 | $count = $Collection->count($FIND); 290 | $Collection->remove($FIND); 291 | $resp = $PARAMS['table']." table truncated from the ".$ThisDB." DB"; 292 | } 293 | return $resp; 294 | } 295 | 296 | /* 297 | I will remove old sessions from the sessions table 298 | */ 299 | function _CleanSessions($PARAMS = array()) 300 | { 301 | global $CONFIG, $DBOBJ; 302 | $stop = false; 303 | $resp = ""; 304 | 305 | $Status = $DBOBJ->GetStatus(); 306 | if ($stop == false && !($Status === true)) 307 | { 308 | $resp = "DB Error: ".$Status; 309 | $stop = true; 310 | } 311 | 312 | if ($stop == false) 313 | { 314 | $MongoDB = $DBOBJ->GetMongoDB(); 315 | $Sessions = $MongoDB->sessions; 316 | $FIND = array("created_at" => array('$lt' => date('Y-m-d H:i:s',(time() - $CONFIG['SessionAge'])))); 317 | $count = $Sessions->count($FIND); 318 | $Sessions->remove($FIND); 319 | $resp = 'Deleted '.$count." entries from the sessions DB"; 320 | } 321 | else 322 | { 323 | $resp = "cannot connect to DB"; 324 | } 325 | return $resp; 326 | } 327 | 328 | /* 329 | I will remove old log entries from the log table/db 330 | */ 331 | function _CleanLog() 332 | { 333 | global $CONFIG, $DBOBJ; 334 | $stop = false; 335 | $resp = ""; 336 | 337 | $Status = $DBOBJ->GetStatus(); 338 | if ($stop == false && !($Status === true)) 339 | { 340 | $resp = "DB Error: ".$Status; 341 | $stop = true; 342 | } 343 | 344 | if ($stop == false) 345 | { 346 | $Connection = $DBOBJ->GetConnection(); 347 | $LogsDB = $Connection->$CONFIG['LOG_DB']; 348 | $Logs = $LogsDB->$CONFIG['LogTable']; 349 | $FIND = array("TimeStamp" => array('$lt' => date('Y-m-d H:i:s',(time() - $CONFIG['LogAge'])))); 350 | $count = $Logs->count($FIND); 351 | $Logs->remove($FIND); 352 | $resp = 'Deleted '.$count." entries from ".$CONFIG['LOG_DB'].".".$CONFIG['LogTable']; 353 | } 354 | else 355 | { 356 | $resp = "cannot connect to ".$CONFIG['LOG_DB'].".".$CONFIG['LogTable']; 357 | } 358 | return $resp; 359 | } 360 | 361 | /* 362 | I will remove old log entries from the log table/db 363 | */ 364 | function _CleanCache() 365 | { 366 | global $CONFIG, $DBOBJ; 367 | $stop = false; 368 | $resp = ""; 369 | 370 | $Status = $DBOBJ->GetStatus(); 371 | if ($stop == false && !($Status === true)) 372 | { 373 | $resp = "DB Error: ".$Status; 374 | $stop = true; 375 | } 376 | 377 | if ($stop == false) 378 | { 379 | $MongoDB = $DBOBJ->GetMongoDB(); 380 | $Caches = $MongoDB->$CONFIG['CacheTable']; 381 | $FIND = array("ExpireTime" => array('$lt' => (time() - $CONFIG['CacheTime']))); 382 | $count = $Caches->count($FIND); 383 | $Caches->remove($FIND); 384 | $resp = 'Deleted '.$count." entries from the CACHE DB"; 385 | } 386 | else 387 | { 388 | $resp = "cannot connect to DB"; 389 | } 390 | return $resp; 391 | } 392 | 393 | function _CountRowsInTable($Table) 394 | { 395 | global $CONFIG, $DBOBJ; 396 | 397 | if ($DBOBJ->GetStatus() != true){return false;} 398 | 399 | $MongoDB = $DBOBJ->GetMongoDB(); 400 | $Colleciton = $MongoDB->$Table; 401 | return $Colleciton->count(); 402 | } 403 | 404 | function _FindDBMaxValue($Table, $col) 405 | { 406 | global $CONFIG, $DBOBJ; 407 | 408 | if ($DBOBJ->GetStatus() != true){return false;} 409 | 410 | $MongoDB = $DBOBJ->GetMongoDB(); 411 | $Colleciton = $MongoDB->$Table; 412 | $object = $Colleciton->find()->sort(array($col),-1)->limit(1); 413 | if(!empty($object[$col])){ 414 | return $object[$col]; 415 | } 416 | else 417 | { 418 | return false; 419 | } 420 | } 421 | 422 | function _FindDBMinValue($Table, $col) 423 | { 424 | global $CONFIG, $DBOBJ; 425 | 426 | $MongoDB = $DBOBJ->GetMongoDB(); 427 | $Colleciton = $MongoDB->$Table; 428 | $object = $Colleciton->find()->sort(array($col),1)->limit(1); 429 | if(!empty($object[$col])){ 430 | return $object[$col]; 431 | } 432 | else 433 | { 434 | return false; 435 | } 436 | } 437 | 438 | ?> -------------------------------------------------------------------------------- /API/DB/DRIVERS/MONGO/TableConfig.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/DB/DRIVERS/MONGO/init.php: -------------------------------------------------------------------------------- 1 | GetStatus(); 22 | if ($Status === true) 23 | { 24 | $Connection = $DBOBJ->GetConnection(); 25 | // require_once($_driver_db_path."TableConfig.php"); 26 | require_once($CONFIG['TableConfigFile']); 27 | require_once($_driver_db_path."DAVE.php"); 28 | } 29 | else 30 | { 31 | $ERROR = "DB Cannot be reached: ".$Status; 32 | } 33 | } 34 | else 35 | { 36 | $ERROR = "DB Config Error: No Class"; 37 | } 38 | 39 | ?> -------------------------------------------------------------------------------- /API/DB/DRIVERS/MYSQL/ConnectToDatabase.php: -------------------------------------------------------------------------------- 1 | Status 14 | - mysql_log(): Will log "queries" to file 15 | - CheckForSpecialStrings(): Will inspect queries for special strings ($CONFIG['SpecialStrings']) and replace. This is to fix situations where user might post "0" as input, etc 16 | - query(): preforms the DB operation 17 | - Returns true on sucess 18 | - Returns false on failure, logs error to $This->Status 19 | - GetLastInsert(): returns the auto incramanet ID of the row added 20 | - NumRowsEffected(): returns a count of the rows effected by the "Edit" command 21 | - GetConnection(): returns the connction object if applicable 22 | - GetStatus(): returns the last status message 23 | - GetResults(): returns the result of the last query() 24 | - close(): closes the DB connection 25 | 26 | ////////////// 27 | 28 | Example useage: 29 | 30 | $DBOBJ = new DBConnection(); 31 | $Status = $DBOBJ->GetStatus(); 32 | if ($Status === true) 33 | { 34 | $DBOBJ->Query($SQL); 35 | $Status = $DBOBJ->GetStatus(); 36 | if ($Status === true){ 37 | $Results = $DBOBJ->GetResults(); 38 | // Do stuff with the $Results array 39 | } 40 | else{ $ERROR = $Status; } 41 | } 42 | else { $ERROR = $Status; } 43 | $DBOBJ->close(); 44 | 45 | use the GetLastInsert() function to get the deatils of an entry you just added. 46 | 47 | ***********************************************/ 48 | 49 | class DBConnection 50 | { 51 | protected $Connection, $Status, $OUT, $DataBase; 52 | 53 | public function __construct($OtherDB = "") 54 | { 55 | global $CONFIG; 56 | $this->Status = true; 57 | 58 | if ($OtherDB != "") { $this->DataBase = $OtherDB ; } 59 | else { $this->DataBase = $CONFIG['DB']; } 60 | $this->Connection = @mysql_connect($CONFIG['dbhost'], $CONFIG['dbuser'], $CONFIG['dbpass']); 61 | if(!empty($this->Connection)) 62 | { 63 | $DatabaseSelected=mysql_select_db($this->DataBase); 64 | if (!empty($DatabaseSelected)) 65 | { 66 | return true; 67 | } 68 | else 69 | { 70 | $this->Status = "Database Selection Error (mySQL) | ".mysql_errno($this->Connection) . ": " . mysql_error($this->Connection); 71 | return false; 72 | } 73 | } 74 | else 75 | { 76 | $this->Status = "Connection Error (mySQL) | Connection Access or permission error"; 77 | return false; 78 | } 79 | } 80 | 81 | private function mysql_log($line) 82 | { 83 | global $IP, $CONFIG; 84 | 85 | $host = $IP; 86 | if ($host == ""){$host = "local_system";} 87 | 88 | $line = date("Y-m-d H:i:s")." | ".$host." | ".$line; 89 | if (strlen($CONFIG['DBLogFile']) > 0) 90 | { 91 | $LogFileHandle = fopen($CONFIG['DBLogFile'], 'a'); 92 | if($LogFileHandle) 93 | { 94 | fwrite($LogFileHandle, ($line."\r\n")); 95 | } 96 | fclose($LogFileHandle); 97 | } 98 | } 99 | 100 | private function CheckForSpecialStrings($string) 101 | { 102 | global $CONFIG; 103 | foreach ($CONFIG['SpecialStrings'] as $term) 104 | { 105 | $string = str_replace($term[0],$term[1],$string); 106 | } 107 | $string = str_replace(" "," ",$string); 108 | return $string; 109 | } 110 | 111 | public function Query($SQL) 112 | { 113 | if($this->Status != true) 114 | { 115 | return false; 116 | } 117 | elseif(strlen($SQL) < 1) 118 | { 119 | return false; 120 | } 121 | else 122 | { 123 | $SQL = $this->CheckForSpecialStrings($SQL); 124 | $LogLine = $SQL; 125 | $Query=mysql_query($SQL); 126 | if (empty($Query)) 127 | { 128 | $this->Status = "MYSQL Query Error: ".mysql_errno($this->Connection) . ": " . mysql_error($this->Connection); 129 | $LogLine .= " | Error->".$this->Status; 130 | $this->mysql_log($LogLine); 131 | return false; 132 | } 133 | else 134 | { 135 | $this->OUT = array(); 136 | $tmp = array(); 137 | $NumRows = 0; 138 | if(is_resource($Query)){ $NumRows = mysql_num_rows($Query); } 139 | 140 | if ($NumRows > 0){ $LogLine .= " | RowsFond -> ".$NumRows; } 141 | elseif($this->NumRowsEffected > 0){ $LogLine .= " | RowsEffected -> ".$this->NumRowsEffected; } 142 | if ($this->GetLastInsert > 0){ $LogLine .= " | InsertID -> ".$this->GetLastInsert; } 143 | 144 | $this->mysql_log($LogLine); 145 | if ($NumRows > 0) 146 | { 147 | while($row = mysql_fetch_assoc($Query)) 148 | { 149 | $tmp[] = $row; 150 | } 151 | $this->OUT = $tmp; 152 | unset($tmp); 153 | return true; 154 | } 155 | else 156 | { 157 | return true; // it worked, but there is no data retruned. Perhaps this wasn't a SELECT 158 | } 159 | } 160 | } 161 | } 162 | 163 | public function GetLastInsert() 164 | { 165 | return mysql_insert_id($this->Connection); 166 | } 167 | 168 | public function NumRowsEffected() 169 | { 170 | return mysql_affected_rows($this->Connection); 171 | } 172 | 173 | public function GetConnection() 174 | { 175 | return $this->Connection; 176 | } 177 | 178 | public function GetStatus() 179 | { 180 | return $this->Status; 181 | } 182 | 183 | public function GetResults() 184 | { 185 | return $this->OUT; 186 | } 187 | 188 | public function close() 189 | { 190 | @mysql_close($this->Connection); 191 | $this->Status = "Disconnected. (mySQL)"; 192 | } 193 | } 194 | 195 | ?> -------------------------------------------------------------------------------- /API/DB/DRIVERS/MYSQL/TableConfig.php: -------------------------------------------------------------------------------- 1 | 0) 24 | { 25 | if ($TableBuildTime + $CONFIG['TableConfigRefreshTime'] < time()) { 26 | $ToReloadTables = true; 27 | $TABLES = array(); // clear it, just to be safe 28 | } 29 | } 30 | } 31 | } 32 | 33 | if ($ToReloadTables) 34 | { 35 | $OUTPUT["TableRelaod"] = "true"; 36 | $Status = $DBOBJ->GetStatus(); 37 | if ($Status === true) 38 | { 39 | $SQL= 'SHOW TABLES;'; 40 | $DBOBJ->Query($SQL); 41 | $out = $DBOBJ->GetResults(); 42 | $TableList = array(); 43 | foreach ($out as $sub){ 44 | $name = $sub["Tables_in_".$CONFIG['DB']]; 45 | if ($name != "cache" && $name != "log") { $TableList[] = $name; } 46 | } 47 | foreach ($TableList as $ThisTable) 48 | { 49 | $SQL= 'DESCRIBE `'.$CONFIG['DB'].'`.`'.$ThisTable.'`;'; 50 | $DBOBJ->Query($SQL); 51 | $Response = $DBOBJ->GetResults(); 52 | foreach ($Response as $col) 53 | { 54 | if ($col['Key'] == "PRI") 55 | { 56 | $TABLES[$ThisTable]['META']['KEY'] = $col['Field']; 57 | } 58 | $is_unique = false; 59 | $is_required = false; 60 | if ($col['Key'] == "UNI" || $col['Key'] == "PRI") { $is_unique = true; } 61 | if ($col['Null'] == "NO") { $is_required = true; } 62 | $TABLES[$ThisTable][] = array($col['Field'],$is_unique,$is_required); 63 | } 64 | } 65 | } 66 | $TABLES["TableBuildTime"] = time(); 67 | @unlink($CONFIG['TableConfigFile']); 68 | $TableStringOutput = ""; 69 | $TableStringOutput .= ""; 99 | 100 | $fh = fopen($CONFIG['TableConfigFile'], 'w'); 101 | fwrite($fh, $TableStringOutput); 102 | fclose($fh); 103 | chmod($CONFIG['TableConfigFile'],0777); 104 | 105 | unset($TABLES["TableBuildTime"]); 106 | } 107 | else 108 | { 109 | $OUTPUT["TableRelaod"] = "false"; 110 | } 111 | 112 | ?> -------------------------------------------------------------------------------- /API/DB/DRIVERS/MYSQL/init.php: -------------------------------------------------------------------------------- 1 | GetStatus(); 19 | if ($Status === true) 20 | { 21 | $Connection = $DBOBJ->GetConnection(); 22 | require_once($_driver_db_path."TableConfig.php"); 23 | require_once($_driver_db_path."DAVE.php"); 24 | } 25 | else 26 | { 27 | $ERROR = "DB Cannot be reached: ".$Status; 28 | } 29 | } 30 | else 31 | { 32 | $ERROR = "DB Config Error: No Class"; 33 | } 34 | 35 | ?> -------------------------------------------------------------------------------- /API/DB/SCHEMA.php.example.mongo: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/DB/SCHEMA.php.example.mySQL: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/GetPostVars.php: -------------------------------------------------------------------------------- 1 | 0) 35 | { 36 | $TableNames = array_keys($TABLES); 37 | while ($i < count($TABLES)) 38 | { 39 | $j = 0; 40 | while ($j < count($TABLES[$TableNames[$i]])) 41 | { 42 | $POST_VARIABLES[] = $TABLES[$TableNames[$i]][$j][0]; 43 | $j++; 44 | } 45 | $i++; 46 | } 47 | } 48 | 49 | // Use "REQUEST" so that both POST and GET will work, along with cookie data 50 | foreach($POST_VARIABLES as $var) 51 | { 52 | $value = _CleanPostVariableInput($_REQUEST[$var],$Connection); 53 | if ($value) { 54 | // $$var = $value; 55 | $PARAMS[$var] = $value; 56 | } 57 | } 58 | 59 | // Special Checks 60 | if ($PARAMS["Rand"] == "") { $PARAMS["Rand"] = _CleanPostVariableInput($_REQUEST['Rand'],$Connection); } 61 | if ($PARAMS["Rand"] == "") { $PARAMS["Rand"] = _CleanPostVariableInput($_REQUEST['rand'],$Connection); } 62 | if ($PARAMS["Hash"] == "") { $PARAMS["Hash"] = _CleanPostVariableInput($_REQUEST['Hash'],$Connection); } 63 | if ($PARAMS["Hash"] == "") { $PARAMS["Hash"] = _CleanPostVariableInput($_REQUEST['hash'],$Connection); } 64 | if ($PARAMS["Hash"] == "" && $PARAMS["DeveloperID"] != "" && $PARAMS["Rand"] != "") 65 | { 66 | $PARAMS["Hash"] = md5($PARAMS["DeveloperID"].$PARAMS["APIKey"].$PARAMS["Rand"]); 67 | } 68 | if ($PARAMS["Rand"] == ""){unset($PARAMS["Rand"]);} 69 | if ($PARAMS["Hash"] == ""){unset($PARAMS["Hash"]);} 70 | 71 | // do a doubles check on the uniqueness of POST_VARIABLES 72 | $POST_VARIABLES = array_unique($POST_VARIABLES); 73 | 74 | ///////////////////////////////////////////////////////////////////////////////////////////////// 75 | 76 | function _CleanPostVariableInput($string,$Connection=null) 77 | { 78 | if (is_resource($Connection) == true && get_resource_type($Connection) == "mysql link"){ $string = mysql_real_escape_string($string,$Connection); } 79 | else{ $string = addslashes($string); } 80 | $replace = ""; 81 | 82 | $search = array( 83 | '@]*?>.*?@si', // Strip out javascript 84 | '@<[\/\!]*?[^<>]*?>@si', // Strip out HTML tags 85 | '@]*?>.*?@siU', // Strip style tags properly 86 | ); 87 | $string = preg_replace($search, $replace, $string); 88 | $string = str_replace("<","(",$string); 89 | $string = str_replace(">",")",$string); 90 | $string = str_replace("¨"," ",$string); 91 | $string = iconv('UTF-8', 'ISO-8859-1//TRANSLIT//IGNORE', $string); 92 | $string = htmlspecialchars($string, ENT_QUOTES); 93 | $string = htmlentities($string, ENT_QUOTES); 94 | 95 | return $string; 96 | } 97 | 98 | ?> -------------------------------------------------------------------------------- /API/LoadEnv.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/Objects/User.php: -------------------------------------------------------------------------------- 1 | DATA["EMail"]) > 0) 15 | { 16 | $func_out = validate_EMail($this->DATA["EMail"]); 17 | if ($func_out != 100){ return $func_out; } 18 | } 19 | 20 | if (strlen($this->DATA["PhoneNumber"]) > 0) 21 | { 22 | list($fun_out, $this->DATA["PhoneNumber"]) = validate_PhoneNumber($this->DATA["PhoneNumber"]); 23 | if ($func_out != 100){ return $func_out; } 24 | } 25 | 26 | if (strlen($this->DATA["Password"]) > 0) 27 | { 28 | $this->DATA["Salt"] = md5(rand(1,999).(microtime()/rand(1,999)).rand(1,999)); 29 | $this->DATA["PasswordHash"] = md5($this->DATA["Password"].$this->DATA["Salt"]); 30 | return true; 31 | } 32 | else { return "Please provide a Password"; } 33 | } 34 | } 35 | 36 | ?> -------------------------------------------------------------------------------- /API/Objects/_BASE.php: -------------------------------------------------------------------------------- 1 | Status = false; 19 | $this->Columns = array(); 20 | if(count($TABLES[$Table]) > 0) 21 | { 22 | $this->Columns = $TABLES[$Table]; 23 | $this->Table = $Table; 24 | $this->Status = true; 25 | return $this->Status; 26 | } 27 | else 28 | { 29 | return $this->Status; 30 | } 31 | } 32 | 33 | public function status() 34 | { 35 | return $this->Status; 36 | } 37 | 38 | public function table() 39 | { 40 | if (!$this->Status){return false;} 41 | return $this->Table; 42 | } 43 | 44 | public function columns() 45 | { 46 | if (!$this->Status){return false;} 47 | return $this->Columns; 48 | } 49 | 50 | public function column_names() 51 | { 52 | if (!$this->Status){return false;} 53 | $out = array(); 54 | foreach ($this->Columns as $Cols) 55 | { 56 | if (strlen($Cols[0]) > 0) 57 | { 58 | $out[] = $Cols[0]; 59 | } 60 | } 61 | return $out; 62 | } 63 | 64 | public function all() 65 | { 66 | if (!$this->Status){return false;} 67 | return $this->find(null, $Conditions); 68 | } 69 | 70 | public function maximum($col) 71 | { 72 | return _FindDBMaxValue($this->Table, $col); //A DiretDBFunction from DRIVER 73 | } 74 | 75 | public function minimum($col) 76 | { 77 | return _FindDBMinValue($this->Table, $col); //A DiretDBFunction from DRIVER 78 | } 79 | 80 | public function count() 81 | { 82 | return _CountRowsInTable($this->Table); //A DiretDBFunction from DRIVER 83 | } 84 | 85 | public function find($Params = null, $Conditions = null) 86 | { 87 | if (!$this->Status){return false;} 88 | 89 | if($Conditions == null){$Conditions = array();} 90 | if($Params == null){$Params = array();} 91 | 92 | $Conditions["SQL_Override"] = true; 93 | $Conditions["UpperLimit"] = 4294967296; //32-bit max 94 | $Conditions["LowerLimit"] = 0; 95 | 96 | $results = _VIEW($this->Table, $Params, $Conditions); 97 | if (count($results[1]) > 0 && is_array($results[1])){ 98 | $objs = array(); 99 | foreach ($results[1] as $row) 100 | { 101 | $this_obj = new DaveRowObject($this, $row); 102 | $objs[] = $this_obj; 103 | } 104 | return $objs; 105 | } 106 | elseif(is_string($results[1])) 107 | { 108 | $this->Status = $results[1]; 109 | return false; // indicates a selection error 110 | } 111 | else 112 | { 113 | return array(); // empty array rather than false indicates no found, but query was OK 114 | } 115 | } 116 | 117 | } 118 | 119 | //////////////////////////////////////////////////////////////////////////////// 120 | 121 | class DaveRowObject 122 | { 123 | protected $DATA, $DaveTableObject; 124 | 125 | public function __construct($DaveTableObject,$params = null) 126 | { 127 | global $OUTPUT; 128 | $this->DATA = array(); 129 | $this->DaveTableObject = $DaveTableObject; 130 | foreach($this->DaveTableObject->column_names() as $cols) 131 | { 132 | $this->DATA[$cols] = null; 133 | } 134 | foreach($params as $k => $v) 135 | { 136 | $this->DATA[$k] = $v; 137 | } 138 | } 139 | 140 | public function __set($key, $value) 141 | { 142 | $this->DATA[$key] = $value; 143 | } 144 | 145 | public function __get($key) 146 | { 147 | if (array_key_exists($key, $this->DATA)) 148 | { 149 | return $this->DATA[$key]; 150 | } 151 | else 152 | { 153 | return false; 154 | } 155 | } 156 | 157 | public function __isset($key) 158 | { 159 | return isset($this->DATA[$key]); 160 | } 161 | 162 | public function __unset($key) 163 | { 164 | unset($this->DATA[$key]); 165 | } 166 | 167 | /////////////////////////////////////////////////// 168 | 169 | public function ADD() 170 | { 171 | $resp = _ADD($this->DaveTableObject->table(),$this->DATA); 172 | $this->DATA = $this->VIEW(); //load in generated data and remove non-col data 173 | return $resp[1]; 174 | } 175 | 176 | public function VIEW() 177 | { 178 | $resp = _VIEW($this->DaveTableObject->table(),$this->DATA); 179 | return $resp[1][0]; 180 | } 181 | 182 | public function EDIT($params = null) 183 | { 184 | if ($params != null) 185 | { 186 | foreach($params as $k => $v) 187 | { 188 | if (is_array($this->DATA) && in_array($k,array_keys($this->DATA))) 189 | { 190 | $this->DATA[$k] = $v; 191 | } 192 | } 193 | $resp = _EDIT($this->DaveTableObject->table(),$this->DATA); 194 | $this->clean_data(); 195 | if($resp[0] === true){ return $resp[1][0]; } 196 | else{return $resp[1]; } 197 | } 198 | else{return true;} 199 | } 200 | 201 | public function DELETE() 202 | { 203 | $resp = _DELETE($this->DaveTableObject->table(),$this->DATA); 204 | return $resp[1]; 205 | } 206 | 207 | public function DATA($request = null) 208 | { 209 | if ($request == null) {$request = array();} 210 | if (is_string($request)) { 211 | $single_key = $request; 212 | $request = array($single_key); 213 | } 214 | if (!is_array($request)){ return false; } 215 | 216 | if (count($request) == 0){ return $this->DATA; } 217 | else 218 | { 219 | $out = array(); 220 | foreach($request as $var) 221 | { 222 | if($this->DATA[$var] != null) 223 | { 224 | $out[$var] = $this->DATA[$var]; 225 | } 226 | if (count($out) == 1){ 227 | return $out[$single_key]; 228 | } 229 | else{ return $out; } 230 | } 231 | } 232 | } 233 | 234 | private function clean_data() 235 | { 236 | if(is_array($this->DATA)) 237 | { 238 | foreach ($this->DATA as $key => $val) 239 | { 240 | if (!in_array($key, $this->DaveTableObject->column_names())) 241 | { 242 | unset($this->DATA[$key]); 243 | } 244 | } 245 | } 246 | } 247 | } 248 | 249 | ?> -------------------------------------------------------------------------------- /API/Output.php: -------------------------------------------------------------------------------- 1 | '."\r\n"; 28 | echo '<'.$CONFIG['XML_ROOT_NODE'].'>'."\r\n"; 29 | _DepthArrayPrint($OUTPUT,1); 30 | echo ''."\r\n"; 31 | } 32 | 33 | elseif ($PARAMS["OutputType"] == "JSON") 34 | { 35 | header('content-type: application/json; charset=utf-8'); 36 | $JSON = json_encode($OUTPUT); 37 | if (strlen($PARAMS['Callback']) > 0) 38 | { 39 | echo $PARAMS['Callback']."(".$JSON.");"; 40 | } 41 | else 42 | { 43 | echo $JSON; 44 | } 45 | } 46 | 47 | elseif ($PARAMS["OutputType"] == "LINE") 48 | { 49 | echo $CONFIG['ServerName']." @ ".$CONFIG['ServerAddress']."\r\n\r\n"; 50 | _recurse_output($OUTPUT); 51 | } 52 | 53 | elseif ($PARAMS["OutputType"] == "CONSOLE") 54 | { 55 | require_once("helper_functions/colors.php"); 56 | $colors = new Colors; 57 | 58 | echo $colors->getColoredString($CONFIG['ServerName']." @ ".$CONFIG['ServerAddress']."\r\n\r\n", "green"); 59 | _recurse_output($OUTPUT, 0, true); 60 | } 61 | 62 | else 63 | { 64 | echo "I am sorry, but I do not know that OutputType. Leave OutputType blank for the default option. Options include: XML, JSON, PHP, LINE, CONSOLE, VAR\r\n"; 65 | } 66 | 67 | flush(); 68 | 69 | ////////////////////////////////////////// 70 | 71 | function _recurse_output($OUTPUT, $depth = 0, $color = false) 72 | { 73 | if ($color) { require_once("helper_functions/colors.php"); $colors = new Colors;} 74 | 75 | $i = 0; 76 | $keys = array_keys($OUTPUT); 77 | while ($i < count($OUTPUT)) 78 | { 79 | if (is_array($OUTPUT[$keys[$i]])) 80 | { 81 | $j = 0; while($j < $depth){echo " "; $j++;} 82 | if ($color) 83 | { 84 | echo $colors->getColoredString($keys[$i],"red").":\r\n"; 85 | } 86 | else 87 | { 88 | echo (string) $keys[$i].":\r\n"; 89 | } 90 | _recurse_output($OUTPUT[$keys[$i]], ($depth + 1), $color); 91 | } 92 | else 93 | { 94 | $j = 0; while($j < $depth){echo " "; $j++;} 95 | if ($color) 96 | { 97 | $out = $colors->getColoredString((string)$keys[$i],"light_red"); 98 | $out .= ": "; 99 | $out .= $colors->getColoredString((string)$OUTPUT[$keys[$i]],"blue"); 100 | $out .= "\r\n"; 101 | echo $out; 102 | } 103 | else 104 | { 105 | echo (string)$keys[$i].": ".(string)$OUTPUT[$keys[$i]]."\r\n"; 106 | } 107 | } 108 | $i++; 109 | } 110 | } 111 | 112 | function _DepthArrayPrint($Array,$depth,$container=null) 113 | { 114 | if (strlen($container) > 0) 115 | { 116 | $j = 0; 117 | while ($j < ($depth-1)) { echo "\t"; $j++; } 118 | if (is_int($container)) { $container = "item"; } 119 | echo '<'.(string)$container.'>'."\r\n"; 120 | } 121 | 122 | $i = 0; 123 | $keys = array_keys($Array); 124 | while ($i < count($Array)) 125 | { 126 | if (is_array($Array[$keys[$i]])) 127 | { 128 | _DepthArrayPrint($Array[$keys[$i]],($depth+1),$keys[$i]); 129 | } 130 | else 131 | { 132 | $j = 0; 133 | while ($j < $depth) { echo "\t"; $j++; } 134 | if (strlen($keys[$i]) > 0) 135 | { 136 | if (is_int($keys[$i])) { $this_key = $container; } else { $this_key = $keys[$i];} 137 | print "<".(string)$this_key.">".(string)$Array[$keys[$i]].""."\r\n"; 138 | } 139 | } 140 | $i++; 141 | } 142 | 143 | if (strlen($container) > 0) 144 | { 145 | $j = 0; 146 | while ($j < ($depth-1)) { echo "\t"; $j++; } 147 | if (is_int($container)) { $container = "item"; } 148 | echo ''."\r\n"; 149 | } 150 | } 151 | 152 | ?> -------------------------------------------------------------------------------- /API/TASKS.php: -------------------------------------------------------------------------------- 1 | $max_name_length) 32 | { 33 | $max_name_length = strlen($class_name); 34 | } 35 | } 36 | 37 | foreach($TaskNames as $class_name) 38 | { 39 | echo "- ".$class_name::class_name(); 40 | $i = strlen($class_name); 41 | while ($i < ($max_name_length + 4)) { echo " "; $i++; } 42 | echo $class_name::get_description(); 43 | echo "\r\n"; 44 | } 45 | exit; 46 | } 47 | 48 | // which task? 49 | $ThisTask = ($ARGS["t"]); 50 | if (strlen($ThisTask) == 0){ $ThisTask = ($ARGS["T"]); } 51 | if (strlen($ThisTask) == 0){ $ThisTask = ($ARGS["task"]); } 52 | if (strlen($ThisTask) == 0) 53 | { 54 | echo "No task provided. Please provide one with -t or --task. Use --list to show available tasks.\r\n"; 55 | exit; 56 | } 57 | else 58 | { 59 | if (in_array(($ThisTask), $TaskNames)) 60 | { 61 | echo run_task($ThisTask, $ARGS); 62 | } 63 | else 64 | { 65 | echo "That task cannot be found. Use --list to show available tasks.\r\n"; 66 | exit; 67 | } 68 | } 69 | 70 | 71 | ?> -------------------------------------------------------------------------------- /API/Tasks/CleanCache.php: -------------------------------------------------------------------------------- 1 | task_log($resp); 22 | 23 | ///////////////////////////////////////////////////////////////////////// 24 | // Check the CACHE Folder table for old entries, and remove them 25 | $files = scandir($CONFIG['CacheFolder']); 26 | $counter = 0; 27 | foreach ($files as $num => $fname) 28 | { 29 | $ThisFile = $CONFIG['CacheFolder'].$fname; 30 | if (file_exists($ThisFile) && ((time() - filemtime($ThisFile)) > $CONFIG['CacheTime']) && $fname != "." && $fname != ".." && $fname != ".svn") 31 | { 32 | unlink($ThisFile); 33 | $counter++; 34 | } 35 | } 36 | $this->task_log('Deleted '.$counter." files from the CACHE directory"); 37 | } 38 | } 39 | 40 | ?> -------------------------------------------------------------------------------- /API/Tasks/CleanLog.php: -------------------------------------------------------------------------------- 1 | task_log($resp); 18 | } 19 | } 20 | 21 | ?> -------------------------------------------------------------------------------- /API/Tasks/CleanSessions.php: -------------------------------------------------------------------------------- 1 | task_log($resp); 18 | } 19 | } 20 | 21 | ?> -------------------------------------------------------------------------------- /API/Tasks/CreateDBSaveState.php: -------------------------------------------------------------------------------- 1 | task_log($line); } 18 | } 19 | } 20 | 21 | ?> -------------------------------------------------------------------------------- /API/Tasks/RemoveLargeLogs.php: -------------------------------------------------------------------------------- 1 | task_log("checking: ".$CONFIG['LogsToCheck'][$i]." against ".$CONFIG['MaxLogFileSize']." bytes"); 23 | $bytes = @filesize($CONFIG['LogsToCheck'][$i]); 24 | if (@filesize($CONFIG['LogsToCheck'][$i]) > $CONFIG['MaxLogFileSize']) 25 | { 26 | $this->task_log(" > file size too large @ ".$bytes." bytes, removing."); 27 | unlink($CONFIG['LogsToCheck'][$i]); 28 | $fh = fopen($CONFIG['LogsToCheck'][$i], 'w'); 29 | fclose($fh); 30 | chmod($Logs[$i], 0777); 31 | $this->task_log(" > recreated with 0 bytes"); 32 | } 33 | else 34 | { 35 | $this->task_log(" > file size OK @ ".$bytes." bytes"); 36 | } 37 | $i++; 38 | } 39 | } 40 | } 41 | 42 | ?> -------------------------------------------------------------------------------- /API/Tasks/RestoreDBSaveState.php: -------------------------------------------------------------------------------- 1 | task_log($line); } 18 | } 19 | } 20 | 21 | ?> -------------------------------------------------------------------------------- /API/Tasks/TruncateTable.php: -------------------------------------------------------------------------------- 1 | task_log($resp); 18 | } 19 | } 20 | 21 | ?> -------------------------------------------------------------------------------- /API/Tasks/_BASE.php: -------------------------------------------------------------------------------- 1 | task_log('Task Complete!'); 25 | } 26 | } 27 | 28 | ***********************************************/ 29 | 30 | if (empty($TASKS)) { $TASKS = array(); } // a list of tasks to be populated by name 31 | 32 | class task 33 | { 34 | protected $DATA = array(); 35 | protected static $description = "empty"; // I will be overwritten by child 36 | 37 | public function __construct($ToRun = false, $PARAMS = array()) 38 | { 39 | if ($ToRun) 40 | { 41 | $this->run($PARAMS); // I will run automatically. BE SURE TO MAKE A run() CLASS IN YOUR task 42 | } 43 | } 44 | 45 | public function task_log($message) 46 | { 47 | $line = date("Y-m-d H:i:s")." | ".$message."\r\n"; 48 | $this->DATA["log"] .= $line; 49 | } 50 | 51 | public static function class_name() 52 | { 53 | return get_called_class(); 54 | } 55 | 56 | public static function get_description() 57 | { 58 | $ThisClass = get_called_class(); 59 | return $ThisClass::$description; 60 | } 61 | 62 | public function get_task_log() 63 | { 64 | return $this->DATA["log"]; 65 | } 66 | 67 | public function check_DBObj() 68 | { 69 | global $DBOBJ; 70 | $Status = $DBOBJ->GetStatus(); 71 | if (!($Status === true)) 72 | { 73 | $this->task_log("DB Error: ".$Status); 74 | } 75 | return $Status; 76 | } 77 | } 78 | 79 | ?> -------------------------------------------------------------------------------- /API/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /API/helper_functions/AES.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/helper_functions/CURL_POST.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/helper_functions/ValidStateZip.php: -------------------------------------------------------------------------------- 1 | array ("9950099929"), 7 | "AL" => array ("3500036999"), 8 | "AR" => array ("7160072999", "7550275505"), 9 | "AZ" => array ("8500086599"), 10 | "CA" => array ("9000096199"), 11 | "CO" => array ("8000081699"), 12 | "CT" => array ("0600006999"), 13 | "DC" => array ("2000020099", "2020020599"), 14 | "DE" => array ("1970019999"), 15 | "FL" => array ("3200033999", "3410034999"), 16 | "GA" => array ("3000031999"), 17 | "HI" => array ("9670096798", "9680096899"), 18 | "IA" => array ("5000052999"), 19 | "ID" => array ("8320083899"), 20 | "IL" => array ("6000062999"), 21 | "IN" => array ("4600047999"), 22 | "KS" => array ("6600067999"), 23 | "KY" => array ("4000042799", "4527545275"), 24 | "LA" => array ("7000071499", "7174971749"), 25 | "MA" => array ("0100002799"), 26 | "MD" => array ("2033120331", "2060021999"), 27 | "ME" => array ("0380103801", "0380403804", "0390004999"), 28 | "MI" => array ("4800049999"), 29 | "MN" => array ("5500056799"), 30 | "MO" => array ("6300065899"), 31 | "MS" => array ("3860039799"), 32 | "MT" => array ("5900059999"), 33 | "NC" => array ("2700028999"), 34 | "ND" => array ("5800058899"), 35 | "NE" => array ("6800069399"), 36 | "NH" => array ("0300003803", "0380903899"), 37 | "NJ" => array ("0700008999"), 38 | "NM" => array ("8700088499"), 39 | "NV" => array ("8900089899"), 40 | "NY" => array ("0040000599", "0639006390", "0900014999"), 41 | "OH" => array ("4300045999"), 42 | "OK" => array ("7300073199", "7340074999"), 43 | "OR" => array ("9700097999"), 44 | "PA" => array ("1500019699"), 45 | "RI" => array ("0280002999", "0637906379"), 46 | "SC" => array ("2900029999"), 47 | "SD" => array ("5700057799"), 48 | "TN" => array ("3700038599", "7239572395"), 49 | "TX" => array ("7330073399", "7394973949", "7500079999", "8850188599"), 50 | "UT" => array ("8400084799"), 51 | "VA" => array ("2010520199", "2030120301", "2037020370", "2200024699"), 52 | "VT" => array ("0500005999"), 53 | "WA" => array ("9800099499"), 54 | "WI" => array ("4993649936", "5300054999"), 55 | "WV" => array ("2470026899"), 56 | "WY" => array ("8200083199")); 57 | 58 | // if you use a drop down list for state selection, ensuring valid data, 59 | // isset is not needed. (Warnings can not be turned off with: @foreach...) 60 | 61 | if (isset($allstates[$state])) 62 | { 63 | foreach($allstates[$state] as $ziprange) 64 | { 65 | if (($zip5 >= substr($ziprange, 0, 5)) && ($zip5 <= substr($ziprange,5))) 66 | { 67 | $valid = "TRUE"; 68 | return ($valid); // on match, jump out of foreach early :) 69 | } 70 | } 71 | } 72 | $valid = "FALSE"; 73 | return ($valid); 74 | } 75 | 76 | ?> -------------------------------------------------------------------------------- /API/helper_functions/colors.php: -------------------------------------------------------------------------------- 1 | foreground_colors[shell]['black'] = '0;30'; 11 | $this->foreground_colors[shell]['dark_gray'] = '1;30'; 12 | $this->foreground_colors[shell]['blue'] = '0;34'; 13 | $this->foreground_colors[shell]['light_blue'] = '1;34'; 14 | $this->foreground_colors[shell]['green'] = '0;32'; 15 | $this->foreground_colors[shell]['light_green'] = '1;32'; 16 | $this->foreground_colors[shell]['cyan'] = '0;36'; 17 | $this->foreground_colors[shell]['light_cyan'] = '1;36'; 18 | $this->foreground_colors[shell]['red'] = '0;31'; 19 | $this->foreground_colors[shell]['light_red'] = '1;31'; 20 | $this->foreground_colors[shell]['purple'] = '0;35'; 21 | $this->foreground_colors[shell]['light_purple'] = '1;35'; 22 | $this->foreground_colors[shell]['brown'] = '0;33'; 23 | $this->foreground_colors[shell]['yellow'] = '1;33'; 24 | $this->foreground_colors[shell]['light_gray'] = '0;37'; 25 | $this->foreground_colors[shell]['white'] = '1;37'; 26 | 27 | $this->foreground_colors[shell]['bold'] = '1;1'; 28 | $this->foreground_colors[shell]['underline'] = '1;4'; 29 | $this->foreground_colors[shell]['blink'] = '5;4'; 30 | 31 | $this->background_colors[shell]['black'] = '40'; 32 | $this->background_colors[shell]['red'] = '41'; 33 | $this->background_colors[shell]['green'] = '42'; 34 | $this->background_colors[shell]['yellow'] = '43'; 35 | $this->background_colors[shell]['blue'] = '44'; 36 | $this->background_colors[shell]['magenta'] = '45'; 37 | $this->background_colors[shell]['cyan'] = '46'; 38 | $this->background_colors[shell]['light_gray'] = '47'; 39 | 40 | // Set up html colors (will be within a style= element of a span) 41 | $this->foreground_colors[html]['black'] = 'color:black;'; 42 | $this->foreground_colors[html]['dark_gray'] = 'color:dark_gray;'; 43 | $this->foreground_colors[html]['blue'] = 'color:blue;'; 44 | $this->foreground_colors[html]['light_blue'] = 'color:light_blue;'; 45 | $this->foreground_colors[html]['green'] = 'color:green;'; 46 | $this->foreground_colors[html]['light_green'] = 'color:light_green;'; 47 | $this->foreground_colors[html]['cyan'] = 'color:cyan;'; 48 | $this->foreground_colors[html]['light_cyan'] = 'color:light_cyan;'; 49 | $this->foreground_colors[html]['red'] = 'color:red;'; 50 | $this->foreground_colors[html]['light_red'] = 'color:light_red;'; 51 | $this->foreground_colors[html]['purple'] = 'color:purple;'; 52 | $this->foreground_colors[html]['light_purple'] = 'color:light_purple;'; 53 | $this->foreground_colors[html]['brown'] = 'color:brown;'; 54 | $this->foreground_colors[html]['yellow'] = 'color:yellow;'; 55 | $this->foreground_colors[html]['light_gray'] = 'color:light_gray;'; 56 | $this->foreground_colors[html]['white'] = 'color:white;'; 57 | 58 | $this->foreground_colors[html]['bold'] = 'font-weight:bold;'; 59 | $this->foreground_colors[html]['underline'] = 'text-decoration:underline;'; 60 | $this->foreground_colors[html]['blink'] = 'text-decoration:blink;'; 61 | 62 | $this->background_colors[html]['black'] = 'background-color:black;'; 63 | $this->background_colors[html]['red'] = 'background-color:red;'; 64 | $this->background_colors[html]['green'] = 'background-color:green;'; 65 | $this->background_colors[html]['yellow'] = 'background-color:yellow;'; 66 | $this->background_colors[html]['blue'] = 'background-color:blue;'; 67 | $this->background_colors[html]['magenta'] = 'background-color:magenta;'; 68 | $this->background_colors[html]['cyan'] = 'background-color:cyan;'; 69 | $this->background_colors[html]['light_gray'] = 'background-color:light_gray;'; 70 | } 71 | 72 | // Returns colored string 73 | public function getColoredString($string, $foreground_color = null, $background_color = null) { 74 | $colored_string = ""; 75 | 76 | $mode = "shell"; 77 | if($this->is_server()){$mode = "html";} 78 | 79 | // begin 80 | if ($mode == "shell") 81 | { 82 | $colored_string .= "\033["; 83 | } 84 | if ($mode == "html") 85 | {$colored_string .= "foreground_colors[$mode][$foreground_color])) { 89 | $colored_string .= $this->foreground_colors[$mode][$foreground_color]; 90 | } 91 | // Check if given background color found 92 | if (isset($this->background_colors[$mode][$background_color])) { 93 | $colored_string .= $this->background_colors[$mode][$background_color]; 94 | } 95 | 96 | // end 97 | if ($mode == "shell") 98 | { 99 | $colored_string .= "m".$string."\033[0m"; 100 | } 101 | if ($mode == "html") 102 | { 103 | $colored_string .= "\">".$string.""; 104 | } 105 | 106 | return $colored_string; 107 | } 108 | 109 | // Returns all foreground color names 110 | public function getForegroundColors() { 111 | return array_keys($this->foreground_colors); 112 | } 113 | 114 | // Returns all background color names 115 | public function getBackgroundColors() { 116 | return array_keys($this->background_colors); 117 | } 118 | 119 | function is_server() 120 | { 121 | if (isset($_SERVER['SERVER_ADDR'])) 122 | { 123 | return true; 124 | } 125 | else 126 | { 127 | return false; 128 | } 129 | } 130 | } 131 | 132 | ?> -------------------------------------------------------------------------------- /API/helper_functions/formatBytes.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/helper_functions/http.php: -------------------------------------------------------------------------------- 1 | _status = $status; 22 | $this->_type = $type; 23 | $this->_url = $url; 24 | $this->_params = $params; 25 | } 26 | 27 | function getStatus() 28 | { 29 | return $this->_status; 30 | } 31 | 32 | function getType() 33 | { 34 | return $this->_type; 35 | } 36 | 37 | function getUrl() 38 | { 39 | return $this->_url; 40 | } 41 | 42 | function getParams() 43 | { 44 | return $this->_params; 45 | } 46 | } 47 | 48 | class Http 49 | { 50 | private $_host = null; 51 | private $_port = null; 52 | private $_user = null; 53 | private $_pass = null; 54 | private $_protocol = null; 55 | 56 | const HTTP = 'http'; 57 | const HTTPS = 'https'; 58 | 59 | private $_connMultiple = false; 60 | /** 61 | * Factory of the class. Lazy connect 62 | * 63 | * @param string $host 64 | * @param integer $port 65 | * @param string $user 66 | * @param string $pass 67 | * @return Http 68 | */ 69 | static public function connect($host, $port = 80, $protocol = self::HTTP) 70 | { 71 | return new self($host, $port, $protocol, false); 72 | } 73 | 74 | /** 75 | * 76 | * @return Http 77 | */ 78 | static public function multiConnect() 79 | { 80 | return new self(null, null, null, true); 81 | } 82 | 83 | private $_append = array(); 84 | public function add($http) 85 | { 86 | $this->_append[] = $http; 87 | return $this; 88 | } 89 | 90 | private $_silentMode = false; 91 | /** 92 | * 93 | * @param bool $mode 94 | * @return Http 95 | */ 96 | public function silentMode($mode=true) 97 | { 98 | $this->_silentMode = $mode; 99 | return $this; 100 | } 101 | 102 | protected function __construct($host, $port, $protocol, $connMultiple) 103 | { 104 | $this->_connMultiple = $connMultiple; 105 | 106 | $this->_host = $host; 107 | $this->_port = $port; 108 | $this->_protocol = $protocol; 109 | } 110 | 111 | public function setCredentials($user, $pass) 112 | { 113 | $this->_user = $user; 114 | $this->_pass = $pass; 115 | return $this; 116 | } 117 | 118 | const POST = 'POST'; 119 | const GET = 'GET'; 120 | const DELETE = 'DELETE'; 121 | const PUT = 'PUT'; 122 | 123 | private $_requests = array(); 124 | 125 | /** 126 | * @param string $url 127 | * @param array $params 128 | * @return Http 129 | */ 130 | public function put($url, $params=array()) 131 | { 132 | $this->_requests[] = array(self::PUT, $this->_url($url), $params); 133 | return $this; 134 | } 135 | 136 | /** 137 | * @param string $url 138 | * @param array $params 139 | * @return Http 140 | */ 141 | public function post($url, $params=array()) 142 | { 143 | $this->_requests[] = array(self::POST, $this->_url($url), $params); 144 | return $this; 145 | } 146 | 147 | /** 148 | * @param string $url 149 | * @param array $params 150 | * @return Http 151 | */ 152 | public function get($url, $params=array()) 153 | { 154 | $this->_requests[] = array(self::GET, $this->_url($url), $params); 155 | return $this; 156 | } 157 | 158 | /** 159 | * @param string $url 160 | * @param array $params 161 | * @return Http 162 | */ 163 | public function delete($url, $params=array()) 164 | { 165 | $this->_requests[] = array(self::DELETE, $this->_url($url), $params); 166 | return $this; 167 | } 168 | 169 | public function _getRequests() 170 | { 171 | return $this->_requests; 172 | } 173 | 174 | /** 175 | * PUT request 176 | * 177 | * @param string $url 178 | * @param array $params 179 | * @return string 180 | */ 181 | public function doPut($url, $params=array()) 182 | { 183 | return $this->_exec(self::PUT, $this->_url($url), $params); 184 | } 185 | 186 | /** 187 | * POST request 188 | * 189 | * @param string $url 190 | * @param array $params 191 | * @return string 192 | */ 193 | public function doPost($url, $params=array()) 194 | { 195 | return $this->_exec(self::POST, $this->_url($url), $params); 196 | } 197 | 198 | /** 199 | * GET Request 200 | * 201 | * @param string $url 202 | * @param array $params 203 | * @return string 204 | */ 205 | public function doGet($url, $params=array()) 206 | { 207 | return $this->_exec(self::GET, $this->_url($url), $params); 208 | } 209 | 210 | /** 211 | * DELETE Request 212 | * 213 | * @param string $url 214 | * @param array $params 215 | * @return string 216 | */ 217 | public function doDelete($url, $params=array()) 218 | { 219 | return $this->_exec(self::DELETE, $this->_url($url), $params); 220 | } 221 | 222 | private $_headers = array(); 223 | /** 224 | * setHeaders 225 | * 226 | * @param array $headers 227 | * @return Http 228 | */ 229 | public function setHeaders($headers) 230 | { 231 | $this->_headers = $headers; 232 | return $this; 233 | } 234 | 235 | /** 236 | * Builds absolute url 237 | * 238 | * @param unknown_type $url 239 | * @return unknown 240 | */ 241 | private function _url($url=null) 242 | { 243 | return "{$this->_protocol}://{$this->_host}:{$this->_port}/{$url}"; 244 | } 245 | 246 | const HTTP_OK = 200; 247 | const HTTP_CREATED = 201; 248 | const HTTP_ACEPTED = 202; 249 | 250 | /** 251 | * Performing the real request 252 | * 253 | * @param string $type 254 | * @param string $url 255 | * @param array $params 256 | * @return string 257 | */ 258 | private function _exec($type, $url, $params = array()) 259 | { 260 | $headers = $this->_headers; 261 | $s = curl_init(); 262 | 263 | if(!is_null($this->_user)){ 264 | curl_setopt($s, CURLOPT_USERPWD, $this->_user.':'.$this->_pass); 265 | } 266 | 267 | switch ($type) { 268 | case self::DELETE: 269 | curl_setopt($s, CURLOPT_URL, $url . '?' . http_build_query($params)); 270 | curl_setopt($s, CURLOPT_CUSTOMREQUEST, self::DELETE); 271 | break; 272 | case self::PUT: 273 | curl_setopt($s, CURLOPT_URL, $url); 274 | curl_setopt($s, CURLOPT_CUSTOMREQUEST, self::PUT); 275 | curl_setopt($s, CURLOPT_POSTFIELDS, $params); 276 | break; 277 | case self::POST: 278 | curl_setopt($s, CURLOPT_URL, $url); 279 | curl_setopt($s, CURLOPT_POST, true); 280 | curl_setopt($s, CURLOPT_POSTFIELDS, $params); 281 | break; 282 | case self::GET: 283 | curl_setopt($s, CURLOPT_URL, $url . '?' . http_build_query($params)); 284 | break; 285 | } 286 | 287 | curl_setopt($s, CURLOPT_RETURNTRANSFER, true); 288 | curl_setopt($s, CURLOPT_HTTPHEADER, $headers); 289 | $_out = curl_exec($s); 290 | $status = curl_getinfo($s, CURLINFO_HTTP_CODE); 291 | curl_close($s); 292 | switch ($status) { 293 | case self::HTTP_OK: 294 | case self::HTTP_CREATED: 295 | case self::HTTP_ACEPTED: 296 | $out = $_out; 297 | break; 298 | default: 299 | if (!$this->_silentMode) { 300 | throw new Http_Exception("http error: {$status}", $status); 301 | } 302 | } 303 | return $out; 304 | } 305 | 306 | public function run() 307 | { 308 | if ($this->_connMultiple) { 309 | return $this->_runMultiple(); 310 | } else { 311 | return $this->_run(); 312 | } 313 | } 314 | 315 | private function _runMultiple() 316 | { 317 | $out= null; 318 | if (count($this->_append) > 0) { 319 | $arr = array(); 320 | foreach ($this->_append as $_append) { 321 | $arr = array_merge($arr, $_append->_getRequests()); 322 | } 323 | 324 | $this->_requests = $arr; 325 | $out = $this->_run(); 326 | } 327 | return $out; 328 | } 329 | 330 | private function _run() 331 | { 332 | $headers = $this->_headers; 333 | $curly = $result = array(); 334 | 335 | $mh = curl_multi_init(); 336 | foreach ($this->_requests as $id => $reg) { 337 | $curly[$id] = curl_init(); 338 | 339 | $type = $reg[0]; 340 | $url = $reg[1]; 341 | $params = $reg[2]; 342 | 343 | if(!is_null($this->_user)){ 344 | curl_setopt($curly[$id], CURLOPT_USERPWD, $this->_user.':'.$this->_pass); 345 | } 346 | 347 | switch ($type) { 348 | case self::DELETE: 349 | curl_setopt($curly[$id], CURLOPT_URL, $url . '?' . http_build_query($params)); 350 | curl_setopt($curly[$id], CURLOPT_CUSTOMREQUEST, self::DELETE); 351 | break; 352 | case self::PUT: 353 | curl_setopt($curly[$id], CURLOPT_URL, $url); 354 | curl_setopt($curly[$id], CURLOPT_CUSTOMREQUEST, self::PUT); 355 | curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $params); 356 | break; 357 | case self::POST: 358 | curl_setopt($curly[$id], CURLOPT_URL, $url); 359 | curl_setopt($curly[$id], CURLOPT_POST, true); 360 | curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $params); 361 | break; 362 | case self::GET: 363 | curl_setopt($curly[$id], CURLOPT_URL, $url . '?' . http_build_query($params)); 364 | break; 365 | } 366 | curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, true); 367 | curl_setopt($curly[$id], CURLOPT_HTTPHEADER, $headers); 368 | 369 | curl_multi_add_handle($mh, $curly[$id]); 370 | } 371 | 372 | $running = null; 373 | do { 374 | curl_multi_exec($mh, $running); 375 | sleep(0.2); 376 | } while($running > 0); 377 | 378 | foreach($curly as $id => $c) { 379 | $status = curl_getinfo($c, CURLINFO_HTTP_CODE); 380 | switch ($status) { 381 | case self::HTTP_OK: 382 | case self::HTTP_CREATED: 383 | case self::HTTP_ACEPTED: 384 | $result[$id] = curl_multi_getcontent($c); 385 | break; 386 | default: 387 | if (!$this->_silentMode) { 388 | $result[$id] = new Http_Multiple_Error($status, $type, $url, $params); 389 | } 390 | } 391 | curl_multi_remove_handle($mh, $c); 392 | } 393 | 394 | curl_multi_close($mh); 395 | return $result; 396 | } 397 | } 398 | ?> -------------------------------------------------------------------------------- /API/helper_functions/microtime_float.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /API/helper_functions/parseArgs.php: -------------------------------------------------------------------------------- 1 | 6 | * @source https://github.com/pwfisher/CommandLine.php 7 | */ 8 | function __parseArgs(){ 9 | global $argv; 10 | array_shift($argv); 11 | $out = array(); 12 | foreach ($argv as $arg){ 13 | if (substr($arg,0,2) == '--'){ 14 | $eqPos = strpos($arg,'='); 15 | if ($eqPos === false){ 16 | $key = substr($arg,2); 17 | $out[$key] = isset($out[$key]) ? $out[$key] : true; 18 | } else { 19 | $key = substr($arg,2,$eqPos-2); 20 | $out[$key] = substr($arg,$eqPos+1); 21 | } 22 | } else if (substr($arg,0,1) == '-'){ 23 | if (substr($arg,2,1) == '='){ 24 | $key = substr($arg,1,1); 25 | $out[$key] = substr($arg,3); 26 | } else { 27 | $chars = str_split(substr($arg,1)); 28 | foreach ($chars as $char){ 29 | $key = $char; 30 | $out[$key] = isset($out[$key]) ? $out[$key] : true; 31 | } 32 | } 33 | } else { 34 | $out[] = $arg; 35 | } 36 | } 37 | return $out; 38 | } 39 | ?> 40 | -------------------------------------------------------------------------------- /API/helper_functions/secondsToWords.php: -------------------------------------------------------------------------------- 1 | 0) 11 | { 12 | $ret .= "$hours hours "; 13 | } 14 | /*** get the minutes ***/ 15 | $minutes = bcmod((intval($seconds) / 60),60); 16 | if($hours > 0 || $minutes > 0) 17 | { 18 | $ret .= "$minutes minutes "; 19 | } 20 | 21 | /*** get the seconds ***/ 22 | $seconds = bcmod(intval($seconds),60); 23 | $ret .= "$seconds seconds"; 24 | 25 | return $ret; 26 | } 27 | 28 | ?> -------------------------------------------------------------------------------- /API/index.php: -------------------------------------------------------------------------------- 1 | 0) 51 | { 52 | if ($CONFIG['CorrectLimitLockPass'] != $PARAMS["LimitLockPass"]) 53 | { 54 | $_api_requests_so_far = _GetAPIRequestsCount(); 55 | if (!is_int($_api_requests_so_far)){ $OUTPUT['ERROR'] = $_api_requests_so_far; require('Output.php'); exit;} 56 | $OUTPUT['APIRequestsRemaining'] = $CONFIG['RequestLimitPerHour'] - $_api_requests_so_far; 57 | if ($OUTPUT['APIRequestsRemaining'] <= 0) 58 | { 59 | $DBOBJ->close(); 60 | $OUTPUT['ERROR'] = "You have exceeded your allotted ".$CONFIG['RequestLimitPerHour']." requests this hour."; 61 | require('Output.php'); 62 | exit; 63 | } 64 | } 65 | } 66 | 67 | // start transaction for connection if needed 68 | if (isset($PARAMS['Rollback'])) 69 | { 70 | if ($PARAMS['Rollback'] == $CONFIG['RollbackPhrase']) 71 | { 72 | _StartTransaction(); 73 | } 74 | else 75 | { 76 | $Action = "HALTED"; 77 | $ERROR = "That is not the correct RollbackPhrase"; 78 | } 79 | } 80 | 81 | // functional Steps 82 | ///////////////////////////////////////////////////////////////////////// 83 | ///////////////////////////////////////////////////////////////////////// 84 | ///////////////////////////////////////////////////////////////////////// 85 | 86 | $ActionPreformed = 0; 87 | $_ActionCounter = 0; 88 | 89 | // check for restful requests 90 | if(empty($PARAMS["Action"]) && count(explode(".",$_SERVER["REQUEST_URI"])) == 1) 91 | { 92 | $parts = explode("?",$_SERVER["REQUEST_URI"]); 93 | $path = $parts[0]; 94 | foreach ($ACTIONS as $action) 95 | { 96 | if (strlen($action[3]) > 0 && strstr($path,$action[3]) !== false) 97 | { 98 | $PARAMS["Action"] = $action[0]; 99 | break; 100 | } 101 | } 102 | } 103 | 104 | while ($_ActionCounter < count($ACTIONS)) 105 | { 106 | if (0 == strcmp($PARAMS["Action"],$ACTIONS[$_ActionCounter][0])) 107 | { 108 | $Action = $ACTIONS[$_ActionCounter][0]; 109 | if ($ACTIONS[$_ActionCounter][2] != "Public") 110 | { 111 | require("CheckAPIKey.php"); 112 | } 113 | if ($ERROR == 100) 114 | { 115 | require($ACTIONS[$_ActionCounter][1]); 116 | } 117 | $ActionPreformed = 1; 118 | break; 119 | } 120 | $_ActionCounter++; 121 | } 122 | 123 | 124 | // Cleanup Steps 125 | ///////////////////////////////////////////////////////////////////////// 126 | ///////////////////////////////////////////////////////////////////////// 127 | ///////////////////////////////////////////////////////////////////////// 128 | 129 | // Check to make sure the action happened... 130 | if ($ActionPreformed == 0 || $PARAMS["Action"] == "" || strlen($PARAMS["Action"]) == 0) 131 | { 132 | if ($ERROR == 100) { 133 | $ERROR = "That Action cannot be found. Did you send the 'Action' parameter? List Actions with Action=DescribeActions"; 134 | $Action = "Unknown Action"; 135 | } 136 | } 137 | 138 | if ($ERROR == 100) 139 | { 140 | $ERROR = "OK"; 141 | } 142 | 143 | // end the timer 144 | $ComputationEndTime = microtime_float(); 145 | $ComputationElapsedTime = $ComputationEndTime - $ComputationStartTime; 146 | 147 | $OUTPUT['Action'] = $Action; 148 | $OUTPUT['Params'] = $PARAMS; 149 | $OUTPUT['ComputationTime'] = $ComputationElapsedTime; 150 | $OUTPUT['IP'] = $IP; 151 | $OUTPUT['ERROR'] = $ERROR; 152 | $OUTPUT['ServerName'] = $CONFIG['ServerName']; 153 | $OUTPUT['ServerAddress'] = $CONFIG['ServerAddress']; 154 | 155 | // end transaction for connection if needed 156 | if ($PARAMS['Rollback'] == $CONFIG['RollbackPhrase'] && ($DBOBJ instanceof DBConnection) == true) 157 | { 158 | if ($DBOBJ->GetStatus() == true) 159 | { 160 | $DBOBJ->Query("ROLLBACK;"); 161 | $OUTPUT["Rollback"] = "true"; 162 | } 163 | } 164 | 165 | // output and cleanup 166 | require('Output.php'); 167 | if ($CONFIG['Logging'] == true){ _LogAPIRequest(); } 168 | @$DBOBJ->close(); 169 | 170 | ?> -------------------------------------------------------------------------------- /API/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | TEST PAGE 4 | 5 | 6 |

I AM A STATIC PAGE

7 | If you can see me, the server can render static pages! 8 | 9 | -------------------------------------------------------------------------------- /BaseDBs/API_BASIC.sql: -------------------------------------------------------------------------------- 1 | SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 2 | 3 | delimiter $$ 4 | 5 | CREATE TABLE `cache` ( 6 | `Key` varchar(255) NOT NULL, 7 | `Value` text NOT NULL, 8 | `ExpireTime` int(11) NOT NULL, 9 | KEY `Key` (`Key`), 10 | KEY `ExpireTime` (`ExpireTime`) 11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 12 | 13 | delimiter $$ 14 | 15 | CREATE TABLE `developers` ( 16 | `ID` int(11) NOT NULL AUTO_INCREMENT, 17 | `DeveloperID` varchar(32) NOT NULL, 18 | `APIKey` varchar(32) NOT NULL, 19 | `UserActions` tinyint(1) NOT NULL, 20 | `IsAdmin` tinyint(1) NOT NULL DEFAULT '0', 21 | PRIMARY KEY (`ID`), 22 | UNIQUE KEY `DeveloperID` (`DeveloperID`), 23 | UNIQUE KEY `APIKey` (`APIKey`) 24 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 25 | 26 | delimiter $$ 27 | 28 | CREATE TABLE `log` ( 29 | `ID` int(11) NOT NULL AUTO_INCREMENT, 30 | `IP` varchar(255) NOT NULL, 31 | `TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 32 | `Action` varchar(255) NOT NULL, 33 | `ERROR` varchar(255) NOT NULL, 34 | `APIKey` varchar(32) NOT NULL, 35 | `DeveloperID` varchar(32) NOT NULL, 36 | `Params` text NOT NULL, 37 | PRIMARY KEY (`ID`), 38 | KEY `IP` (`IP`), 39 | KEY `TimeStamp` (`TimeStamp`), 40 | KEY `Action` (`Action`), 41 | KEY `Error` (`ERROR`), 42 | KEY `APIKey` (`APIKey`), 43 | KEY `DeveloperID` (`DeveloperID`) 44 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 45 | 46 | delimiter $$ 47 | 48 | CREATE TABLE `sessions` ( 49 | `ID` int(11) NOT NULL AUTO_INCREMENT, 50 | `KEY` varchar(128) NOT NULL, 51 | `DATA` text NOT NULL, 52 | `created_at` datetime NOT NULL, 53 | `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 54 | PRIMARY KEY (`ID`), 55 | UNIQUE KEY `KEY` (`KEY`), 56 | KEY `created_at` (`created_at`), 57 | KEY `updated_at` (`updated_at`) 58 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 59 | 60 | -------------------------------------------------------------------------------- /BaseDBs/API_WITH_USER_TABLE.sql: -------------------------------------------------------------------------------- 1 | SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 2 | 3 | delimiter $$ 4 | 5 | CREATE TABLE `cache` ( 6 | `Key` varchar(255) NOT NULL, 7 | `Value` text NOT NULL, 8 | `ExpireTime` int(11) NOT NULL, 9 | KEY `Key` (`Key`), 10 | KEY `ExpireTime` (`ExpireTime`) 11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 12 | 13 | delimiter $$ 14 | 15 | CREATE TABLE `developers` ( 16 | `ID` int(11) NOT NULL AUTO_INCREMENT, 17 | `DeveloperID` varchar(32) NOT NULL, 18 | `APIKey` varchar(32) NOT NULL, 19 | `UserActions` tinyint(1) NOT NULL, 20 | `IsAdmin` tinyint(1) NOT NULL DEFAULT '0', 21 | PRIMARY KEY (`ID`), 22 | UNIQUE KEY `DeveloperID` (`DeveloperID`), 23 | UNIQUE KEY `APIKey` (`APIKey`) 24 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 25 | 26 | delimiter $$ 27 | 28 | CREATE TABLE `lobbies` ( 29 | `LobbyID` int(11) NOT NULL AUTO_INCREMENT, 30 | `LobbyKey` varchar(45) NOT NULL, 31 | `LobbyName` varchar(45) NOT NULL, 32 | `TimeStamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 33 | PRIMARY KEY (`LobbyID`), 34 | UNIQUE KEY `LobbyKey_UNIQUE` (`LobbyKey`), 35 | UNIQUE KEY `LobyName_UNIQUE` (`LobbyName`) 36 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 37 | 38 | delimiter $$ 39 | 40 | CREATE TABLE `log` ( 41 | `ID` int(11) NOT NULL AUTO_INCREMENT, 42 | `IP` varchar(255) NOT NULL, 43 | `TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 44 | `Action` varchar(255) NOT NULL, 45 | `ERROR` varchar(255) NOT NULL, 46 | `APIKey` varchar(32) NOT NULL, 47 | `DeveloperID` varchar(32) NOT NULL, 48 | `Params` text NOT NULL, 49 | PRIMARY KEY (`ID`), 50 | KEY `IP` (`IP`), 51 | KEY `TimeStamp` (`TimeStamp`), 52 | KEY `Action` (`Action`), 53 | KEY `Error` (`ERROR`), 54 | KEY `APIKey` (`APIKey`), 55 | KEY `DeveloperID` (`DeveloperID`) 56 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 57 | 58 | delimiter $$ 59 | 60 | CREATE TABLE `messages` ( 61 | `MessageID` int(11) NOT NULL AUTO_INCREMENT, 62 | `LobbyID` int(11) NOT NULL, 63 | `Speaker` varchar(45) NOT NULL, 64 | `Message` text NOT NULL, 65 | `Timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 66 | PRIMARY KEY (`MessageID`) 67 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 68 | 69 | delimiter $$ 70 | 71 | CREATE TABLE `sessions` ( 72 | `ID` int(11) NOT NULL AUTO_INCREMENT, 73 | `KEY` varchar(128) NOT NULL, 74 | `DATA` text NOT NULL, 75 | `created_at` datetime NOT NULL, 76 | `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 77 | PRIMARY KEY (`ID`), 78 | UNIQUE KEY `KEY` (`KEY`), 79 | KEY `created_at` (`created_at`), 80 | KEY `updated_at` (`updated_at`) 81 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 82 | 83 | delimiter $$ 84 | 85 | CREATE TABLE `users` ( 86 | `UserID` int(11) NOT NULL AUTO_INCREMENT, 87 | `FirstName` varchar(32) NOT NULL, 88 | `LastName` varchar(32) NOT NULL, 89 | `PhoneNumber` varchar(32) DEFAULT NULL, 90 | `Gender` text, 91 | `ScreenName` varchar(32) NOT NULL, 92 | `EMail` varchar(255) NOT NULL, 93 | `Birthday` date DEFAULT NULL, 94 | `PasswordHash` varchar(32) NOT NULL, 95 | `Salt` varchar(32) NOT NULL, 96 | `Joined` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 97 | PRIMARY KEY (`UserID`), 98 | UNIQUE KEY `ScreenName` (`ScreenName`), 99 | UNIQUE KEY `EMail` (`EMail`), 100 | UNIQUE KEY `PasswordHash` (`PasswordHash`), 101 | UNIQUE KEY `PhoneNumber` (`PhoneNumber`) 102 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 103 | 104 | -------------------------------------------------------------------------------- /SERVER/script_runner.php: -------------------------------------------------------------------------------- 1 | >".$__CLIENT_ID; 56 | echo "\r\nSending to client #".$__CLIENT_ID."\r\n"; 57 | if (strlen($__PARENT_URL) > 0) 58 | { 59 | $socket = stream_socket_client("tcp://".$__PARENT_URL.":".$__PARENT_PORT, $errno, $errstr); 60 | if ($socket) 61 | { 62 | fwrite($socket, serialize($string)); 63 | } 64 | @fclose($socket); 65 | } 66 | } 67 | 68 | function __ErrorHandler($errno, $errstr, $errfile, $errline) 69 | { 70 | $error_string = "<>ERROR @ "; 71 | $deets = debug_backtrace(); 72 | $error_string .= "line ".$deets[1]["line"]." > "; 73 | 74 | if (!(error_reporting() & $errno)) { 75 | return; 76 | } 77 | 78 | switch ($errno) { 79 | case E_USER_ERROR: 80 | $error_string .= "ERROR [$errno] $errstr
\r\n"; 81 | $error_string .= " Fatal error on line $errline in file $errfile"; 82 | $error_string .= ", PHP " . PHP_VERSION . " (" . PHP_OS . ")
\r\n"; 83 | $error_string .= "Aborting...
\r\n"; 84 | break; 85 | 86 | case E_USER_WARNING: 87 | $error_string .= "WARNING [$errno] $errstr
\r\n"; 88 | break; 89 | 90 | case E_USER_NOTICE: 91 | $error_string .= "NOTICE [$errno] $errstr
\r\n"; 92 | break; 93 | 94 | default: 95 | $error_string .= "Unknown error type: [$errno] $errstr
\r\n"; 96 | break; 97 | } 98 | 99 | echo $error_string; 100 | __SendToParent($error_string); 101 | 102 | return true; 103 | } 104 | $old_error_handler = set_error_handler("__ErrorHandler"); 105 | 106 | $_GET = array(); 107 | $_POST = array(); 108 | $_COOKIE = array(); 109 | $_REQUEST = array(); 110 | 111 | $__input = @__parseArgs(); 112 | $_GET = @unserialize($__input["GET"]); 113 | $_POST = @unserialize($__input["POST"]); 114 | $_SERVER = @unserialize($__input["SERVER"]); 115 | $_COOKIE = @unserialize($__input["COOKIE"]); 116 | $__FILE = @unserialize($__input["FILE"]); 117 | $__CLIENT_ID = @unserialize($__input["CLIENT_ID"]); 118 | $__PARENT_URL = @unserialize($__input["PARENT_URL"]); 119 | $__PARENT_PORT = @unserialize($__input["PARENT_PORT"]); 120 | 121 | foreach ($_GET as $k => $v){ $_REQUEST[$k] = $v; } 122 | foreach ($_POST as $k => $v){ $_REQUEST[$k] = $v; } 123 | foreach ($_COOKIE as $k => $v){ $_REQUEST[$k] = $v; } 124 | 125 | // header 126 | $_HEADER = array(); 127 | function _header($string) 128 | { 129 | global $_HEADER; 130 | $out = @header($string); 131 | if ($out === false || $out === NULL) 132 | { 133 | $_HEADER[] = $string; 134 | return true; 135 | } 136 | else {return true;} 137 | } 138 | 139 | // cookie 140 | function _setcookie($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httponly = null) 141 | { 142 | global $SERVER; 143 | $out = @setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); 144 | if ($out === false) 145 | { 146 | // TODO: Handle $domain, $secure and $httponly 147 | 148 | if (!($expire > 0)){$expire = time() + 60*60*24;} // 1 day default cookie duration 149 | $datetime = new DateTime(date("Y-m-d H:i:s",$expire)); 150 | $cookie_time = $datetime->format(DATE_COOKIE); 151 | if ($path == null){$path = "/";} 152 | if ($domain == null){$domain = $SERVER['domain'];} 153 | $ret .= "Set-Cookie: ".urlencode($name)."=".urlencode($value)."; expires=".$cookie_time."; path=".$path."; domain=".$domain.";"; 154 | _header($ret); 155 | return true; 156 | } 157 | else {return true;} 158 | } 159 | 160 | // send the empty buffer to force all header and cookie functions to fail 161 | // TODO: this seems to break things on newer PHP versions 162 | // ob_start();ob_end_flush(); 163 | 164 | // output buffer 165 | ob_start(); 166 | require($__FILE); 167 | echo "<>"; 168 | foreach($_HEADER as $header) 169 | { 170 | echo $header."<>"; 171 | } 172 | $__OUT = ob_get_contents(); 173 | ob_end_flush(); 174 | 175 | __SendToParent($__OUT); 176 | 177 | ?> -------------------------------------------------------------------------------- /SERVER/server_config.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SPEC/TEST.php: -------------------------------------------------------------------------------- 1 | log("------------ TEST SUITE RESLTS ------------"); 53 | $T->log((($__TEST_SUITE_RESULTS["Successes"] + $__TEST_SUITE_RESULTS["Failures"]))." total tests in ".(time() - $__TEST_SUITE_RESULTS["StartTime"])." seconds"); 54 | if ($__TEST_SUITE_RESULTS["Successes"] > 0){ $T->log($__TEST_SUITE_RESULTS["Successes"]." passing tests"); } 55 | else { $T->log("0 passing tests"); } 56 | 57 | if ($__TEST_SUITE_RESULTS["Failures"] > 0){ $T->log($__TEST_SUITE_RESULTS["Failures"]." failing tests"); } 58 | else { $T->log("0 failing tests"); } 59 | 60 | echo ((int)($__TEST_SUITE_RESULTS["Successes"] + $__TEST_SUITE_RESULTS["Failures"])).",".((int)$__TEST_SUITE_RESULTS["Successes"]).",".((int)$__TEST_SUITE_RESULTS["Failures"]); 61 | echo "\r\n"; 62 | 63 | $T->end(); 64 | 65 | ?> -------------------------------------------------------------------------------- /SPEC/actions/CacheTest_spec.php: -------------------------------------------------------------------------------- 1 | context("The Action will error properly when no Hash is provided"); 13 | $PostArray = array( 14 | "OutputType" => "PHP", 15 | "Action" => "CacheTest", 16 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'] 17 | ); 18 | 19 | $APIDATA = $T->api_request($PostArray); 20 | $T->assert("==",$APIDATA["ERROR"],"You need to provide a Hash"); 21 | 22 | $T->context("The Action will store the provided value in the cache"); 23 | $PostArray = array( 24 | "OutputType" => "PHP", 25 | "Action" => "CacheTest", 26 | "hash" => "abc123", 27 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'] 28 | ); 29 | 30 | $APIDATA = $T->api_request($PostArray); 31 | $T->assert("==",$APIDATA["ERROR"],"OK"); 32 | $T->assert("==",$APIDATA["CachedResult"],"abc123"); 33 | 34 | 35 | $T->end(); 36 | 37 | ?> -------------------------------------------------------------------------------- /SPEC/actions/DescribeActions_spec.php: -------------------------------------------------------------------------------- 1 | "PHP", 14 | "Action" => "DescribeActions", 15 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'] 16 | ); 17 | 18 | $APIDATA = $T->api_request($PostArray); 19 | 20 | $ExpectedActions = array( 21 | "DescribeActions", 22 | "DescribeTables", 23 | "ObjectTest", 24 | "SlowAction", 25 | "CacheTest", 26 | "UserAdd", 27 | "UserView", 28 | "UserEdit", 29 | "UserEdit", 30 | "LogIn" 31 | ); 32 | 33 | $T->context("There should be at least one Action returned"); 34 | $T->assert(">",count($APIDATA["Actions"]),0); 35 | $Actions = array(); 36 | foreach($APIDATA["Actions"] as $Action) 37 | { 38 | $Actions[] = $Action["Name"]; 39 | } 40 | 41 | $T->context("Certain Actions should be in the server results"); 42 | foreach($ExpectedActions as $Action) 43 | { 44 | $T->assert("in_array",$Action,$Actions); 45 | } 46 | 47 | 48 | $T->end(); 49 | 50 | ?> -------------------------------------------------------------------------------- /SPEC/end_to_end/messages_and_lobbies_spec.php: -------------------------------------------------------------------------------- 1 | rand().time()."_name", 16 | ); 17 | 18 | $T->context("I should be able to create a lobby"); 19 | $PostArray = array( 20 | "OutputType" => "PHP", 21 | "Action" => "LobbyAdd", 22 | "LobbyName" => $TestValues["LobbyName"] 23 | ); 24 | 25 | $APIDATA = $T->api_request($PostArray); 26 | $T->assert("==",$APIDATA["ERROR"],"OK"); 27 | $T->assert("==",$APIDATA["LobbyName"],$TestValues["LobbyName"]); 28 | $T->assert("==",strlen($APIDATA["LobbyKey"]),32); 29 | $TestValues["LobbyKey"] = $APIDATA["LobbyKey"]; // save for later tests 30 | 31 | $T->context("I should be able to list lobbies, and my new lobby should be included"); 32 | $PostArray = array( 33 | "OutputType" => "PHP", 34 | "Action" => "LobbyView", 35 | ); 36 | 37 | $APIDATA = $T->api_request($PostArray); 38 | $T->assert("==",$APIDATA["ERROR"],"OK"); 39 | $found = false; 40 | foreach($APIDATA["Lobbies"] as $Lobby) 41 | { 42 | if ($Lobby["LobbyName"] == $TestValues["LobbyName"]){$found = true;} 43 | } 44 | $T->assert("true",$found); 45 | 46 | $T->context("I should be able to authenticate to my new lobby"); 47 | $PostArray = array( 48 | "OutputType" => "PHP", 49 | "Action" => "LobbyAuthenticate", 50 | "LobbyName" => $TestValues["LobbyName"], 51 | "LobbyKey" => $TestValues["LobbyKey"], 52 | ); 53 | 54 | $APIDATA = $T->api_request($PostArray); 55 | $T->assert("==",$APIDATA["ERROR"],"OK"); 56 | $T->assert("==",$APIDATA["LobbyAuthentication"],"TRUE"); 57 | 58 | $T->context("I should be able to post a message to my lobby"); 59 | $PostArray = array( 60 | "OutputType" => "PHP", 61 | "Action" => "MessageAdd", 62 | "Message" => "A test message", 63 | "Speaker" => "DemoTestMan", 64 | "LobbyKey" => $TestValues["LobbyKey"], 65 | ); 66 | 67 | $APIDATA = $T->api_request($PostArray); 68 | $T->assert("==",$APIDATA["ERROR"],"OK"); 69 | $T->assert(">=",$APIDATA["MessageID"],1); 70 | 71 | $T->context("I should be able to see messages posted to the lobby"); 72 | $PostArray = array( 73 | "OutputType" => "PHP", 74 | "Action" => "MessageView", 75 | "LobbyKey" => $TestValues["LobbyKey"], 76 | ); 77 | 78 | $APIDATA = $T->api_request($PostArray); 79 | $T->assert("==",$APIDATA["ERROR"],"OK"); 80 | $found = false; 81 | foreach($APIDATA["Messages"] as $Message) 82 | { 83 | if ($Message["Message"] == "A test message"){$found = true;} 84 | } 85 | $T->assert("true",$found); 86 | 87 | $T->end(); 88 | ?> -------------------------------------------------------------------------------- /SPEC/end_to_end/users_spec.php: -------------------------------------------------------------------------------- 1 | rand().time()."_name", 18 | "EMail" => rand().time()."@test.com" 19 | ); 20 | 21 | $T->context("I should be able to create a user"); 22 | $PostArray = array( 23 | "OutputType" => "PHP", 24 | "Action" => "UserAdd", 25 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'], 26 | "Password" => "password", 27 | "FirstName" => "DEMO", 28 | "LastName" => "TESTMAN", 29 | "ScreenName" => $TestValues['ScreenName'], 30 | "EMail" => $TestValues['EMail'] 31 | ); 32 | 33 | $APIDATA = $T->api_request($PostArray); 34 | $T->assert("==",$APIDATA["ERROR"],"OK"); 35 | $T->assert(">",$APIDATA[$__TABLES["users"]["META"]["KEY"]],0); 36 | 37 | $UserID = $APIDATA[$__TABLES["users"]["META"]["KEY"]]; 38 | 39 | $T->context("I should be able to View a user publicly"); 40 | $PostArray = array( 41 | "OutputType" => "PHP", 42 | "Action" => "UserView", 43 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'], 44 | "ScreenName" => $TestValues['ScreenName'], 45 | ); 46 | 47 | $APIDATA = $T->api_request($PostArray); 48 | $T->assert("==",$APIDATA["ERROR"],"OK"); 49 | $T->assert("==",$APIDATA["User"]["InformationType"],"Public"); 50 | $T->assert("==",$APIDATA["User"]["ScreenName"],$TestValues['ScreenName']); 51 | $T->assert("==",count($APIDATA["User"]),3); 52 | 53 | $T->context("I should be able to View a user privately"); 54 | $PostArray = array( 55 | "OutputType" => "PHP", 56 | "Action" => "UserView", 57 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'], 58 | "ScreenName" => $TestValues['ScreenName'], 59 | "Password" => "password", 60 | ); 61 | 62 | $APIDATA = $T->api_request($PostArray); 63 | $T->assert("==",$APIDATA["ERROR"],"OK"); 64 | $T->assert("==",$APIDATA["User"]["InformationType"],"Private"); 65 | $T->assert("==",$APIDATA["User"]["ScreenName"],$TestValues['ScreenName']); 66 | $T->assert("==",$APIDATA["User"]["FirstName"],"DEMO"); 67 | $T->assert("==",$APIDATA["User"]["LastName"],"TESTMAN"); 68 | $T->assert("==",$APIDATA["User"]["EMail"],$TestValues['EMail']); 69 | 70 | $T->context("I should be able to Log In"); 71 | $PostArray = array( 72 | "OutputType" => "PHP", 73 | "Action" => "LogIn", 74 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'], 75 | "ScreenName" => $TestValues['ScreenName'], 76 | "Password" => "password", 77 | ); 78 | 79 | $APIDATA = $T->api_request($PostArray); 80 | $T->assert("==",$APIDATA["ERROR"],"OK"); 81 | $T->assert("==",$APIDATA["LOGIN"],"TRUE"); 82 | $T->assert(">",strlen($APIDATA["SessionKey"]),0); 83 | $T->assert(">",$APIDATA["SESSION"]["login_time"],0); 84 | 85 | $T->context("I should be able to Edit a user"); 86 | //It's importnat to use UserID here (META KEY) so you can change other values 87 | $PostArray = array( 88 | "OutputType" => "PHP", 89 | "Action" => "UserEdit", 90 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'], 91 | "Password" => "password", 92 | "EMail" => "NewEmail@fake.com", 93 | $__TABLES["users"]["META"]["KEY"] => $UserID 94 | ); 95 | 96 | $APIDATA = $T->api_request($PostArray); 97 | $T->assert("==",$APIDATA["ERROR"],"OK"); 98 | $T->assert("==",$APIDATA["User"]["EMail"],"NewEmail@fake.com"); 99 | 100 | $T->context("I should be able to Delete a user"); 101 | $PostArray = array( 102 | "OutputType" => "PHP", 103 | "Action" => "UserDelete", 104 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'], 105 | "ScreenName" => $TestValues['ScreenName'], 106 | "Password" => "password" 107 | ); 108 | 109 | $APIDATA = $T->api_request($PostArray); 110 | $T->assert("==",$APIDATA["ERROR"],"OK"); 111 | 112 | $T->context("Deleted users should not be found"); 113 | $PostArray = array( 114 | "OutputType" => "PHP", 115 | "Action" => "UserView", 116 | "LimitLockPass" => $CONFIG['CorrectLimitLockPass'], 117 | "ScreenName" => $TestValues['ScreenName'], 118 | ); 119 | 120 | $APIDATA = $T->api_request($PostArray); 121 | $T->assert("==",$APIDATA["ERROR"],"User cannot be found"); 122 | 123 | $T->end(); 124 | ?> -------------------------------------------------------------------------------- /SPEC/spec_helper.php: -------------------------------------------------------------------------------- 1 | StartTime = time(); 27 | $this->colors = new Colors(); 28 | $this->MessageDepth = 0; 29 | $this->ToDBSave = $ToDBSave; 30 | 31 | global $TestLog; 32 | 33 | if ($title == null){$title == "Unknown Test";} 34 | $this->title = $title; 35 | $this->TestLog = $TestLog; 36 | $this->log($this->colors->getColoredString($this->title,"yellow")); 37 | 38 | $this->Successes = array(); 39 | $this->Failures = array(); 40 | 41 | load_tasks(); 42 | if ($this->ToDBSave) { $this->log_task_output(run_task("CreateDBSaveState")); } 43 | } 44 | 45 | private function log_task_output($string) 46 | { 47 | $this->log(""); 48 | $string = str_replace("\r\n\r\n","\r\n",$string); 49 | $string = substr($string,0,-4); 50 | $this->log($string); 51 | $this->log(""); 52 | } 53 | 54 | public function __set($key, $value) 55 | { 56 | $this->DATA[$key] = $value; 57 | } 58 | 59 | public function __get($key) 60 | { 61 | if (array_key_exists($key, $this->DATA)) 62 | { 63 | return $this->DATA[$key]; 64 | } 65 | else 66 | { 67 | return false; 68 | } 69 | } 70 | 71 | //////////////////////////////////////////// 72 | 73 | public function api_request($PARAMS) 74 | { 75 | global $CONFIG; 76 | 77 | $exec = "eval \" cd ".$CONFIG['App_dir']."../;"; 78 | $exec .= " script/api "; 79 | foreach ($PARAMS as $k => $v) 80 | { 81 | $exec .= " --".$k."='".$v."' "; 82 | } 83 | if (!in_array("OutputType",array_keys($PARAMS))) 84 | { 85 | $exec .= " --OutputType=PHP "; 86 | } 87 | $exec .= " ; \""; 88 | $resp = `$exec`; 89 | $this->LastAPIResponse = $resp; // raw response 90 | return unserialize($resp); 91 | } 92 | 93 | public function get_raw_api_respnse() 94 | { 95 | return $this->LastAPIResponse; 96 | } 97 | 98 | //////////////////////////////////////////// 99 | 100 | public function assert($eval = null, $a = null, $b = null) 101 | { 102 | global $_RESULTS; 103 | 104 | $deets = debug_backtrace(); 105 | $ds = " @ line ".$deets[0]["line"]; 106 | 107 | if ($eval == "==") 108 | { 109 | if ($a == $b){ 110 | $this->log(((string)$a)." equals ".((string)$b).$ds); 111 | return $this->do_success(); 112 | } 113 | else 114 | { 115 | $this->log("! ".((string)$a)." does not equal ".((string)$b).$ds); 116 | return $this->do_failure(); 117 | } 118 | 119 | } 120 | 121 | elseif ($eval == "!=") 122 | { 123 | if ($a != $b){ 124 | $this->log(((string)$a)." does not equal ".((string)$b).$ds); 125 | return $this->do_success(); 126 | } 127 | else 128 | { 129 | $this->log("! ".((string)$a)." equals ".((string)$b).$ds); 130 | return $this->do_failure(); 131 | } 132 | 133 | } 134 | 135 | elseif ($eval == "<") 136 | { 137 | if ($a < $b) 138 | { 139 | $this->log(((string)$a)." < ".((string)$b).$ds); 140 | return $this->do_success(); 141 | } 142 | else 143 | { 144 | $this->log("! ".((string)$a)." < ".((string)$b).$ds); 145 | return $this->do_failure(); 146 | } 147 | } 148 | 149 | elseif ($eval == ">") 150 | { 151 | if ($a > $b) 152 | { 153 | $this->log(((string)$a)." > ".((string)$b).$ds); 154 | return $this->do_success(); 155 | } 156 | else 157 | { 158 | $this->log("! ".((string)$a)." > ".((string)$b).$ds); 159 | return $this->do_failure(); 160 | } 161 | } 162 | 163 | elseif ($eval == "<=") 164 | { 165 | if ($a <= $b) 166 | { 167 | $this->log(((string)$a)." <= ".((string)$b).$ds); 168 | return $this->do_success(); 169 | } 170 | else 171 | { 172 | $this->log("! ".((string)$a)." <= ".((string)$b).$ds); 173 | return $this->do_failure(); 174 | } 175 | } 176 | 177 | elseif ($eval == ">=") 178 | { 179 | if ($a <= $b) 180 | { 181 | $this->log(((string)$a)." >= ".((string)$b).$ds); 182 | return $this->do_success(); 183 | } 184 | else 185 | { 186 | $this->log("! ".((string)$a)." >= ".((string)$b).$ds); 187 | return $this->do_failure(); 188 | } 189 | } 190 | 191 | elseif (strtolower($eval) == "empty") 192 | { 193 | if (empty($a)) 194 | { 195 | $this->log(((string)$a)." is empty".$ds); 196 | return $this->do_success(); 197 | } 198 | else 199 | { 200 | $this->log("! ".((string)$a)." is not empty".$ds); 201 | return $this->do_failure(); 202 | } 203 | } 204 | 205 | elseif (strtolower($eval) == "null") 206 | { 207 | if (is_null($a)) 208 | { 209 | $this->log(((string)$a)." is null".$ds); 210 | return $this->do_success(); 211 | } 212 | else 213 | { 214 | $this->log("! ".((string)$a)." is not null".$ds); 215 | return $this->do_failure(); 216 | } 217 | } 218 | 219 | elseif (strtolower($eval) == "true") 220 | { 221 | if ($a) 222 | { 223 | $this->log(((string)$a)." is true".$ds); 224 | return $this->do_success(); 225 | } 226 | else 227 | { 228 | $this->log("! ".((string)$a)." is false".$ds); 229 | return $this->do_failure(); 230 | } 231 | } 232 | 233 | elseif (strtolower($eval) == "false") 234 | { 235 | if (!$a) 236 | { 237 | $this->log(((string)$a)." is false".$ds); 238 | return $this->do_success(); 239 | } 240 | else 241 | { 242 | $this->log("! ".((string)$a)." is true".$ds); 243 | return $this->do_failure(); 244 | } 245 | } 246 | 247 | elseif (strtolower($eval) == "in_array") 248 | { 249 | if (in_array($a,$b)) 250 | { 251 | $this->log(((string)$a)." is within the array".$ds); 252 | return $this->do_success(); 253 | } 254 | else 255 | { 256 | $this->log("! ".((string)$a)." is not within the array".$ds); 257 | return $this->do_failure(); 258 | } 259 | } 260 | 261 | elseif (strtolower($eval) == "not_in_array") 262 | { 263 | if (!in_array($a,$b)) 264 | { 265 | $this->log(((string)$a)." is not within the array".$ds); 266 | return $this->do_success(); 267 | } 268 | else 269 | { 270 | $this->log("! ".((string)$a)." is within the array".$ds); 271 | return $this->do_failure(); 272 | } 273 | } 274 | 275 | else 276 | { 277 | return false; 278 | } 279 | } 280 | 281 | private function do_success() 282 | { 283 | global $__TEST_SUITE_RESULTS; 284 | if (isset($__TEST_SUITE_RESULTS)){ 285 | $__TEST_SUITE_RESULTS["Successes"]++; 286 | $__TEST_SUITE_RESULTS["Successes_List"][] = array("title" => $title, "message" => $this->LastLogMessage); 287 | } 288 | $this->Successes[] = $this->LastLogMessage; 289 | return true; 290 | } 291 | 292 | private function do_failure() 293 | { 294 | global $__TEST_SUITE_RESULTS; 295 | if (isset($__TEST_SUITE_RESULTS)){ 296 | $__TEST_SUITE_RESULTS["Failures"]++; 297 | $__TEST_SUITE_RESULTS["Failures_List"][] = array("title" => $title, "message" => $this->LastLogMessage); 298 | } 299 | $this->Failures[] = $this->LastLogMessage; 300 | return false; 301 | } 302 | 303 | public function end() 304 | { 305 | $this->MessageDepth = 0; 306 | 307 | if (count($this->Successes) + count($this->Failures) > 0) 308 | { 309 | $this->log(""); 310 | $this->log($this->colors->getColoredString("Summary: ", "cyan")); 311 | $duration = (time() - $this->StartTime); 312 | $timeString = $this->secondsToWords($duration); 313 | $this->log("Test suite [".(count($this->Successes) + count($this->Failures))."] complete in ".$timeString); 314 | $this->log($this->colors->getColoredString(count($this->Successes)." successes","green", null)); 315 | if (count($this->Failures) == 0) 316 | { 317 | $this->log($this->colors->getColoredString(count($this->Failures)." failures","green", null)); 318 | } 319 | else 320 | { 321 | $this->log($this->colors->getColoredString(count($this->Failures)." failures","red")); 322 | } 323 | foreach($this->Failures as $fail) 324 | { 325 | $this->log($this->colors->getColoredString("Failure: ".$fail,"red")); 326 | } 327 | } 328 | 329 | if ($this->ToDBSave) { $this->log_task_output(run_task("RestoreDBSaveState")); } 330 | } 331 | 332 | public function log($line) 333 | { 334 | global $CONFIG; 335 | $log_folder = 336 | $this->LastLogMessage = $line; 337 | 338 | $i = 0; 339 | while($i < $this->MessageDepth) 340 | { 341 | $line = " ".$line; 342 | $i++; 343 | } 344 | 345 | if ($line[0] === "\\") 346 | { 347 | $line = $line."\r\n"; 348 | } 349 | else 350 | { 351 | $line = date("Y-m-d H:i:s")." | ".$line."\r\n"; 352 | } 353 | 354 | if(isset($CONFIG['TestLog'])) 355 | { 356 | $fh = fopen($CONFIG['TestLog'], 'a'); 357 | fwrite($fh, $line); 358 | fclose($fh); 359 | } 360 | 361 | if (isset($_SERVER['SERVER_ADDR'])) 362 | { 363 | $line = str_replace("\r\n","
",$line); 364 | $line = str_replace(" ","  ",$line); 365 | } 366 | echo $line; 367 | 368 | return true; 369 | } 370 | 371 | public function context($contect_message, $depth = 1) 372 | { 373 | $this->MessageDepth = $depth; 374 | $this->log($this->colors->getColoredString("Context: ".$contect_message,"purple")); 375 | $this->MessageDepth = $depth + 1; 376 | } 377 | 378 | private function secondsToWords($seconds) 379 | { 380 | /*** return value ***/ 381 | $ret = ""; 382 | 383 | /*** get the hours ***/ 384 | $hours = intval(intval($seconds) / 3600); 385 | if($hours > 0) 386 | { 387 | $ret .= "$hours hours "; 388 | } 389 | /*** get the minutes ***/ 390 | $minutes = bcmod((intval($seconds) / 60),60); 391 | if($hours > 0 || $minutes > 0) 392 | { 393 | $ret .= "$minutes minutes "; 394 | } 395 | 396 | /*** get the seconds ***/ 397 | $seconds = bcmod(intval($seconds),60); 398 | $ret .= "$seconds seconds"; 399 | 400 | return $ret; 401 | } 402 | } 403 | } 404 | 405 | ?> -------------------------------------------------------------------------------- /SPEC/system/general.php: -------------------------------------------------------------------------------- 1 | context("APIRequestsRemaining should decrement on subsequent loads"); 13 | $PostArray = array("OutputType" => "PHP"); 14 | $APIDATA = $T->api_request($PostArray); 15 | $first = $APIDATA["APIRequestsRemaining"]; 16 | $T->assert(">",$first,0); 17 | $APIDATA = $T->api_request($PostArray); 18 | $second = $APIDATA["APIRequestsRemaining"]; 19 | $T->assert(">",$second,0); 20 | $T->assert("<",$second,$first); 21 | 22 | $T->context("computation time should be > 0s but less than 10s for rendering no Action"); 23 | $PostArray = array("OutputType" => "PHP", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 24 | $APIDATA = $T->api_request($PostArray); 25 | $ComputationTime = $APIDATA["ComputationTime"]; 26 | $T->assert(">",$ComputationTime,0); 27 | $T->assert("<",$ComputationTime,10); 28 | 29 | $T->context("I should have an IP address"); 30 | $PostArray = array("OutputType" => "PHP", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 31 | $APIDATA = $T->api_request($PostArray); 32 | $IP = $APIDATA["IP"]; 33 | $T->assert("==",$IP,"localhost"); 34 | 35 | $T->context("The sever should have an IP address and a ServerName"); 36 | $PostArray = array("OutputType" => "PHP", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 37 | $APIDATA = $T->api_request($PostArray); 38 | $ServerAddress = $APIDATA["ServerAddress"]; 39 | $T->assert(">",strlen($APIDATA["ServerAddress"]),0); 40 | $T->assert(">",strlen($APIDATA["ServerName"]),0); 41 | 42 | $T->context("The name of the Action should be returned if a correct action is passed, and not otherwise"); 43 | $PostArray = array("OutputType" => "PHP", "Action" => "DescribeActions", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 44 | $APIDATA = $T->api_request($PostArray); 45 | $T->assert("==",$APIDATA["Action"],"DescribeActions"); 46 | $PostArray = array("OutputType" => "PHP", "Action" => "NOT_AN_ACTION", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 47 | $APIDATA = $T->api_request($PostArray); 48 | $T->assert("==",$APIDATA["Action"],"Unknown Action"); 49 | 50 | $T->context("Only meaningful PARAMS that are passed should be returned"); 51 | $PostArray = array("OutputType" => "PHP", "Action" => "TheAction", "ADumbParam" => "Dumb", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 52 | $APIDATA = $T->api_request($PostArray); 53 | $Params = $APIDATA["Params"]; 54 | $T->assert("in_array",'TheAction',$Params); 55 | $T->assert("not_in_array",'Dumb',$Params); 56 | 57 | 58 | $T->end(); 59 | 60 | ?> -------------------------------------------------------------------------------- /SPEC/system/output_types.php: -------------------------------------------------------------------------------- 1 | context("The API should return various OutputTypes"); 12 | 13 | $T->context("PHP",2); 14 | $PostArray = array("OutputType" => "PHP", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 15 | $APIDATA = $T->api_request($PostArray); 16 | $T->assert(">",count($APIDATA),0); 17 | $T->assert("==",$APIDATA["ERROR"],"That Action cannot be found. Did you send the 'Action' parameter? List Actions with Action=DescribeActions"); 18 | 19 | $T->context("JSON",2); 20 | $PostArray = array("OutputType" => "JSON", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 21 | $APIDATA = $T->api_request($PostArray); 22 | $JSON_resp = json_decode($T->get_raw_api_respnse(), true); 23 | $T->assert(">",count($JSON_resp),0); 24 | $T->assert("==",$JSON_resp["ERROR"],"That Action cannot be found. Did you send the 'Action' parameter? List Actions with Action=DescribeActions"); 25 | 26 | $T->context("XML",2); 27 | $PostArray = array("OutputType" => "XML", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 28 | $APIDATA = $T->api_request($PostArray); 29 | $XML_resp = simplexml_load_string($T->get_raw_api_respnse()); 30 | $T->assert(">",count($XML_resp),0); 31 | $T->assert("==",$XML_resp->ERROR,"That Action cannot be found. Did you send the 'Action' parameter? List Actions with Action=DescribeActions"); 32 | 33 | $T->context("LINE",2); // CONSOLE and LINE are similar 34 | $PostArray = array("OutputType" => "LINE", "LimitLockPass" => $CONFIG['CorrectLimitLockPass']); 35 | $APIDATA = $T->api_request($PostArray); 36 | $Lines = explode("\r\n",$T->get_raw_api_respnse()); 37 | $T->assert(">",count($Lines),0); 38 | $T->assert("==",$Lines[3],"Action: Unknown Action"); 39 | $T->assert("==",$Lines[10],"ERROR: That Action cannot be found. Did you send the 'Action' parameter? List Actions with Action=DescribeActions"); 40 | 41 | $T->end(); 42 | 43 | ?> -------------------------------------------------------------------------------- /examples/api_explorer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | PHP DAVE API: API Explorer 4 | 22 | 23 | 128 | 129 | 130 | 131 | 132 |
133 |

PHP DAVE API: API Explorer

134 |
135 | Action:
136 | 137 |

138 |
139 |
140 |
Loading...
141 |
142 | 143 | -------------------------------------------------------------------------------- /examples/chat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | PHP DAVE API: Chat Example 4 | 22 | 23 | 128 | 129 | 130 | 131 | 132 |
133 |

PHP DAVE API: Chat Example

134 |
135 |

Chat Entry:

136 |
137 | Name: 138 | LobbyKey: 139 | Message: 140 | 141 |
142 |

New Lobby:

143 |
144 | LobbyName: 145 | 146 |
147 |
148 |
149 |

Messages for {nothing}:

150 |
No Messages Yet. Join a Lobby.
151 |
152 |
153 | 154 | -------------------------------------------------------------------------------- /examples/describe_actions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | PHP DAVE API: Describe Actions Example 4 | 22 | 23 | 80 | 81 | 82 | 83 | 84 |
85 |

PHP DAVE API: Describe Actions

86 |
Loading...
87 |
88 | 89 | -------------------------------------------------------------------------------- /humans.txt: -------------------------------------------------------------------------------- 1 | /* TEAM */ 2 | Project Lead: Evan Tahler 3 | Site: http://evantahler.com 4 | Twitter: @GordoMandoza 5 | 6 | /* CONTRIBUTORS */ 7 | The person who coined the term "D.A.V.E." and Architecture Contributor: Erica Sandbothe 8 | Site: http://www.evilgeniusdesigns.com/ 9 | 10 | Architecture Contributor: David Evans 11 | Site: http://campevans.net/ 12 | Twitter: @spaceLenny 13 | 14 | /* THANKS */ 15 | mySQL-foo: Daniel Chetlin 16 | Twitter: @dwma 17 | 18 | Original Inception, Documentation Help: Kyle Prestenback 19 | Twitter: @theotherkyle 20 | 21 | Original Inception: Jeff Ashbrook 22 | Twitter: @JefeMcOwnage 23 | 24 | 25 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Don't Be a Jerk: The Open Source Software License. 2 | Last Update: November 30, 2011 3 | 4 | This software is free and open source. 5 | I want to keep this simple. Here goes: 6 | 7 | * This is free software. I will never charge you to use, license, or obtain this software. Doing so would make me a jerk. 8 | * I will never take down or start charing for what is available today. Doing so would make me a jerk. 9 | * You may use this code (and by code I mean *anything* contained within in this project) for whatever you want. Personal use, Educational use, Corporate use, Military use, and all other uses are OK! Limiting how you can use something free would make me a jerk. 10 | * I offer no warrantee on anything, ever. I've tried to ensure that there are no gaping security holes where using this software might automatically send your credit card information to aliens or erase your entire hard drive, but it might happen. I'm sorry. However, I warned you, so you can't sue me. Suing people over free software would make you a jerk. 11 | * If you find bugs, it would be nice if you let me know so I can fix them. You don't have to, but not doing so would make you a jerk. 12 | * Speaking of bugs, I am not obligated to fix anything nor am I obligated to add a feature for you. Feeling entitled about free software would make you a jerk. 13 | * If you add a cool feature or fix a bug, it would be nice if you passed it back to the project. You don't have to, but not doing so would make you a jerk. The repository/site you obtained this software from should contain a way for you to contact me. Contributing to open source makes you awesome! 14 | * If you use this software, you don't have to give me any credit, but it would be nice. 15 | 16 | Don't be a jerk. 17 | Enjoy your free software! -------------------------------------------------------------------------------- /readme.markdown: -------------------------------------------------------------------------------- 1 | *I will not be doing more work on this framework. However, many of the philosophies and syntax are used in the [node.js](http://nodejs.org) successor to this project. Check it out @ [https://github.com/evantahler/actionHero](https://github.com/evantahler/actionHero)* 2 | *If you are interested in helping to maintain this project, please open an Issue or Pull Request, and let me know!* 3 | 4 | Who is _DAVE_? 5 | ============ 6 | 7 | DAVE is a minimalist, multi-node, transactional API framework written in PHP 8 | 9 | Dave contains an end-to-end API test suite for TDD, a Task model, an Active Database Model, and a stand-alone development server (written in PHP) to get you started. 10 | 11 | DAVE is an acronym that stands for Delete, Add, Edit, and View. These four methods make up the core functionality of many transactional web applications. The DAVE API aims to simplify and abstract may of the common tasks that these types of APIs require. DAVE does the work for you, and he's not CRUD. Dave was built to be both easy to use, but to be as simple as possible. I was tired of bloated frameworks that were designed to be monolithic applications which include M's, V's, and C's together in a single running application. As applications grow and become more 'service oriented', this is the eventual route which many applications go. I wanted to make is as simple as possible to create a new application with this mindset, and to allow for future flexibility. 12 | 13 | The DAVE API defines a single access point and accepts GET, POST, or COOKIE input. You define "Action's" that handle the input, such as "AddUser" or "GeoLocate". The DAVE API is NOT "RESTful", in that it does not use the normal verbs (Get, Put, etc) and uses a single /path/. This was chosen to make it as simple as possible for devices/users to access the functions, including low-level embedded devices which may have trouble with all the HTTP verbs. To see how simple it is to handle basic actions, this package comes with a basic user system included. Look in `/Actions/examples` to see the logic behind adding, editing, viewing, and deleting users. This includes log in. RESTful paths are optional if you really must have them, and be defined per Action. 14 | 15 | The DAVE API understands 2 types of security methodology. "Public" actions can be called by anyone, and then can implement optional user-based security (checking userIDs and PasswordHashes?). Optionally, certain Actions can be defined as "Private", and will require a defined developer to authenticate with every request. This requires your developers to provide an MD5 hash of their APIKey and private DeveloperID to authenticate with. You can mix private and public actions. Of course, you can make your own actions for this as well! 16 | 17 | Dave contains an end-to-end API test suite for TDD, a Task model, an Active Database Model, and a stand-alone development server (written in just PHP) to get you started. 18 | 19 | Philosophical Questions 20 | ----------------------- 21 | 22 | If you have ever asked these questions of other web-frameworks, then DAVE might be the right fit for you: 23 | 24 | * Why do we really need a controller? 25 | * Why are linear actions so hidden in object abstraction? 26 | * Why can't I de-couple my M's, V's and C's? 27 | * Why can't my test suite use the real application? 28 | * Is there an option for a non-RESTful API? 29 | * Why isn't there an easier way to develop and test locally with PHP? 30 | * Why are there no modern PHP API Frameworks?! 31 | 32 | Features 33 | -------- 34 | * Abstraction of basic DAVE (Delete, Add, Edit, View) actions 35 | * Active Database Modeling on-the-fly or fixed per your requirements 36 | * (optional) Objects for Database entities with DAVE abstraction 37 | * Built with a Multi-Node system in mind, but works great on a single machine as well 38 | * Developer-based authentication in tandem with user-level authentication 39 | * Rate Limiting for client connections 40 | * Class-based abstraction of MySQL connections 41 | * Built-in support for multiple types of Caching (Flat File, MySQL, memcache) 42 | * CRON processing of delayed events 43 | * Simple error handling and input sanitization 44 | * XML, JSON, Serialized PHP output types built in 45 | * Task Classes to automate periodic management and to ease development 46 | * End-to-end spec testing framework for the API including custom assertions 47 | 48 | Stand-Alone Development Webserver written in PHP 49 | ----------------------------------------------------------------------------------- 50 | To help with development, a single-threaded multi-request webserver is a part of this project. This will allow you to locally run this framework in "development mode". This webserver is written entirely in PHP and has support for basic static file-types (css, js, images, html) along with the sand-boxed execution of PHP scripts (including all of those required for this framework.). The server currently provides the normal $_GET, $_POST, $_COOKIE, $_REQUEST arrays and a basic emulation of $SERVER. Due to metaprogramming limitations in the default PHP installs on most servers/machines, it is impossible to modify the behavior of header() and setcookie(). To remedy this, please use _header() and _setcookie() in your DAVE projects. These functions will first attempt to use the default versions of these functions, and if they fail (AKA when using the StandAlone server), will emulate their behavior in other ways. This server implementation was inspired by nginx and rails unicorns, and makes use of spawning OS-level processes to do the heavy lifting for each request. 51 | 52 | You certainly don't need to use the bundled SERVER to run dave. For production deployment, upload DAVE to `/var/www/html` (or however you normally deploy). The SERVER was included to allow for local test-driven development common to other frameworks/languages to which the modern web developer may be accustomed too. 53 | 54 | Run "php SERVER.php" from within the project directory to get started. Point your browser at http://localhost:3000 55 | 56 | Requirements 57 | ------------ 58 | * PHP 5.3+ 59 | * MySQL 5+ 60 | 61 | However, for production deployment, your traditional LAMP stack is best. 62 | 63 | 64 | Actions you can try [[&Action=..]] which are included in the framework: 65 | ----------------------------------------------------------------------- 66 | * DescribeActions: I will list all the actions available to the API 67 | * DescribeTables: I am an introspection method that will show the results of the auto-described available tables and cols. I will show weather or not a col is required and if it is unique 68 | * CacheTest: Send a Hash [[ &Hash=MyString ]] and I will first store it in the cache, and on subsequent calls retrieve the vale from the cache until expired. Change the value of the Hash and note the old value will be displayed until it expires 69 | * LogIn: Example user system. Follow returned error messages. 70 | * UserAdd: Example user system. Follow returned error messages. 71 | * UserDelete: Example user system. Follow returned error messages. 72 | * UserEdit: Example user system. Follow returned error messages. 73 | * UserView: Example user system. Follow returned error messages. 74 | * ObjectTest: An example of on-the-fly database object manipulation. Check the code for this file to see how simple it is. 75 | * CookieTest: Will set cookies in your browser. Use this to test SERVER's implementation of _setcookie() 76 | * SlowAction: A simple action that will sleep for a number of seconds. Use this to test SERVER's non-blocking implementation by making a slow request, and then other requests to ensure that a slow request will not block other actions from processing. 77 | 78 | 79 | QuickStart 80 | ---------- 81 | You can get started on your local machine in 5 minutes! This tutorial is for Unix-like machines (OSX OK!). We'll be using the included stand-alone server for development. You certainly don't need to use the bundled SERVER to run dave. For production deployment, upload DAVE to `/var/www/html` (or however you normally deploy). 82 | 83 | * Instal PHP (OSX users already have it, Linux folks use yum/apt-get install php5) 84 | * Install mySQL 5 [OSX: http://www.mysql.com/] [Linux: yum/apt-get install mysql-server mysql-client) 85 | * Get clone this project 86 | * `git clone git://github.com/evantahler/PHP-DAVE-API.git /path/where/you/want/it` OR just hit the `download` button above 87 | * Rename `/API/CONFIG.example.php` to `/API/CONFIG.php` 88 | * Configure CONFIG.php. Assuming we will be running mySQL locally as root with no password, all you should need to change is: 89 | * `$CONFIG['SystemTimeZone']` (check http://www.php.net/manual/en/timezones.php for how to define your timezone) 90 | * `$CONFIG['App_dir']` (this is where the /API folder is) 91 | * setup mySQL for DAVE 92 | * create a mysql database called "daveapi" 93 | * (from the command line) 94 | * `mysql -u root` 95 | * `create database daveapi;` 96 | * `exit` 97 | * load in the default tables 98 | * `mysql -u root daveapi < BaseDBs/API_WITH_USER_TABLE.sql` 99 | * Install the CRON.php file to run on a set frequency. Note that paths have to be absolute. 100 | ** `crontab -e` 101 | ** `*/1 * * * * /usr/bin/php /path/to/CRON.php > /path/to/CRON_LOG.txt` 102 | * start up the webserver 103 | * `php /SERVER/SERVER.php` 104 | * Visit Dave 105 | * Browser: `http://localhost:3000&OutputType=XML` 106 | * CURL + time: `time curl -v http://127.0.0.1:3000/ -d "OutputType=XML"` 107 | * Use the API console `script/api --Action=DescribeActions` 108 | 109 | That's it! You should see JSON and XML output that describes all of the actions that the server could preform, and an Error asking you to supply an action. Give `http://localhost:3000/?OutputType=XML&Action=ObjectTest` or `http://localhost:3000/?OutputType=PHP&Action=SlowAction` a try to see some basic examples. 110 | -------------------------------------------------------------------------------- /script/api: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | -------------------------------------------------------------------------------- /script/cron: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | -------------------------------------------------------------------------------- /script/server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | -------------------------------------------------------------------------------- /script/spec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | -------------------------------------------------------------------------------- /script/task: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | --------------------------------------------------------------------------------