summaryrefslogtreecommitdiff
path: root/modules/gallery/helpers
diff options
context:
space:
mode:
authorNathan Kinkade <nath@nkinka.de>2013-02-14 14:28:46 +0000
committerNathan Kinkade <nath@nkinka.de>2013-02-14 14:28:46 +0000
commit711651f727e093cc7357a6bbff6bd992fd6dfd80 (patch)
tree2dadc1c06acf1ab3d42d3ed5415568535db54416 /modules/gallery/helpers
parent0047af90bf4db08b22838e6ded22a7fa70cee98a (diff)
parente5ed05004f005bdccdbf68e199ae2324ad97e895 (diff)
Merge branch 'master' of git://github.com/gallery/gallery3
Diffstat (limited to 'modules/gallery/helpers')
-rw-r--r--modules/gallery/helpers/MY_html.php2
-rw-r--r--modules/gallery/helpers/MY_num.php2
-rw-r--r--modules/gallery/helpers/MY_remote.php2
-rw-r--r--modules/gallery/helpers/MY_url.php2
-rw-r--r--modules/gallery/helpers/MY_valid.php2
-rw-r--r--modules/gallery/helpers/access.php2
-rw-r--r--modules/gallery/helpers/ajax.php2
-rw-r--r--modules/gallery/helpers/album.php2
-rw-r--r--modules/gallery/helpers/auth.php2
-rw-r--r--modules/gallery/helpers/batch.php2
-rw-r--r--modules/gallery/helpers/block_manager.php2
-rw-r--r--modules/gallery/helpers/data_rest.php74
-rw-r--r--modules/gallery/helpers/dir.php2
-rw-r--r--modules/gallery/helpers/encoding.php2
-rw-r--r--modules/gallery/helpers/gallery.php18
-rw-r--r--modules/gallery/helpers/gallery_block.php4
-rw-r--r--modules/gallery/helpers/gallery_error.php2
-rw-r--r--modules/gallery/helpers/gallery_event.php42
-rw-r--r--modules/gallery/helpers/gallery_graphics.php149
-rw-r--r--modules/gallery/helpers/gallery_installer.php68
-rw-r--r--modules/gallery/helpers/gallery_rss.php2
-rw-r--r--modules/gallery/helpers/gallery_task.php117
-rw-r--r--modules/gallery/helpers/gallery_theme.php8
-rw-r--r--modules/gallery/helpers/graphics.php197
-rw-r--r--modules/gallery/helpers/identity.php2
-rw-r--r--modules/gallery/helpers/item.php109
-rw-r--r--modules/gallery/helpers/item_rest.php4
-rw-r--r--modules/gallery/helpers/items_rest.php2
-rw-r--r--modules/gallery/helpers/json.php2
-rw-r--r--modules/gallery/helpers/l10n_client.php4
-rw-r--r--modules/gallery/helpers/l10n_scanner.php2
-rw-r--r--modules/gallery/helpers/legal_file.php242
-rw-r--r--modules/gallery/helpers/locales.php2
-rw-r--r--modules/gallery/helpers/log.php2
-rw-r--r--modules/gallery/helpers/message.php2
-rw-r--r--modules/gallery/helpers/model_cache.php2
-rw-r--r--modules/gallery/helpers/module.php5
-rw-r--r--modules/gallery/helpers/movie.php154
-rw-r--r--modules/gallery/helpers/photo.php72
-rw-r--r--modules/gallery/helpers/random.php2
-rw-r--r--modules/gallery/helpers/site_status.php2
-rw-r--r--modules/gallery/helpers/system.php38
-rw-r--r--modules/gallery/helpers/task.php2
-rw-r--r--modules/gallery/helpers/theme.php2
-rw-r--r--modules/gallery/helpers/tree_rest.php2
-rw-r--r--modules/gallery/helpers/upgrade_checker.php4
-rw-r--r--modules/gallery/helpers/user_profile.php2
-rw-r--r--modules/gallery/helpers/xml.php2
48 files changed, 993 insertions, 376 deletions
diff --git a/modules/gallery/helpers/MY_html.php b/modules/gallery/helpers/MY_html.php
index edb16ec9..767fe3f7 100644
--- a/modules/gallery/helpers/MY_html.php
+++ b/modules/gallery/helpers/MY_html.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/MY_num.php b/modules/gallery/helpers/MY_num.php
index 88810bda..a550a1a0 100644
--- a/modules/gallery/helpers/MY_num.php
+++ b/modules/gallery/helpers/MY_num.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/MY_remote.php b/modules/gallery/helpers/MY_remote.php
index 5bed2437..59804b95 100644
--- a/modules/gallery/helpers/MY_remote.php
+++ b/modules/gallery/helpers/MY_remote.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/MY_url.php b/modules/gallery/helpers/MY_url.php
index aa42ca49..eba08b2b 100644
--- a/modules/gallery/helpers/MY_url.php
+++ b/modules/gallery/helpers/MY_url.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/MY_valid.php b/modules/gallery/helpers/MY_valid.php
index ee17267a..f1dd9c34 100644
--- a/modules/gallery/helpers/MY_valid.php
+++ b/modules/gallery/helpers/MY_valid.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php
index fbde36c2..a7dca57d 100644
--- a/modules/gallery/helpers/access.php
+++ b/modules/gallery/helpers/access.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/ajax.php b/modules/gallery/helpers/ajax.php
index 6d59b6e4..0c69fe7f 100644
--- a/modules/gallery/helpers/ajax.php
+++ b/modules/gallery/helpers/ajax.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php
index 0945e4d9..23aed8ac 100644
--- a/modules/gallery/helpers/album.php
+++ b/modules/gallery/helpers/album.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/auth.php b/modules/gallery/helpers/auth.php
index c86eaa5e..2eb3c252 100644
--- a/modules/gallery/helpers/auth.php
+++ b/modules/gallery/helpers/auth.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/batch.php b/modules/gallery/helpers/batch.php
index 991cad43..bf2425e7 100644
--- a/modules/gallery/helpers/batch.php
+++ b/modules/gallery/helpers/batch.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/block_manager.php b/modules/gallery/helpers/block_manager.php
index f59e6d58..bd6ca1c8 100644
--- a/modules/gallery/helpers/block_manager.php
+++ b/modules/gallery/helpers/block_manager.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/data_rest.php b/modules/gallery/helpers/data_rest.php
index 343975f6..d4f456d7 100644
--- a/modules/gallery/helpers/data_rest.php
+++ b/modules/gallery/helpers/data_rest.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -32,51 +32,51 @@ class data_rest_Core {
throw new Rest_Exception("Bad Request", 400, array("errors" => array("size" => "invalid")));
}
- switch ($p->size) {
- case "thumb":
- $file = $item->thumb_path();
- break;
-
- case "resize":
- $file = $item->resize_path();
- break;
+ // Note: this code is roughly duplicated in file_proxy, so if you modify this, please look to
+ // see if you should make the same change there as well.
- case "full":
+ if ($p->size == "full") {
$file = $item->file_path();
- break;
+ } else if ($p->size == "resize") {
+ $file = $item->resize_path();
+ } else {
+ $file = $item->thumb_path();
}
if (!file_exists($file)) {
throw new Kohana_404_Exception();
}
- // Note: this code is roughly duplicated in data_rest, so if you modify this, please look to
- // see if you should make the same change there as well.
- //
- // We don't have a cache buster in the url, so don't set cache headers here.
- // We don't need to save the session for this request
- Session::instance()->abort_save();
+ header("Content-Length: " . filesize($file));
- if ($item->is_album() && !$item->album_cover_item_id) {
- // No thumbnail. Return nothing.
- // @todo: what should we do here?
- return;
+ if (isset($p->m)) {
+ header("Pragma:");
+ // Check that the content hasn't expired or it wasn't changed since cached
+ expires::check(2592000, $item->updated);
+
+ expires::set(2592000, $item->updated); // 30 days
}
- // Dump out the image. If the item is a movie, then its thumbnail will be a JPG.
- if ($item->is_movie() && $p->size == "thumb") {
+ // We don't need to save the session for this request
+ Session::instance()->abort_save();
+
+ // Dump out the image. If the item is a movie or album, then its thumbnail will be a JPG.
+ if (($item->is_movie() || $item->is_album()) && $p->size == "thumb") {
header("Content-Type: image/jpeg");
- } else if ($item->is_album()) {
- header("Content-Type: " . $item->album_cover()->mime_type);
} else {
- header("Content-Type: {$item->mime_type}");
+ header("Content-Type: $item->mime_type");
}
- Kohana::close_buffers(false);
- if (isset($p->encoding) && $p->encoding == "base64") {
- print base64_encode(file_get_contents($file));
+ if (TEST_MODE) {
+ return $file;
} else {
- readfile($file);
+ Kohana::close_buffers(false);
+
+ if (isset($p->encoding) && $p->encoding == "base64") {
+ print base64_encode(file_get_contents($file));
+ } else {
+ readfile($file);
+ }
}
// We must exit here to keep the regular REST framework reply code from adding more bytes on
@@ -93,6 +93,18 @@ class data_rest_Core {
}
static function url($item, $size) {
- return url::abs_site("rest/data/{$item->id}?size=$size");
+ if ($size == "full") {
+ $file = $item->file_path();
+ } else if ($size == "resize") {
+ $file = $item->resize_path();
+ } else {
+ $file = $item->thumb_path();
+ }
+ if (!file_exists($file)) {
+ throw new Kohana_404_Exception();
+ }
+
+ return url::abs_site("rest/data/{$item->id}?size=$size&m=" . filemtime($file));
}
}
+
diff --git a/modules/gallery/helpers/dir.php b/modules/gallery/helpers/dir.php
index 44a142be..807f7bd3 100644
--- a/modules/gallery/helpers/dir.php
+++ b/modules/gallery/helpers/dir.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/encoding.php b/modules/gallery/helpers/encoding.php
index ce30aa1c..073aef9a 100644
--- a/modules/gallery/helpers/encoding.php
+++ b/modules/gallery/helpers/encoding.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php
index 8b118a80..f1f7190c 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -214,4 +214,20 @@ class gallery_Core {
}
return null;
}
+
+ /**
+ * Return true if we should show the profiler at the bottom of the page. Note that this
+ * function is called at database setup time so it cannot rely on the database.
+ */
+ static function show_profiler() {
+ return file_exists(VARPATH . "PROFILE");
+ }
+
+ /**
+ * Return true if we should allow Javascript and CSS combining for performance reasons.
+ * Typically we want this, but it's convenient for developers to be able to disable it.
+ */
+ static function allow_css_and_js_combining() {
+ return !file_exists(VARPATH . "DONT_COMBINE");
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/gallery_block.php b/modules/gallery/helpers/gallery_block.php
index fe9173c0..5ac4d74d 100644
--- a/modules/gallery/helpers/gallery_block.php
+++ b/modules/gallery/helpers/gallery_block.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -78,7 +78,7 @@ class gallery_block_Core {
$block->css_id = "g-project-news";
$block->title = t("Gallery project news");
$block->content = new View("admin_block_news.html");
- $block->content->feed = feed::parse("http://gallery.menalto.com/node/feed", 3);
+ $block->content->feed = feed::parse("http://galleryproject.org/node/feed", 3);
break;
case "block_adder":
diff --git a/modules/gallery/helpers/gallery_error.php b/modules/gallery/helpers/gallery_error.php
index b2515f44..76c8ca99 100644
--- a/modules/gallery/helpers/gallery_error.php
+++ b/modules/gallery/helpers/gallery_error.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index 6225633f..aeb1c7eb 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -86,17 +86,17 @@ class gallery_event_Core {
static function item_created($item) {
access::add_item($item);
- if ($item->is_photo() || $item->is_movie()) {
- // Build our thumbnail/resizes.
- try {
- graphics::generate($item);
- } catch (Exception $e) {
- log::error("graphics", t("Couldn't create a thumbnail or resize for %item_title",
- array("item_title" => $item->title)),
- html::anchor($item->abs_url(), t("details")));
- Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString());
- }
+ // Build our thumbnail/resizes.
+ try {
+ graphics::generate($item);
+ } catch (Exception $e) {
+ log::error("graphics", t("Couldn't create a thumbnail or resize for %item_title",
+ array("item_title" => $item->title)),
+ html::anchor($item->abs_url(), t("details")));
+ Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString());
+ }
+ if ($item->is_photo() || $item->is_movie()) {
// If the parent has no cover item, make this it.
$parent = $item->parent();
if (access::can("edit", $parent) && $parent->album_cover_item_id == null) {
@@ -141,10 +141,9 @@ class gallery_event_Core {
foreach (ORM::factory("item")
->where("album_cover_item_id", "=", $item->id)
->find_all() as $target) {
- copy($item->thumb_path(), $target->thumb_path());
- $target->thumb_width = $item->thumb_width;
- $target->thumb_height = $item->thumb_height;
+ $target->thumb_dirty = 1;
$target->save();
+ graphics::generate($target);
}
}
@@ -347,9 +346,9 @@ class gallery_event_Core {
if (($item->type == "album" && empty($item->album_cover_item_id)) ||
($item->type == "album" && $parent->album_cover_item_id == $item->album_cover_item_id) ||
$parent->album_cover_item_id == $item->id) {
- $disabledState = " ui-state-disabled";
+ $disabledState = "ui-state-disabled";
} else {
- $disabledState = " ";
+ $disabledState = "";
}
if ($item->parent()->id != 1) {
@@ -358,7 +357,7 @@ class gallery_event_Core {
Menu::factory("ajax_link")
->id("make_album_cover")
->label(t("Choose as the album cover"))
- ->css_class("ui-icon-star")
+ ->css_class("ui-icon-star $disabledState")
->ajax_handler("function(data) { window.location.reload() }")
->url(url::site("quick/make_album_cover/$item->id?csrf=$csrf")));
}
@@ -501,16 +500,16 @@ class gallery_event_Core {
if (($item->type == "album" && empty($item->album_cover_item_id)) ||
($item->type == "album" && $parent->album_cover_item_id == $item->album_cover_item_id) ||
$parent->album_cover_item_id == $item->id) {
- $disabledState = " ui-state-disabled";
+ $disabledState = "ui-state-disabled";
} else {
- $disabledState = " ";
+ $disabledState = "";
}
if ($item->parent()->id != 1) {
$options_menu
->append(Menu::factory("ajax_link")
->id("make_album_cover")
->label($cover_title)
- ->css_class("ui-icon-star")
+ ->css_class("ui-icon-star $disabledState")
->ajax_handler("function(data) { window.location.reload() }")
->url(url::site("quick/make_album_cover/$item->id?csrf=$csrf")));
}
@@ -519,7 +518,8 @@ class gallery_event_Core {
->id("delete")
->label($delete_title)
->css_class("ui-icon-trash")
- ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&amp;from_id={$theme_item->id}&amp;page_type=$page_type")));
+ ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&amp;" .
+ "from_id={$theme_item->id}&amp;page_type=$page_type")));
}
if ($item->is_album()) {
diff --git a/modules/gallery/helpers/gallery_graphics.php b/modules/gallery/helpers/gallery_graphics.php
index d2b92c87..eb76353f 100644
--- a/modules/gallery/helpers/gallery_graphics.php
+++ b/modules/gallery/helpers/gallery_graphics.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -29,12 +29,28 @@ class gallery_graphics_Core {
static function rotate($input_file, $output_file, $options, $item=null) {
graphics::init_toolkit();
- module::event("graphics_rotate", $input_file, $output_file, $options, $item);
+ $temp_file = system::temp_filename("rotate_", pathinfo($output_file, PATHINFO_EXTENSION));
+ module::event("graphics_rotate", $input_file, $temp_file, $options, $item);
- Image::factory($input_file)
- ->quality(module::get_var("gallery", "image_quality"))
- ->rotate($options["degrees"])
- ->save($output_file);
+ if (@filesize($temp_file) > 0) {
+ // A graphics_rotate event made an image - move it to output_file and use it.
+ @rename($temp_file, $output_file);
+ } else {
+ // No events made an image - proceed with standard process.
+ if (@filesize($input_file) == 0) {
+ throw new Exception("@todo EMPTY_INPUT_FILE");
+ }
+
+ if (!isset($options["degrees"])) {
+ $options["degrees"] = 0;
+ }
+
+ // Rotate the image. This also implicitly converts its format if needed.
+ Image::factory($input_file)
+ ->quality(module::get_var("gallery", "image_quality"))
+ ->rotate($options["degrees"])
+ ->save($output_file);
+ }
module::event("graphics_rotate_completed", $input_file, $output_file, $options, $item);
}
@@ -51,24 +67,46 @@ class gallery_graphics_Core {
static function resize($input_file, $output_file, $options, $item=null) {
graphics::init_toolkit();
- module::event("graphics_resize", $input_file, $output_file, $options, $item);
-
- if (@filesize($input_file) == 0) {
- throw new Exception("@todo EMPTY_INPUT_FILE");
- }
+ $temp_file = system::temp_filename("resize_", pathinfo($output_file, PATHINFO_EXTENSION));
+ module::event("graphics_resize", $input_file, $temp_file, $options, $item);
- $dims = getimagesize($input_file);
- if (max($dims[0], $dims[1]) <= min($options["width"], $options["height"])) {
- // Image would get upscaled; do nothing
- copy($input_file, $output_file);
+ if (@filesize($temp_file) > 0) {
+ // A graphics_resize event made an image - move it to output_file and use it.
+ @rename($temp_file, $output_file);
} else {
- $image = Image::factory($input_file)
- ->resize($options["width"], $options["height"], $options["master"])
- ->quality(module::get_var("gallery", "image_quality"));
- if (graphics::can("sharpen")) {
- $image->sharpen(module::get_var("gallery", "image_sharpen"));
+ // No events made an image - proceed with standard process.
+ if (@filesize($input_file) == 0) {
+ throw new Exception("@todo EMPTY_INPUT_FILE");
+ }
+
+ list ($input_width, $input_height, $input_mime, $input_extension) =
+ photo::get_file_metadata($input_file);
+ if ($input_width && $input_height &&
+ (empty($options["width"]) || empty($options["height"]) || empty($options["master"]) ||
+ (max($input_width, $input_height) <= min($options["width"], $options["height"])))) {
+ // Photo dimensions well-defined, but options not well-defined or would upscale the image.
+ // Do not resize. Check mimes to see if we can copy the file or if we need to convert it.
+ // (checking mimes avoids needlessly converting jpg to jpeg, etc.)
+ $output_mime = legal_file::get_photo_types_by_extension(pathinfo($output_file, PATHINFO_EXTENSION));
+ if ($input_mime && $output_mime && ($input_mime == $output_mime)) {
+ // Mimes well-defined and identical - copy input to output
+ copy($input_file, $output_file);
+ } else {
+ // Mimes not well-defined or not the same - convert input to output
+ $image = Image::factory($input_file)
+ ->quality(module::get_var("gallery", "image_quality"))
+ ->save($output_file);
+ }
+ } else {
+ // Resize the image. This also implicitly converts its format if needed.
+ $image = Image::factory($input_file)
+ ->resize($options["width"], $options["height"], $options["master"])
+ ->quality(module::get_var("gallery", "image_quality"));
+ if (graphics::can("sharpen")) {
+ $image->sharpen(module::get_var("gallery", "image_sharpen"));
+ }
+ $image->save($output_file);
}
- $image->save($output_file);
}
module::event("graphics_resize_completed", $input_file, $output_file, $options, $item);
@@ -94,38 +132,51 @@ class gallery_graphics_Core {
try {
graphics::init_toolkit();
- module::event("graphics_composite", $input_file, $output_file, $options, $item);
-
- list ($width, $height) = getimagesize($input_file);
- list ($w_width, $w_height) = getimagesize($options["file"]);
-
- $pad = isset($options["padding"]) ? $options["padding"] : 10;
- $top = $pad;
- $left = $pad;
- $y_center = max($height / 2 - $w_height / 2, $pad);
- $x_center = max($width / 2 - $w_width / 2, $pad);
- $bottom = max($height - $w_height - $pad, $pad);
- $right = max($width - $w_width - $pad, $pad);
-
- switch ($options["position"]) {
- case "northwest": $x = $left; $y = $top; break;
- case "north": $x = $x_center; $y = $top; break;
- case "northeast": $x = $right; $y = $top; break;
- case "west": $x = $left; $y = $y_center; break;
- case "center": $x = $x_center; $y = $y_center; break;
- case "east": $x = $right; $y = $y_center; break;
- case "southwest": $x = $left; $y = $bottom; break;
- case "south": $x = $x_center; $y = $bottom; break;
- case "southeast": $x = $right; $y = $bottom; break;
- }
+ $temp_file = system::temp_filename("composite_", pathinfo($output_file, PATHINFO_EXTENSION));
+ module::event("graphics_composite", $input_file, $temp_file, $options, $item);
- Image::factory($input_file)
- ->composite($options["file"], $x, $y, $options["transparency"])
- ->quality(module::get_var("gallery", "image_quality"))
- ->save($output_file);
+ if (@filesize($temp_file) > 0) {
+ // A graphics_composite event made an image - move it to output_file and use it.
+ @rename($temp_file, $output_file);
+ } else {
+ // No events made an image - proceed with standard process.
+
+ list ($width, $height) = photo::get_file_metadata($input_file);
+ list ($w_width, $w_height) = photo::get_file_metadata($options["file"]);
+
+ $pad = isset($options["padding"]) ? $options["padding"] : 10;
+ $top = $pad;
+ $left = $pad;
+ $y_center = max($height / 2 - $w_height / 2, $pad);
+ $x_center = max($width / 2 - $w_width / 2, $pad);
+ $bottom = max($height - $w_height - $pad, $pad);
+ $right = max($width - $w_width - $pad, $pad);
+
+ switch ($options["position"]) {
+ case "northwest": $x = $left; $y = $top; break;
+ case "north": $x = $x_center; $y = $top; break;
+ case "northeast": $x = $right; $y = $top; break;
+ case "west": $x = $left; $y = $y_center; break;
+ case "center": $x = $x_center; $y = $y_center; break;
+ case "east": $x = $right; $y = $y_center; break;
+ case "southwest": $x = $left; $y = $bottom; break;
+ case "south": $x = $x_center; $y = $bottom; break;
+ case "southeast": $x = $right; $y = $bottom; break;
+ }
+
+ Image::factory($input_file)
+ ->composite($options["file"], $x, $y, $options["transparency"])
+ ->quality(module::get_var("gallery", "image_quality"))
+ ->save($output_file);
+ }
module::event("graphics_composite_completed", $input_file, $output_file, $options, $item);
} catch (ErrorException $e) {
+ // Unlike rotate and resize, composite catches its exceptions here. This is because
+ // composite is typically called for watermarks. If during thumb/resize generation
+ // the watermark fails, we'd still like the image resized, just without its watermark.
+ // If the exception isn't caught here, graphics::generate will replace it with a
+ // placeholder.
Kohana_Log::add("error", $e->getMessage());
}
}
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index 597771f3..051a66cf 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -116,7 +116,8 @@ class gallery_installer {
KEY `type` (`type`),
KEY `random` (`rand_key`),
KEY `weight` (`weight` DESC),
- KEY `left_ptr` (`left_ptr`))
+ KEY `left_ptr` (`left_ptr`),
+ KEY `relative_path_cache` (`relative_path_cache`))
DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {logs} (
@@ -314,8 +315,7 @@ class gallery_installer {
module::set_var("gallery", "timezone", null);
module::set_var("gallery", "lock_timeout", 1);
module::set_var("gallery", "movie_extract_frame_time", 3);
-
- module::set_version("gallery", 53);
+ module::set_var("gallery", "movie_allow_uploads", "autodetect");
}
static function upgrade($version) {
@@ -718,14 +718,14 @@ class gallery_installer {
if ($version == 50) {
// In v51, we added a lock_timeout variable so that administrators could edit the time out
- // from 1 second to a higher variable if their system runs concurrent parallel uploads for
+ // from 1 second to a higher variable if their system runs concurrent parallel uploads for
// instance.
module::set_var("gallery", "lock_timeout", 1);
module::set_version("gallery", $version = 51);
}
if ($version == 51) {
- // In v52, we added functions to the legal_file helper that map photo and movie file
+ // In v52, we added functions to the legal_file helper that map photo and movie file
// extensions to their mime types (and allow extension of the list by other modules). During
// this process, we correctly mapped m4v files to video/x-m4v, correcting a previous error
// where they were mapped to video/mp4. This corrects the existing items.
@@ -736,13 +736,67 @@ class gallery_installer {
->execute();
module::set_version("gallery", $version = 52);
}
-
+
if ($version == 52) {
// In v53, we added the ability to change the default time used when extracting frames from
// movies. Previously we hard-coded this at 3 seconds, so we use that as the default.
module::set_var("gallery", "movie_extract_frame_time", 3);
module::set_version("gallery", $version = 53);
}
+
+ if ($version == 53) {
+ // In v54, we changed how we check for name and slug conflicts in Item_Model. Previously,
+ // we checked the whole filename. As a result, "foo.jpg" and "foo.png" were not considered
+ // conflicting if their slugs were different (a rare case in practice since server_add and
+ // uploader would give them both the same slug "foo"). Now, we check the filename without its
+ // extension. This upgrade stanza fixes any conflicts where they were previously allowed.
+
+ // This might be slow, but if it times out it can just pick up where it left off.
+
+ // Find and loop through each conflict (e.g. "foo.jpg", "foo.png", and "foo.flv" are one
+ // conflict; "bar.jpg", "bar.png", and "bar.flv" are another)
+ foreach (db::build()
+ ->select_distinct(array("parent_base_name" =>
+ db::expr("CONCAT(`parent_id`, ':', LOWER(SUBSTR(`name`, 1, LOCATE('.', `name`) - 1)))")))
+ ->select(array("C" => "COUNT(\"*\")"))
+ ->from("items")
+ ->where("type", "<>", "album")
+ ->having("C", ">", 1)
+ ->group_by("parent_base_name")
+ ->execute() as $conflict) {
+ list ($parent_id, $base_name) = explode(":", $conflict->parent_base_name, 2);
+ $base_name_escaped = Database::escape_for_like($base_name);
+ // Loop through the items for each conflict
+ foreach (db::build()
+ ->from("items")
+ ->select("id")
+ ->where("type", "<>", "album")
+ ->where("parent_id", "=", $parent_id)
+ ->where("name", "LIKE", "{$base_name_escaped}.%")
+ ->limit(1000000) // required to satisfy SQL syntax (no offset without limit)
+ ->offset(1) // skips the 0th item
+ ->execute() as $row) {
+ set_time_limit(30);
+ $item = ORM::factory("item", $row->id);
+ $item->name = $item->name; // this will force Item_Model to check for conflicts on save
+ $item->save();
+ }
+ }
+ module::set_version("gallery", $version = 54);
+ }
+
+ if ($version == 54) {
+ $db->query("ALTER TABLE {items} ADD KEY `relative_path_cache` (`relative_path_cache`)");
+ module::set_version("gallery", $version = 55);
+ }
+
+ if ($version == 55) {
+ // In v56, we added the ability to change the default behavior regarding movie uploads. It
+ // can be set to "always", "never", or "autodetect" to match the previous behavior where they
+ // are allowed only if FFmpeg is found.
+ module::set_var("gallery", "movie_allow_uploads", "autodetect");
+ module::set_version("gallery", $version = 56);
+ }
}
static function uninstall() {
diff --git a/modules/gallery/helpers/gallery_rss.php b/modules/gallery/helpers/gallery_rss.php
index c952f4b6..d6b33022 100644
--- a/modules/gallery/helpers/gallery_rss.php
+++ b/modules/gallery/helpers/gallery_rss.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php
index 65a72884..856d2639 100644
--- a/modules/gallery/helpers/gallery_task.php
+++ b/modules/gallery/helpers/gallery_task.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -26,11 +26,13 @@ class gallery_task_Core {
const FIX_STATE_RUN_DUPE_SLUGS = 5;
const FIX_STATE_START_DUPE_NAMES = 6;
const FIX_STATE_RUN_DUPE_NAMES = 7;
- const FIX_STATE_START_REBUILD_ITEM_CACHES = 8;
- const FIX_STATE_RUN_REBUILD_ITEM_CACHES = 9;
- const FIX_STATE_START_MISSING_ACCESS_CACHES = 10;
- const FIX_STATE_RUN_MISSING_ACCESS_CACHES = 11;
- const FIX_STATE_DONE = 12;
+ const FIX_STATE_START_DUPE_BASE_NAMES = 8;
+ const FIX_STATE_RUN_DUPE_BASE_NAMES = 9;
+ const FIX_STATE_START_REBUILD_ITEM_CACHES = 10;
+ const FIX_STATE_RUN_REBUILD_ITEM_CACHES = 11;
+ const FIX_STATE_START_MISSING_ACCESS_CACHES = 12;
+ const FIX_STATE_RUN_MISSING_ACCESS_CACHES = 13;
+ const FIX_STATE_DONE = 14;
static function available_tasks() {
$dirty_count = graphics::find_dirty_images_query()->count_records();
@@ -348,8 +350,9 @@ class gallery_task_Core {
// album audit (permissions and bogus album covers): 1 operation for every album
$total += db::build()->where("type", "=", "album")->count_records("items");
- // one operation for each missing slug, name and access cache
- foreach (array("find_dupe_slugs", "find_dupe_names", "find_missing_access_caches") as $func) {
+ // one operation for each dupe slug, dupe name, dupe base name, and missing access cache
+ foreach (array("find_dupe_slugs", "find_dupe_names", "find_dupe_base_names",
+ "find_missing_access_caches") as $func) {
foreach (self::$func() as $row) {
$total++;
}
@@ -489,11 +492,12 @@ class gallery_task_Core {
$task->set("stack", implode(" ", $stack));
$state = self::FIX_STATE_RUN_DUPE_NAMES;
} else {
- $state = self::FIX_STATE_START_ALBUMS;
+ $state = self::FIX_STATE_START_DUPE_BASE_NAMES;
}
break;
case self::FIX_STATE_RUN_DUPE_NAMES:
+ // NOTE: This does *not* attempt to fix the file system!
$stack = explode(" ", $task->get("stack"));
list ($parent_id, $name) = explode(":", array_pop($stack));
@@ -505,9 +509,16 @@ class gallery_task_Core {
->find_all(1, 1);
if ($conflicts->count() && $conflict = $conflicts->current()) {
$task->log("Fixing conflicting name for item id {$conflict->id}");
+ if (!$conflict->is_album() && preg_match("/^(.*)(\.[^\.\/]*?)$/", $conflict->name, $matches)) {
+ $item_base_name = $matches[1];
+ $item_extension = $matches[2]; // includes a leading dot
+ } else {
+ $item_base_name = $conflict->name;
+ $item_extension = "";
+ }
db::build()
->update("items")
- ->set("name", $name . "-" . (string)rand(1000, 9999))
+ ->set("name", $item_base_name . "-" . (string)rand(1000, 9999) . $item_extension)
->where("id", "=", $conflict->id)
->execute();
@@ -522,6 +533,74 @@ class gallery_task_Core {
$completed++;
if (empty($stack)) {
+ $state = self::FIX_STATE_START_DUPE_BASE_NAMES;
+ }
+ break;
+
+ case self::FIX_STATE_START_DUPE_BASE_NAMES:
+ $stack = array();
+ foreach (self::find_dupe_base_names() as $row) {
+ list ($parent_id, $base_name) = explode(":", $row->parent_base_name, 2);
+ $stack[] = join(":", array($parent_id, $base_name));
+ }
+ if ($stack) {
+ $task->set("stack", implode(" ", $stack));
+ $state = self::FIX_STATE_RUN_DUPE_BASE_NAMES;
+ } else {
+ $state = self::FIX_STATE_START_ALBUMS;
+ }
+ break;
+
+ case self::FIX_STATE_RUN_DUPE_BASE_NAMES:
+ // NOTE: This *does* attempt to fix the file system! So, it must go *after* run_dupe_names.
+ $stack = explode(" ", $task->get("stack"));
+ list ($parent_id, $base_name) = explode(":", array_pop($stack));
+ $base_name_escaped = Database::escape_for_like($base_name);
+
+ $fixed = 0;
+ // We want to leave the first one alone and update all conflicts to be random values.
+ $conflicts = ORM::factory("item")
+ ->where("parent_id", "=", $parent_id)
+ ->where("name", "LIKE", "{$base_name_escaped}.%")
+ ->where("type", "<>", "album")
+ ->find_all(1, 1);
+ if ($conflicts->count() && $conflict = $conflicts->current()) {
+ $task->log("Fixing conflicting name for item id {$conflict->id}");
+ if (preg_match("/^(.*)(\.[^\.\/]*?)$/", $conflict->name, $matches)) {
+ $item_base_name = $matches[1]; // unlike $base_name, this always maintains capitalization
+ $item_extension = $matches[2]; // includes a leading dot
+ } else {
+ $item_base_name = $conflict->name;
+ $item_extension = "";
+ }
+ // Unlike conflicts found in run_dupe_names, these items are likely to have an intact
+ // file system. Let's use the item save logic to rebuild the paths and rename the files
+ // if possible.
+ try {
+ $conflict->name = $item_base_name . "-" . (string)rand(1000, 9999) . $item_extension;
+ $conflict->validate();
+ // If we get here, we're safe to proceed with save
+ $conflict->save();
+ } catch (Exception $e) {
+ // Didn't work. Edit database directly without fixing file system.
+ db::build()
+ ->update("items")
+ ->set("name", $item_base_name . "-" . (string)rand(1000, 9999) . $item_extension)
+ ->where("id", "=", $conflict->id)
+ ->execute();
+ }
+
+ // We fixed one conflict, but there might be more so put this parent back on the stack
+ // and try again. We won't consider it completed when we don't fix a conflict. This
+ // guarantees that we won't spend too long fixing one set of conflicts, and that we
+ // won't stop before all are fixed.
+ $stack[] = "$parent_id:$base_name";
+ break;
+ }
+ $task->set("stack", implode(" ", $stack));
+ $completed++;
+
+ if (empty($stack)) {
$state = self::FIX_STATE_START_ALBUMS;
}
break;
@@ -612,7 +691,7 @@ class gallery_task_Core {
break;
case self::FIX_STATE_RUN_MISSING_ACCESS_CACHES:
- $stack = explode(" ", $task->get("stack"));
+ $stack = array_filter(explode(" ", $task->get("stack"))); // filter removes empty/zero ids
if (!empty($stack)) {
$id = array_pop($stack);
$access_cache = ORM::factory("access_cache");
@@ -669,18 +748,32 @@ class gallery_task_Core {
}
static function find_dupe_names() {
+ // looking for photos, movies, and albums
return db::build()
->select_distinct(
array("parent_name" => db::expr("CONCAT(`parent_id`, ':', LOWER(`name`))")))
->select("id")
->select(array("C" => "COUNT(\"*\")"))
->from("items")
- ->where("type", "<>", "album")
->having("C", ">", 1)
->group_by("parent_name")
->execute();
}
+ static function find_dupe_base_names() {
+ // looking for photos or movies, not albums
+ return db::build()
+ ->select_distinct(
+ array("parent_base_name" => db::expr("CONCAT(`parent_id`, ':', LOWER(SUBSTR(`name`, 1, LOCATE('.', `name`) - 1)))")))
+ ->select("id")
+ ->select(array("C" => "COUNT(\"*\")"))
+ ->from("items")
+ ->where("type", "<>", "album")
+ ->having("C", ">", 1)
+ ->group_by("parent_base_name")
+ ->execute();
+ }
+
static function find_empty_item_caches($limit) {
return db::build()
->select("items.id")
diff --git a/modules/gallery/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php
index 2263d8d7..3c6d71e9 100644
--- a/modules/gallery/helpers/gallery_theme.php
+++ b/modules/gallery/helpers/gallery_theme.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -71,7 +71,7 @@ class gallery_theme_Core {
static function page_bottom($theme) {
$session = Session::instance();
- if ($session->get("profiler", false)) {
+ if (gallery::show_profiler()) {
Profiler::enable();
$profiler = new Profiler();
$profiler->render();
@@ -96,7 +96,7 @@ class gallery_theme_Core {
static function admin_page_bottom($theme) {
$session = Session::instance();
- if ($session->get("profiler", false)) {
+ if (gallery::show_profiler()) {
Profiler::enable();
$profiler = new Profiler();
$profiler->render();
@@ -134,7 +134,7 @@ class gallery_theme_Core {
'<bdo dir="ltr">Gallery ' . gallery::version_string() . '</bdo>');
return "<li class=\"g-first\">" .
t(module::get_var("gallery", "credits"),
- array("url" => "http://gallery.menalto.com",
+ array("url" => "http://galleryproject.org",
"gallery_version" => $version_string)) .
"</li>";
}
diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php
index e7c5da68..e66908c4 100644
--- a/modules/gallery/helpers/graphics.php
+++ b/modules/gallery/helpers/graphics.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -115,36 +115,12 @@ class graphics_Core {
* @param Item_Model $item
*/
static function generate($item) {
- if ($item->is_album()) {
- if (!$cover = $item->album_cover()) {
- // This album has no cover; there's nothing to generate. Because of an old bug, it's
- // possible that there's an album cover item id that points to an invalid item. In that
- // case, just null out the album cover item id. It's not optimal to do that at this low
- // level, but it's not trivial to find these cases quickly in an upgrade script and if we
- // don't do this, the album may be permanently marked as "needs rebuilding"
- //
- // ref: http://sourceforge.net/apps/trac/gallery/ticket/1172
- // http://gallery.menalto.com/node/96926
- if ($item->album_cover_item_id) {
- $item->album_cover_item_id = null;
- $item->save();
- }
- return;
- }
- $input_file = $cover->file_path();
- $input_item = $cover;
- } else {
- $input_file = $item->file_path();
- $input_item = $item;
- }
-
if ($item->thumb_dirty) {
$ops["thumb"] = $item->thumb_path();
}
- if ($item->resize_dirty && !$item->is_album() && !$item->is_movie()) {
+ if ($item->resize_dirty && $item->is_photo()) {
$ops["resize"] = $item->resize_path();
}
-
if (empty($ops)) {
$item->thumb_dirty = 0;
$item->resize_dirty = 0;
@@ -154,10 +130,11 @@ class graphics_Core {
try {
foreach ($ops as $target => $output_file) {
- if ($input_item->is_movie()) {
- // Convert the movie filename to a JPG first, delete anything that might already be there
- $output_file = legal_file::change_extension($output_file, "jpg");
- unlink($output_file);
+ $working_file = $item->file_path();
+ // Delete anything that might already be there
+ @unlink($output_file);
+ switch ($item->type) {
+ case "movie":
// Run movie_extract_frame events, which can either:
// - generate an output file, bypassing the ffmpeg-based movie::extract_frame
// - add to the options sent to movie::extract_frame (e.g. change frame extract time,
@@ -165,27 +142,70 @@ class graphics_Core {
// Note that the args are similar to those of the events in gallery_graphics
$movie_options_wrapper = new stdClass();
$movie_options_wrapper->movie_options = array();
- module::event("movie_extract_frame", $input_file, $output_file,
- $movie_options_wrapper, $input_item);
+ module::event("movie_extract_frame", $working_file, $output_file,
+ $movie_options_wrapper, $item);
// If no output_file generated by events, run movie::extract_frame with movie_options
clearstatcache();
if (@filesize($output_file) == 0) {
try {
- movie::extract_frame($input_file, $output_file, $movie_options_wrapper->movie_options);
+ movie::extract_frame($working_file, $output_file, $movie_options_wrapper->movie_options);
+ // If we're here, we know ffmpeg is installed and the movie is valid. Because the
+ // user may not always have had ffmpeg installed, the movie's width, height, and
+ // mime type may need updating. Let's use this opportunity to make sure they're
+ // correct. It's not optimal to do it at this low level, but it's not trivial to find
+ // these cases quickly in an upgrade script.
+ list ($width, $height, $mime_type) = movie::get_file_metadata($working_file);
+ // Only set them if they need updating to avoid marking them as "changed"
+ if (($item->width != $width) || ($item->height != $height) ||
+ ($item->mime_type != $mime_type)) {
+ $item->width = $width;
+ $item->height = $height;
+ $item->mime_type = $mime_type;
+ }
} catch (Exception $e) {
- // Didn't work, likely because of MISSING_FFMPEG - copy missing_movie instead
- copy(MODPATH . "gallery/images/missing_movie.jpg", $output_file);
+ // Didn't work, likely because of MISSING_FFMPEG - use placeholder
+ graphics::_replace_image_with_placeholder($item, $target);
+ break;
}
}
$working_file = $output_file;
- } else {
- $working_file = $input_file;
- }
- foreach (self::_get_rules($target) as $rule) {
- $args = array($working_file, $output_file, unserialize($rule->args), $item);
- call_user_func_array($rule->operation, $args);
- $working_file = $output_file;
+ case "photo":
+ // Run the graphics rules (for both movies and photos)
+ foreach (self::_get_rules($target) as $rule) {
+ $args = array($working_file, $output_file, unserialize($rule->args), $item);
+ call_user_func_array($rule->operation, $args);
+ $working_file = $output_file;
+ }
+ break;
+
+ case "album":
+ if (!$cover = $item->album_cover()) {
+ // This album has no cover; copy its placeholder image. Because of an old bug, it's
+ // possible that there's an album cover item id that points to an invalid item. In that
+ // case, just null out the album cover item id. It's not optimal to do that at this low
+ // level, but it's not trivial to find these cases quickly in an upgrade script and if we
+ // don't do this, the album may be permanently marked as "needs rebuilding"
+ //
+ // ref: http://sourceforge.net/apps/trac/gallery/ticket/1172
+ // http://galleryproject.org/node/96926
+ if ($item->album_cover_item_id) {
+ $item->album_cover_item_id = null;
+ $item->save();
+ }
+ graphics::_replace_image_with_placeholder($item, $target);
+ break;
+ }
+ if ($cover->thumb_dirty) {
+ graphics::generate($cover);
+ }
+ if (!$cover->thumb_dirty) {
+ // Make the album cover from the cover item's thumb. Run gallery_graphics::resize with
+ // null options and it will figure out if this is a direct copy or conversion to jpg.
+ $working_file = $cover->thumb_path();
+ gallery_graphics::resize($working_file, $output_file, null, $item);
+ }
+ break;
}
}
@@ -193,33 +213,93 @@ class graphics_Core {
if (file_exists($item->thumb_path())) {
$item->thumb_dirty = 0;
} else {
- copy(MODPATH . "gallery/images/missing_photo.png", $item->thumb_path());
+ Kohana_Log::add("error", "Failed to rebuild thumb image: $item->title");
+ graphics::_replace_image_with_placeholder($item, "thumb");
}
- $dims = getimagesize($item->thumb_path());
- $item->thumb_width = $dims[0];
- $item->thumb_height = $dims[1];
}
if (!empty($ops["resize"])) {
if (file_exists($item->resize_path())) {
$item->resize_dirty = 0;
} else {
- copy(MODPATH . "gallery/images/missing_photo.png", $item->resize_path());
+ Kohana_Log::add("error", "Failed to rebuild resize image: $item->title");
+ graphics::_replace_image_with_placeholder($item, "resize");
}
- $dims = getimagesize($item->resize_path());
- $item->resize_width = $dims[0];
- $item->resize_height = $dims[1];
}
+ graphics::_update_item_dimensions($item);
$item->save();
} catch (Exception $e) {
- // Something went wrong rebuilding the image. Leave it dirty and move on.
- // @todo we should handle this better.
- Kohana_Log::add("error", "Caught exception rebuilding image: {$item->title}\n" .
+ // Something went wrong rebuilding the image. Replace with the placeholder images,
+ // leave it dirty and move on.
+ Kohana_Log::add("error", "Caught exception rebuilding images: {$item->title}\n" .
$e->getMessage() . "\n" . $e->getTraceAsString());
+ if ($item->is_photo()) {
+ graphics::_replace_image_with_placeholder($item, "resize");
+ }
+ graphics::_replace_image_with_placeholder($item, "thumb");
+ try {
+ graphics::_update_item_dimensions($item);
+ } catch (Exception $e) {
+ // Looks like get_file_metadata couldn't identify our placeholders. We should never get
+ // here, but in the odd case we do, we need to do something. Let's put in hardcoded values.
+ if ($item->is_photo()) {
+ list ($item->resize_width, $item->resize_height) = array(200, 200);
+ }
+ list ($item->thumb_width, $item->thumb_height) = array(200, 200);
+ }
+ $item->save();
throw $e;
}
}
+ private static function _update_item_dimensions($item) {
+ if ($item->is_photo()) {
+ list ($item->resize_width, $item->resize_height) =
+ photo::get_file_metadata($item->resize_path());
+ }
+ list ($item->thumb_width, $item->thumb_height) =
+ photo::get_file_metadata($item->thumb_path());
+ }
+
+ private static function _replace_image_with_placeholder($item, $target) {
+ if ($item->is_album() && !$item->album_cover_item_id) {
+ $input_path = MODPATH . "gallery/images/missing_album_cover.jpg";
+ } else if ($item->is_movie() || ($item->is_album() && $item->album_cover()->is_movie())) {
+ $input_path = MODPATH . "gallery/images/missing_movie.jpg";
+ } else {
+ $input_path = MODPATH . "gallery/images/missing_photo.jpg";
+ }
+
+ if ($target == "thumb") {
+ $output_path = $item->thumb_path();
+ $size = module::get_var("gallery", "thumb_size", 200);
+ } else {
+ $output_path = $item->resize_path();
+ $size = module::get_var("gallery", "resize_size", 640);
+ }
+ $options = array("width" => $size, "height" => $size, "master" => Image::AUTO);
+
+ try {
+ // Copy/convert/resize placeholder as needed.
+ gallery_graphics::resize($input_path, $output_path, $options, null);
+ } catch (Exception $e) {
+ // Copy/convert/resize didn't work. Add to the log and copy the jpg version (which could have
+ // a non-jpg extension). This is less than ideal, but it's better than putting nothing
+ // there and causing theme views to act strangely because a file is missing.
+ // @todo we should handle this better.
+ Kohana_Log::add("error", "Caught exception converting placeholder for missing image: " .
+ $item->title . "\n" . $e->getMessage() . "\n" . $e->getTraceAsString());
+ copy($input_path, $output_path);
+ }
+
+ if (!file_exists($output_path)) {
+ // Copy/convert/resize didn't throw an exception, but still didn't work - do the same as above.
+ // @todo we should handle this better.
+ Kohana_Log::add("error", "Failed to convert placeholder for missing image: $item->title");
+ copy($input_path, $output_path);
+ }
+ }
+
private static function _get_rules($target) {
if (empty(self::$_rules_cache[$target])) {
$rules = array();
@@ -256,12 +336,19 @@ class graphics_Core {
}
/**
- * Mark thumbnails and resizes as dirty. They will have to be rebuilt.
+ * Mark thumbnails and resizes as dirty. They will have to be rebuilt. Optionally, only those of
+ * a specified type and/or mime type can be marked (e.g. $type="movie" to rebuild movies only).
*/
- static function mark_dirty($thumbs, $resizes) {
+ static function mark_dirty($thumbs, $resizes, $type=null, $mime_type=null) {
if ($thumbs || $resizes) {
$db = db::build()
->update("items");
+ if ($type) {
+ $db->where("type", "=", $type);
+ }
+ if ($mime_type) {
+ $db->where("mime_type", "=", $mime_type);
+ }
if ($thumbs) {
$db->set("thumb_dirty", 1);
}
diff --git a/modules/gallery/helpers/identity.php b/modules/gallery/helpers/identity.php
index fcc9c6e8..5fc0f2f6 100644
--- a/modules/gallery/helpers/identity.php
+++ b/modules/gallery/helpers/identity.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php
index b739e8bd..9882a9c5 100644
--- a/modules/gallery/helpers/item.php
+++ b/modules/gallery/helpers/item.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -39,55 +39,28 @@ class item_Core {
}
}
- $source->parent_id = $target->id;
-
- // Moving may result in name or slug conflicts. If that happens, try up to 5 times to pick a
- // random name (or slug) to avoid the conflict.
$orig_name = $source->name;
- $orig_name_filename = pathinfo($source->name, PATHINFO_FILENAME);
- $orig_name_extension = pathinfo($source->name, PATHINFO_EXTENSION);
- $orig_slug = $source->slug;
- for ($i = 0; $i < 5; $i++) {
- try {
- $source->save();
- if ($orig_name != $source->name) {
- switch ($source->type) {
- case "album":
- message::info(
- t("Album <b>%old_name</b> renamed to <b>%new_name</b> to avoid a conflict",
- array("old_name" => $orig_name, "new_name" => $source->name)));
- break;
-
- case "photo":
- message::info(
- t("Photo <b>%old_name</b> renamed to <b>%new_name</b> to avoid a conflict",
- array("old_name" => $orig_name, "new_name" => $source->name)));
- break;
+ $source->parent_id = $target->id;
+ $source->save();
+ if ($orig_name != $source->name) {
+ switch ($source->type) {
+ case "album":
+ message::info(
+ t("Album <b>%old_name</b> renamed to <b>%new_name</b> to avoid a conflict",
+ array("old_name" => $orig_name, "new_name" => $source->name)));
+ break;
- case "movie":
- message::info(
- t("Movie <b>%old_name</b> renamed to <b>%new_name</b> to avoid a conflict",
- array("old_name" => $orig_name, "new_name" => $source->name)));
- break;
- }
- }
+ case "photo":
+ message::info(
+ t("Photo <b>%old_name</b> renamed to <b>%new_name</b> to avoid a conflict",
+ array("old_name" => $orig_name, "new_name" => $source->name)));
break;
- } catch (ORM_Validation_Exception $e) {
- $rand = rand(10, 99);
- $errors = $e->validation->errors();
- if (isset($errors["name"])) {
- $source->name = $orig_name_filename . "-{$rand}." . $orig_name_extension;
- unset($errors["name"]);
- }
- if (isset($errors["slug"])) {
- $source->slug = $orig_slug . "-{$rand}";
- unset($errors["slug"]);
- }
- if ($errors) {
- // There were other validation issues-- we don't know how to handle those
- throw $e;
- }
+ case "movie":
+ message::info(
+ t("Movie <b>%old_name</b> renamed to <b>%new_name</b> to avoid a conflict",
+ array("old_name" => $orig_name, "new_name" => $source->name)));
+ break;
}
}
@@ -103,34 +76,42 @@ class item_Core {
access::required("view", $parent);
access::required("edit", $parent);
+ $old_album_cover_id = $parent->album_cover_item_id;
+
model_cache::clear();
$parent->album_cover_item_id = $item->is_album() ? $item->album_cover_item_id : $item->id;
- if ($item->thumb_dirty) {
- $parent->thumb_dirty = 1;
- graphics::generate($parent);
- } else {
- copy($item->thumb_path(), $parent->thumb_path());
- $parent->thumb_width = $item->thumb_width;
- $parent->thumb_height = $item->thumb_height;
- }
$parent->save();
+ graphics::generate($parent);
+
+ // Walk up the parent hierarchy and set album covers if necessary
$grand_parent = $parent->parent();
if ($grand_parent && access::can("edit", $grand_parent) &&
$grand_parent->album_cover_item_id == null) {
item::make_album_cover($parent);
}
+
+ // When albums are album covers themselves, we hotlink directly to the target item. This
+ // means that when we change an album cover, the grandparent may have a deep link to the old
+ // album cover. So find any parent albums that had the old item as their album cover and
+ // switch them over to the new item.
+ if ($old_album_cover_id) {
+ foreach ($item->parents(array(array("album_cover_item_id", "=", $old_album_cover_id)))
+ as $ancestor) {
+ if (access::can("edit", $ancestor)) {
+ $ancestor->album_cover_item_id = $parent->album_cover_item_id;
+ $ancestor->save();
+ graphics::generate($ancestor);
+ }
+ }
+ }
}
static function remove_album_cover($album) {
access::required("view", $album);
access::required("edit", $album);
- @unlink($album->thumb_path());
model_cache::clear();
$album->album_cover_item_id = null;
- $album->thumb_width = 0;
- $album->thumb_height = 0;
- $album->thumb_dirty = 1;
$album->save();
graphics::generate($album);
}
@@ -437,4 +418,16 @@ class item_Core {
}
return call_user_func_array($callback, $args);
}
+
+ /**
+ * Reset all child weights of a given album to a monotonically increasing sequence based on the
+ * current sort order of the album.
+ */
+ static function resequence_child_weights($album) {
+ $weight = 0;
+ foreach ($album->children() as $child) {
+ $child->weight = ++$weight;
+ $child->save();
+ }
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php
index 43fec3ab..efeba2ef 100644
--- a/modules/gallery/helpers/item_rest.php
+++ b/modules/gallery/helpers/item_rest.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -64,7 +64,7 @@ class item_rest_Core {
}
if (isset($p->name)) {
- $orm->where("name", "LIKE", "%{$p->name}%");
+ $orm->where("name", "LIKE", "%" . Database::escape_for_like($p->name) . "%");
}
if (isset($p->type)) {
diff --git a/modules/gallery/helpers/items_rest.php b/modules/gallery/helpers/items_rest.php
index 71d7a59a..7622c534 100644
--- a/modules/gallery/helpers/items_rest.php
+++ b/modules/gallery/helpers/items_rest.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/json.php b/modules/gallery/helpers/json.php
index 0cd78581..b56f2690 100644
--- a/modules/gallery/helpers/json.php
+++ b/modules/gallery/helpers/json.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/l10n_client.php b/modules/gallery/helpers/l10n_client.php
index a8c36d29..2a1be2f9 100644
--- a/modules/gallery/helpers/l10n_client.php
+++ b/modules/gallery/helpers/l10n_client.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -21,7 +21,7 @@
class l10n_client_Core {
private static function _server_url($path) {
- return "http://gallery.menalto.com/translations/$path";
+ return "http://galleryproject.org/translations/$path";
}
static function server_api_key_url() {
diff --git a/modules/gallery/helpers/l10n_scanner.php b/modules/gallery/helpers/l10n_scanner.php
index 1f184da5..5980ebe0 100644
--- a/modules/gallery/helpers/l10n_scanner.php
+++ b/modules/gallery/helpers/l10n_scanner.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/legal_file.php b/modules/gallery/helpers/legal_file.php
index b3622764..eb9c25de 100644
--- a/modules/gallery/helpers/legal_file.php
+++ b/modules/gallery/helpers/legal_file.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -18,24 +18,44 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class legal_file_Core {
+ private static $photo_types_by_extension;
+ private static $movie_types_by_extension;
+ private static $photo_extensions;
+ private static $movie_extensions;
+ private static $photo_types;
+ private static $movie_types;
+ private static $blacklist = array("php", "php3", "php4", "php5", "phtml", "phtm", "shtml", "shtm",
+ "pl", "cgi", "asp", "sh", "py", "c", "js");
+
/**
- * Create a default list of allowed photo MIME types paired with their extensions and then let
+ * Create a default list of allowed photo MIME types paired with their extensions and then let
* modules modify it. This is an ordered map, mapping extensions to their MIME types.
* Extensions cannot be duplicated, but MIMEs can (e.g. jpeg and jpg both map to image/jpeg).
*
* @param string $extension (opt.) - return MIME of extension; if not given, return complete array
*/
- static function get_photo_types_by_extension($extension=NULL) {
- $types_by_extension_wrapper = new stdClass();
- $types_by_extension_wrapper->types_by_extension = array(
- "jpg" => "image/jpeg", "jpeg" => "image/jpeg", "gif" => "image/gif", "png" => "image/png");
- module::event("photo_types_by_extension", $types_by_extension_wrapper);
+ static function get_photo_types_by_extension($extension=null) {
+ if (empty(self::$photo_types_by_extension)) {
+ $types_by_extension_wrapper = new stdClass();
+ $types_by_extension_wrapper->types_by_extension = array(
+ "jpg" => "image/jpeg", "jpeg" => "image/jpeg", "gif" => "image/gif", "png" => "image/png");
+ module::event("photo_types_by_extension", $types_by_extension_wrapper);
+ foreach (self::$blacklist as $key) {
+ unset($types_by_extension_wrapper->types_by_extension[$key]);
+ }
+ self::$photo_types_by_extension = $types_by_extension_wrapper->types_by_extension;
+ }
if ($extension) {
// return matching MIME type
- return $types_by_extension_wrapper->types_by_extension[$extension];
+ $extension = strtolower($extension);
+ if (isset(self::$photo_types_by_extension[$extension])) {
+ return self::$photo_types_by_extension[$extension];
+ } else {
+ return null;
+ }
} else {
// return complete array
- return $types_by_extension_wrapper->types_by_extension;
+ return self::$photo_types_by_extension;
}
}
@@ -46,49 +66,115 @@ class legal_file_Core {
*
* @param string $extension (opt.) - return MIME of extension; if not given, return complete array
*/
- static function get_movie_types_by_extension($extension=NULL) {
- $types_by_extension_wrapper = new stdClass();
- $types_by_extension_wrapper->types_by_extension = array(
- "flv" => "video/x-flv", "mp4" => "video/mp4", "m4v" => "video/x-m4v");
- module::event("movie_types_by_extension", $types_by_extension_wrapper);
+ static function get_movie_types_by_extension($extension=null) {
+ if (empty(self::$movie_types_by_extension)) {
+ $types_by_extension_wrapper = new stdClass();
+ $types_by_extension_wrapper->types_by_extension = array(
+ "flv" => "video/x-flv", "mp4" => "video/mp4", "m4v" => "video/x-m4v");
+ module::event("movie_types_by_extension", $types_by_extension_wrapper);
+ foreach (self::$blacklist as $key) {
+ unset($types_by_extension_wrapper->types_by_extension[$key]);
+ }
+ self::$movie_types_by_extension = $types_by_extension_wrapper->types_by_extension;
+ }
if ($extension) {
// return matching MIME type
- return $types_by_extension_wrapper->types_by_extension[$extension];
+ $extension = strtolower($extension);
+ if (isset(self::$movie_types_by_extension[$extension])) {
+ return self::$movie_types_by_extension[$extension];
+ } else {
+ return null;
+ }
} else {
// return complete array
- return $types_by_extension_wrapper->types_by_extension;
+ return self::$movie_types_by_extension;
+ }
+ }
+
+ /**
+ * Create a merged list of all allowed photo and movie MIME types paired with their extensions.
+ *
+ * @param string $extension (opt.) - return MIME of extension; if not given, return complete array
+ */
+ static function get_types_by_extension($extension=null) {
+ $types_by_extension = legal_file::get_photo_types_by_extension();
+ if (movie::allow_uploads()) {
+ $types_by_extension = array_merge($types_by_extension,
+ legal_file::get_movie_types_by_extension());
+ }
+ if ($extension) {
+ // return matching MIME type
+ $extension = strtolower($extension);
+ if (isset($types_by_extension[$extension])) {
+ return $types_by_extension[$extension];
+ } else {
+ return null;
+ }
+ } else {
+ // return complete array
+ return $types_by_extension;
}
}
/**
* Create a default list of allowed photo extensions and then let modules modify it.
+ *
+ * @param string $extension (opt.) - return true if allowed; if not given, return complete array
*/
- static function get_photo_extensions() {
- $extensions_wrapper = new stdClass();
- $extensions_wrapper->extensions = array_keys(legal_file::get_photo_types_by_extension());
- module::event("legal_photo_extensions", $extensions_wrapper);
- return $extensions_wrapper->extensions;
+ static function get_photo_extensions($extension=null) {
+ if (empty(self::$photo_extensions)) {
+ $extensions_wrapper = new stdClass();
+ $extensions_wrapper->extensions = array_keys(legal_file::get_photo_types_by_extension());
+ module::event("legal_photo_extensions", $extensions_wrapper);
+ self::$photo_extensions = array_diff($extensions_wrapper->extensions, self::$blacklist);
+ }
+ if ($extension) {
+ // return true if in array, false if not
+ return in_array(strtolower($extension), self::$photo_extensions);
+ } else {
+ // return complete array
+ return self::$photo_extensions;
+ }
}
/**
* Create a default list of allowed movie extensions and then let modules modify it.
+ *
+ * @param string $extension (opt.) - return true if allowed; if not given, return complete array
*/
- static function get_movie_extensions() {
- $extensions_wrapper = new stdClass();
- $extensions_wrapper->extensions = array_keys(legal_file::get_movie_types_by_extension());
- module::event("legal_movie_extensions", $extensions_wrapper);
- return $extensions_wrapper->extensions;
+ static function get_movie_extensions($extension=null) {
+ if (empty(self::$movie_extensions)) {
+ $extensions_wrapper = new stdClass();
+ $extensions_wrapper->extensions = array_keys(legal_file::get_movie_types_by_extension());
+ module::event("legal_movie_extensions", $extensions_wrapper);
+ self::$movie_extensions = array_diff($extensions_wrapper->extensions, self::$blacklist);
+ }
+ if ($extension) {
+ // return true if in array, false if not
+ return in_array(strtolower($extension), self::$movie_extensions);
+ } else {
+ // return complete array
+ return self::$movie_extensions;
+ }
}
/**
* Create a merged list of all allowed photo and movie extensions.
+ *
+ * @param string $extension (opt.) - return true if allowed; if not given, return complete array
*/
- static function get_extensions() {
+ static function get_extensions($extension=null) {
$extensions = legal_file::get_photo_extensions();
- if (movie::find_ffmpeg()) {
+ if (movie::allow_uploads()) {
$extensions = array_merge($extensions, legal_file::get_movie_extensions());
}
- return $extensions;
+ if ($extension) {
+ // return true if in array, false if not
+ return in_array(strtolower($extension), $extensions);
+ } else {
+ // return complete array
+ return $extensions;
+ }
}
/**
@@ -109,10 +195,14 @@ class legal_file_Core {
* (e.g. flv maps to video/x-flv by default, but video/flv is still legal).
*/
static function get_photo_types() {
- $types_wrapper = new stdClass();
- $types_wrapper->types = array_values(legal_file::get_photo_types_by_extension());
- module::event("legal_photo_types", $types_wrapper);
- return $types_wrapper->types;
+ if (empty(self::$photo_types)) {
+ $types_wrapper = new stdClass();
+ // Need array_unique since types_by_extension can be many-to-one (e.g. jpeg and jpg).
+ $types_wrapper->types = array_unique(array_values(legal_file::get_photo_types_by_extension()));
+ module::event("legal_photo_types", $types_wrapper);
+ self::$photo_types = $types_wrapper->types;
+ }
+ return self::$photo_types;
}
/**
@@ -121,29 +211,34 @@ class legal_file_Core {
* (e.g. flv maps to video/x-flv by default, but video/flv is still legal).
*/
static function get_movie_types() {
- $types_wrapper = new stdClass();
- $types_wrapper->types = array_values(legal_file::get_movie_types_by_extension());
- $types_wrapper->types[] = "video/flv";
- module::event("legal_movie_types", $types_wrapper);
- return $types_wrapper->types;
+ if (empty(self::$movie_types)) {
+ $types_wrapper = new stdClass();
+ // Need array_unique since types_by_extension can be many-to-one (e.g. jpeg and jpg).
+ $types_wrapper->types = array_unique(array_values(legal_file::get_movie_types_by_extension()));
+ $types_wrapper->types[] = "video/flv";
+ module::event("legal_movie_types", $types_wrapper);
+ self::$movie_types = $types_wrapper->types;
+ }
+ return self::$movie_types;
}
/**
- * Convert the extension of a filename. If the original filename has no
+ * Change the extension of a filename. If the original filename has no
* extension, add the new one to the end.
*/
static function change_extension($filename, $new_ext) {
- if (strpos($filename, ".") === false) {
- return "{$filename}.{$new_ext}";
- } else {
- return preg_replace("/\.[^\.]*?$/", ".{$new_ext}", $filename);
- }
+ $filename_no_ext = preg_replace("/\.[^\.\/]*?$/", "", $filename);
+ return "{$filename_no_ext}.{$new_ext}";
}
/**
* Reduce the given file to having a single extension.
*/
static function smash_extensions($filename) {
+ if (!$filename) {
+ // It's harmless, so return it before it causes issues with pathinfo.
+ return $filename;
+ }
$parts = pathinfo($filename);
$result = "";
if ($parts["dirname"] != ".") {
@@ -152,7 +247,64 @@ class legal_file_Core {
$parts["filename"] = str_replace(".", "_", $parts["filename"]);
$parts["filename"] = preg_replace("/[_]+/", "_", $parts["filename"]);
$parts["filename"] = trim($parts["filename"], "_");
- $result .= "{$parts['filename']}.{$parts['extension']}";
+ $result .= isset($parts["extension"]) ? "{$parts['filename']}.{$parts['extension']}" : $parts["filename"];
return $result;
}
+
+ /**
+ * Sanitize a filename for a given type (given as "photo" or "movie") and a target file format
+ * (given as an extension). This returns a completely legal and valid filename,
+ * or throws an exception if the type or extension given is invalid or illegal. It tries to
+ * maintain the filename's original extension even if it's not identical to the given extension
+ * (e.g. don't change "JPG" or "jpeg" to "jpg").
+ *
+ * Note: it is not okay if the extension given is legal but does not match the type (e.g. if
+ * extension is "mp4" and type is "photo", it will throw an exception)
+ *
+ * @param string $filename (with no directory)
+ * @param string $extension (can be uppercase or lowercase)
+ * @param string $type (as "photo" or "movie")
+ * @return string sanitized filename (or null if bad extension argument)
+ */
+ static function sanitize_filename($filename, $extension, $type) {
+ // Check if the type is valid - if so, get the mime types of the
+ // original and target extensions; if not, throw an exception.
+ $original_extension = pathinfo($filename, PATHINFO_EXTENSION);
+ switch ($type) {
+ case "photo":
+ $mime_type = legal_file::get_photo_types_by_extension($extension);
+ $original_mime_type = legal_file::get_photo_types_by_extension($original_extension);
+ break;
+ case "movie":
+ $mime_type = legal_file::get_movie_types_by_extension($extension);
+ $original_mime_type = legal_file::get_movie_types_by_extension($original_extension);
+ break;
+ default:
+ throw new Exception("@todo INVALID_TYPE");
+ }
+
+ // Check if the target extension is blank or invalid - if so, throw an exception.
+ if (!$extension || !$mime_type) {
+ throw new Exception("@todo ILLEGAL_EXTENSION");
+ }
+
+ // Check if the mime types of the original and target extensions match - if not, fix it.
+ if (!$original_extension || ($mime_type != $original_mime_type)) {
+ $filename = legal_file::change_extension($filename, $extension);
+ }
+
+ // It should be a filename without a directory - remove all slashes (and backslashes).
+ $filename = str_replace("/", "_", $filename);
+ $filename = str_replace("\\", "_", $filename);
+
+ // Remove extra dots from the filename. This will also remove extraneous underscores.
+ $filename = legal_file::smash_extensions($filename);
+
+ // It's possible that the filename has no base (e.g. ".jpg") - if so, give it a generic one.
+ if (empty($filename) || (substr($filename, 0, 1) == ".")) {
+ $filename = $type . $filename; // e.g. "photo.jpg" or "movie.mp4"
+ }
+
+ return $filename;
+ }
}
diff --git a/modules/gallery/helpers/locales.php b/modules/gallery/helpers/locales.php
index f4837e01..8ca25c39 100644
--- a/modules/gallery/helpers/locales.php
+++ b/modules/gallery/helpers/locales.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/log.php b/modules/gallery/helpers/log.php
index 98a5c7d0..cd554b5c 100644
--- a/modules/gallery/helpers/log.php
+++ b/modules/gallery/helpers/log.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/message.php b/modules/gallery/helpers/message.php
index 277a0fee..d1099953 100644
--- a/modules/gallery/helpers/message.php
+++ b/modules/gallery/helpers/message.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/model_cache.php b/modules/gallery/helpers/model_cache.php
index fd56f131..7cff68d7 100644
--- a/modules/gallery/helpers/model_cache.php
+++ b/modules/gallery/helpers/model_cache.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php
index e4f41d3d..df258e87 100644
--- a/modules/gallery/helpers/module.php
+++ b/modules/gallery/helpers/module.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -175,9 +175,8 @@ class module_Core {
$installer_class = "{$module_name}_installer";
if (method_exists($installer_class, "install")) {
call_user_func_array(array($installer_class, "install"), array());
- } else {
- module::set_version($module_name, module::available()->$module_name->code_version);
}
+ 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
// loaded. By default, new modules are installed at the end of the priority list. Since the
diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php
index 6d70ab2d..eda478c7 100644
--- a/modules/gallery/helpers/movie.php
+++ b/modules/gallery/helpers/movie.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -24,6 +24,8 @@
* Note: by design, this class does not do any permission checking.
*/
class movie_Core {
+ private static $allow_uploads;
+
static function get_edit_form($movie) {
$form = new Forge("movies/update/$movie->id", "", "post", array("id" => "g-edit-movie-form"));
$form->hidden("from_id")->value($movie->id);
@@ -66,7 +68,7 @@ class movie_Core {
* @param string $output_file
* @param array $movie_options (optional)
*/
- static function extract_frame($input_file, $output_file, $movie_options=NULL) {
+ static function extract_frame($input_file, $output_file, $movie_options=null) {
$ffmpeg = movie::find_ffmpeg();
if (empty($ffmpeg)) {
throw new Exception("@todo MISSING_FFMPEG");
@@ -74,17 +76,17 @@ class movie_Core {
list($width, $height, $mime_type, $extension, $duration) = movie::get_file_metadata($input_file);
- if (is_numeric($movie_options["start_time"])) {
+ if (isset($movie_options["start_time"]) && is_numeric($movie_options["start_time"])) {
$start_time = max(0, $movie_options["start_time"]); // ensure it's non-negative
} else {
$start_time = module::get_var("gallery", "movie_extract_frame_time", 3); // use default
}
// extract frame at start_time, unless movie is too short
$start_time_arg = ($duration >= $start_time + 0.1) ?
- "-ss " . date("H:i:s", mktime(0,0,$start_time,0,0,0,0)) : "";
-
- $input_args = $movie_options["input_args"] ? $movie_options["input_args"] : "";
- $output_args = $movie_options["output_args"] ? $movie_options["output_args"] : "";
+ "-ss " . movie::seconds_to_hhmmssdd($start_time) : "";
+
+ $input_args = isset($movie_options["input_args"]) ? $movie_options["input_args"] : "";
+ $output_args = isset($movie_options["output_args"]) ? $movie_options["output_args"] : "";
$cmd = escapeshellcmd($ffmpeg) . " $input_args -i " . escapeshellarg($input_file) .
" -an $start_time_arg -an -r 1 -vframes 1" .
@@ -110,6 +112,29 @@ class movie_Core {
}
/**
+ * Return true if movie uploads are allowed, false if not. This is based on the
+ * "movie_allow_uploads" Gallery variable as well as whether or not ffmpeg is found.
+ */
+ static function allow_uploads() {
+ if (empty(self::$allow_uploads)) {
+ // Refresh ffmpeg settings
+ $ffmpeg = movie::find_ffmpeg();
+ switch (module::get_var("gallery", "movie_allow_uploads", "autodetect")) {
+ case "always":
+ self::$allow_uploads = true;
+ break;
+ case "never":
+ self::$allow_uploads = false;
+ break;
+ default:
+ self::$allow_uploads = !empty($ffmpeg);
+ break;
+ }
+ }
+ return self::$allow_uploads;
+ }
+
+ /**
* Return the path to the ffmpeg binary if one exists and is executable, or null.
*/
static function find_ffmpeg() {
@@ -123,41 +148,108 @@ class movie_Core {
/**
* Return the width, height, mime_type, extension and duration of the given movie file.
+ * Metadata is first generated using ffmpeg (or set to defaults if it fails),
+ * then can be modified by other modules using movie_get_file_metadata events.
+ *
+ * This function and its use cases are symmetric to those of photo::get_file_metadata.
+ *
+ * @param string $file_path
+ * @return array array($width, $height, $mime_type, $extension, $duration)
+ *
+ * Use cases in detail:
+ * Input is standard movie type (flv/mp4/m4v)
+ * -> return metadata from ffmpeg
+ * Input is *not* standard movie type that is supported by ffmpeg (e.g. avi, mts...)
+ * -> return metadata from ffmpeg
+ * Input is *not* standard movie type that is *not* supported by ffmpeg but is legal
+ * -> return zero width, height, and duration; mime type and extension according to legal_file
+ * Input is *not* standard movie type that is *not* supported by ffmpeg and is *not* legal
+ * -> return zero width, height, and duration; null mime type and extension
+ * Input is not readable or does not exist
+ * -> throw exception
+ * Note: movie_get_file_metadata events can change any of the above cases (except the last one).
*/
static function get_file_metadata($file_path) {
- $ffmpeg = movie::find_ffmpeg();
- if (empty($ffmpeg)) {
- throw new Exception("@todo MISSING_FFMPEG");
+ if (!is_readable($file_path)) {
+ throw new Exception("@todo UNREADABLE_FILE");
}
- $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($file_path) . " 2>&1";
- $result = `$cmd`;
- if (preg_match("/Stream.*?Video:.*?, (\d+)x(\d+)/", $result, $matches_res)) {
- if (preg_match("/Stream.*?Video:.*? \[.*?DAR (\d+):(\d+).*?\]/", $result, $matches_dar) &&
- $matches_dar[1] >= 1 && $matches_dar[2] >= 1) {
- // DAR is defined - determine width based on height and DAR
- // (should always be int, but adding round to be sure)
- $matches_res[1] = round($matches_res[2] * $matches_dar[1] / $matches_dar[2]);
+ $metadata = new stdClass();
+ $ffmpeg = movie::find_ffmpeg();
+ if (!empty($ffmpeg)) {
+ // ffmpeg found - use it to get width, height, and duration.
+ $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($file_path) . " 2>&1";
+ $result = `$cmd`;
+ if (preg_match("/Stream.*?Video:.*?, (\d+)x(\d+)/", $result, $matches_res)) {
+ if (preg_match("/Stream.*?Video:.*? \[.*?DAR (\d+):(\d+).*?\]/", $result, $matches_dar) &&
+ $matches_dar[1] >= 1 && $matches_dar[2] >= 1) {
+ // DAR is defined - determine width based on height and DAR
+ // (should always be int, but adding round to be sure)
+ $matches_res[1] = round($matches_res[2] * $matches_dar[1] / $matches_dar[2]);
+ }
+ list ($metadata->width, $metadata->height) = array($matches_res[1], $matches_res[2]);
+ } else {
+ list ($metadata->width, $metadata->height) = array(0, 0);
+ }
+
+ if (preg_match("/Duration: (\d+:\d+:\d+\.\d+)/", $result, $matches)) {
+ $metadata->duration = movie::hhmmssdd_to_seconds($matches[1]);
+ } else if (preg_match("/duration.*?:.*?(\d+)/", $result, $matches)) {
+ $metadata->duration = $matches[1];
+ } else {
+ $metadata->duration = 0;
}
- list ($width, $height) = array($matches_res[1], $matches_res[2]);
} else {
- list ($width, $height) = array(0, 0);
+ // ffmpeg not found - set width, height, and duration to zero.
+ $metadata->width = 0;
+ $metadata->height = 0;
+ $metadata->duration = 0;
}
- $extension = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
- $extension = $extension ? $extension : "flv"; // No extension? Assume FLV.
- $mime_type = legal_file::get_movie_types_by_extension($extension);
- $mime_type = $mime_type ? $mime_type : "video/x-flv"; // No MIME found? Default to video/x-flv.
-
- if (preg_match("/Duration: (\d+):(\d+):(\d+\.\d+)/", $result, $matches)) {
- $duration = 3600 * $matches[1] + 60 * $matches[2] + $matches[3];
- } else if (preg_match("/duration.*?:.*?(\d+)/", $result, $matches)) {
- $duration = $matches[1];
+ $extension = pathinfo($file_path, PATHINFO_EXTENSION);
+ if (!$extension ||
+ (!$metadata->mime_type = legal_file::get_movie_types_by_extension($extension))) {
+ // Extension is empty or illegal.
+ $metadata->extension = null;
+ $metadata->mime_type = null;
} else {
- $duration = 0;
+ // Extension is legal (and mime is already set above).
+ $metadata->extension = strtolower($extension);
}
- return array($width, $height, $mime_type, $extension, $duration);
+ // Run movie_get_file_metadata events which can modify the class.
+ module::event("movie_get_file_metadata", $file_path, $metadata);
+
+ // If the post-events results are invalid, throw an exception. Note that, unlike photos, having
+ // zero width and height isn't considered invalid (as is the case when FFmpeg isn't installed).
+ if (!$metadata->mime_type || !$metadata->extension ||
+ ($metadata->mime_type != legal_file::get_movie_types_by_extension($metadata->extension))) {
+ throw new Exception("@todo ILLEGAL_OR_UNINDENTIFIABLE_FILE");
+ }
+
+ return array($metadata->width, $metadata->height, $metadata->mime_type,
+ $metadata->extension, $metadata->duration);
+ }
+
+ /**
+ * Return the time/duration formatted in hh:mm:ss.dd from a number of seconds.
+ * Useful for inputs to ffmpeg.
+ *
+ * Note that this is similar to date("H:i:s", mktime(0,0,$seconds,0,0,0,0)), but unlike this
+ * approach avoids potential issues with time zone and DST mismatch and/or using deprecated
+ * features (the last argument of mkdate above, which disables DST, is deprecated as of PHP 5.3).
+ */
+ static function seconds_to_hhmmssdd($seconds) {
+ return sprintf("%02d:%02d:%05.2f", floor($seconds / 3600), floor(($seconds % 3600) / 60),
+ floor(100 * $seconds % 6000) / 100);
}
+ /**
+ * Return the number of seconds from a time/duration formatted in hh:mm:ss.dd.
+ * Useful for outputs from ffmpeg.
+ */
+ static function hhmmssdd_to_seconds($hhmmssdd) {
+ preg_match("/(\d+):(\d+):(\d+\.\d+)/", $hhmmssdd, $matches);
+ return 3600 * $matches[1] + 60 * $matches[2] + $matches[3];
+ }
}
diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php
index c4001bd5..2d32f0d3 100644
--- a/modules/gallery/helpers/photo.php
+++ b/modules/gallery/helpers/photo.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -80,20 +80,68 @@ class photo_Core {
/**
* Return the width, height, mime_type and extension of the given image file.
+ * Metadata is first generated using getimagesize (or the legal_file mapping if it fails),
+ * then can be modified by other modules using photo_get_file_metadata events.
+ *
+ * This function and its use cases are symmetric to those of photo::get_file_metadata.
+ *
+ * @param string $file_path
+ * @return array array($width, $height, $mime_type, $extension)
+ *
+ * Use cases in detail:
+ * Input is standard photo type (jpg/png/gif)
+ * -> return metadata from getimagesize()
+ * Input is *not* standard photo type that is supported by getimagesize (e.g. tif, bmp...)
+ * -> return metadata from getimagesize()
+ * Input is *not* standard photo type that is *not* supported by getimagesize but is legal
+ * -> return zero width and height, mime type and extension according to legal_file
+ * Input is *not* standard photo type that is *not* supported by getimagesize and is *not* legal
+ * -> return zero width and height, null mime type and extension
+ * Input is not readable or does not exist
+ * -> throw exception
+ * Note: photo_get_file_metadata events can change any of the above cases (except the last one).
*/
static function get_file_metadata($file_path) {
- $image_info = getimagesize($file_path);
- if ($image_info) {
- $width = $image_info[0];
- $height = $image_info[1];
- $mime_type = $image_info["mime"];
- $extension = image_type_to_extension($image_info[2], false);
- return array($width, $height, $mime_type, $extension);
+ if (!is_readable($file_path)) {
+ throw new Exception("@todo UNREADABLE_FILE");
+ }
+
+ $metadata = new stdClass();
+ if ($image_info = getimagesize($file_path)) {
+ // getimagesize worked - use its results.
+ $metadata->width = $image_info[0];
+ $metadata->height = $image_info[1];
+ $metadata->mime_type = $image_info["mime"];
+ $metadata->extension = image_type_to_extension($image_info[2], false);
+ // We prefer jpg instead of jpeg (which is returned by image_type_to_extension).
+ if ($metadata->extension == "jpeg") {
+ $metadata->extension = "jpg";
+ }
} else {
- // getimagesize failed - use legal_file mapping instead.
- $extension = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
- $mime_type = legal_file::get_photo_types_by_extension($extension);
- return array(0, 0, $mime_type, $extension);
+ // getimagesize failed - try to use legal_file mapping instead.
+ $extension = pathinfo($file_path, PATHINFO_EXTENSION);
+ if (!$extension ||
+ (!$metadata->mime_type = legal_file::get_photo_types_by_extension($extension))) {
+ // Extension is empty or illegal.
+ $metadata->extension = null;
+ $metadata->mime_type = null;
+ } else {
+ // Extension is legal (and mime is already set above).
+ $metadata->extension = strtolower($extension);
+ }
+ $metadata->width = 0;
+ $metadata->height = 0;
}
+
+ // Run photo_get_file_metadata events which can modify the class.
+ module::event("photo_get_file_metadata", $file_path, $metadata);
+
+ // If the post-events results are invalid, throw an exception.
+ if (!$metadata->width || !$metadata->height || !$metadata->mime_type || !$metadata->extension ||
+ ($metadata->mime_type != legal_file::get_photo_types_by_extension($metadata->extension))) {
+ throw new Exception("@todo ILLEGAL_OR_UNINDENTIFIABLE_FILE");
+ }
+
+ return array($metadata->width, $metadata->height, $metadata->mime_type, $metadata->extension);
}
}
diff --git a/modules/gallery/helpers/random.php b/modules/gallery/helpers/random.php
index ea08815a..d40bfb52 100644
--- a/modules/gallery/helpers/random.php
+++ b/modules/gallery/helpers/random.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/site_status.php b/modules/gallery/helpers/site_status.php
index dc8a6c23..e1a81637 100644
--- a/modules/gallery/helpers/site_status.php
+++ b/modules/gallery/helpers/site_status.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/system.php b/modules/gallery/helpers/system.php
index 9293e422..e1398103 100644
--- a/modules/gallery/helpers/system.php
+++ b/modules/gallery/helpers/system.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -20,22 +20,42 @@
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.
+ * The paths are traversed in the following order:
+ * 1. $priority_path (if specified)
+ * 2. Gallery's own bin directory (DOCROOT . "bin")
+ * 3. PATH environment variable
+ * 4. extra_binary_paths Gallery variable (if specified)
+ * In addition, if the file is found inside Gallery's bin directory but
+ * it's not executable, we try to change its permissions to 0755.
+ *
+ * @param string $binary
+ * @param string $priority_path (optional)
+ * @return string path to binary if found; null if not found
*/
static function find_binary($binary, $priority_path=null) {
- $paths = array_merge(
- explode(":", getenv("PATH")),
- explode(":", module::get_var("gallery", "extra_binary_paths")));
+ $bin_path = DOCROOT . "bin";
+
if ($priority_path) {
- array_unshift($paths, $priority_path);
+ $paths = array($priority_path, $bin_path);
+ } else {
+ $paths = array($bin_path);
}
+ $paths = array_merge($paths,
+ explode(":", getenv("PATH")),
+ explode(":", module::get_var("gallery", "extra_binary_paths")));
foreach ($paths as $path) {
$candidate = "$path/$binary";
// @suppress errors below to avoid open_basedir issues
- if (@file_exists($candidate) && @is_executable($candidate)) {
- return $candidate;
+ if (@file_exists($candidate)) {
+ if (!@is_executable($candidate) &&
+ (substr_compare($bin_path, $candidate, 0, strlen($bin_path)) == 0)) {
+ // Binary isn't executable but is in Gallery's bin directory - try fixing permissions.
+ @chmod($candidate, 0755);
+ }
+ if (@is_executable($candidate)) {
+ return $candidate;
+ }
}
}
return null;
diff --git a/modules/gallery/helpers/task.php b/modules/gallery/helpers/task.php
index 6fd6618f..32fd9739 100644
--- a/modules/gallery/helpers/task.php
+++ b/modules/gallery/helpers/task.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/theme.php b/modules/gallery/helpers/theme.php
index ea93a44f..072f98a1 100644
--- a/modules/gallery/helpers/theme.php
+++ b/modules/gallery/helpers/theme.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/tree_rest.php b/modules/gallery/helpers/tree_rest.php
index c2f81d3a..5186cf09 100644
--- a/modules/gallery/helpers/tree_rest.php
+++ b/modules/gallery/helpers/tree_rest.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/upgrade_checker.php b/modules/gallery/helpers/upgrade_checker.php
index d92da6e5..492f72e9 100644
--- a/modules/gallery/helpers/upgrade_checker.php
+++ b/modules/gallery/helpers/upgrade_checker.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class upgrade_checker_Core {
- const CHECK_URL = "http://gallery.menalto.com/versioncheck/gallery3";
+ const CHECK_URL = "http://galleryproject.org/versioncheck/gallery3";
const AUTO_CHECK_INTERVAL = 604800; // 7 days in seconds
/**
diff --git a/modules/gallery/helpers/user_profile.php b/modules/gallery/helpers/user_profile.php
index be79d9a8..222d2f57 100644
--- a/modules/gallery/helpers/user_profile.php
+++ b/modules/gallery/helpers/user_profile.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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
diff --git a/modules/gallery/helpers/xml.php b/modules/gallery/helpers/xml.php
index b57ecafa..e20beb19 100644
--- a/modules/gallery/helpers/xml.php
+++ b/modules/gallery/helpers/xml.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2012 Bharat Mediratta
+ * Copyright (C) 2000-2013 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