summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBharat Mediratta <bharat@menalto.com>2010-01-22 00:27:00 -0800
committerBharat Mediratta <bharat@menalto.com>2010-01-22 00:27:00 -0800
commitbcf1caad1459a458a7923335a4a6bc521816de40 (patch)
treefc3815c13e079d0b1b25f3929dcb73f2de7ca927
parent3665391f8bbf40aa27acc816dc546237461e1cba (diff)
Reshape the rest code to be more consistent with regards to
relationships. Now when you view a resource, it has 4 top level elements: url: the url of this resource resource: array of key value pairs describing the resource members: array of urls to members of this collection relationships: array of array of members. Relationships are a special type of collection that links two different resources together. To remove a relationship, just DELETE its url. To create a relationship, POST to its collection. Individual modules can add their own relationships to any resource via a callback mechanism. Example: Array( [url] => http://g3.com/rest/item/1 [resource] => Array ( [id] => 1 [album_cover_item_id] => 4 [captured] => [created] => 1264056417 [description] => [height] => ... ) [members] => Array( [0] => http://g3.com/rest/item/2 [1] => http://g3.com/rest/item/3 [2] => http://g3.com/rest/item/4 [3] => http://g3.com/rest/item/5 ... ) [relationships] => Array( [tags] => Array ( [0] => http://g3.com/rest/tag_item/2,1 [1] => http://g3.com/rest/tag_item/23,1 ) ) )
-rw-r--r--modules/gallery/helpers/item_rest.php (renamed from modules/gallery/helpers/gallery_rest.php)28
-rw-r--r--modules/rest/controllers/rest.php2
-rw-r--r--modules/rest/helpers/rest.php50
-rw-r--r--modules/tag/helpers/tag.php14
-rw-r--r--modules/tag/helpers/tag_event.php12
-rw-r--r--modules/tag/helpers/tag_item_rest.php50
-rw-r--r--modules/tag/helpers/tag_rest.php43
-rw-r--r--modules/tag/helpers/tags_rest.php4
8 files changed, 148 insertions, 55 deletions
diff --git a/modules/gallery/helpers/gallery_rest.php b/modules/gallery/helpers/item_rest.php
index c5838ea5..edc44c45 100644
--- a/modules/gallery/helpers/gallery_rest.php
+++ b/modules/gallery/helpers/item_rest.php
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class gallery_rest_Core {
+class item_rest_Core {
/**
* For items that are collections, you can specify the following additional query parameters to
* query the collection. You can specify them in any combination.
@@ -72,10 +72,14 @@ class gallery_rest_Core {
$members = array();
foreach ($orm->find_all() as $child) {
- $members[] = rest::url("gallery", $child);
+ $members[] = rest::url("item", $child);
}
- return array("resource" => $item->as_array(), "members" => $members);
+ return array(
+ "url" => $request->url,
+ "resource" => $item->as_array(),
+ "members" => $members,
+ "relationships" => rest::relationships("item", $item));
}
static function put($request) {
@@ -94,9 +98,9 @@ class gallery_rest_Core {
$item->$key = $request->params->$key;
}
}
- $item->save();
-
- return array("url" => rest::url("gallery", $item));
+ if ($item->changed) {
+ $item->save();
+ }
}
static function post($request) {
@@ -131,8 +135,6 @@ class gallery_rest_Core {
default:
throw new Rest_Exception("Invalid type: $params->type", 400);
}
-
- return array("url" => rest::url("gallery", $item));
}
static function delete($request) {
@@ -142,11 +144,15 @@ class gallery_rest_Core {
$item->delete();
}
- static function resolve($path) {
- return url::get_item_from_uri($path);
+ static function resolve($id) {
+ $item = ORM::factory("item")->where("id", "=", $id)->find();
+ if (!access::can("view", $item)) {
+ throw new Kohana_404_Exception();
+ }
+ return $item;
}
static function url($item) {
- return url::abs_site("rest/gallery/" . $item->relative_url());
+ return url::abs_site("rest/item/{$item->id}");
}
}
diff --git a/modules/rest/controllers/rest.php b/modules/rest/controllers/rest.php
index 9f0bc5b3..ba996b84 100644
--- a/modules/rest/controllers/rest.php
+++ b/modules/rest/controllers/rest.php
@@ -56,7 +56,7 @@ class Rest_Controller extends Controller {
$handler_method = $request->method;
if (!method_exists($handler_class, $handler_method)) {
- throw new Rest_Exception("Forbidden", 403);
+ throw new Rest_Exception("Bad Request", 400);
}
try {
diff --git a/modules/rest/helpers/rest.php b/modules/rest/helpers/rest.php
index 85987ca1..fe704a9e 100644
--- a/modules/rest/helpers/rest.php
+++ b/modules/rest/helpers/rest.php
@@ -22,8 +22,16 @@ class rest_Core {
Session::abort_save();
if ($data) {
- header("Content-type: application/json");
- print json_encode($data);
+ if (Input::instance()->get("output_type") == "html") {
+ header("Content-type: text/html");
+ $html = preg_replace(
+ "#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t<]*)#ise", "'\\1<a href=\"\\2\" >\\2</a>'",
+ print_r($data, 1));
+ print "<pre>$html</pre>";
+ } else {
+ header("Content-type: application/json");
+ print json_encode($data);
+ }
}
}
@@ -64,7 +72,10 @@ class rest_Core {
/**
* Convert a REST url into an object.
- * Eg: "http://example.com/gallery3/index.php/rest/gallery/Family/Wedding" -> Item_Model
+ * Eg:
+ * http://example.com/gallery3/index.php/rest/item/35 -> Item_Model
+ * http://example.com/gallery3/index.php/rest/tag/16 -> Tag_Model
+ * http://example.com/gallery3/index.php/rest/tagged_item/1,16 -> [Tag_Model, Item_Model]
*
* @param string the fully qualified REST url
* @return mixed the corresponding object (usually a model of some kind)
@@ -88,15 +99,38 @@ class rest_Core {
/**
* Return an absolute url used for REST resource location.
- * @param string module name (eg, "gallery", "tags")
+ * @param string resource type (eg, "item", "tag")
* @param object resource
*/
- static function url($module, $resource) {
- $class = "{$module}_rest";
+ static function url() {
+ $args = func_get_args();
+ $resource_type = array_shift($args);
+
+ $class = "{$resource_type}_rest";
if (!method_exists($class, "url")) {
- throw new Exception("@todo MISSING REST CLASS: $class");
+ throw new Rest_Exception("Bad Request", 400);
+ }
+
+ $url = call_user_func_array(array($class, "url"), $args);
+ if (Input::instance()->get("output_type") == "html") {
+ $url .= "?output_type=html";
+ }
+ return $url;
+ }
+
+ static function relationships($resource_type, $resource) {
+ $results = array();
+ foreach (module::active() as $module) {
+ foreach (glob(MODPATH . "{$module->name}/helpers/*_rest.php") as $filename) {
+ $class = str_replace(".php", "", basename($filename));
+ if (method_exists($class, "relationships")) {
+ $results = array_merge(
+ $results,
+ call_user_func(array($class, "relationships"), $resource_type, $resource));
+ }
+ }
}
- return call_user_func(array($class, "url"), $resource);
+ return $results;
}
}
diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php
index c49a2d0f..9e59b527 100644
--- a/modules/tag/helpers/tag.php
+++ b/modules/tag/helpers/tag.php
@@ -91,16 +91,10 @@ class tag_Core {
* @return array
*/
static function item_tags($item) {
- $tags = array();
- foreach (db::build()
- ->select("name")
- ->from("tags")
- ->join("items_tags", "tags.id", "items_tags.tag_id", "left")
- ->where("items_tags.item_id", "=", $item->id)
- ->execute() as $row) {
- $tags[] = $row->name;
- }
- return $tags;
+ return ORM::factory("tag")
+ ->join("items_tags", "tags.id", "items_tags.tag_id", "left")
+ ->where("items_tags.item_id", "=", $item->id)
+ ->find_all();
}
static function get_add_form($item) {
diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php
index 6ee8e708..403ccd52 100644
--- a/modules/tag/helpers/tag_event.php
+++ b/modules/tag/helpers/tag_event.php
@@ -71,9 +71,13 @@ class tag_event_Core {
$('form input[id=tags]').autocomplete(
'$url', {max: 30, multiple: true, multipleSeparator: ',', cacheLength: 1});
});");
- $tag_value = implode(", ", tag::item_tags($item));
+
+ $tag_names = array();
+ foreach (tag::item_tags($item) as $tag) {
+ $tag_names[] = $tag->name;
+ }
$form->edit_item->input("tags")->label(t("Tags (comma separated)"))
- ->value($tag_value);
+ ->value(implode(", ", $tag_names));
}
static function item_edit_form_completed($item, $form) {
@@ -95,7 +99,9 @@ class tag_event_Core {
}
static function item_index_data($item, $data) {
- $data[] = join(" ", tag::item_tags($item));
+ foreach (tag::item_tags($item) as $tag) {
+ $data[] = $tag->name;
+ }
}
static function add_photos_form($album, $form) {
diff --git a/modules/tag/helpers/tag_item_rest.php b/modules/tag/helpers/tag_item_rest.php
new file mode 100644
index 00000000..cd9bb6fe
--- /dev/null
+++ b/modules/tag/helpers/tag_item_rest.php
@@ -0,0 +1,50 @@
+<?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 tag_item_rest_Core {
+ static function get($request) {
+ list ($tag, $item) = rest::resolve($request->url);
+ return array(
+ "url" => $request->url,
+ "members" => array(
+ rest::url("tag", $tag),
+ rest::url("item", $item)));
+ }
+
+ static function delete($request) {
+ list ($tag, $item) = rest::resolve($request->url);
+ $tag->remove($item);
+ $tag->save();
+ }
+
+ static function resolve($tuple) {
+ list ($tag_id, $item_id) = split(",", $tuple);
+ $tag = ORM::factory("tag")->where("id", "=", $tag_id)->find();
+ $item = ORM::factory("item")->where("id", "=", $item_id)->find();
+ if (!$tag->loaded() || !$item->loaded() || !$tag->has($item)) {
+ throw new Kohana_404_Exception();
+ }
+
+ return array($tag, $item);
+ }
+
+ static function url($tag, $item) {
+ return url::abs_site("rest/tag_item/{$tag->id},{$item->id}");
+ }
+}
diff --git a/modules/tag/helpers/tag_rest.php b/modules/tag/helpers/tag_rest.php
index 0226c6d3..d68cb73d 100644
--- a/modules/tag/helpers/tag_rest.php
+++ b/modules/tag/helpers/tag_rest.php
@@ -20,12 +20,18 @@
class tag_rest_Core {
static function get($request) {
$tag = rest::resolve($request->url);
- $items = array();
+ $tag_items = array();
foreach ($tag->items() as $item) {
- $items[] = rest::url("gallery", $item);
+ if (access::can("view", $item)) {
+ $tag_items[] = rest::url("tag_item", $tag, $item);
+ }
}
- return array("resource" => $tag->as_array(), "members" => $items);
+ return array(
+ "url" => $request->url,
+ "resource" => $tag->as_array(),
+ "relationships" => array(
+ "items" => $tag_items));
}
static function post($request) {
@@ -38,37 +44,34 @@ class tag_rest_Core {
access::required("edit", $item);
tag::add($item, $tag->name);
- return array("url" => rest::url("tag", $tag));
}
static function put($request) {
$tag = rest::resolve($request->url);
if (isset($request->params->name)) {
$tag->name = $request->params->name;
+ $tag->save();
}
-
- $tag->save();
- return array("url" => rest::url("tag", $tag));
}
static function delete($request) {
$tag = rest::resolve($request->url);
+ $tag->delete();
+ }
- if (empty($request->params->url)) {
- // Delete the tag
- $tag->delete();
- } else {
- // Remove an item from the tag
- $item = rest::resolve($request->params->url);
- access::required("edit", $item);
- $tag->remove($item);
- $tag->save();
- tag::compact();
+ static function relationships($resource_type, $resource) {
+ switch ($resource_type) {
+ case "item":
+ $tags = array();
+ foreach (tag::item_tags($resource) as $tag) {
+ $tags[] = rest::url("tag_item", $tag, $resource);
+ }
+ return array("tags" => $tags);
}
}
- static function resolve($tag_name) {
- $tag = ORM::factory("tag")->where("name", "=", $tag_name)->find();
+ static function resolve($id) {
+ $tag = ORM::factory("tag")->where("id", "=", $id)->find();
if (!$tag->loaded()) {
throw new Kohana_404_Exception();
}
@@ -77,6 +80,6 @@ class tag_rest_Core {
}
static function url($tag) {
- return url::abs_site("rest/tag/" . rawurlencode($tag->name));
+ return url::abs_site("rest/tag/{$tag->id}");
}
}
diff --git a/modules/tag/helpers/tags_rest.php b/modules/tag/helpers/tags_rest.php
index 41317ecd..57461125 100644
--- a/modules/tag/helpers/tags_rest.php
+++ b/modules/tag/helpers/tags_rest.php
@@ -21,7 +21,7 @@ class tags_rest_Core {
static function get($request) {
$tags = array();
foreach (ORM::factory("tag")->find_all() as $tag) {
- $tags[$tag->name] = rest::url("tag", $tag);
+ $tags[] = rest::url("tag", $tag);
}
return array("members" => $tags);
}
@@ -33,7 +33,7 @@ class tags_rest_Core {
access::required("edit", item::root());
if (empty($request->params->name)) {
- throw new Rest_Exception("Bad Request: missing name", 400);
+ throw new Rest_Exception("Bad Request", 400);
}
$tag = ORM::factory("tag")->where("name", "=", $request->params->name)->find();