summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Kinkade <nkinkade@nkinka.de>2010-09-17 20:23:05 +0000
committerNathan Kinkade <nkinkade@nkinka.de>2010-09-17 20:23:05 +0000
commit7a5de04e51daa102840a02af6b9ce8138d08c4bb (patch)
treea3f8bcb9ac961523b4835b8865c152c8835f25e7
parentf96a75f2b13a0bd7a37b320aa5655f67868ca80d (diff)
parent3e1743b21fd35b9d6d540e827292f1f4f006b531 (diff)
Pulled latest source from upstream.
-rw-r--r--.htaccess6
-rw-r--r--index.php9
-rw-r--r--installer/cli.php2
-rw-r--r--installer/install.sql12
-rw-r--r--lib/gallery.common.js37
-rw-r--r--modules/comment/controllers/comments.php1
-rw-r--r--modules/comment/helpers/comment.php3
-rw-r--r--modules/comment/helpers/comment_rss.php10
-rw-r--r--modules/exif/helpers/exif_task.php4
-rw-r--r--modules/g2_import/css/g2_import.css30
-rw-r--r--modules/g2_import/helpers/g2_import.php6
-rw-r--r--modules/g2_import/helpers/g2_import_theme.php28
-rw-r--r--modules/g2_import/views/admin_g2_import.html.php106
-rw-r--r--modules/gallery/controllers/admin_modules.php5
-rw-r--r--modules/gallery/controllers/items.php9
-rw-r--r--modules/gallery/controllers/quick.php3
-rw-r--r--modules/gallery/controllers/reauthenticate.php11
-rw-r--r--modules/gallery/controllers/upgrader.php36
-rw-r--r--modules/gallery/controllers/uploader.php13
-rw-r--r--modules/gallery/controllers/user_profile.php39
-rw-r--r--modules/gallery/css/upgrader.css28
-rw-r--r--modules/gallery/helpers/access.php31
-rw-r--r--modules/gallery/helpers/album.php1
-rw-r--r--modules/gallery/helpers/gallery.php24
-rw-r--r--modules/gallery/helpers/gallery_event.php31
-rw-r--r--modules/gallery/helpers/gallery_installer.php38
-rw-r--r--modules/gallery/helpers/gallery_rss.php10
-rw-r--r--modules/gallery/helpers/gallery_task.php6
-rw-r--r--modules/gallery/helpers/graphics.php3
-rw-r--r--modules/gallery/helpers/identity.php8
-rw-r--r--modules/gallery/helpers/locales.php2
-rw-r--r--modules/gallery/helpers/module.php24
-rw-r--r--modules/gallery/helpers/movie.php3
-rw-r--r--modules/gallery/hooks/init_gallery.php1
-rw-r--r--modules/gallery/libraries/Gallery_I18n.php6
-rw-r--r--modules/gallery/libraries/Sendmail.php7
-rw-r--r--modules/gallery/libraries/drivers/IdentityProvider.php12
-rw-r--r--modules/gallery/models/item.php79
-rw-r--r--modules/gallery/module.info2
-rw-r--r--modules/gallery/tests/Access_Helper_Test.php4
-rw-r--r--modules/gallery/tests/Item_Model_Test.php57
-rw-r--r--modules/gallery/tests/Sendmail_Test.php30
-rw-r--r--modules/gallery/tests/controller_auth_data.txt3
-rw-r--r--modules/gallery/tests/xss_data.txt115
-rw-r--r--modules/gallery/views/admin_block_platform.html.php3
-rw-r--r--modules/gallery/views/admin_graphics.html.php1
-rw-r--r--modules/gallery/views/admin_maintenance.html.php15
-rw-r--r--modules/gallery/views/admin_maintenance_task.html.php20
-rw-r--r--modules/gallery/views/form_uploadify.html.php6
-rw-r--r--modules/gallery/views/upgrader.html.php53
-rw-r--r--modules/notification/helpers/notification.php156
-rw-r--r--modules/notification/helpers/notification_installer.php11
-rw-r--r--modules/notification/module.info2
-rw-r--r--modules/organize/lib/Gallery3WebClient.swfbin148799 -> 148926 bytes
-rw-r--r--modules/organize/views/organize_dialog.html.php10
-rw-r--r--modules/rest/helpers/rest_installer.php4
-rw-r--r--modules/rest/views/error_rest.json.php4
-rw-r--r--modules/search/helpers/search_task.php4
-rw-r--r--modules/tag/controllers/tag.php49
-rw-r--r--modules/tag/controllers/tags.php28
-rw-r--r--modules/tag/css/tag.css6
-rw-r--r--modules/tag/helpers/tag_rss.php3
-rw-r--r--modules/tag/models/tag.php2
-rw-r--r--modules/tag/views/tag_block.html.php5
-rw-r--r--modules/user/controllers/admin_users.php9
-rw-r--r--modules/user/helpers/group.php8
-rw-r--r--modules/user/helpers/user.php14
-rw-r--r--modules/user/libraries/drivers/IdentityProvider/Gallery.php9
-rw-r--r--modules/user/models/user.php4
-rw-r--r--modules/user/views/admin_users.html.php4
-rw-r--r--modules/user/views/admin_users_delete_user.html.php7
-rw-r--r--themes/admin_wind/css/screen.css8
-rw-r--r--themes/wind/js/ui.init.js9
-rw-r--r--themes/wind/views/page.html.php4
-rw-r--r--themes/wind/views/photo.html.php15
75 files changed, 856 insertions, 512 deletions
diff --git a/.htaccess b/.htaccess
index 38042737..d142d557 100644
--- a/.htaccess
+++ b/.htaccess
@@ -25,9 +25,15 @@
# you'll get an "Internal Server Error".
#
<FilesMatch "(\.(class|fla|inc|sql|txt|gitignore)|(README|LICENSE))$">
+ Order deny,allow
+ Deny from all
+</FilesMatch>
+<FilesMatch "robots.txt">
Order allow,deny
+ Allow from all
</FilesMatch>
+
# Improve performance by uncommenting this block. It tells the
# browser that your images don't change very often so it won't keep
# asking for them. If you get an error after uncommenting this, make
diff --git a/index.php b/index.php
index 4ef3d943..68000ef8 100644
--- a/index.php
+++ b/index.php
@@ -73,9 +73,12 @@ if (PHP_SAPI == "cli") {
break;
default:
- print "To install:\n php index.php install -d database -h host -u user -p password -x table_prefix \n\n\n";
- print "To upgrade:\n php index.php upgrade\n\n\n";
- print "Developer-only features:\n ** CAUTION! THESE FEATURES -WILL- DAMAGE YOUR INSTALL **\n";
+ print "To install:\n";
+ print " php index.php install -d database -h host -u user -p password -x table_prefix \n\n";
+ print "To upgrade:\n";
+ print " php index.php upgrade\n\n";
+ print "Developer-only features:\n";
+ print " ** CAUTION! THESE FEATURES -WILL- DAMAGE YOUR INSTALL **\n";
print " php index.php package # create new installer files\n";
print " php index.php test # run unit tests\n";
exit(1);
diff --git a/installer/cli.php b/installer/cli.php
index e7c81ac3..fe82395a 100644
--- a/installer/cli.php
+++ b/installer/cli.php
@@ -32,7 +32,7 @@ if (installer::already_installed()) {
$errors = installer::check_environment();
if ($errors) {
- oops(implode("errors", "\n"));
+ oops(implode($errors, "\n"));
}
$config = parse_cli_params();
diff --git a/installer/install.sql b/installer/install.sql
index 7440cc8f..52654faf 100644
--- a/installer/install.sql
+++ b/installer/install.sql
@@ -244,7 +244,7 @@ CREATE TABLE {modules} (
KEY `weight` (`weight`)
) AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
-INSERT INTO {modules} VALUES (1,1,'gallery',37,1);
+INSERT INTO {modules} VALUES (1,1,'gallery',40,1);
INSERT INTO {modules} VALUES (2,1,'user',3,2);
INSERT INTO {modules} VALUES (3,1,'comment',3,3);
INSERT INTO {modules} VALUES (4,1,'organize',2,4);
@@ -395,7 +395,7 @@ CREATE TABLE {vars} (
`value` text,
PRIMARY KEY (`id`),
UNIQUE KEY `module_name` (`module_name`,`name`)
-) AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=51 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO {vars} VALUES (NULL,'gallery','active_site_theme','wind');
INSERT INTO {vars} VALUES (NULL,'gallery','active_admin_theme','admin_wind');
@@ -417,15 +417,17 @@ INSERT INTO {vars} VALUES (NULL,'gallery','date_time_format','Y-M-d H:i:s');
INSERT INTO {vars} VALUES (NULL,'gallery','favicon_url','lib/images/favicon.ico');
INSERT INTO {vars} VALUES (NULL,'gallery','date_format','Y-M-d');
INSERT INTO {vars} VALUES (NULL,'gallery','blocks_dashboard_center','a:3:{i:6;a:2:{i:0;s:7:\"gallery\";i:1;s:7:\"welcome\";}i:7;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"photo_stream\";}i:8;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"log_entries\";}}');
-INSERT INTO {vars} VALUES (NULL,'gallery','email_from','admin@example.com');
-INSERT INTO {vars} VALUES (NULL,'gallery','email_reply_to','public@example.com');
+INSERT INTO {vars} VALUES (NULL,'gallery','email_from','unknown@unknown.com');
+INSERT INTO {vars} VALUES (NULL,'gallery','email_reply_to','unknown@unknown.com');
INSERT INTO {vars} VALUES (NULL,'gallery','choose_default_tookit','1');
INSERT INTO {vars} VALUES (NULL,'gallery','email_line_length','70');
INSERT INTO {vars} VALUES (NULL,'gallery','email_header_separator','s:1:\"\n\";');
+INSERT INTO {vars} VALUES (NULL,'gallery','show_user_profiles_to','registered_users');
+INSERT INTO {vars} VALUES (NULL,'gallery','extra_binary_paths','/usr/local/bin:/opt/local/bin:/opt/bin');
+INSERT INTO {vars} VALUES (NULL,'comment','spam_caught','0');
INSERT INTO {vars} VALUES (NULL,'comment','access_permissions','everybody');
INSERT INTO {vars} VALUES (NULL,'gallery','blocks_site_sidebar','a:4:{i:9;a:2:{i:0;s:7:\"gallery\";i:1;s:8:\"language\";}i:10;a:2:{i:0;s:4:\"info\";i:1;s:8:\"metadata\";}i:11;a:2:{i:0;s:3:\"rss\";i:1;s:9:\"rss_feeds\";}i:12;a:2:{i:0;s:3:\"tag\";i:1;s:3:\"tag\";}}');
INSERT INTO {vars} VALUES (NULL,'gallery','identity_provider','user');
-INSERT INTO {vars} VALUES (NULL,'comment','spam_caught','0');
INSERT INTO {vars} VALUES (NULL,'user','mininum_password_length','5');
INSERT INTO {vars} VALUES (NULL,'rest','allow_guest_access','0');
INSERT INTO {vars} VALUES (NULL,'slideshow','max_scale','0');
diff --git a/lib/gallery.common.js b/lib/gallery.common.js
index a8b237bf..2dbd7c7c 100644
--- a/lib/gallery.common.js
+++ b/lib/gallery.common.js
@@ -24,8 +24,12 @@
if (container == null) {
container = 'div';
}
- $(this).html("<" + container + " class=\"g-valign\">" + $(this).html() + "</" + container + ">");
- var el = $(this).children(container + ".g-valign");
+ var el = $(this).find(".g-valign");
+ if (!el.length) {
+ $(this).html("<" + container + " class=\"g-valign\">" + $(this).html() +
+ "</" + container + ">");
+ el = $(this).children(container + ".g-valign");
+ }
var elh = $(el).height();
var ph = $(this).height();
var nh = (ph - elh) / 2;
@@ -119,29 +123,32 @@
};
// Ajax handler for replacing an image, used in Ajax thumbnail rotation
- $.gallery_replace_image = function(data, thumb) {
- $(thumb).attr({src: data.src, width: data.width, height: data.height});
+ $.gallery_replace_image = function(data, img_selector) {
+ $(img_selector).attr({src: data.src, width: data.width, height: data.height});
+ $(img_selector).trigger("gallery.change");
};
// Initialize context menus
$.fn.gallery_context_menu = function() {
if ($(".g-context-menu li").length) {
- var hover_target = ".g-context-menu";
- var in_progress = 0;
- $(hover_target + " *").removeAttr('title');
- $(hover_target + " ul").hide();
- $(hover_target).hover(
+ var hover_target = $(this).find(".g-context-menu");
+ if (hover_target.attr("context_menu_initialized")) {
+ return;
+ }
+ var list = $(hover_target).find("ul");
+ hover_target.find("*").removeAttr('title');
+ list.hide();
+ hover_target.hover(
function() {
- if (in_progress == 0) {
- $(this).find("ul").slideDown("fast", function() { in_progress = 1; });
- $(this).find(".g-dialog-link").gallery_dialog();
- $(this).find(".g-ajax-link").gallery_ajax();
- }
+ list.stop(true, true).slideDown("fast");
+ $(this).find(".g-dialog-link").gallery_dialog();
+ $(this).find(".g-ajax-link").gallery_ajax();
},
function() {
- $(this).find("ul").slideUp("slow", function() { in_progress = 0; });
+ list.stop(true, true).slideUp("slow");
}
);
+ hover_target.attr("context_menu_initialized", 1);
}
};
diff --git a/modules/comment/controllers/comments.php b/modules/comment/controllers/comments.php
index ff0e9ce1..ded9743e 100644
--- a/modules/comment/controllers/comments.php
+++ b/modules/comment/controllers/comments.php
@@ -45,6 +45,7 @@ class Comments_Controller extends Controller {
switch ($key) {
case "guest_name": $key = "name"; break;
case "guest_email": $key = "email"; break;
+ case "guest_url": $key = "url"; break;
}
$form->add_comment->inputs[$key]->add_error($error, 1);
}
diff --git a/modules/comment/helpers/comment.php b/modules/comment/helpers/comment.php
index 7aa007cb..958f2f3d 100644
--- a/modules/comment/helpers/comment.php
+++ b/modules/comment/helpers/comment.php
@@ -38,7 +38,8 @@ class comment_Core {
->error_messages("invalid", t("You must enter a valid email address"));
$group->input("url")
->label(t("Website (hidden)"))
- ->id("g-url");
+ ->id("g-url")
+ ->error_messages("url", t("You must enter a valid url"));
$group->textarea("text")
->label(t("Comment"))
->id("g-text")
diff --git a/modules/comment/helpers/comment_rss.php b/modules/comment/helpers/comment_rss.php
index 26d98d21..cc4180bf 100644
--- a/modules/comment/helpers/comment_rss.php
+++ b/modules/comment/helpers/comment_rss.php
@@ -57,13 +57,19 @@ class comment_rss_Core {
"thumb_height" => $item->thumb_height,
"thumb_width" => $item->thumb_width,
"item_uri" => url::abs_site("{$item->type}s/$item->id"),
- "title" => html::purify($item->title),
+ "title" => (
+ ($item->id == item::root()->id) ?
+ html::purify($item->title) :
+ t("%site_title - %item_title",
+ array("site_title" => item::root()->title,
+ "item_title" => $item->title))),
"author" => html::clean($comment->author_name())),
ArrayObject::ARRAY_AS_PROPS);
}
$feed->max_pages = ceil($comments->count_all() / $limit);
- $feed->title = htmlspecialchars(t("Recent Comments"));
+ $feed->title = html::purify(t("%site_title - Recent Comments",
+ array("site_title" => item::root()->title)));
$feed->uri = url::abs_site("albums/" . (empty($id) ? "1" : $id));
$feed->description = t("Recent comments");
diff --git a/modules/exif/helpers/exif_task.php b/modules/exif/helpers/exif_task.php
index a754865a..5963d03f 100644
--- a/modules/exif/helpers/exif_task.php
+++ b/modules/exif/helpers/exif_task.php
@@ -50,7 +50,7 @@ class exif_task_Core {
->where("exif_records.item_id", "IS", null)
->or_where("exif_records.dirty", "=", 1)
->close()
- ->find_all() as $item) {
+ ->find_all(100) as $item) {
// The query above can take a long time, so start the timer after its done
// to give ourselves a little time to actually process rows.
if (!isset($start)) {
@@ -60,7 +60,7 @@ class exif_task_Core {
exif::extract($item);
$completed++;
- if (microtime(true) - $start > 1.5) {
+ if (microtime(true) - $start > .75) {
break;
}
}
diff --git a/modules/g2_import/css/g2_import.css b/modules/g2_import/css/g2_import.css
deleted file mode 100644
index d53564d7..00000000
--- a/modules/g2_import/css/g2_import.css
+++ /dev/null
@@ -1,30 +0,0 @@
-#g-admin-g2-import-notes {
- padding-bottom: 20px;
-}
-
-#g-admin-g2-import-details {
- padding-top: 20px;
-}
-
-#g-admin-g2-import-details .g-warning {
- margin-top: 4px;
-}
-
-#g-admin-g2-import-details .g-info {
- padding: 2px;
- border: 1px solid #999;
- margin-bottom: 10px;
-}
-
-#g-admin-g2-import-notes p,
-#g-admin-g2-import-details .g-info p {
- padding: 0;
- margin: 0;
-}
-
-#g-admin-g2-import-notes ul li,
-#g-admin-g2-import .g-info ul li {
- padding-left: 0;
- margin-left: 20px;
- list-style-type: disc;
-}
diff --git a/modules/g2_import/helpers/g2_import.php b/modules/g2_import/helpers/g2_import.php
index c3737f8f..515eb73d 100644
--- a/modules/g2_import/helpers/g2_import.php
+++ b/modules/g2_import/helpers/g2_import.php
@@ -452,9 +452,9 @@ class g2_import_Core {
"title" => "title",
"viewCount" => "view_count");
$direction_map = array(
- 1 => "asc",
- ORDER_ASCENDING => "asc",
- ORDER_DESCENDING => "desc");
+ 1 => "ASC",
+ ORDER_ASCENDING => "ASC",
+ ORDER_DESCENDING => "DESC");
// Only consider G2's first sort order
$g2_order = explode("|", $g2_album->getOrderBy() . "");
$g2_order = $g2_order[0];
diff --git a/modules/g2_import/helpers/g2_import_theme.php b/modules/g2_import/helpers/g2_import_theme.php
deleted file mode 100644
index 788253f9..00000000
--- a/modules/g2_import/helpers/g2_import_theme.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2010 Bharat Mediratta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
- */
-class g2_import_theme_Core {
- static function head($theme) {
- $theme->css("g2_import.css");
- }
-
- static function admin_head($theme) {
- $theme->css("g2_import.css");
- }
-} \ No newline at end of file
diff --git a/modules/g2_import/views/admin_g2_import.html.php b/modules/g2_import/views/admin_g2_import.html.php
index 05cbab71..564bea9f 100644
--- a/modules/g2_import/views/admin_g2_import.html.php
+++ b/modules/g2_import/views/admin_g2_import.html.php
@@ -6,29 +6,10 @@
</p>
<div class="g-block-content">
- <div id="g-admin-g2-import-notes">
- <h2> <?= t("Notes") ?> </h2>
- <p>
- <?= t("The import process is a work in progress with some known issues:") ?>
- </p>
- <ul>
- <li>
- <?= t("Gallery 3 does not support per-user / per-item permissions. <b>Review permissions after your import is done.</b>") ?>
- </li>
- <li>
- <?= t("The only supported file formats are JPG, PNG and GIF, FLV and MP4. Other formats will be skipped.") ?>
- </li>
- <li>
- <?= t("Deactivating the <b>notification</b>, <b>search</b> and <b>exif</b> modules during your import will make it go faster.") ?>
- </li>
- <li>
- <?= t("The eAccelerator PHP performance extension is known to cause issues. If you're using eAccelerator and having problems, please disable it while you do your import. One way to do that is to put <code>php_value eaccelerator.enable 0</code> in gallery3/.htaccess") ?>
- </li>
- </ul>
- </div>
-
<?= $form ?>
+ </div>
+ <div class="g-block-content">
<? if (g2_import::is_initialized()): ?>
<div id="g-admin-g2-import-details">
<h2> <?= t("Import") ?> </h2>
@@ -53,60 +34,65 @@
"url" => html::mark_clean(url::site("admin/theme_options")))) ?>
</li>
<? endif ?>
+
+ <li class="g-info">
+ <?= t("Your Gallery 2 has the following importable data in it:") ?>
+ <p>
+ <?= t2("1 user", "%count users", $g2_stats["users"]) ?>,
+ <?= t2("1 group", "%count groups", $g2_stats["groups"]) ?>,
+ <?= t2("1 album", "%count albums", $g2_stats["albums"]) ?>,
+ <?= t2("1 photo", "%count photos", $g2_stats["photos"]) ?>,
+ <?= t2("1 movie", "%count movies", $g2_stats["movies"]) ?>,
+ <?= t2("1 comment", "%count comments", $g2_stats["comments"]) ?>,
+ <?= t2("1 tagged photo/movie/album",
+ "%count tagged photos/movies/albums", $g2_stats["tags"]) ?>
+ </p>
+ </li>
</ul>
- <div class="g-message-block g-info">
- <p>
- <?= t("Your Gallery 2 has the following importable data in it") ?>
- </p>
- <ul>
- <li>
- <?= t2("1 user", "%count users", $g2_stats["users"]) ?>
- </li>
- <li>
- <?= t2("1 group", "%count groups", $g2_stats["groups"]) ?>
- </li>
- <li>
- <?= t2("1 album", "%count albums", $g2_stats["albums"]) ?>
- </li>
+ <p>
+ <a class="g-button g-dialog-link ui-state-default ui-corner-all"
+ href="<?= url::site("admin/maintenance/start/g2_import_task::import?csrf=$csrf") ?>">
+ <?= t("Begin import!") ?>
+ </a>
+ </p>
+ </div>
+
+ <div class="g-block-content">
+ <div id="g-admin-g2-import-notes">
+ <h2> <?= t("Notes") ?> </h2>
+ <ul class="enumeration">
<li>
- <?= t2("1 photo", "%count photos", $g2_stats["photos"]) ?>
+ <?= t("Gallery 3 does not support per-user / per-item permissions. <b>Review permissions after your import is done.</b>") ?>
</li>
<li>
- <?= t2("1 movie", "%count movies", $g2_stats["movies"]) ?>
+ <?= t("The only supported file formats are JPG, PNG and GIF, FLV and MP4. Other formats will be skipped.") ?>
</li>
<li>
- <?= t2("1 comment", "%count comments", $g2_stats["comments"]) ?>
+ <?= t("Deactivating the <b>notification</b>, <b>search</b> and <b>exif</b> modules during your import will make it go faster.") ?>
</li>
<li>
- <?= t2("1 tagged photo/movie/album",
- "%count tagged photos/movies/albums", $g2_stats["tags"]) ?>
+ <?= t("The eAccelerator and XCache PHP performance extensions are known to cause issues. If you're using either of those and are having problems, please disable them while you do your import. Add the following lines: <pre>%lines</pre> to gallery3/.htaccess and remove them when the import is done.", array("lines" => "\n\n php_value eaccelerator.enable 0\n php_value xcache.cacher off\n php_value xcache.optimizer off\n\n")) ?>
</li>
</ul>
</div>
-
- <p>
- <a class="g-button g-dialog-link ui-state-default ui-corner-all"
- href="<?= url::site("admin/maintenance/start/g2_import_task::import?csrf=$csrf") ?>">
- <?= t("Begin import!") ?>
- </a>
- </p>
</div>
- <div>
- <h2> <?= t("Migrating from Gallery 2") ?> </h2>
- <p>
- <?= t("Once your migration is complete, put this block at the top of your gallery2/.htaccess file and all Gallery 2 urls will be redirected to Gallery 3") ?>
- </p>
+ <div class="g-block-content">
+ <div>
+ <h2> <?= t("Migrating from Gallery 2") ?> </h2>
+ <p>
+ <?= t("Once your migration is complete, put this block at the top of your gallery2/.htaccess file and all Gallery 2 urls will be redirected to Gallery 3") ?>
+ </p>
- <code>
- &lt;IfModule mod_rewrite.c&gt;<br/>
- RewriteEngine On<br/>
- RewriteBase <?= html::clean(g2_import::$g2_base_url) ?><br/>
- RewriteRule ^(.*)$ <?= url::site("g2/map?path=\$1") ?> [QSA,L,R=301]<br/>
- &lt;/IfModule&gt;<br/>
- </code>
+ <textarea rows="4" cols="60">&lt;IfModule mod_rewrite.c&gt;
+ Options +FollowSymLinks
+ RewriteEngine On
+ RewriteBase <?= html::clean(g2_import::$g2_base_url) ?>
+ RewriteRule ^(.*)$ <?= url::site("g2/map?path=\$1") ?> [QSA,L,R=301]
+&lt;/IfModule&gt;</textarea>
+ </div>
+ <? endif ?>
</div>
- <? endif ?>
</div>
</div>
diff --git a/modules/gallery/controllers/admin_modules.php b/modules/gallery/controllers/admin_modules.php
index f5af9a5a..650b7e9e 100644
--- a/modules/gallery/controllers/admin_modules.php
+++ b/modules/gallery/controllers/admin_modules.php
@@ -95,12 +95,17 @@ class Admin_Modules_Controller extends Admin_Controller {
$activated_names[] = t($info->name);
}
} catch (Exception $e) {
+ message::warning(t("An error occurred while installing the <b>%module_name</b> module",
+ array("module_name" => $info->name)));
Kohana_Log::add("error", (string)$e);
}
}
module::event("module_change", $changes);
+ // If modules need upgrading, this will get recreated
+ site_status::clear("upgrade_now");
+
// @todo this type of collation is questionable from an i18n perspective
if ($activated_names) {
message::success(t("Activated: %names", array("names" => join(", ", $activated_names))));
diff --git a/modules/gallery/controllers/items.php b/modules/gallery/controllers/items.php
index f205bf86..39b0f638 100644
--- a/modules/gallery/controllers/items.php
+++ b/modules/gallery/controllers/items.php
@@ -31,4 +31,13 @@ class Items_Controller extends Controller {
access::required("view", $item);
url::redirect($item->abs_url());
}
+
+ // Return the width/height dimensinons for the given item
+ public function dimensions($id) {
+ $item = ORM::factory("item", $id);
+ access::required("view", $item);
+ json::reply(array("thumb" => array((int)$item->thumb_width, (int)$item->thumb_height),
+ "resize" => array((int)$item->resize_width, (int)$item->resize_height),
+ "full" => array((int)$item->width, (int)$item->height)));
+ }
}
diff --git a/modules/gallery/controllers/quick.php b/modules/gallery/controllers/quick.php
index c34209da..3db4f5df 100644
--- a/modules/gallery/controllers/quick.php
+++ b/modules/gallery/controllers/quick.php
@@ -36,7 +36,8 @@ class Quick_Controller extends Controller {
}
if ($degrees) {
- $tmpfile = tempnam(TMPPATH, "rotate");
+ $tmpfile = tempnam(TMPPATH, "rotate") . "." .
+ pathinfo($item->file_path(), PATHINFO_EXTENSION);
gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $degrees));
$item->set_data_file($tmpfile);
$item->save();
diff --git a/modules/gallery/controllers/reauthenticate.php b/modules/gallery/controllers/reauthenticate.php
index 0486c0fe..53a96374 100644
--- a/modules/gallery/controllers/reauthenticate.php
+++ b/modules/gallery/controllers/reauthenticate.php
@@ -19,12 +19,19 @@
*/
class Reauthenticate_Controller extends Controller {
public function index() {
+ $is_ajax = Session::instance()->get_once("is_ajax_request", request::is_ajax());
if (!identity::active_user()->admin) {
- access::forbidden();
+ if ($is_ajax) {
+ // We should never be able to get here since Admin_Controller::_reauth_check() won't work
+ // for non-admins.
+ access::forbidden();
+ } else {
+ url::redirect(item::root()->abs_url());
+ }
}
+
// On redirects from the admin controller, the ajax request indicator is lost,
// so we store it in the session.
- $is_ajax = Session::instance()->get_once("is_ajax_request", request::is_ajax());
if ($is_ajax) {
$v = new View("reauthenticate.html");
$v->form = self::_form();
diff --git a/modules/gallery/controllers/upgrader.php b/modules/gallery/controllers/upgrader.php
index cb940b46..b2646874 100644
--- a/modules/gallery/controllers/upgrader.php
+++ b/modules/gallery/controllers/upgrader.php
@@ -39,10 +39,12 @@ class Upgrader_Controller extends Controller {
}
}
+ $failed = Input::instance()->get("failed");
$view = new View("upgrader.html");
$view->can_upgrade = identity::active_user()->admin || $session->get("can_upgrade");
$view->upgrade_token = $upgrade_token;
$view->available = module::available();
+ $view->failed = $failed ? explode(",", $failed) : array();
$view->done = $available_upgrades == 0;
print $view;
}
@@ -52,8 +54,16 @@ class Upgrader_Controller extends Controller {
// @todo this may screw up some module installers, but we don't have a better answer at
// this time.
$_SERVER["HTTP_HOST"] = "example.com";
- } else if (!identity::active_user()->admin && !Session::instance()->get("can_upgrade", false)) {
- access::forbidden();
+ } else {
+ if (!identity::active_user()->admin && !Session::instance()->get("can_upgrade", false)) {
+ access::forbidden();
+ }
+
+ try {
+ access::verify_csrf();
+ } catch (Exception $e) {
+ url::redirect("upgrader");
+ }
}
$available = module::available();
@@ -65,20 +75,36 @@ class Upgrader_Controller extends Controller {
}
// Then upgrade the rest
+ $failed = array();
foreach (module::available() as $id => $module) {
if ($id == "gallery") {
continue;
}
if ($module->active && $module->code_version != $module->version) {
- module::upgrade($id);
+ try {
+ module::upgrade($id);
+ } catch (Exception $e) {
+ // @todo assume it's MODULE_FAILED_TO_UPGRADE for now
+ $failed[] = $id;
+ }
}
}
+ // If the upgrade failed, this will get recreated
+ site_status::clear("upgrade_now");
+
if (php_sapi_name() == "cli") {
- print "Upgrade complete\n";
+ if ($failed) {
+ print "Upgrade completed ** WITH FAILURES **\n";
+ print "The following modules were not successfully upgraded:\n";
+ print " " . implode($failed, "\n ") . "\n";
+ print "Try getting newer versions or deactivating those modules\n";
+ } else {
+ print "Upgrade complete\n";
+ }
} else {
- url::redirect("upgrader");
+ url::redirect("upgrader?failed=" . join(",", $failed));
}
}
}
diff --git a/modules/gallery/controllers/uploader.php b/modules/gallery/controllers/uploader.php
index fb496f60..168e8b2d 100644
--- a/modules/gallery/controllers/uploader.php
+++ b/modules/gallery/controllers/uploader.php
@@ -103,11 +103,14 @@ class Uploader_Controller extends Controller {
}
public function status($success_count, $error_count) {
- // The "errors" won't be properly pluralized :-/
- print t2("Uploaded %count photo (%error errors)",
- "Uploaded %count photos (%error errors)",
- $success_count,
- array("error" => $error_count));
+ if ($error_count) {
+ // The "errors" won't be properly pluralized :-/
+ print t2("Uploaded %count photo (%error errors)",
+ "Uploaded %count photos (%error errors)",
+ $success_count,
+ array("error" => $error_count));
+ } else {
+ print t2("Uploaded %count photo", "Uploaded %count photos", $success_count);}
}
public function finish() {
diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php
index e992655b..4922416c 100644
--- a/modules/gallery/controllers/user_profile.php
+++ b/modules/gallery/controllers/user_profile.php
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class User_Profile_Controller extends Controller {
+
public function show($id) {
// If we get here, then we should have a user id other than guest.
$user = identity::lookup_user($id);
@@ -25,6 +26,10 @@ class User_Profile_Controller extends Controller {
throw new Kohana_404_Exception();
}
+ if (!$this->_can_view_profile_pages($user)) {
+ throw new Kohana_404_Exception();
+ }
+
$v = new Theme_View("page.html", "other", "profile");
$v->page_title = t("%name Profile", array("name" => $user->display_name()));
$v->content = new View("user_profile.html");
@@ -44,12 +49,20 @@ class User_Profile_Controller extends Controller {
public function contact($id) {
$user = identity::lookup_user($id);
+ if (!$this->_can_view_profile_pages($user)) {
+ throw new Kohana_404_Exception();
+ }
+
print user_profile::get_contact_form($user);
}
public function send($id) {
access::verify_csrf();
$user = identity::lookup_user($id);
+ if (!$this->_can_view_profile_pages($user)) {
+ throw new Kohana_404_Exception();
+ }
+
$form = user_profile::get_contact_form($user);
if ($form->validate()) {
Sendmail::factory()
@@ -66,4 +79,30 @@ class User_Profile_Controller extends Controller {
json::reply(array("result" => "error", "html" => (string)$form));
}
}
+
+ private function _can_view_profile_pages($user) {
+ if (!$user->loaded()) {
+ return false;
+ }
+
+ if ($user->id == identity::active_user()->id) {
+ // You can always view your own profile
+ return true;
+ }
+
+ switch (module::get_var("gallery", "show_user_profiles_to")) {
+ case "admin_users":
+ return identity::active_user()->admin;
+
+ case "registered_users":
+ return !identity::active_user()->guest;
+
+ case "everybody":
+ return true;
+
+ default:
+ // Fail in private mode on an invalid setting
+ return false;
+ }
+ }
}
diff --git a/modules/gallery/css/upgrader.css b/modules/gallery/css/upgrader.css
index d1b74c31..8610016e 100644
--- a/modules/gallery/css/upgrader.css
+++ b/modules/gallery/css/upgrader.css
@@ -58,6 +58,10 @@ tr.upgradeable td.gallery {
color: #00d;
}
+tr.failed td {
+ color: red;
+}
+
p {
font-size: .9em;
}
@@ -120,12 +124,28 @@ div#dialog div {
opacity: 0.5;
}
+.failed {
+ color: red;
+}
+
pre {
display: inline;
margin: 0px;
padding: 0px;
}
+div#upgrade_button {
+ margin-bottom: 20px;
+}
+
+div#welcome_message {
+ margin-left: 30px;
+}
+
+#logo {
+ margin-left: 14px;
+}
+
.rtl {
direction: rtl;
}
@@ -153,3 +173,11 @@ pre {
.rtl div#dialog a.close {
float: left;
}
+
+.rtl div#welcome_message {
+ padding-right: 30px;
+}
+
+.rtl #logo {
+ padding-right: 12px;
+}
diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php
index f1ea00c0..52a36298 100644
--- a/modules/gallery/helpers/access.php
+++ b/modules/gallery/helpers/access.php
@@ -263,15 +263,15 @@ class access_Core {
}
/**
- * Recalculate the permissions for a given item and its hierarchy. $item must be an album.
+ * Recalculate the permissions for an album's hierarchy.
*/
- static function recalculate_permissions($item) {
+ static function recalculate_album_permissions($album) {
foreach (self::_get_all_groups() as $group) {
foreach (ORM::factory("permission")->find_all() as $perm) {
if ($perm->name == "view") {
- self::_update_access_view_cache($group, $item);
+ self::_update_access_view_cache($group, $album);
} else {
- self::_update_access_non_view_cache($group, $perm->name, $item);
+ self::_update_access_non_view_cache($group, $perm->name, $album);
}
}
}
@@ -279,6 +279,28 @@ class access_Core {
}
/**
+ * Recalculate the permissions for a single photo.
+ */
+ static function recalculate_photo_permissions($photo) {
+ $parent = $photo->parent();
+ $parent_access_cache = ORM::factory("access_cache")->where("item_id", "=", $parent->id)->find();
+ $photo_access_cache = ORM::factory("access_cache")->where("item_id", "=", $photo->id)->find();
+ foreach (self::_get_all_groups() as $group) {
+ foreach (ORM::factory("permission")->find_all() as $perm) {
+ $field = "{$perm->name}_{$group->id}";
+ if ($perm->name == "view") {
+ $photo->$field = $parent->$field;
+ } else {
+ $photo_access_cache->$field = $parent_access_cache->$field;
+ }
+ }
+ }
+ $photo_access_cache->save();
+ $photo->save();
+ model_cache::clear();
+ }
+
+ /**
* Register a permission so that modules can use it.
*
* @param string $name The internal name for for this permission
@@ -694,6 +716,7 @@ class access_Core {
@mkdir(VARPATH . "security_test");
try {
if ($fp = @fopen(VARPATH . "security_test/.htaccess", "w+")) {
+ fwrite($fp, "Options +FollowSymLinks\n");
fwrite($fp, "RewriteEngine On\n");
fwrite($fp, "RewriteRule verify $success_url [L]\n");
fclose($fp);
diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php
index 0ac5e8b0..89185e50 100644
--- a/modules/gallery/helpers/album.php
+++ b/modules/gallery/helpers/album.php
@@ -114,6 +114,7 @@ class album_Core {
"captured" => t("Date captured"),
"created" => t("Date uploaded"),
"title" => t("Title"),
+ "name" => t("File name"),
"updated" => t("Date modified"),
"view_count" => t("Number of views"),
"rand_key" => t("Random"));
diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php
index 3f83b23d..ca8c92c9 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -37,6 +37,30 @@ class gallery_Core {
}
/**
+ * If the gallery is only available to registered users and the user is not logged in, present
+ * the login page.
+ */
+ static function private_gallery() {
+ if (Router::$controller != "login" &&
+ Router::$controller != "combined" &&
+ identity::active_user()->guest &&
+ !access::user_can(identity::guest(), "view", item::root()) &&
+ php_sapi_name() != "cli") {
+ if (Router::$controller == "admin") {
+ // At this point we're in the admin theme and it doesn't have a themed login page, so
+ // we can't just swap in the login controller and have it work. So redirect back to the
+ // root item where we'll run this code again with the site theme.
+ url::redirect(item::root()->abs_url());
+ } else {
+ Session::instance()->set("continue_url", url::abs_current());
+ Router::$controller = "login";
+ Router::$controller_path = MODPATH . "gallery/controllers/login.php";
+ Router::$method = "html";
+ }
+ }
+ }
+
+ /**
* This function is called when the Gallery is fully initialized. We relay it to modules as the
* "gallery_ready" event. Any module that wants to perform an action at the start of every
* request should implement the <module>_event::gallery_ready() handler.
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index df5394c9..b59bb9b9 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -63,6 +63,8 @@ class gallery_event_Core {
->update("logs")
->set("user_id", $admin->id)
->execute();
+ module::set_var("gallery", "email_from", $admin->email);
+ module::set_var("gallery", "email_reply_to", $admin->email);
}
static function group_created($group) {
@@ -116,8 +118,8 @@ class gallery_event_Core {
$batch_missing_album_cover[$parent->id] = 1;
Session::instance()->set("batch_missing_album_cover", $batch_missing_album_cover);
} else {
- // Choose the first child as the new cover.
- if ($child = $parent->children(1)->current()) {
+ // Choose the first viewable child as the new cover.
+ if ($child = $parent->viewable()->children(1)->current()) {
item::make_album_cover($child);
}
}
@@ -155,7 +157,11 @@ class gallery_event_Core {
}
static function item_moved($item, $old_parent) {
- access::recalculate_permissions($item->parent());
+ if ($item->is_album()) {
+ access::recalculate_album_permissions($item->parent());
+ } else {
+ access::recalculate_photo_permissions($item);
+ }
// If the new parent doesn't have an album cover, make this it.
if (!$item->parent()->album_cover_item_id) {
@@ -208,10 +214,10 @@ class gallery_event_Core {
->label($user->display_name()));
if (Router::$controller == "admin") {
- $continue_url = url::site("");
- } else if (isset($theme->item)) {
+ $continue_url = url::abs_site("");
+ } else if ($item = $theme->item()) {
if (access::user_can(identity::guest(), "view", $theme->item)) {
- $continue_url = $theme->item->abs_url();
+ $continue_url = $item->abs_url();
} else {
$continue_url = item::root()->abs_url();
}
@@ -547,4 +553,17 @@ class gallery_event_Core {
$data->content[] = (object) array("title" => t("User information"), "view" => $v);
}
+
+ static function user_updated($original_user, $updated_user) {
+ // If the default from/reply-to email address is set to the install time placeholder value
+ // of unknown@unknown.com then adopt the value from the first admin to set their own email
+ // address so that we at least have a valid address for the Gallery.
+ if ($updated_user->admin) {
+ $email = module::get_var("gallery", "email_from", "");
+ if ($email == "unknown@unknown.com") {
+ module::set_var("gallery", "email_from", $updated_user->email);
+ module::set_var("gallery", "email_reply_to", $updated_user->email);
+ }
+ }
+ }
}
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index d5264fcc..83961d6b 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -302,14 +302,14 @@ class gallery_installer {
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");
-
- // Sendmail configuration
- module::set_var("gallery", "email_from", "admin@example.com");
- module::set_var("gallery", "email_reply_to", "public@example.com");
+ module::set_var("gallery", "email_from", "");
+ module::set_var("gallery", "email_reply_to", "");
module::set_var("gallery", "email_line_length", 70);
module::set_var("gallery", "email_header_separator", serialize("\n"));
+ module::set_var("gallery", "show_user_profiles_to", "registered_users");
+ module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin");
- module::set_version("gallery", 37);
+ module::set_version("gallery", 40);
}
static function upgrade($version) {
@@ -550,7 +550,9 @@ class gallery_installer {
}
if ($version == 26) {
- $db->query("RENAME TABLE {failed_logins} TO {failed_auths}");
+ if (in_array("failed_logins", Database::instance()->list_tables())) {
+ $db->query("RENAME TABLE {failed_logins} TO {failed_auths}");
+ }
module::set_version("gallery", $version = 27);
}
@@ -611,6 +613,30 @@ class gallery_installer {
module::set_var("gallery", "email_header_separator", serialize("\n"));
module::set_version("gallery", $version = 37);
}
+
+ // Changed our minds and decided that the initial value should be empty
+ // But don't just reset it blindly, only do it if the value is version 37 default
+ if ($version == 37) {
+ $email = module::get_var("gallery", "email_from", "");
+ if ($email == "admin@example.com") {
+ module::set_var("gallery", "email_from", "");
+ }
+ $email = module::get_var("gallery", "email_reply_to", "");
+ if ($email == "admin@example.com") {
+ module::set_var("gallery", "email_reply_to", "");
+ }
+ module::set_version("gallery", $version = 38);
+ }
+
+ if ($version == 38) {
+ module::set_var("gallery", "show_user_profiles_to", "registered_users");
+ module::set_version("gallery", $version = 39);
+ }
+
+ if ($version == 39) {
+ module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin");
+ module::set_version("gallery", $version = 40);
+ }
}
static function uninstall() {
diff --git a/modules/gallery/helpers/gallery_rss.php b/modules/gallery/helpers/gallery_rss.php
index bec34912..fb617934 100644
--- a/modules/gallery/helpers/gallery_rss.php
+++ b/modules/gallery/helpers/gallery_rss.php
@@ -40,7 +40,7 @@ class gallery_rss_Core {
->order_by("created", "DESC");
$feed->max_pages = ceil($all_items->find_all()->count() / $limit);
- $feed->title = t("Recent updates");
+ $feed->title = t("%site_title - Recent updates", array("site_title" => item::root()->title));
$feed->description = t("Recent updates");
return $feed;
@@ -53,7 +53,13 @@ class gallery_rss_Core {
->descendants($limit, $offset, array(array("type", "=", "photo")));
$feed->max_pages = ceil(
$item->viewable()->descendants_count(array(array("type", "=", "photo"))) / $limit);
- $feed->title = html::purify($item->title);
+ if ($item->id == item::root()->id) {
+ $feed->title = html::purify($item->title);
+ } else {
+ $feed->title = t("%site_title - %item_title",
+ array("site_title" => item::root()->title,
+ "item_title" => $item->title));
+ }
$feed->description = nl2br(html::purify($item->description));
return $feed;
diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php
index 0886aad0..3b173928 100644
--- a/modules/gallery/helpers/gallery_task.php
+++ b/modules/gallery/helpers/gallery_task.php
@@ -571,7 +571,7 @@ class gallery_task_Core {
// 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());
+ access::recalculate_album_permissions(item::root());
$state = self::FIX_STATE_DONE;
}
break;
@@ -596,7 +596,7 @@ class gallery_task_Core {
static function find_dupe_slugs() {
return db::build()
->select_distinct(
- array("parent_slug" => new Database_Expression("CONCAT(`parent_id`, ':', `slug`)")))
+ array("parent_slug" => new Database_Expression("CONCAT(`parent_id`, ':', LOWER(`slug`))")))
->select("id")
->select(array("C" => "COUNT(\"*\")"))
->from("items")
@@ -608,7 +608,7 @@ class gallery_task_Core {
static function find_dupe_names() {
return db::build()
->select_distinct(
- array("parent_name" => new Database_Expression("CONCAT(`parent_id`, ':', `name`)")))
+ array("parent_name" => new Database_Expression("CONCAT(`parent_id`, ':', LOWER(`name`))")))
->select("id")
->select(array("C" => "COUNT(\"*\")"))
->from("items")
diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php
index bb085ea5..2868a28d 100644
--- a/modules/gallery/helpers/graphics.php
+++ b/modules/gallery/helpers/graphics.php
@@ -314,9 +314,10 @@ class graphics_Core {
$toolkits->graphicsmagick->error = t("GraphicsMagick requires the <b>exec</b> function");
} else {
$graphics_path = module::get_var("gallery", "graphics_toolkit_path", null);
+ $extra_binary_paths = module::get_var("gallery", "extra_binary_paths", null);
putenv("PATH=" . getenv("PATH") . (empty($graphics_path) ? "" : ":$graphics_path") .
- ":/usr/local/bin:/opt/local/bin:/opt/bin");
+ ":" . $extra_binary_paths);
// @todo: consider refactoring the two segments below into a loop since they are so
// similar.
diff --git a/modules/gallery/helpers/identity.php b/modules/gallery/helpers/identity.php
index 5de05948..5ca024e9 100644
--- a/modules/gallery/helpers/identity.php
+++ b/modules/gallery/helpers/identity.php
@@ -233,14 +233,14 @@ class identity_Core {
/**
* @see IdentityProvider_Driver::add_user_to_group.
*/
- static function add_user_to_group($user, $group_id) {
- return IdentityProvider::instance()->add_user_to_group($user, $group_id);
+ static function add_user_to_group($user, $group) {
+ return IdentityProvider::instance()->add_user_to_group($user, $group);
}
/**
* @see IdentityProvider_Driver::remove_user_to_group.
*/
- static function remove_user_from_group($user, $group_id) {
- return IdentityProvider::instance()->remove_user_from_group($user, $group_id);
+ static function remove_user_from_group($user, $group) {
+ return IdentityProvider::instance()->remove_user_from_group($user, $group);
}
} \ No newline at end of file
diff --git a/modules/gallery/helpers/locales.php b/modules/gallery/helpers/locales.php
index aacb37ca..d1e72260 100644
--- a/modules/gallery/helpers/locales.php
+++ b/modules/gallery/helpers/locales.php
@@ -92,6 +92,7 @@ class locales_Core {
$l["ko_KR"] = "한국어"; // Korean
$l["lt_LT"] = "Lietuvių"; // Lithuanian
$l["lv_LV"] = "Latviešu"; // Latvian
+ $l["mk_MK"] = "Македонски јазик"; // Macedonian
$l["nl_NL"] = "Nederlands"; // Dutch
$l["no_NO"] = "Norsk bokmål"; // Norwegian
$l["pl_PL"] = "Polski"; // Polish
@@ -103,6 +104,7 @@ class locales_Core {
$l["sl_SI"] = "Slovenščina"; // Slovenian
$l["sr_CS"] = "Srpski"; // Serbian
$l["sv_SE"] = "Svenska"; // Swedish
+ $l["tn_ZA"] = "Setswana"; // Setswana
$l["tr_TR"] = "Türkçe"; // Turkish
$l["uk_UA"] = "українська"; // Ukrainian
$l["vi_VN"] = "Tiếng Việt"; // Vietnamese
diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php
index ca6651f1..7863520e 100644
--- a/modules/gallery/helpers/module.php
+++ b/modules/gallery/helpers/module.php
@@ -99,6 +99,10 @@ class module_Core {
$m->code_version = $m->version;
$m->version = self::get_version($module_name);
$m->locked = false;
+
+ if ($m->active && $m->version != $m->code_version) {
+ site_status::warning(t("Some of your modules are out of date. <a href=\"%upgrader_url\">Upgrade now!</a>", array("upgrader_url" => url::site("upgrader"))), "upgrade_now");
+ }
}
// Lock certain modules
@@ -139,7 +143,7 @@ class module_Core {
}
/**
- * Allow modules to indicate the impact of deactivating the specifeid module
+ * Allow modules to indicate the impact of deactivating the specified module
* @param string $module_name
* @return array an array of warning or error messages to be displayed
*/
@@ -214,10 +218,10 @@ class module_Core {
static function upgrade($module_name) {
$version_before = module::get_version($module_name);
$installer_class = "{$module_name}_installer";
+ $available = module::available();
if (method_exists($installer_class, "upgrade")) {
call_user_func_array(array($installer_class, "upgrade"), array($version_before));
} else {
- $available = module::available();
if (isset($available->$module_name->code_version)) {
module::set_version($module_name, $available->$module_name->code_version);
} else {
@@ -234,6 +238,10 @@ class module_Core {
"version_before" => $version_before,
"version_after" => $version_after)));
}
+
+ if ($version_after != $available->$module_name->code_version) {
+ throw new Exception("@todo MODULE_FAILED_TO_UPGRADE");
+ }
}
/**
@@ -448,7 +456,17 @@ class module_Core {
$cache->module_name = "gallery";
$cache->name = "_cache";
$cache->value = serialize(self::$var_cache);
- $cache->save();
+ try {
+ $cache->save();
+ } catch (Database_Exception $e) {
+ // There's a potential race condition here. Don't fail if that happens because it's
+ // bound to be transient and not a huge deal, but at least put something in the logs.
+ if (stristr($e->getMessage(), "duplicate entry")) {
+ Kohana_Log::add("error", "Failed to cache vars");
+ } else {
+ throw $e;
+ }
+ }
}
}
diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php
index 3e55eefe..50339541 100644
--- a/modules/gallery/helpers/movie.php
+++ b/modules/gallery/helpers/movie.php
@@ -86,9 +86,10 @@ class movie_Core {
static function find_ffmpeg() {
if (!($ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) || !file_exists($ffmpeg_path)) {
$graphics_path = module::get_var("gallery", "graphics_toolkit_path", null);
+ $extra_binary_paths = module::get_var("gallery", "extra_binary_paths", null);
putenv("PATH=" . getenv("PATH") . (empty($graphics_path) ? "" : ":$graphics_path") .
- ":/usr/local/bin:/opt/local/bin:/opt/bin");
+ ":" . $extra_binary_paths);
if (function_exists("exec")) {
$ffmpeg_path = exec("which ffmpeg");
}
diff --git a/modules/gallery/hooks/init_gallery.php b/modules/gallery/hooks/init_gallery.php
index 64e44b56..10a74733 100644
--- a/modules/gallery/hooks/init_gallery.php
+++ b/modules/gallery/hooks/init_gallery.php
@@ -38,6 +38,7 @@ Event::add("system.ready", array("module", "load_modules"));
Event::add("system.ready", array("gallery", "ready"));
Event::add("system.post_routing", array("url", "parse_url"));
Event::add("system.post_routing", array("gallery", "maintenance_mode"));
+Event::add("system.post_routing", array("gallery", "private_gallery"));
Event::add("system.shutdown", array("gallery", "shutdown"));
// @todo once we convert to Kohana 2.4 this doesn't have to be here
diff --git a/modules/gallery/libraries/Gallery_I18n.php b/modules/gallery/libraries/Gallery_I18n.php
index f8068eec..6cb36f07 100644
--- a/modules/gallery/libraries/Gallery_I18n.php
+++ b/modules/gallery/libraries/Gallery_I18n.php
@@ -44,7 +44,7 @@ function t($message, $options=array()) {
*/
function t2($singular, $plural, $count, $options=array()) {
return Gallery_I18n::instance()->translate(array("one" => $singular, "other" => $plural),
- array_merge($options, array("count" => $count)));
+ array_merge($options, array("count" => $count)));
}
class Gallery_I18n_Core {
@@ -175,7 +175,7 @@ class Gallery_I18n_Core {
->execute() as $row) {
$translations[$row->key] = unserialize($row->translation);
}
-
+
// Override incoming with outgoing...
foreach (db::build()
->select("key", "translation")
@@ -184,7 +184,7 @@ class Gallery_I18n_Core {
->execute() as $row) {
$translations[$row->key] = unserialize($row->translation);
}
-
+
$cache->set($cache_key, $translations, array("translation"), 0);
}
return $translations;
diff --git a/modules/gallery/libraries/Sendmail.php b/modules/gallery/libraries/Sendmail.php
index 0fa554b4..a93be736 100644
--- a/modules/gallery/libraries/Sendmail.php
+++ b/modules/gallery/libraries/Sendmail.php
@@ -35,12 +35,11 @@ class Sendmail_Core {
public function __construct() {
$this->headers = array();
- $domain = Input::instance()->server("HTTP_HOST");
- $this->from(module::get_var("gallery", "email_from", "admin@$domain"));
- $this->reply_to(module::get_var("gallery", "email_reply_to", "public@$domain"));
+ $this->from(module::get_var("gallery", "email_from", ""));
+ $this->reply_to(module::get_var("gallery", "email_reply_to", ""));
$this->line_length(module::get_var("gallery", "email_line_length", 70));
$separator = module::get_var("gallery", "email_header_separator", null);
- $this->header_separator(empty($separator) ? "\n" : deserialize($separator));
+ $this->header_separator(empty($separator) ? "\n" : unserialize($separator));
}
public function __get($key) {
diff --git a/modules/gallery/libraries/drivers/IdentityProvider.php b/modules/gallery/libraries/drivers/IdentityProvider.php
index 3e85a57b..ac2473f5 100644
--- a/modules/gallery/libraries/drivers/IdentityProvider.php
+++ b/modules/gallery/libraries/drivers/IdentityProvider.php
@@ -116,17 +116,17 @@ interface IdentityProvider_Driver {
/**
* Add the user to the specified group
- * @param User_Definition the user to add to the group
- * @param int the group_id
+ * @param User_Definition the user to add
+ * @param Group_Definition the target group
*/
- static function add_user_to_group($user, $group_id);
+ public function add_user_to_group($user, $group);
/**
* Remove the user to the specified group
- * @param User_Definition the user to add to the group
- * @param int the group id
+ * @param User_Definition the user to remove
+ * @param Group_Definition the owning group
*/
- static function remove_user_from_group($user, $group_id);
+ public function remove_user_from_group($user, $group);
} // End Identity Driver Definition
interface Group_Definition {}
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index 1db766e9..7bcf1f31 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class Item_Model extends ORM_MPTT {
+class Item_Model_Core extends ORM_MPTT {
protected $children = "items";
protected $sorting = array();
protected $data_file = null;
@@ -357,26 +357,7 @@ class Item_Model extends ORM_MPTT {
}
}
- // Randomize the name or slug if there's a conflict. Preserve the extension.
- // @todo Improve this. Random numbers are not user friendly
- $base_name = pathinfo($this->name, PATHINFO_FILENAME);
- $base_ext = pathinfo($this->name, PATHINFO_EXTENSION);
- $base_slug = $this->slug;
- while (ORM::factory("item")
- ->where("parent_id", "=", $this->parent_id)
- ->and_open()
- ->where("name", "=", $this->name)
- ->or_where("slug", "=", $this->slug)
- ->close()
- ->find()->id) {
- $rand = rand();
- if ($base_ext) {
- $this->name = "$base_name-$rand.$base_ext";
- } else {
- $this->name = "$base_name-$rand";
- }
- $this->slug = "$base_slug-$rand";
- }
+ $this->_randomize_name_or_slug_on_conflict();
parent::save();
@@ -427,6 +408,8 @@ class Item_Model extends ORM_MPTT {
$this->relative_url_cache = null;
}
+ $this->_randomize_name_or_slug_on_conflict();
+
parent::save();
// Now update the filesystem and any database caches if there were significant value
@@ -505,6 +488,33 @@ class Item_Model extends ORM_MPTT {
}
/**
+ * Check to see if there's another item that occupies the same name or slug that this item
+ * intends to use, and if so choose a new name/slug while preserving the extension.
+ * @todo Improve this. Random numbers are not user friendly
+ */
+ private function _randomize_name_or_slug_on_conflict() {
+ $base_name = pathinfo($this->name, PATHINFO_FILENAME);
+ $base_ext = pathinfo($this->name, PATHINFO_EXTENSION);
+ $base_slug = $this->slug;
+ while (ORM::factory("item")
+ ->where("parent_id", "=", $this->parent_id)
+ ->where("id", "<>", $this->id)
+ ->and_open()
+ ->where("name", "=", $this->name)
+ ->or_where("slug", "=", $this->slug)
+ ->close()
+ ->find()->id) {
+ $rand = rand();
+ if ($base_ext) {
+ $this->name = "$base_name-$rand.$base_ext";
+ } else {
+ $this->name = "$base_name-$rand";
+ }
+ $this->slug = "$base_slug-$rand";
+ }
+ }
+
+ /**
* Return the Item_Model representing the cover for this album.
* @return Item_Model or null if there's no cover
*/
@@ -530,7 +540,7 @@ class Item_Model extends ORM_MPTT {
* the first child in the album is at position 1.
*/
public function get_position($child, $where=array()) {
- if ($this->sort_order == "DESC") {
+ if (!strcasecmp($this->sort_order, "DESC")) {
$comp = ">";
} else {
$comp = "<";
@@ -975,23 +985,32 @@ class Item_Model extends ORM_MPTT {
}
unset($data["album_cover_item_id"]);
- if (access::can("view_full", $this) && !$this->is_album()) {
- $data["file_url"] = rest::url("data", $this, "full");
- }
- if (access::user_can(identity::guest(), "view_full", $this)) {
- $data["file_url_public"] = $this->file_url(true);
+ $data["web_url"] = $this->abs_url();
+
+ if (!$this->is_album()) {
+ if (access::can("view_full", $this)) {
+ $data["file_url"] = rest::url("data", $this, "full");
+ $data["file_size"] = filesize($this->file_path());
+ }
+ if (access::user_can(identity::guest(), "view_full", $this)) {
+ $data["file_url_public"] = $this->file_url(true);
+ }
}
if ($this->is_photo()) {
$data["resize_url"] = rest::url("data", $this, "resize");
+ $data["resize_size"] = filesize($this->resize_path());
if (access::user_can(identity::guest(), "view", $this)) {
$data["resize_url_public"] = $this->resize_url(true);
}
}
- $data["thumb_url"] = rest::url("data", $this, "thumb");
- if (access::user_can(identity::guest(), "view", $this)) {
- $data["thumb_url_public"] = $this->thumb_url(true);
+ if ($this->has_thumb()) {
+ $data["thumb_url"] = rest::url("data", $this, "thumb");
+ $data["thumb_size"] = filesize($this->thumb_path());
+ if (access::user_can(identity::guest(), "view", $this)) {
+ $data["thumb_url_public"] = $this->thumb_url(true);
+ }
}
$data["can_edit"] = access::can("edit", $this);
diff --git a/modules/gallery/module.info b/modules/gallery/module.info
index 901158b5..1155ddf7 100644
--- a/modules/gallery/module.info
+++ b/modules/gallery/module.info
@@ -1,3 +1,3 @@
name = "Gallery 3"
description = "Gallery core application"
-version = 37
+version = 40
diff --git a/modules/gallery/tests/Access_Helper_Test.php b/modules/gallery/tests/Access_Helper_Test.php
index c092e3fd..32b3020f 100644
--- a/modules/gallery/tests/Access_Helper_Test.php
+++ b/modules/gallery/tests/Access_Helper_Test.php
@@ -359,11 +359,13 @@ class Access_Helper_Test extends Gallery_Unit_Test_Case {
$public_album = test::random_album();
$public_photo = test::random_photo($public_album);
access::allow(identity::everybody(), "view", $public_album);
+ access::allow(identity::everybody(), "edit", $public_album);
item::root()->reload(); // Account for MPTT changes
$private_album = test::random_album();
access::deny(identity::everybody(), "view", $private_album);
+ access::deny(identity::everybody(), "edit", $private_album);
$private_photo = test::random_photo($private_album);
// Make sure that we now have a public photo and private photo.
@@ -385,6 +387,8 @@ class Access_Helper_Test extends Gallery_Unit_Test_Case {
// Make sure that the public_photo is now private, and the private_photo is now public.
$this->assert_false(access::group_can(identity::everybody(), "view", $public_photo));
+ $this->assert_false(access::group_can(identity::everybody(), "edit", $public_photo));
$this->assert_true(access::group_can(identity::everybody(), "view", $private_photo));
+ $this->assert_true(access::group_can(identity::everybody(), "edit", $private_photo));
}
}
diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php
index bd123098..90c54e3c 100644
--- a/modules/gallery/tests/Item_Model_Test.php
+++ b/modules/gallery/tests/Item_Model_Test.php
@@ -136,20 +136,17 @@ class Item_Model_Test extends Gallery_Unit_Test_Case {
$this->assert_true(false, "Shouldn't get here");
}
- public function item_rename_fails_with_existing_name_test() {
+ public function item_rename_over_existing_name_gets_uniqified_test() {
// Create a test photo
$item = test::random_photo();
$item2 = test::random_photo();
- try {
- $item->name = $item2->name;
- $item->save();
- } catch (ORM_Validation_Exception $e) {
- $this->assert_true(in_array("conflict", $e->validation->errors()));
- return;
- }
+ $item->name = $item2->name;
+ $item->save();
- $this->assert_false(true, "rename should conflict");
+ // foo.jpg should become foo-####.jpg
+ $this->assert_true(
+ preg_match("/" . str_replace(".jpg", "", $item2->name) . "-\d+\.jpg/", $item->name));
}
public function move_album_test() {
@@ -208,24 +205,21 @@ class Item_Model_Test extends Gallery_Unit_Test_Case {
$this->assert_equal("file", file_get_contents($photo->file_path()));
}
- public function move_album_fails_conflicting_target_test() {
+ public function move_album_with_conflicting_target_gets_uniqified_test() {
$album = test::random_album();
$source = test::random_album_unsaved($album);
$source->name = $album->name;
$source->save();
// $source and $album have the same name, so if we move $source into the root they should
- // conflict.
+ // conflict and get randomized
- try {
- $source->parent_id = item::root()->id;
- $source->save();
- } catch (ORM_Validation_Exception $e) {
- $this->assert_equal(
- array("name" => "conflict", "slug" => "conflict"), $e->validation->errors());
- return;
- }
- $this->assert_true(false, "Shouldn't get here");
+ $source->parent_id = item::root()->id;
+ $source->save();
+
+ // foo should become foo-####
+ $this->assert_true(preg_match("/{$album->name}-\d+/", $source->name));
+ $this->assert_true(preg_match("/{$album->slug}-\d+/", $source->slug));
}
public function move_album_fails_wrong_target_type_test() {
@@ -245,7 +239,7 @@ class Item_Model_Test extends Gallery_Unit_Test_Case {
$this->assert_true(false, "Shouldn't get here");
}
- public function move_photo_fails_conflicting_target_test() {
+ public function move_photo_with_conflicting_target_gets_uniqified_test() {
$photo1 = test::random_photo();
$album = test::random_album();
$photo2 = test::random_photo_unsaved($album);
@@ -253,18 +247,17 @@ class Item_Model_Test extends Gallery_Unit_Test_Case {
$photo2->save();
// $photo1 and $photo2 have the same name, so if we move $photo1 into the root they should
- // conflict.
+ // conflict and get uniqified.
- try {
- $photo2->parent_id = item::root()->id;
- $photo2->save();
- } catch (Exception $e) {
- // pass
- $this->assert_equal(
- array("name" => "conflict", "slug" => "conflict"), $e->validation->errors());
- return;
- }
- $this->assert_true(false, "Shouldn't get here");
+ $photo2->parent_id = item::root()->id;
+ $photo2->save();
+
+ // foo.jpg should become foo-####.jpg
+ $this->assert_true(
+ preg_match("/" . str_replace(".jpg", "", $photo1->name) . "-\d+\.jpg/", $photo2->name));
+
+ // foo should become foo
+ $this->assert_true(preg_match("/{$photo1->slug}/", $photo2->name));
}
public function move_album_inside_descendent_fails_test() {
diff --git a/modules/gallery/tests/Sendmail_Test.php b/modules/gallery/tests/Sendmail_Test.php
index 92974e5c..aee6abf5 100644
--- a/modules/gallery/tests/Sendmail_Test.php
+++ b/modules/gallery/tests/Sendmail_Test.php
@@ -19,24 +19,18 @@
*/
class Sendmail_Test extends Gallery_Unit_Test_Case {
public function setup() {
- Kohana_Config::instance()->set("sendmail.from", "from@gallery3.com");
+ module::set_var("gallery", "email_from", "from@gallery3.com");
+ module::set_var("gallery", "email_reply_to", "reply_to@gallery3.com");
}
- public function sendmail_test() {
- $domain = Input::instance()->server("HTTP_HOST");
+ public function sendmail_basic_test() {
$expected = "To: receiver@someemail.com\r\n" .
"From: from@gallery3.com\n" .
- "Reply-To: public@$domain\r\n" .
+ "Reply-To: reply_to@gallery3.com\r\n" .
"Subject: Test Email Unit test\r\n\r\n" .
"The mail message body";
$result = Sendmail_For_Test::factory()
->to("receiver@someemail.com")
- /*
- * @todo figure out why this test fails so badly, when the following
- * line is not supplied. It doesn't seem to be set by setup method
- * as you would expect.
- */
- ->from("from@gallery3.com")
->subject("Test Email Unit test")
->message("The mail message body")
->send()
@@ -46,16 +40,15 @@ class Sendmail_Test extends Gallery_Unit_Test_Case {
}
public function sendmail_reply_to_test() {
- $domain = Input::instance()->server("HTTP_HOST");
$expected = "To: receiver@someemail.com\r\n" .
- "From: admin@$domain\n" .
- "Reply-To: reply-to@gallery3.com\r\n" .
+ "From: from@gallery3.com\n" .
+ "Reply-To: reply_to@gallery3.com\r\n" .
"Subject: Test Email Unit test\r\n\r\n" .
"The mail message body";
$result = Sendmail_For_Test::factory()
->to("receiver@someemail.com")
->subject("Test Email Unit test")
- ->reply_to("reply-to@gallery3.com")
+ ->reply_to("reply_to@gallery3.com")
->message("The mail message body")
->send()
->send_text;
@@ -63,10 +56,9 @@ class Sendmail_Test extends Gallery_Unit_Test_Case {
}
public function sendmail_html_message_test() {
- $domain = Input::instance()->server("HTTP_HOST");
$expected = "To: receiver@someemail.com\r\n" .
- "From: admin@$domain\n" .
- "Reply-To: public@$domain\n" .
+ "From: from@gallery3.com\n" .
+ "Reply-To: reply_to@gallery3.com\n" .
"MIME-Version: 1.0\n" .
"Content-Type: text/html; charset=UTF-8\r\n" .
"Subject: Test Email Unit test\r\n\r\n" .
@@ -85,8 +77,8 @@ class Sendmail_Test extends Gallery_Unit_Test_Case {
public function sendmail_wrapped_message_test() {
$domain = Input::instance()->server("HTTP_HOST");
$expected = "To: receiver@someemail.com\r\n" .
- "From: admin@$domain\n" .
- "Reply-To: public@$domain\r\n" .
+ "From: from@gallery3.com\n" .
+ "Reply-To: reply_to@gallery3.com\r\n" .
"Subject: Test Email Unit test\r\n\r\n" .
"This is a long message that needs to go\n" .
"over forty characters If we get lucky we\n" .
diff --git a/modules/gallery/tests/controller_auth_data.txt b/modules/gallery/tests/controller_auth_data.txt
index 8b776fb9..03032fd9 100644
--- a/modules/gallery/tests/controller_auth_data.txt
+++ b/modules/gallery/tests/controller_auth_data.txt
@@ -15,8 +15,9 @@ modules/gallery/controllers/login.php html
modules/gallery/controllers/login.php auth_html DIRTY_AUTH
modules/gallery/controllers/logout.php index DIRTY_AUTH
modules/gallery/controllers/quick.php form_edit DIRTY_CSRF
-modules/gallery/controllers/upgrader.php index DIRTY_AUTH
+modules/gallery/controllers/upgrader.php index DIRTY_CSRF|DIRTY_AUTH
modules/gallery/controllers/uploader.php start DIRTY_AUTH
+modules/gallery/controllers/uploader.php status DIRTY_AUTH
modules/gallery/controllers/uploader.php finish DIRTY_AUTH
modules/gallery/controllers/user_profile.php show DIRTY_AUTH
modules/gallery/controllers/user_profile.php contact DIRTY_AUTH
diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt
index 3eae3d07..6821c963 100644
--- a/modules/gallery/tests/xss_data.txt
+++ b/modules/gallery/tests/xss_data.txt
@@ -42,7 +42,7 @@ modules/digibug/views/digibug_form.html.php 4 DIRTY form::
modules/digibug/views/digibug_form.html.php 6 DIRTY form::hidden($key,$value)
modules/exif/views/exif_dialog.html.php 14 DIRTY $details[$i]["caption"]
modules/exif/views/exif_dialog.html.php 21 DIRTY $details[$i]["caption"]
-modules/g2_import/views/admin_g2_import.html.php 30 DIRTY $form
+modules/g2_import/views/admin_g2_import.html.php 9 DIRTY $form
modules/gallery/views/admin_advanced_settings.html.php 21 DIRTY_ATTR text::alternate("g-odd","g-even")
modules/gallery/views/admin_advanced_settings.html.php 22 DIRTY $var->module_name
modules/gallery/views/admin_block_log_entries.html.php 4 DIRTY_ATTR log::severity_class($entry->severity)
@@ -88,15 +88,15 @@ modules/gallery/views/admin_maintenance.html.php 87 DIRTY_ATTR $tas
modules/gallery/views/admin_maintenance.html.php 88 DIRTY gallery::date_time($task->updated)
modules/gallery/views/admin_maintenance.html.php 91 DIRTY $task->name
modules/gallery/views/admin_maintenance.html.php 106 DIRTY $task->status
-modules/gallery/views/admin_maintenance.html.php 157 DIRTY_ATTR text::alternate("g-odd","g-even")
-modules/gallery/views/admin_maintenance.html.php 157 DIRTY_ATTR $task->state=="success"?"g-success":"g-error"
-modules/gallery/views/admin_maintenance.html.php 158 DIRTY_ATTR $task->state=="success"?"g-success":"g-error"
-modules/gallery/views/admin_maintenance.html.php 159 DIRTY gallery::date_time($task->updated)
-modules/gallery/views/admin_maintenance.html.php 162 DIRTY $task->name
-modules/gallery/views/admin_maintenance.html.php 174 DIRTY $task->status
+modules/gallery/views/admin_maintenance.html.php 162 DIRTY_ATTR text::alternate("g-odd","g-even")
+modules/gallery/views/admin_maintenance.html.php 162 DIRTY_ATTR $task->state=="success"?"g-success":"g-error"
+modules/gallery/views/admin_maintenance.html.php 163 DIRTY_ATTR $task->state=="success"?"g-success":"g-error"
+modules/gallery/views/admin_maintenance.html.php 164 DIRTY gallery::date_time($task->updated)
+modules/gallery/views/admin_maintenance.html.php 167 DIRTY $task->name
+modules/gallery/views/admin_maintenance.html.php 179 DIRTY $task->status
modules/gallery/views/admin_maintenance_show_log.html.php 8 DIRTY_JS url::site("admin/maintenance/save_log/$task->id?csrf=$csrf")
modules/gallery/views/admin_maintenance_show_log.html.php 13 DIRTY $task->name
-modules/gallery/views/admin_maintenance_task.html.php 55 DIRTY $task->name
+modules/gallery/views/admin_maintenance_task.html.php 75 DIRTY $task->name
modules/gallery/views/admin_modules.html.php 51 DIRTY access::csrf_form_field()
modules/gallery/views/admin_modules.html.php 60 DIRTY_ATTR text::alternate("g-odd","g-even")
modules/gallery/views/admin_modules.html.php 63 DIRTY form::checkbox($data,'1',module::is_active($module_name))
@@ -109,7 +109,7 @@ modules/gallery/views/admin_sidebar.html.php 50 DIRTY $avail
modules/gallery/views/admin_sidebar.html.php 58 DIRTY $active
modules/gallery/views/admin_sidebar_blocks.html.php 4 DIRTY_ATTR $ref
modules/gallery/views/admin_sidebar_blocks.html.php 4 DIRTY $text
-modules/gallery/views/admin_theme_options.html.php 36 DIRTY $form
+modules/gallery/views/admin_theme_options.html.php 5 DIRTY $form
modules/gallery/views/admin_themes.html.php 3 DIRTY_JS url::site("admin/themes/choose")
modules/gallery/views/admin_themes.html.php 5 DIRTY_JS $csrf
modules/gallery/views/admin_themes.html.php 22 DIRTY $themes[$site]->name
@@ -168,10 +168,13 @@ modules/gallery/views/error_admin.html.php 284 DIRTY $var
modules/gallery/views/error_admin.html.php 285 DIRTY_ATTR $env_id
modules/gallery/views/error_admin.html.php 291 DIRTY $key
modules/gallery/views/error_admin.html.php 295 DIRTY Kohana_Exception::safe_dump($value,$key)
-modules/gallery/views/form_uploadify.html.php 9 DIRTY_JS url::file("lib/uploadify/uploadify.swf")
-modules/gallery/views/form_uploadify.html.php 10 DIRTY_JS url::site("uploader/add_photo/{$album->id}")
-modules/gallery/views/form_uploadify.html.php 14 DIRTY_JS url::file("lib/uploadify/cancel.png")
-modules/gallery/views/form_uploadify.html.php 15 DIRTY_JS $simultaneous_upload_limit
+modules/gallery/views/form_uploadify.html.php 16 DIRTY_JS url::site("uploader/status/_S/_E")
+modules/gallery/views/form_uploadify.html.php 24 DIRTY_JS $flash_minimum_version
+modules/gallery/views/form_uploadify.html.php 28 DIRTY_JS url::file("lib/uploadify/uploadify.swf")
+modules/gallery/views/form_uploadify.html.php 29 DIRTY_JS url::site("uploader/add_photo/{$album->id}")
+modules/gallery/views/form_uploadify.html.php 33 DIRTY_JS url::file("lib/uploadify/cancel.png")
+modules/gallery/views/form_uploadify.html.php 34 DIRTY_JS $simultaneous_upload_limit
+modules/gallery/views/form_uploadify.html.php 160 DIRTY_ATTR request::protocol()
modules/gallery/views/in_place_edit.html.php 2 DIRTY form::open($action,array("method"=>"post","id"=>"g-in-place-edit-form","class"=>"g-short-form"))
modules/gallery/views/in_place_edit.html.php 3 DIRTY access::csrf_form_field()
modules/gallery/views/in_place_edit.html.php 6 DIRTY form::input("input",$form["input"]," class=\"textbox\"")
@@ -207,17 +210,6 @@ modules/gallery/views/menu_dialog.html.php 5 DIRTY_JS $menu-
modules/gallery/views/menu_link.html.php 3 DIRTY $menu->css_id?"id='{$menu->css_id}'":""
modules/gallery/views/menu_link.html.php 4 DIRTY_ATTR $menu->css_class
modules/gallery/views/menu_link.html.php 5 DIRTY_JS $menu->url
-modules/gallery/views/move_browse.html.php 5 DIRTY_JS url::site("move/show_sub_tree/{$source->id}/__TARGETID__")
-modules/gallery/views/move_browse.html.php 40 DIRTY $tree
-modules/gallery/views/move_browse.html.php 44 DIRTY access::csrf_form_field()
-modules/gallery/views/move_tree.html.php 2 DIRTY $parent->thumb_img(array(),25);
-modules/gallery/views/move_tree.html.php 4 DIRTY_JS $parent->id
-modules/gallery/views/move_tree.html.php 6 DIRTY_JS $parent->id
-modules/gallery/views/move_tree.html.php 8 DIRTY_ATTR $parent->id
-modules/gallery/views/move_tree.html.php 10 DIRTY_ATTR $child->id
-modules/gallery/views/move_tree.html.php 11 DIRTY $child->thumb_img(array(),25);
-modules/gallery/views/move_tree.html.php 13 DIRTY_JS $child->id
-modules/gallery/views/move_tree.html.php 15 DIRTY_JS $child->id
modules/gallery/views/movieplayer.html.php 2 DIRTY html::anchor($item->file_url(true),"",$attrs)
modules/gallery/views/movieplayer.html.php 5 DIRTY_JS $attrs["id"]
modules/gallery/views/movieplayer.html.php 7 DIRTY_JS url::abs_file("lib/flowplayer.swf")
@@ -256,14 +248,15 @@ modules/gallery/views/permissions_form.html.php 80 DIRTY_JS $permi
modules/gallery/views/permissions_form.html.php 80 DIRTY_JS $item->id
modules/gallery/views/quick_delete_confirm.html.php 11 DIRTY $form
modules/gallery/views/reauthenticate.html.php 9 DIRTY $form
-modules/gallery/views/upgrader.html.php 59 DIRTY_ATTR $done?"muted":""
-modules/gallery/views/upgrader.html.php 63 DIRTY_ATTR $done?"muted":""
-modules/gallery/views/upgrader.html.php 71 DIRTY_ATTR $module->version==$module->code_version?"current":"upgradeable"
-modules/gallery/views/upgrader.html.php 72 DIRTY_ATTR $id
-modules/gallery/views/upgrader.html.php 76 DIRTY $module->version
-modules/gallery/views/upgrader.html.php 79 DIRTY $module->code_version
-modules/gallery/views/upgrader.html.php 101 DIRTY_ATTR $done?"muted":""
-modules/gallery/views/upgrader.html.php 104 DIRTY_ATTR $done?"muted":""
+modules/gallery/views/upgrader.html.php 76 DIRTY_ATTR $done?"muted":""
+modules/gallery/views/upgrader.html.php 94 DIRTY_ATTR $done?"muted":""
+modules/gallery/views/upgrader.html.php 102 DIRTY_ATTR $module->version==$module->code_version?"current":"upgradeable"
+modules/gallery/views/upgrader.html.php 102 DIRTY_ATTR in_array($id,$failed)?"failed":""
+modules/gallery/views/upgrader.html.php 103 DIRTY_ATTR $id
+modules/gallery/views/upgrader.html.php 107 DIRTY $module->version
+modules/gallery/views/upgrader.html.php 110 DIRTY $module->code_version
+modules/gallery/views/upgrader.html.php 120 DIRTY_ATTR $done?"muted":""
+modules/gallery/views/upgrader.html.php 123 DIRTY_ATTR $done?"muted":""
modules/gallery/views/user_languages_block.html.php 2 DIRTY form::dropdown("g-select-session-locale",$installed_locales,$selected)
modules/gallery/views/user_profile.html.php 34 DIRTY_ATTR $user->avatar_url(40,$theme->url(,true))
modules/gallery/views/user_profile.html.php 43 DIRTY $info->view
@@ -288,10 +281,11 @@ modules/organize/views/organize_dialog.html.php 93 DIRTY_JS $file_
modules/organize/views/organize_dialog.html.php 94 DIRTY_JS $sort_order
modules/organize/views/organize_dialog.html.php 95 DIRTY_JS $sort_fields
modules/organize/views/organize_dialog.html.php 96 DIRTY_JS $album->id
-modules/organize/views/organize_dialog.html.php 97 DIRTY_JS $rest_uri
-modules/organize/views/organize_dialog.html.php 98 DIRTY_JS $controller_uri
-modules/organize/views/organize_dialog.html.php 104 DIRTY_JS $flash_minimum_version="10.0.0"
-modules/organize/views/organize_dialog.html.php 122 DIRTY_JS $swf_uri
+modules/organize/views/organize_dialog.html.php 97 DIRTY_JS $selected_id
+modules/organize/views/organize_dialog.html.php 98 DIRTY_JS $rest_uri
+modules/organize/views/organize_dialog.html.php 99 DIRTY_JS $controller_uri
+modules/organize/views/organize_dialog.html.php 105 DIRTY_JS $flash_minimum_version="10.0.0"
+modules/organize/views/organize_dialog.html.php 123 DIRTY_JS $swf_uri
modules/organize/views/organize_dialog.html.php 136 DIRTY_ATTR request::protocol()
modules/recaptcha/views/admin_recaptcha.html.php 11 DIRTY $form
modules/recaptcha/views/admin_recaptcha.html.php 23 DIRTY_JS $public_key
@@ -337,23 +331,25 @@ modules/server_add/views/server_add_tree_dialog.html.php 4 DIRTY_JS url::s
modules/server_add/views/server_add_tree_dialog.html.php 21 DIRTY $tree
modules/tag/views/admin_tags.html.php 45 DIRTY_ATTR $tag->id
modules/tag/views/admin_tags.html.php 46 DIRTY $tag->count
-modules/tag/views/tag_block.html.php 25 DIRTY $cloud
-modules/tag/views/tag_block.html.php 27 DIRTY $form
+modules/tag/views/tag_block.html.php 26 DIRTY $cloud
+modules/tag/views/tag_block.html.php 28 DIRTY $form
modules/tag/views/tag_cloud.html.php 4 DIRTY_ATTR (int)(($tag->count/$max_count)*7)
modules/tag/views/tag_cloud.html.php 5 DIRTY $tag->count
modules/tag/views/tag_cloud.html.php 6 DIRTY_JS $tag->url()
modules/user/views/admin_users.html.php 3 DIRTY_JS url::site("admin/users/add_user_to_group/__USERID__/__GROUPID__?csrf=$csrf")
modules/user/views/admin_users.html.php 26 DIRTY_JS url::site("admin/users/group/__GROUPID__")
modules/user/views/admin_users.html.php 36 DIRTY_JS url::site("admin/users/remove_user_from_group/__USERID__/__GROUPID__?csrf=$csrf")
-modules/user/views/admin_users.html.php 71 DIRTY_ATTR $user->id
-modules/user/views/admin_users.html.php 71 DIRTY_ATTR text::alternate("g-odd","g-even")
-modules/user/views/admin_users.html.php 71 DIRTY_ATTR $user->admin?"g-admin":""
modules/user/views/admin_users.html.php 72 DIRTY_ATTR $user->id
-modules/user/views/admin_users.html.php 73 DIRTY_ATTR $user->avatar_url(20,$theme->url(,true))
-modules/user/views/admin_users.html.php 87 DIRTY ($user->last_login==0)?"":gallery::date($user->last_login)
-modules/user/views/admin_users.html.php 123 DIRTY_ATTR $group->id
-modules/user/views/admin_users.html.php 123 DIRTY_ATTR ($group->special?"g-default-group":"")
-modules/user/views/admin_users.html.php 125 DIRTY $v
+modules/user/views/admin_users.html.php 72 DIRTY_ATTR text::alternate("g-odd","g-even")
+modules/user/views/admin_users.html.php 72 DIRTY_ATTR $user->admin?"g-admin":""
+modules/user/views/admin_users.html.php 73 DIRTY_ATTR $user->id
+modules/user/views/admin_users.html.php 74 DIRTY_ATTR $user->avatar_url(20,$theme->url(,true))
+modules/user/views/admin_users.html.php 88 DIRTY ($user->last_login==0)?"":gallery::date($user->last_login)
+modules/user/views/admin_users.html.php 91 DIRTY db::build()->from("items")->where("owner_id","=",$user->id)->count_records()
+modules/user/views/admin_users.html.php 127 DIRTY_ATTR $group->id
+modules/user/views/admin_users.html.php 127 DIRTY_ATTR ($group->special?"g-default-group":"")
+modules/user/views/admin_users.html.php 129 DIRTY $v
+modules/user/views/admin_users_delete_user.html.php 6 DIRTY $form
modules/user/views/admin_users_group.html.php 24 DIRTY_JS $user->id
modules/user/views/admin_users_group.html.php 24 DIRTY_JS $group->id
modules/watermark/views/admin_watermarks.html.php 20 DIRTY_ATTR $width
@@ -385,10 +381,10 @@ themes/admin_wind/views/pager.html.php 37 DIRTY_JS str_re
themes/wind/views/album.html.php 16 DIRTY_ATTR $child->id
themes/wind/views/album.html.php 16 DIRTY_ATTR $item_class
themes/wind/views/album.html.php 18 DIRTY_JS $child->url()
-themes/wind/views/album.html.php 19 DIRTY $child->thumb_img(array("class"=>"g-thumbnail"))
-themes/wind/views/album.html.php 23 DIRTY_ATTR $item_class
-themes/wind/views/album.html.php 24 DIRTY_JS $child->url()
-themes/wind/views/album.html.php 42 DIRTY $theme->paginator()
+themes/wind/views/album.html.php 20 DIRTY $child->thumb_img(array("class"=>"g-thumbnail"))
+themes/wind/views/album.html.php 25 DIRTY_ATTR $item_class
+themes/wind/views/album.html.php 26 DIRTY_JS $child->url()
+themes/wind/views/album.html.php 44 DIRTY $theme->paginator()
themes/wind/views/block.html.php 3 DIRTY_ATTR $anchor
themes/wind/views/block.html.php 5 DIRTY_ATTR $css_id
themes/wind/views/block.html.php 6 DIRTY $title
@@ -410,16 +406,17 @@ themes/wind/views/page.html.php 44 DIRTY $thumb
themes/wind/views/page.html.php 81 DIRTY $header_text
themes/wind/views/page.html.php 83 DIRTY_JS item::root()->url()
themes/wind/views/page.html.php 87 DIRTY $theme->user_menu()
-themes/wind/views/page.html.php 108 DIRTY_JS $parent->url($parent==$theme->item()->parent()?"show={$theme->item()->id}":null)
-themes/wind/views/page.html.php 126 DIRTY $content
-themes/wind/views/page.html.php 132 DIRTY newView("sidebar.html")
-themes/wind/views/page.html.php 139 DIRTY $footer_text
+themes/wind/views/page.html.php 108 DIRTY_JS $parent->url($parent->id==$theme->item()->parent_id?"show={$theme->item()->id}":null)
+themes/wind/views/page.html.php 129 DIRTY $content
+themes/wind/views/page.html.php 135 DIRTY newView("sidebar.html")
+themes/wind/views/page.html.php 142 DIRTY $footer_text
themes/wind/views/paginator.html.php 33 DIRTY_JS $first_page_url
themes/wind/views/paginator.html.php 42 DIRTY_JS $previous_page_url
themes/wind/views/paginator.html.php 70 DIRTY_JS $next_page_url
themes/wind/views/paginator.html.php 79 DIRTY_JS $last_page_url
-themes/wind/views/photo.html.php 8 DIRTY_JS $theme->item()->width
-themes/wind/views/photo.html.php 8 DIRTY_JS $theme->item()->height
-themes/wind/views/photo.html.php 18 DIRTY $theme->paginator()
-themes/wind/views/photo.html.php 23 DIRTY_JS $item->file_url()
-themes/wind/views/photo.html.php 25 DIRTY $item->resize_img(array("id"=>"g-item-id-{$item->id}","class"=>"g-resize"))
+themes/wind/views/photo.html.php 7 DIRTY_JS $theme->item()->width
+themes/wind/views/photo.html.php 7 DIRTY_JS $theme->item()->height
+themes/wind/views/photo.html.php 17 DIRTY_JS url::site("items/dimensions/".$theme->item()->id)
+themes/wind/views/photo.html.php 31 DIRTY $theme->paginator()
+themes/wind/views/photo.html.php 36 DIRTY_JS $item->file_url()
+themes/wind/views/photo.html.php 38 DIRTY $item->resize_img(array("id"=>"g-item-id-{$item->id}","class"=>"g-resize"))
diff --git a/modules/gallery/views/admin_block_platform.html.php b/modules/gallery/views/admin_block_platform.html.php
index b1b8a2f9..379ab0aa 100644
--- a/modules/gallery/views/admin_block_platform.html.php
+++ b/modules/gallery/views/admin_block_platform.html.php
@@ -18,4 +18,7 @@
<li>
<?= t("Server load: %load_average", array("load_average" => $load_average)) ?>
</li>
+ <li>
+ <?= t("Graphics toolkit: %toolkit", array("toolkit" => module::get_var("gallery", "graphics_toolkit"))) ?>
+ </li>
</ul>
diff --git a/modules/gallery/views/admin_graphics.html.php b/modules/gallery/views/admin_graphics.html.php
index 3a48e087..ae76f1e1 100644
--- a/modules/gallery/views/admin_graphics.html.php
+++ b/modules/gallery/views/admin_graphics.html.php
@@ -16,6 +16,7 @@
<h1> <?= t("Graphics settings") ?> </h1>
<p>
<?= t("Gallery needs a graphics toolkit in order to manipulate your photos. Please choose one from the list below.") ?>
+ <?= t("Can't decide which toolkit to choose? <a href=\"%url\">We can help!</a>", array("url" => "http://codex.gallery2.org/Gallery3:Choosing_A_Graphics_Toolkit")) ?>
</p>
<div class="g-block-content">
diff --git a/modules/gallery/views/admin_maintenance.html.php b/modules/gallery/views/admin_maintenance.html.php
index 4bfc57f0..c28def1d 100644
--- a/modules/gallery/views/admin_maintenance.html.php
+++ b/modules/gallery/views/admin_maintenance.html.php
@@ -109,16 +109,21 @@
<?= html::clean($task->owner()->name) ?>
</td>
<td>
- <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>"
- class="g-button g-right ui-icon-left ui-state-default ui-corner-all">
- <?= t("cancel") ?>
- </a>
<? if ($task->state == "stalled"): ?>
<a class="g-dialog-link g-button ui-icon-left ui-state-default ui-corner-all"
href="<?= url::site("admin/maintenance/resume/$task->id?csrf=$csrf") ?>">
<?= t("resume") ?>
</a>
<? endif ?>
+ <? if ($task->get_log()): ?>
+ <a href="<?= url::site("admin/maintenance/show_log/$task->id?csrf=$csrf") ?>" class="g-dialog-link g-button ui-state-default ui-corner-all">
+ <?= t("view log") ?>
+ </a>
+ <? endif ?>
+ <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>"
+ class="g-button ui-icon-left ui-state-default ui-corner-all">
+ <?= t("cancel") ?>
+ </a>
</td>
</tr>
<? endforeach ?>
@@ -183,7 +188,7 @@
</a>
<? if ($task->get_log()): ?>
<a href="<?= url::site("admin/maintenance/show_log/$task->id?csrf=$csrf") ?>" class="g-dialog-link g-button ui-state-default ui-corner-all">
- <?= t("browse log") ?>
+ <?= t("view log") ?>
</a>
<? endif ?>
<? else: ?>
diff --git a/modules/gallery/views/admin_maintenance_task.html.php b/modules/gallery/views/admin_maintenance_task.html.php
index 76756b66..013ac01f 100644
--- a/modules/gallery/views/admin_maintenance_task.html.php
+++ b/modules/gallery/views/admin_maintenance_task.html.php
@@ -3,6 +3,7 @@
var target_value;
var animation = null;
var delta = 1;
+ var consecutive_error_count = 0;
animate_progress_bar = function() {
var current_value = parseInt($(".g-progress-bar div").css("width").replace("%", ""));
if (target_value > current_value) {
@@ -26,12 +27,15 @@
$.fn.gallery_hover_init();
}
+ var FAILED_MSG = <?= t("Something went wrong...sorry! <a>Retry</a> or check the task log for details")->for_js() ?>;
+ var ERROR_MSG = <?= t("Something went wrong! Trying again in a moment... (__COUNT__)")->for_js() ?>;
update = function() {
$.ajax({
url: <?= html::js_string(url::site("admin/maintenance/run/$task->id?csrf=$csrf")) ?>,
dataType: "json",
success: function(data) {
target_value = data.task.percent_complete;
+ consecutive_error_count = 0;
if (!animation) {
animate_progress_bar();
}
@@ -42,6 +46,22 @@
} else {
setTimeout(update, 100);
}
+ },
+ error: function(req, textStatus, errorThrown) {
+ if (textStatus == "timeout" || textStatus == "parsererror") {
+ consecutive_error_count++;
+ if (consecutive_error_count == 5) {
+ $("#g-status").html(FAILED_MSG);
+ $("#g-pause-button").hide();
+ $("#g-done-button").show();
+ consecutive_error_count = 0; // in case of a manual retry
+ $("#g-status a").attr("href", "javascript:update()");
+ } else {
+ $("#g-status").html(ERROR_MSG.replace("__COUNT__", consecutive_error_count));
+ // Give a little time to back off before retrying
+ setTimeout(update, 1500 * consecutive_error_count);
+ }
+ }
}
});
}
diff --git a/modules/gallery/views/form_uploadify.html.php b/modules/gallery/views/form_uploadify.html.php
index 36f5f284..893bb3b9 100644
--- a/modules/gallery/views/form_uploadify.html.php
+++ b/modules/gallery/views/form_uploadify.html.php
@@ -60,7 +60,7 @@
$("#g-add-photos-status ul").append(
"<li id=\"q" + queueID + "\" class=\"g-success\">" + fileObj.name + " - " +
<?= t("Completed")->for_js() ?> + "</li>");
- setTimeout(function() { $("#q" + queueID).slideUp("slow") }, 5000);
+ setTimeout(function() { $("#q" + queueID).slideUp("slow").remove() }, 5000);
success_count++;
update_status();
return true;
@@ -87,8 +87,8 @@
.replace("__TYPE__", errorObj.type));
}
$("#g-add-photos-status ul").append(
- "<li class=\"g-error\">" + fileObj.name + msg + "</li>");
- $("#g-uploadify" + queueID).remove();
+ "<li id=\"q" + queueID + "\" class=\"g-error\">" + fileObj.name + msg + "</li>");
+ $("#g-uploadify").uploadifyCancel(queueID);
error_count++;
update_status();
},
diff --git a/modules/gallery/views/upgrader.html.php b/modules/gallery/views/upgrader.html.php
index 0ce24ef8..1ec49c77 100644
--- a/modules/gallery/views/upgrader.html.php
+++ b/modules/gallery/views/upgrader.html.php
@@ -10,7 +10,7 @@
</head>
<body<? if (locales::is_rtl()) { echo ' class="rtl"'; } ?>>
<div id="outer">
- <img src="<?= url::file("modules/gallery/images/gallery.png") ?>" />
+ <img id="logo" src="<?= url::file("modules/gallery/images/gallery.png") ?>" />
<div id="inner">
<? if ($can_upgrade): ?>
<div id="dialog" style="visibility: hidden">
@@ -31,6 +31,12 @@
array("url" => html::mark_clean(url::base()))) ?>
</p>
</div>
+ <div id="failed" style="display: none">
+ <h1> <?= t("Some modules failed to upgrade!") ?> </h1>
+ <p>
+ <?= t("Failed modules are <span class=\"failed\">highlighted</span>. Try getting newer versions or <a href=\"%admin_modules\">deactivating those modules</a>.", array("admin_modules" => url::site("admin/modules"))) ?>
+ </p>
+ </div>
</div>
<script type="text/javascript">
$(document).ready(function() {
@@ -41,6 +47,10 @@
<? if ($done): ?>
show_done();
<? endif ?>
+
+ <? if ($failed): ?>
+ show_failed();
+ <? endif ?>
});
var show_busy = function() {
@@ -55,10 +65,31 @@
$("#done").show();
$("#dialog_close_link").show();
}
+
+ var show_failed = function() {
+ $("#dialog").css("visibility", "visible");
+ $("#failed").show();
+ $("#dialog_close_link").show();
+ }
</script>
- <p class="<?= $done ? "muted" : "" ?>">
- <?= t("Welcome to the Gallery upgrader. One click and you're done!") ?>
- </p>
+ <div id="welcome_message">
+ <p class="<?= $done ? "muted" : "" ?>">
+ <?= t("Welcome to the Gallery upgrader. One click and you're done!") ?>
+ </p>
+ </div>
+
+ <? if ($done): ?>
+ <div id="upgrade_button" class="button muted">
+ <?= t("Upgrade all") ?>
+ </div>
+ <? else: ?>
+ <div id="upgrade_button" class="button button-active">
+ <a id="upgrade_link" href="<?= url::site("upgrader/upgrade?csrf=" . access::csrf_token()) ?>">
+ <?= t("Upgrade all") ?>
+ </a>
+ </div>
+ <? endif ?>
+
<table>
<tr class="<?= $done ? "muted" : "" ?>">
<th class="name"> <?= t("Module name") ?> </th>
@@ -68,7 +99,7 @@
<? foreach ($available as $id => $module): ?>
<? if ($module->active): ?>
- <tr class="<?= $module->version == $module->code_version ? "current" : "upgradeable" ?>" >
+ <tr class="<?= $module->version == $module->code_version ? "current" : "upgradeable" ?> <?= in_array($id, $failed) ? "failed" : "" ?>" >
<td class="name <?= $id ?>">
<?= t($module->name) ?>
</td>
@@ -85,18 +116,6 @@
<? endforeach ?>
</table>
- <? if ($done): ?>
- <div class="button muted">
- <?= t("Upgrade all") ?>
- </div>
- <? else: ?>
- <div class="button button-active">
- <a id="upgrade_link" href="<?= url::site("upgrader/upgrade") ?>">
- <?= t("Upgrade all") ?>
- </a>
- </div>
- <? endif ?>
-
<? if (@$inactive): ?>
<p class="<?= $done ? "muted" : "" ?>">
<?= t("The following modules are inactive and don't require an upgrade.") ?>
diff --git a/modules/notification/helpers/notification.php b/modules/notification/helpers/notification.php
index e4212203..0564d336 100644
--- a/modules/notification/helpers/notification.php
+++ b/modules/notification/helpers/notification.php
@@ -67,7 +67,7 @@ class notification {
}
static function get_subscribers($item) {
- $subscriber_ids = array();
+ $subscriber_ids = array();
foreach (ORM::factory("subscription")
->select("user_id")
->join("items", "subscriptions.item_id", "items.id")
@@ -86,88 +86,76 @@ class notification {
$subscribers = array();
foreach ($users as $user) {
if (access::user_can($user, "view", $item) && !empty($user->email)) {
- $subscribers[$user->email] = 1;
+ $subscribers[$user->email] = $user->locale;
}
}
- return array_keys($subscribers);
+ return $subscribers;
}
static function send_item_updated($original, $item) {
- $subscribers = self::get_subscribers($item);
- if (!$subscribers) {
- return;
+ foreach (self::get_subscribers($item) as $email => $locale) {
+ $v = new View("item_updated.html");
+ $v->original = $original;
+ $v->item = $item;
+ $v->subject = $item->is_album() ?
+ t("Album \"%title\" updated", array("title" => $original->title, "locale" => $locale)) :
+ ($item->is_photo() ?
+ t("Photo \"%title\" updated", array("title" => $original->title, "locale" => $locale))
+ : t("Movie \"%title\" updated", array("title" => $original->title, "locale" => $locale)));
+ self::_notify($email, $locale, $item, $v->render(), $v->subject);
}
-
- $v = new View("item_updated.html");
- $v->original = $original;
- $v->item = $item;
- $v->subject = $item->is_album() ?
- t("Album \"%title\" updated", array("title" => $original->title)) :
- ($item->is_photo() ?
- t("Photo \"%title\" updated", array("title" => $original->title))
- : t("Movie \"%title\" updated", array("title" => $original->title)));
-
- self::_notify($subscribers, $item, $v->render(), $v->subject);
}
static function send_item_add($item) {
- $subscribers = self::get_subscribers($item);
- if (!$subscribers) {
- return;
- }
-
$parent = $item->parent();
- $v = new View("item_added.html");
- $v->item = $item;
- $v->subject = $item->is_album() ?
- t("Album \"%title\" added to \"%parent_title\"",
- array("title" => $item->title, "parent_title" => $parent->title)) :
- ($item->is_photo() ?
- t("Photo \"%title\" added to \"%parent_title\"",
- array("title" => $item->title, "parent_title" => $parent->title)) :
- t("Movie \"%title\" added to \"%parent_title\"",
- array("title" => $item->title, "parent_title" => $parent->title)));
-
- self::_notify($subscribers, $item, $v->render(), $v->subject);
+ foreach (self::get_subscribers($item) as $email => $locale) {
+ $v = new View("item_added.html");
+ $v->item = $item;
+ $v->subject = $item->is_album() ?
+ t("Album \"%title\" added to \"%parent_title\"",
+ array("title" => $item->title, "parent_title" => $parent->title, "locale" => $locale)) :
+ ($item->is_photo() ?
+ t("Photo \"%title\" added to \"%parent_title\"",
+ array("title" => $item->title, "parent_title" => $parent->title, "locale" => $locale)) :
+ t("Movie \"%title\" added to \"%parent_title\"",
+ array("title" => $item->title, "parent_title" => $parent->title, "locale" => $locale)));
+ self::_notify($email, $locale, $item, $v->render(), $v->subject);
+ }
}
static function send_item_deleted($item) {
- $subscribers = self::get_subscribers($item);
- if (!$subscribers) {
- return;
- }
-
$parent = $item->parent();
- $v = new View("item_deleted.html");
- $v->item = $item;
- $v->subject = $item->is_album() ?
- t("Album \"%title\" removed from \"%parent_title\"",
- array("title" => $item->title, "parent_title" => $parent->title)) :
- ($item->is_photo() ?
- t("Photo \"%title\" removed from \"%parent_title\"",
- array("title" => $item->title, "parent_title" => $parent->title))
- : t("Movie \"%title\" removed from \"%parent_title\"",
- array("title" => $item->title, "parent_title" => $parent->title)));
-
- self::_notify($subscribers, $item, $v->render(), $v->subject);
+ foreach (self::get_subscribers($item) as $email => $locale) {
+ $v = new View("item_deleted.html");
+ $v->item = $item;
+ $v->subject = $item->is_album() ?
+ t("Album \"%title\" removed from \"%parent_title\"",
+ array("title" => $item->title, "parent_title" => $parent->title, "locale" => $locale)) :
+ ($item->is_photo() ?
+ t("Photo \"%title\" removed from \"%parent_title\"",
+ array("title" => $item->title, "parent_title" => $parent->title, "locale" => $locale))
+ : t("Movie \"%title\" removed from \"%parent_title\"",
+ array("title" => $item->title, "parent_title" => $parent->title,
+ "locale" => $locale)));
+ self::_notify($email, $locale, $item, $v->render(), $v->subject);
+ }
}
static function send_comment_published($comment) {
$item = $comment->item();
- $subscribers = self::get_subscribers($item);
- if (!$subscribers) {
- return;
- }
-
- $v = new View("comment_published.html");
- $v->comment = $comment;
- $v->subject = $item->is_album() ?
- t("A new comment was published for album \"%title\"", array("title" => $item->title)) :
+ foreach (self::get_subscribers($item) as $email => $locale) {
+ $v = new View("comment_published.html");
+ $v->comment = $comment;
+ $v->subject = $item->is_album() ?
+ t("A new comment was published for album \"%title\"",
+ array("title" => $item->title, "locale" => $locale)) :
($item->is_photo() ?
- t("A new comment was published for photo \"%title\"", array("title" => $item->title))
- : t("A new comment was published for movie \"%title\"", array("title" => $item->title)));
-
- self::_notify($subscribers, $item, $v->render(), $v->subject);
+ t("A new comment was published for photo \"%title\"",
+ array("title" => $item->title, "locale" => $locale))
+ : t("A new comment was published for movie \"%title\"",
+ array("title" => $item->title, "locale" => $locale)));
+ self::_notify($email, $locale, $item, $v->render(), $v->subject);
+ }
}
static function send_pending_notifications() {
@@ -191,13 +179,16 @@ class notification {
$pending->delete();
} else {
$text = "";
+ $locale = null;
foreach ($result as $pending) {
$text .= $pending->text;
+ $locale = $pending->locale;
$pending->delete();
}
Sendmail::factory()
->to($email)
- ->subject(t("Multiple events have occurred")) // @todo fix this terrible subject line
+ ->subject(t("New activity for %site_name",
+ array("site_name" => item::root()->title, "locale" => $locale)))
->header("Mime-Version", "1.0")
->header("Content-Type", "text/html; charset=UTF-8")
->message($text)
@@ -206,25 +197,22 @@ class notification {
}
}
- private static function _notify($subscribers, $item, $text, $subject) {
- if (!empty($subscribers)) {
- if (!batch::in_progress()) {
- Sendmail::factory()
- ->to($subscribers)
- ->subject($subject)
- ->header("Mime-Version", "1.0")
- ->header("Content-Type", "text/html; charset=UTF-8")
- ->message($text)
- ->send();
- } else {
- foreach ($subscribers as $subscriber) {
- $pending = ORM::factory("pending_notification");
- $pending->subject = $subject;
- $pending->text = $text;
- $pending->email = $subscriber;
- $pending->save();
- }
- }
+ private static function _notify($email, $locale, $item, $text, $subject) {
+ if (!batch::in_progress()) {
+ Sendmail::factory()
+ ->to($email)
+ ->subject($subject)
+ ->header("Mime-Version", "1.0")
+ ->header("Content-Type", "text/html; charset=UTF-8")
+ ->message($text)
+ ->send();
+ } else {
+ $pending = ORM::factory("pending_notification");
+ $pending->subject = $subject;
+ $pending->text = $text;
+ $pending->email = $email;
+ $pending->locale = $locale;
+ $pending->save();
}
}
}
diff --git a/modules/notification/helpers/notification_installer.php b/modules/notification/helpers/notification_installer.php
index d082d80f..2ba25298 100644
--- a/modules/notification/helpers/notification_installer.php
+++ b/modules/notification/helpers/notification_installer.php
@@ -30,13 +30,22 @@ class notification_installer {
DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {pending_notifications} (
`id` int(9) NOT NULL auto_increment,
+ `locale` char(10) default NULL,
`email` varchar(128) NOT NULL,
`subject` varchar(255) NOT NULL,
`text` text,
PRIMARY KEY (`id`))
DEFAULT CHARSET=utf8;");
- module::set_version("notification", 1);
+ module::set_version("notification", 2);
+ }
+
+ static function upgrade($version) {
+ $db = Database::instance();
+ if ($version == 1) {
+ $db->query("ALTER TABLE {pending_notifications} ADD COLUMN `locale` char(10) default NULL");
+ module::set_version("notification", $version = 2);
+ }
}
static function uninstall() {
diff --git a/modules/notification/module.info b/modules/notification/module.info
index 31684ccf..8c5e1162 100644
--- a/modules/notification/module.info
+++ b/modules/notification/module.info
@@ -1,3 +1,3 @@
name = "Notification"
description = "Send notifications to users when changes are made to watched albums."
-version = 1
+version = 2
diff --git a/modules/organize/lib/Gallery3WebClient.swf b/modules/organize/lib/Gallery3WebClient.swf
index b82c8a42..356a1a2f 100644
--- a/modules/organize/lib/Gallery3WebClient.swf
+++ b/modules/organize/lib/Gallery3WebClient.swf
Binary files differ
diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php
index b76813ad..3ea1143d 100644
--- a/modules/organize/views/organize_dialog.html.php
+++ b/modules/organize/views/organize_dialog.html.php
@@ -19,13 +19,21 @@
<script type="text/javascript">
$("#g-dialog").bind("dialogclose", function(event, ui) {
// @todo do a call to organize/closing to end the batch
- window.location.reload();
+ if ($(this).data("reload.location")) {
+ window.location = $(this).data("reload.location");
+ } else {
+ window.location.reload();
+ }
});
function closeOrganizeDialog() {
$("#g-dialog").dialog("close");
}
+ function setLocation(url) {
+ $("#g-dialog").data("reload.location", url);
+ }
+
function setTitle(title) {
$("#ui-dialog-title-g-dialog").text(<?= t("Organize :: ")->for_js() ?> + title);
}
diff --git a/modules/rest/helpers/rest_installer.php b/modules/rest/helpers/rest_installer.php
index c2694a29..3c7fea4b 100644
--- a/modules/rest/helpers/rest_installer.php
+++ b/modules/rest/helpers/rest_installer.php
@@ -35,7 +35,9 @@ class rest_installer {
static function upgrade($version) {
$db = Database::instance();
if ($version == 1) {
- $db->query("RENAME TABLE {user_access_tokens} TO {user_access_keys}");
+ if (in_array("user_access_tokens", Database::instance()->list_tables())) {
+ $db->query("RENAME TABLE {user_access_tokens} TO {user_access_keys}");
+ }
module::set_version("rest", $version = 2);
}
diff --git a/modules/rest/views/error_rest.json.php b/modules/rest/views/error_rest.json.php
index 179ce7f9..8c99ef45 100644
--- a/modules/rest/views/error_rest.json.php
+++ b/modules/rest/views/error_rest.json.php
@@ -1,2 +1,6 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
+<?
+// Log error response to ease debugging
+Kohana_Log::add("error", "Rest error details: " . print_r($e->response, 1));
+?>
<?= json_encode($e->response); \ No newline at end of file
diff --git a/modules/search/helpers/search_task.php b/modules/search/helpers/search_task.php
index 08f75d66..48a6688b 100644
--- a/modules/search/helpers/search_task.php
+++ b/modules/search/helpers/search_task.php
@@ -47,7 +47,7 @@ class search_task_Core {
->join("search_records", "items.id", "search_records.item_id", "left")
->where("search_records.item_id", "IS", null)
->or_where("search_records.dirty", "=", 1)
- ->find_all() as $item) {
+ ->find_all(100) as $item) {
// The query above can take a long time, so start the timer after its done
// to give ourselves a little time to actually process rows.
if (!isset($start)) {
@@ -57,7 +57,7 @@ class search_task_Core {
search::update($item);
$completed++;
- if (microtime(true) - $start > 1.5) {
+ if (microtime(true) - $start > .75) {
break;
}
}
diff --git a/modules/tag/controllers/tag.php b/modules/tag/controllers/tag.php
new file mode 100644
index 00000000..0e924f3d
--- /dev/null
+++ b/modules/tag/controllers/tag.php
@@ -0,0 +1,49 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2010 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Tag_Controller extends Controller {
+ public function __call($function, $args) {
+ $tag_name = $function;
+ $tag = ORM::factory("tag")->where("name", "=", $tag_name)->find();
+ $page_size = module::get_var("gallery", "page_size", 9);
+ $page = (int) Input::instance()->get("page", "1");
+ $children_count = $tag->items_count();
+ $offset = ($page-1) * $page_size;
+ $max_pages = max(ceil($children_count / $page_size), 1);
+
+ // Make sure that the page references a valid offset
+ if ($page < 1) {
+ url::redirect($album->abs_url());
+ } else if ($page > $max_pages) {
+ url::redirect($album->abs_url("page=$max_pages"));
+ }
+
+ $template = new Theme_View("page.html", "collection", "tag");
+ $template->set_global("page", $page);
+ $template->set_global("max_pages", $max_pages);
+ $template->set_global("page_size", $page_size);
+ $template->set_global("tag", $tag);
+ $template->set_global("children", $tag->items($page_size, $offset));
+ $template->set_global("children_count", $children_count);
+ $template->content = new View("dynamic.html");
+ $template->content->title = t("Tag: %tag_name", array("tag_name" => $tag->name));
+
+ print $template;
+ }
+}
diff --git a/modules/tag/controllers/tags.php b/modules/tag/controllers/tags.php
index bc657644..aa39b6cd 100644
--- a/modules/tag/controllers/tags.php
+++ b/modules/tag/controllers/tags.php
@@ -18,34 +18,6 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Tags_Controller extends Controller {
- public function show($tag_id) {
- $tag = ORM::factory("tag", $tag_id);
- $page_size = module::get_var("gallery", "page_size", 9);
- $page = (int) Input::instance()->get("page", "1");
- $children_count = $tag->items_count();
- $offset = ($page-1) * $page_size;
- $max_pages = max(ceil($children_count / $page_size), 1);
-
- // Make sure that the page references a valid offset
- if ($page < 1) {
- url::redirect($album->abs_url());
- } else if ($page > $max_pages) {
- url::redirect($album->abs_url("page=$max_pages"));
- }
-
- $template = new Theme_View("page.html", "collection", "tag");
- $template->set_global("page", $page);
- $template->set_global("max_pages", $max_pages);
- $template->set_global("page_size", $page_size);
- $template->set_global("tag", $tag);
- $template->set_global("children", $tag->items($page_size, $offset));
- $template->set_global("children_count", $children_count);
- $template->content = new View("dynamic.html");
- $template->content->title = t("Tag: %tag_name", array("tag_name" => $tag->name));
-
- print $template;
- }
-
public function index() {
// Far from perfection, but at least require view permission for the root album
$album = ORM::factory("item", 1);
diff --git a/modules/tag/css/tag.css b/modules/tag/css/tag.css
index 6d6438e3..8a64960a 100644
--- a/modules/tag/css/tag.css
+++ b/modules/tag/css/tag.css
@@ -19,6 +19,12 @@
display: none;
}
+#g-tag-cloud ul li.size0 a {
+ color: #9cf;
+ font-size: 70%;
+ font-weight: 100;
+}
+
#g-tag-cloud ul li.size1 a {
color: #9cf;
font-size: 80%;
diff --git a/modules/tag/helpers/tag_rss.php b/modules/tag/helpers/tag_rss.php
index ea3865be..f60bd908 100644
--- a/modules/tag/helpers/tag_rss.php
+++ b/modules/tag/helpers/tag_rss.php
@@ -38,7 +38,8 @@ class tag_rss_Core {
$feed = new stdClass();
$feed->items = $tag->items($limit, $offset, "photo");
$feed->max_pages = ceil($tag->count / $limit);
- $feed->title = $tag->name;
+ $feed->title = t("%site_title - %tag_name",
+ array("site_title" => item::root()->title, "tag_name" => $tag->name));
$feed->description = t("Photos related to %tag_name", array("tag_name" => $tag->name));
return $feed;
diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php
index 96f926bb..b5bb857f 100644
--- a/modules/tag/models/tag.php
+++ b/modules/tag/models/tag.php
@@ -125,7 +125,7 @@ class Tag_Model extends ORM {
* @param string $query the query string (eg "page=3")
*/
public function url($query=null) {
- $url = url::site("tags/show/$this->id");
+ $url = url::site("tag/{$this->name}");
if ($query) {
$url .= "?$query";
}
diff --git a/modules/tag/views/tag_block.html.php b/modules/tag/views/tag_block.html.php
index 8b887282..cc204c72 100644
--- a/modules/tag/views/tag_block.html.php
+++ b/modules/tag/views/tag_block.html.php
@@ -7,7 +7,8 @@
max: 30,
multiple: true,
multipleSeparator: ',',
- cacheLength: 1
+ cacheLength: 1,
+ selectFirst: false,
}
);
$("#g-add-tag-form").ajaxForm({
@@ -24,4 +25,4 @@
<div id="g-tag-cloud" ref="<?= url::site("tags") ?>">
<?= $cloud ?>
</div>
-<?= $form ?> \ No newline at end of file
+<?= $form ?>
diff --git a/modules/user/controllers/admin_users.php b/modules/user/controllers/admin_users.php
index 24478aa5..c22fcc2e 100644
--- a/modules/user/controllers/admin_users.php
+++ b/modules/user/controllers/admin_users.php
@@ -95,7 +95,10 @@ class Admin_Users_Controller extends Admin_Controller {
if (empty($user)) {
throw new Kohana_404_Exception();
}
- print $this->_get_user_delete_form_admin($user);
+ $v = new View("admin_users_delete_user.html");
+ $v->user = $user;
+ $v->form = $this->_get_user_delete_form_admin($user);
+ print $v;
}
public function edit_user($id) {
@@ -364,8 +367,8 @@ class Admin_Users_Controller extends Admin_Controller {
$form = new Forge("admin/users/delete_user/$user->id", "", "post",
array("id" => "g-delete-user-form"));
$group = $form->group("delete_user")->label(
- t("Are you sure you want to delete user %name?", array("name" => $user->name)));
- $group->submit("")->value(t("Delete user %name", array("name" => $user->name)));
+ t("Delete user %name?", array("name" => $user->display_name())));
+ $group->submit("")->value(t("Delete"));
return $form;
}
diff --git a/modules/user/helpers/group.php b/modules/user/helpers/group.php
index c84910f1..88bfac35 100644
--- a/modules/user/helpers/group.php
+++ b/modules/user/helpers/group.php
@@ -68,13 +68,13 @@ class group_Core {
*/
private static function _lookup_by_field($field_name, $value) {
try {
- $user = model_cache::get("group", $value, $field_name);
- if ($user->loaded()) {
- return $user;
+ $group = model_cache::get("group", $value, $field_name);
+ if ($group->loaded()) {
+ return $group;
}
} catch (Exception $e) {
if (strpos($e->getMessage(), "MISSING_MODEL") === false) {
- throw $e;
+ throw $e;
}
}
return null;
diff --git a/modules/user/helpers/user.php b/modules/user/helpers/user.php
index 55153263..be50d6d1 100644
--- a/modules/user/helpers/user.php
+++ b/modules/user/helpers/user.php
@@ -36,6 +36,20 @@ class user_Core {
}
/**
+ * Return an admin user. Prefer the currently logged in user, if possible.
+ *
+ * @return User_Model
+ */
+ static function admin_user() {
+ $active = identity::active_user();
+ if ($active->admin) {
+ return $active;
+ }
+
+ return ORM::factory("user")->where("admin", "=", 1)->order_by("id", "ASC")->find();
+ }
+
+ /**
* Is the password provided correct?
*
* @param user User Model
diff --git a/modules/user/libraries/drivers/IdentityProvider/Gallery.php b/modules/user/libraries/drivers/IdentityProvider/Gallery.php
index 1ed7dd4f..73ac9bd0 100644
--- a/modules/user/libraries/drivers/IdentityProvider/Gallery.php
+++ b/modules/user/libraries/drivers/IdentityProvider/Gallery.php
@@ -32,7 +32,7 @@ class IdentityProvider_Gallery_Driver implements IdentityProvider_Driver {
* @see IdentityProvider_Driver::guest.
*/
public function admin_user() {
- return self::lookup_user(2);
+ return user::admin_user();
}
/**
@@ -148,9 +148,7 @@ class IdentityProvider_Gallery_Driver implements IdentityProvider_Driver {
/**
* @see IdentityProvider_Driver::add_user_to_group.
*/
- static function add_user_to_group($user, $group_id) {
- $group = self::lookup_group($group_id);
-
+ public function add_user_to_group($user, $group) {
$group->add($user);
$group->save();
}
@@ -158,8 +156,7 @@ class IdentityProvider_Gallery_Driver implements IdentityProvider_Driver {
/**
* @see IdentityProvider_Driver::remove_user_to_group.
*/
- static function remove_user_from_group($user, $group_id) {
- $group = self::lookup_group_by_name($group_id);
+ public function remove_user_from_group($user, $group_id) {
$group->remove($user);
$group->save();
}
diff --git a/modules/user/models/user.php b/modules/user/models/user.php
index 78d74aa3..b28288be 100644
--- a/modules/user/models/user.php
+++ b/modules/user/models/user.php
@@ -88,6 +88,10 @@ class User_Model extends ORM implements User_Definition {
* @return ORM User_Model
*/
public function save() {
+ if ($this->full_name === null) {
+ $this->full_name = "";
+ }
+
if (!$this->loaded()) {
// New user
$this->add(group::everybody());
diff --git a/modules/user/views/admin_users.html.php b/modules/user/views/admin_users.html.php
index b2526bd8..f067cae8 100644
--- a/modules/user/views/admin_users.html.php
+++ b/modules/user/views/admin_users.html.php
@@ -64,6 +64,7 @@
<th><?= t("Full name") ?></th>
<th><?= t("Email") ?></th>
<th><?= t("Last login") ?></th>
+ <th><?= t("Albums/Photos") ?></th>
<th><?= t("Actions") ?></th>
</tr>
@@ -87,6 +88,9 @@
<?= ($user->last_login == 0) ? "" : gallery::date($user->last_login) ?>
</td>
<td>
+ <?= db::build()->from("items")->where("owner_id", "=", $user->id)->count_records() ?>
+ </td>
+ <td>
<a href="<?= url::site("admin/users/edit_user_form/$user->id") ?>"
open_text="<?= t("Close") ?>"
class="g-panel-link g-button ui-state-default ui-corner-all ui-icon-left">
diff --git a/modules/user/views/admin_users_delete_user.html.php b/modules/user/views/admin_users_delete_user.html.php
new file mode 100644
index 00000000..44777ae5
--- /dev/null
+++ b/modules/user/views/admin_users_delete_user.html.php
@@ -0,0 +1,7 @@
+<?php defined("SYSPATH") or die("No direct script access.") ?>
+<div id="g-admin-users-delete-user">
+ <p>
+ <?= t("Really delete <b>%name</b>? Any photos, movies or albums owned by this user will transfer ownership to <b>%new_owner</b>.", array("name" => $user->display_name(), "new_owner" => identity::active_user()->display_name())) ?>
+ </p>
+ <?= $form ?>
+</div>
diff --git a/themes/admin_wind/css/screen.css b/themes/admin_wind/css/screen.css
index 81b1a896..0d891149 100644
--- a/themes/admin_wind/css/screen.css
+++ b/themes/admin_wind/css/screen.css
@@ -191,7 +191,8 @@ th {
.g-unavailable {
border-color: #999;
- opacity: 0.4;
+ color: black;
+ opacity: .6;
}
.g-info td {
@@ -221,6 +222,11 @@ th {
background-color: #fff;
}
+ul.enumeration li {
+ list-style-type: disc;
+ margin-left: 20px;
+}
+
/*** ******************************************************************
* 3) Page layout containers
*********************************************************************/
diff --git a/themes/wind/js/ui.init.js b/themes/wind/js/ui.init.js
index a4fc0e2f..2c67bf3a 100644
--- a/themes/wind/js/ui.init.js
+++ b/themes/wind/js/ui.init.js
@@ -90,9 +90,18 @@ $(document).ready(function() {
$(this).css("top", 0).css("left", 0);
// Remove the placeholder and hover class from the item
$(this).removeClass("g-hover-item");
+ $(this).gallery_valign();
$("#g-place-holder").remove();
}
);
+
+ // Realign any thumbnails that change so that when we rotate a thumb it stays centered.
+ $(".g-item").bind("gallery.change", function() {
+ $(".g-item").each(function() {
+ $(this).height($(this).find("img").height() + 2);
+ });
+ $(".g-item").equal_heights().gallery_valign();
+ });
}
// Photo/Item item view
diff --git a/themes/wind/views/page.html.php b/themes/wind/views/page.html.php
index 4938ed60..e620d652 100644
--- a/themes/wind/views/page.html.php
+++ b/themes/wind/views/page.html.php
@@ -105,9 +105,9 @@
// containing that photo. For now, we just do it for
// the immediate parent so that when you go back up a
// level you're on the right page. ?>
- <a href="<?= $parent->url($parent == $theme->item()->parent() ?
+ <a href="<?= $parent->url($parent->id == $theme->item()->parent_id ?
"show={$theme->item()->id}" : null) ?>">
- <!-- limit the title length to something reasonable (defaults to 15) -->
+ <? // limit the title length to something reasonable (defaults to 15) ?>
<?= html::purify(text::limit_chars($parent->title,
module::get_var("gallery", "visible_title_length"))) ?>
</a>
diff --git a/themes/wind/views/photo.html.php b/themes/wind/views/photo.html.php
index c17d6b90..92eb08f5 100644
--- a/themes/wind/views/photo.html.php
+++ b/themes/wind/views/photo.html.php
@@ -4,10 +4,23 @@
<!-- Use javascript to show the full size as an overlay on the current page -->
<script type="text/javascript">
$(document).ready(function() {
+ full_dims = [<?= $theme->item()->width ?>, <?= $theme->item()->height ?>];
$(".g-fullsize-link").click(function() {
- $.gallery_show_full_size(<?= html::js_string($theme->item()->file_url()) ?>, "<?= $theme->item()->width ?>", "<?= $theme->item()->height ?>");
+ $.gallery_show_full_size(<?= html::js_string($theme->item()->file_url()) ?>, full_dims[0], full_dims[1]);
return false;
});
+
+ // After the image is rotated or replaced we have to reload the image dimensions
+ // so that the full size view isn't distorted.
+ $("#g-photo").bind("gallery.change", function() {
+ $.ajax({
+ url: "<?= url::site("items/dimensions/" . $theme->item()->id) ?>",
+ dataType: "json",
+ success: function(data, textStatus) {
+ full_dims = data.full;
+ }
+ });
+ });
});
</script>
<? endif ?>