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);
        }
    }
?>