summaryrefslogtreecommitdiff
path: root/modules/gallery/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gallery/helpers')
-rw-r--r--modules/gallery/helpers/MY_url.php42
-rw-r--r--modules/gallery/helpers/access.php14
-rw-r--r--modules/gallery/helpers/block_manager.php2
-rw-r--r--modules/gallery/helpers/gallery_event.php7
-rw-r--r--modules/gallery/helpers/gallery_installer.php4
-rw-r--r--modules/gallery/helpers/item.php71
-rw-r--r--modules/gallery/helpers/items_rest.php6
-rw-r--r--modules/gallery/helpers/random.php50
-rw-r--r--modules/gallery/helpers/tree_rest.php92
9 files changed, 251 insertions, 37 deletions
diff --git a/modules/gallery/helpers/MY_url.php b/modules/gallery/helpers/MY_url.php
index 877c5ada..8ac26602 100644
--- a/modules/gallery/helpers/MY_url.php
+++ b/modules/gallery/helpers/MY_url.php
@@ -31,7 +31,7 @@ class url extends url_Core {
return;
}
- $item = self::get_item_from_uri(Router::$current_uri);
+ $item = item::find_by_relative_url(html_entity_decode(Router::$current_uri, ENT_QUOTES));
if ($item && $item->loaded()) {
Router::$controller = "{$item->type}s";
Router::$controller_path = MODPATH . "gallery/controllers/{$item->type}s.php";
@@ -41,32 +41,6 @@ class url extends url_Core {
}
/**
- * Locate an item using the URI. We assume that the uri is in the form /a/b/c where each
- * component matches up with an item slug.
- * @param string $uri the uri fragment
- * @return Item_Model
- */
- static function get_item_from_uri($uri) {
- $current_uri = html_entity_decode($uri, ENT_QUOTES);
- // In most cases, we'll have an exact match in the relative_url_cache item field.
- // but failing that, walk down the tree until we find it. The fallback code will fix caches
- // as it goes, so it'll never be run frequently.
- $item = ORM::factory("item")->where("relative_url_cache", "=", $current_uri)->find();
- if (!$item->loaded()) {
- $count = count(Router::$segments);
- foreach (ORM::factory("item")
- ->where("slug", "=", html_entity_decode(Router::$segments[$count - 1], ENT_QUOTES))
- ->where("level", "=", $count + 1)
- ->find_all() as $match) {
- if ($match->relative_url() == $current_uri) {
- $item = $match;
- }
- }
- }
- return $item;
- }
-
- /**
* Just like url::file() except that it returns an absolute URI
*/
static function abs_file($path) {
@@ -101,4 +75,18 @@ class url extends url_Core {
static function current($qs=false, $suffix=false) {
return htmlspecialchars(parent::current($qs, $suffix));
}
+
+ /**
+ * Merge extra an query string onto a given url safely.
+ * @param string the original url
+ * @param array the query string data in key=value form
+ */
+ static function merge_querystring($url, $query_params) {
+ $qs = implode("&", $query_params);
+ if (strpos($url, "?") === false) {
+ return $url . "?$qs";
+ } else {
+ return $url . "&$qs";
+ }
+ }
}
diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php
index 0b0dcbc1..4148049a 100644
--- a/modules/gallery/helpers/access.php
+++ b/modules/gallery/helpers/access.php
@@ -99,8 +99,12 @@ class access_Core {
return true;
}
+ // Use the nearest parent album (including the current item) so that we take advantage
+ // of the cache when checking many items in a single album.
+ $id = ($item->type == "album") ? $item->id : $item->parent_id;
$resource = $perm_name == "view" ?
- $item : model_cache::get("access_cache", $item->id, "item_id");
+ $item : model_cache::get("access_cache", $id, "item_id");
+
foreach ($user->groups() as $group) {
if ($resource->__get("{$perm_name}_{$group->id}") === access::ALLOW) {
return true;
@@ -136,8 +140,12 @@ class access_Core {
* @return boolean
*/
static function group_can($group, $perm_name, $item) {
+ // Use the nearest parent album (including the current item) so that we take advantage
+ // of the cache when checking many items in a single album.
+ $id = ($item->type == "album") ? $item->id : $item->parent_id;
$resource = $perm_name == "view" ?
- $item : model_cache::get("access_cache", $item->id, "item_id");
+ $item : model_cache::get("access_cache", $id, "item_id");
+
return $resource->__get("{$perm_name}_{$group->id}") === access::ALLOW;
}
@@ -426,7 +434,7 @@ class access_Core {
$session = Session::instance();
$csrf = $session->get("csrf");
if (empty($csrf)) {
- $csrf = md5(rand());
+ $csrf = random::hash();
$session->set("csrf", $csrf);
}
return $csrf;
diff --git a/modules/gallery/helpers/block_manager.php b/modules/gallery/helpers/block_manager.php
index 2237b702..4bd649c2 100644
--- a/modules/gallery/helpers/block_manager.php
+++ b/modules/gallery/helpers/block_manager.php
@@ -28,7 +28,7 @@ class block_manager_Core {
static function add($location, $module_name, $block_id) {
$blocks = block_manager::get_active($location);
- $blocks[rand()] = array($module_name, $block_id);
+ $blocks[random::int()] = array($module_name, $block_id);
block_manager::set_active($location, $blocks);
}
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index b59bb9b9..5d3ee6ee 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -178,6 +178,10 @@ class gallery_event_Core {
}
Session::instance()->set("active_auth_timestamp", time());
auth::clear_failed_attempts($user);
+
+ if ($user->admin && ini_get("session.use_trans_sid")) {
+ message::info(t("PHP is configured with <a href=\"url\">session.use_trans_sid</a> enabled which will cause random logouts. Please disable this setting.", array("url" => "http://www.php.net/manual/en/session.configuration.php#ini.session.use-trans-sid")));
+ }
}
static function user_auth_failed($name) {
@@ -371,6 +375,9 @@ class gallery_event_Core {
->id("admin_menu")
->label(t("Admin")));
module::event("admin_menu", $admin_menu, $theme);
+
+ $settings_menu = $admin_menu->get("settings_menu");
+ sort($settings_menu->elements);
}
}
}
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index 3d82bc69..a6b8e6a2 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -459,7 +459,7 @@ class gallery_installer {
$blocks = block_manager::get_active($location);
$new_blocks = array();
foreach ($blocks as $block) {
- $new_blocks[rand()] = $block;
+ $new_blocks[random::int()] = $block;
}
block_manager::set_active($location, $new_blocks);
}
@@ -507,7 +507,7 @@ class gallery_installer {
->execute() as $row) {
$new_slug = item::convert_filename_to_slug($row->slug);
if (empty($new_slug)) {
- $new_slug = rand();
+ $new_slug = random::int();
}
db::build()
->update("items")
diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php
index 052b1c8e..29dd8603 100644
--- a/modules/gallery/helpers/item.php
+++ b/modules/gallery/helpers/item.php
@@ -210,6 +210,75 @@ class item_Core {
}
/**
+ * Find an item by its path. If there's no match, return an empty Item_Model.
+ * NOTE: the caller is responsible for performing security checks on the resulting item.
+ * @param string $path
+ * @return object Item_Model
+ */
+ static function find_by_path($path) {
+ $path = trim($path, "/");
+
+ // The root path name is NULL not "", hence this workaround.
+ if ($path == "") {
+ return item::root();
+ }
+
+ // Check to see if there's an item in the database with a matching relative_path_cache value.
+ // Since that field is urlencoded, we must urlencoded the components of the path.
+ foreach (explode("/", $path) as $part) {
+ $encoded_array[] = rawurlencode($part);
+ }
+ $encoded_path = join("/", $encoded_array);
+ $item = ORM::factory("item")
+ ->where("relative_path_cache", "=", $encoded_path)
+ ->find();
+ if ($item->loaded()) {
+ return $item;
+ }
+
+ // Since the relative_path_cache field is a cache, it can be unavailable. If we don't find
+ // anything, fall back to checking the path the hard way.
+ $paths = explode("/", $path);
+ foreach (ORM::factory("item")
+ ->where("name", "=", end($paths))
+ ->where("level", "=", count($paths) + 1)
+ ->find_all() as $item) {
+ if (urldecode($item->relative_path()) == $path) {
+ return $item;
+ }
+ }
+
+ return new Item_Model();
+ }
+
+
+ /**
+ * Locate an item using the URL. We assume that the url is in the form /a/b/c where each
+ * component matches up with an item slug. If there's no match, return an empty Item_Model
+ * NOTE: the caller is responsible for performing security checks on the resulting item.
+ * @param string $url the relative url fragment
+ * @return Item_Model
+ */
+ static function find_by_relative_url($relative_url) {
+ // In most cases, we'll have an exact match in the relative_url_cache item field.
+ // but failing that, walk down the tree until we find it. The fallback code will fix caches
+ // as it goes, so it'll never be run frequently.
+ $item = ORM::factory("item")->where("relative_url_cache", "=", $relative_url)->find();
+ if (!$item->loaded()) {
+ $segments = explode("/", $relative_url);
+ foreach (ORM::factory("item")
+ ->where("slug", "=", end($segments))
+ ->where("level", "=", count($segments) + 1)
+ ->find_all() as $match) {
+ if ($match->relative_url() == $relative_url) {
+ $item = $match;
+ }
+ }
+ }
+ return $item;
+ }
+
+ /**
* Return the root Item_Model
* @return Item_Model
*/
@@ -232,7 +301,7 @@ class item_Core {
// distributed so this is going to be more efficient with larger data sets.
return ORM::factory("item")
->viewable()
- ->where("rand_key", "<", ((float)mt_rand()) / (float)mt_getrandmax())
+ ->where("rand_key", "<", random::percent())
->order_by("rand_key", "DESC");
}
} \ No newline at end of file
diff --git a/modules/gallery/helpers/items_rest.php b/modules/gallery/helpers/items_rest.php
index 08aa3279..3c09faa8 100644
--- a/modules/gallery/helpers/items_rest.php
+++ b/modules/gallery/helpers/items_rest.php
@@ -84,9 +84,9 @@ class items_rest_Core {
if ($item->type == "album") {
$members = array();
foreach ($item->viewable()->children() as $child) {
- if (empty($types) || in_array($child->type, $types)) {
- $members[] = rest::url("item", $child);
- }
+ if (empty($types) || in_array($child->type, $types)) {
+ $members[] = rest::url("item", $child);
+ }
}
$item_rest["members"] = $members;
}
diff --git a/modules/gallery/helpers/random.php b/modules/gallery/helpers/random.php
new file mode 100644
index 00000000..a26762bd
--- /dev/null
+++ b/modules/gallery/helpers/random.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-2010 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 random_Core {
+ /**
+ * Return a random 32 bit hash value.
+ * @param string extra entropy data
+ */
+ static function hash($entropy="") {
+ return md5($entropy . uniqid(mt_rand(), true));
+ }
+
+ /**
+ * Return a random hexadecimal string of the given length.
+ * @param int the desired length of the string
+ */
+ static function string($length) {
+ return substr(random::hash(), 0, $length);
+ }
+
+ /**
+ * Return a random floating point number between 0 and 1
+ */
+ static function percent() {
+ return ((float)mt_rand()) / (float)mt_getrandmax();
+ }
+
+ /**
+ * Return a random number between 0 and mt_getrandmax()
+ */
+ static function int() {
+ return mt_rand();
+ }
+} \ No newline at end of file
diff --git a/modules/gallery/helpers/tree_rest.php b/modules/gallery/helpers/tree_rest.php
new file mode 100644
index 00000000..21928cbe
--- /dev/null
+++ b/modules/gallery/helpers/tree_rest.php
@@ -0,0 +1,92 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2010 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 tree_rest_Core {
+ /**
+ * 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 resolve($id) {
+ $item = ORM::factory("item", $id);
+ if (!access::can("view", $item)) {
+ throw new Kohana_404_Exception();
+ }
+ return $item;
+ }
+
+ static function url($item) {
+ return url::abs_site("rest/tree/{$item->id}");
+ }
+}