summaryrefslogtreecommitdiff
path: root/modules/gallery/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gallery/helpers')
-rw-r--r--modules/gallery/helpers/data_rest.php93
-rw-r--r--modules/gallery/helpers/gallery.php18
-rw-r--r--modules/gallery/helpers/gallery_event.php26
-rw-r--r--modules/gallery/helpers/gallery_installer.php51
-rw-r--r--modules/gallery/helpers/gallery_task.php98
-rw-r--r--modules/gallery/helpers/graphics.php6
-rw-r--r--modules/gallery/helpers/identity.php7
-rw-r--r--modules/gallery/helpers/item_rest.php6
-rw-r--r--modules/gallery/helpers/items_rest.php2
-rw-r--r--modules/gallery/helpers/json.php4
-rw-r--r--modules/gallery/helpers/l10n_scanner.php37
-rw-r--r--modules/gallery/helpers/module.php20
-rw-r--r--modules/gallery/helpers/movie.php46
-rw-r--r--modules/gallery/helpers/photo.php12
-rw-r--r--modules/gallery/helpers/theme.php35
-rw-r--r--modules/gallery/helpers/user_profile.php13
16 files changed, 351 insertions, 123 deletions
diff --git a/modules/gallery/helpers/data_rest.php b/modules/gallery/helpers/data_rest.php
new file mode 100644
index 00000000..98c98894
--- /dev/null
+++ b/modules/gallery/helpers/data_rest.php
@@ -0,0 +1,93 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2010 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * This resource returns the raw contents of Item_Model data files. It's analogous to the
+ * file_proxy controller, but it uses the REST authentication model.
+ */
+class data_rest_Core {
+ static function get($request) {
+ $item = rest::resolve($request->url);
+ access::required("view", $item);
+
+ $p = $request->params;
+ if (!isset($p->size) || !in_array($p->size, array("thumb", "resize", "full"))) {
+ 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;
+
+ case "full":
+ $file = $item->file_path();
+ break;
+ }
+
+ 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();
+
+ if ($item->is_album() && !$item->album_cover_item_id) {
+ // No thumbnail. Return nothing.
+ // @todo: what should we do here?
+ return;
+ }
+
+ // Dump out the image. If the item is a movie, then its thumbnail will be a JPG.
+ if ($item->is_movie() && $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}");
+ }
+ Kohana::close_buffers(false);
+ readfile($file);
+
+ // We must exit here to keep the regular REST framework reply code from adding more bytes on
+ // at the end or tinkering with headers.
+ exit;
+ }
+
+ static function resolve($id) {
+ $item = ORM::factory("item", $id);
+ if (!access::can("view", $item)) {
+ throw new Kohana_404_Exception();
+ }
+ return $item;
+ }
+
+ static function url($item, $size) {
+ return url::abs_site("rest/data/{$item->id}?size=$size");
+ }
+}
diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php
index d4078209..3f83b23d 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -25,12 +25,14 @@ class gallery_Core {
* down for maintenance" page.
*/
static function maintenance_mode() {
- $maintenance_mode = Kohana::config("core.maintenance_mode", false, false);
-
- if (Router::$controller != "login" && !empty($maintenance_mode) && !identity::active_user()->admin) {
- Router::$controller = "maintenance";
- Router::$controller_path = MODPATH . "gallery/controllers/maintenance.php";
- Router::$method = "index";
+ if (Router::$controller != "login" &&
+ Router::$controller != "combined" &&
+ module::get_var("gallery", "maintenance_mode", 0) &&
+ !identity::active_user()->admin) {
+ Session::instance()->set("continue_url", url::abs_site("admin/maintenance"));
+ Router::$controller = "login";
+ Router::$controller_path = MODPATH . "gallery/controllers/login.php";
+ Router::$method = "html";
}
}
@@ -58,7 +60,7 @@ class gallery_Core {
* @return string
*/
static function date_time($timestamp) {
- return date(module::get_var("gallery", "date_time_format", "Y-M-d H:i:s"), $timestamp);
+ return date(module::get_var("gallery", "date_time_format"), $timestamp);
}
/**
@@ -67,7 +69,7 @@ class gallery_Core {
* @return string
*/
static function date($timestamp) {
- return date(module::get_var("gallery", "date_format", "Y-M-d"), $timestamp);
+ return date(module::get_var("gallery", "date_format"), $timestamp);
}
/**
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index e3fa5e08..df5394c9 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -124,6 +124,20 @@ class gallery_event_Core {
}
}
+ static function item_updated_data_file($item) {
+ graphics::generate($item);
+
+ // Update any places where this is the album cover
+ 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->save();
+ }
+ }
+
static function batch_complete() {
// Set the album covers for any items that where we probably deleted the album cover during
// this batch. The item may have been deleted, so don't count on it being around. Choose the
@@ -433,7 +447,6 @@ class gallery_event_Core {
break;
}
$cover_title = t("Choose as the album cover");
- $move_title = t("Move to another album");
$csrf = access::csrf_token();
@@ -464,17 +477,6 @@ class gallery_event_Core {
->url(url::site("quick/rotate/$item->id/cw?csrf=$csrf&amp;from_id={$theme_item->id}&amp;page_type=$page_type")));
}
- // @todo Don't move photos from the photo page; we don't yet have a good way of redirecting
- // after move
- if ($theme->page_subtype() == "album") {
- $options_menu
- ->append(Menu::factory("dialog")
- ->id("move")
- ->label($move_title)
- ->css_class("ui-icon-folder-open")
- ->url(url::site("move/browse/$item->id")));
- }
-
$parent = $item->parent();
if (access::can("edit", $parent)) {
// We can't make this item the highlight if it's an album with no album cover, or if it's
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index 39c35711..d1bfa656 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -23,7 +23,8 @@ class gallery_installer {
$db->query("CREATE TABLE {access_caches} (
`id` int(9) NOT NULL auto_increment,
`item_id` int(9),
- PRIMARY KEY (`id`))
+ PRIMARY KEY (`id`),
+ KEY (`item_id`))
DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {access_intents} (
@@ -114,7 +115,8 @@ class gallery_installer {
KEY `parent_id` (`parent_id`),
KEY `type` (`type`),
KEY `random` (`rand_key`),
- KEY `weight` (`weight` DESC))
+ KEY `weight` (`weight` DESC),
+ KEY `left_ptr` (`left_ptr`))
DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {logs} (
@@ -144,8 +146,10 @@ class gallery_installer {
`active` BOOLEAN default 0,
`name` varchar(64) default NULL,
`version` int(9) default NULL,
+ `weight` int(9) default NULL,
PRIMARY KEY (`id`),
- UNIQUE KEY(`name`))
+ UNIQUE KEY(`name`),
+ KEY (`weight`))
DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {outgoing_translations} (
@@ -295,7 +299,10 @@ class gallery_installer {
module::set_var("gallery", "credits", (string) $powered_by_string);
module::set_var("gallery", "simultaneous_upload_limit", 5);
module::set_var("gallery", "admin_area_timeout", 90 * 60);
- module::set_version("gallery", 30);
+ module::set_var("gallery", "maintenance_mode", 0);
+ module::set_var("gallery", "visible_title_length", 15);
+ module::set_var("gallery", "favicon_url", "lib/images/favicon.ico");
+ module::set_version("gallery", 36);
}
static function upgrade($version) {
@@ -554,7 +561,41 @@ class gallery_installer {
if ($version == 29) {
$db->query("ALTER TABLE {caches} ADD KEY (`key`);");
module::set_version("gallery", $version = 30);
- }
+ }
+
+ if ($version == 30) {
+ module::set_var("gallery", "maintenance_mode", 0);
+ module::set_version("gallery", $version = 31);
+ }
+
+ if ($version == 31) {
+ $db->query("ALTER TABLE {modules} ADD COLUMN `weight` int(9) DEFAULT NULL");
+ $db->query("ALTER TABLE {modules} ADD KEY (`weight`)");
+ db::update("modules")
+ ->set("weight", new Database_Expression("`id`"))
+ ->execute();
+ module::set_version("gallery", $version = 32);
+ }
+
+ if ($version == 32) {
+ $db->query("ALTER TABLE {items} ADD KEY (`left_ptr`)");
+ module::set_version("gallery", $version = 33);
+ }
+
+ if ($version == 33) {
+ $db->query("ALTER TABLE {access_caches} ADD KEY (`item_id`)");
+ module::set_version("gallery", $version = 34);
+ }
+
+ if ($version == 34) {
+ module::set_var("gallery", "visible_title_length", 15);
+ module::set_version("gallery", $version = 35);
+ }
+
+ if ($version == 35) {
+ module::set_var("gallery", "favicon_url", "lib/images/favicon.ico");
+ module::set_version("gallery", $version = 36);
+ }
}
static function uninstall() {
diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php
index da9fba49..0886aad0 100644
--- a/modules/gallery/helpers/gallery_task.php
+++ b/modules/gallery/helpers/gallery_task.php
@@ -20,13 +20,15 @@
class gallery_task_Core {
const FIX_STATE_START_MPTT = 0;
const FIX_STATE_RUN_MPTT = 1;
- const FIX_STATE_START_PERMISSIONS = 2;
- const FIX_STATE_RUN_PERMISSIONS = 3;
+ const FIX_STATE_START_ALBUMS = 2;
+ const FIX_STATE_RUN_ALBUMS = 3;
const FIX_STATE_START_DUPE_SLUGS = 4;
const FIX_STATE_RUN_DUPE_SLUGS = 5;
const FIX_STATE_START_DUPE_NAMES = 6;
const FIX_STATE_RUN_DUPE_NAMES = 7;
- const FIX_STATE_DONE = 8;
+ const FIX_STATE_START_MISSING_ACCESS_CACHES = 8;
+ const FIX_STATE_RUN_MISSING_ACCESS_CACHES = 9;
+ const FIX_STATE_DONE = 10;
static function available_tasks() {
$dirty_count = graphics::find_dirty_images_query()->count_records();
@@ -56,8 +58,7 @@ class gallery_task_Core {
$tasks[] = Task_Definition::factory()
->callback("gallery_task::fix")
->name(t("Fix your Gallery"))
- ->description(t("Fix up a variety of little problems that might be causing " .
- "your Gallery to act a little weird"))
+ ->description(t("Fix a variety of problems that might cause your Gallery to act strangely. Requires maintenance mode."))
->severity(log::SUCCESS);
return $tasks;
@@ -323,15 +324,14 @@ class gallery_task_Core {
$total = $task->get("total");
if (empty($total)) {
// mptt: 2 operations for every item
- // permissions: 1 operation for every album
- // dupe slugs: 1 operation for each unique conflicted slug
$total = 2 * db::build()->count_records("items");
+ // album audit (permissions and bogus album covers): 1 operation for every album
$total += db::build()->where("type", "=", "album")->count_records("items");
- foreach (self::find_dupe_slugs() as $row) {
- $total++;
- }
- foreach (self::find_dupe_names() as $row) {
- $total++;
+ // one operation for each missing slug, name and access cache
+ foreach (array("find_dupe_slugs", "find_dupe_names", "find_missing_access_caches") as $func) {
+ foreach (self::$func() as $row) {
+ $total++;
+ }
}
$task->set("total", $total);
@@ -343,15 +343,24 @@ class gallery_task_Core {
$completed = $task->get("completed");
$state = $task->get("state");
+ if (!module::get_var("gallery", "maintenance_mode")) {
+ module::set_var("gallery", "maintenance_mode", 1);
+ }
+
// This is a state machine that checks each item in the database. It verifies the following
// attributes for an item.
// 1. Left and right MPTT pointers are correct
// 2. The .htaccess permission files for restricted items exist and are well formed.
// 3. The relative_path_cache and relative_url_cache values are set to null.
+ // 4. there are no album_cover_item_ids pointing to missing items
//
// We'll do a depth-first tree walk over our hierarchy using only the adjacency data because
// we don't trust MPTT here (that might be what we're here to fix!). Avoid avoid using ORM
// calls as much as possible since they're expensive.
+ //
+ // NOTE: the MPTT check will only traverse items that have valid parents. It's possible that
+ // we have some tree corruption where there are items with parent ids to non-existent items.
+ // We should probably do something about that.
while ($state != self::FIX_STATE_DONE && microtime(true) - $start < 1.5) {
switch ($state) {
case self::FIX_STATE_START_MPTT:
@@ -456,7 +465,7 @@ class gallery_task_Core {
$task->set("stack", implode(" ", $stack));
$state = self::FIX_STATE_RUN_DUPE_NAMES;
} else {
- $state = self::FIX_STATE_START_PERMISSIONS;
+ $state = self::FIX_STATE_START_ALBUMS;
}
break;
@@ -489,11 +498,11 @@ class gallery_task_Core {
$completed++;
if (empty($stack)) {
- $state = self::FIX_STATE_START_PERMISSIONS;
+ $state = self::FIX_STATE_START_ALBUMS;
}
break;
- case self::FIX_STATE_START_PERMISSIONS:
+ case self::FIX_STATE_START_ALBUMS:
$stack = array();
foreach (db::build()
->select("id")
@@ -503,23 +512,26 @@ class gallery_task_Core {
$stack[] = $row->id;
}
$task->set("stack", implode(" ", $stack));
- $state = self::FIX_STATE_RUN_PERMISSIONS;
+ $state = self::FIX_STATE_RUN_ALBUMS;
break;
- case self::FIX_STATE_RUN_PERMISSIONS:
+ case self::FIX_STATE_RUN_ALBUMS:
$stack = explode(" ", $task->get("stack"));
$id = array_pop($stack);
+ $item = ORM::factory("item", $id);
+ if ($item->album_cover_item_id) {
+ $album_cover_item = ORM::factory("item", $item->album_cover_item_id);
+ if (!$album_cover_item->loaded()) {
+ $item->album_cover_item_id = null;
+ $item->save();
+ }
+ }
+
$everybody = identity::everybody();
$view_col = "view_{$everybody->id}";
$view_full_col = "view_full_{$everybody->id}";
$intent = ORM::factory("access_intent")->where("item_id", "=", $id)->find();
-
- // Only load the item if we're going to use it below
- if ($intent->$view_col === access::DENY ||
- $intent->$view_full_col === access::DENY) {
- $item = ORM::factory("item", $id);
- }
if ($intent->$view_col === access::DENY) {
access::update_htaccess_files($item, $everybody, "view", access::DENY);
}
@@ -530,6 +542,36 @@ class gallery_task_Core {
$completed++;
if (empty($stack)) {
+ $state = self::FIX_STATE_START_MISSING_ACCESS_CACHES;
+ }
+ break;
+
+ case self::FIX_STATE_START_MISSING_ACCESS_CACHES:
+ $stack = array();
+ foreach (self::find_missing_access_caches() as $row) {
+ $stack[] = $row->id;
+ }
+ if ($stack) {
+ $task->set("stack", implode(" ", $stack));
+ $state = self::FIX_STATE_RUN_MISSING_ACCESS_CACHES;
+ } else {
+ $state = self::FIX_STATE_DONE;
+ }
+ break;
+
+ case self::FIX_STATE_RUN_MISSING_ACCESS_CACHES:
+ $stack = explode(" ", $task->get("stack"));
+ $id = array_pop($stack);
+ $access_cache = ORM::factory("access_cache");
+ $access_cache->item_id = $id;
+ $access_cache->save();
+ $task->set("stack", implode(" ", $stack));
+ $completed++;
+ if (empty($stack)) {
+ // The new cache rows are there, but they're incorrectly populated so we have to fix
+ // them. If this turns out to be too slow, we'll have to refactor
+ // access::recalculate_permissions to allow us to do it in slices.
+ access::recalculate_permissions(item::root());
$state = self::FIX_STATE_DONE;
}
break;
@@ -543,6 +585,7 @@ class gallery_task_Core {
$task->done = true;
$task->state = "success";
$task->percent_complete = 100;
+ module::set_var("gallery", "maintenance_mode", 0);
} else {
$task->percent_complete = round(100 * $completed / $total);
}
@@ -574,4 +617,13 @@ class gallery_task_Core {
->group_by("parent_name")
->execute();
}
+
+ static function find_missing_access_caches() {
+ return db::build()
+ ->select("items.id")
+ ->from("items")
+ ->join("access_caches", "items.id", "access_caches.item_id", "left")
+ ->where("access_caches.id", "is", null)
+ ->execute();
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php
index cc4d2e76..bb085ea5 100644
--- a/modules/gallery/helpers/graphics.php
+++ b/modules/gallery/helpers/graphics.php
@@ -338,8 +338,7 @@ class graphics_Core {
} else {
$toolkits->imagemagick->installed = false;
$toolkits->imagemagick->error =
- t("ImageMagick is installed, but PHP's open_basedir restriction " .
- "prevents Gallery from using it.");
+ t("ImageMagick is installed, but PHP's open_basedir restriction prevents Gallery from using it.");
}
} else {
$toolkits->imagemagick->installed = false;
@@ -363,8 +362,7 @@ class graphics_Core {
} else {
$toolkits->graphicsmagick->installed = false;
$toolkits->graphicsmagick->error =
- t("GraphicsMagick is installed, but PHP's open_basedir restriction " .
- "prevents Gallery from using it.");
+ t("GraphicsMagick is installed, but PHP's open_basedir restriction prevents Gallery from using it.");
}
} else {
$toolkits->graphicsmagick->installed = false;
diff --git a/modules/gallery/helpers/identity.php b/modules/gallery/helpers/identity.php
index 5f1664ec..5de05948 100644
--- a/modules/gallery/helpers/identity.php
+++ b/modules/gallery/helpers/identity.php
@@ -66,17 +66,20 @@ class identity_Core {
// The installer cannot set a user into the session, so it just sets an id which we should
// upconvert into a user.
- // @todo set the user name into the session instead of 2 and then use it to get the user object
+ // @todo set the user name into the session instead of 2 and then use it to get the
+ // user object
if ($user === 2) {
auth::login(IdentityProvider::instance()->admin_user());
}
- if (!$session->get("group_ids")) {
+ // Cache the group ids for a day to trade off performance for security updates.
+ if (!$session->get("group_ids") || $session->get("group_ids_timeout", 0) < time()) {
$ids = array();
foreach ($user->groups() as $group) {
$ids[] = $group->id;
}
$session->set("group_ids", $ids);
+ $session->set("group_ids_timeout", time() + 86400);
}
} catch (Exception $e) {
// Log it, so we at least have so notification that we swallowed the exception.
diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php
index 6869181d..10f9e16a 100644
--- a/modules/gallery/helpers/item_rest.php
+++ b/modules/gallery/helpers/item_rest.php
@@ -126,6 +126,12 @@ class item_rest_Core {
}
}
}
+
+ // Replace the data file, if required
+ if (($item->is_photo() || $item->is_movie()) && isset($request->file)) {
+ $item->set_data_file($request->file);
+ }
+
$item->save();
if (isset($request->params->members) && $item->sort_column == "weight") {
diff --git a/modules/gallery/helpers/items_rest.php b/modules/gallery/helpers/items_rest.php
index 9cca9a54..f0b68d63 100644
--- a/modules/gallery/helpers/items_rest.php
+++ b/modules/gallery/helpers/items_rest.php
@@ -80,7 +80,7 @@ class items_rest_Core {
"relationships" => rest::relationships("item", $item));
if ($item->type == "album") {
$members = array();
- foreach ($item->children() as $child) {
+ foreach ($item->viewable()->children() as $child) {
$members[] = rest::url("item", $child);
}
$item_rest["members"] = $members;
diff --git a/modules/gallery/helpers/json.php b/modules/gallery/helpers/json.php
index a39db27a..a88608aa 100644
--- a/modules/gallery/helpers/json.php
+++ b/modules/gallery/helpers/json.php
@@ -25,9 +25,7 @@ class json_Core {
* @param mixed $message string or object to json encode and print
*/
static function reply($message) {
- if (!headers_sent()) {
- header("Content-Type: application/json; charset=" . Kohana::CHARSET);
- }
+ header("Content-Type: application/json; charset=" . Kohana::CHARSET);
print json_encode($message);
}
} \ No newline at end of file
diff --git a/modules/gallery/helpers/l10n_scanner.php b/modules/gallery/helpers/l10n_scanner.php
index 2287a7ba..843c74f7 100644
--- a/modules/gallery/helpers/l10n_scanner.php
+++ b/modules/gallery/helpers/l10n_scanner.php
@@ -74,10 +74,21 @@ class l10n_scanner_Core {
unset($raw_tokens);
if (!empty($func_token_list["t"])) {
- l10n_scanner::_parse_t_calls($tokens, $func_token_list["t"], $cache);
+ $errors = l10n_scanner::_parse_t_calls($tokens, $func_token_list["t"], $cache);
+ foreach ($errors as $line => $error) {
+ Kohana_Log::add(
+ "error", "Translation scanner error. " .
+ "file: " . substr($file, strlen(DOCROOT)) . ", line: $line, context: $error");
+ }
}
+
if (!empty($func_token_list["t2"])) {
- l10n_scanner::_parse_plural_calls($tokens, $func_token_list["t2"], $cache);
+ $errors = l10n_scanner::_parse_plural_calls($tokens, $func_token_list["t2"], $cache);
+ foreach ($errors as $line => $error) {
+ Kohana_Log::add(
+ "error", "Translation scanner error. " .
+ "file: " . substr($file, strlen(DOCROOT)) . ", line: $line, context: $error");
+ }
}
}
@@ -91,6 +102,7 @@ class l10n_scanner_Core {
}
private static function _parse_t_calls(&$tokens, &$call_list, &$cache) {
+ $errors = array();
foreach ($call_list as $index) {
$function_name = $tokens[$index++];
$parens = $tokens[$index++];
@@ -103,14 +115,21 @@ class l10n_scanner_Core {
$message = self::_escape_quoted_string($first_param[1]);
l10n_scanner::process_message($message, $cache);
} else {
- // t() found, but inside is something which is not a string literal.
- // @todo Call status callback with error filename/line.
+ if (is_array($first_param) && ($first_param[0] == T_CONSTANT_ENCAPSED_STRING)) {
+ // Malformed string literals; escalate this
+ $errors[$first_param[2]] =
+ var_export(array($function_name, $parens, $first_param, $next_token), 1);
+ } else {
+ // t() found, but inside is something which is not a string literal. That's fine.
+ }
}
}
}
+ return $errors;
}
private static function _parse_plural_calls(&$tokens, &$call_list, &$cache) {
+ $errors = array();
foreach ($call_list as $index) {
$function_name = $tokens[$index++];
$parens = $tokens[$index++];
@@ -127,11 +146,17 @@ class l10n_scanner_Core {
$plural = self::_escape_quoted_string($second_param[1]);
l10n_scanner::process_message(array("one" => $singular, "other" => $plural), $cache);
} else {
- // t2() found, but inside is something which is not a string literal.
- // @todo Call status callback with error filename/line.
+ if (is_array($first_param) && $first_param[0] == T_CONSTANT_ENCAPSED_STRING) {
+ $errors[$first_param[2]] = var_export(
+ array($function_name, $parens, $first_param,
+ $first_separator, $second_param, $next_token), 1);
+ } else {
+ // t2() found, but inside is something which is not a string literal. That's fine.
+ }
}
}
}
+ return $errors;
}
/**
diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php
index 5134c7b3..ca6651f1 100644
--- a/modules/gallery/helpers/module.php
+++ b/modules/gallery/helpers/module.php
@@ -166,6 +166,16 @@ class module_Core {
} else {
module::set_version($module_name, 1);
}
+
+ // 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
+ // id field is monotonically increasing, the easiest way to guarantee that is to set the weight
+ // the same as the id. We don't know that until we save it for the first time
+ $module = ORM::factory("module")->where("name", "=", $module_name)->find();
+ if ($module->loaded()) {
+ $module->weight = $module->id;
+ $module->save();
+ }
module::load_modules();
// Now the module is installed but inactive, so don't leave it in the active path
@@ -314,7 +324,15 @@ class module_Core {
self::$modules = array();
self::$active = array();
$kohana_modules = array();
- foreach (ORM::factory("module")->find_all() as $module) {
+
+ // In version 32 we introduced a weight column so we can specify the module order
+ // If we try to use that blindly, we'll break earlier versions before they can even
+ // run the upgrader.
+ $modules = module::get_version("gallery") < 32 ?
+ ORM::factory("module")->find_all():
+ ORM::factory("module")->order_by("weight")->find_all();
+
+ foreach ($modules as $module) {
self::$modules[$module->name] = $module;
if (!$module->active) {
continue;
diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php
index bbb5b66c..3e55eefe 100644
--- a/modules/gallery/helpers/movie.php
+++ b/modules/gallery/helpers/movie.php
@@ -57,23 +57,6 @@ class movie_Core {
return $form;
}
-
- static function getmoviesize($filename) {
- $ffmpeg = self::find_ffmpeg();
- if (empty($ffmpeg)) {
- throw new Exception("@todo MISSING_FFMPEG");
- }
-
- $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($filename) . " 2>&1";
- $result = `$cmd`;
- if (preg_match("/Stream.*?Video:.*?(\d+)x(\d+)/", $result, $regs)) {
- list ($width, $height) = array($regs[1], $regs[2]);
- } else {
- list ($width, $height) = array(0, 0);
- }
- return array($width, $height);
- }
-
static function extract_frame($input_file, $output_file) {
$ffmpeg = self::find_ffmpeg();
if (empty($ffmpeg)) {
@@ -101,7 +84,7 @@ class movie_Core {
}
static function find_ffmpeg() {
- if (!$ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) {
+ if (!($ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) || !file_exists($ffmpeg_path)) {
$graphics_path = module::get_var("gallery", "graphics_toolkit_path", null);
putenv("PATH=" . getenv("PATH") . (empty($graphics_path) ? "" : ":$graphics_path") .
@@ -114,4 +97,31 @@ class movie_Core {
}
return $ffmpeg_path;
}
+
+
+ /**
+ * Return the width, height, mime_type and extension of the given movie file.
+ */
+ static function get_file_metadata($file_path) {
+ $ffmpeg = self::find_ffmpeg();
+ if (empty($ffmpeg)) {
+ throw new Exception("@todo MISSING_FFMPEG");
+ }
+
+ $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($file_path) . " 2>&1";
+ $result = `$cmd`;
+ if (preg_match("/Stream.*?Video:.*?(\d+)x(\d+)/", $result, $regs)) {
+ list ($width, $height) = array($regs[1], $regs[2]);
+ } else {
+ list ($width, $height) = array(0, 0);
+ }
+
+ $pi = pathinfo($file_path);
+ $extension = isset($pi["extension"]) ? $pi["extension"] : "flv"; // No extension? Assume FLV.
+ $mime_type = in_array(strtolower($extension), array("mp4", "m4v")) ?
+ "video/mp4" : "video/x-flv";
+
+ return array($width, $height, $mime_type, $extension);
+ }
+
}
diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php
index 73cd60c0..a38b4fb2 100644
--- a/modules/gallery/helpers/photo.php
+++ b/modules/gallery/helpers/photo.php
@@ -77,4 +77,16 @@ class photo_Core {
}
return sprintf($format, $new_width, $new_height);
}
+
+ /**
+ * Return the width, height, mime_type and extension of the given image file.
+ */
+ static function get_file_metadata($file_path) {
+ $image_info = getimagesize($file_path);
+ $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);
+ }
}
diff --git a/modules/gallery/helpers/theme.php b/modules/gallery/helpers/theme.php
index 3589a5b7..1dc1f3b6 100644
--- a/modules/gallery/helpers/theme.php
+++ b/modules/gallery/helpers/theme.php
@@ -77,41 +77,8 @@ class theme_Core {
$config->set("core.modules", $modules);
}
- static function get_edit_form_admin() {
- $form = new Forge("admin/theme_options/save/", "", null, array("id" =>"g-theme-options-form"));
- $group = $form->group("edit_theme")->label(t("Theme layout"));
- $group->input("page_size")->label(t("Items per page"))->id("g-page-size")
- ->rules("required|valid_digit")
- ->error_messages("required", t("You must enter a number"))
- ->error_messages("valid_digit", t("You must enter a number"))
- ->value(module::get_var("gallery", "page_size"));
- $group->input("thumb_size")->label(t("Thumbnail size (in pixels)"))->id("g-thumb-size")
- ->rules("required|valid_digit")
- ->error_messages("required", t("You must enter a number"))
- ->error_messages("valid_digit", t("You must enter a number"))
- ->value(module::get_var("gallery", "thumb_size"));
- $group->input("resize_size")->label(t("Resized image size (in pixels)"))->id("g-resize-size")
- ->rules("required|valid_digit")
- ->error_messages("required", t("You must enter a number"))
- ->error_messages("valid_digit", t("You must enter a number"))
- ->value(module::get_var("gallery", "resize_size"));
- $group->textarea("header_text")->label(t("Header text"))->id("g-header-text")
- ->value(module::get_var("gallery", "header_text"));
- $group->textarea("footer_text")->label(t("Footer text"))->id("g-footer-text")
- ->value(module::get_var("gallery", "footer_text"));
- $group->checkbox("show_credits")->label(t("Show site credits"))->id("g-footer-text")
- ->checked(module::get_var("gallery", "show_credits"));
-
- module::event("theme_edit_form", $form);
-
- $group = $form->group("buttons")
- ->set_attr("style","border: none");
- $group->submit("")->value(t("Save"));
- return $form;
- }
-
static function get_info($theme_name) {
- $theme_name = preg_replace("/[^\w]/", "", $theme_name);
+ $theme_name = preg_replace("/[^a-zA-Z0-9\._-]/", "", $theme_name);
$file = THEMEPATH . "$theme_name/theme.info";
$theme_info = new ArrayObject(parse_ini_file($file), ArrayObject::ARRAY_AS_PROPS);
$theme_info->description = t($theme_info->description);
diff --git a/modules/gallery/helpers/user_profile.php b/modules/gallery/helpers/user_profile.php
index e5ebce84..d9cc8ace 100644
--- a/modules/gallery/helpers/user_profile.php
+++ b/modules/gallery/helpers/user_profile.php
@@ -35,19 +35,20 @@ class user_profile_Core {
$group->input("reply_to")
->label(t("From:"))
->rules("required|length[1, 256]|valid_email")
- ->error_messages("required", t("Field is required"))
- ->error_messages("max_length", t("Field exceeds 256 bytes"))
- ->error_messages("valid_email", t("Field is not a valid email address"));
+ ->error_messages("required", t("You must enter a valid email address"))
+ ->error_messages("max_length", t("Your email address is too long"))
+ ->error_messages("valid_email", t("You must enter a valid email address"));
$group->input("subject")
->label(t("Subject:"))
->rules("required|length[1, 256]")
- ->error_messages("required", t("Field is required"))
- ->error_messages("max_length", t("Field exceeds 256 bytes"));
+ ->error_messages("required", t("Your message must have a subject"))
+ ->error_messages("max_length", t("Your subject is too long"));
$group->textarea("message")
->label(t("Message:"))
->rules("required")
- ->error_messages("required", t("Field is required"));
+ ->error_messages("required", t("You must enter a message"));
module::event("user_profile_contact_form", $form);
+ module::event("captcha_protect_form", $form);
$group->submit("")->value(t("Send"));
return $form;
}