diff options
Diffstat (limited to 'modules/gallery/helpers')
-rw-r--r-- | modules/gallery/helpers/gallery.php | 77 | ||||
-rw-r--r-- | modules/gallery/helpers/gallery_event.php | 6 | ||||
-rw-r--r-- | modules/gallery/helpers/gallery_graphics.php | 4 | ||||
-rw-r--r-- | modules/gallery/helpers/gallery_installer.php | 23 | ||||
-rw-r--r-- | modules/gallery/helpers/gallery_task.php | 6 | ||||
-rw-r--r-- | modules/gallery/helpers/graphics.php | 86 | ||||
-rw-r--r-- | modules/gallery/helpers/item.php | 88 | ||||
-rw-r--r-- | modules/gallery/helpers/l10n_client.php | 23 | ||||
-rw-r--r-- | modules/gallery/helpers/locales.php | 2 | ||||
-rw-r--r-- | modules/gallery/helpers/module.php | 4 | ||||
-rw-r--r-- | modules/gallery/helpers/movie.php | 14 | ||||
-rw-r--r-- | modules/gallery/helpers/system.php | 43 |
12 files changed, 260 insertions, 116 deletions
diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php index 2bb55ccb..282289b5 100644 --- a/modules/gallery/helpers/gallery.php +++ b/modules/gallery/helpers/gallery.php @@ -25,18 +25,27 @@ class gallery_Core { * down for maintenance" page. */ static function maintenance_mode() { - // @todo: we need a mechanism here to identify controllers that are still legally accessible - // when the entire Gallery is in maintenance mode. Perhaps a controller class function or - // method? - // https://sourceforge.net/apps/trac/gallery/ticket/1411 - if (Router::$controller != "login" && - Router::$controller != "combined" && - module::get_var("gallery", "maintenance_mode", 0) && + if (module::get_var("gallery", "maintenance_mode", 0) && !identity::active_user()->admin) { - Session::instance()->set("continue_url", url::abs_site("admin/maintenance")); - Router::$controller = "login"; - Router::$controller_path = MODPATH . "gallery/controllers/login.php"; - Router::$method = "html"; + try { + $class = new ReflectionClass(ucfirst(Router::$controller).'_Controller'); + $allowed = $class->getConstant("ALLOW_MAINTENANCE_MODE") === true; + } catch (ReflectionClass $e) { + $allowed = false; + } + if (!$allowed) { + if (Router::$controller == "admin") { + // At this point we're in the admin theme and it doesn't have a themed login page, so + // we can't just swap in the login controller and have it work. So redirect back to the + // root item where we'll run this code again with the site theme. + url::redirect(item::root()->abs_url()); + } else { + Session::instance()->set("continue_url", url::abs_site("admin/maintenance")); + Router::$controller = "login"; + Router::$controller_path = MODPATH . "gallery/controllers/login.php"; + Router::$method = "html"; + } + } } } @@ -45,26 +54,27 @@ class gallery_Core { * the login page. */ static function private_gallery() { - // @todo: we need a mechanism here to identify controllers that are still legally accessible - // when the entire Gallery is private. Perhaps a controller class function or method? - // https://sourceforge.net/apps/trac/gallery/ticket/1411 - if (Router::$controller != "login" && - Router::$controller != "combined" && - Router::$controller != "digibug" && - Router::$controller != "rest" && - identity::active_user()->guest && + if (identity::active_user()->guest && !access::user_can(identity::guest(), "view", item::root()) && php_sapi_name() != "cli") { - if (Router::$controller == "admin") { - // At this point we're in the admin theme and it doesn't have a themed login page, so - // we can't just swap in the login controller and have it work. So redirect back to the - // root item where we'll run this code again with the site theme. - url::redirect(item::root()->abs_url()); - } else { - Session::instance()->set("continue_url", url::abs_current()); - Router::$controller = "login"; - Router::$controller_path = MODPATH . "gallery/controllers/login.php"; - Router::$method = "html"; + try { + $class = new ReflectionClass(ucfirst(Router::$controller).'_Controller'); + $allowed = $class->getConstant("ALLOW_PRIVATE_GALLERY") === true; + } catch (ReflectionClass $e) { + $allowed = false; + } + if (!$allowed) { + if (Router::$controller == "admin") { + // At this point we're in the admin theme and it doesn't have a themed login page, so + // we can't just swap in the login controller and have it work. So redirect back to the + // root item where we'll run this code again with the site theme. + url::redirect(item::root()->abs_url()); + } else { + Session::instance()->set("continue_url", url::abs_current()); + Router::$controller = "login"; + Router::$controller_path = MODPATH . "gallery/controllers/login.php"; + Router::$method = "html"; + } } } } @@ -143,8 +153,15 @@ class gallery_Core { if (is_string($file_name)) { // make relative to DOCROOT $parts = explode("/", $file_name); + $count = count($parts); foreach ($parts as $idx => $part) { - if (in_array($part, array("application", "modules", "themes", "lib"))) { + // If this part is "modules" or "themes" make sure that the part 2 after this + // is the target directory, and if it is then we're done. This check makes + // sure that if Gallery is installed in a directory called "modules" or "themes" + // We don't parse the directory structure incorrectly. + if (in_array($part, array("modules", "themes")) && + $idx + 2 < $count && + $parts[$idx + 2] == $directory) { break; } unset($parts[$idx]); diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 5d3ee6ee..13a0bdb4 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -178,10 +178,6 @@ 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) { @@ -377,7 +373,7 @@ class gallery_event_Core { module::event("admin_menu", $admin_menu, $theme); $settings_menu = $admin_menu->get("settings_menu"); - sort($settings_menu->elements); + uasort($settings_menu->elements, array("Menu", "title_comparator")); } } } diff --git a/modules/gallery/helpers/gallery_graphics.php b/modules/gallery/helpers/gallery_graphics.php index 6038a95b..4cd7143e 100644 --- a/modules/gallery/helpers/gallery_graphics.php +++ b/modules/gallery/helpers/gallery_graphics.php @@ -56,7 +56,7 @@ class gallery_graphics_Core { } $dims = getimagesize($input_file); - if (max($dims[0], $dims[1]) < min($options["width"], $options["height"])) { + if (max($dims[0], $dims[1]) <= min($options["width"], $options["height"])) { // Image would get upscaled; do nothing copy($input_file, $output_file); } else { @@ -75,7 +75,7 @@ class gallery_graphics_Core { /** * Overlay an image on top of the input file. * - * Valid options are: file, mime_type, position, transparency_percent, padding + * Valid options are: file, position, transparency, padding * * Valid positions: northwest, north, northeast, * west, center, east, diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index a6b8e6a2..f7b8da5f 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -44,7 +44,7 @@ class gallery_installer { `expiration` int(9) NOT NULL, `cache` longblob, PRIMARY KEY (`id`), - KEY (`key`), + UNIQUE KEY (`key`), KEY (`tags`)) DEFAULT CHARSET=utf8;"); @@ -84,7 +84,7 @@ class gallery_installer { `album_cover_item_id` int(9) default NULL, `captured` int(9) default NULL, `created` int(9) default NULL, - `description` varchar(2048) default NULL, + `description` text default NULL, `height` int(9) default NULL, `left_ptr` int(9) NOT NULL, `level` int(9) NOT NULL, @@ -309,7 +309,7 @@ class gallery_installer { module::set_var("gallery", "show_user_profiles_to", "registered_users"); module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin"); - module::set_version("gallery", 41); + module::set_version("gallery", 43); } static function upgrade($version) { @@ -503,7 +503,7 @@ class gallery_installer { foreach (db::build() ->from("items") ->select("id", "slug") - ->where(new Database_Expression("`slug` REGEXP '[^_A-Za-z0-9-]'"), "=", 1) + ->where(db::expr("`slug` REGEXP '[^_A-Za-z0-9-]'"), "=", 1) ->execute() as $row) { $new_slug = item::convert_filename_to_slug($row->slug); if (empty($new_slug)) { @@ -540,7 +540,7 @@ class gallery_installer { if ($version == 25) { db::build() ->update("items") - ->set("title", new Database_Expression("`name`")) + ->set("title", db::expr("`name`")) ->and_open() ->where("title", "IS", null) ->or_where("title", "=", "") @@ -581,7 +581,7 @@ class gallery_installer { $db->query("ALTER TABLE {modules} ADD COLUMN `weight` int(9) DEFAULT NULL"); $db->query("ALTER TABLE {modules} ADD KEY (`weight`)"); db::update("modules") - ->set("weight", new Database_Expression("`id`")) + ->set("weight", db::expr("`id`")) ->execute(); module::set_version("gallery", $version = 32); } @@ -642,6 +642,17 @@ class gallery_installer { module::clear_var("gallery", "_cache"); module::set_version("gallery", $version = 41); } + + if ($version == 41) { + $db->query("TRUNCATE TABLE {caches}"); + $db->query("ALTER TABLE {caches} DROP INDEX `key`, ADD UNIQUE `key` (`key`)"); + module::set_version("gallery", $version = 42); + } + + if ($version == 42) { + $db->query("ALTER TABLE {items} CHANGE `description` `description` text DEFAULT NULL"); + module::set_version("gallery", $version = 43); + } } static function uninstall() { diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php index e69ff91a..9ccff152 100644 --- a/modules/gallery/helpers/gallery_task.php +++ b/modules/gallery/helpers/gallery_task.php @@ -74,7 +74,7 @@ class gallery_task_Core { // Choose the dirty images in a random order so that if we run this task multiple times // concurrently each task is rebuilding different images simultaneously. $result = graphics::find_dirty_images_query()->select("id") - ->select(new Database_Expression("RAND() as r")) + ->select(db::expr("RAND() as r")) ->order_by("r", "ASC") ->execute(); $total_count = $task->get("total_count", $result->count()); @@ -608,7 +608,7 @@ class gallery_task_Core { static function find_dupe_slugs() { return db::build() ->select_distinct( - array("parent_slug" => new Database_Expression("CONCAT(`parent_id`, ':', LOWER(`slug`))"))) + array("parent_slug" => db::expr("CONCAT(`parent_id`, ':', LOWER(`slug`))"))) ->select("id") ->select(array("C" => "COUNT(\"*\")")) ->from("items") @@ -620,7 +620,7 @@ class gallery_task_Core { static function find_dupe_names() { return db::build() ->select_distinct( - array("parent_name" => new Database_Expression("CONCAT(`parent_id`, ':', LOWER(`name`))"))) + array("parent_name" => db::expr("CONCAT(`parent_id`, ':', LOWER(`name`))"))) ->select("id") ->select(array("C" => "COUNT(\"*\")")) ->from("items") diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index edba6b76..18820ed7 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -313,60 +313,42 @@ class graphics_Core { $toolkits->graphicsmagick->installed = false; $toolkits->graphicsmagick->error = t("GraphicsMagick requires the <b>exec</b> function"); } else { - gallery::set_path_env( - array(module::get_var("gallery", "graphics_toolkit_path"), - getenv("PATH"), - module::get_var("gallery", "extra_binary_paths"))); - - // @todo: consider refactoring the two segments below into a loop since they are so - // similar. - - // ImageMagick - $path = exec("which convert"); - $toolkits->imagemagick->name = "ImageMagick"; - if ($path) { - if (@is_file($path)) { - preg_match('/Version: \S+ (\S+)/', `convert -v`, $matches); - $version = $matches[1]; - - $toolkits->imagemagick->installed = true; - $toolkits->imagemagick->version = $version; - $toolkits->imagemagick->binary = $path; - $toolkits->imagemagick->dir = dirname($path); - $toolkits->imagemagick->rotate = true; - $toolkits->imagemagick->sharpen = true; - } else { - $toolkits->imagemagick->installed = false; - $toolkits->imagemagick->error = - t("ImageMagick is installed, but PHP's open_basedir restriction prevents Gallery from using it."); - } - } else { - $toolkits->imagemagick->installed = false; - $toolkits->imagemagick->error = t("We could not locate ImageMagick on your system."); - } - - // GraphicsMagick - $path = exec("which gm"); - $toolkits->graphicsmagick->name = "GraphicsMagick"; - if ($path) { - if (@is_file($path)) { - preg_match('/\S+ (\S+)/', `gm version`, $matches); - $version = $matches[1]; - - $toolkits->graphicsmagick->installed = true; - $toolkits->graphicsmagick->version = $version; - $toolkits->graphicsmagick->binary = $path; - $toolkits->graphicsmagick->dir = dirname($path); - $toolkits->graphicsmagick->rotate = true; - $toolkits->graphicsmagick->sharpen = true; + // ImageMagick & GraphicsMagick + $magick_kits = array( + "imagemagick" => array( + "name" => "ImageMagick", "binary" => "convert", "version" => "convert -v", + "version_regex" => "/Version: \S+ (\S+)/"), + "graphicsmagick" => array( + "name" => "GraphicsMagick", "binary" => "gm", "version" => "gm version", + "version_regex" => "/\S+ (\S+)/")); + // Loop through the kits + foreach ($magick_kits as $index => $settings) { + $path = system::find_binary( + $settings["binary"], module::get_var("gallery", "graphics_toolkit_path")); + $toolkits->$index->name = $settings["name"]; + if ($path) { + if (@is_file($path) && + preg_match($settings["version_regex"], shell_exec($settings["version"]), $matches)) { + $version = $matches[1]; + + $toolkits->$index->installed = true; + $toolkits->$index->version = $version; + $toolkits->$index->binary = $path; + $toolkits->$index->dir = dirname($path); + $toolkits->$index->rotate = true; + $toolkits->$index->sharpen = true; + } else { + $toolkits->$index->installed = false; + $toolkits->$index->error = + t("%toolkit_name is installed, but PHP's open_basedir restriction prevents Gallery from using it.", + array("toolkit_name" => $settings["name"])); + } } else { - $toolkits->graphicsmagick->installed = false; - $toolkits->graphicsmagick->error = - t("GraphicsMagick is installed, but PHP's open_basedir restriction prevents Gallery from using it."); + $toolkits->$index->installed = false; + $toolkits->$index->error = + t("We could not locate %toolkit_name on your system.", + array("toolkit_name" => $settings["name"])); } - } else { - $toolkits->graphicsmagick->installed = false; - $toolkits->graphicsmagick->error = t("We could not locate GraphicsMagick on your system."); } } diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php index 29dd8603..8aa14934 100644 --- a/modules/gallery/helpers/item.php +++ b/modules/gallery/helpers/item.php @@ -304,4 +304,92 @@ class item_Core { ->where("rand_key", "<", random::percent()) ->order_by("rand_key", "DESC"); } + + /** + * Find the position of the given item in its parent album. The resulting + * value is 1-indexed, so the first child in the album is at position 1. + * + * @param Item_Model $item + * @param array $where an array of arrays, each compatible with ORM::where() + */ + static function get_position($item, $where=array()) { + $album = $item->parent(); + + if (!strcasecmp($album->sort_order, "DESC")) { + $comp = ">"; + } else { + $comp = "<"; + } + $query_model = ORM::factory("item"); + + // If the comparison column has NULLs in it, we can't use comparators on it + // and will have to deal with it the hard way. + $count = $query_model->viewable() + ->where("parent_id", "=", $album->id) + ->where($album->sort_column, "IS", null) + ->merge_where($where) + ->count_all(); + + if (empty($count)) { + // There are no NULLs in the sort column, so we can just use it directly. + $sort_column = $album->sort_column; + + $position = $query_model->viewable() + ->where("parent_id", "=", $album->id) + ->where($sort_column, $comp, $item->$sort_column) + ->merge_where($where) + ->count_all(); + + // We stopped short of our target value in the sort (notice that we're + // using a inequality comparator above) because it's possible that we have + // duplicate values in the sort column. An equality check would just + // arbitrarily pick one of those multiple possible equivalent columns, + // which would mean that if you choose a sort order that has duplicates, + // it'd pick any one of them as the child's "position". + // + // Fix this by doing a 2nd query where we iterate over the equivalent + // columns and add them to our position count. + foreach ($query_model->viewable() + ->select("id") + ->where("parent_id", "=", $album->id) + ->where($sort_column, "=", $item->$sort_column) + ->merge_where($where) + ->order_by(array("id" => "ASC")) + ->find_all() as $row) { + $position++; + if ($row->id == $item->id) { + break; + } + } + } else { + // There are NULLs in the sort column, so we can't use MySQL comparators. + // Fall back to iterating over every child row to get to the current one. + // This can be wildly inefficient for really large albums, but it should + // be a rare case that the user is sorting an album with null values in + // the sort column. + // + // Reproduce the children() functionality here using Database directly to + // avoid loading the whole ORM for each row. + $order_by = array($album->sort_column => $album->sort_order); + // Use id as a tie breaker + if ($album->sort_column != "id") { + $order_by["id"] = "ASC"; + } + + $position = 0; + foreach ($query_model->viewable() + ->select("id") + ->where("parent_id", "=", $album->id) + ->merge_where($where) + ->order_by($order_by) + ->find_all() as $row) { + $position++; + if ($row->id == $item->id) { + break; + } + } + } + + return $position; + } }
\ No newline at end of file diff --git a/modules/gallery/helpers/l10n_client.php b/modules/gallery/helpers/l10n_client.php index 8c2685a8..8fc66b68 100644 --- a/modules/gallery/helpers/l10n_client.php +++ b/modules/gallery/helpers/l10n_client.php @@ -55,15 +55,24 @@ class l10n_client_Core { $url = self::_server_url("status"); $signature = self::_sign($version, $api_key); - list ($response_data, $response_status) = remote::post( - $url, array("version" => $version, - "client_token" => l10n_client::client_token(), - "signature" => $signature, - "uid" => l10n_client::server_uid($api_key))); + try { + list ($response_data, $response_status) = remote::post( + $url, array("version" => $version, + "client_token" => l10n_client::client_token(), + "signature" => $signature, + "uid" => l10n_client::server_uid($api_key))); + } catch (ErrorException $e) { + // Log the error, but then return a "can't make connection" error + Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); + } + if (!isset($response_data) && !isset($response_status)) { + return array(false, false); + } + if (!remote::success($response_status)) { - return false; + return array(true, false); } - return true; + return array(true, true); } /** diff --git a/modules/gallery/helpers/locales.php b/modules/gallery/helpers/locales.php index 565e9da8..d06bb319 100644 --- a/modules/gallery/helpers/locales.php +++ b/modules/gallery/helpers/locales.php @@ -64,6 +64,7 @@ class locales_Core { // @todo Might want to add a localizable language name as well. // ref: http://cldr.unicode.org/ // ref: http://cldr.unicode.org/index/cldr-spec/picking-the-right-language-code + // ref: http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/likely_subtags.html private static function _init_language_data() { $l["af_ZA"] = "Afrikaans"; // Afrikaans $l["ar_SA"] = "العربية"; // Arabic @@ -88,6 +89,7 @@ class locales_Core { $l["fr_FR"] = "Français"; // French $l["ga_IE"] = "Gaeilge"; // Irish $l["he_IL"] = "עברית"; // Hebrew + $l["hr_HR"] = "hr̀vātskī"; // Croatian $l["hu_HU"] = "Magyar"; // Hungarian $l["is_IS"] = "Icelandic"; // Icelandic $l["it_IT"] = "Italiano"; // Italian diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php index 2b446daa..6efe6162 100644 --- a/modules/gallery/helpers/module.php +++ b/modules/gallery/helpers/module.php @@ -168,7 +168,7 @@ class module_Core { if (method_exists($installer_class, "install")) { call_user_func_array(array($installer_class, "install"), array()); } else { - module::set_version($module_name, 1); + module::set_version($module_name, module::available()->$module_name->code_version); } // Set the weight of the new module, which controls the order in which the modules are @@ -488,7 +488,7 @@ class module_Core { static function incr_var($module_name, $name, $increment=1) { db::build() ->update("vars") - ->set("value", new Database_Expression("`value` + $increment")) + ->set("value", db::expr("`value` + $increment")) ->where("module_name", "=", $module_name) ->where("name", "=", $name) ->execute(); diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 0895c5f4..dd0b437e 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -83,22 +83,18 @@ class movie_Core { } } + /** + * Return the path to the ffmpeg binary if one exists and is executable, or null. + */ static function find_ffmpeg() { if (!($ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) || !file_exists($ffmpeg_path)) { - gallery::set_path_env( - array(module::get_var("gallery", "graphics_toolkit_path"), - getenv("PATH"), - module::get_var("gallery", "extra_binary_paths"))); - if (function_exists("exec")) { - $ffmpeg_path = exec("which ffmpeg"); - } - + $ffmpeg_path = system::find_binary( + "ffmpeg", module::get_var("gallery", "graphics_toolkit_path")); module::set_var("gallery", "ffmpeg_path", $ffmpeg_path); } return $ffmpeg_path; } - /** * Return the width, height, mime_type and extension of the given movie file. */ diff --git a/modules/gallery/helpers/system.php b/modules/gallery/helpers/system.php new file mode 100644 index 00000000..4a6a3c0f --- /dev/null +++ b/modules/gallery/helpers/system.php @@ -0,0 +1,43 @@ +<?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 system_Core { + /** + * Return the path to an executable version of the named binary, or null. + * Traverse the PATH environment variable looking for the given file. If + * the $priority_path variable is set, check that path first. + */ + static function find_binary($binary, $priority_path=null) { + $paths = array_merge( + explode(":", getenv("PATH")), + explode(":", module::get_var("gallery", "extra_binary_paths"))); + if ($priority_path) { + array_unshift($paths, $priority_path); + } + + foreach ($paths as $path) { + $candidate = "$path/$binary"; + // @suppress errors below to avoid open_basedir issues + if (@file_exists($candidate) && @is_executable($candidate)) { + return $candidate; + } + } + return null; + } +}
\ No newline at end of file |