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);
 }
Example #3
0
 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);
 }
Example #4
0
 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);
             }
         }
     }
 }
Example #5
0
 /**
  * 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);
 }
Example #7
0
 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;
     }
 }
Example #8
0
 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";
 }
Example #9
0
 static function delete($request)
 {
     list($tag, $item) = rest::resolve($request->url);
     access::required("edit", $item);
     $tag->remove($item);
     $tag->save();
 }
Example #10
0
 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");
     }
 }
Example #11
0
 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);
 }
Example #12
0
 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);
 }
Example #13
0
 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;
 }
Example #14
0
 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());
 }
Example #15
0
 /**
  * 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();
     }
 }
Example #16
0
 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;
 }
Example #17
0
 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());
 }
Example #18
0
 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);
 }
Example #19
0
 /**
  * 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;
 }
Example #20
0
 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)));
 }
Example #21
0
 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());
 }
Example #22
0
 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;
 }
Example #23
0
 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;
 }
Example #24
0
 /**
  * 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;
 }
Example #25
0
 /**
  * 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();
     }
 }
Example #26
0
 static function delete($request)
 {
     if (!identity::active_user()->admin) {
         access::forbidden();
     }
     $comment = rest::resolve($request->url);
     access::required("edit", $comment->item());
     $comment->delete();
 }
Example #27
0
 /**
  * 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));
 }
Example #28
0
 /**
  * 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));
 }
Example #29
0
 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");
     }
 }
Example #30
0
 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);
 }