function save($album_id) { access::verify_csrf(); $album = ORM::factory("item", $album_id); access::required("edit", $album); if (Input::instance()->post("save")) { $titles = Input::instance()->post("title"); $descriptions = Input::instance()->post("description"); $filenames = Input::instance()->post("filename"); $internetaddresses = Input::instance()->post("internetaddress"); $tags = Input::instance()->post("tags"); $enable_tags = module::is_active("tag"); foreach (array_keys($titles) as $id) { $item = ORM::factory("item", $id); if ($item->loaded() && access::can("edit", $item)) { $item->title = $titles[$id]; $item->description = $descriptions[$id]; $item->name = $filenames[$id]; $item->slug = $internetaddresses[$id]; $item->save(); if ($enable_tags) { tag::clear_all($item); foreach (explode(",", $tags[$id]) as $tag_name) { if ($tag_name) { tag::add($item, trim($tag_name)); } } tag::compact(); } } } message::success(t("Captions saved")); } url::redirect($album->abs_url()); }
static function get($request) { $item = rest::resolve($request->url); access::required("view", $item); $checksums = array(rest::url("itemchecksum_md5", $item), rest::url("itemchecksum_sha1", $item)); return array("url" => $request->url, "members" => $checksums); }
public function _form_add($item_id) { $item = ORM::factory("item", $item_id); access::required("view", $item); access::required("edit", $item); return tag::get_add_form($item); }
function change($command, $group_id, $perm_id, $item_id) { access::verify_csrf(); $group = identity::lookup_group($group_id); $perm = ORM::factory("permission", $perm_id); $item = ORM::factory("item", $item_id); access::required("view", $item); access::required("edit", $item); if (!empty($group) && $perm->loaded() && $item->loaded()) { switch ($command) { case "allow": access::allow($group, $perm->name, $item); break; case "deny": access::deny($group, $perm->name, $item); break; case "reset": access::reset($group, $perm->name, $item); break; } // If the active user just took away their own edit permissions, give it back. if ($perm->name == "edit") { if (!access::user_can(identity::active_user(), "edit", $item)) { access::allow($group, $perm->name, $item); } } } }
/** * The tree is rooted in a single item and can have modifiers which adjust what data is shown * for items inside the given tree, up to the depth that you want. The entity for this resource * is a series of items. * * depth=<number> * Only traverse this far down into the tree. If there are more albums * below this depth, provide RESTful urls to other tree resources in * the members section. Default is infinite. * * type=<album|photo|movie> * Restrict the items displayed to the given type. Default is all types. * * fields=<comma separated list of field names> * In the entity section only return these fields for each item. * Default is all fields. */ static function get($request) { $item = rest::resolve($request->url); access::required("view", $item); $query_params = array(); $p = $request->params; $where = array(); if (isset($p->type)) { $where[] = array("type", "=", $p->type); $query_params[] = "type={$p->type}"; } if (isset($p->depth)) { $lowest_depth = $item->level + $p->depth; $where[] = array("level", "<=", $lowest_depth); $query_params[] = "depth={$p->depth}"; } $fields = array(); if (isset($p->fields)) { $fields = explode(",", $p->fields); $query_params[] = "fields={$p->fields}"; } $entity = array(array("url" => rest::url("item", $item), "entity" => $item->as_restful_array($fields))); $members = array(); foreach ($item->viewable()->descendants(null, null, $where) as $child) { $entity[] = array("url" => rest::url("item", $child), "entity" => $child->as_restful_array($fields)); if (isset($lowest_depth) && $child->level == $lowest_depth) { $members[] = url::merge_querystring(rest::url("tree", $child), $query_params); } } $result = array("url" => $request->url, "entity" => $entity, "members" => $members, "relationships" => rest::relationships("tree", $item)); return $result; }
static function delete($request) { $item = rest::resolve($request->url); access::required("edit", $item); // Deleting this collection means removing all tags associated with the item. tag::clear_all($item); }
static function feed($feed_id, $offset, $limit, $id) { $feed = new stdClass(); switch ($feed_id) { case "latest": $feed->items = ORM::factory("item")->viewable()->where("type", "<>", "album")->order_by("created", "DESC")->find_all($limit, $offset); $all_items = ORM::factory("item")->viewable()->where("type", "<>", "album")->order_by("created", "DESC"); $feed->max_pages = ceil($all_items->find_all()->count() / $limit); $feed->title = t("%site_title - Recent updates", array("site_title" => item::root()->title)); $feed->description = t("Recent updates"); return $feed; case "album": $item = ORM::factory("item", $id); access::required("view", $item); $feed->items = $item->viewable()->descendants($limit, $offset, array(array("type", "=", "photo"))); $feed->max_pages = ceil($item->viewable()->descendants_count(array(array("type", "=", "photo"))) / $limit); if ($item->id == item::root()->id) { $feed->title = html::purify($item->title); } else { $feed->title = t("%site_title - %item_title", array("site_title" => item::root()->title, "item_title" => $item->title)); } $feed->description = nl2br(html::purify($item->description)); return $feed; } }
public function add_photo($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); $file_validation = new Validation($_FILES); $file_validation->add_rules("Filedata", "upload::valid", "upload::type[gif,jpg,png,flv,mp4]"); if ($file_validation->validate()) { // SimpleUploader.swf does not yet call /start directly, so simulate it here for now. if (!batch::in_progress()) { batch::start(); } $temp_filename = upload::save("Filedata"); try { $name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds $title = item::convert_filename_to_title($name); $path_info = pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), array("flv", "mp4"))) { $movie = movie::create($album, $temp_filename, $name, $title); log::success("content", t("Added a movie"), html::anchor("movies/{$movie->id}", t("view movie"))); } else { $photo = photo::create($album, $temp_filename, $name, $title); log::success("content", t("Added a photo"), html::anchor("photos/{$photo->id}", t("view photo"))); } } catch (Exception $e) { unlink($temp_filename); throw $e; } unlink($temp_filename); } print "File Received"; }
static function delete($request) { list($tag, $item) = rest::resolve($request->url); access::required("edit", $item); $tag->remove($item); $tag->save(); }
public function add_photo($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); // The Flash uploader not call /start directly, so simulate it here for now. if (!batch::in_progress()) { batch::start(); } $form = $this->_get_add_form($album); if ($form->validate()) { // Uploadify puts the result in $_FILES["Filedata"] - process it. try { list($tmp_name, $name) = $this->_process_upload("Filedata"); } catch (Exception $e) { header("HTTP/1.1 400 Bad Request"); print "ERROR: " . $e->getMessage(); return; } // We have a valid upload file (of unknown type) - build an item from it. try { $item = $this->_add_item($id, $tmp_name, $name); module::event("add_photos_form_completed", $item, $form); print "FILEID: {$item->id}"; } catch (Exception $e) { header("HTTP/1.1 500 Internal Server Error"); print "ERROR: " . $e->getMessage(); } } else { header("HTTP/1.1 400 Bad Request"); print "ERROR: " . t("Invalid upload"); } }
public function form_edit($movie_id) { $movie = ORM::factory("item", $movie_id); access::required("view", $movie); access::required("edit", $movie); print movie::get_edit_form($movie); }
public function form_edit($photo_id) { $photo = ORM::factory("item", $photo_id); access::required("view", $photo); access::required("edit", $photo); print photo::get_edit_form($photo); }
public function albums($id) { $item = ORM::factory("item", $id); access::required("view", $item); $page = $this->input->get("page", 1); if ($page < 1) { url::redirect("rss/albums/{$item->id}"); } $children = $item->viewable()->descendants(self::$page_size, ($page - 1) * self::$page_size, "photo"); $max_pages = ceil($item->viewable()->descendants_count("photo") / self::$page_size); if ($max_pages && $page > $max_pages) { url::redirect("rss/albums/{$item->id}?page={$max_pages}"); } $view = new View("feed.mrss"); $view->title = $item->title; $view->link = url::abs_site("albums/{$item->id}"); $view->description = $item->description; $view->feed_link = url::abs_site("rss/albums/{$item->id}"); $view->children = $children; if ($page > 1) { $previous_page = $page - 1; $view->previous_page_link = url::site("rss/albums/{$item->id}?page={$previous_page}"); } if ($page < $max_pages) { $next_page = $page + 1; $view->next_page_link = url::site("rss/albums/{$item->id}?page={$next_page}"); } // @todo do we want to add an upload date to the items table? $view->pub_date = date("D, d M Y H:i:s T"); rest::http_content_type(rest::RSS); print $view; }
public function random($item_id) { $item = ORM::factory("item", $item_id); access::required("view", $item); item::set_display_context_callback("Albums_Controller::get_display_context"); url::redirect($item->abs_url()); }
/** * Redirect Gallery 2 urls to their appropriate matching Gallery 3 url. * * We use mod_rewrite to create this path, so Gallery2 urls like this: * /gallery2/v/Family/Wedding.jpg.html * /gallery2/main.php?g2_view=core.ShowItem&g2_itemId=1234 * * Show up here like this: * /g2/map?path=v/Family/Wedding.jpg.html * /g2/map?g2_view=core.ShowItem&g2_itemId=1931 */ public function map() { $input = Input::instance(); $path = $input->get("path"); $id = $input->get("g2_itemId"); if ($path && $path != 'index.php' && $path != 'main.php' || $id) { if ($id) { // Requests by id are either core.DownloadItem or core.ShowItem requests. Later versions of // Gallery 2 don't specify g2_view if it's the default (core.ShowItem). And in some cases // (bbcode, embedding) people are using the id style URLs although URL rewriting is enabled. $where = array(array("g2_id", "=", $id)); $view = $input->get("g2_view"); if ($view == "core.DownloadItem") { $where[] = array("resource_type", "IN", array("file", "resize", "thumbnail", "full")); } else { if ($view) { $where[] = array("g2_url", "like", "%g2_view={$view}%"); } } // else: Assuming that the first search hit is sufficiently good. } else { if ($path) { $where = array(array("g2_url", "IN", array($path, str_replace(" ", "+", $path)))); } else { throw new Kohana_404_Exception(); } } $g2_map = ORM::factory("g2_map")->merge_where($where)->find(); if (!$g2_map->loaded()) { throw new Kohana_404_Exception(); } $item = ORM::factory("item", $g2_map->g3_id); if (!$item->loaded()) { throw new Kohana_404_Exception(); } $resource_type = $g2_map->resource_type; } else { $item = item::root(); $resource_type = "album"; } access::required("view", $item); // Redirect the user to the new url switch ($resource_type) { case "thumbnail": url::redirect($item->thumb_url(true)); case "resize": url::redirect($item->resize_url(true)); case "file": case "full": url::redirect($item->file_url(true)); case "item": case "album": url::redirect($item->abs_url()); case "group": case "user": default: throw new Kohana_404_Exception(); } }
public function embed() { /** * This is used to embed the tag cloud in other things. New in version 7. * * It expects the url to be in the form: * tag_cloud/embed/optionsbase/option1/value1/option2/value2/.../optionN/valueN * Where: * optionsbase = "sidebar" or "wholecloud" (takes settings from this config) * optionX = option name (either "maxtags" or any of the TagCanvas parameters - no name verification performed!) * valueX = value of option (no value verification performed here!) * Here's how the tag cloud is built: * 1. Load "maxtags" and "options" variables for optionbase (as defined in admin menu or admin/advanced variables) * Note: width and height are ignored, and the add tag form, wholecloud link, and inline tags are not shown. * 2. Use option/value pairs to override and/or append those loaded above. * 3. Build tag cloud, using 100% of the size from its parent. * Correspondingly, the optionsbase is required, but the options and values are not. */ // Require view permission for the root album for security purposes. $album = ORM::factory("item", 1); access::required("view", $album); // get the function arguments $args = func_get_args(); // get/check the number of arguments - must be odd $countargs = count($args); if ($countargs % 2 == 0) { return; } // get/check the first argument - must be sidebar or wholecloud $optionsbase = $args[0]; if (!in_array($optionsbase, array("sidebar", "wholecloud"))) { return; } // get and override/append options/values $maxtags = module::get_var("tag_cloud_html5", "maxtags_" . $optionsbase, null); $options = module::get_var("tag_cloud_html5", "options_" . $optionsbase, null); $options = json_decode($options, true); for ($i = 0; $i < ($countargs - 1) / 2; $i++) { $option = $args[2 * $i + 1]; $value = $args[2 * $i + 2]; if ($option == "maxtags") { // assign to maxtags $maxtags = $value; } elseif (substr($option, -6) == 'Colour') { // assign to options with a hash in front $options[$option] = '#' . $value; } else { // assign to options $options[$option] = $value; } } $options = json_encode($options); // Set up and display the actual page. $template = new View("tag_cloud_html5_embed.html"); $template->cloud = tag::cloud($maxtags); $template->options = $options; // Display the page. print $template; }
public function _show($item) { // Redirect to the more specific resource type, since it will render // differently. We could also just delegate here, but it feels more appropriate // to have a single canonical resource mapping. access::required("view", $item); return url::redirect($item->url()); }
public function show_sub_tree($source_id, $target_id) { $source = ORM::factory("item", $source_id); $target = ORM::factory("item", $target_id); access::required("edit", $source); access::required("view", $target); print $this->_get_tree_html($source, $target); }
/** * Display the EXIF data for an item. */ public function show($item_id) { $item = ORM::factory("item", $item_id); access::required("view", $item); $view = new View("exif_dialog.html"); $view->details = exif::get($item); print $view; }
static function post($request) { $tag = rest::resolve($request->params->tag); $item = rest::resolve($request->params->item); access::required("view", $item); tag::add($item, $tag->name); return array("url" => rest::url("tag_item", $tag, $item), "members" => array(rest::url("tag", $tag), rest::url("item", $item))); }
public function item($item_id) { // Make sure the context callback is set to album when linking to photos from map pages. $item = ORM::factory("item", $item_id); access::required("view", $item); item::set_display_context_callback("Albums_Controller::get_display_context"); url::redirect($item->abs_url()); }
public function tags_for($id) { $item = ORM::factory("item", $id); access::required("view", $item); $view = new View("tag_it_tags_for.html"); $view->tags = tag::item_tags($item); print $view; }
static function get($request) { $item = rest::resolve($request->url); $p = $request->params; if (!isset($p->size) || !in_array($p->size, array("thumb", "resize", "full"))) { throw new Rest_Exception("Bad Request", 400, array("errors" => array("size" => "invalid"))); } // Note: this code is roughly duplicated in file_proxy, so if you modify this, please look to // see if you should make the same change there as well. if ($p->size == "full") { if ($item->is_album()) { throw new Kohana_404_Exception(); } access::required("view_full", $item); $file = $item->file_path(); } else { if ($p->size == "resize") { access::required("view", $item); $file = $item->resize_path(); } else { access::required("view", $item); $file = $item->thumb_path(); } } if (!file_exists($file)) { throw new Kohana_404_Exception(); } header("Content-Length: " . filesize($file)); if (isset($p->m)) { header("Pragma:"); // Check that the content hasn't expired or it wasn't changed since cached expires::check(2592000, $item->updated); expires::set(2592000, $item->updated); // 30 days } // We don't need to save the session for this request Session::instance()->abort_save(); // Dump out the image. If the item is a movie or album, then its thumbnail will be a JPG. if (($item->is_movie() || $item->is_album()) && $p->size == "thumb") { header("Content-Type: image/jpeg"); } else { header("Content-Type: {$item->mime_type}"); } if (TEST_MODE) { return $file; } else { Kohana::close_buffers(false); if (isset($p->encoding) && $p->encoding == "base64") { print base64_encode(file_get_contents($file)); } else { readfile($file); } } // We must exit here to keep the regular REST framework reply code from adding more bytes on // at the end or tinkering with headers. exit; }
/** * Return all the tags for a given item. * @return array */ static function item_tags($item) { access::required("view", $item); $tags = array(); foreach (Database::instance()->select("name")->from("tags")->join("items_tags", "tags.id", "items_tags.tag_id", "left")->where("items_tags.item_id", $item->id)->get() as $row) { $tags[] = $row->name; } return $tags; }
/** * Checks whether the given object can be starred by the active user. * * @param Item_Model $item the item */ private function _check_star_permissions(Item_Model $item) { access::verify_csrf(); access::required("view", $item); access::required("edit", $item); if (!star::can_star()) { access::forbidden(); } }
static function delete($request) { if (!identity::active_user()->admin) { access::forbidden(); } $comment = rest::resolve($request->url); access::required("edit", $comment->item()); $comment->delete(); }
/** * Present a form for adding a new comment to this item or editing an existing comment. */ public function form_add($item_id) { $item = ORM::factory("item", $item_id); access::required("view", $item); if (!comment::can_comment()) { access::forbidden(); } print comment::prefill_add_form(comment::get_add_form($item)); }
/** * Present a form for sending a new ecard. */ public function form_send($item_id) { $item = ORM::factory("item", $item_id); access::required("view", $item); if (!ecard::can_send_ecard()) { access::forbidden(); } print ecard::prefill_send_form(ecard::get_send_form($item)); }
public function add_photo($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); // The Flash uploader not call /start directly, so simulate it here for now. if (!batch::in_progress()) { batch::start(); } $form = $this->_get_add_form($album); // Uploadify adds its own field to the form, so validate that separately. $file_validation = new Validation($_FILES); $file_validation->add_rules("Filedata", "upload::valid", "upload::required", "upload::type[" . implode(",", legal_file::get_extensions()) . "]"); if ($form->validate() && $file_validation->validate()) { $temp_filename = upload::save("Filedata"); Event::add("system.shutdown", create_function("", "unlink(\"{$temp_filename}\");")); try { $item = ORM::factory("item"); $item->name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds $item->title = item::convert_filename_to_title($item->name); $item->parent_id = $album->id; $item->set_data_file($temp_filename); // Remove double extensions from the filename - they'll be disallowed in the model but if // we don't do it here then it'll result in a failed upload. $item->name = legal_file::smash_extensions($item->name); $path_info = @pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), legal_file::get_movie_extensions())) { $item->type = "movie"; $item->save(); log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie"))); } else { $item->type = "photo"; $item->save(); log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo"))); } module::event("add_photos_form_completed", $item, $form); } catch (Exception $e) { // The Flash uploader has no good way of reporting complex errors, so just keep it simple. Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); // Ugh. I hate to use instanceof, But this beats catching the exception separately since // we mostly want to treat it the same way as all other exceptions if ($e instanceof ORM_Validation_Exception) { Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); } header("HTTP/1.1 500 Internal Server Error"); print "ERROR: " . $e->getMessage(); return; } print "FILEID: {$item->id}"; } else { header("HTTP/1.1 400 Bad Request"); print "ERROR: " . t("Invalid upload"); } }
static function get($request) { $item = rest::resolve($request->url); access::required("view", $item); $comments = array(); foreach (ORM::factory("comment")->viewable()->where("item_id", "=", $item->id)->order_by("created", "DESC")->find_all() as $comment) { $comments[] = rest::url("comment", $comment); } return array("url" => $request->url, "members" => $comments); }