summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.htaccess6
-rw-r--r--index.php9
-rw-r--r--installer/install.sql6
-rw-r--r--lib/gallery.common.js40
-rw-r--r--modules/comment/controllers/admin_manage_comments.php2
-rw-r--r--modules/comment/controllers/comments.php1
-rw-r--r--modules/comment/helpers/comment.php3
-rw-r--r--modules/exif/helpers/exif_task.php4
-rw-r--r--modules/g2_import/controllers/g2.php54
-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.php95
-rw-r--r--modules/gallery/controllers/admin_maintenance.php7
-rw-r--r--modules/gallery/controllers/admin_modules.php5
-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/user_profile.php39
-rw-r--r--modules/gallery/css/upgrader.css28
-rw-r--r--modules/gallery/helpers/access.php30
-rw-r--r--modules/gallery/helpers/album.php1
-rw-r--r--modules/gallery/helpers/gallery.php3
-rw-r--r--modules/gallery/helpers/gallery_event.php14
-rw-r--r--modules/gallery/helpers/gallery_installer.php16
-rw-r--r--modules/gallery/helpers/gallery_task.php6
-rw-r--r--modules/gallery/helpers/graphics.php3
-rw-r--r--modules/gallery/helpers/locales.php1
-rw-r--r--modules/gallery/helpers/module.php12
-rw-r--r--modules/gallery/helpers/movie.php3
-rw-r--r--modules/gallery/libraries/drivers/Cache/Database.php14
-rw-r--r--modules/gallery/models/item.php77
-rw-r--r--modules/gallery/module.info2
-rw-r--r--modules/gallery/tests/Access_Helper_Test.php4
-rw-r--r--modules/gallery/tests/Cache_Test.php20
-rw-r--r--modules/gallery/tests/Item_Model_Test.php57
-rw-r--r--modules/gallery/tests/controller_auth_data.txt4
-rw-r--r--modules/gallery/tests/xss_data.txt73
-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/upgrader.html.php53
-rw-r--r--modules/notification/helpers/notification_installer.php3
-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/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/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/user.php14
-rw-r--r--modules/user/libraries/drivers/IdentityProvider/Gallery.php2
-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.css5
-rw-r--r--themes/wind/js/ui.init.js9
-rw-r--r--themes/wind/views/photo.html.php4
60 files changed, 593 insertions, 386 deletions
diff --git a/.htaccess b/.htaccess
index bea9a10a..f6008361 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/install.sql b/installer/install.sql
index 7a40918d..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',38,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');
@@ -422,6 +422,8 @@ 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\";}}');
diff --git a/lib/gallery.common.js b/lib/gallery.common.js
index 69452f39..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,32 +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});
- if (typeof gallery_image_replaced_hook == 'function') {
- gallery_image_replaced_hook(data, thumb);
- }
+ $.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/admin_manage_comments.php b/modules/comment/controllers/admin_manage_comments.php
index 0889dc4e..49bd85d5 100644
--- a/modules/comment/controllers/admin_manage_comments.php
+++ b/modules/comment/controllers/admin_manage_comments.php
@@ -25,7 +25,7 @@ class Admin_Manage_Comments_Controller extends Admin_Controller {
db::build()
->delete("comments")
->where("state", "IN", array("deleted", "spam"))
- ->where("updated", "<", "UNIX_TIMESTAMP() - 86400 * 7")
+ ->where("updated", "<", new Database_Expression("UNIX_TIMESTAMP() - 86400 * 7"))
->execute();
// Redirect to the appropriate queue
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/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/controllers/g2.php b/modules/g2_import/controllers/g2.php
index d260c9b4..0f51173a 100644
--- a/modules/g2_import/controllers/g2.php
+++ b/modules/g2_import/controllers/g2.php
@@ -34,38 +34,44 @@ class G2_Controller extends Controller {
$path = $input->get("path");
$id = $input->get("g2_itemId");
- if ($id) {
- // Requests by id are either core.DownloadItem or core.ShowItem requests. Later versions of
- // Gallery 2 don't specify g2_view if it's the default (core.ShowItem). And in some cases
- // (bbcode, embedding) people are using the id style URLs although URL rewriting is enabled.
- $where = array(array("g2_id", "=", $id));
- $view = $input->get("g2_view");
- if ($view) {
- $where[] = array("g2_url", "like", "%g2_view=$view%");
- } // else: Assuming that the first search hit is sufficiently good.
- } else if ($path) {
- $where = array(array("g2_url", "=", $path));
- } else {
- throw new Kohana_404_Exception();
- }
+ if ($path || $id) {
+ if ($id) {
+ // Requests by id are either core.DownloadItem or core.ShowItem requests. Later versions of
+ // Gallery 2 don't specify g2_view if it's the default (core.ShowItem). And in some cases
+ // (bbcode, embedding) people are using the id style URLs although URL rewriting is enabled.
+ $where = array(array("g2_id", "=", $id));
+ $view = $input->get("g2_view");
+ if ($view) {
+ $where[] = array("g2_url", "like", "%g2_view=$view%");
+ } // else: Assuming that the first search hit is sufficiently good.
+ } else if ($path) {
+ $where = array(array("g2_url", "IN", array($path, str_replace(" ", "+", $path))));
+ } else {
+ throw new Kohana_404_Exception();
+ }
- $g2_map = ORM::factory("g2_map")
- ->merge_where($where)
- ->find();
+ $g2_map = ORM::factory("g2_map")
+ ->merge_where($where)
+ ->find();
- if (!$g2_map->loaded()) {
- throw new Kohana_404_Exception();
- }
+ if (!$g2_map->loaded()) {
+ throw new Kohana_404_Exception();
+ }
- $item = ORM::factory("item", $g2_map->g3_id);
- if (!$item->loaded()) {
- throw new Kohana_404_Exception();
+ $item = ORM::factory("item", $g2_map->g3_id);
+ if (!$item->loaded()) {
+ throw new Kohana_404_Exception();
+ }
+ $resource_type = $g2_map->resource_type;
+ } else {
+ $item = item::root();
+ $resource_type = "album";
}
access::required("view", $item);
// Redirect the user to the new url
- switch ($g2_map->resource_type) {
+ switch ($resource_type) {
case "thumbnail":
url::redirect($item->thumb_url(true));
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 8ec4b5ce..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,59 +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>
- <textarea rows="2">&lt;IfModule mod_rewrite.c&gt;
+ <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_maintenance.php b/modules/gallery/controllers/admin_maintenance.php
index a9cc933c..7729d797 100644
--- a/modules/gallery/controllers/admin_maintenance.php
+++ b/modules/gallery/controllers/admin_maintenance.php
@@ -48,6 +48,13 @@ class Admin_Maintenance_Controller extends Admin_Controller {
$view->content->finished_tasks = ORM::factory("task")
->where("done", "=", 1)->order_by("updated", "DESC")->find_all();
print $view;
+
+ // Do some maintenance while we're in here
+ db::build()
+ ->delete("caches")
+ ->where("expiration", "<>", 0)
+ ->where("expiration", "<=", time())
+ ->execute();
}
/**
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/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/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 86ea9572..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
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 9430231c..ca8c92c9 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -44,7 +44,8 @@ class gallery_Core {
if (Router::$controller != "login" &&
Router::$controller != "combined" &&
identity::active_user()->guest &&
- !access::user_can(identity::guest(), "view", item::root())) {
+ !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
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index 0ba98025..b59bb9b9 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -118,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);
}
}
@@ -157,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) {
@@ -211,9 +215,9 @@ class gallery_event_Core {
if (Router::$controller == "admin") {
$continue_url = url::abs_site("");
- } else if (isset($theme->item)) {
+ } 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();
}
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index c23bcca8..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", "");
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", 38);
+ module::set_version("gallery", 40);
}
static function upgrade($version) {
@@ -627,6 +627,16 @@ class gallery_installer {
}
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_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/locales.php b/modules/gallery/helpers/locales.php
index 1f5473ff..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
diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php
index 736b6854..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");
+ }
}
/**
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/libraries/drivers/Cache/Database.php b/modules/gallery/libraries/drivers/Cache/Database.php
index 9ada52e1..b7822811 100644
--- a/modules/gallery/libraries/drivers/Cache/Database.php
+++ b/modules/gallery/libraries/drivers/Cache/Database.php
@@ -179,20 +179,6 @@ class Cache_Database_Driver extends Cache_Driver {
}
/**
- * Deletes all cache files that are older than the current time.
- */
- public function delete_expired() {
- // Delete all expired caches
- $status = db::build()
- ->delete("caches")
- ->where("expiration", "<>", 0)
- ->where("expiration", "<=", time())
- ->execute();
-
- return count($status) > 0;
- }
-
- /**
* Empty the cache
*/
public function delete_all() {
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index 34c22021..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 = "<";
@@ -977,23 +987,30 @@ class Item_Model extends ORM_MPTT {
$data["web_url"] = $this->abs_url();
- 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);
+ 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 cc3b2723..1155ddf7 100644
--- a/modules/gallery/module.info
+++ b/modules/gallery/module.info
@@ -1,3 +1,3 @@
name = "Gallery 3"
description = "Gallery core application"
-version = 38
+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/Cache_Test.php b/modules/gallery/tests/Cache_Test.php
index 4c65698a..e8d8b6f4 100644
--- a/modules/gallery/tests/Cache_Test.php
+++ b/modules/gallery/tests/Cache_Test.php
@@ -85,26 +85,6 @@ class Cache_Test extends Gallery_Unit_Test_Case {
$this->assert_equal(array($id3 => $value3), $data, "Expected id3");
}
- public function cache_delete_expired_test() {
- $id1 = md5(rand());
- $value1 = array("field1" => "value1", "field2" => "value2");
- $this->_driver->set(array($id1 => $value1), array("tag1", "tag2"), -84600);
-
- $id2 = md5(rand());
- $value2 = array("field3" => "value3", "field4" => "value4");
- $this->_driver->set(array($id2 => $value2), array("tag2", "tag3"), -846000);
-
- $id3 = md5(rand());
- $value3 = array("field5" => "value5", "field6" => "value6");
- $this->_driver->set(array($id3 => $value3), array("tag3", "tag4"), -84600);
-
- $data = $this->_driver->delete_expired();
-
- $this->assert_false($this->_driver->exists($id1), "$id1 should have been deleted");
- $this->assert_false($this->_driver->exists($id2), "$id2 should have been deleted");
- $this->assert_false($this->_driver->exists($id3), "$id3 should have been deleted");
- }
-
public function cache_delete_id_test() {
$id1 = md5(rand());
$value1 = array("field1" => "value1", "field2" => "value2");
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/controller_auth_data.txt b/modules/gallery/tests/controller_auth_data.txt
index 212577c7..9ea6043a 100644
--- a/modules/gallery/tests/controller_auth_data.txt
+++ b/modules/gallery/tests/controller_auth_data.txt
@@ -15,7 +15,7 @@ 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
@@ -34,7 +34,7 @@ modules/search/controllers/search.php index
modules/server_add/controllers/admin_server_add.php autocomplete DIRTY_CSRF
modules/server_add/controllers/server_add.php children DIRTY_CSRF
modules/tag/controllers/admin_tags.php index DIRTY_CSRF
-modules/tag/controllers/tags.php show DIRTY_CSRF|DIRTY_AUTH
+modules/tag/controllers/tag.php __call DIRTY_CSRF|DIRTY_AUTH
modules/tag/controllers/tags.php autocomplete DIRTY_CSRF|DIRTY_AUTH
modules/user/controllers/password.php reset DIRTY_AUTH
modules/user/controllers/password.php do_reset DIRTY_CSRF|DIRTY_AUTH
diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt
index 4405dad3..a714b3e5 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)
@@ -58,9 +58,9 @@ modules/gallery/views/admin_block_photo_stream.html.php 6 DIRTY photo:
modules/gallery/views/admin_block_photo_stream.html.php 7 DIRTY_ATTR $photo->thumb_url()
modules/gallery/views/admin_dashboard.html.php 5 DIRTY_JS $csrf
modules/gallery/views/admin_dashboard.html.php 35 DIRTY $blocks
-modules/gallery/views/admin_graphics.html.php 24 DIRTY newView("admin_graphics_none.html")
-modules/gallery/views/admin_graphics.html.php 26 DIRTY newView("admin_graphics_$active.html",array("tk"=>$tk->$active,"is_active"=>true))
-modules/gallery/views/admin_graphics.html.php 33 DIRTY newView("admin_graphics_$id.html",array("tk"=>$tk->$id,"is_active"=>false))
+modules/gallery/views/admin_graphics.html.php 25 DIRTY newView("admin_graphics_none.html")
+modules/gallery/views/admin_graphics.html.php 27 DIRTY newView("admin_graphics_$active.html",array("tk"=>$tk->$active,"is_active"=>true))
+modules/gallery/views/admin_graphics.html.php 34 DIRTY newView("admin_graphics_$id.html",array("tk"=>$tk->$id,"is_active"=>false))
modules/gallery/views/admin_graphics_gd.html.php 2 DIRTY_ATTR $is_active?" g-selected":""
modules/gallery/views/admin_graphics_gd.html.php 2 DIRTY_ATTR $tk->installed?" g-installed-toolkit":" g-unavailable"
modules/gallery/views/admin_graphics_gd.html.php 19 DIRTY $tk->error
@@ -248,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
@@ -273,19 +274,19 @@ modules/notification/views/item_updated.html.php 20 DIRTY_JS $item-
modules/notification/views/item_updated.html.php 20 DIRTY $item->abs_url()
modules/notification/views/user_profile_notification.html.php 5 DIRTY_ATTR $subscription->id
modules/notification/views/user_profile_notification.html.php 6 DIRTY_JS $subscription->url
-modules/organize/views/organize_dialog.html.php 86 DIRTY_JS $domain
-modules/organize/views/organize_dialog.html.php 87 DIRTY_JS $access_key
-modules/organize/views/organize_dialog.html.php 88 DIRTY_JS request::protocol()
-modules/organize/views/organize_dialog.html.php 89 DIRTY_JS $file_filter
-modules/organize/views/organize_dialog.html.php 90 DIRTY_JS $sort_order
-modules/organize/views/organize_dialog.html.php 91 DIRTY_JS $sort_fields
-modules/organize/views/organize_dialog.html.php 92 DIRTY_JS $album->id
-modules/organize/views/organize_dialog.html.php 93 DIRTY_JS $selected_id
-modules/organize/views/organize_dialog.html.php 94 DIRTY_JS $rest_uri
-modules/organize/views/organize_dialog.html.php 95 DIRTY_JS $controller_uri
-modules/organize/views/organize_dialog.html.php 101 DIRTY_JS $flash_minimum_version="10.0.0"
-modules/organize/views/organize_dialog.html.php 119 DIRTY_JS $swf_uri
-modules/organize/views/organize_dialog.html.php 132 DIRTY_ATTR request::protocol()
+modules/organize/views/organize_dialog.html.php 94 DIRTY_JS $domain
+modules/organize/views/organize_dialog.html.php 95 DIRTY_JS $access_key
+modules/organize/views/organize_dialog.html.php 96 DIRTY_JS request::protocol()
+modules/organize/views/organize_dialog.html.php 97 DIRTY_JS $file_filter
+modules/organize/views/organize_dialog.html.php 98 DIRTY_JS $sort_order
+modules/organize/views/organize_dialog.html.php 99 DIRTY_JS $sort_fields
+modules/organize/views/organize_dialog.html.php 100 DIRTY_JS $album->id
+modules/organize/views/organize_dialog.html.php 101 DIRTY_JS $selected_id
+modules/organize/views/organize_dialog.html.php 102 DIRTY_JS $rest_uri
+modules/organize/views/organize_dialog.html.php 103 DIRTY_JS $controller_uri
+modules/organize/views/organize_dialog.html.php 109 DIRTY_JS $flash_minimum_version="10.0.0"
+modules/organize/views/organize_dialog.html.php 127 DIRTY_JS $swf_uri
+modules/organize/views/organize_dialog.html.php 140 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
modules/recaptcha/views/form_recaptcha.html.php 7 DIRTY_JS $public_key
@@ -330,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
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/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_installer.php b/modules/notification/helpers/notification_installer.php
index 78f72194..2ba25298 100644
--- a/modules/notification/helpers/notification_installer.php
+++ b/modules/notification/helpers/notification_installer.php
@@ -30,13 +30,14 @@ 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) {
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/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/models/tag.php b/modules/tag/models/tag.php
index e8bd69c5..269a0f39 100644
--- a/modules/tag/models/tag.php
+++ b/modules/tag/models/tag.php
@@ -124,7 +124,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/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 44433ad7..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();
}
/**
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 eda79b97..0d891149 100644
--- a/themes/admin_wind/css/screen.css
+++ b/themes/admin_wind/css/screen.css
@@ -222,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/photo.html.php b/themes/wind/views/photo.html.php
index cb830e23..b42ab987 100644
--- a/themes/wind/views/photo.html.php
+++ b/themes/wind/views/photo.html.php
@@ -12,7 +12,7 @@
// After the image is rotated or replaced we have to reload the image dimensions
// so that the full size view isn't distorted.
- gallery_image_replaced_hook = function(data, thumb) {
+ $("#g-photo").bind("gallery.change", function() {
$.ajax({
url: "<?= url::site("items/dimensions/" . $theme->item()->id) ?>",
dataType: "json",
@@ -20,7 +20,7 @@
full_dims = data.full;
}
});
- }
+ });
});
</script>
<? endif ?>