diff options
| author | Nathan Kinkade <nkinkade@nkinka.de> | 2010-12-23 02:12:38 +0000 | 
|---|---|---|
| committer | Nathan Kinkade <nkinkade@nkinka.de> | 2010-12-23 02:12:38 +0000 | 
| commit | 5e17a5e7fcb678bd7081bdf8089afec5b25f3aff (patch) | |
| tree | 9590eae390af1f72b72ddc6500a2566e3558e3bb /modules/gallery/helpers | |
| parent | cf1965957c48b1c88a3913f8167688d03d191cec (diff) | |
| parent | 032e6fde5f99c3150a4ae70e410ce314d8c3877a (diff) | |
Merge branch 'master' of git://github.com/gallery/gallery3
Diffstat (limited to 'modules/gallery/helpers')
| -rw-r--r-- | modules/gallery/helpers/MY_url.php | 42 | ||||
| -rw-r--r-- | modules/gallery/helpers/access.php | 14 | ||||
| -rw-r--r-- | modules/gallery/helpers/block_manager.php | 2 | ||||
| -rw-r--r-- | modules/gallery/helpers/gallery_event.php | 7 | ||||
| -rw-r--r-- | modules/gallery/helpers/gallery_installer.php | 4 | ||||
| -rw-r--r-- | modules/gallery/helpers/item.php | 71 | ||||
| -rw-r--r-- | modules/gallery/helpers/items_rest.php | 6 | ||||
| -rw-r--r-- | modules/gallery/helpers/random.php | 50 | ||||
| -rw-r--r-- | modules/gallery/helpers/tree_rest.php | 92 | 
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}"); +  } +} | 
