summaryrefslogtreecommitdiff
path: root/modules/gallery
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gallery')
-rw-r--r--modules/gallery/controllers/admin_languages.php12
-rw-r--r--modules/gallery/controllers/admin_maintenance.php2
-rw-r--r--modules/gallery/controllers/albums.php24
-rw-r--r--modules/gallery/controllers/combined.php3
-rw-r--r--modules/gallery/controllers/file_proxy.php13
-rw-r--r--modules/gallery/controllers/login.php2
-rw-r--r--modules/gallery/controllers/movies.php24
-rw-r--r--modules/gallery/controllers/packager.php2
-rw-r--r--modules/gallery/controllers/photos.php24
-rw-r--r--modules/gallery/helpers/gallery.php77
-rw-r--r--modules/gallery/helpers/gallery_event.php6
-rw-r--r--modules/gallery/helpers/gallery_graphics.php4
-rw-r--r--modules/gallery/helpers/gallery_installer.php23
-rw-r--r--modules/gallery/helpers/gallery_task.php6
-rw-r--r--modules/gallery/helpers/graphics.php86
-rw-r--r--modules/gallery/helpers/item.php88
-rw-r--r--modules/gallery/helpers/l10n_client.php23
-rw-r--r--modules/gallery/helpers/locales.php2
-rw-r--r--modules/gallery/helpers/module.php4
-rw-r--r--modules/gallery/helpers/movie.php14
-rw-r--r--modules/gallery/helpers/system.php43
-rw-r--r--modules/gallery/libraries/Admin_View.php17
-rw-r--r--modules/gallery/libraries/Gallery_View.php61
-rw-r--r--modules/gallery/libraries/MY_View.php10
-rw-r--r--modules/gallery/libraries/Menu.php4
-rw-r--r--modules/gallery/libraries/ORM_MPTT.php22
-rw-r--r--modules/gallery/libraries/Theme_View.php24
-rw-r--r--modules/gallery/libraries/drivers/Cache/Database.php37
-rw-r--r--modules/gallery/models/item.php95
-rw-r--r--modules/gallery/module.info2
-rw-r--r--modules/gallery/tests/Gallery_Installer_Test.php2
-rw-r--r--modules/gallery/tests/Item_Model_Test.php4
-rw-r--r--modules/gallery/tests/xss_data.txt24
-rw-r--r--modules/gallery/views/movieplayer.html.php3
34 files changed, 442 insertions, 345 deletions
diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php
index 573ededf..f96a0eb7 100644
--- a/modules/gallery/controllers/admin_languages.php
+++ b/modules/gallery/controllers/admin_languages.php
@@ -74,9 +74,11 @@ class Admin_Languages_Controller extends Admin_Controller {
private function _save_api_key($form) {
$new_key = $form->sharing->api_key->value;
- if ($new_key && !l10n_client::validate_api_key($new_key)) {
- $form->sharing->api_key->add_error("invalid", 1);
- $valid = false;
+ if ($new_key) {
+ list($connected, $valid) = l10n_client::validate_api_key($new_key);
+ if (!$valid) {
+ $form->sharing->api_key->add_error($connected ? "invalid" : "no_connection", 1);
+ }
} else {
$valid = true;
}
@@ -119,7 +121,9 @@ class Admin_Languages_Controller extends Admin_Controller {
array("server-link" => html::mark_clean(html::anchor($server_link))))
: t("API key"))
->value($api_key)
- ->error_messages("invalid", t("The API key you provided is invalid."));
+ ->error_messages("invalid", t("The API key you provided is invalid."))
+ ->error_messages(
+ "no_connection", t("Could not connect to remote server to validate the API key."));
$group->submit("save")->value(t("Save settings"));
if ($api_key && $this->_outgoing_translations_count()) {
// TODO: UI improvement: hide API key / save button when API key is set.
diff --git a/modules/gallery/controllers/admin_maintenance.php b/modules/gallery/controllers/admin_maintenance.php
index 7729d797..80247a0f 100644
--- a/modules/gallery/controllers/admin_maintenance.php
+++ b/modules/gallery/controllers/admin_maintenance.php
@@ -27,7 +27,7 @@ class Admin_Maintenance_Controller extends Admin_Controller {
->set("state", "stalled")
->where("done", "=", 0)
->where("state", "<>", "stalled")
- ->where(new Database_Expression("UNIX_TIMESTAMP(NOW()) - `updated` > 15"))
+ ->where(db::expr("UNIX_TIMESTAMP(NOW()) - `updated` > 15"))
->execute();
$stalled_count = $query->count();
if ($stalled_count) {
diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php
index b0887195..3435465c 100644
--- a/modules/gallery/controllers/albums.php
+++ b/modules/gallery/controllers/albums.php
@@ -37,7 +37,7 @@ class Albums_Controller extends Items_Controller {
if ($show) {
$child = ORM::factory("item", $show);
- $index = $album->get_position($child);
+ $index = item::get_position($child);
if ($index) {
$page = ceil($index / $page_size);
if ($page == 1) {
@@ -61,20 +61,18 @@ class Albums_Controller extends Items_Controller {
}
$template = new Theme_View("page.html", "collection", "album");
- $template->set_global("page", $page);
- $template->set_global("page_title", null);
- $template->set_global("max_pages", $max_pages);
- $template->set_global("page_size", $page_size);
- $template->set_global("item", $album);
- $template->set_global("children", $album->viewable()->children($page_size, $offset));
- $template->set_global("children_count", $children_count);
- $template->set_global("parents", $album->parents()->as_array()); // view calls empty() on this
+ $template->set_global(
+ array("page" => $page,
+ "page_title" => null,
+ "max_pages" => $max_pages,
+ "page_size" => $page_size,
+ "item" => $album,
+ "children" => $album->viewable()->children($page_size, $offset),
+ "parents" => $album->parents()->as_array(), // view calls empty() on this
+ "children_count" => $children_count));
$template->content = new View("album.html");
- // We can't use math in ORM or the query builder, so do this by hand. It's important
- // that we do this with math, otherwise concurrent accesses will damage accuracy.
- db::query("UPDATE {items} SET `view_count` = `view_count` + 1 WHERE `id` = $album->id")
- ->execute();
+ $album->increment_view_count();
print $template;
}
diff --git a/modules/gallery/controllers/combined.php b/modules/gallery/controllers/combined.php
index 4b1a342a..64f8d22b 100644
--- a/modules/gallery/controllers/combined.php
+++ b/modules/gallery/controllers/combined.php
@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Combined_Controller extends Controller {
+ const ALLOW_MAINTENANCE_MODE = true;
+ const ALLOW_PRIVATE_GALLERY = true;
+
/**
* Return the combined Javascript bundle associated with the given key.
*/
diff --git a/modules/gallery/controllers/file_proxy.php b/modules/gallery/controllers/file_proxy.php
index 22854fbd..98f4e839 100644
--- a/modules/gallery/controllers/file_proxy.php
+++ b/modules/gallery/controllers/file_proxy.php
@@ -27,10 +27,13 @@
* input is sanitized against the database before we perform any file I/O.
*/
class File_Proxy_Controller extends Controller {
+ const ALLOW_PRIVATE_GALLERY = true;
public function __call($function, $args) {
- // request_uri: gallery3/var/trunk/albums/foo/bar.jpg
+ // request_uri: gallery3/var/albums/foo/bar.jpg?m=1234
$request_uri = rawurldecode(Input::instance()->server("REQUEST_URI"));
+ // get rid of query parameters
+ // request_uri: gallery3/var/albums/foo/bar.jpg
$request_uri = preg_replace("/\?.*/", "", $request_uri);
// var_uri: gallery3/var/
@@ -42,13 +45,11 @@ class File_Proxy_Controller extends Controller {
throw new Kohana_404_Exception();
}
+ // file_uri: albums/foo/bar.jpg
$file_uri = substr($request_uri, strlen($var_uri));
- // Make sure that we don't leave the var dir
- if (strpos($file_uri, "..") !== false) {
- throw new Kohana_404_Exception();
- }
-
+ // type: albums
+ // path: foo/bar.jpg
list ($type, $path) = explode("/", $file_uri, 2);
if ($type != "resizes" && $type != "albums" && $type != "thumbs") {
throw new Kohana_404_Exception();
diff --git a/modules/gallery/controllers/login.php b/modules/gallery/controllers/login.php
index 62d33345..adb2e50b 100644
--- a/modules/gallery/controllers/login.php
+++ b/modules/gallery/controllers/login.php
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Login_Controller extends Controller {
+ const ALLOW_MAINTENANCE_MODE = true;
+ const ALLOW_PRIVATE_GALLERY = true;
public function ajax() {
$view = new View("login_ajax.html");
diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php
index 717eb8aa..7c85dd98 100644
--- a/modules/gallery/controllers/movies.php
+++ b/modules/gallery/controllers/movies.php
@@ -28,29 +28,29 @@ class Movies_Controller extends Items_Controller {
access::required("view", $movie);
$where = array(array("type", "!=", "album"));
- $position = $movie->parent()->get_position($movie, $where);
+ $position = item::get_position($movie, $where);
if ($position > 1) {
list ($previous_item, $ignore, $next_item) =
- $movie->parent()->children(3, $position - 2, $where);
+ $movie->parent()->viewable()->children(3, $position - 2, $where);
} else {
$previous_item = null;
list ($next_item) = $movie->parent()->viewable()->children(1, $position, $where);
}
$template = new Theme_View("page.html", "item", "movie");
- $template->set_global("item", $movie);
- $template->set_global("children", array());
- $template->set_global("children_count", 0);
- $template->set_global("parents", $movie->parents()->as_array());
- $template->set_global("next_item", $next_item);
- $template->set_global("previous_item", $previous_item);
- $template->set_global("sibling_count", $movie->parent()->viewable()->children_count($where));
- $template->set_global("position", $position);
+ $template->set_global(
+ array("item" => $movie,
+ "children" => array(),
+ "children_count" => 0,
+ "parents" => $movie->parents()->as_array(),
+ "next_item" => $next_item,
+ "previous_item" => $previous_item,
+ "sibling_count" => $movie->parent()->viewable()->children_count($where),
+ "position" => $position));
$template->content = new View("movie.html");
- $movie->view_count++;
- $movie->save();
+ $movie->increment_view_count();
print $template;
}
diff --git a/modules/gallery/controllers/packager.php b/modules/gallery/controllers/packager.php
index bd51b93c..9da34f9c 100644
--- a/modules/gallery/controllers/packager.php
+++ b/modules/gallery/controllers/packager.php
@@ -59,7 +59,7 @@ class Packager_Controller extends Controller {
// numbers, keeping our install.sql file more stable.
srand(0);
- foreach (array("gallery", "user", "comment", "organize", "info", "rest",
+ foreach (array("gallery", "user", "comment", "organize", "info",
"rss", "search", "slideshow", "tag") as $module_name) {
module::install($module_name);
module::activate($module_name);
diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php
index b22ac8e5..4578747d 100644
--- a/modules/gallery/controllers/photos.php
+++ b/modules/gallery/controllers/photos.php
@@ -28,29 +28,29 @@ class Photos_Controller extends Items_Controller {
access::required("view", $photo);
$where = array(array("type", "!=", "album"));
- $position = $photo->parent()->get_position($photo, $where);
+ $position = item::get_position($photo, $where);
if ($position > 1) {
list ($previous_item, $ignore, $next_item) =
- $photo->parent()->children(3, $position - 2, $where);
+ $photo->parent()->viewable()->children(3, $position - 2, $where);
} else {
$previous_item = null;
list ($next_item) = $photo->parent()->viewable()->children(1, $position, $where);
}
$template = new Theme_View("page.html", "item", "photo");
- $template->set_global("item", $photo);
- $template->set_global("children", array());
- $template->set_global("children_count", 0);
- $template->set_global("parents", $photo->parents()->as_array());
- $template->set_global("next_item", $next_item);
- $template->set_global("previous_item", $previous_item);
- $template->set_global("sibling_count", $photo->parent()->viewable()->children_count($where));
- $template->set_global("position", $position);
+ $template->set_global(
+ array("item" => $photo,
+ "children" => array(),
+ "children_count" => 0,
+ "parents" => $photo->parents()->as_array(),
+ "next_item" => $next_item,
+ "previous_item" => $previous_item,
+ "sibling_count" => $photo->parent()->viewable()->children_count($where),
+ "position" => $position));
$template->content = new View("photo.html");
- $photo->view_count++;
- $photo->save();
+ $photo->increment_view_count();
print $template;
}
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
diff --git a/modules/gallery/libraries/Admin_View.php b/modules/gallery/libraries/Admin_View.php
index 11f8ad14..1a633a34 100644
--- a/modules/gallery/libraries/Admin_View.php
+++ b/modules/gallery/libraries/Admin_View.php
@@ -34,11 +34,11 @@ class Admin_View_Core extends Gallery_View {
$this->theme_name = Input::instance()->get("theme", $this->theme_name);
}
$this->sidebar = "";
- $this->set_global("theme", $this);
- $this->set_global("user", identity::active_user());
- $this->set_global("page_type", "admin");
- $this->set_global("page_subtype", $name);
- $this->set_global("page_title", null);
+ $this->set_global(array("theme" => $this,
+ "user" => identity::active_user(),
+ "page_type" => "admin",
+ "page_subtype" => $name,
+ "page_title" => null));
}
public function admin_menu() {
@@ -46,7 +46,7 @@ class Admin_View_Core extends Gallery_View {
module::event("admin_menu", $menu, $this);
$settings_menu = $menu->get("settings_menu");
- sort($settings_menu->elements);
+ uasort($settings_menu->elements, array("Menu", "title_comparator"));
return $menu->render();
}
@@ -96,11 +96,6 @@ class Admin_View_Core extends Gallery_View {
}
}
- if ($function == "admin_head") {
- array_unshift($blocks, $this->combine_files($this->scripts, "javascript"));
- array_unshift($blocks, $this->combine_files($this->css, "css"));
- }
-
if (Session::instance()->get("debug")) {
if ($function != "admin_head") {
array_unshift(
diff --git a/modules/gallery/libraries/Gallery_View.php b/modules/gallery/libraries/Gallery_View.php
index b45bb94a..8befda95 100644
--- a/modules/gallery/libraries/Gallery_View.php
+++ b/modules/gallery/libraries/Gallery_View.php
@@ -19,18 +19,35 @@
*/
class Gallery_View_Core extends View {
protected $theme_name = null;
- protected $scripts = array();
- protected $css = array();
+ protected $combine_queue = array();
/**
- * Add a script to the combined scripts list.
+ * Begin gather up scripts or css files so that they can be combined into a single request.
+ *
+ * @param $types a comma separated list of types to combine, eg "script,css"
+ */
+ public function start_combining($types) {
+ foreach (explode(",", $types) as $type) {
+ $this->combine_queue[$type] = array();
+ }
+ }
+
+ /**
+ * If script combining is enabled, add this script to the list of scripts that will be
+ * combined into a single script element. When combined, the order of scripts is preserved.
+ *
* @param $file the file name or path of the script to include. If a path is specified then
* it needs to be relative to DOCROOT. Just specifying a file name will result
* in searching Kohana's cascading file system.
+ * @param $group the group of scripts to combine this with. defaults to "core"
*/
- public function script($file) {
+ public function script($file, $group="core") {
if (($path = gallery::find_file("js", $file, false))) {
- $this->scripts[$path] = 1;
+ if (isset($this->combine_queue["script"])) {
+ $this->combine_queue["script"][$group][$path] = 1;
+ } else {
+ return html::script($path);
+ }
} else {
Kohana_Log::add("error", "Can't find script file: $file");
}
@@ -46,14 +63,22 @@ class Gallery_View_Core extends View {
}
/**
- * Add a css file to the combined css list.
- * @param $file the file name or path of the script to include. If a path is specified then
+ * If css combining is enabled, add this css to the list of css that will be
+ * combined into a single style element. When combined, the order of style elements
+ * is preserved.
+ *
+ * @param $file the file name or path of the css to include. If a path is specified then
* it needs to be relative to DOCROOT. Just specifying a file name will result
* in searching Kohana's cascading file system.
+ * @param $group the group of css to combine this with. defaults to "core"
*/
- public function css($file) {
+ public function css($file, $group="core") {
if (($path = gallery::find_file("css", $file, false))) {
- $this->css[$path] = 1;
+ if (isset($this->combine_queue["css"])) {
+ $this->combine_queue["css"][$group][$path] = 1;
+ } else {
+ return html::stylesheet($path);
+ }
} else {
Kohana_Log::add("error", "Can't find css file: $file");
}
@@ -61,11 +86,13 @@ class Gallery_View_Core extends View {
/**
* Combine a series of files into a single one and cache it in the database.
+ * @param $type the data type (script or css)
+ * @param $group the group of scripts or css we want
*/
- protected function combine_files($paths, $type) {
+ public function get_combined($type, $group="core") {
$links = array();
- if (empty($paths)) {
+ if (empty($this->combine_queue[$type][$group])) {
return;
}
@@ -73,7 +100,7 @@ class Gallery_View_Core extends View {
// entries.
$key = array(url::abs_file(""));
- foreach (array_keys($paths) as $path) {
+ foreach (array_keys($this->combine_queue[$type][$group]) as $path) {
$stats = stat($path);
// 7 == size, 9 == mtime, see http://php.net/stat
$key[] = "$path $stats[7] $stats[9]";
@@ -85,7 +112,7 @@ class Gallery_View_Core extends View {
if (empty($contents)) {
$contents = "";
- foreach (array_keys($paths) as $path) {
+ foreach (array_keys($this->combine_queue[$type][$group]) as $path) {
if ($type == "css") {
$contents .= "/* $path */\n" . $this->process_css($path) . "\n";
} else {
@@ -103,12 +130,12 @@ class Gallery_View_Core extends View {
}
}
+ unset($this->combine_queue[$type][$group]);
+
if ($type == "css") {
- return "<!-- LOOKING FOR YOUR CSS? It's all been combined into the link below -->\n" .
- html::stylesheet("combined/css/$key", "screen,print,projection", true);
+ return html::stylesheet("combined/css/$key", "screen,print,projection", true);
} else {
- return "<!-- LOOKING FOR YOUR JAVASCRIPT? It's all been combined into the link below -->\n" .
- html::script("combined/javascript/$key", true);
+ return html::script("combined/javascript/$key", true);
}
}
diff --git a/modules/gallery/libraries/MY_View.php b/modules/gallery/libraries/MY_View.php
index ded77792..2230203a 100644
--- a/modules/gallery/libraries/MY_View.php
+++ b/modules/gallery/libraries/MY_View.php
@@ -23,8 +23,14 @@ class View extends View_Core {
/**
* Reimplement Kohana 2.3's View::set_global() functionality.
*/
- public function set_global($key, $value) {
- View::$global_data[$key] = $value;
+ public function set_global($key, $value = NULL) {
+ if (is_array($key)) {
+ foreach ($key as $key2 => $value) {
+ View::$global_data[$key2] = $value;
+ }
+ } else {
+ View::$global_data[$key] = $value;
+ }
}
public function is_set($key=null) {
diff --git a/modules/gallery/libraries/Menu.php b/modules/gallery/libraries/Menu.php
index 58852a72..78b60196 100644
--- a/modules/gallery/libraries/Menu.php
+++ b/modules/gallery/libraries/Menu.php
@@ -250,4 +250,8 @@ class Menu_Core extends Menu_Element {
$view->menu = $this;
return $view;
}
+
+ static function title_comparator($a, $b) {
+ return strnatcasecmp((string)$a->label, (string)$b->label);
+ }
}
diff --git a/modules/gallery/libraries/ORM_MPTT.php b/modules/gallery/libraries/ORM_MPTT.php
index f20fafa0..4556273c 100644
--- a/modules/gallery/libraries/ORM_MPTT.php
+++ b/modules/gallery/libraries/ORM_MPTT.php
@@ -54,12 +54,12 @@ class ORM_MPTT_Core extends ORM {
// Make a hole in the parent for this new item
db::build()
->update($this->table_name)
- ->set("left_ptr", new Database_Expression("`left_ptr` + 2"))
+ ->set("left_ptr", db::expr("`left_ptr` + 2"))
->where("left_ptr", ">=", $parent->right_ptr)
->execute();
db::build()
->update($this->table_name)
- ->set("right_ptr", new Database_Expression("`right_ptr` + 2"))
+ ->set("right_ptr", db::expr("`right_ptr` + 2"))
->where("right_ptr", ">=", $parent->right_ptr)
->execute();
$parent->right_ptr += 2;
@@ -109,12 +109,12 @@ class ORM_MPTT_Core extends ORM {
try {
db::build()
->update($this->table_name)
- ->set("left_ptr", new Database_Expression("`left_ptr` - 2"))
+ ->set("left_ptr", db::expr("`left_ptr` - 2"))
->where("left_ptr", ">", $this->right_ptr)
->execute();
db::build()
->update($this->table_name)
- ->set("right_ptr", new Database_Expression("`right_ptr` - 2"))
+ ->set("right_ptr", db::expr("`right_ptr` - 2"))
->where("right_ptr", ">", $this->right_ptr)
->execute();
} catch (Exception $e) {
@@ -253,7 +253,7 @@ class ORM_MPTT_Core extends ORM {
// Update the levels for the to-be-moved items
db::build()
->update($this->table_name)
- ->set("level", new Database_Expression("`level` + $level_delta"))
+ ->set("level", db::expr("`level` + $level_delta"))
->where("left_ptr", ">=", $original_left_ptr)
->where("right_ptr", "<=", $original_right_ptr)
->execute();
@@ -262,12 +262,12 @@ class ORM_MPTT_Core extends ORM {
// Make a hole in the target for the move
db::build()
->update($this->table_name)
- ->set("left_ptr", new Database_Expression("`left_ptr` + $size_of_hole"))
+ ->set("left_ptr", db::expr("`left_ptr` + $size_of_hole"))
->where("left_ptr", ">=", $target_right_ptr)
->execute();
db::build()
->update($this->table_name)
- ->set("right_ptr", new Database_Expression("`right_ptr` + $size_of_hole"))
+ ->set("right_ptr", db::expr("`right_ptr` + $size_of_hole"))
->where("right_ptr", ">=", $target_right_ptr)
->execute();
@@ -290,8 +290,8 @@ class ORM_MPTT_Core extends ORM {
$new_offset = $target->right_ptr - $left_ptr;
db::build()
->update($this->table_name)
- ->set("left_ptr", new Database_Expression("`left_ptr` + $new_offset"))
- ->set("right_ptr", new Database_Expression("`right_ptr` + $new_offset"))
+ ->set("left_ptr", db::expr("`left_ptr` + $new_offset"))
+ ->set("right_ptr", db::expr("`right_ptr` + $new_offset"))
->where("left_ptr", ">=", $left_ptr)
->where("right_ptr", "<=", $right_ptr)
->execute();
@@ -299,12 +299,12 @@ class ORM_MPTT_Core extends ORM {
// Close the hole in the source's parent after the move
db::build()
->update($this->table_name)
- ->set("left_ptr", new Database_Expression("`left_ptr` - $size_of_hole"))
+ ->set("left_ptr", db::expr("`left_ptr` - $size_of_hole"))
->where("left_ptr", ">", $right_ptr)
->execute();
db::build()
->update($this->table_name)
- ->set("right_ptr", new Database_Expression("`right_ptr` - $size_of_hole"))
+ ->set("right_ptr", db::expr("`right_ptr` - $size_of_hole"))
->where("right_ptr", ">", $right_ptr)
->execute();
} catch (Exception $e) {
diff --git a/modules/gallery/libraries/Theme_View.php b/modules/gallery/libraries/Theme_View.php
index d22bb03a..04784ca1 100644
--- a/modules/gallery/libraries/Theme_View.php
+++ b/modules/gallery/libraries/Theme_View.php
@@ -37,11 +37,11 @@ class Theme_View_Core extends Gallery_View {
}
$this->item = null;
$this->tag = null;
- $this->set_global("theme", $this);
- $this->set_global("user", identity::active_user());
- $this->set_global("page_type", $page_type);
- $this->set_global("page_subtype", $page_subtype);
- $this->set_global("page_title", null);
+ $this->set_global(array("theme" => $this,
+ "user" => identity::active_user(),
+ "page_type" => $page_type,
+ "page_subtype" => $page_subtype,
+ "page_title" => null));
if ($page_type == "collection") {
$this->set_global("thumb_proportion", $this->thumb_proportion());
}
@@ -236,13 +236,6 @@ class Theme_View_Core extends Gallery_View {
case "thumb_bottom":
case "thumb_info":
case "thumb_top":
- if ($function == "head") {
- // Stash any CSS we have already; that came from the theme and we want theme CSS to
- // override module CSs
- $save_css = $this->css;
- $this->css = array();
- }
-
$blocks = array();
if (method_exists("gallery_theme", $function)) {
switch (count($args)) {
@@ -281,13 +274,6 @@ class Theme_View_Core extends Gallery_View {
array_merge(array($this), $args));
}
- if ($function == "head") {
- // Merge the theme CSS/JS at the end
- $this->css = array_merge($this->css, $save_css);
- array_unshift($blocks, $this->combine_files($this->scripts, "javascript"));
- array_unshift($blocks, $this->combine_files($this->css, "css"));
- }
-
if (Session::instance()->get("debug")) {
if ($function != "head" && $function != "body_attributes") {
array_unshift(
diff --git a/modules/gallery/libraries/drivers/Cache/Database.php b/modules/gallery/libraries/drivers/Cache/Database.php
index b7822811..2e773ca4 100644
--- a/modules/gallery/libraries/drivers/Cache/Database.php
+++ b/modules/gallery/libraries/drivers/Cache/Database.php
@@ -25,20 +25,6 @@ class Cache_Database_Driver extends Cache_Driver {
protected $db;
/**
- * Checks if a cache id is already set.
- *
- * @param string cache id
- * @return boolean
- */
- public function exists($id) {
- $count = db::build()
- ->where("key", "=", $id)
- ->where("expiration", ">=", time())
- ->count_records("caches");
- return $count > 0;
- }
-
- /**
* Sets a cache item to the given data, tags, and lifetime.
*
* @param array assoc array of key => value pairs
@@ -59,22 +45,15 @@ class Cache_Database_Driver extends Cache_Driver {
$lifetime += time();
}
+ $db = Database::instance();
+ $tags = $db->escape($tags);
foreach ($items as $id => $data) {
- if ($this->exists($id)) {
- $status = db::build()
- ->update("caches")
- ->set("tags", $tags)
- ->set("expiration", $lifetime)
- ->set("cache", serialize($data))
- ->where("key", "=", $id)
- ->execute();
- } else {
- $status = db::build()
- ->insert("caches")
- ->columns("key", "tags", "expiration", "cache")
- ->values($id, $tags, $lifetime, serialize($data))
- ->execute();
- }
+ $id = $db->escape($id);
+ $data = $db->escape(serialize($data));
+ $db->query("INSERT INTO {caches} (`key`, `tags`, `expiration`, `cache`)
+ VALUES ('$id', '$tags', $lifetime, '$data')
+ ON DUPLICATE KEY UPDATE `tags` = VALUES(tags), `expiration` = VALUES(expiration),
+ `cache` = VALUES(cache)");
}
return true;
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index fc5c3ff9..47b062b8 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -546,83 +546,12 @@ class Item_Model_Core extends ORM_MPTT {
/**
* Find the position of the given child id in this album. The resulting value is 1-indexed, so
* the first child in the album is at position 1.
+ *
+ * This method stands as a backward compatibility for gallery 3.0, and will
+ * be deprecated in version 3.1.
*/
public function get_position($child, $where=array()) {
- if (!strcasecmp($this->sort_order, "DESC")) {
- $comp = ">";
- } else {
- $comp = "<";
- }
- $db = db::build();
-
- // 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 = $db->from("items")
- ->where("parent_id", "=", $this->id)
- ->where($this->sort_column, "IS", null)
- ->merge_where($where)
- ->count_records();
-
- if (empty($count)) {
- // There are no NULLs in the sort column, so we can just use it directly.
- $sort_column = $this->sort_column;
-
- $position = $db->from("items")
- ->where("parent_id", "=", $this->id)
- ->where($sort_column, $comp, $child->$sort_column)
- ->merge_where($where)
- ->count_records();
-
- // We stopped short of our target value in the sort (notice that we're using a < 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 base value.
- foreach ($db
- ->select("id")
- ->from("items")
- ->where("parent_id", "=", $this->id)
- ->where($sort_column, "=", $child->$sort_column)
- ->merge_where($where)
- ->order_by(array("id" => "ASC"))
- ->execute() as $row) {
- $position++;
- if ($row->id == $child->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($this->sort_column => $this->sort_order);
- // Use id as a tie breaker
- if ($this->sort_column != "id") {
- $order_by["id"] = "ASC";
- }
-
- $position = 0;
- foreach ($db->select("id")
- ->from("items")
- ->where("parent_id", "=", $this->id)
- ->merge_where($where)
- ->order_by($order_by)
- ->execute() as $row) {
- $position++;
- if ($row->id == $child->id) {
- break;
- }
- }
- }
-
- return $position;
+ return item::get_position($child, $where);
}
/**
@@ -653,7 +582,7 @@ class Item_Model_Core extends ORM_MPTT {
/**
* Calculate the largest width/height that fits inside the given maximum, while preserving the
- * aspect ratio.
+ * aspect ratio. Don't upscale.
* @param int $max Maximum size of the largest dimension
* @return array
*/
@@ -661,6 +590,10 @@ class Item_Model_Core extends ORM_MPTT {
$width = $this->thumb_width;
$height = $this->thumb_height;
+ if ($width <= $max && $height <= $max) {
+ return array($height, $width);
+ }
+
if ($height) {
if (isset($max)) {
if ($width > $height) {
@@ -1078,6 +1011,16 @@ class Item_Model_Core extends ORM_MPTT {
return $data;
}
+ /**
+ * Increments the view counter of this item
+ * We can't use math in ORM or the query builder, so do this by hand. It's important
+ * that we do this with math, otherwise concurrent accesses will damage accuracy.
+ */
+ public function increment_view_count() {
+ db::query("UPDATE {items} SET `view_count` = `view_count` + 1 WHERE `id` = $this->id")
+ ->execute();
+ }
+
private function _cache_buster($path) {
return "?m=" . (string)(file_exists($path) ? filemtime($path) : 0);
}
diff --git a/modules/gallery/module.info b/modules/gallery/module.info
index 2b684e5e..eb579ab6 100644
--- a/modules/gallery/module.info
+++ b/modules/gallery/module.info
@@ -1,3 +1,3 @@
name = "Gallery 3"
description = "Gallery core application"
-version = 41
+version = 43
diff --git a/modules/gallery/tests/Gallery_Installer_Test.php b/modules/gallery/tests/Gallery_Installer_Test.php
index 67e712de..d34c3b0e 100644
--- a/modules/gallery/tests/Gallery_Installer_Test.php
+++ b/modules/gallery/tests/Gallery_Installer_Test.php
@@ -35,7 +35,7 @@ class Gallery_Installer_Test extends Gallery_Unit_Test_Case {
public function install_creates_root_item_test() {
$max_right_ptr = ORM::factory("item")
- ->select(new Database_Expression("MAX(`right_ptr`) AS `right_ptr`"))
+ ->select(db::expr("MAX(`right_ptr`) AS `right_ptr`"))
->find()->right_ptr;
$root = ORM::factory('item')->find(1);
$this->assert_equal("Gallery", $root->title);
diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php
index 4987d2f9..0554c0e2 100644
--- a/modules/gallery/tests/Item_Model_Test.php
+++ b/modules/gallery/tests/Item_Model_Test.php
@@ -362,11 +362,11 @@ class Item_Model_Test extends Gallery_Unit_Test_Case {
}
public function as_restful_array_with_edit_bit_test() {
- $response = item::root()->as_restful_array(true);
+ $response = item::root()->as_restful_array();
$this->assert_true($response["can_edit"]);
identity::set_active_user(identity::guest());
- $response = item::root()->as_restful_array(true);
+ $response = item::root()->as_restful_array();
$this->assert_false($response["can_edit"]);
}
diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt
index 7c5e803d..366391cf 100644
--- a/modules/gallery/tests/xss_data.txt
+++ b/modules/gallery/tests/xss_data.txt
@@ -399,17 +399,19 @@ themes/wind/views/dynamic.html.php 29 DIRTY $theme
themes/wind/views/movie.html.php 5 DIRTY $theme->paginator()
themes/wind/views/movie.html.php 9 DIRTY $item->movie_img(array("class"=>"g-movie","id"=>"g-item-id-{$item->id}"))
themes/wind/views/page.html.php 9 DIRTY $page_title
-themes/wind/views/page.html.php 32 DIRTY_JS $theme->url()
-themes/wind/views/page.html.php 41 DIRTY $new_width
-themes/wind/views/page.html.php 42 DIRTY $new_height
-themes/wind/views/page.html.php 43 DIRTY $thumb_proportion
-themes/wind/views/page.html.php 80 DIRTY $header_text
-themes/wind/views/page.html.php 82 DIRTY_JS item::root()->url()
-themes/wind/views/page.html.php 86 DIRTY $theme->user_menu()
-themes/wind/views/page.html.php 107 DIRTY_JS $parent->url($parent->id==$theme->item()->parent_id?"show={$theme->item()->id}":null)
-themes/wind/views/page.html.php 128 DIRTY $content
-themes/wind/views/page.html.php 134 DIRTY newView("sidebar.html")
-themes/wind/views/page.html.php 141 DIRTY $footer_text
+themes/wind/views/page.html.php 12 DIRTY $theme->item()->title
+themes/wind/views/page.html.php 16 DIRTY item::root()->title
+themes/wind/views/page.html.php 26 DIRTY_JS $theme->url()
+themes/wind/views/page.html.php 35 DIRTY $new_width
+themes/wind/views/page.html.php 36 DIRTY $new_height
+themes/wind/views/page.html.php 37 DIRTY $thumb_proportion
+themes/wind/views/page.html.php 74 DIRTY $header_text
+themes/wind/views/page.html.php 76 DIRTY_JS item::root()->url()
+themes/wind/views/page.html.php 80 DIRTY $theme->user_menu()
+themes/wind/views/page.html.php 101 DIRTY_JS $parent->url($parent->id==$theme->item()->parent_id?"show={$theme->item()->id}":null)
+themes/wind/views/page.html.php 122 DIRTY $content
+themes/wind/views/page.html.php 128 DIRTY newView("sidebar.html")
+themes/wind/views/page.html.php 135 DIRTY $footer_text
themes/wind/views/paginator.html.php 33 DIRTY_JS $first_page_url
themes/wind/views/paginator.html.php 42 DIRTY_JS $previous_page_url
themes/wind/views/paginator.html.php 70 DIRTY_JS $next_page_url
diff --git a/modules/gallery/views/movieplayer.html.php b/modules/gallery/views/movieplayer.html.php
index 2e79b620..5c280a36 100644
--- a/modules/gallery/views/movieplayer.html.php
+++ b/modules/gallery/views/movieplayer.html.php
@@ -9,6 +9,9 @@
provider: "pseudostreaming"
},
{
+ clip: {
+ scaling: 'fit'
+ },
plugins: {
pseudostreaming: {
url: "<?= url::abs_file("lib/flowplayer.pseudostreaming.swf") ?>"