Further progress on refining the REST server side code.

1) Deal in fully qualified URL resources through the rest
   interface.  All rest methods are now passed the complete url in
   request->url.

2) Create rest::resolve() which lets individual resource definition
   code convert a full url into the appropriate matching resource.
   Implement gallery_rest::resolve() and tag_rest::resolve()

3) Reimplement tag_rest's get() and post() methods.  They're much
   simpler now.

4) Implement the tags_rest helper which supports working with the
   entire tags collection.
This commit is contained in:
Bharat Mediratta
2010-01-04 21:48:21 -08:00
parent 0e3327bca7
commit 3fffa18e65
6 changed files with 97 additions and 60 deletions
+9 -5
View File
@@ -37,14 +37,14 @@
class gallery_rest_Core {
static function get($request) {
$item = url::get_item_from_uri($request->path);
$item = rest::resolve($request->url);
access::required("view", $item);
return json_encode($item->as_array());
return rest::reply($item->as_array());
}
static function put($request) {
$item = url::get_item_from_uri($request->path);
$item = rest::resolve($request->url);
access::required("edit", $item);
$params = $request->params;
@@ -60,7 +60,7 @@ class gallery_rest_Core {
}
static function post($request) {
$parent = url::get_item_from_uri($request->path);
$parent = rest::resolve($request->url);
access::required("edit", $parent);
$params = $request->params;
@@ -90,10 +90,14 @@ class gallery_rest_Core {
}
static function delete($request) {
$item = url::get_item_from_uri($request->path);
$item = rest::resolve($request->url);
access::required("edit", $item);
$item->delete();
return rest::reply();
}
static function resolve($path) {
return url::get_item_from_uri($path);
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ class Rest_Controller extends Controller {
$request->method = strtolower($input->server("HTTP_X_GALLERY_REQUEST_METHOD", $method));
$request->access_token = $input->server("HTTP_X_GALLERY_REQUEST_KEY");
$request->path = implode("/", $args);
$request->url = url::abs_current(true);
try {
rest::set_active_user($request->access_token);
+20
View File
@@ -51,4 +51,24 @@ class rest_Core {
static function send_headers($exception) {
header("HTTP/1.1 " . $exception->getCode() . " " . $exception->getMessage());
}
/**
* Convert a REST url into an object.
* Eg: "http://example.com/gallery3/index.php/rest/gallery/Family/Wedding" -> Item_Model
*
* @param string the fully qualified REST url
* @return mixed the corresponding object (usually a model of some kind)
*/
static function resolve($url) {
$components = explode("/", substr($url, strlen(url::abs_site("rest"))), 3);
// The first component will be empty because of the slash between "rest" and the
// resource type.
$class = "$components[1]_rest";
if (!method_exists($class, "resolve")) {
throw new Kohana_404_Exception($url);
}
return call_user_func(array($class, "resolve"), !empty($components[2]) ? $components[2] : null);
}
}
+1 -1
View File
@@ -41,7 +41,7 @@ class tag_Core {
}
if (!$tag->has($item)) {
if (!$tag->add($item, $tag)) {
if (!$tag->add($item)) {
throw new Exception("@todo {$tag->name} WAS_NOT_ADDED_TO {$item->id}");
}
$tag->count++;
+18 -53
View File
@@ -18,71 +18,36 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class tag_rest_Core {
// If no arguments just return all the tags. If 2 or more then it is a path then
// return the tags for that item. But if its only 1, then is it a path or a tag?
// Assume a tag first, if nothing is found then try finding the item.
static function get($request) {
$resources = array();
switch (count($request->arguments)) {
case 0:
$tags = ORM::factory("tag")
->select("name", "count")
->order_by("count", "DESC");
if (!empty($request->limit)) {
$tags->limit($request->limit);
}
if (!empty($request->offset)) {
$tags->offset($request->offset);
}
$resources = array("tags" => array());
foreach ($tags->find_all() as $row) {
$resources["tags"][] = array("name" => $row->name, "count" => $row->count);
}
break;
case 1:
$resources = tag_rest::_get_items($request);
if (!empty($resources)) {
$resources = array("resources" => $resources);
break;
}
default:
$item = ORM::factory("item")
->where("relative_url_cache", "=", implode("/", $request->arguments))
->viewable()
->find();
if ($item->loaded()) {
$resources = array("tags" => tag::item_tags($item));
}
}
return rest::reply($resources);
return rest::reply(rest::resolve($request->url)->as_array());
}
static function post($request) {
if (empty($request->arguments) || count($request->arguments) != 1 || empty($request->path)) {
$tag = rest::resolve($request->url);
if (empty($request->params->url)) {
throw new Rest_Exception("Bad request", 400);
}
$path = $request->path;
$tags = explode(",", $request->arguments[0]);
$item = ORM::factory("item")
->where("relative_url_cache", "=", $path)
->viewable()
->find();
if (!$item->loaded()) {
throw new Kohana_404_Exception();
}
$item = rest::resolve($request->params->url);
if (!access::can("edit", $item)) {
throw new Kohana_404_Exception();
}
access::required("edit", $item);
tag::add($item, $tag->name);
foreach ($tags as $tag) {
tag::add($item, $tag);
}
return rest::reply();
}
static function resolve($tag_name) {
$tag = ORM::factory("tag")->where("name", "=", $tag_name)->find();
if (!$tag->loaded()) {
throw new Kohana_404_Exception();
}
return $tag;
}
// ------------------------------------------------------------
static function put($request) {
if (empty($request->arguments[0]) || empty($request->new_name)) {
throw new Rest_Exception("Bad request", 400);
+48
View File
@@ -0,0 +1,48 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class tags_rest_Core {
static function get($request) {
$data = array();
foreach (ORM::factory("tag")->find_all() as $tag) {
$data[$tag->name] = url::abs_site("rest/tags/" . rawurlencode($tag->name));
}
return rest::reply($data);
}
static function post($request) {
// @todo: what permission should be required to create a tag here?
// for now, require edit at the top level. Perhaps later, just require any edit perms,
// anywhere in the gallery?
access::required("edit", item::root());
if (empty($request->params->name)) {
throw new Rest_Exception("Bad Request", 400);
}
$tag = ORM::factory("tag")->where("name", "=", $request->params->name)->find();
if (!$tag->loaded()) {
$tag->name = $request->params->name;
$tag->count = 0;
$tag->save();
}
return rest::reply(array("url" => url::abs_site("rest/tag/" . rawurlencode($tag->name))));
}
}