Technical description of the REST server
EasyCoder includes a small REST server with a range of useful features for file management and access to some database tables. However, this is not enough for many projects, which have special data handling needs. So we have an extension mechanism that allows you to add extra functionality without modifying the basic REST server.
You can find the REST server in the plugin folder of any EasyCoder installation or at our GitHub repository.
The added functionality goes in a file called rest-local.php, and it's kept in a folder called "easycoder" at the root of your WordPress installation. There are 2 entry points, one for GET and the other for POST, and these are called if the endpoint requested has an underscore ('_') where the table name would otherwise be.
Most of the content of messages to and from the server are JSON formatted.
The listing below is the rest-local.php file for Here On The Map and is included for completeness. It should be largely self-documenting, but most of the time you will only want to know the syntax of each endpoint, which is provided as a comment for each one.
<?php date_default_timezone_set("Europe/London"); // This is the local extension for the HereOnTheMap REST server. // It contains endpoints for accessing the various tables used by the site. // For consistency, all endpoints have the same format: // {site root}/wp-content/plugins/easycoder/rest.php/_/{table name}/{action}[/...] ///////////////////////////////////////////////////////////////////////// // GET function get_local($conn, $request) { $table = $request[0]; array_shift($request); $action = $request[0]; array_shift($request); switch ($table) { case 'ec_users': switch ($action) { case 'get': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_users/get/{email} if ($request[0]) { logger("SELECT * from $table WHERE email='" . $request[0] . "'"); $result = query($conn, "SELECT * from $table WHERE email='" . $request[0] . "'"); if ($row = mysqli_fetch_object($result)) { $response->id = $row->id; $response->email = $row->email; $response->password = $row->password; $response->name = $row->name; $response->home = $row->year . '/' . str_pad($row->day, 3, '0', STR_PAD_LEFT); print json_encode($response); } } else { http_response_code(404); print "{\"message\":\"REST: Email is empty.\"}"; } break; default: http_response_code(404); print "{\"message\":\"REST: Unknown action '$action' for '$table'.\"}"; break; } break; case 'ec_markers': switch ($action) { case 'id': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_markers/id/{id} $id = $request[0]; logger("SELECT * from $table WHERE id=$id"); $result = query($conn, "SELECT * from $table WHERE id=$id"); if ($row = mysqli_fetch_object($result)) { if ($row->private == 1) { $response->id = 0; } else { $response->id = $id; $response->email = $row->email; $response->latitude = $row->latitude; $response->longitude = $row->longitude; $response->zoom = $row->zoom; $response->title = $row->title; $response->private = $row->private; } print json_encode($response); } mysqli_free_result($result); break; case 'get': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_markers/get/{data} if ($request[0]) { $json = json_decode($request[0]); $email = $json->email; $tag = $json->tag; $mymail = $json->mymail; $south = $json->south; $west = $json->west; $north = $json->north; $east = $json->east; $zoom = floatval($json->zoom); $minus = floatval($json->minus); $minZoom = $zoom - $minus; if ($minZoom < 0) { $minZoom = 0; } $join = ''; $where = "latitude>='$south' AND latitude<'$north' AND longitude>='$west' AND longitude<'$east'" ." AND zoom>=$minZoom AND (private=0 OR email='$mymail')"; if ($email) { $where .= " AND email='$email' AND (email='$mymail' OR story!='')"; } else { if ($tag) { $join = " INNER JOIN ec_tags ON (ec_tags.tag='$tag' AND $table.id=ec_tags.marker)"; } $where .= " AND (email='$mymail' OR story!='')"; } // logger("SELECT $table.* from $table$join WHERE $where ORDER BY zoom ASC, RAND() LIMIT 20"); $result = query($conn, "SELECT $table.* from $table$join WHERE $where ORDER BY zoom ASC, RAND() LIMIT 20"); $response = array(); while ($row = mysqli_fetch_object($result)) { $marker = null; $marker->id = $row->id; $marker->email = $row->email; $marker->latitude = $row->latitude; $marker->longitude = $row->longitude; $marker->zoom = $row->zoom; $marker->title = $row->title; $marker->private = $row->private; array_push($response, $marker); } mysqli_free_result($result); print json_encode($response); } else { http_response_code(404); print "{\"message\":\"REST: Data is empty.\"}"; } break; case 'story': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_markers/story/{id} $id = $request[0]; $result = query($conn, "SELECT tag from ec_tags WHERE marker=$id ORDER BY tag ASC"); $tags = array(); while ($row = mysqli_fetch_object($result)) { array_push($tags, $row->tag); } mysqli_free_result($result); logger("SELECT * from $table INNER JOIN ec_users ON ec_users.email = $table.email WHERE $table.id=$id"); $result = query($conn, "SELECT * from $table INNER JOIN ec_users ON ec_users.email = $table.email WHERE $table.id=$id"); if ($row = mysqli_fetch_object($result)) { $response->author = $row->name; $response->tags = $tags; $response->story = $row->story; } mysqli_free_result($result); print json_encode($response); break; default: http_response_code(404); print "{\"message\":\"REST: Unknown action '$action' for '$table'.\"}"; break; } break; default: http_response_code(404); print "{\"message\":\"REST: Unknown table '$table'.\"}"; break; } } ///////////////////////////////////////////////////////////////////////// // POST function post_local($conn, $request) { $ts = time(); $table = $request[0]; array_shift($request); $action = $request[0]; array_shift($request); switch ($table) { case 'ec_users': switch ($action) { case 'set': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_users/set header("Content-Type: application/json"); $value = stripslashes(file_get_contents("php://input")); $json = json_decode($value); $email = $json->email; $password = $json->password; $name = $json->name; // Check if this user is already present $result = query($conn, "SELECT id FROM $table WHERE email='$email'"); if ($row = mysqli_fetch_object($result)) { // Yes, so update the record logger("UPDATE $table SET password='$password',name='$name',ts=$ts WHERE email='$email'"); query($conn, "UPDATE $table SET password='$password',name='$name',ts=$ts WHERE email='$email'"); } else { // No, so add a new record $year = date('Y'); $day = str_pad(date('z'), 3, '0', STR_PAD_LEFT); logger("INSERT INTO $table (email,password,name,year,day,ts) VALUES ('$email','$password','$name','$year','$day','$ts')"); query($conn, "INSERT INTO $table (email,password,name,year,day,ts) VALUES ('$email','$password','$name','$year','$day','$ts')"); mkdir("../../../resources/$year/$day", 0777, true); } mysqli_free_result($result); break; default: http_response_code(400); print "{\"message\":\"REST: Unknown action '$action' for '$table'.\"}"; break; } break; case 'ec_markers': switch ($action) { case 'set': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_markers/set header("Content-Type: application/json"); $value = stripslashes(file_get_contents("php://input")); $json = json_decode($value); $email = $json->email; $latitude = $json->latitude; $longitude = $json->longitude; $zoom = $json->zoom; $title = $json->title; $story = $json->story; // Check if this marker is already present $result = query($conn, "SELECT id FROM $table WHERE email='$email' AND latitude=$latitude AND longitude=$longitude"); if ($row = mysqli_fetch_object($result)) { // Yes, so update the record $id = $row->id; logger("UPDATE $table SET latitude='$latitude',longitude='$longitude',zoom='$zoom',title='$title',story='$story',ts=$ts WHERE id=$id"); query($conn, "UPDATE $table SET latitude='$latitude',longitude='$longitude',zoom='$zoom',title='$title',story='$story',ts=$ts WHERE id=$id"); mysqli_free_result($result); } else { // No, so add a new marker // First look for a deleted record mysqli_free_result($result); $result = query($conn, "SELECT id FROM $table WHERE email=''"); if ($row = mysqli_fetch_object($result)) { $id = $row->id; logger("UPDATE $table SET email='$email',latitude='$latitude',longitude='$longitude',zoom='$zoom',title='$title',story='$story',ts=$ts WHERE id=$id"); query($conn, "UPDATE $table SET email='$email',latitude='$latitude',longitude='$longitude',zoom='$zoom',title='$title',story='$story',ts=$ts WHERE id=$id"); } else { logger("INSERT INTO $table (email,latitude,longitude,zoom,title,story,ts) VALUES ('$email','$latitude','$longitude','$zoom','$title','$story','$ts')"); query($conn, "INSERT INTO $table (email,latitude,longitude,zoom,title,story,ts) VALUES ('$email','$latitude','$longitude','$zoom','$title','$story','$ts')"); } } break; case 'update': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_markers/update header("Content-Type: application/json"); $value = stripslashes(file_get_contents("php://input")); $json = json_decode($value); $id = $json->id; $title = $json->title; $story = $json->story; $private = $json->private; // Update the record logger("UPDATE $table SET title='$title',story='$story',private='$private',ts=$ts WHERE id=$id"); query($conn, "UPDATE $table SET title='$title',story='$story',private='$private',ts=$ts WHERE id=$id"); ec_process_tags($conn, $id, $json->tags); break; case 'delete': // Endpoint: {site root}/wp-content/plugins/easycoder/rest.php/_/ec_markers/delete/ header("Content-Type: application/json"); $value = stripslashes(file_get_contents("php://input")); $json = json_decode($value); $id = $json->id; $email = $json->email; // Delete the record by clearing the email field logger("UPDATE $table SET email='' WHERE id=$id AND email='$email'"); query($conn, "UPDATE $table SET email='' WHERE id=$id AND email='$email'"); break; default: http_response_code(400); print "{\"message\":\"REST: Unknown action '$action' for '$table'.\"}"; break; } break; default: http_response_code(404); print "{\"message\":\"REST: Unknown table '$table'.\"}"; break; } } function ec_process_tags($conn, $marker, $tags) { $result = $conn->query("UPDATE ec_tags SET tag='' WHERE marker=$marker"); $tags = explode(',', $tags); foreach ($tags as $tag) { $tag = trim($tag); $result = $conn->query("SELECT id FROM ec_tags WHERE tag=''"); if ($row = mysqli_fetch_object($result)) { $id = $row->id; $conn->query("UPDATE ec_tags SET marker=$marker,tag='$tag' WHERE id=$id"); } else { $conn->query("INSERT INTO ec_tags (marker,tag) VALUES ($marker,'$tag')"); } mysqli_free_result($result); } } ?>