summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBharat Mediratta <bharat@menalto.com>2009-08-27 16:11:47 -0700
committerBharat Mediratta <bharat@menalto.com>2009-08-27 16:11:47 -0700
commit74363ced870d4114e7570729636875e0258917b3 (patch)
tree61bc27831a362994fc96ea90172d50e25d5c76cb
parent98e9a96ba4d2419e02717369be8c0d886bc35ef7 (diff)
parent4828db003f3ee505eb9e6d056cdb142da34b78ff (diff)
Merge branch 'master' of git@github.com:gallery/gallery3 into HEAD
Conflicts: modules/slideshow/helpers/slideshow_event.php
-rw-r--r--.gitignore4
-rw-r--r--.htaccess5
-rw-r--r--index.php3
-rwxr-xr-xinstaller/install.sql139
-rw-r--r--installer/views/get_db_info.html.php6
-rw-r--r--installer/web.php4
-rw-r--r--lib/gallery.ajax.js15
-rw-r--r--lib/gallery.common.js153
-rw-r--r--lib/gallery.dialog.js256
-rw-r--r--lib/gallery.panel.js116
-rw-r--r--lib/gallery.show_full_size.js117
-rw-r--r--lib/jquery-ui.js533
-rw-r--r--modules/akismet/helpers/akismet_event.php22
-rw-r--r--modules/akismet/helpers/akismet_menu.php36
-rw-r--r--modules/akismet/module.info2
-rw-r--r--modules/akismet/views/admin_akismet.html.php4
-rw-r--r--modules/comment/controllers/admin_comments.php4
-rw-r--r--modules/comment/controllers/comments.php1
-rw-r--r--modules/comment/helpers/comment.php5
-rw-r--r--modules/comment/helpers/comment_event.php30
-rw-r--r--modules/comment/helpers/comment_installer.php15
-rw-r--r--modules/comment/helpers/comment_menu.php37
-rw-r--r--modules/comment/helpers/comment_theme.php2
-rw-r--r--modules/comment/models/comment.php19
-rw-r--r--modules/comment/module.info4
-rw-r--r--modules/comment/views/admin_block_recent_comments.html.php2
-rw-r--r--modules/comment/views/admin_comments.html.php2
-rw-r--r--modules/comment/views/comment.html.php2
-rw-r--r--modules/comment/views/comments.html.php2
-rw-r--r--modules/digibug/config/digibug.php (renamed from modules/comment/helpers/comment_search.php)25
-rw-r--r--modules/digibug/controllers/digibug.php50
-rw-r--r--modules/digibug/helpers/digibug_event.php (renamed from modules/digibug/helpers/digibug_menu.php)35
-rw-r--r--modules/digibug/helpers/digibug_installer.php2
-rw-r--r--modules/digibug/helpers/digibug_theme.php2
-rw-r--r--modules/digibug/module.info4
-rw-r--r--modules/digibug/tests/Digibug_Controller_Test.php78
-rw-r--r--modules/exif/helpers/exif.php2
-rw-r--r--modules/exif/helpers/exif_event.php6
-rw-r--r--modules/exif/helpers/exif_installer.php2
-rw-r--r--modules/exif/helpers/exif_task.php65
-rw-r--r--modules/exif/module.info2
-rw-r--r--modules/g2_import/helpers/g2_import.php26
-rw-r--r--modules/g2_import/helpers/g2_import_event.php11
-rw-r--r--modules/g2_import/helpers/g2_import_installer.php2
-rw-r--r--modules/g2_import/helpers/g2_import_menu.php29
-rw-r--r--modules/g2_import/module.info4
-rw-r--r--modules/gallery/controllers/admin_graphics.php39
-rw-r--r--modules/gallery/controllers/admin_languages.php8
-rw-r--r--modules/gallery/controllers/albums.php27
-rw-r--r--modules/gallery/controllers/combined.php5
-rw-r--r--modules/gallery/controllers/file_proxy.php43
-rw-r--r--modules/gallery/controllers/movies.php14
-rw-r--r--modules/gallery/controllers/packager.php8
-rw-r--r--modules/gallery/controllers/photos.php16
-rw-r--r--modules/gallery/controllers/quick.php15
-rw-r--r--modules/gallery/controllers/simple_uploader.php26
-rw-r--r--modules/gallery/css/quick.css40
-rw-r--r--modules/gallery/helpers/MY_remote.php27
-rw-r--r--modules/gallery/helpers/access.php108
-rw-r--r--modules/gallery/helpers/album.php12
-rw-r--r--modules/gallery/helpers/gallery.php234
-rw-r--r--modules/gallery/helpers/gallery_event.php14
-rw-r--r--modules/gallery/helpers/gallery_installer.php84
-rw-r--r--modules/gallery/helpers/gallery_menu.php163
-rw-r--r--modules/gallery/helpers/gallery_quick.php144
-rw-r--r--modules/gallery/helpers/gallery_rss.php5
-rw-r--r--modules/gallery/helpers/gallery_task.php227
-rw-r--r--modules/gallery/helpers/gallery_theme.php63
-rw-r--r--modules/gallery/helpers/graphics.php105
-rw-r--r--modules/gallery/helpers/item.php20
-rw-r--r--modules/gallery/helpers/l10n_client.php13
-rw-r--r--modules/gallery/helpers/locales.php (renamed from modules/gallery/helpers/locale.php)2
-rw-r--r--modules/gallery/helpers/model_cache.php6
-rw-r--r--modules/gallery/helpers/module.php8
-rw-r--r--modules/gallery/helpers/movie.php6
-rw-r--r--modules/gallery/helpers/photo.php8
-rw-r--r--modules/gallery/helpers/task.php3
-rw-r--r--modules/gallery/js/quick.js90
-rw-r--r--modules/gallery/lib/HTMLPurifier/HTMLPurifier.includes.php2
-rw-r--r--modules/gallery/lib/HTMLPurifier/HTMLPurifier.php6
-rw-r--r--modules/gallery/lib/HTMLPurifier/HTMLPurifier/Config.php2
-rw-r--r--modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer.php2
-rw-r--r--modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php2
-rw-r--r--modules/gallery/lib/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php4
-rw-r--r--modules/gallery/libraries/Admin_View.php17
-rw-r--r--modules/gallery/libraries/Form_Script.php66
-rw-r--r--modules/gallery/libraries/Gallery_View.php74
-rw-r--r--modules/gallery/libraries/HtmlPurifier.php5
-rw-r--r--modules/gallery/libraries/I18n.php9
-rw-r--r--modules/gallery/libraries/MY_ORM.php29
-rw-r--r--modules/gallery/libraries/MY_View.php10
-rw-r--r--modules/gallery/libraries/Menu.php47
-rw-r--r--modules/gallery/libraries/ORM_MPTT.php142
-rw-r--r--modules/gallery/libraries/Theme_View.php64
-rw-r--r--modules/gallery/models/item.php70
-rw-r--r--modules/gallery/module.info6
-rw-r--r--modules/gallery/tests/Access_Helper_Test.php73
-rw-r--r--modules/gallery/tests/Database_Test.php8
-rw-r--r--modules/gallery/tests/DrawForm_Test.php39
-rw-r--r--modules/gallery/tests/File_Structure_Test.php37
-rw-r--r--modules/gallery/tests/Gallery_Installer_Test.php10
-rw-r--r--modules/gallery/tests/Item_Model_Test.php10
-rw-r--r--modules/gallery/tests/ORM_MPTT_Test.php22
-rw-r--r--modules/gallery/tests/Photo_Helper_Test.php4
-rw-r--r--modules/gallery/tests/Xss_Security_Test.php2
-rw-r--r--modules/gallery/tests/xss_data.txt209
-rw-r--r--modules/gallery/views/admin_block_platform.html.php5
-rw-r--r--modules/gallery/views/admin_block_stats.html.php2
-rw-r--r--modules/gallery/views/admin_graphics.html.php14
-rw-r--r--modules/gallery/views/admin_graphics_gd.html.php15
-rw-r--r--modules/gallery/views/admin_graphics_graphicsmagick.html.php10
-rw-r--r--modules/gallery/views/admin_graphics_imagemagick.html.php12
-rw-r--r--modules/gallery/views/admin_graphics_none.html.php2
-rw-r--r--modules/gallery/views/admin_maintenance.html.php19
-rw-r--r--modules/gallery/views/admin_maintenance_task.html.php32
-rw-r--r--modules/gallery/views/after_install.html.php4
-rw-r--r--modules/gallery/views/after_install_loader.html.php2
-rw-r--r--modules/gallery/views/form.html.php2
-rw-r--r--modules/gallery/views/l10n_client.html.php2
-rw-r--r--modules/gallery/views/movieplayer.html.php25
-rw-r--r--modules/gallery/views/permissions_form.html.php2
-rw-r--r--modules/gallery/views/quick_pane.html.php26
-rw-r--r--modules/gallery/views/simple_uploader.html.php22
-rw-r--r--modules/image_block/module.info4
-rw-r--r--modules/info/helpers/info_theme.php6
-rw-r--r--modules/info/module.info4
-rw-r--r--modules/info/views/info_block.html.php6
-rw-r--r--modules/notification/helpers/notification.php35
-rw-r--r--modules/notification/helpers/notification_event.php29
-rw-r--r--modules/notification/helpers/notification_installer.php4
-rw-r--r--modules/notification/helpers/notification_menu.php39
-rw-r--r--modules/notification/module.info2
-rw-r--r--modules/notification/views/item_added.html.php2
-rw-r--r--modules/notification/views/item_updated.html.php16
-rw-r--r--modules/organize/controllers/organize.php8
-rw-r--r--modules/organize/css/organize.css2
-rw-r--r--modules/organize/helpers/organize.php2
-rw-r--r--modules/organize/helpers/organize_event.php (renamed from modules/organize/helpers/organize_menu.php)4
-rw-r--r--modules/organize/helpers/organize_theme.php6
-rw-r--r--modules/organize/js/organize.js2
-rw-r--r--modules/organize/js/organize_init.js2
-rw-r--r--modules/organize/module.info4
-rw-r--r--modules/organize/views/organize.html.php2
-rw-r--r--modules/organize/views/organize_button_pane.html.php2
-rw-r--r--modules/recaptcha/helpers/recaptcha_event.php8
-rw-r--r--modules/recaptcha/helpers/recaptcha_menu.php28
-rw-r--r--modules/recaptcha/libraries/Form_Recaptcha.php2
-rw-r--r--modules/recaptcha/module.info2
-rw-r--r--modules/recaptcha/views/admin_recaptcha.html.php2
-rw-r--r--modules/rss/module.info4
-rw-r--r--modules/search/helpers/search.php16
-rw-r--r--modules/search/helpers/search_event.php11
-rw-r--r--modules/search/helpers/search_installer.php2
-rw-r--r--modules/search/helpers/search_task.php54
-rw-r--r--modules/search/module.info4
-rw-r--r--modules/server_add/controllers/admin_server_add.php14
-rw-r--r--modules/server_add/controllers/server_add.php388
-rw-r--r--modules/server_add/helpers/server_add.php15
-rw-r--r--modules/server_add/helpers/server_add_event.php (renamed from modules/server_add/helpers/server_add_menu.php)8
-rw-r--r--modules/server_add/helpers/server_add_installer.php30
-rw-r--r--modules/server_add/helpers/server_add_task.php85
-rw-r--r--modules/server_add/helpers/server_add_theme.php8
-rw-r--r--modules/server_add/js/server_add.js229
-rw-r--r--modules/server_add/models/server_add_file.php (renamed from modules/gallery/helpers/gallery_search.php)5
-rw-r--r--modules/server_add/module.info6
-rw-r--r--modules/server_add/views/admin_server_add.html.php2
-rw-r--r--modules/server_add/views/server_add_tree.html.php53
-rw-r--r--modules/server_add/views/server_add_tree_dialog.html.php59
-rw-r--r--modules/slideshow/helpers/slideshow_menu.php51
-rw-r--r--modules/slideshow/helpers/slideshow_theme.php2
-rw-r--r--modules/slideshow/module.info4
-rw-r--r--modules/tag/controllers/tags.php19
-rw-r--r--modules/tag/helpers/tag.php40
-rw-r--r--modules/tag/helpers/tag_event.php53
-rw-r--r--modules/tag/helpers/tag_installer.php4
-rw-r--r--modules/tag/helpers/tag_menu.php28
-rw-r--r--modules/tag/helpers/tag_theme.php6
-rw-r--r--modules/tag/js/tag.js5
-rw-r--r--modules/tag/models/tag.php58
-rw-r--r--modules/tag/module.info4
-rw-r--r--modules/tag/views/tag_block.html.php14
-rw-r--r--modules/user/controllers/admin_users.php5
-rw-r--r--modules/user/controllers/logout.php11
-rw-r--r--modules/user/controllers/password.php4
-rw-r--r--modules/user/controllers/users.php1
-rw-r--r--modules/user/helpers/group.php1
-rw-r--r--modules/user/helpers/user.php18
-rw-r--r--modules/user/helpers/user_event.php8
-rw-r--r--modules/user/helpers/user_installer.php6
-rw-r--r--modules/user/helpers/user_menu.php28
-rw-r--r--modules/user/helpers/user_theme.php12
-rw-r--r--modules/user/models/group.php15
-rw-r--r--modules/user/models/user.php25
-rw-r--r--modules/user/module.info4
-rw-r--r--modules/user/views/admin_users.html.php4
-rw-r--r--modules/user/views/login.html.php4
-rw-r--r--modules/user/views/login_ajax.html.php2
-rw-r--r--modules/watermark/helpers/watermark_event.php (renamed from modules/watermark/helpers/watermark_menu.php)4
-rw-r--r--modules/watermark/helpers/watermark_installer.php2
-rw-r--r--modules/watermark/module.info4
-rw-r--r--system/libraries/Database.php9
-rw-r--r--system/libraries/ORM.php4
-rw-r--r--system/libraries/drivers/Database.php4
-rw-r--r--themes/admin_default/css/admin_screen.css458
-rw-r--r--themes/admin_default/css/screen.css1149
-rw-r--r--themes/admin_default/images/ico-album.pngbin0 -> 397 bytes
-rw-r--r--themes/admin_default/images/ico-error.pngbin0 -> 701 bytes
-rw-r--r--themes/admin_default/images/ico-info.pngbin0 -> 778 bytes
-rw-r--r--themes/admin_default/images/ico-print.pngbin0 -> 989 bytes
-rw-r--r--themes/admin_default/images/ico-separator.gifbin0 -> 106 bytes
-rw-r--r--themes/admin_default/images/ico-success.pngbin0 -> 537 bytes
-rw-r--r--themes/admin_default/images/ico-view-comments.pngbin0 -> 768 bytes
-rw-r--r--themes/admin_default/images/ico-view-fullsize.pngbin0 -> 1046 bytes
-rw-r--r--themes/admin_default/images/ico-view-hybrid.pngbin0 -> 494 bytes
-rw-r--r--themes/admin_default/images/ico-view-slideshow.pngbin0 -> 960 bytes
-rw-r--r--themes/admin_default/images/ico-warning.pngbin0 -> 666 bytes
-rw-r--r--themes/admin_default/images/loading-lg.gifbin0 -> 8238 bytes
-rw-r--r--themes/admin_default/images/loading-sm.gifbin0 -> 673 bytes
-rw-r--r--themes/admin_default/js/ui.init.js18
-rw-r--r--themes/admin_default/theme.info6
-rw-r--r--themes/admin_default/views/admin.html.php31
-rw-r--r--themes/default/css/fix-ie.css23
-rw-r--r--themes/default/css/screen.css167
-rw-r--r--themes/default/js/ui.init.js109
-rw-r--r--themes/default/theme.info6
-rw-r--r--themes/default/views/album.html.php2
-rw-r--r--themes/default/views/header.html.php26
-rw-r--r--themes/default/views/movie.html.php30
-rw-r--r--themes/default/views/page.html.php37
-rw-r--r--themes/default/views/photo.html.php3
230 files changed, 5233 insertions, 3146 deletions
diff --git a/.gitignore b/.gitignore
index 6ebdd994..e7d630f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
-# Ignore the var subdirectory
+# We store Gallery3 data in var
var
-# Ignore the index.local.php
+# local.php is a local customization point that gets loaded at the end of index.php
local.php
diff --git a/.htaccess b/.htaccess
index 08b9c5bb..c3f94237 100644
--- a/.htaccess
+++ b/.htaccess
@@ -44,6 +44,11 @@
#
# Then just use your Gallery 3 without the index.php in the url.
#
+# NOTE: future upgrades of Gallery 3 will overwrite this file! If you
+# want these changes to be persistent, you should talk to your system
+# administrator about putting this block into your Apache config
+# files.
+#
# <IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteBase /
diff --git a/index.php b/index.php
index 7def7d16..d0e12cfc 100644
--- a/index.php
+++ b/index.php
@@ -21,7 +21,8 @@
define("IN_PRODUCTION", true);
// Gallery requires PHP 5.2+
-version_compare(PHP_VERSION, "5.2.3", "<") and exit("Gallery requires PHP 5.2.3 or newer.");
+version_compare(PHP_VERSION, "5.2.3", "<") and
+ exit("Gallery requires PHP 5.2.3 or newer (you're using " . PHP_VERSION . ")");
// Gallery requires short_tags to be on
!ini_get("short_open_tag") and exit("Gallery requires short_open_tag to be on.");
diff --git a/installer/install.sql b/installer/install.sql
index 7da5fe68..21464379 100755
--- a/installer/install.sql
+++ b/installer/install.sql
@@ -4,34 +4,34 @@ SET character_set_client = utf8;
CREATE TABLE {access_caches} (
`id` int(9) NOT NULL auto_increment,
`item_id` int(9) default NULL,
- `view_full_1` smallint(6) NOT NULL default '0',
- `edit_1` smallint(6) NOT NULL default '0',
- `add_1` smallint(6) NOT NULL default '0',
- `view_full_2` smallint(6) NOT NULL default '0',
- `edit_2` smallint(6) NOT NULL default '0',
- `add_2` smallint(6) NOT NULL default '0',
+ `view_full_1` binary(1) NOT NULL default '0',
+ `edit_1` binary(1) NOT NULL default '0',
+ `add_1` binary(1) NOT NULL default '0',
+ `view_full_2` binary(1) NOT NULL default '0',
+ `edit_2` binary(1) NOT NULL default '0',
+ `add_2` binary(1) NOT NULL default '0',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {access_caches} VALUES (1,1,1,0,0,1,0,0);
+INSERT INTO {access_caches} VALUES (1,1,'1','0','0','1','0','0');
DROP TABLE IF EXISTS {access_intents};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE {access_intents} (
`id` int(9) NOT NULL auto_increment,
`item_id` int(9) default NULL,
- `view_1` tinyint(1) default NULL,
- `view_full_1` tinyint(1) default NULL,
- `edit_1` tinyint(1) default NULL,
- `add_1` tinyint(1) default NULL,
- `view_2` tinyint(1) default NULL,
- `view_full_2` tinyint(1) default NULL,
- `edit_2` tinyint(1) default NULL,
- `add_2` tinyint(1) default NULL,
+ `view_1` binary(1) default NULL,
+ `view_full_1` binary(1) default NULL,
+ `edit_1` binary(1) default NULL,
+ `add_1` binary(1) default NULL,
+ `view_2` binary(1) default NULL,
+ `view_full_2` binary(1) default NULL,
+ `edit_2` binary(1) default NULL,
+ `add_2` binary(1) default NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {access_intents} VALUES (1,1,1,1,0,0,1,1,0,0);
+INSERT INTO {access_intents} VALUES (1,1,'1','1','0','0','1','1','0','0');
DROP TABLE IF EXISTS {caches};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -43,7 +43,7 @@ CREATE TABLE {caches} (
`cache` longblob,
PRIMARY KEY (`id`),
KEY `tags` (`tags`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {comments};
SET @saved_cs_client = @@character_set_client;
@@ -72,7 +72,7 @@ CREATE TABLE {comments} (
`text` text,
`updated` int(9) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {graphics_rules};
SET @saved_cs_client = @@character_set_client;
@@ -86,9 +86,10 @@ CREATE TABLE {graphics_rules} (
`priority` int(9) NOT NULL,
`target` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {graphics_rules} VALUES (1,1,'a:3:{s:5:\"width\";i:200;s:6:\"height\";i:200;s:6:\"master\";i:2;}','gallery','resize',100,'thumb'),(2,1,'a:3:{s:5:\"width\";i:640;s:6:\"height\";i:480;s:6:\"master\";i:2;}','gallery','resize',100,'resize');
+INSERT INTO {graphics_rules} VALUES (1,1,'a:3:{s:5:\"width\";i:200;s:6:\"height\";i:200;s:6:\"master\";i:2;}','gallery','resize',100,'thumb');
+INSERT INTO {graphics_rules} VALUES (2,1,'a:3:{s:5:\"width\";i:640;s:6:\"height\";i:480;s:6:\"master\";i:2;}','gallery','resize',100,'resize');
DROP TABLE IF EXISTS {groups};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -98,9 +99,10 @@ CREATE TABLE {groups} (
`special` tinyint(1) default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {groups} VALUES (1,'Everybody',1),(2,'Registered Users',1);
+INSERT INTO {groups} VALUES (1,'Everybody',1);
+INSERT INTO {groups} VALUES (2,'Registered Users',1);
DROP TABLE IF EXISTS {groups_users};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -109,9 +111,11 @@ CREATE TABLE {groups_users} (
`user_id` int(9) NOT NULL,
PRIMARY KEY (`group_id`,`user_id`),
UNIQUE KEY `user_id` (`user_id`,`group_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {groups_users} VALUES (1,1),(1,2),(2,2);
+INSERT INTO {groups_users} VALUES (1,1);
+INSERT INTO {groups_users} VALUES (1,2);
+INSERT INTO {groups_users} VALUES (2,2);
DROP TABLE IF EXISTS {incoming_translations};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -125,7 +129,7 @@ CREATE TABLE {incoming_translations} (
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`,`locale`),
KEY `locale_key` (`locale`,`key`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {items};
SET @saved_cs_client = @@character_set_client;
@@ -137,7 +141,7 @@ CREATE TABLE {items} (
`created` int(9) default NULL,
`description` varchar(2048) default NULL,
`height` int(9) default NULL,
- `left` int(9) NOT NULL,
+ `left_ptr` int(9) NOT NULL,
`level` int(9) NOT NULL,
`mime_type` varchar(64) default NULL,
`name` varchar(255) default NULL,
@@ -148,7 +152,7 @@ CREATE TABLE {items} (
`resize_dirty` tinyint(1) default '1',
`resize_height` int(9) default NULL,
`resize_width` int(9) default NULL,
- `right` int(9) NOT NULL,
+ `right_ptr` int(9) NOT NULL,
`sort_column` varchar(64) default NULL,
`sort_order` char(4) default 'ASC',
`thumb_dirty` tinyint(1) default '1',
@@ -160,15 +164,16 @@ CREATE TABLE {items} (
`view_count` int(9) default '0',
`weight` int(9) NOT NULL default '0',
`width` int(9) default NULL,
- `view_1` smallint(6) NOT NULL default '0',
- `view_2` smallint(6) NOT NULL default '0',
+ `view_1` binary(1) default '0',
+ `view_2` binary(1) default '0',
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`),
KEY `type` (`type`),
- KEY `random` (`rand_key`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+ KEY `random` (`rand_key`),
+ KEY `weight` (`weight`)
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {items} VALUES (1,NULL,NULL,UNIX_TIMESTAMP(),'',NULL,1,1,NULL,NULL,NULL,0,NULL,'',1,NULL,NULL,2,'weight','ASC',1,NULL,NULL,'Gallery','album',UNIX_TIMESTAMP(),0,1,NULL,1,1);
+INSERT INTO {items} VALUES (1,NULL,NULL,UNIX_TIMESTAMP(),'',NULL,1,1,NULL,NULL,NULL,0,NULL,'',1,NULL,NULL,2,'weight','ASC',1,NULL,NULL,'Gallery','album',UNIX_TIMESTAMP(),0,1,NULL,'1','1');
DROP TABLE IF EXISTS {items_tags};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -179,7 +184,7 @@ CREATE TABLE {items_tags} (
PRIMARY KEY (`id`),
KEY `tag_id` (`tag_id`,`id`),
KEY `item_id` (`item_id`,`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {logs};
SET @saved_cs_client = @@character_set_client;
@@ -195,7 +200,7 @@ CREATE TABLE {logs} (
`url` varchar(255) default NULL,
`user_id` int(9) default '0',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {messages};
SET @saved_cs_client = @@character_set_client;
@@ -207,7 +212,7 @@ CREATE TABLE {messages} (
`value` varchar(255) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {modules};
SET @saved_cs_client = @@character_set_client;
@@ -219,9 +224,17 @@ CREATE TABLE {modules} (
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {modules} VALUES (1,1,'gallery',6),(2,1,'user',1),(3,1,'comment',2),(4,1,'organize',1),(5,1,'info',1),(6,1,'rss',1),(7,1,'search',1),(8,1,'slideshow',1),(9,1,'tag',1);
+INSERT INTO {modules} VALUES (1,1,'gallery',10);
+INSERT INTO {modules} VALUES (2,1,'user',1);
+INSERT INTO {modules} VALUES (3,1,'comment',2);
+INSERT INTO {modules} VALUES (4,1,'organize',1);
+INSERT INTO {modules} VALUES (5,1,'info',1);
+INSERT INTO {modules} VALUES (6,1,'rss',1);
+INSERT INTO {modules} VALUES (7,1,'search',1);
+INSERT INTO {modules} VALUES (8,1,'slideshow',1);
+INSERT INTO {modules} VALUES (9,1,'tag',1);
DROP TABLE IF EXISTS {outgoing_translations};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -235,7 +248,7 @@ CREATE TABLE {outgoing_translations} (
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`,`locale`),
KEY `locale_key` (`locale`,`key`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {permissions};
SET @saved_cs_client = @@character_set_client;
@@ -246,9 +259,12 @@ CREATE TABLE {permissions} (
`name` varchar(64) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {permissions} VALUES (1,'View','view'),(2,'View Full Size','view_full'),(3,'Edit','edit'),(4,'Add','add');
+INSERT INTO {permissions} VALUES (1,'View','view');
+INSERT INTO {permissions} VALUES (2,'View Full Size','view_full');
+INSERT INTO {permissions} VALUES (3,'Edit','edit');
+INSERT INTO {permissions} VALUES (4,'Add','add');
DROP TABLE IF EXISTS {search_records};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -260,9 +276,9 @@ CREATE TABLE {search_records} (
PRIMARY KEY (`id`),
KEY `item_id` (`item_id`),
FULLTEXT KEY `data` (`data`)
-) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {search_records} VALUES (1,1,0,' Gallery');
+INSERT INTO {search_records} VALUES (1,1,0,' Gallery');
DROP TABLE IF EXISTS {sessions};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -271,7 +287,7 @@ CREATE TABLE {sessions} (
`data` text NOT NULL,
`last_activity` int(10) unsigned NOT NULL,
PRIMARY KEY (`session_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {tags};
SET @saved_cs_client = @@character_set_client;
@@ -282,7 +298,7 @@ CREATE TABLE {tags} (
`count` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {tasks};
SET @saved_cs_client = @@character_set_client;
@@ -300,7 +316,7 @@ CREATE TABLE {tasks} (
`updated` int(9) default NULL,
PRIMARY KEY (`id`),
KEY `owner_id` (`owner_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+) DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS {themes};
SET @saved_cs_client = @@character_set_client;
@@ -311,9 +327,10 @@ CREATE TABLE {themes} (
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {themes} VALUES (1,'default',1),(2,'admin_default',1);
+INSERT INTO {themes} VALUES (1,'default',1);
+INSERT INTO {themes} VALUES (2,'admin_default',1);
DROP TABLE IF EXISTS {users};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -333,9 +350,10 @@ CREATE TABLE {users} (
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `hash` (`hash`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {users} VALUES (1,'guest','Guest User','',0,0,NULL,0,1,NULL,NULL,NULL),(2,'admin','Gallery Administrator','',0,0,NULL,1,0,NULL,NULL,NULL);
+INSERT INTO {users} VALUES (1,'guest','Guest User','',0,0,NULL,0,1,NULL,NULL,NULL);
+INSERT INTO {users} VALUES (2,'admin','Gallery Administrator','',0,0,NULL,1,0,NULL,NULL,NULL);
DROP TABLE IF EXISTS {vars};
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
@@ -346,6 +364,21 @@ CREATE TABLE {vars} (
`value` text,
PRIMARY KEY (`id`),
UNIQUE KEY `module_name` (`module_name`,`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+) AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
-INSERT INTO {vars} VALUES (1,'gallery','active_site_theme','default'),(2,'gallery','active_admin_theme','admin_default'),(3,'gallery','page_size','9'),(4,'gallery','thumb_size','200'),(5,'gallery','resize_size','640'),(6,'gallery','default_locale','en_US'),(7,'gallery','image_quality','75'),(9,'gallery','blocks_dashboard_sidebar','a:4:{i:2;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"block_adder\";}i:3;a:2:{i:0;s:7:\"gallery\";i:1;s:5:\"stats\";}i:4;a:2:{i:0;s:7:\"gallery\";i:1;s:13:\"platform_info\";}i:5;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"project_news\";}}'),(14,'gallery','blocks_dashboard_center','a:4:{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\";}i:9;a:2:{i:0;s:7:\"comment\";i:1;s:15:\"recent_comments\";}}'),(17,'gallery','version','3.0 pre beta 2 (git)'),(18,'gallery','choose_default_tookit','1'),(19,'gallery','date_format','Y-M-d'),(20,'gallery','date_time_format','Y-M-d H:i:s'),(21,'gallery','time_format','H:i:s'),(22,'gallery','show_credits','1'),(23,'gallery','credits','Powered by <a href=\"%url\">Gallery %version</a>'),(25,'comment','spam_caught','0');
+INSERT INTO {vars} VALUES (1,'gallery','active_site_theme','default');
+INSERT INTO {vars} VALUES (2,'gallery','active_admin_theme','admin_default');
+INSERT INTO {vars} VALUES (3,'gallery','page_size','9');
+INSERT INTO {vars} VALUES (4,'gallery','thumb_size','200');
+INSERT INTO {vars} VALUES (5,'gallery','resize_size','640');
+INSERT INTO {vars} VALUES (6,'gallery','default_locale','en_US');
+INSERT INTO {vars} VALUES (7,'gallery','image_quality','75');
+INSERT INTO {vars} VALUES (9,'gallery','blocks_dashboard_sidebar','a:4:{i:2;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"block_adder\";}i:3;a:2:{i:0;s:7:\"gallery\";i:1;s:5:\"stats\";}i:4;a:2:{i:0;s:7:\"gallery\";i:1;s:13:\"platform_info\";}i:5;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"project_news\";}}');
+INSERT INTO {vars} VALUES (14,'gallery','blocks_dashboard_center','a:4:{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\";}i:9;a:2:{i:0;s:7:\"comment\";i:1;s:15:\"recent_comments\";}}');
+INSERT INTO {vars} VALUES (17,'gallery','choose_default_tookit','1');
+INSERT INTO {vars} VALUES (18,'gallery','date_format','Y-M-d');
+INSERT INTO {vars} VALUES (19,'gallery','date_time_format','Y-M-d H:i:s');
+INSERT INTO {vars} VALUES (20,'gallery','time_format','H:i:s');
+INSERT INTO {vars} VALUES (21,'gallery','show_credits','1');
+INSERT INTO {vars} VALUES (22,'gallery','credits','Powered by <a href=\"%url\">Gallery %version</a>');
+INSERT INTO {vars} VALUES (24,'comment','spam_caught','0');
diff --git a/installer/views/get_db_info.html.php b/installer/views/get_db_info.html.php
index 7835f246..ada0793c 100644
--- a/installer/views/get_db_info.html.php
+++ b/installer/views/get_db_info.html.php
@@ -26,6 +26,7 @@
<?php endif ?>
</fieldset>
+<?php if (installer::var_writable()): ?>
<form method="post" action="index.php?step=save_db_info">
<fieldset>
<legend>Database</legend>
@@ -77,13 +78,10 @@
</tr>
<tr>
<td colspan="2">
- <?php if (installer::var_writable()): ?>
<input type="submit" value="Continue"/>
- <?php else: ?>
- <i class="error">(Please fix the photo storage problem before continuing)</i>
- <?php endif ?>
</td>
</tr>
</table>
</fieldset>
</form>
+<?php endif ?>
diff --git a/installer/web.php b/installer/web.php
index 78784539..f31c0644 100644
--- a/installer/web.php
+++ b/installer/web.php
@@ -104,6 +104,10 @@ function check_environment() {
$errors[] = "PHP is missing the <a href=\"http://php.net/iconv\">iconv extension</a>";
}
+ if (!(extension_loaded("simplexml"))) {
+ $errors[] = "PHP is missing the <a href=\"http://php.net/simplexml\">SimpleXML extension</a>";
+ }
+
if (extension_loaded("mbstring") && (ini_get("mbstring.func_overload") & MB_OVERLOAD_STRING)) {
$errors[] = "The <a href=\"http://php.net/mbstring\">mbstring extension</a> is overloading PHP's native string functions. Please disable it.";
}
diff --git a/lib/gallery.ajax.js b/lib/gallery.ajax.js
new file mode 100644
index 00000000..0cdd8f27
--- /dev/null
+++ b/lib/gallery.ajax.js
@@ -0,0 +1,15 @@
+(function($) {
+ $.widget("ui.gallery_ajax", {
+ _init: function() {
+ this.element.click(function(event) {
+ eval("var ajax_handler = " + $(event.currentTarget).attr("ajax_handler"));
+ $.get($(event.currentTarget).attr("href"), function(data) {
+ eval("var data = " + data);
+ ajax_handler(data);
+ });
+ event.preventDefault();
+ return false;
+ });
+ }
+ });
+})(jQuery);
diff --git a/lib/gallery.common.js b/lib/gallery.common.js
index 14c28a56..a959d90d 100644
--- a/lib/gallery.common.js
+++ b/lib/gallery.common.js
@@ -1,29 +1,158 @@
-/**
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-(function () {
- $.fn.showMessage = function(message) {
+(function ($) {
+ $.fn.gallery_show_message = function(message) {
return this.each(function(i){
$(this).effect("highlight", {"color": "white"}, 3000);
$(this).animate({opacity: 1.0}, 6000);
});
};
-})(jQuery);
-// Vertically align a block element's content
-(function () {
- $.fn.vAlign = function(container) {
+ // Vertically align a block element's content
+ $.fn.gallery_valign = function(container) {
return this.each(function(i){
if (container == null) {
container = 'div';
}
- $(this).html("<" + container + ">" + $(this).html() + "</" + container + ">");
- var el = $(this).children(container + ":first");
+ $(this).html("<" + container + " class=\"gValign\">" + $(this).html() + "</" + container + ">");
+ var el = $(this).children(container + ".gValign");
var elh = $(el).height();
var ph = $(this).height();
var nh = (ph - elh) / 2;
$(el).css('margin-top', nh);
});
};
+
+ // Get the viewport size
+ $.gallery_get_viewport_size = function() {
+ return {
+ width : function() {
+ return $(window).width();
+ },
+ height : function() {
+ return $(window).height();
+ }
+ };
+ };
+
+ /**
+ * Toggle the processing indicator, both large and small
+ * @param elementID Target ID, including #, to apply .gLoadingSize
+ */
+ $.fn.gallery_show_loading = function() {
+ return this.each(function(i){
+ var size;
+ switch ($(this).attr("id")) {
+ case "#gDialog":
+ case "#gPanel":
+ size = "Large";
+ break;
+ default:
+ size = "Small";
+ break;
+ }
+ $(this).toggleClass("gLoading" + size);
+ });
+ };
+
+ /**
+ * Reduce the width of an image if it's wider than its parent container
+ * @param elementID The image container's ID
+ */
+ $.fn.gallery_fit_photo = function() {
+ return this.each(function(i) {
+ var container_width = $(this).width();
+ var photo = $(this).gallery_get_photo();
+ var photo_width = photo.width();
+ if (container_width < photo_width) {
+ var proportion = container_width / photo_width;
+ photo.width(container_width);
+ photo.height(proportion * photo.height());
+ }
+ });
+ };
+
+ /**
+ * Get a thumbnail or resize photo within a container
+ * @param elementID The image container's ID
+ * @return object
+ */
+ $.fn.gallery_get_photo = function() {
+ var photo = $(this).find("img").filter(function() {
+ return this.id.match(/gPhotoId-\d+/);
+ });
+ return photo;
+ };
+
+ /**
+ * Get the sum of an element's height, margin-top, and margin-bottom
+ * @param elementID the element's ID
+ * @return int
+ */
+ $.fn.gallery_height = function() {
+ var ht = $(this).height();
+ var mt = parseInt($(this).css("margin-top"));
+ var mb = parseInt($(this).css("margin-bottom"));
+ return ht + parseInt(mt) + parseInt(mb);
+ };
+
+ // Add hover state to buttons
+ $.fn.gallery_hover_init = function() {
+ $(".ui-state-default").hover(
+ function(){
+ $(this).addClass("ui-state-hover");
+ },
+ function(){
+ $(this).removeClass("ui-state-hover");
+ }
+ );
+ };
+
+ // 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});
+ };
+
+ $.fn.gallery_context_menu = function() {
+ var in_progress = 0;
+ $(".gContextMenu *").removeAttr('title');
+ $(".gContextMenu ul").hide();
+ $(".gContextMenu").hover(
+ function() {
+ if (in_progress == 0) {
+ $(this).find("ul").slideDown("fast", function() { in_progress = 1; });
+ $(this).find(".gDialogLink").gallery_dialog();
+ $(this).find(".gAjaxLink").gallery_ajax();
+ }
+ },
+ function() {
+ $(this).find("ul").slideUp("slow", function() { in_progress = 0; });
+ }
+ );
+ };
+
+ $.gallery_auto_fit_window = function(imageWidth, imageHeight) {
+ var size = $.gallery_get_viewport_size();
+ var width = size.width() - 6,
+ height = size.height() - 6;
+
+ var ratio = width / imageWidth;
+ imageWidth *= ratio;
+ imageHeight *= ratio;
+
+ /* after scaling the width, check that the height fits */
+ if (imageHeight > height) {
+ ratio = height / imageHeight;
+ imageWidth *= ratio;
+ imageHeight *= ratio;
+ }
+
+ // handle the case where the calculation is almost zero (2.14e-14)
+ return {
+ top: Number((height - imageHeight) / 2),
+ left: Number((width - imageWidth) / 2),
+ width: Number(imageWidth),
+ height: Number(imageHeight)
+ };
+ };
+
})(jQuery);
+
diff --git a/lib/gallery.dialog.js b/lib/gallery.dialog.js
index fc66323e..4bbb8ab7 100644
--- a/lib/gallery.dialog.js
+++ b/lib/gallery.dialog.js
@@ -1,143 +1,137 @@
-/**
- * Fire openDialog() and prevent links from opening
- * @see openDialog()
- */
-function handleDialogEvent(event) {
- var target = event.currentTarget;
- if (!target) {
- target = event.srcElement;
- }
- openDialog(target);
- event.preventDefault();
-}
+(function($) {
+ $.widget("ui.gallery_dialog", {
+ _init: function() {
+ var self = this;
+ if (!self.options.immediate) {
+ this.element.click(function(event) {
+ event.preventDefault();
+ self._show($(event.currentTarget).attr("href"));
+ return false;
+ });
+ } else {
+ self._show(this.element.attr("href"));
+ }
+ },
-function ajaxify_dialog(on_success) {
- $("#gDialog form").ajaxForm({
- dataType: "json",
- success: function(data) {
- if (data.form) {
- $("#gDialog form").replaceWith(data.form);
- ajaxify_dialog(on_success);
- on_form_loaded();
- if (typeof data.reset == 'function') {
- eval(data.reset + '()');
- }
- }
- if (data.result == "success") {
- $("#gDialog").dialog("close");
- if (on_success) {
- on_success();
- } else if (data.location) {
- window.location = data.location;
- } else {
- window.location.reload();
- }
- }
- }
- });
-};
+ _show: function(sHref) {
+ var self = this;
+ var eDialog = '<div id="gDialog"></div>';
+
+ $("body").append(eDialog);
-/**
- * Display modal dialogs, populate dialog with trigger link's href
- * @requires ui.core
- * @requires ui.draggable
- * @requires ui.resizable
- * @requires ui.dialog
- * @see handleDialogEvent()
- * @see showLoading()
- */
-function openDialog(element, on_success) {
- var sHref = $(element).attr("href");
- var sTitle = $(element).attr("title");
- var eDialog = '<div id="gDialog"></div>';
- var dialogWidth;
+ if (!self.options.close) {
+ self.options.close = self.close_dialog;
+ }
+ $("#gDialog").dialog(self.options);
- $("body").append(eDialog);
+ $("#gDialog").gallery_show_loading();
- $("#gDialog").dialog({
- autoOpen: false,
- autoResize: true,
- modal: true,
- resizable: false,
- close: closeDialog
- });
+ $.get(sHref, function(data) {
+ $("#gDialog").html(data).gallery_show_loading();
- showLoading("#gDialog");
+ if ($("#gDialog form").length) {
+ self._trigger("form_loaded", null, $("#gDialog form"));
+ }
+ self._layout();
- $.get(sHref, function(data) {
- showLoading("#gDialog");
- $("#gDialog").html(data);
- var dialogHeight = $("#gDialog").height();
- var cssWidth = new String($("#gDialog form").css("width"));
- var childWidth = cssWidth.replace(/[^0-9]/g,"");
- if ($("#gDialog iframe").length) {
- dialogWidth = $(window).width() - 100;
- // Set the iframe width and height
- $("#gDialog iframe").width("100%");
- $("#gDialog iframe").height($(window).height() - 100);
- } else if (childWidth == "" || childWidth > 300) {
- dialogWidth = 500;
- }
- $("#gDialog").dialog('option', 'width', dialogWidth);
+ $("#gDialog").dialog("open");
+ // Remove titlebar for progress dialogs or set title
+ if ($("#gDialog #gProgress").length) {
+ $(".ui-dialog-titlebar").remove();
+ } else if ($("#gDialog h1").length) {
+ $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html());
+ } else if ($("#gDialog fieldset legend").length) {
+ $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html());
+ }
- on_form_loaded();
+ if ($("#gDialog form").length) {
+ self._ajaxify_dialog();
+ }
+ });
+ $("#gDialog").dialog("option", "self", self);
+ },
- $("#gDialog").dialog("open");
- // Remove titlebar for progress dialogs or set title
- if ($("#gDialog #gProgress").length) {
- $(".ui-dialog-titlebar").remove();
- } else if ($("#gDialog h1").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html());
- } else if ($("#gDialog fieldset legend").length) {
- $("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html());
- }
+ _layout: function() {
+ var dialogWidth;
+ var dialogHeight = $("#gDialog").height();
+ var cssWidth = new String($("#gDialog form").css("width"));
+ var childWidth = cssWidth.replace(/[^0-9]/g,"");
+ if ($("#gDialog iframe").length) {
+ dialogWidth = $(window).width() - 100;
+ // Set the iframe width and height
+ $("#gDialog iframe").width("100%").height($(window).height() - 100);
+ } else if (childWidth == "" || childWidth > 300) {
+ dialogWidth = 500;
+ }
+ $("#gDialog").dialog('option', 'width', dialogWidth);
+ },
+
+ form_loaded: function event(event, ui) {
+ // Should be defined (and localized) in the theme
+ MSG_CANCEL = MSG_CANCEL || 'Cancel';
+ var eCancel = '<a href="#" class="gCancel">' + MSG_CANCEL + '</a>';
+ if ($("#gDialog .submit").length) {
+ $("#gDialog .submit").addClass("ui-state-default ui-corner-all");
+ $("#gDialog .submit").parent().append(eCancel);
+ $("#gDialog .gCancel").click(function(event) {
+ $("gDialog").dialog("close");
+ event.preventDefault();
+ });
+ }
+ $("#gDialog .ui-state-default").hover(
+ function() {
+ $(this).addClass("ui-state-hover");
+ },
+ function() {
+ $(this).removeClass("ui-state-hover");
+ }
+ );
+ },
- ajaxify_dialog(on_success);
- });
- return false;
-}
+ close_dialog: function (event, ui) {
+ var self = $("#gDialog").dialog("option", "self");
+ if ($("#gDialog form").length) {
+ self._trigger("form_closing", null, $("#gDialog form"));
+ }
+ self._trigger("dialog_closing", null, $("#gDialog"));
+ $("#gDialog").dialog("destroy").remove();
+ },
-function on_form_loaded() {
- // Should be defined (and localized) in the theme
- MSG_CANCEL = MSG_CANCEL || 'Cancel';
- var eCancel = '<a href="javascript: closeDialog()" class="gCancel">' + MSG_CANCEL + '</a>';
- if ($("#gDialog .submit").length) {
- $("#gDialog .submit").addClass("ui-state-default ui-corner-all");
- $("#gDialog .submit").parent().append(eCancel);
- }
- $("#gDialog").dialog("option", "form", $("#gDialog form"));
- $("#gDialog .ui-state-default").hover(
- function() {
- $(this).addClass("ui-state-hover");
- },
- function() {
- $(this).removeClass("ui-state-hover");
- }
- );
-}
+ _ajaxify_dialog: function() {
+ var self = this;
+ $("#gDialog form").ajaxForm({
+ dataType: "json",
+ success: function(data) {
+ if (data.form) {
+ $("#gDialog form").replaceWith(data.form);
+ self._ajaxify_dialog();
+ self._trigger("form_loaded", null, $("#gDialog form"));
+ if (typeof data.reset == 'function') {
+ eval(data.reset + '()');
+ }
+ }
+ if (data.result == "success") {
+ if (data.location) {
+ window.location = data.location;
+ } else {
+ window.location.reload();
+ }
+ }
+ }
+ });
+ },
-function closeDialog() {
- var form = $("#gDialog").dialog("option", "form");
- if (form != null) {
- $("#gDialog").dialog("option", "form").trigger("form_closing");
- }
- $("#gDialog").dialog("destroy").remove();
-}
+ form_closing: function(event, ui) {},
+ dialog_closing: function(event, ui) {}
+ });
-/**
- * Toggle the processing indicator, both large and small
- * @param elementID Target ID, including #, to apply .gLoadingSize
- */
-function showLoading(elementID) {
- var size;
- switch (elementID) {
- case "#gDialog":
- case "#gPanel":
- size = "Large";
- break;
- default:
- size = "Small";
- break;
- }
- $(elementID).toggleClass("gLoading" + size);
-}
+ $.extend($.ui.gallery_dialog, {
+ defaults: {
+ autoOpen: false,
+ autoResize: true,
+ modal: true,
+ resizable: false,
+ position: "center"
+ }
+ });
+})(jQuery);
diff --git a/lib/gallery.panel.js b/lib/gallery.panel.js
index 022e4878..e0bf4259 100644
--- a/lib/gallery.panel.js
+++ b/lib/gallery.panel.js
@@ -1,62 +1,58 @@
-/**
- * Fire togglePanel() and prevent links from opening
- * @see togglePanel()
- */
-function handlePanelEvent(event) {
- togglePanel(event.currentTarget);
- event.preventDefault();
-}
+(function($) {
+ $.widget("ui.gallery_panel", {
+ _init: function() {
+ var self = this;
+ this.element.click(function(event) {
+ event.preventDefault();
+ var element = event.currentTarget;
+ var parent = $(element).parent().parent();
+ var sHref = $(element).attr("href");
+ var parentClass = $(parent).attr("class");
+ var ePanel = "<tr id=\"gPanel\"><td colspan=\"6\"></td></tr>";
-function togglePanel(element, on_success) {
- var parent = $(element).parent().parent();
- var sHref = $(element).attr("href");
- var parentClass = $(parent).attr("class");
- var ePanel = "<tr id=\"gPanel\"><td colspan=\"6\"></td></tr>";
+ if ($("#gPanel").length) {
+ $("#gPanel").slideUp("slow").remove();
+ if ($(element).attr("orig_text")) {
+ $(element).children(".gButtonText").text($(element).attr("orig_text"));
+ }
+ } else {
+ $(parent).after(ePanel);
+ $("#gPanel td").html(sHref);
+ $.get(sHref, function(data) {
+ $("#gPanel td").html(data);
+ self._ajaxify_panel();
+ if ($(element).attr("open_text")) {
+ $(element).attr("orig_text", $(element).children(".gButtonText").text());
+ $(element).children(".gButtonText").text($(element).attr("open_text"));
+ }
+ $("#gPanel").addClass(parentClass).show().slideDown("slow");
+ });
+ }
+ return false;
+ });
+ },
- if ($("#gPanel").length) {
- $("#gPanel").slideUp("slow");
- $("#gPanel *").remove();
- $("#gPanel").remove();
- if ($(element).attr("orig_text")) {
- $(element).children(".gButtonText").text($(element).attr("orig_text"));
- }
- //togglePanel(element, on_success);
- } else {
- $(parent).after(ePanel);
- //showLoading("#here");
- $("#gPanel td").html(sHref);
- $("#gPanel").addClass(parentClass).show().slideDown("slow");
- $.get(sHref, function(data) {
- $("#gPanel td").html(data);
- ajaxify_panel = function() {
- $("#gPanel td form").ajaxForm({
- dataType: "json",
- success: function(data) {
- if (data.form) {
- $("#gPanel td form").replaceWith(data.form);
- ajaxify_panel();
- }
- if (data.result == "success") {
- if (on_success) {
- on_success();
- } else if (data.location) {
- window.location = data.location;
- } else {
- window.location.reload();
- }
- }
- }
- });
- if ($("#gPanel td").hasClass("gLoadingLarge")) {
- showLoading("#gPanel td");
- }
- };
- ajaxify_panel();
- if ($(element).attr("open_text")) {
- $(element).attr("orig_text", $(element).children(".gButtonText").text());
- $(element).children(".gButtonText").text($(element).attr("open_text"));
- }
- });
- }
- return false;
-}
+ _ajaxify_panel: function () {
+ var self = this;
+ $("#gPanel td form").ajaxForm({
+ dataType: "json",
+ success: function(data) {
+ if (data.form) {
+ $("#gPanel td form").replaceWith(data.form);
+ self._ajaxify_panel();
+ }
+ if (data.result == "success") {
+ self._trigger("success", null, {});
+ if (data.location) {
+ window.location = data.location;
+ } else {
+ window.location.reload();
+ }
+ }
+ }
+ });
+ },
+
+ success: function(event, ui) {}
+ });
+ })(jQuery);
diff --git a/lib/gallery.show_full_size.js b/lib/gallery.show_full_size.js
index 8b271db9..2f365f0d 100644
--- a/lib/gallery.show_full_size.js
+++ b/lib/gallery.show_full_size.js
@@ -1,76 +1,49 @@
-/**
- * @todo Move inline CSS out to external style sheet (theme style sheet)
- */
-var show_full_size = function(image_url, image_width, image_height) {
- /*
- * Calculate the size of the image panel based on the size of the image and the size of the
- * window. Scale the image so the entire panel fits in the view port.
- */
- function _auto_fit(imageWidth, imageHeight) {
- // ui-dialog gives a padding of 2 pixels
- var windowWidth = $(window).width() - 10;
- var windowHeight = $(window).height() - 10;
+(function($) {
+ /**
+ * @todo Move inline CSS out to external style sheet (theme style sheet)
+ */
+ $.gallery_show_full_size = function(image_url, image_width, image_height) {
+ var width = $(document).width();
+ var height = $(document).height();
+ var size = $.gallery_get_viewport_size();
- /* If the width is greater then scale the image width first */
- if (imageWidth > windowWidth) {
- var ratio = windowWidth / imageWidth;
- imageWidth *= ratio;
- imageHeight *= ratio;
- }
- /* after scaling the width, check that the height fits */
- if (imageHeight > windowHeight) {
- var ratio = windowHeight / imageHeight;
- imageWidth *= ratio;
- imageHeight *= ratio;
- }
+ $("body").append('<div id="gFullsizeOverlay" class="ui-dialog-overlay" ' +
+ 'style="border: none; margin: 0; padding: 0; background-color: #000; ' +
+ 'position: absolute; top: 0px; left: 0px; ' +
+ 'width: ' + size.width() + 'px; height: ' + size.height() + 'px;' +
+ ' opacity: 0.7; filter: alpha(opacity=70);' +
+ '-moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; ' +
+ '-moz-background-inline-policy: -moz-initial; z-index: 1001;"> </div>');
- // handle the case where the calculation is almost zero (2.14e-14)
- return {
- top: Number((windowHeight - imageHeight) / 2),
- left: Number((windowWidth - imageWidth) / 2),
- width: Number(imageWidth),
- height: Number(imageHeight)
- };
- }
+ var image_size = $.gallery_auto_fit_window(image_width, image_height);
- var width = $(document).width();
- var height = $(document).height();
+ $("body").append('<div id="gFullsize" class="ui-dialog ui-widget" ' +
+ 'style="overflow: hidden; display: block; ' +
+ 'position: absolute; z-index: 1002; outline-color: -moz-use-text-color; ' +
+ 'outline-style: none; outline-width: 0px; ' +
+ 'height: ' + image_size.height + 'px; ' +
+ 'width: ' + image_size.width + 'px; ' +
+ 'top: ' + image_size.top + 'px; left: ' + image_size.left + 'px;">' +
+ '<img id="gFullSizeImage" src="' + image_url + '"' +
+ 'height="' + image_size.height + '" width="' + image_size.width + '"/></div>');
- $("body").append('<div id="gFullsizeOverlay" class="ui-dialog-overlay" ' +
- 'style="border: none; margin: 0; padding: 0; background-color: #000; ' +
- 'position: absolute; top: 0px; left: 0px; ' +
- 'width: ' + width + 'px; height: ' + height + 'px; opacity: 0.7; filter: alpha(opacity=70);' +
- '-moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; ' +
- '-moz-background-inline-policy: -moz-initial; z-index: 1001;"> </div>');
-
- var image_size = _auto_fit(image_width, image_height);
-
- $("body").append('<div id="gFullsize" class="ui-dialog ui-widget" ' +
- 'style="overflow: hidden; display: block; ' +
- 'position: absolute; z-index: 1002; outline-color: -moz-use-text-color; ' +
- 'outline-style: none; outline-width: 0px; ' +
- 'height: ' + image_size.height + 'px; ' +
- 'width: ' + image_size.width + 'px; ' +
- 'top: ' + image_size.top + 'px; left: ' + image_size.left + 'px;">' +
- '<img id="gFullSizeImage" src="' + image_url + '"' +
- 'height="' + image_size.height + '" width="' + image_size.width + '"/></div>');
-
- $("#gFullsize").append('<span id="gFullsizeClose" class="fg-button ui-icon ui-state-default ' +
- 'ui-icon-closethick ui-corner-all" style="z-index: 1003; position: absolute; ' +
- 'right: 1em; top: 1em;"></span>');
- $("#gFullsizeClose").click(function() {
- $("#gFullsizeOverlay*").remove();
- $("#gFullsize").remove();
- });
- $(window).resize(function() {
- $("#gFullsizeOverlay").width($(document).width());
- $("#gFullsizeOverlay").height($(document).height());
- image_size = _auto_fit(image_width, image_height);
- $("#gFullsize").height(image_size.height);
- $("#gFullsize").width(image_size.width);
- $("#gFullsize").css("top", image_size.top);
- $("#gFullsize").css("left", image_size.left);
- $("#gFullSizeImage").height(image_size.height);
- $("#gFullSizeImage").width(image_size.width);
- });
-};
+ $("#gFullsize").append('<span id="gFullsizeClose" class="fg-button ui-icon ui-state-default ' +
+ 'ui-icon-closethick ui-corner-all" style="z-index: 1003; position: absolute; ' +
+ 'right: 1em; top: 1em;"></span>');
+ $("#gFullsizeClose").click(function() {
+ $("#gFullsizeOverlay*").remove();
+ $("#gFullsize").remove();
+ });
+ $(window).resize(function() {
+ $("#gFullsizeOverlay").width($(document).width())
+ .height($(document).height());
+ image_size = $.gallery_auto_fit_window(image_width, image_height);
+ $("#gFullsize").height(image_size.height)
+ .width(image_size.width)
+ .css("top", image_size.top)
+ .css("left", image_size.left);
+ $("#gFullSizeImage").height(image_size.height)
+ .width(image_size.width);
+ });
+ };
+})(jQuery);
diff --git a/lib/jquery-ui.js b/lib/jquery-ui.js
index 0c6a0ebe..4939d009 100644
--- a/lib/jquery-ui.js
+++ b/lib/jquery-ui.js
@@ -45,18 +45,6 @@ jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.bro
* ui.core.js
*/
(function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f<k.length;f++){var h=c.trim(k[f]),d="ui-resizable-"+h;var g=c('<div class="ui-resizable-handle '+d+'"></div>');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidth<k.width),l=a(k.height)&&h.maxHeight&&(h.maxHeight<k.height),g=a(k.width)&&h.minWidth&&(h.minWidth>k.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e<this._proportionallyResizeElements.length;e++){var g=this._proportionallyResizeElements[e];if(!this.borderDif){var d=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],h=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=c.map(d,function(k,m){var l=parseInt(k,10)||0,n=parseInt(h[m],10)||0;return l+n})}if(c.browser.msie&&!(!(c(f).is(":hidden")||c(f).parents(":hidden").length))){continue}g.css({height:(f.height()-this.borderDif[0]-this.borderDif[2])||0,width:(f.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var e=this.element,h=this.options;this.elementOffset=e.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));c.extend(c.ui.resizable,{version:"1.7.2",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,t){var s=(q[t]||0)+(j[t]||0);if(s&&s>=0){o[t]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=s._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)){s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/s.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*s.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);;/*
- * jQuery UI Selectable 1.7.2
- *
- * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * http://docs.jquery.com/UI/Selectables
- *
- * Depends:
- * ui.core.js
- */
-(function(a){a.widget("ui.selectable",a.extend({},a.ui.mouse,{_init:function(){var b=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]);c.each(function(){var d=a(this);var e=d.offset();a.data(this,"selectable-item",{element:this,$element:d,left:e.left,top:e.top,right:e.left+d.outerWidth(),bottom:e.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(d){var b=this;this.opos=[d.pageX,d.pageY];if(this.options.disabled){return}var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",d);a(c.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:d.clientX,top:d.clientY,width:0,height:0});if(c.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var e=a.data(this,"selectable-item");e.startselected=true;if(!d.metaKey){e.$element.removeClass("ui-selected");e.selected=false;e.$element.addClass("ui-unselecting");e.unselecting=true;b._trigger("unselecting",d,{unselecting:e.element})}});a(d.target).parents().andSelf().each(function(){var e=a.data(this,"selectable-item");if(e){e.$element.removeClass("ui-unselecting").addClass("ui-selecting");e.unselecting=false;e.selecting=true;e.selected=true;b._trigger("selecting",d,{selecting:e.element});return false}})},_mouseDrag:function(i){var c=this;this.dragged=true;if(this.options.disabled){return}var e=this.options;var d=this.opos[0],h=this.opos[1],b=i.pageX,g=i.pageY;if(d>b){var f=b;b=d;d=f}if(h>g){var f=g;g=h;h=f}this.helper.css({left:d,top:h,width:b-d,height:g-h});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!j||j.element==c.element[0]){return}var k=false;if(e.tolerance=="touch"){k=(!(j.left>b||j.right<d||j.top>g||j.bottom<h))}else{if(e.tolerance=="fit"){k=(j.left>d&&j.right<b&&j.top>h&&j.bottom<g)}}if(k){if(j.selected){j.$element.removeClass("ui-selected");j.selected=false}if(j.unselecting){j.$element.removeClass("ui-unselecting");j.unselecting=false}if(!j.selecting){j.$element.addClass("ui-selecting");j.selecting=true;c._trigger("selecting",i,{selecting:j.element})}}else{if(j.selecting){if(i.metaKey&&j.startselected){j.$element.removeClass("ui-selecting");j.selecting=false;j.$element.addClass("ui-selected");j.selected=true}else{j.$element.removeClass("ui-selecting");j.selecting=false;if(j.startselected){j.$element.addClass("ui-unselecting");j.unselecting=true}c._trigger("unselecting",i,{unselecting:j.element})}}if(j.selected){if(!i.metaKey&&!j.startselected){j.$element.removeClass("ui-selected");j.selected=false;j.$element.addClass("ui-unselecting");j.unselecting=true;c._trigger("unselecting",i,{unselecting:j.element})}}}});return false},_mouseStop:function(d){var b=this;this.dragged=false;var c=this.options;a(".ui-unselecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-unselecting");e.unselecting=false;e.startselected=false;b._trigger("unselected",d,{unselected:e.element})});a(".ui-selecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-selecting").addClass("ui-selected");e.selecting=false;e.selected=true;e.startselected=true;b._trigger("selected",d,{selected:e.element})});this._trigger("stop",d);this.helper.remove();return false}}));a.extend(a.ui.selectable,{version:"1.7.2",defaults:{appendTo:"body",autoRefresh:true,cancel:":input,option",delay:0,distance:0,filter:"*",tolerance:"touch"}})})(jQuery);;/*
* jQuery UI Sortable 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
@@ -107,18 +95,6 @@ jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.bro
* ui.core.js
*/
(function(a){a.widget("ui.tabs",{_init:function(){if(this.options.deselectable!==undefined){this.options.collapsible=this.options.deselectable}this._tabify(true)},_setData:function(b,c){if(b=="selected"){if(this.options.collapsible&&c==this.options.selected){return}this.select(c)}else{this.options[b]=c;if(b=="deselectable"){this.options.collapsible=c}this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+a.data(b)},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+a.data(this.list[0]));return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(c,b){return{tab:c,panel:b,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(n){this.list=this.element.children("ul:first");this.lis=a("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);var p=this,d=this.options;var c=/^#.+/;this.anchors.each(function(r,o){var q=a(o).attr("href");var s=q.split("#")[0],u;if(s&&(s===location.toString().split("#")[0]||(u=a("base")[0])&&s===u.href)){q=o.hash;o.href=q}if(c.test(q)){p.panels=p.panels.add(p._sanitizeSelector(q))}else{if(q!="#"){a.data(o,"href.tabs",q);a.data(o,"load.tabs",q.replace(/#.*$/,""));var w=p._tabId(o);o.href="#"+w;var v=a("#"+w);if(!v.length){v=a(d.panelTemplate).attr("id",w).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(p.panels[r-1]||p.list);v.data("destroy.tabs",true)}p.panels=p.panels.add(v)}else{d.disabled.push(r)}}});if(n){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(d.selected===undefined){if(location.hash){this.anchors.each(function(q,o){if(o.hash==location.hash){d.selected=q;return false}})}if(typeof d.selected!="number"&&d.cookie){d.selected=parseInt(p._cookie(),10)}if(typeof d.selected!="number"&&this.lis.filter(".ui-tabs-selected").length){d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}d.selected=d.selected||0}else{if(d.selected===null){d.selected=-1}}d.selected=((d.selected>=0&&this.anchors[d.selected])||d.selected<0)?d.selected:0;d.disabled=a.unique(d.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(q,o){return p.lis.index(q)}))).sort();if(a.inArray(d.selected,d.disabled)!=-1){d.disabled.splice(a.inArray(d.selected,d.disabled),1)}this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");if(d.selected>=0&&this.anchors.length){this.panels.eq(d.selected).removeClass("ui-tabs-hide");this.lis.eq(d.selected).addClass("ui-tabs-selected ui-state-active");p.element.queue("tabs",function(){p._trigger("show",null,p._ui(p.anchors[d.selected],p.panels[d.selected]))});this.load(d.selected)}a(window).bind("unload",function(){p.lis.add(p.anchors).unbind(".tabs");p.lis=p.anchors=p.panels=null})}else{d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}this.element[d.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");if(d.cookie){this._cookie(d.selected,d.cookie)}for(var g=0,m;(m=this.lis[g]);g++){a(m)[a.inArray(g,d.disabled)!=-1&&!a(m).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled")}if(d.cache===false){this.anchors.removeData("cache.tabs")}this.lis.add(this.anchors).unbind(".tabs");if(d.event!="mouseover"){var f=function(o,i){if(i.is(":not(.ui-state-disabled)")){i.addClass("ui-state-"+o)}};var j=function(o,i){i.removeClass("ui-state-"+o)};this.lis.bind("mouseover.tabs",function(){f("hover",a(this))});this.lis.bind("mouseout.tabs",function(){j("hover",a(this))});this.anchors.bind("focus.tabs",function(){f("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var b,h;if(d.fx){if(a.isArray(d.fx)){b=d.fx[0];h=d.fx[1]}else{b=h=d.fx}}function e(i,o){i.css({display:""});if(a.browser.msie&&o.opacity){i[0].style.removeAttribute("filter")}}var k=h?function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.hide().removeClass("ui-tabs-hide").animate(h,h.duration||"normal",function(){e(o,h);p._trigger("show",null,p._ui(i,o[0]))})}:function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");p._trigger("show",null,p._ui(i,o[0]))};var l=b?function(o,i){i.animate(b,b.duration||"normal",function(){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");e(i,b);p.element.dequeue("tabs")})}:function(o,i,q){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");p.element.dequeue("tabs")};this.anchors.bind(d.event+".tabs",function(){var o=this,r=a(this).closest("li"),i=p.panels.filter(":not(.ui-tabs-hide)"),q=a(p._sanitizeSelector(this.hash));if((r.hasClass("ui-tabs-selected")&&!d.collapsible)||r.hasClass("ui-state-disabled")||r.hasClass("ui-state-processing")||p._trigger("select",null,p._ui(this,q[0]))===false){this.blur();return false}d.selected=p.anchors.index(this);p.abort();if(d.collapsible){if(r.hasClass("ui-tabs-selected")){d.selected=-1;if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){l(o,i)}).dequeue("tabs");this.blur();return false}else{if(!i.length){if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this));this.blur();return false}}}if(d.cookie){p._cookie(d.selected,d.cookie)}if(q.length){if(i.length){p.element.queue("tabs",function(){l(o,i)})}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this))}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(a.browser.msie){this.blur()}});this.anchors.bind("click.tabs",function(){return false})},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var c=a.data(this,"href.tabs");if(c){this.href=c}var d=a(this).unbind(".tabs");a.each(["href","load","cache"],function(e,f){d.removeData(f+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){if(a.data(this,"destroy.tabs")){a(this).remove()}else{a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}});if(b.cookie){this._cookie(null,b.cookie)}},add:function(e,d,c){if(c===undefined){c=this.anchors.length}var b=this,g=this.options,i=a(g.tabTemplate.replace(/#\{href\}/g,e).replace(/#\{label\}/g,d)),h=!e.indexOf("#")?e.replace("#",""):this._tabId(a("a",i)[0]);i.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var f=a("#"+h);if(!f.length){f=a(g.panelTemplate).attr("id",h).data("destroy.tabs",true)}f.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(c>=this.lis.length){i.appendTo(this.list);f.appendTo(this.list[0].parentNode)}else{i.insertBefore(this.lis[c]);f.insertBefore(this.panels[c])}g.disabled=a.map(g.disabled,function(k,j){return k>=c?++k:k});this._tabify();if(this.anchors.length==1){i.addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[c],this.panels[c]))},remove:function(b){var d=this.options,e=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();if(e.hasClass("ui-tabs-selected")&&this.anchors.length>1){this.select(b+(b+1<this.anchors.length?1:-1))}d.disabled=a.map(a.grep(d.disabled,function(g,f){return g!=b}),function(g,f){return g>=b?--g:g});this._tabify();this._trigger("remove",null,this._ui(e.find("a")[0],c[0]))},enable:function(b){var c=this.options;if(a.inArray(b,c.disabled)==-1){return}this.lis.eq(b).removeClass("ui-state-disabled");c.disabled=a.grep(c.disabled,function(e,d){return e!=b});this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]))},disable:function(c){var b=this,d=this.options;if(c!=d.selected){this.lis.eq(c).addClass("ui-state-disabled");d.disabled.push(c);d.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}},select:function(b){if(typeof b=="string"){b=this.anchors.index(this.anchors.filter("[href$="+b+"]"))}else{if(b===null){b=-1}}if(b==-1&&this.options.collapsible){b=this.options.selected}this.anchors.eq(b).trigger(this.options.event+".tabs")},load:function(e){var c=this,g=this.options,b=this.anchors.eq(e)[0],d=a.data(b,"load.tabs");this.abort();if(!d||this.element.queue("tabs").length!==0&&a.data(b,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(e).addClass("ui-state-processing");if(g.spinner){var f=a("span",b);f.data("label.tabs",f.html()).html(g.spinner)}this.xhr=a.ajax(a.extend({},g.ajaxOptions,{url:d,success:function(i,h){a(c._sanitizeSelector(b.hash)).html(i);c._cleanup();if(g.cache){a.data(b,"cache.tabs",true)}c._trigger("load",null,c._ui(c.anchors[e],c.panels[e]));try{g.ajaxOptions.success(i,h)}catch(j){}c.element.dequeue("tabs")}}))},abort:function(){this.element.queue([]);this.panels.stop(false,true);if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup()},url:function(c,b){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",b)},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.7.2",getter:"length",defaults:{ajaxOptions:null,cache:false,cookie:null,collapsible:false,disabled:[],event:"click",fx:null,idPrefix:"ui-tabs-",panelTemplate:"<div></div>",spinner:"<em>Loading&#8230;</em>",tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>'}});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(d,f){var b=this,g=this.options;var c=b._rotate||(b._rotate=function(h){clearTimeout(b.rotation);b.rotation=setTimeout(function(){var i=g.selected;b.select(++i<b.anchors.length?i:0)},d);if(h){h.stopPropagation()}});var e=b._unrotate||(b._unrotate=!f?function(h){if(h.clientX){b.rotate(null)}}:function(h){t=g.selected;c()});if(d){this.element.bind("tabsshow",c);this.anchors.bind(g.event+".tabs",e);c()}else{clearTimeout(b.rotation);this.element.unbind("tabsshow",c);this.anchors.unbind(g.event+".tabs",e);delete this._rotate;delete this._unrotate}}})})(jQuery);;/*
- * jQuery UI Datepicker 1.7.2
- *
- * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * http://docs.jquery.com/UI/Datepicker
- *
- * Depends:
- * ui.core.js
- */
-(function($){$.extend($.ui,{datepicker:{version:"1.7.2"}});var PROP_NAME="datepicker";function Datepicker(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass="ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dateFormat:"mm/dd/yy",firstDay:0,isRTL:false};this._defaults={showOn:"focus",showAnim:"show",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,showMonthAfterYear:false,yearRange:"-10:+10",showOtherMonths:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"normal",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false};$.extend(this._defaults,this.regional[""]);this.dpDiv=$('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(target,inst){var input=$(target);inst.append=$([]);inst.trigger=$([]);if(input.hasClass(this.markerClassName)){return}var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){inst.append=$('<span class="'+this._appendClass+'">'+appendText+"</span>");input[isRTL?"before":"after"](inst.append)}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");inst.trigger=$(this._get(inst,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$('<button type="button"></button>').addClass(this._triggerClass).html(buttonImage==""?buttonText:$("<img/>").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](inst.trigger);inst.trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return}divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst);this._updateAlternate(inst)},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$('<input type="text" id="'+id+'" size="1" style="position: absolute; top: -100px;"/>');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){inst.append.remove();inst.trigger.remove();$target.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;inst.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().removeClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;inst.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().addClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i<this._disabledInputs.length;i++){if(this._disabledInputs[i]==target){return true}}return false},_getInst:function(target){try{return $.data(target,PROP_NAME)}catch(err){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(target,name,value){var inst=this._getInst(target);if(arguments.length==2&&typeof name=="string"){return(name=="defaults"?$.extend({},$.datepicker._defaults):(inst?(name=="all"?$.extend({},inst.settings):this._get(inst,name)):null))}var settings=name||{};if(typeof name=="string"){settings={};settings[name]=value}if(inst){if(this._curInst==inst){this._hideDatepicker(null)}var date=this._getDateDatepicker(target);extendRemove(inst.settings,settings);this._setDateDatepicker(target,date);this._updateDatepicker(inst)}},_changeDatepicker:function(target,name,value){this._optionDatepicker(target,name,value)},_refreshDatepicker:function(target){var inst=this._getInst(target);if(inst){this._updateDatepicker(inst)}},_setDateDatepicker:function(target,date,endDate){var inst=this._getInst(target);if(inst){this._setDate(inst,date,endDate);this._updateDatepicker(inst);this._updateAlternate(inst)}},_getDateDatepicker:function(target){var inst=this._getInst(target);if(inst&&!inst.inline){this._setDateFromField(inst)}return(inst?this._getDate(inst):null)},_doKeyDown:function(event){var inst=$.datepicker._getInst(event.target);var handled=true;var isRTL=inst.dpDiv.is(".ui-datepicker-rtl");inst._keyEvent=true;if($.datepicker._datepickerShowing){switch(event.keyCode){case 9:$.datepicker._hideDatepicker(null,"");break;case 13:var sel=$("td."+$.datepicker._dayOverClass+", td."+$.datepicker._currentClass,inst.dpDiv);if(sel[0]){$.datepicker._selectDay(event.target,inst.selectedMonth,inst.selectedYear,sel[0])}else{$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"))}return false;break;case 27:$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"));break;case 33:$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M");break;case 34:$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M");break;case 35:if(event.ctrlKey||event.metaKey){$.datepicker._clearDate(event.target)}handled=event.ctrlKey||event.metaKey;break;case 36:if(event.ctrlKey||event.metaKey){$.datepicker._gotoToday(event.target)}handled=event.ctrlKey||event.metaKey;break;case 37:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?+1:-1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M")}break;case 38:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,-7,"D")}handled=event.ctrlKey||event.metaKey;break;case 39:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?-1:+1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M")}break;case 40:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,+7,"D")}handled=event.ctrlKey||event.metaKey;break;default:handled=false}}else{if(event.keyCode==36&&event.ctrlKey){$.datepicker._showDatepicker(this)}else{handled=false}}if(handled){event.preventDefault();event.stopPropagation()}},_doKeyPress:function(event){var inst=$.datepicker._getInst(event.target);if($.datepicker._get(inst,"constrainInput")){var chars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat"));var chr=String.fromCharCode(event.charCode==undefined?event.keyCode:event.charCode);return event.ctrlKey||(chr<" "||!chars||chars.indexOf(chr)>-1)}},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return}var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};var self=this;inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){$(this).removeClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).removeClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).removeClass("ui-datepicker-next-hover")}}).bind("mouseover",function(){if(!self._isDisabledDatepicker(inst.inline?inst.dpDiv.parent()[0]:inst.input[0])){$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");$(this).addClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).addClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).addClass("ui-datepicker-next-hover")}}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();var numMonths=this._getNumberOfMonths(inst);var cols=numMonths[1];var width=17;if(cols>1){inst.dpDiv.addClass("ui-datepicker-multi-"+cols).css("width",(width*cols)+"em")}else{inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("")}inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"&&inst==$.datepicker._curInst){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var dpWidth=inst.dpDiv.outerWidth();var dpHeight=inst.dpDiv.outerHeight();var inputWidth=inst.input?inst.input.outerWidth():0;var inputHeight=inst.input?inst.input.outerHeight():0;var viewWidth=(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)+$(document).scrollLeft();var viewHeight=(window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)+$(document).scrollTop();offset.left-=(this._get(inst,"isRTL")?(dpWidth-inputWidth):0);offset.left-=(isFixed&&offset.left==inst.input.offset().left)?$(document).scrollLeft():0;offset.top-=(isFixed&&offset.top==(inst.input.offset().top+inputHeight))?$(document).scrollTop():0;offset.left-=(offset.left+dpWidth>viewWidth&&viewWidth>dpWidth)?Math.abs(offset.left+dpWidth-viewWidth):0;offset.top-=(offset.top+dpHeight>viewHeight&&viewHeight>dpHeight)?Math.abs(offset.top+dpHeight+inputHeight*2-viewHeight):0;return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return}if(inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(event){if(!$.datepicker._curInst){return}var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);if(this._isDisabledDatepicker(target[0])){return}this._adjustInstDate(inst,offset+(period=="M"?this._get(inst,"showCurrentAtPos"):0),period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_selectDay:function(id,month,year,td){var target=$(id);if($(td).hasClass(this._unselectableClass)||this._isDisabledDatepicker(target[0])){return}var inst=this._getInst(target[0]);inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay));this._updateDatepicker(inst)}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof(inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat")||this._get(inst,"dateFormat");var date=this._getDate(inst);dateStr=this.formatDate(altFormat,date,this._getFormatConfig(inst));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDate<firstMon){checkDate.setDate(checkDate.getDate()-3);return $.datepicker.iso8601Week(checkDate)}else{if(checkDate>new Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)<firstDay-3){return 1}}}return Math.floor(((checkDate-firstMon)/86400000)/7)+1},parseDate:function(format,value,settings){if(format==null||value==null){throw"Invalid arguments"}value=(typeof value=="object"?value.toString():value+"");if(value==""){return null}var shortYearCutoff=(settings?settings.shortYearCutoff:null)||this._defaults.shortYearCutoff;var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var year=-1;var month=-1;var day=-1;var doy=-1;var literal=false;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var getNumber=function(match){lookAhead(match);var origSize=(match=="@"?14:(match=="y"?4:(match=="o"?3:2)));var size=origSize;var num=0;while(size>0&&iValue<value.length&&value.charAt(iValue)>="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j<names.length;j++){size=Math.max(size,names[j].length)}var name="";var iInit=iValue;while(size>0&&iValue<value.length){name+=value.charAt(iValue++);for(var i=0;i<names.length;i++){if(name==names[i]){return i+1}}size--}throw"Unknown name at position "+iInit};var checkLiteral=function(){if(value.charAt(iValue)!=format.charAt(iFormat)){throw"Unexpected literal at position "+iValue}iValue++};var iValue=0;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{checkLiteral()}}else{switch(format.charAt(iFormat)){case"d":day=getNumber("d");break;case"D":getName("D",dayNamesShort,dayNames);break;case"o":doy=getNumber("o");break;case"m":month=getNumber("m");break;case"M":month=getName("M",monthNamesShort,monthNames);break;case"y":year=getNumber("y");break;case"@":var date=new Date(getNumber("@"));year=date.getFullYear();month=date.getMonth()+1;day=date.getDate();break;case"'":if(lookAhead("'")){checkLiteral()}else{literal=true}break;default:checkLiteral()}}}if(year==-1){year=new Date().getFullYear()}else{if(year<100){year+=new Date().getFullYear()-new Date().getFullYear()%100+(year<=shortYearCutoff?0:-100)}}if(doy>-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=this._daylightSavingAdjust(new Date(year,month-1,day));if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var formatNumber=function(match,value,len){var num=""+value;if(lookAhead(match)){while(num.length<len){num="0"+num}}return num};var formatName=function(match,value,shortNames,longNames){return(lookAhead(match)?longNames[value]:shortNames[value])};var output="";var literal=false;if(date){for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{output+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":output+=formatNumber("d",date.getDate(),2);break;case"D":output+=formatName("D",date.getDay(),dayNamesShort,dayNames);break;case"o":var doy=date.getDate();for(var m=date.getMonth()-1;m>=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{chars+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":case"m":case"y":case"@":chars+="0123456789";break;case"D":case"M":return null;case"'":if(lookAhead("'")){chars+="'"}else{literal=true}break;default:chars+=format.charAt(iFormat)}}}return chars},_get:function(inst,name){return inst.settings[name]!==undefined?inst.settings[name]:this._defaults[name]},_setDateFromField:function(inst){var dateFormat=this._get(inst,"dateFormat");var dates=inst.input?inst.input.val():null;inst.endDay=inst.endMonth=inst.endYear=null;var date=defaultDate=this._getDefaultDate(inst);var settings=this._getFormatConfig(inst);try{date=this.parseDate(dateFormat,dates,settings)||defaultDate}catch(event){this.log(event);date=defaultDate}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates?date.getDate():0);inst.currentMonth=(dates?date.getMonth():0);inst.currentYear=(dates?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setDate(date.getDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));date=(date&&date.toString()=="Invalid Date"?defaultDate:date);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return this._daylightSavingAdjust(date)},_daylightSavingAdjust:function(date){if(!date){return null}date.setHours(date.getHours()>12?date.getHours()+2:0);return date},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return startDate},_generateHTML:function(inst){var today=new Date();today=this._daylightSavingAdjust(new Date(today.getFullYear(),today.getMonth(),today.getDate()));var isRTL=this._get(inst,"isRTL");var showButtonPanel=this._get(inst,"showButtonPanel");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=this._daylightSavingAdjust((!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=this._daylightSavingAdjust(new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate()));maxDraw=(minDate&&maxDraw<minDate?minDate:maxDraw);while(this._daylightSavingAdjust(new Date(drawYear,drawMonth,1))>maxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}inst.drawMonth=drawMonth;inst.drawYear=drawYear;var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,this._daylightSavingAdjust(new Date(drawYear,drawMonth-stepMonths,1)),this._getFormatConfig(inst)));var prev=(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', -"+stepMonths+", 'M');\" title=\""+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>"));var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,this._daylightSavingAdjust(new Date(drawYear,drawMonth+stepMonths,1)),this._getFormatConfig(inst)));var next=(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', +"+stepMonths+", 'M');\" title=\""+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>"));var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var controls=(!inst.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">'+this._get(inst,"closeText")+"</button>":"");var buttonPanel=(showButtonPanel)?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(isRTL?controls:"")+(this._isInRange(inst,gotoDate)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#'+inst.id+"');\">"+currentText+"</button>":"")+(isRTL?"":controls)+"</div>":"";var firstDay=parseInt(this._get(inst,"firstDay"),10);firstDay=(isNaN(firstDay)?0:firstDay);var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var monthNamesShort=this._get(inst,"monthNamesShort");var beforeShowDay=this._get(inst,"beforeShowDay");var showOtherMonths=this._get(inst,"showOtherMonths");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var endDate=inst.endDay?this._daylightSavingAdjust(new Date(inst.endYear,inst.endMonth,inst.endDay)):currentDate;var defaultDate=this._getDefaultDate(inst);var html="";for(var row=0;row<numMonths[0];row++){var group="";for(var col=0;col<numMonths[1];col++){var selectedDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,inst.selectedDay));var cornerClass=" ui-corner-all";var calender="";if(isMultiMonth){calender+='<div class="ui-datepicker-group ui-datepicker-group-';switch(col){case 0:calender+="first";cornerClass=" ui-corner-"+(isRTL?"right":"left");break;case numMonths[1]-1:calender+="last";cornerClass=" ui-corner-"+(isRTL?"left":"right");break;default:calender+="middle";cornerClass="";break}calender+='">'}calender+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+cornerClass+'">'+(/all|left/.test(cornerClass)&&row==0?(isRTL?next:prev):"")+(/all|right/.test(cornerClass)&&row==0?(isRTL?prev:next):"")+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,monthNames,monthNamesShort)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var thead="";for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;thead+="<th"+((dow+firstDay+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+dayNames[day]+'">'+dayNamesMin[day]+"</span></th>"}calender+=thead+"</tr></thead><tbody>";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));var printDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,1-leadDays));for(var dRow=0;dRow<numRows;dRow++){calender+="<tr>";var tbody="";for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDate<minDate)||(maxDate&&printDate>maxDate);tbody+='<td class="'+((dow+firstDay+6)%7>=5?" ui-datepicker-week-end":"")+(otherMonth?" ui-datepicker-other-month":"")+((printDate.getTime()==selectedDate.getTime()&&drawMonth==inst.selectedMonth&&inst._keyEvent)||(defaultDate.getTime()==printDate.getTime()&&defaultDate.getTime()==selectedDate.getTime())?" "+this._dayOverClass:"")+(unselectable?" "+this._unselectableClass+" ui-state-disabled":"")+(otherMonth&&!showOtherMonths?"":" "+daySettings[1]+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?"":" onclick=\"DP_jQuery.datepicker._selectDay('#"+inst.id+"',"+drawMonth+","+drawYear+', this);return false;"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():"&#xa0;"):(unselectable?'<span class="ui-state-default">'+printDate.getDate()+"</span>":'<a class="ui-state-default'+(printDate.getTime()==today.getTime()?" ui-state-highlight":"")+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" ui-state-active":"")+'" href="#">'+printDate.getDate()+"</a>"))+"</td>";printDate.setDate(printDate.getDate()+1);printDate=this._daylightSavingAdjust(printDate)}calender+=tbody+"</tr>"}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}calender+="</tbody></table>"+(isMultiMonth?"</div>"+((numMonths[0]>0&&col==numMonths[1]-1)?'<div class="ui-datepicker-row-break"></div>':""):"");group+=calender}html+=group}html+=buttonPanel+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,monthNames,monthNamesShort){minDate=(inst.rangeStart&&minDate&&selectedDate<minDate?selectedDate:minDate);var changeMonth=this._get(inst,"changeMonth");var changeYear=this._get(inst,"changeYear");var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='<div class="ui-datepicker-title">';var monthHtml="";if(secondary||!changeMonth){monthHtml+='<span class="ui-datepicker-month">'+monthNames[drawMonth]+"</span> "}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='<select class="ui-datepicker-month" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'M');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='<option value="'+month+'"'+(month==drawMonth?' selected="selected"':"")+">"+monthNamesShort[month]+"</option>"}}monthHtml+="</select>"}if(!showMonthAfterYear){html+=monthHtml+((secondary||changeMonth||changeYear)&&(!(changeMonth&&changeYear))?"&#xa0;":"")}if(secondary||!changeYear){html+='<span class="ui-datepicker-year">'+drawYear+"</span>"}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=drawYear+parseInt(years[0],10);endYear=drawYear+parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='<select class="ui-datepicker-year" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'Y');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(;year<=endYear;year++){html+='<option value="'+year+'"'+(year==drawYear?' selected="selected"':"")+">"+year+"</option>"}html+="</select>"}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?"&#xa0;":"")+monthHtml}html+="</div>";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart<newMinDate?inst.rangeStart:newMinDate);var minDate=newMinDate||this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date>=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.7.2";window.DP_jQuery=$})(jQuery);;/*
* jQuery UI Progressbar 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
@@ -163,4 +139,511 @@ jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(v
* Depends:
* effects.core.js
*/
-(function(a){a.effects.transfer=function(b){return this.queue(function(){var f=a(this),h=a(b.options.to),e=h.offset(),g={top:e.top,left:e.left,height:h.innerHeight(),width:h.innerWidth()},d=f.offset(),c=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);; \ No newline at end of file
+(function(a){a.effects.transfer=function(b){return this.queue(function(){var f=a(this),h=a(b.options.to),e=h.offset(),g={top:e.top,left:e.left,height:h.innerHeight(),width:h.innerWidth()},d=f.offset(),c=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);;/*
+ * jQuery UI Selectable @VERSION
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function($) {
+
+ $.widget('ui.selectable', $.extend({}, $.ui.mouse, {
+
+ _init: function() {
+
+ var self = this;
+ this.items = $(this.options.filter, this.element);
+ this.element.addClass("ui-selectable");
+
+ //Set the currentFocus to the first item
+ this.currentFocus = this.items.eq(0);
+
+ //Refresh item positions
+ this.refresh();
+
+ //Disable text selection
+ this.element.disableSelection();
+
+ //Prepare caret selection
+ if(this.options.lasso) this._mouseInit();
+
+ this.element
+ .bind('mousedown.selectable', function(event) {
+
+ var item = self._targetIsItem(event.target);
+ if (!item) return;
+
+ // If item is part of current selection and current
+ // selection is multiple, return and allow mouseup
+ // to fire (Windows gets this right too, OSX doesn't)
+ if(self._selection.length > 1 && $(item).hasClass(self.options.selectedClass)) {
+ return (self._listenForMouseUp = 1);
+ }
+
+ if(self._trigger('beforeselect', event) === false)
+ return true;
+
+ self._select(event, item);
+ self.element[0].focus();
+ event.preventDefault();
+
+ })
+ .bind('mouseup.selectable', function(event) {
+ if(self._listenForMouseUp) {
+
+ self._listenForMouseUp = 0;
+ var item = self._targetIsItem(event.target);
+ if (!item) return;
+
+ if(self._trigger('beforeselect', event) === false)
+ return true;
+
+ self._select(event, item);
+ self.element[0].focus();
+ event.preventDefault();
+ }
+ })
+ .bind('focus.selectable', function() {
+ self.currentFocus.addClass('ui-focused');
+ })
+ .bind('blur.selectable', function() {
+ self.currentFocus.removeClass('ui-focused');
+ })
+ .bind('keydown.selectable', function(event) {
+
+ if(!self.options.keyboard)
+ return;
+
+ if(self._trigger('beforeselect', event) === false)
+ return true;
+
+ if(event.keyCode == $.ui.keyCode.DOWN) {
+ self.options.smart ? self.selectClosest('down', event) : self.selectNext(event);
+ event.preventDefault();
+ }
+
+ if(event.keyCode == $.ui.keyCode.RIGHT) {
+ self.options.smart ? self.selectClosest('right', event) : self.selectNext(event);
+ event.preventDefault();
+ }
+
+ if(event.keyCode == $.ui.keyCode.UP) {
+ self.options.smart ? self.selectClosest('up', event) : self.selectPrevious(event);
+ event.preventDefault();
+ }
+
+ if(event.keyCode == $.ui.keyCode.LEFT) {
+ self.options.smart ? self.selectClosest('left', event) : self.selectPrevious(event);
+ event.preventDefault();
+ }
+
+ if ((event.ctrlKey || event.metaKey) && event.keyCode == $.ui.keyCode.SPACE) {
+ self._toggleSelection(self.currentFocus, event);
+ }
+
+ });
+
+ this.helper = $(document.createElement('div'))
+ .addClass("ui-selectable-lasso");
+
+ },
+
+ selectClosest: function(direction, event) {
+
+ var current = [/(down|right)/.test(direction) ? 10000 : -10000, null],
+ overlap = 10000,
+ selfOffset = this.currentFocus.data('selectable-item');
+
+ $(this.options.filter, this.element).not(this.currentFocus).filter(':visible').each(function() {
+
+ var $this = $(this),
+ offset = $this.data('selectable-item'),
+ distance = {
+ x: Math.abs(selfOffset.left - offset.left) + Math.abs((offset.left+this.offsetWidth) - (selfOffset.left+this.offsetWidth)),
+ y: Math.abs(selfOffset.top - offset.top) + Math.abs((offset.top+this.offsetHeight) - (selfOffset.top+this.offsetHeight))
+ };
+
+ switch(direction) {
+
+ case 'up':
+ if((selfOffset.top > offset.top && offset.top >= current[0]) && (offset.top != current[0] || distance.x < overlap)) {
+ current = [offset.top, $this];
+ overlap = distance.x;
+ }
+ break;
+
+ case 'down':
+ if((selfOffset.top < offset.top && offset.top <= current[0]) && (offset.top != current[0] || distance.x < overlap)) {
+ current = [offset.top, $this];
+ overlap = distance.x;
+ }
+ break;
+
+ case 'left':
+ if((selfOffset.left > offset.left && offset.left >= current[0]) && (offset.left != current[0] || distance.y < overlap)) {
+ current = [offset.left, $this];
+ overlap = distance.y;
+ }
+ break;
+
+ case 'right':
+ if((selfOffset.left < offset.left && offset.left <= current[0]) && (offset.left != current[0] || distance.y < overlap)) {
+ current = [offset.left, $this];
+ overlap = distance.y;
+ }
+ break;
+
+ }
+
+ });
+
+ return current[1] ? this._select(event, current[1]) : false;
+
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass("ui-selectable ui-selectable-disabled")
+ .removeData("selectable")
+ .unbind(".selectable");
+ this._mouseDestroy();
+ },
+
+ _mouseCapture: function(event) {
+ //If the item we start dragging on is a selectable, we bail (if keyboard is used)
+ this.clickedOnItem = this._targetIsItem(event.target);
+ return !this.options.keyboard || !this.clickedOnItem;
+ },
+
+ _mouseStart: function(event) {
+
+ var self = this, o = this.options;
+ this.opos = [event.pageX, event.pageY];
+
+ if (o.disabled)
+ return;
+
+ //Cache positions
+ this.refresh();
+
+ //Trigger start event
+ this._trigger("start", event, this._uiHash());
+
+ // append and position helper (lasso)
+ $('body').append(this.helper);
+ this.helper.css({
+ zIndex: 100,
+ position: "absolute",
+ left: event.clientX,
+ top: event.clientY,
+ width: 0,
+ height: 0
+ });
+
+ //Tell the intersection that some start selected
+ this.items.filter('.'+this.options.selectedClass).each(function() {
+ if(event.metaKey) {
+ if(this != self.clickedOnItem) $.data(this, "selectable-item").startSelected = true;
+ } else self._removeFromSelection($(this), event);
+ });
+
+ },
+
+ _mouseDrag: function(event) {
+
+ var self = this, o = this.options;
+
+ if (o.disabled)
+ return;
+
+ //Do the lasso magic
+ var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
+ if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
+ if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
+ this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
+
+ //Loop through all items and check overlaps
+ this.items.each(function() {
+
+ var item = $.data(this, "selectable-item");
+
+ //prevent helper from being selected if appendTo: selectable
+ if (!item || item.element == self.element[0])
+ return;
+
+ var hit = false;
+ if (o.lasso && o.lasso.tolerance == 'touch') {
+ hit = ( !(item.left > x2 || item.right < x1 || item.top > y2 || item.bottom < y1) );
+ } else if (o.lasso && o.lasso.tolerance == 'fit') {
+ hit = (item.left > x1 && item.right < x2 && item.top > y1 && item.bottom < y2);
+ }
+
+ hit ?
+ item.startSelected ? self._removeFromSelection($(this), event) : self._addToSelection($(this), event)
+ : !item.startSelected ? self._removeFromSelection($(this), event) : self._addToSelection($(this), event);
+
+ });
+
+ return false;
+
+ },
+
+ _mouseStop: function(event) {
+ this._trigger("stop", event, this._uiHash());
+ this.helper.remove();
+ return false;
+ },
+
+ _targetIsItem: function(item) {
+ var found = $(item).parents().andSelf().filter(':data(selectable-item)');
+ return found.length && found;
+ },
+
+ _selection: [],
+
+ _clearSelection: function(triggerEvent) {
+
+ var triggerItems = [];
+
+ for (var i = this._selection.length - 1; i >= 0; i--){
+ if(triggerEvent && this._selection[i].data('selectable-item').selected) triggerItems.push(this._selection[i]);
+ this._selection[i].removeClass(this.options.selectedClass);
+ this._selection[i].data('selectable-item').selected = false;
+ };
+
+ this._selection = [];
+ if(triggerEvent) this._trigger('unselect', triggerEvent, this._uiHash($($.map(triggerItems, function(i) { return i[0]; })), 'removed'));
+
+ },
+
+ _toggleSelection: function(item, event) {
+ item.data('selectable-item').selected ? this._removeFromSelection(item, event) : this._addToSelection(item);
+ },
+
+ _addToSelection: function(item, triggerEvent) {
+
+ if (item.data('selectable-item').selected)
+ return null;
+
+ this._selection.push(item);
+ this.latestSelection = item;
+ item.addClass(this.options.selectedClass);
+ item.data('selectable-item').selected = true;
+
+ if(triggerEvent) {
+ this._trigger('select', triggerEvent, $.extend({ lasso: true }, this._uiHash(item)));
+ }
+
+ return item;
+
+ },
+
+ _removeFromSelection: function(item, triggerEvent) {
+
+ for (var i=0; i < this._selection.length; i++) {
+ if (this._selection[i][0] == item[0]) {
+ this._selection[i].removeClass(this.options.selectedClass);
+ this._selection[i].data('selectable-item').selected = false;
+ this._selection.splice(i,1);
+ if(triggerEvent) this._trigger('unselect', triggerEvent, this._uiHash($(item), 'removed'));
+ break;
+ }
+ };
+
+ },
+
+ _updateSelectionMouse: function(event) {
+
+ var newlySelected = [];
+
+ if (event.shiftKey && this.options.multiple) {
+
+ //Clear the previous selection to make room for a shift selection
+ this._clearSelection(event);
+
+ var index = this.items.index(this.latestWithoutModifier[0]) > this.items.index(this.currentFocus[0]) ? -1 : 1;
+ var i = this.latestWithoutModifier.data('selectable-item').selected ? this.items.eq(this.items.index(this.latestWithoutModifier[0])+index) : this.latestWithoutModifier;
+ while(i.length && i[0] != this.currentFocus[0]) {
+ i[0] == this.previousFocus[0] ? this._addToSelection(i) : newlySelected.push(this._addToSelection(i));
+ i = this.items.eq(this.items.index(i[0])+index);
+ }
+
+ //Readd the item with the current focus
+ newlySelected.push(this._addToSelection(this.currentFocus));
+
+ } else {
+
+ if (event.metaKey) {
+ this._toggleSelection(this.currentFocus, event);
+ } else {
+ this._clearSelection(event);
+ newlySelected.push(this._addToSelection(this.currentFocus));
+ this.latestWithoutModifier = this.currentFocus;
+ }
+
+ }
+
+ return $($.map(newlySelected, function(i) { return i[0]; }));
+
+ },
+
+ _updateSelection: function(event, index) {
+
+ var newlySelected = [];
+
+ if (event.shiftKey && this.options.multiple) {
+
+ if (this.currentFocus.data('selectable-item').selected) {
+ this._removeFromSelection(this.previousFocus, event);
+ } else {
+
+ var index2 = this.items.index(this.latestSelection[0]) > this.items.index(this.currentFocus[0]) ? 1 : -1;
+ if (!this.previousFocus.data('selectable-item').selected) {
+ var i = index == index2 ? this.items.eq(this.items.index(this.previousFocus[0])+index2) : this.previousFocus;
+ while(i.length && !i.data('selectable-item').selected) {
+ newlySelected.push(this._addToSelection(i));
+ i = this.items.eq(this.items.index(i[0])+index2);
+ }
+ }
+
+ newlySelected.push(this._addToSelection(this.currentFocus));
+
+ }
+
+ } else {
+
+ //If the CTRL or Apple/Win key is pressed, only set focus
+ if (event.metaKey)
+ return;
+
+ this._clearSelection(event);
+ newlySelected.push(this._addToSelection(this.currentFocus));
+ this.latestWithoutModifier = this.currentFocus;
+
+ }
+
+ return $($.map(newlySelected, function(i) { return i[0]; }));
+
+ },
+
+ _select: function(event, item) {
+
+ //Set the current selection to the previous/next item
+ this.previousFocus = this.currentFocus;
+ this.currentFocus = $(item);
+
+ this.previousFocus.removeClass('ui-focused');
+ this.currentFocus.addClass('ui-focused');
+
+ //Set and update the selection
+ var newlySelected = this._updateSelectionMouse(event);
+
+ //Trigger select event
+ if(newlySelected && newlySelected.length) this._trigger('select', event, this._uiHash(newlySelected, 'added'));
+
+ },
+
+ _selectAdjacent: function(event, index) {
+
+ var item = this.items.eq(this.items.index(this.currentFocus[0]) + index);
+
+ //Bail if there's no previous/next item
+ if (!item.length) return;
+
+ //Set the current selection to the previous/next item
+ this.previousFocus = this.currentFocus;
+ this.currentFocus = item;
+
+ this.previousFocus.removeClass('ui-focused');
+ this.currentFocus.addClass('ui-focused');
+
+ //Set and update the selection
+ var newlySelected = this._updateSelection(event, index);
+
+ //Trigger select event
+ if(newlySelected && newlySelected.length) this._trigger('select', event, this._uiHash(newlySelected, 'added'));
+
+ },
+
+ selectPrevious: function(event) {
+ this._selectAdjacent(event, -1);
+ },
+
+ selectNext: function(event) {
+ this._selectAdjacent(event, 1);
+ },
+
+ refresh: function() {
+
+ var o = this.options;
+ this.items = $(o.filter, this.element);
+ this.items.each(function() {
+ var $this = $(this);
+ var pos = $this.offset();
+ $.data(this, "selectable-item", {
+ left: pos.left,
+ top: pos.top,
+ right: pos.left + $this.width(),
+ bottom: pos.top + $this.height(),
+ startSelected: false,
+ selected: $this.hasClass(o.selectedClass)
+ });
+ });
+
+ },
+
+ select: function(item) {
+ //TODO
+ },
+
+ deselect: function(item) {
+ if(!item) this._clearSelection(true);
+ //TODO: Deselect single elements
+ },
+
+ _uiHash: function(items, specialKey) {
+ var uiHash = {
+ previousFocus: this.previousFocus,
+ currentFocus: this.currentFocus,
+ selection: $($.map(this._selection, function(i) { return i[0]; }))
+ };
+ if(specialKey) uiHash[specialKey] = items;
+ return uiHash;
+ }
+
+ }));
+
+ $.extend($.ui.selectable, {
+ defaults: {
+
+ //TODO: Figure out how to move these defaults out
+ cancel: ":input,option",
+ delay: 0,
+ distance: 1,
+ appendTo: 'body',
+
+ multiple: true,
+ smart: true,
+ filter: '> *',
+
+ keyboard: true,
+ lasso: {
+ cancel: ":input,option",
+ delay: 0,
+ distance: 1,
+ tolerance: 'touch',
+ appendTo: 'body'
+ },
+
+ //Should we really delete that?
+ selectedClass: 'ui-state-selected'
+ }
+ });
+
+})(jQuery);
diff --git a/modules/akismet/helpers/akismet_event.php b/modules/akismet/helpers/akismet_event.php
index 80fe0127..cec6d95d 100644
--- a/modules/akismet/helpers/akismet_event.php
+++ b/modules/akismet/helpers/akismet_event.php
@@ -40,15 +40,31 @@ class akismet_event_Core {
$comment->save();
}
- static function comment_updated($old, $new) {
+ static function comment_updated($original, $new) {
if (!module::get_var("akismet", "api_key")) {
return;
}
- if ($old->state != "spam" && $new->state == "spam") {
+ if ($original->state != "spam" && $new->state == "spam") {
akismet::submit_spam($new);
- } else if ($old->state == "spam" && $new->state != "spam") {
+ } else if ($original->state == "spam" && $new->state != "spam") {
akismet::submit_ham($new);
}
}
+
+ static function admin_menu($menu, $theme) {
+ $menu->get("settings_menu")
+ ->append(Menu::factory("link")
+ ->id("akismet")
+ ->label(t("Akismet"))
+ ->url(url::site("admin/akismet")));
+
+ if (module::get_var("akismet", "api_key")) {
+ $menu->get("statistics_menu")
+ ->append(Menu::factory("link")
+ ->id("akismet")
+ ->label(t("Akismet"))
+ ->url(url::site("admin/akismet/stats")));
+ }
+ }
}
diff --git a/modules/akismet/helpers/akismet_menu.php b/modules/akismet/helpers/akismet_menu.php
deleted file mode 100644
index ebd948d6..00000000
--- a/modules/akismet/helpers/akismet_menu.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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 akismet_menu_Core {
- static function admin($menu, $theme) {
- $menu->get("settings_menu")
- ->append(Menu::factory("link")
- ->id("akismet")
- ->label(t("Akismet"))
- ->url(url::site("admin/akismet")));
-
- if (module::get_var("akismet", "api_key")) {
- $menu->get("statistics_menu")
- ->append(Menu::factory("link")
- ->id("akismet")
- ->label(t("Akismet"))
- ->url(url::site("admin/akismet/stats")));
- }
- }
-}
diff --git a/modules/akismet/module.info b/modules/akismet/module.info
index d45d8a7b..b61ed107 100644
--- a/modules/akismet/module.info
+++ b/modules/akismet/module.info
@@ -1,3 +1,3 @@
-name = Akismet
+name = "Akismet"
description = "Filter comments through the Akismet web service to detect and eliminate spam (http://akismet.com). You'll need a WordPress.com API key to use it."
version = 1
diff --git a/modules/akismet/views/admin_akismet.html.php b/modules/akismet/views/admin_akismet.html.php
index 9963f223..410902a5 100644
--- a/modules/akismet/views/admin_akismet.html.php
+++ b/modules/akismet/views/admin_akismet.html.php
@@ -2,7 +2,9 @@
<div id="gAdminAkismet">
<h1> <?= t("Akismet Spam Filtering") ?> </h1>
<p>
- <?= t("Akismet is a free, automated spam filtering service. In order to use it, you need to sign up for a <a href=\"http://wordpress.com/api-keys\">Wordpress.com API Key</a>, which is also free. Your comments will be automatically relayed to <a href=\"http://akismet.com\">Akismet.com</a> where they'll be scanned for spam. Spam messages will be flagged accordingly and hidden from your vistors until you approve or delete them.") ?>
+ <?= t("Akismet is a free, automated spam filtering service. In order to use it, you need to sign up for a <a href=\"%api_key_url\">Wordpress.com API Key</a>, which is also free. Your comments will be automatically relayed to <a href=\"%akismet_url\">Akismet.com</a> where they'll be scanned for spam. Spam messages will be flagged accordingly and hidden from your vistors until you approve or delete them.",
+ array("api_key_url" => "http://wordpress.com/api-keys",
+ "akismet_url" => "http://akismet.com")) ?>
</p>
<? if ($valid_key): ?>
diff --git a/modules/comment/controllers/admin_comments.php b/modules/comment/controllers/admin_comments.php
index 3e8d3c46..a164f79f 100644
--- a/modules/comment/controllers/admin_comments.php
+++ b/modules/comment/controllers/admin_comments.php
@@ -113,10 +113,6 @@ class Admin_Comments_Controller extends Admin_Controller {
if ($comment->loaded) {
$comment->state = $state;
$comment->save();
- module::event("comment_updated", $orig, $comment);
- if ($orig->state == "published" || $comment->state == "published") {
- module::event("item_related_update", $comment->item());
- }
}
}
diff --git a/modules/comment/controllers/comments.php b/modules/comment/controllers/comments.php
index 02c38491..9fb4796e 100644
--- a/modules/comment/controllers/comments.php
+++ b/modules/comment/controllers/comments.php
@@ -152,7 +152,6 @@ class Comments_Controller extends REST_Controller {
$comment->url = $form->edit_comment->url->value;
$comment->text = $form->edit_comment->text->value;
$comment->save();
- module::event("comment_updated", $comment);
print json_encode(
array("result" => "success",
diff --git a/modules/comment/helpers/comment.php b/modules/comment/helpers/comment.php
index 08cba096..3d743325 100644
--- a/modules/comment/helpers/comment.php
+++ b/modules/comment/helpers/comment.php
@@ -61,11 +61,6 @@ class comment_Core {
$comment->server_remote_port = substr($input->server("REMOTE_PORT"), 0, 16);
$comment->save();
- module::event("comment_created", $comment);
- if ($comment->state == "published") {
- module::event("item_related_update", $comment->item());
- }
-
return $comment;
}
diff --git a/modules/comment/helpers/comment_event.php b/modules/comment/helpers/comment_event.php
index a3beb27a..0234aea9 100644
--- a/modules/comment/helpers/comment_event.php
+++ b/modules/comment/helpers/comment_event.php
@@ -18,7 +18,35 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class comment_event_Core {
- static function item_before_delete($item) {
+ static function item_deleted($item) {
Database::instance()->delete("comments", array("item_id" => $item->id));
}
+
+ static function admin_menu($menu, $theme) {
+ $menu->get("content_menu")
+ ->append(Menu::factory("link")
+ ->id("comments")
+ ->label(t("Comments"))
+ ->url(url::site("admin/comments")));
+ }
+
+ static function photo_menu($menu, $theme) {
+ $menu
+ ->append(Menu::factory("link")
+ ->id("comments")
+ ->label(t("View comments on this item"))
+ ->url("#comments")
+ ->css_id("gCommentsLink"));
+ }
+
+ static function item_index_data($item, $data) {
+ foreach (Database::instance()
+ ->select("text")
+ ->from("comments")
+ ->where("item_id", $item->id)
+ ->get()
+ ->as_array() as $row) {
+ $data[] = $row->text;
+ }
+ }
}
diff --git a/modules/comment/helpers/comment_installer.php b/modules/comment/helpers/comment_installer.php
index f54913c3..80594c16 100644
--- a/modules/comment/helpers/comment_installer.php
+++ b/modules/comment/helpers/comment_installer.php
@@ -44,7 +44,7 @@ class comment_installer {
`text` text,
`updated` int(9) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
block_manager::add("dashboard_center", "comment", "recent_comments");
module::set_var("comment", "spam_caught", 0);
@@ -52,8 +52,8 @@ class comment_installer {
}
static function upgrade($version) {
+ $db = Database::instance();
if ($version == 1) {
- $db = Database::instance();
$db->query("ALTER TABLE {comments} CHANGE `state` `state` varchar(15) default 'unpublished'");
module::set_version("comment", 2);
}
@@ -61,9 +61,16 @@ class comment_installer {
static function uninstall() {
$db = Database::instance();
- $sql = "SELECT `item_id` FROM {comments}";
- module::event("item_related_update_batch", $sql);
+ // Notify listeners that we're deleting some data. This is probably going to be very
+ // inefficient for large uninstalls, and we could make it better by doing things like passing
+ // a SQL fragment through so that the listeners could use subselects. But by using a single,
+ // simple event API we lighten the load on module developers.
+ foreach (ORM::factory("item")
+ ->join("comments", "items.id", "comments.item_id")
+ ->find_all() as $item) {
+ module::event("item_related_update", $item);
+ }
$db->query("DROP TABLE IF EXISTS {comments};");
}
}
diff --git a/modules/comment/helpers/comment_menu.php b/modules/comment/helpers/comment_menu.php
deleted file mode 100644
index 01881921..00000000
--- a/modules/comment/helpers/comment_menu.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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 comment_menu_Core {
- static function admin($menu, $theme) {
- $menu->get("content_menu")
- ->append(Menu::factory("link")
- ->id("comments")
- ->label(t("Comments"))
- ->url(url::site("admin/comments")));
- }
-
- static function photo($menu, $theme) {
- $menu
- ->append(Menu::factory("link")
- ->id("comments")
- ->label(t("View comments on this item"))
- ->url("#comments")
- ->css_id("gCommentsLink"));
- }
-}
diff --git a/modules/comment/helpers/comment_theme.php b/modules/comment/helpers/comment_theme.php
index 89b2f57c..b807e2cf 100644
--- a/modules/comment/helpers/comment_theme.php
+++ b/modules/comment/helpers/comment_theme.php
@@ -19,7 +19,7 @@
*/
class comment_theme_Core {
static function head($theme) {
- $theme->script("modules/comment/js/comment.js");
+ $theme->script("comment.js");
return "";
}
diff --git a/modules/comment/models/comment.php b/modules/comment/models/comment.php
index 22c465df..83d0888a 100644
--- a/modules/comment/models/comment.php
+++ b/modules/comment/models/comment.php
@@ -31,7 +31,7 @@ class Comment_Model extends ORM {
if ($author->guest) {
return $this->guest_name;
} else {
- return $author->full_name;
+ return $author->display_name();
}
}
@@ -61,8 +61,23 @@ class Comment_Model extends ORM {
$this->updated = time();
if (!$this->loaded && empty($this->created)) {
$this->created = $this->updated;
+ $created = true;
}
}
- return parent::save();
+ $visible_change = $this->original()->state == "published" || $this->state == "published";
+ parent::save();
+
+ if (isset($created)) {
+ module::event("comment_created", $this);
+ } else {
+ module::event("comment_updated", $this->original(), $this);
+ }
+
+ // We only notify on the related items if we're making a visible change.
+ if ($visible_change) {
+ module::event("item_related_update", $this->item());
+ }
+
+ return $this;
}
}
diff --git a/modules/comment/module.info b/modules/comment/module.info
index 946f1d39..c371cf27 100644
--- a/modules/comment/module.info
+++ b/modules/comment/module.info
@@ -1,3 +1,3 @@
-name = Comments
-description = Allows users and guests to leave comments on photos and albums.
+name = "Comments"
+description = "Allows users and guests to leave comments on photos and albums."
version = 2
diff --git a/modules/comment/views/admin_block_recent_comments.html.php b/modules/comment/views/admin_block_recent_comments.html.php
index 4ff24f86..516a8181 100644
--- a/modules/comment/views/admin_block_recent_comments.html.php
+++ b/modules/comment/views/admin_block_recent_comments.html.php
@@ -2,7 +2,7 @@
<ul>
<? foreach ($comments as $i => $comment): ?>
<li class="<?= ($i % 2 == 0) ? "gEvenRow" : "gOddRow" ?>">
- <img src="<?= $comment->author()->avatar_url(32, $theme->theme_url("images/avatar.jpg", true)) ?>"
+ <img src="<?= $comment->author()->avatar_url(32, $theme->url("images/avatar.jpg", true)) ?>"
class="gAvatar"
alt="<?= p::clean($comment->author_name()) ?>"
width="32"
diff --git a/modules/comment/views/admin_comments.html.php b/modules/comment/views/admin_comments.html.php
index ad0ae8f3..9fe7164b 100644
--- a/modules/comment/views/admin_comments.html.php
+++ b/modules/comment/views/admin_comments.html.php
@@ -106,7 +106,7 @@
<tr id="gComment-<?= $comment->id ?>" class="<?= ($i % 2 == 0) ? "gEvenRow" : "gOddRow" ?>">
<td>
<a href="#">
- <img src="<?= $comment->author()->avatar_url(40, $theme->theme_url("images/avatar.jpg", true)) ?>"
+ <img src="<?= $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>"
class="gAvatar"
alt="<?= p::clean($comment->author_name()) ?>"
width="40"
diff --git a/modules/comment/views/comment.html.php b/modules/comment/views/comment.html.php
index ab72a0c8..3d17411c 100644
--- a/modules/comment/views/comment.html.php
+++ b/modules/comment/views/comment.html.php
@@ -2,7 +2,7 @@
<li id="gComment-<?= $comment->id; ?>">
<p class="gAuthor">
<a href="#">
- <img src="<?= $comment->author()->avatar_url(40, $theme->theme_url("images/avatar.jpg", true)) ?>"
+ <img src="<?= $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>"
class="gAvatar"
alt="<?= p::clean($comment->author_name()) ?>"
width="40"
diff --git a/modules/comment/views/comments.html.php b/modules/comment/views/comments.html.php
index fa25a4e0..f7251389 100644
--- a/modules/comment/views/comments.html.php
+++ b/modules/comment/views/comments.html.php
@@ -10,7 +10,7 @@
<li id="gComment-<?= $comment->id ?>">
<p class="gAuthor">
<a href="#">
- <img src="<?= $comment->author()->avatar_url(40, $theme->theme_url("images/avatar.jpg", true)) ?>"
+ <img src="<?= $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>"
class="gAvatar"
alt="<?= p::clean($comment->author_name()) ?>"
width="40"
diff --git a/modules/comment/helpers/comment_search.php b/modules/digibug/config/digibug.php
index 29762eae..6cd165d1 100644
--- a/modules/comment/helpers/comment_search.php
+++ b/modules/digibug/config/digibug.php
@@ -17,18 +17,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
-class Comment_Search_Core {
- static function item_index_data($item) {
- $data = array();
- foreach (Database::instance()
- ->select("text")
- ->from("comments")
- ->where("item_id", $item->id)
- ->get()
- ->as_array() as $row) {
- $data[] = $row->text;
- }
- return join(" ", $data);
- }
-}
+/**
+ * PHP Mail Configuration parameters
+ * from => email address that appears as the from address
+ * line-length => word wrap length (PHP documentations suggest no larger tha 70 characters
+ * reply-to => what goes into the reply to header
+ */
+$config["ranges"] = array(
+ "Digibug1" => array("low" => "65.249.152.0", "high" => "65.249.159.255"),
+ "Digibug2" => array("low" => "208.122.55.0", "high" => "208.122.55.255")
+);
diff --git a/modules/digibug/controllers/digibug.php b/modules/digibug/controllers/digibug.php
index d881db9b..e0f4b6bf 100644
--- a/modules/digibug/controllers/digibug.php
+++ b/modules/digibug/controllers/digibug.php
@@ -21,7 +21,7 @@ class Digibug_Controller extends Controller {
public function print_photo($id) {
access::verify_csrf();
$item = ORM::factory("item", $id);
- access::required("view_full", $item);
+ access::required("view", $item);
if (access::group_can(group::everybody(), "view_full", $item)) {
$full_url = $item->file_url(true);
@@ -56,6 +56,30 @@ class Digibug_Controller extends Controller {
}
public function print_proxy($type, $id) {
+ // If its a request for the full size then make sure we are coming from an
+ // authorized address
+ if ($type == "full") {
+ $remote_addr = ip2long($this->input->server("REMOTE_ADDR"));
+ if ($remote_addr === false) {
+ Kohana::show_404();
+ }
+ $config = Kohana::config("digibug");
+
+ $authorized = false;
+ foreach ($config["ranges"] as $ip_range) {
+ $low = ip2long($ip_range["low"]);
+ $high = ip2long($ip_range["high"]);
+ $authorized = $low !== false && $high !== false &&
+ $low <= $remote_addr && $remote_addr <= $high;
+ if ($authorized) {
+ break;
+ }
+ }
+ if (!$authorized) {
+ Kohana::show_404();
+ }
+ }
+
$proxy = ORM::factory("digibug_proxy", array("uuid" => $id));
if (!$proxy->loaded || !$proxy->item->loaded) {
Kohana::show_404();
@@ -69,16 +93,18 @@ class Digibug_Controller extends Controller {
// We don't need to save the session for this request
Session::abort_save();
- // Dump out the image
- header("Content-Type: $proxy->item->mime_type");
- Kohana::close_buffers(false);
- $fd = fopen($file, "rb");
- fpassthru($fd);
- fclose($fd);
+ if (!TEST_MODE) {
+ // Dump out the image
+ header("Content-Type: $proxy->item->mime_type");
+ Kohana::close_buffers(false);
+ $fd = fopen($file, "rb");
+ fpassthru($fd);
+ fclose($fd);
- // If the request was for the image and not the thumb, then delete the proxy.
- if ($type == "full") {
- $proxy->delete();
+ // If the request was for the image and not the thumb, then delete the proxy.
+ if ($type == "full") {
+ $proxy->delete();
+ }
}
$this->_clean_expired();
@@ -89,8 +115,8 @@ class Digibug_Controller extends Controller {
}
private function _clean_expired() {
- Database::instance()>query(
- "DELETE FROM {digibug_proxy} " .
+ Database::instance()->query(
+ "DELETE FROM {digibug_proxies} " .
"WHERE request_date <= (CURDATE() - INTERVAL 10 DAY) " .
"LIMIT 20");
}
diff --git a/modules/digibug/helpers/digibug_menu.php b/modules/digibug/helpers/digibug_event.php
index f1d4fc1d..d2830b80 100644
--- a/modules/digibug/helpers/digibug_menu.php
+++ b/modules/digibug/helpers/digibug_event.php
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class digibug_menu {
- static function admin($menu, $theme) {
+class digibug_event_Core {
+ static function admin_menu($menu, $theme) {
$menu->get("settings_menu")
->append(Menu::factory("link")
->id("digibug_menu")
@@ -26,24 +26,25 @@ class digibug_menu {
->url(url::site("admin/digibug")));
}
- static function photo($menu, $theme) {
+ static function photo_menu($menu, $theme) {
$item = $theme->item();
- $menu->append(
- Menu::factory("link")
- ->id("digibug")
- ->label(t("Print with Digibug"))
- ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
- ->css_id("gDigibugLink"));
+ $menu->append(Menu::factory("link")
+ ->id("digibug")
+ ->label(t("Print with Digibug"))
+ ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
+ ->css_id("gDigibugLink")
+ ->css_class("ui-icon-print"));
}
- static function thumb($menu, $theme, $item) {
- if ($item->type == "photo" && access::can("view_full", $item)) {
- $menu->append(
- Menu::factory("link")
- ->id("digibug")
- ->label(t("Print with Digibug"))
- ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
- ->css_id("gDigibugLink"));
+ static function context_menu($menu, $theme, $item) {
+ if ($item->type == "photo") {
+ $menu->get("options_menu")
+ ->append(Menu::factory("link")
+ ->id("digibug")
+ ->label(t("Print with Digibug"))
+ ->url(url::site("digibug/print_photo/$item->id?csrf=$theme->csrf"))
+ ->css_id("gDigibugLink")
+ ->css_class("ui-icon-print"));
}
}
}
diff --git a/modules/digibug/helpers/digibug_installer.php b/modules/digibug/helpers/digibug_installer.php
index 1cd78b44..7e8145d2 100644
--- a/modules/digibug/helpers/digibug_installer.php
+++ b/modules/digibug/helpers/digibug_installer.php
@@ -26,7 +26,7 @@ class digibug_installer {
`request_date` TIMESTAMP NOT NULL DEFAULT current_timestamp,
`item_id` int(9) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_var("digibug", "company_id", "3153");
module::set_var("digibug", "event_id", "8491");
diff --git a/modules/digibug/helpers/digibug_theme.php b/modules/digibug/helpers/digibug_theme.php
index f94d07c6..ceda55b5 100644
--- a/modules/digibug/helpers/digibug_theme.php
+++ b/modules/digibug/helpers/digibug_theme.php
@@ -19,6 +19,6 @@
*/
class digibug_theme_Core {
static function head($theme) {
- $theme->script("modules/digibug/js/digibug.js");
+ $theme->script("digibug.js");
}
}
diff --git a/modules/digibug/module.info b/modules/digibug/module.info
index c25a2454..be4e880a 100644
--- a/modules/digibug/module.info
+++ b/modules/digibug/module.info
@@ -1,3 +1,3 @@
-name = Digibug
-description = Digibug Photo Printing Module
+name = "Digibug"
+description = "Digibug Photo Printing Module"
version = 2
diff --git a/modules/digibug/tests/Digibug_Controller_Test.php b/modules/digibug/tests/Digibug_Controller_Test.php
new file mode 100644
index 00000000..859ff637
--- /dev/null
+++ b/modules/digibug/tests/Digibug_Controller_Test.php
@@ -0,0 +1,78 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 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 Digibug_Controller_Test extends Unit_Test_Case {
+ private $_proxy;
+ private $_item;
+ private $_server;
+
+ public function teardown() {
+ $_SERVER = $this->_server;
+
+ if ($this->_proxy) {
+ $this->_proxy->delete();
+ }
+ }
+
+ public function setup() {
+ $this->_server = $_SERVER;
+
+ $root = ORM::factory("item", 1);
+ $this->_album = album::create($root, rand(), "test album");
+ access::deny(group::everybody(), "view_full", $this->_album);
+ access::deny(group::registered_users(), "view_full", $this->_album);
+
+ $rand = rand();
+ $this->_item = photo::create($this->_album, MODPATH . "gallery/tests/test.jpg", "$rand.jpg",
+ $rand, $rand);
+ $this->_proxy = ORM::factory("digibug_proxy");
+ $this->_proxy->uuid = md5(rand());
+ $this->_proxy->item_id = $this->_item->id;
+ $this->_proxy->save();
+ }
+
+ public function digibug_request_thumb_test() {
+ $controller = new Digibug_Controller();
+ $controller->print_proxy("thumb", $this->_proxy->uuid);
+ }
+
+ public function digibug_request_full_malicious_ip_test() {
+ $_SERVER["REMOTE_ADDR"] = "123.123.123.123";
+ try {
+ $controller = new Digibug_Controller();
+ $controller->print_proxy("full", $this->_proxy->uuid);
+ $this->assert_true(false, "Should have failed with an 404 exception");
+ } catch (Kohana_404_Exception $e) {
+ // expected behavior
+ }
+ }
+
+ public function digibug_request_full_authorized_ip_test() {
+ $config = Kohana::config("digibug");
+ $this->assert_true(!empty($config), "The Digibug config is empty");
+
+ $ranges = array_values($config["ranges"]);
+ $low = ip2long($ranges[0]["low"]);
+ $high = ip2long($ranges[0]["high"]);
+
+ $_SERVER["REMOTE_ADDR"] = long2ip(rand($low, $high));
+ $controller = new Digibug_Controller();
+ $controller->print_proxy("full", $this->_proxy->uuid);
+ }
+}
diff --git a/modules/exif/helpers/exif.php b/modules/exif/helpers/exif.php
index b0e7e93f..20ecd0cb 100644
--- a/modules/exif/helpers/exif.php
+++ b/modules/exif/helpers/exif.php
@@ -163,7 +163,7 @@ class exif_Core {
list ($remaining) = exif::stats();
if ($remaining) {
site_status::warning(
- t('Your EXIF index needs to be updated. <a href="%url" class="gDialogLink">Fix this now</a>',
+ t('Your Exif index needs to be updated. <a href="%url" class="gDialogLink">Fix this now</a>',
array("url" => url::site("admin/maintenance/start/exif_task::update_index?csrf=__CSRF__"))),
"exif_index_out_of_date");
}
diff --git a/modules/exif/helpers/exif_event.php b/modules/exif/helpers/exif_event.php
index f5677653..826ec959 100644
--- a/modules/exif/helpers/exif_event.php
+++ b/modules/exif/helpers/exif_event.php
@@ -19,10 +19,12 @@
*/
class exif_event_Core {
static function item_created($item) {
- exif::extract($item);
+ if (!$item->is_album()) {
+ exif::extract($item);
+ }
}
- static function item_before_delete($item) {
+ static function item_deleted($item) {
Database::instance()->delete("exif_records", array("item_id" => $item->id));
}
}
diff --git a/modules/exif/helpers/exif_installer.php b/modules/exif/helpers/exif_installer.php
index 0233f2bb..66226061 100644
--- a/modules/exif/helpers/exif_installer.php
+++ b/modules/exif/helpers/exif_installer.php
@@ -28,7 +28,7 @@ class exif_installer {
`dirty` BOOLEAN default 1,
PRIMARY KEY (`id`),
KEY(`item_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("exif", 1);
}
diff --git a/modules/exif/helpers/exif_task.php b/modules/exif/helpers/exif_task.php
index 375503e3..c269b732 100644
--- a/modules/exif/helpers/exif_task.php
+++ b/modules/exif/helpers/exif_task.php
@@ -28,47 +28,54 @@ class exif_task_Core {
list ($remaining, $total, $percent) = exif::stats();
return array(Task_Definition::factory()
->callback("exif_task::update_index")
- ->name(t("Extract EXIF data"))
+ ->name(t("Extract Exif data"))
->description($remaining
? t2("1 photo needs to be scanned",
"%count (%percent%) of your photos need to be scanned",
$remaining, array("percent" => (100 - $percent)))
- : t("EXIF data is up-to-date"))
+ : t("Exif data is up-to-date"))
->severity($remaining ? log::WARNING : log::SUCCESS));
}
static function update_index($task) {
- $completed = $task->get("completed", 0);
+ try {
+ $completed = $task->get("completed", 0);
- $start = microtime(true);
- foreach (ORM::factory("item")
- ->join("exif_records", "items.id", "exif_records.item_id", "left")
- ->where("type", "photo")
- ->open_paren()
- ->where("exif_records.item_id", null)
- ->orwhere("exif_records.dirty", 1)
- ->close_paren()
- ->find_all() as $item) {
- if (microtime(true) - $start > 1.5) {
- break;
- }
+ $start = microtime(true);
+ foreach (ORM::factory("item")
+ ->join("exif_records", "items.id", "exif_records.item_id", "left")
+ ->where("type", "photo")
+ ->open_paren()
+ ->where("exif_records.item_id", null)
+ ->orwhere("exif_records.dirty", 1)
+ ->close_paren()
+ ->find_all() as $item) {
+ if (microtime(true) - $start > 1.5) {
+ break;
+ }
- $completed++;
- exif::extract($item);
- }
+ $completed++;
+ exif::extract($item);
+ }
- list ($remaining, $total, $percent) = exif::stats();
- $task->set("completed", $completed);
- if ($remaining == 0 || !($remaining + $completed)) {
+ list ($remaining, $total, $percent) = exif::stats();
+ $task->set("completed", $completed);
+ if ($remaining == 0 || !($remaining + $completed)) {
+ $task->done = true;
+ $task->state = "success";
+ site_status::clear("exif_index_out_of_date");
+ $task->percent_complete = 100;
+ } else {
+ $task->percent_complete = round(100 * $completed / ($remaining + $completed));
+ }
+ $task->status = t2("one record updated, index is %percent% up-to-date",
+ "%count records updated, index is %percent% up-to-date",
+ $completed, array("percent" => $percent));
+ } catch (Exception $e) {
$task->done = true;
- $task->state = "success";
- site_status::clear("exif_index_out_of_date");
- $task->percent_complete = 100;
- } else {
- $task->percent_complete = round(100 * $completed / ($remaining + $completed));
+ $task->state = "error";
+ $task->status = $e->getMessage();
+ $task->log($e->__toString());
}
- $task->status = t2("one record updated, index is %percent% up-to-date",
- "%count records updated, index is %percent% up-to-date",
- $completed, array("percent" => $percent));
}
}
diff --git a/modules/exif/module.info b/modules/exif/module.info
index 1e16a5ff..c8ae688e 100644
--- a/modules/exif/module.info
+++ b/modules/exif/module.info
@@ -1,3 +1,3 @@
-name = Exif Data
+name = "Exif Data"
description = "Extract Exif data and display it on photo pages."
version = 1
diff --git a/modules/g2_import/helpers/g2_import.php b/modules/g2_import/helpers/g2_import.php
index d67d4c04..436cef52 100644
--- a/modules/g2_import/helpers/g2_import.php
+++ b/modules/g2_import/helpers/g2_import.php
@@ -376,12 +376,10 @@ class g2_import_Core {
}
$album->save();
- $message[] = t("Album '%name' imported.", array("name" => $album->name));
- $message[] = self::import_keywords_as_tags($g2_album->getKeywords(), $album);
+ self::import_keywords_as_tags($g2_album->getKeywords(), $album);
self::set_map($g2_album_id, $album->id);
// @todo import album highlights
- return $message;
}
/**
@@ -401,7 +399,6 @@ class g2_import_Core {
}
$table = g2(GalleryCoreApi::fetchThumbnailsByItemIds(array($g2_album_id)));
- $message = "";
if (isset($table[$g2_album_id])) {
// Backtrack the source id to an item
$g2_source = $table[$g2_album_id];
@@ -417,10 +414,8 @@ class g2_import_Core {
$g2_album->view_count = g2(GalleryCoreApi::fetchItemViewCount($g2_album_id));
$g2_album->save();
graphics::generate($g2_album);
- $message = t("Highlight created for album '%name'", array("name" => $g2_album->name));
}
}
- return $message;
}
/**
@@ -471,8 +466,6 @@ class g2_import_Core {
$corrupt = 1;
}
try {
- Kohana::log("error", "description: " . self::extract_description($g2_item));
- Kohana::log("error", "title: " . $g2_item->getTitle());
$item = photo::create(
$parent,
$g2_path,
@@ -480,7 +473,6 @@ class g2_import_Core {
self::_decode_html_special_chars($g2_item->getTitle()),
self::_decode_html_special_chars(self::extract_description($g2_item)),
self::map($g2_item->getOwnerId()));
- $message[].= t("Imported photo: '%title'", array("title" => p::purify($item->title)));
} catch (Exception $e) {
Kohana::log(
"alert", "Corrupt image $g2_path\n" . $e->__toString());
@@ -501,7 +493,6 @@ class g2_import_Core {
self::_decode_html_special_chars($g2_item->getTitle()),
self::_decode_html_special_chars(self::extract_description($g2_item)),
self::map($g2_item->getOwnerId()));
- $message[] = t("Imported movie: '%title'", array("title" => p::purify($item->title)));
} catch (Exception $e) {
Kohana::log("alert", "Corrupt movie $g2_path\n" . $e->__toString());
$message[] = t("Corrupt movie '%path'", array("path" => $g2_path));
@@ -522,14 +513,13 @@ class g2_import_Core {
}
if (!empty($item)) {
- $message[] = self::import_keywords_as_tags($g2_item->getKeywords(), $item);
+ self::import_keywords_as_tags($g2_item->getKeywords(), $item);
}
if (isset($item)) {
self::set_map($g2_item_id, $item->id);
$item->view_count = g2(GalleryCoreApi::fetchItemViewCount($g2_item_id));
$item->save();
- $message[] = t("View count updated: %count", array("count" => $item->view_count));
}
if ($corrupt) {
@@ -623,21 +613,17 @@ class g2_import_Core {
}
$tags = "";
+ // Multiword tags have the space changed to dots.s
foreach ($tag_names as $tag_name) {
- $tags .= (strlen($tags) ? ", " : "") . tag::add($g3_item, $tag_name);
+ $tags .= (strlen($tags) ? ", " : "") .
+ tag::add($g3_item, $tag_name);
}
// Tag operations are idempotent so we don't need to map them. Which is good because we don't
// have an id for each individual tag mapping anyway so it'd be hard to set up the mapping.
- return t("Added '%tags' to '%title'", array("tags" => $tags,
- "title" => p::purify($item->title)));
}
static function import_keywords_as_tags($keywords, $item) {
- if (!module::is_active("tag")) {
- return t("Gallery 3 tag module is inactive, no keywords will be imported");
- }
-
// Keywords in G2 are free form. So we don't know what our user used as a separator. Try to
// be smart about it. If we see a comma or a semicolon, expect the keywords to be separated
// by that delimeter. Otherwise, use space as the delimiter.
@@ -656,8 +642,6 @@ class g2_import_Core {
$tags .= (strlen($tags) ? ", " : "") . tag::add($item, $keyword);
}
}
- return strlen($tags) ? t("Added '%keywords' to '%title'",
- array("keywords" => $tags, "title" => p::purify($item->title))) : "";
}
/**
diff --git a/modules/g2_import/helpers/g2_import_event.php b/modules/g2_import/helpers/g2_import_event.php
index 13f5b1a0..609e1a45 100644
--- a/modules/g2_import/helpers/g2_import_event.php
+++ b/modules/g2_import/helpers/g2_import_event.php
@@ -18,11 +18,20 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class g2_import_event_Core {
- static function item_before_delete($item) {
+ static function item_deleted($item) {
Database::instance()->delete("g2_maps", array("g3_id" => $item->id));
}
static function item_created($item) {
g2_import::copy_matching_thumbnails_and_resizes($item);
}
+
+ static function admin_menu($menu, $theme) {
+ $menu
+ ->get("settings_menu")
+ ->append(Menu::factory("link")
+ ->id("g2_import")
+ ->label(t("Gallery 2 Import"))
+ ->url(url::site("admin/g2_import")));
+ }
}
diff --git a/modules/g2_import/helpers/g2_import_installer.php b/modules/g2_import/helpers/g2_import_installer.php
index 0f87da6c..feacb518 100644
--- a/modules/g2_import/helpers/g2_import_installer.php
+++ b/modules/g2_import/helpers/g2_import_installer.php
@@ -26,7 +26,7 @@ class g2_import_installer {
`g3_id` int(9) NOT NULL,
PRIMARY KEY (`id`),
KEY (`g2_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("g2_import", 1);
mkdir(VARPATH . "modules/g2_import");
diff --git a/modules/g2_import/helpers/g2_import_menu.php b/modules/g2_import/helpers/g2_import_menu.php
deleted file mode 100644
index 68d75cb4..00000000
--- a/modules/g2_import/helpers/g2_import_menu.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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_menu_Core {
- static function admin($menu, $theme) {
- $menu
- ->get("settings_menu")
- ->append(Menu::factory("link")
- ->id("g2_import")
- ->label(t("Gallery 2 Import"))
- ->url(url::site("admin/g2_import")));
- }
-}
diff --git a/modules/g2_import/module.info b/modules/g2_import/module.info
index 9e04f49b..554cf33b 100644
--- a/modules/g2_import/module.info
+++ b/modules/g2_import/module.info
@@ -1,3 +1,3 @@
-name = Gallery2 Import
-description = Import your Gallery 2 content into Gallery 3
+name = "Gallery2 Import"
+description = "Import your Gallery 2 content into Gallery 3"
version = 1
diff --git a/modules/gallery/controllers/admin_graphics.php b/modules/gallery/controllers/admin_graphics.php
index 72f8d8e1..c59dd38e 100644
--- a/modules/gallery/controllers/admin_graphics.php
+++ b/modules/gallery/controllers/admin_graphics.php
@@ -21,41 +21,24 @@ class Admin_Graphics_Controller extends Admin_Controller {
public function index() {
$view = new Admin_View("admin.html");
$view->content = new View("admin_graphics.html");
- $view->content->available = "";
-
- $tk = new ArrayObject(graphics::detect_toolkits(), ArrayObject::ARRAY_AS_PROPS);
- $active = module::get_var("gallery", "graphics_toolkit", "none");
- foreach (array("gd", "imagemagick", "graphicsmagick", "none") as $id) {
- if ($id == $active) {
- $view->content->active = new View("admin_graphics_$id.html");
- $view->content->active->tk = $tk;
- $view->content->active->is_active = true;
- } else if ($id != "none") {
- $v = new View("admin_graphics_$id.html");
- $v->tk = $tk;
- $v->is_active = false;
- $view->content->available .= $v;
- }
- }
-
+ $view->content->tk = graphics::detect_toolkits();
+ $view->content->active = module::get_var("gallery", "graphics_toolkit", "none");
print $view;
}
- public function choose($toolkit) {
+ public function choose($toolkit_id) {
access::verify_csrf();
- if ($toolkit != module::get_var("gallery", "graphics_toolkit")) {
- module::set_var("gallery", "graphics_toolkit", $toolkit);
-
- $toolkit_info = graphics::detect_toolkits();
- if ($toolkit == "graphicsmagick" || $toolkit == "imagemagick") {
- module::set_var("gallery", "graphics_toolkit_path", $toolkit_info[$toolkit]);
- }
+ if ($toolkit_id != module::get_var("gallery", "graphics_toolkit")) {
+ $tk = graphics::detect_toolkits();
+ module::set_var("gallery", "graphics_toolkit", $toolkit_id);
+ module::set_var("gallery", "graphics_toolkit_path", $tk->$toolkit_id->dir);
site_status::clear("missing_graphics_toolkit");
- message::success(t("Updated Graphics Toolkit"));
- log::success("graphics", t("Changed graphics toolkit to: %toolkit",
- array("toolkit" => $toolkit)));
+
+ $msg = t("Changed graphics toolkit to: %toolkit", array("toolkit" => $tk->$toolkit_id->name));
+ message::success($msg);
+ log::success("graphics", $msg);
}
url::redirect("admin/graphics");
diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php
index 4639de89..ae90ad07 100644
--- a/modules/gallery/controllers/admin_languages.php
+++ b/modules/gallery/controllers/admin_languages.php
@@ -36,7 +36,7 @@ class Admin_Languages_Controller extends Admin_Controller {
$form = $this->_languages_form();
if ($form->validate()) {
module::set_var("gallery", "default_locale", $form->choose_language->locale->value);
- locale::update_installed($form->choose_language->installed_locales->value);
+ locales::update_installed($form->choose_language->installed_locales->value);
message::success(t("Settings saved"));
}
url::redirect("admin/languages");
@@ -89,8 +89,8 @@ class Admin_Languages_Controller extends Admin_Controller {
}
private function _languages_form() {
- $all_locales = locale::available();
- $installed_locales = locale::installed();
+ $all_locales = locales::available();
+ $installed_locales = locales::installed();
$form = new Forge("admin/languages/save", "", "post", array("id" => "gLanguageSettingsForm"));
$group = $form->group("choose_language")
->label(t("Language settings"));
@@ -119,7 +119,7 @@ class Admin_Languages_Controller extends Admin_Controller {
private function _share_translations_form() {
$form = new Forge("admin/languages/share", "", "post", array("id" => "gShareTranslationsForm"));
$group = $form->group("sharing")
- ->label(t("Sharing you own translations with the Gallery community is easy. Please do!"));
+ ->label(t("Sharing your own translations with the Gallery community is easy. Please do!"));
$api_key = l10n_client::api_key();
$server_link = l10n_client::server_api_key_url();
$group->input("api_key")
diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php
index d141d157..cdfa823d 100644
--- a/modules/gallery/controllers/albums.php
+++ b/modules/gallery/controllers/albums.php
@@ -122,7 +122,7 @@ class Albums_Controller extends Items_Controller {
print json_encode(
array(
"result" => "error",
- "form" => $form->__toString() . html::script("modules/gallery/js/albums_form_add.js")));
+ "form" => $form->__toString()));
}
}
@@ -174,29 +174,23 @@ class Albums_Controller extends Items_Controller {
->from("items")
->where("parent_id", $album->parent_id)
->where("id <>", $album->id)
- ->where("name", $form->edit_album->dirname->value)
+ ->where("name", $form->edit_item->dirname->value)
->count_records()) {
- $form->edit_album->dirname->add_error("conflict", 1);
+ $form->edit_item->dirname->add_error("conflict", 1);
$valid = false;
}
}
- // @todo
- // @todo we need to make sure that filename / dirname components can't contain a /
- // @todo
-
if ($valid) {
- $orig = clone $album;
- $album->title = $form->edit_album->title->value;
- $album->description = $form->edit_album->description->value;
- $album->sort_column = $form->edit_album->sort_order->column->value;
- $album->sort_order = $form->edit_album->sort_order->direction->value;
+ $album->title = $form->edit_item->title->value;
+ $album->description = $form->edit_item->description->value;
+ $album->sort_column = $form->edit_item->sort_order->column->value;
+ $album->sort_order = $form->edit_item->sort_order->direction->value;
if ($album->id != 1) {
- $album->rename($form->edit_album->dirname->value);
+ $album->rename($form->edit_item->dirname->value);
}
$album->save();
-
- module::event("item_updated", $orig, $album);
+ module::event("item_edit_form_completed", $album, $form);
log::success("content", "Updated album", "<a href=\"albums/$album->id\">view</a>");
message::success(
@@ -222,8 +216,7 @@ class Albums_Controller extends Items_Controller {
switch ($this->input->get("type")) {
case "album":
- print album::get_add_form($album) .
- html::script("modules/gallery/js/albums_form_add.js");
+ print album::get_add_form($album);
break;
case "photo":
diff --git a/modules/gallery/controllers/combined.php b/modules/gallery/controllers/combined.php
index 925d052d..9a790fdf 100644
--- a/modules/gallery/controllers/combined.php
+++ b/modules/gallery/controllers/combined.php
@@ -60,14 +60,15 @@ class Combined_Controller extends Controller {
$cache = Cache::instance();
$use_gzip = function_exists("gzencode") &&
- (strpos($input->server("HTTP_ACCEPT_ENCODING"), "gzip") !== false);
+ stripos($input->server("HTTP_ACCEPT_ENCODING"), "gzip") !== false &&
+ (int) ini_get("zlib.output_compression") === 0;
+
if ($use_gzip && $content = $cache->get("{$key}_gz")) {
header("Content-Encoding: gzip");
} else {
// Fall back to non-gzipped if we have to
$content = $cache->get($key);
}
-
if (empty($content)) {
Kohana::show_404();
}
diff --git a/modules/gallery/controllers/file_proxy.php b/modules/gallery/controllers/file_proxy.php
index 0d64bcd9..8cb90c50 100644
--- a/modules/gallery/controllers/file_proxy.php
+++ b/modules/gallery/controllers/file_proxy.php
@@ -32,8 +32,9 @@ class File_Proxy_Controller extends Controller {
$request_uri = $this->input->server("REQUEST_URI");
$request_uri = preg_replace("/\?.*/", "", $request_uri);
- // Unescape %7E ("~") and %20 (" ")
- $request_uri = str_replace(array("%7E", "%20"), array("~", " "), $request_uri);
+ // Unescape %7E (~), %20 ( ) and %27 (')
+ // @todo: figure out why we have to do this and unescape everything appropriate
+ $request_uri = str_replace(array("%7E", "%20", "%27"), array("~", " ", "'"), $request_uri);
// var_uri: http://example.com/gallery3/var/
$var_uri = url::file("var/");
@@ -62,21 +63,20 @@ class File_Proxy_Controller extends Controller {
// We now have the relative path to the item. Search for it in the path cache
$item = ORM::factory("item")->where("relative_path_cache", $path)->find();
if (!$item->loaded) {
- // We didn't turn it up. This may mean that the path cache is out of date, so look it up
- // the hard way.
- //
- // Find all items that match the level and name, then iterate over those to find a match.
- // In most cases we'll get it in one. Note that for the level calculation, we just count the
- // size of $paths.
- $paths = explode("/", $path);
- $count = count($paths);
- foreach (ORM::factory("item")
- ->where("name", $paths[$count - 1])
- ->where("level", $count + 1)
- ->find_all() as $match) {
- if ($match->relative_path() == $path) {
- $item = $match;
- break;
+ // We didn't turn it up. It's possible that the relative_path_cache is out of date here.
+ // There was fallback code, but bharat deleted it in 8f1bca74. If it turns out to be
+ // necessary, it's easily resurrected.
+
+ // If we're looking for a .jpg then it's it's possible that we're requesting the thumbnail
+ // for a movie. In that case, the .flv or .mp4 file would have been converted to a .jpg.
+ // So try some alternate types:
+ if (preg_match('/.jpg$/', $path)) {
+ foreach (array("flv", "mp4") as $ext) {
+ $movie_path = preg_replace('/.jpg$/', ".$ext", $path);
+ $item = ORM::factory("item")->where("relative_path_cache", $movie_path)->find();
+ if ($item->loaded) {
+ break;
+ }
}
}
}
@@ -115,8 +115,13 @@ class File_Proxy_Controller extends Controller {
// We don't need to save the session for this request
Session::abort_save();
- // Dump out the image
- header("Content-Type: $item->mime_type");
+ // Dump out the image. If the item is a movie, then its thumbnail will be a JPG.
+ if (in_array($item->mime_type, array("video/x-flv", "video/mp4"))) {
+ header("Content-type: image/jpeg");
+ } else {
+ header("Content-Type: $item->mime_type");
+ }
+
Kohana::close_buffers(false);
$fd = fopen($file, "rb");
fpassthru($fd);
diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php
index 30a5d78c..c8227d74 100644
--- a/modules/gallery/controllers/movies.php
+++ b/modules/gallery/controllers/movies.php
@@ -77,21 +77,19 @@ class Movies_Controller extends Items_Controller {
->from("items")
->where("parent_id", $photo->parent_id)
->where("id <>", $photo->id)
- ->where("name", $form->edit_photo->filename->value)
+ ->where("name", $form->edit_item->filename->value)
->count_records()) {
- $form->edit_photo->filename->add_error("conflict", 1);
+ $form->edit_item->filename->add_error("conflict", 1);
$valid = false;
}
}
if ($valid) {
- $orig = clone $photo;
- $photo->title = $form->edit_photo->title->value;
- $photo->description = $form->edit_photo->description->value;
- $photo->rename($form->edit_photo->filename->value);
+ $photo->title = $form->edit_item->title->value;
+ $photo->description = $form->edit_item->description->value;
+ $photo->rename($form->edit_item->filename->value);
$photo->save();
-
- module::event("item_updated", $orig, $photo);
+ module::event("item_edit_form_completed", $photo, $form);
log::success("content", "Updated photo", "<a href=\"photos/$photo->id\">view</a>");
message::success(
diff --git a/modules/gallery/controllers/packager.php b/modules/gallery/controllers/packager.php
index da0a7983..fbb1d07d 100644
--- a/modules/gallery/controllers/packager.php
+++ b/modules/gallery/controllers/packager.php
@@ -98,7 +98,7 @@ class Packager_Controller extends Controller {
print "$sql_file is not writeable";
return;
}
- $command = "mysqldump --compact --add-drop-table -h{$conn['host']} " .
+ $command = "mysqldump --compact --skip-extended-insert --add-drop-table -h{$conn['host']} " .
"-u{$conn['user']} $pass {$conn['database']} > $sql_file";
exec($command, $output, $status);
if ($status) {
@@ -123,6 +123,10 @@ class Packager_Controller extends Controller {
// Normalize dates
$line = preg_replace("/,$root_created_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
$line = preg_replace("/,$root_updated_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
+
+ // Remove ENGINE= specifications
+ $line = preg_replace("/ENGINE=\S+ /", "", $line);
+
$buf .= $line;
}
$fd = fopen($sql_file, "wb");
@@ -153,7 +157,7 @@ class Packager_Controller extends Controller {
$paths[] = "VARPATH . \"" . substr($name, strlen(VARPATH)) . "\"";
} else {
// @todo: serialize non-directories
- print "Unknown file: $name";
+ print "IGNORING FILE: $name\n";
return;
}
}
diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php
index 6a62e859..8ee24da8 100644
--- a/modules/gallery/controllers/photos.php
+++ b/modules/gallery/controllers/photos.php
@@ -63,28 +63,26 @@ class Photos_Controller extends Items_Controller {
$form = photo::get_edit_form($photo);
if ($valid = $form->validate()) {
- if ($form->edit_photo->filename->value != $photo->name) {
+ if ($form->edit_item->filename->value != $photo->name) {
// Make sure that there's not a conflict
if (Database::instance()
->from("items")
->where("parent_id", $photo->parent_id)
->where("id <>", $photo->id)
- ->where("name", $form->edit_photo->filename->value)
+ ->where("name", $form->edit_item->filename->value)
->count_records()) {
- $form->edit_photo->filename->add_error("conflict", 1);
+ $form->edit_item->filename->add_error("conflict", 1);
$valid = false;
}
}
}
if ($valid) {
- $orig = clone $photo;
- $photo->title = $form->edit_photo->title->value;
- $photo->description = $form->edit_photo->description->value;
- $photo->rename($form->edit_photo->filename->value);
+ $photo->title = $form->edit_item->title->value;
+ $photo->description = $form->edit_item->description->value;
+ $photo->rename($form->edit_item->filename->value);
$photo->save();
-
- module::event("item_updated", $orig, $photo);
+ module::event("item_edit_form_completed", $photo, $form);
log::success("content", "Updated photo", "<a href=\"photos/$photo->id\">view</a>");
message::success(
diff --git a/modules/gallery/controllers/quick.php b/modules/gallery/controllers/quick.php
index 53af2ba6..82176e02 100644
--- a/modules/gallery/controllers/quick.php
+++ b/modules/gallery/controllers/quick.php
@@ -18,20 +18,6 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Quick_Controller extends Controller {
- public function pane($id) {
- $item = model_cache::get("item", $id);
- if (!access::can("view", $item) || !access::can("edit", $item)) {
- return "";
- }
-
- $view = new View("quick_pane.html");
- $page_type = Input::instance()->get("page_type");
- $view->button_list = gallery_quick::get_quick_buttons($item, $page_type);
- $view->item = $item;
- $view->page_type = $page_type;
- print $view;
- }
-
public function rotate($id, $dir) {
access::verify_csrf();
$item = model_cache::get("item", $id);
@@ -127,6 +113,7 @@ class Quick_Controller extends Controller {
$msg = t("Deleted photo <b>%title</b>", array("title" => p::purify($item->title)));
}
+ $parent = $item->parent();
$item->delete();
message::success($msg);
diff --git a/modules/gallery/controllers/simple_uploader.php b/modules/gallery/controllers/simple_uploader.php
index 713e30af..e7c0bd6f 100644
--- a/modules/gallery/controllers/simple_uploader.php
+++ b/modules/gallery/controllers/simple_uploader.php
@@ -43,7 +43,7 @@ class Simple_Uploader_Controller extends Controller {
$file_validation = new Validation($_FILES);
$file_validation->add_rules(
- "Filedata", "upload::valid", "upload::type[gif,jpg,jpeg,png,flv,mp4]");
+ "Filedata", "upload::valid", "upload::required", "upload::type[gif,jpg,jpeg,png,flv,mp4]");
if ($file_validation->validate()) {
// SimpleUploader.swf does not yet call /start directly, so simulate it here for now.
if (!batch::in_progress()) {
@@ -54,24 +54,32 @@ class Simple_Uploader_Controller extends Controller {
try {
$name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds
$title = item::convert_filename_to_title($name);
- $path_info = pathinfo($temp_filename);
+ $path_info = @pathinfo($temp_filename);
if (array_key_exists("extension", $path_info) &&
in_array(strtolower($path_info["extension"]), array("flv", "mp4"))) {
- $movie = movie::create($album, $temp_filename, $name, $title);
+ $item = movie::create($album, $temp_filename, $name, $title);
log::success("content", t("Added a movie"),
- html::anchor("movies/$movie->id", t("view movie")));
+ html::anchor("movies/$item->id", t("view movie")));
} else {
- $photo = photo::create($album, $temp_filename, $name, $title);
+ $item = photo::create($album, $temp_filename, $name, $title);
log::success("content", t("Added a photo"),
- html::anchor("photos/$photo->id", t("view photo")));
+ html::anchor("photos/$item->id", t("view photo")));
}
} catch (Exception $e) {
- unlink($temp_filename);
- throw $e;
+ Kohana::log("alert", $e->__toString());
+ if (file_exists($temp_filename)) {
+ unlink($temp_filename);
+ }
+ header("HTTP/1.1 500 Internal Server Error");
+ print "ERROR:" . $e->getMessage();
+ return;
}
unlink($temp_filename);
+ print "FILEID: $item->id";
+ } else {
+ header("HTTP/1.1 400 Bad Request");
+ print "ERROR: Invalid Upload";
}
- print "File Received";
}
public function finish() {
diff --git a/modules/gallery/css/quick.css b/modules/gallery/css/quick.css
deleted file mode 100644
index 02f9953e..00000000
--- a/modules/gallery/css/quick.css
+++ /dev/null
@@ -1,40 +0,0 @@
-.gItem:hover {
- background-color: #cfdeff;
-}
-
-.gQuick {
- border: none !important;
- margin: 0 !important;
- padding: 0 !important;
-}
-
-#gQuickPane {
- background: #000;
- border-bottom: 1px solid #ccc;
- opacity: 0.9;
-}
-
-#gQuickPane a {
- cursor: pointer;
- float: left;
- margin: 4px;
-}
-
-#gQuickPaneOptions {
- background: #000;
- float: left;
- width: 100%;
-}
-
-#gQuickPaneOptions li a {
- display: block;
- float: none;
- width: auto;
- margin: 0;
- padding: .5em .5em .5em .8em;
- text-align: left;
-}
-
-#gQuickPaneOptions li a:hover {
- background-color: #4d4d4d;
-}
diff --git a/modules/gallery/helpers/MY_remote.php b/modules/gallery/helpers/MY_remote.php
index 4abf5bf1..af2a05d8 100644
--- a/modules/gallery/helpers/MY_remote.php
+++ b/modules/gallery/helpers/MY_remote.php
@@ -21,11 +21,11 @@ class remote extends remote_Core {
static function post($url, $post_data_array, $extra_headers=array()) {
$post_data_raw = self::_encode_post_data($post_data_array, $extra_headers);
-
+
/* Read the web page into a buffer */
list ($response_status, $response_headers, $response_body) =
self::do_request($url, 'POST', $extra_headers, $post_data_raw);
-
+
return array($response_body, $response_status, $response_headers);
}
@@ -49,22 +49,23 @@ class remote extends remote_Core {
}
$post_data_raw .= urlencode($key) . '=' . urlencode($value);
}
-
+
$extra_headers['Content-Type'] = 'application/x-www-form-urlencoded';
$extra_headers['Content-Length'] = strlen($post_data_raw);
-
+
return $post_data_raw;
}
/**
* A single request, without following redirects
*
- * @todo: Handle redirects? If so, only for GET (i.e. not for POST), and use G2's WebHelper_simple::_parseLocation logic.
+ * @todo: Handle redirects? If so, only for GET (i.e. not for POST), and use G2's
+ * WebHelper_simple::_parseLocation logic.
*/
static function do_request($url, $method='GET', $headers=array(), $body='') {
/* Convert illegal characters */
$url = str_replace(' ', '%20', $url);
-
+
$url_components = self::_parse_url_for_fsockopen($url);
$handle = fsockopen(
$url_components['fsockhost'], $url_components['port'], $errno, $errstr, 5);
@@ -72,12 +73,12 @@ class remote extends remote_Core {
// log "Error $errno: '$errstr' requesting $url";
return array(null, null, null);
}
-
+
$header_lines = array('Host: ' . $url_components['host']);
foreach ($headers as $key => $value) {
$header_lines[] = $key . ': ' . $value;
}
-
+
$success = fwrite($handle, sprintf("%s %s HTTP/1.0\r\n%s\r\n\r\n%s",
$method,
$url_components['uri'],
@@ -89,7 +90,7 @@ class remote extends remote_Core {
return array(null, null, null);
}
fflush($handle);
-
+
/*
* Read the status line. fgets stops after newlines. The first line is the protocol
* version followed by a numeric status code and its associated textual phrase.
@@ -99,7 +100,7 @@ class remote extends remote_Core {
// 'Empty http response code, maybe timeout'
return array(null, null, null);
}
-
+
/* Read the headers */
$response_headers = array();
while (!feof($handle)) {
@@ -107,10 +108,10 @@ class remote extends remote_Core {
if (empty($line)) {
break;
}
-
+
/* Normalize the line endings */
$line = str_replace("\r", '', $line);
-
+
list ($key, $value) = explode(':', $line, 2);
if (isset($response_headers[$key])) {
if (!is_array($response_headers[$key])) {
@@ -121,7 +122,7 @@ class remote extends remote_Core {
$response_headers[$key] = trim($value);
}
}
-
+
/* Read the body */
$response_body = '';
while (!feof($handle)) {
diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php
index c48f0b79..949aea84 100644
--- a/modules/gallery/helpers/access.php
+++ b/modules/gallery/helpers/access.php
@@ -66,9 +66,10 @@
* the Access_Intent_Model
*/
class access_Core {
- const DENY = 0;
- const ALLOW = 1;
- const UNKNOWN = 2;
+ const DENY = false;
+ const ALLOW = true;
+ const INHERIT = null; // access_intent
+ const UNKNOWN = null; // cache (access_cache, items)
/**
* Does the active user have this permission on this item?
@@ -78,18 +79,30 @@ class access_Core {
* @return boolean
*/
static function can($perm_name, $item) {
+ return self::user_can(user::active(), $perm_name, $item);
+ }
+
+ /**
+ * Does the user have this permission on this item?
+ *
+ * @param User_Model $user
+ * @param string $perm_name
+ * @param Item_Model $item
+ * @return boolean
+ */
+ static function user_can($user, $perm_name, $item) {
if (!$item->loaded) {
return false;
}
- if (user::active()->admin) {
+ if ($user->admin) {
return true;
}
$resource = $perm_name == "view" ?
$item : model_cache::get("access_cache", $item->id, "item_id");
- foreach (user::group_ids() as $id) {
- if ($resource->__get("{$perm_name}_$id") === self::ALLOW) {
+ foreach ($user->groups as $group) {
+ if ($resource->__get("{$perm_name}_{$group->id}") === self::ALLOW) {
return true;
}
}
@@ -129,7 +142,7 @@ class access_Core {
* @param Group_Model $group
* @param string $perm_name
* @param Item_Model $item
- * @return integer access::ALLOW, access::DENY or null for no intent
+ * @return boolean access::ALLOW, access::DENY or access::INHERIT (null) for no intent
*/
static function group_intent($group, $perm_name, $item) {
$intent = model_cache::get("access_intent", $item->id, "item_id");
@@ -153,11 +166,11 @@ class access_Core {
// For view permissions, if any parent is self::DENY, then those parents lock this one.
// Return
$lock = ORM::factory("item")
- ->where("`left` <= $item->left")
- ->where("`right` >= $item->right")
+ ->where("`left_ptr` <= $item->left_ptr")
+ ->where("`right_ptr` >= $item->right_ptr")
->where("items.id <> $item->id")
->join("access_intents", "items.id", "access_intents.item_id")
- ->where("access_intents.view_$group->id", 0)
+ ->where("access_intents.view_$group->id", self::DENY)
->orderby("level", "DESC")
->limit(1)
->find();
@@ -205,6 +218,7 @@ class access_Core {
}
self::_update_htaccess_files($album, $group, $perm_name, $value);
+ model_cache::clear();
}
/**
@@ -240,7 +254,23 @@ class access_Core {
if ($item->id == 1) {
throw new Exception("@todo CANT_RESET_ROOT_PERMISSION");
}
- self::_set($group, $perm_name, $item, null);
+ self::_set($group, $perm_name, $item, self::INHERIT);
+ }
+
+ /**
+ * Recalculate the permissions for a given item and its hierarchy. $item must be an album.
+ */
+ static function recalculate_permissions($item) {
+ 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);
+ } else {
+ self::_update_access_non_view_cache($group, $perm->name, $item);
+ }
+ }
+ }
+ model_cache::clear();
}
/**
@@ -411,6 +441,7 @@ class access_Core {
$cache_table = $perm_name == "view" ? "items" : "access_caches";
$db->query("ALTER TABLE {{$cache_table}} DROP `$field`");
$db->query("ALTER TABLE {access_intents} DROP `$field`");
+ model_cache::clear();
ORM::factory("access_intent")->clear_cache();
}
@@ -425,9 +456,11 @@ class access_Core {
$db = Database::instance();
$field = "{$perm_name}_{$group->id}";
$cache_table = $perm_name == "view" ? "items" : "access_caches";
- $db->query("ALTER TABLE {{$cache_table}} ADD `$field` SMALLINT NOT NULL DEFAULT 0");
- $db->query("ALTER TABLE {access_intents} ADD `$field` BOOLEAN DEFAULT NULL");
- $db->update("access_intents", array($field => 0), array("item_id" => 1));
+ $not_null = $cache_table == "items" ? "" : "NOT NULL";
+ $db->query("ALTER TABLE {{$cache_table}} ADD `$field` BINARY $not_null DEFAULT FALSE");
+ $db->query("ALTER TABLE {access_intents} ADD `$field` BINARY DEFAULT NULL");
+ $db->update("access_intents", array($field => self::DENY), array("item_id" => 1));
+ model_cache::clear();
ORM::factory("access_intent")->clear_cache();
}
@@ -457,11 +490,11 @@ class access_Core {
// item, then its safe to propagate from here.
if ($access->$field !== self::DENY) {
$tmp_item = ORM::factory("item")
- ->where("left <", $item->left)
- ->where("right >", $item->right)
+ ->where("left_ptr <", $item->left_ptr)
+ ->where("right_ptr >", $item->right_ptr)
->join("access_intents", "access_intents.item_id", "items.id")
->where("access_intents.$field", self::DENY)
- ->orderby("left", "DESC")
+ ->orderby("left_ptr", "DESC")
->limit(1)
->find();
if ($tmp_item->loaded) {
@@ -474,26 +507,26 @@ class access_Core {
// them according the rule above. So mark every permission below this level as UNKNOWN so
// that we can tell which permissions have been changed, and which ones need to be updated.
$db->update("items", array($field => self::UNKNOWN),
- array("left >=" => $item->left, "right <=" => $item->right));
+ array("left_ptr >=" => $item->left_ptr, "right_ptr <=" => $item->right_ptr));
$query = ORM::factory("access_intent")
- ->select(array("access_intents.$field", "items.left", "items.right", "items.id"))
+ ->select(array("access_intents.$field", "items.left_ptr", "items.right_ptr", "items.id"))
->join("items", "items.id", "access_intents.item_id")
- ->where("left >=", $item->left)
- ->where("right <=", $item->right)
+ ->where("left_ptr >=", $item->left_ptr)
+ ->where("right_ptr <=", $item->right_ptr)
->where("type", "album")
- ->where("access_intents.$field IS NOT", null)
+ ->where("access_intents.$field IS NOT", self::INHERIT)
->orderby("level", "DESC")
->find_all();
foreach ($query as $row) {
if ($row->$field == self::ALLOW) {
// Propagate ALLOW for any row that is still UNKNOWN.
$db->update("items", array($field => $row->$field),
- array($field => self::UNKNOWN, "left >=" => $row->left, "right <=" => $row->right));
+ array($field => self::UNKNOWN, "left_ptr >=" => $row->left_ptr, "right_ptr <=" => $row->right_ptr));
} else if ($row->$field == self::DENY) {
// DENY overwrites everything below it
$db->update("items", array($field => $row->$field),
- array("left >=" => $row->left, "right <=" => $row->right));
+ array("left_ptr >=" => $row->left_ptr, "right_ptr <=" => $row->right_ptr));
}
}
@@ -501,7 +534,7 @@ class access_Core {
// DENY parent in the hierarchy to propagate from. So we'll still have a UNKNOWN values in
// the hierarchy, and all of those are safe to change to ALLOW.
$db->update("items", array($field => self::ALLOW),
- array($field => self::UNKNOWN, "left >=" => $item->left, "right <=" => $item->right));
+ array($field => self::UNKNOWN, "left_ptr >=" => $item->left_ptr, "right_ptr <=" => $item->right_ptr));
}
/**
@@ -526,13 +559,13 @@ class access_Core {
//
// @todo To optimize this, we wouldn't need to propagate from the parent, we could just
// propagate from here with the parent's intent.
- if ($access->$field === null) {
+ if ($access->$field === self::INHERIT) {
$tmp_item = ORM::factory("item")
->join("access_intents", "items.id", "access_intents.item_id")
- ->where("left <", $item->left)
- ->where("right >", $item->right)
- ->where("$field IS NOT", null)
- ->orderby("left", "DESC")
+ ->where("left_ptr <", $item->left_ptr)
+ ->where("right_ptr >", $item->right_ptr)
+ ->where("$field IS NOT", self::UNKNOWN)
+ ->orderby("left_ptr", "DESC")
->limit(1)
->find();
if ($tmp_item->loaded) {
@@ -543,20 +576,21 @@ class access_Core {
// With non-view permissions, each level can override any permissions that came above it
// so start at the top and work downwards, overlaying permissions as we go.
$query = ORM::factory("access_intent")
- ->select(array("access_intents.$field", "items.left", "items.right"))
+ ->select(array("access_intents.$field", "items.left_ptr", "items.right_ptr"))
->join("items", "items.id", "access_intents.item_id")
- ->where("left >=", $item->left)
- ->where("right <=", $item->right)
- ->where("$field IS NOT", null)
+ ->where("left_ptr >=", $item->left_ptr)
+ ->where("right_ptr <=", $item->right_ptr)
+ ->where("$field IS NOT", self::INHERIT)
->orderby("level", "ASC")
->find_all();
foreach ($query as $row) {
+ $value = ($row->$field === self::ALLOW) ? "TRUE" : "FALSE";
$db->query(
- "UPDATE {access_caches} SET `$field` = {$row->$field} " .
+ "UPDATE {access_caches} SET `$field` = $value " .
"WHERE `item_id` IN " .
" (SELECT `id` FROM {items} " .
- " WHERE `left` >= $row->left " .
- " AND `right` <= $row->right)");
+ " WHERE `left_ptr` >= $row->left_ptr " .
+ " AND `right_ptr` <= $row->right_ptr)");
}
}
diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php
index 362b93d0..8a7c9951 100644
--- a/modules/gallery/helpers/album.php
+++ b/modules/gallery/helpers/album.php
@@ -71,6 +71,8 @@ class album_Core {
mkdir(dirname($album->thumb_path()));
mkdir(dirname($album->resize_path()));
+ // @todo: publish this from inside Item_Model::save() when we refactor to the point where
+ // there's only one save() happening here.
module::event("item_created", $album);
return $album;
@@ -88,18 +90,21 @@ class album_Core {
$group->hidden("type")->value("album");
$group->submit("")->value(t("Create"));
$form->add_rules_from(ORM::factory("item"));
+ $form->script("")
+ ->url(url::abs_file("modules/gallery/js/albums_form_add.js"));
return $form;
}
static function get_edit_form($parent) {
$form = new Forge("albums/{$parent->id}", "", "post", array("id" => "gEditAlbumForm"));
$form->hidden("_method")->value("put");
- $group = $form->group("edit_album")->label(t("Edit Album"));
+ $group = $form->group("edit_item")->label(t("Edit Album"));
$group->input("title")->label(t("Title"))->value($parent->title);
$group->textarea("description")->label(t("Description"))->value($parent->description);
if ($parent->id != 1) {
$group->input("dirname")->label(t("Directory Name"))->value($parent->name)
+ ->rules("required")
->callback("item::validate_no_slashes")
->error_messages("no_slashes", t("The directory name can't contain a \"/\""))
->callback("item::validate_no_trailing_period")
@@ -111,7 +116,7 @@ class album_Core {
$sort_order->dropdown("column", array("id" => "gAlbumSortColumn"))
->label(t("Sort by"))
- ->options(array("weight" => t("Default"),
+ ->options(array("weight" => t("Order Added"),
"captured" => t("Capture Date"),
"created" => t("Creation Date"),
"title" => t("Title"),
@@ -124,6 +129,9 @@ class album_Core {
->options(array("ASC" => t("Ascending"),
"DESC" => t("Descending")))
->selected($parent->sort_order);
+
+ module::event("item_edit_form", $parent, $form);
+
$group->hidden("type")->value("album");
$group->submit("")->value(t("Modify"));
$form->add_rules_from(ORM::factory("item"));
diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php
index e22cc17f..c81af842 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class gallery_Core {
+ const VERSION = "3.0 git (pre-beta3)";
+
/**
* If Gallery is in maintenance mode, then force all non-admins to get routed to a "This site is
* down for maintenance" page.
@@ -76,4 +78,236 @@ class gallery_Core {
static function time($timestamp) {
return date(module::get_var("gallery", "time_format", "H:i:s"), $timestamp);
}
+
+ static function site_menu($menu, $theme) {
+ if ($theme->page_type != "login") {
+ $menu->append(Menu::factory("link")
+ ->id("home")
+ ->label(t("Home"))
+ ->url(url::site("albums/1")));
+
+ $item = $theme->item();
+
+ $can_edit = $item && access::can("edit", $item);
+ $can_add = $item && access::can("add", $item);
+
+ if ($can_add) {
+ $menu->append(Menu::factory("dialog")
+ ->id("add_photos_item")
+ ->label(t("Add photos"))
+ ->url(url::site("simple_uploader/app/$item->id")));
+ }
+
+ $menu->append($options_menu = Menu::factory("submenu")
+ ->id("options_menu")
+ ->label(t("Options")));
+ if ($item && ($can_edit || $can_add)) {
+ if ($can_edit) {
+ $options_menu
+ ->append(Menu::factory("dialog")
+ ->id("edit_item")
+ ->label($item->is_album() ? t("Edit album") : t("Edit photo"))
+ ->url(url::site("form/edit/{$item->type}s/$item->id")));
+ }
+
+ // @todo Move album options menu to the album quick edit pane
+ if ($item->is_album()) {
+ if ($can_add) {
+ $options_menu
+ ->append(Menu::factory("dialog")
+ ->id("add_album")
+ ->label(t("Add an album"))
+ ->url(url::site("form/add/albums/$item->id?type=album")));
+ }
+
+ if ($can_edit) {
+ $options_menu
+ ->append(Menu::factory("dialog")
+ ->id("edit_permissions")
+ ->label(t("Edit permissions"))
+ ->url(url::site("permissions/browse/$item->id")));
+ }
+ }
+ }
+
+ if (user::active()->admin) {
+ $menu->append($admin_menu = Menu::factory("submenu")
+ ->id("admin_menu")
+ ->label(t("Admin")));
+ gallery::admin_menu($admin_menu, $theme);
+ module::event("admin_menu", $admin_menu, $theme);
+ }
+
+ module::event("site_menu", $menu, $theme);
+ }
+ }
+
+ static function admin_menu($menu, $theme) {
+ $menu
+ ->append(Menu::factory("link")
+ ->id("dashboard")
+ ->label(t("Dashboard"))
+ ->url(url::site("admin")))
+ ->append(Menu::factory("submenu")
+ ->id("settings_menu")
+ ->label(t("Settings"))
+ ->append(Menu::factory("link")
+ ->id("graphics_toolkits")
+ ->label(t("Graphics"))
+ ->url(url::site("admin/graphics")))
+ ->append(Menu::factory("link")
+ ->id("languages")
+ ->label(t("Languages"))
+ ->url(url::site("admin/languages")))
+ ->append(Menu::factory("link")
+ ->id("l10n_mode")
+ ->label(Session::instance()->get("l10n_mode", false)
+ ? t("Stop translating") : t("Start translating"))
+ ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" .
+ access::csrf_token())))
+ ->append(Menu::factory("link")
+ ->id("advanced")
+ ->label(t("Advanced"))
+ ->url(url::site("admin/advanced_settings"))))
+ ->append(Menu::factory("link")
+ ->id("modules")
+ ->label(t("Modules"))
+ ->url(url::site("admin/modules")))
+ ->append(Menu::factory("submenu")
+ ->id("content_menu")
+ ->label(t("Content")))
+ ->append(Menu::factory("submenu")
+ ->id("appearance_menu")
+ ->label(t("Appearance"))
+ ->append(Menu::factory("link")
+ ->id("themes")
+ ->label(t("Theme Choice"))
+ ->url(url::site("admin/themes")))
+ ->append(Menu::factory("link")
+ ->id("theme_options")
+ ->label(t("Theme Options"))
+ ->url(url::site("admin/theme_options"))))
+ ->append(Menu::factory("submenu")
+ ->id("statistics_menu")
+ ->label(t("Statistics")))
+ ->append(Menu::factory("link")
+ ->id("maintenance")
+ ->label(t("Maintenance"))
+ ->url(url::site("admin/maintenance")));
+ return $menu;
+ }
+
+ static function context_menu($menu, $theme, $item, $thumb_css_selector) {
+ $menu->append($options_menu = Menu::factory("submenu")
+ ->id("options_menu")
+ ->label(t("Options"))
+ ->css_class("ui-icon-carat-1-n"));
+
+ if (access::can("edit", $item)) {
+ $page_type = $theme->page_type();
+ switch ($item->type) {
+ case "movie":
+ $edit_title = t("Edit this movie");
+ $delete_title = t("Delete this movie");
+ break;
+
+ case "album":
+ $edit_title = t("Edit this album");
+ $delete_title = t("Delete this album");
+ break;
+
+ default:
+ $edit_title = t("Edit this photo");
+ $delete_title = t("Delete this photo");
+ break;
+ }
+ $cover_title = t("Choose as the album cover");
+ $move_title = t("Move to another album");
+
+ $csrf = access::csrf_token();
+
+ $options_menu->append(Menu::factory("dialog")
+ ->id("edit")
+ ->label($edit_title)
+ ->css_class("ui-icon-pencil")
+ ->url(url::site("quick/form_edit/$item->id?page_type=$page_type")));
+
+
+ if ($item->is_photo() && graphics::can("rotate")) {
+ $options_menu
+ ->append(
+ Menu::factory("ajax_link")
+ ->id("rotate_ccw")
+ ->label(t("Rotate 90&deg; counter clockwise"))
+ ->css_class("ui-icon-rotate-ccw")
+ ->ajax_handler("function(data) { " .
+ "\$.gallery_replace_image(data, \$('$thumb_css_selector')) }")
+ ->url(url::site("quick/rotate/$item->id/ccw?csrf=$csrf&page_type=$page_type")))
+ ->append(
+ Menu::factory("ajax_link")
+ ->id("rotate_cw")
+ ->label(t("Rotate 90&deg; clockwise"))
+ ->css_class("ui-icon-rotate-cw")
+ ->ajax_handler("function(data) { " .
+ "\$.gallery_replace_image(data, \$('$thumb_css_selector')) }")
+ ->url(url::site("quick/rotate/$item->id/cw?csrf=$csrf&page_type=$page_type")));
+ }
+
+ // Don't move photos from the photo page; we don't yet have a good way of redirecting after
+ // move
+ if ($page_type == "album") {
+ $options_menu
+ ->append(Menu::factory("dialog")
+ ->id("move")
+ ->label($move_title)
+ ->css_class("ui-icon-folder-open")
+ ->url(url::site("move/browse/$item->id")));
+ }
+
+ $parent = $item->parent();
+ if (access::can("edit", $parent)) {
+ // We can't make this item the highlight if it's an album with no album cover, or if it's
+ // already the album cover.
+ if (($item->type == "album" && empty($item->album_cover_item_id)) ||
+ ($item->type == "album" && $parent->album_cover_item_id == $item->album_cover_item_id) ||
+ $parent->album_cover_item_id == $item->id) {
+ $disabledState = " ui-state-disabled";
+ } else {
+ $disabledState = " ";
+ }
+ $options_menu
+ ->append(Menu::factory("ajax_link")
+ ->id("make_album_cover")
+ ->label($cover_title)
+ ->css_class("ui-icon-star")
+ ->ajax_handler("function(data) { window.location.reload() }")
+ ->url(url::site("quick/make_album_cover/$item->id?csrf=$csrf")))
+ ->append(Menu::factory("dialog")
+ ->id("delete")
+ ->label($delete_title)
+ ->css_class("ui-icon-trash")
+ ->css_id("gQuickDelete")
+ ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&page_type=$page_type")));
+ }
+
+ if ($item->is_album()) {
+ $options_menu
+ ->append(Menu::factory("dialog")
+ ->id("add_item")
+ ->label(t("Add a photo"))
+ ->css_class("add_item")
+ ->url(url::site("simple_uploader/app/$item->id")))
+ ->append(Menu::factory("dialog")
+ ->id("add_album")
+ ->label(t("Add an album"))
+ ->css_class("add_album")
+ ->url(url::site("form/add/albums/$item->id?type=album")))
+ ->append(Menu::factory("dialog")
+ ->id("edit_permissions")
+ ->label(t("Edit permissions"))
+ ->css_class("permissions")
+ ->url(url::site("permissions/browse/$item->id")));
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index aa11b7c0..64f2a9ff 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -23,7 +23,7 @@ class gallery_event_Core {
access::add_group($group);
}
- static function group_before_delete($group) {
+ static function group_deleted($group) {
access::delete_group($group);
}
@@ -31,10 +31,14 @@ class gallery_event_Core {
access::add_item($item);
}
- static function item_before_delete($item) {
+ static function item_deleted($item) {
access::delete_item($item);
}
+ static function item_moved($item, $old_parent) {
+ access::recalculate_permissions($item->parent());
+ }
+
static function user_login($user) {
// If this user is an admin, check to see if there are any post-install tasks that we need
// to run and take care of those now.
@@ -43,4 +47,10 @@ class gallery_event_Core {
module::clear_var("gallery", "choose_default_tookit");
}
}
+
+ static function item_index_data($item, $data) {
+ $data[] = $item->description;
+ $data[] = $item->name;
+ $data[] = $item->title;
+ }
}
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index 0e5d29b9..a212ef85 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -24,13 +24,13 @@ class gallery_installer {
`id` int(9) NOT NULL auto_increment,
`item_id` int(9),
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {access_intents} (
`id` int(9) NOT NULL auto_increment,
`item_id` int(9),
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {caches} (
`id` int(9) NOT NULL auto_increment,
@@ -40,7 +40,7 @@ class gallery_installer {
`cache` longblob,
PRIMARY KEY (`id`),
KEY (`tags`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {graphics_rules} (
`id` int(9) NOT NULL auto_increment,
@@ -51,7 +51,7 @@ class gallery_installer {
`priority` int(9) NOT NULL,
`target` varchar(32) NOT NULL,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {incoming_translations} (
`id` int(9) NOT NULL auto_increment,
@@ -63,7 +63,7 @@ class gallery_installer {
PRIMARY KEY (`id`),
UNIQUE KEY(`key`, `locale`),
KEY `locale_key` (`locale`, `key`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {items} (
`id` int(9) NOT NULL auto_increment,
@@ -72,7 +72,7 @@ class gallery_installer {
`created` int(9) default NULL,
`description` varchar(2048) default NULL,
`height` int(9) default NULL,
- `left` int(9) NOT NULL,
+ `left_ptr` int(9) NOT NULL,
`level` int(9) NOT NULL,
`mime_type` varchar(64) default NULL,
`name` varchar(255) default NULL,
@@ -83,7 +83,7 @@ class gallery_installer {
`resize_dirty` boolean default 1,
`resize_height` int(9) default NULL,
`resize_width` int(9) default NULL,
- `right` int(9) NOT NULL,
+ `right_ptr` int(9) NOT NULL,
`sort_column` varchar(64) default NULL,
`sort_order` char(4) default 'ASC',
`thumb_dirty` boolean default 1,
@@ -98,8 +98,9 @@ class gallery_installer {
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`),
KEY `type` (`type`),
- KEY `random` (`rand_key`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ KEY `random` (`rand_key`),
+ KEY `weight` (`weight` DESC))
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {logs} (
`id` int(9) NOT NULL auto_increment,
@@ -112,7 +113,7 @@ class gallery_installer {
`url` varchar(255) default NULL,
`user_id` int(9) default 0,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {messages} (
`id` int(9) NOT NULL auto_increment,
@@ -121,7 +122,7 @@ class gallery_installer {
`value` varchar(255) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`key`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {modules} (
`id` int(9) NOT NULL auto_increment,
@@ -130,7 +131,7 @@ class gallery_installer {
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {outgoing_translations} (
`id` int(9) NOT NULL auto_increment,
@@ -142,7 +143,7 @@ class gallery_installer {
PRIMARY KEY (`id`),
UNIQUE KEY(`key`, `locale`),
KEY `locale_key` (`locale`, `key`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {permissions} (
`id` int(9) NOT NULL auto_increment,
@@ -150,14 +151,14 @@ class gallery_installer {
`name` varchar(64) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {sessions} (
`session_id` varchar(127) NOT NULL,
`data` text NOT NULL,
`last_activity` int(10) UNSIGNED NOT NULL,
PRIMARY KEY (`session_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {tasks} (
`id` int(9) NOT NULL auto_increment,
@@ -172,7 +173,7 @@ class gallery_installer {
`updated` int(9) default NULL,
PRIMARY KEY (`id`),
KEY (`owner_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {themes} (
`id` int(9) NOT NULL auto_increment,
@@ -180,7 +181,7 @@ class gallery_installer {
`version` int(9) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE {vars} (
`id` int(9) NOT NULL auto_increment,
@@ -189,7 +190,7 @@ class gallery_installer {
`value` text,
PRIMARY KEY (`id`),
UNIQUE KEY(`module_name`, `name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
foreach (array("albums", "logs", "modules", "resizes", "thumbs", "tmp", "uploads") as $dir) {
@mkdir(VARPATH . $dir);
@@ -204,8 +205,8 @@ class gallery_installer {
$root->type = "album";
$root->title = "Gallery";
$root->description = "";
- $root->left = 1;
- $root->right = 2;
+ $root->left_ptr = 1;
+ $root->right_ptr = 2;
$root->parent_id = 0;
$root->level = 1;
$root->thumb_dirty = 1;
@@ -251,7 +252,6 @@ class gallery_installer {
block_manager::add("dashboard_center", "gallery", "photo_stream");
block_manager::add("dashboard_center", "gallery", "log_entries");
- module::set_var("gallery", "version", "3.0 pre beta 2 (git)");
module::set_var("gallery", "choose_default_tookit", 1);
module::set_var("gallery", "date_format", "Y-M-d");
module::set_var("gallery", "date_time_format", "Y-M-d H:i:s");
@@ -259,7 +259,7 @@ class gallery_installer {
module::set_var("gallery", "show_credits", 1);
// @todo this string needs to be picked up by l10n_scanner
module::set_var("gallery", "credits", "Powered by <a href=\"%url\">Gallery %version</a>");
- module::set_version("gallery", 6);
+ module::set_version("gallery", 10);
}
static function upgrade($version) {
@@ -268,7 +268,6 @@ class gallery_installer {
module::set_var("gallery", "date_format", "Y-M-d");
module::set_var("gallery", "date_time_format", "Y-M-d H:i:s");
module::set_var("gallery", "time_format", "H:i:s");
- module::set_var("gallery", "version", "3.0 pre beta 2 (git)");
module::set_version("gallery", $version = 2);
}
@@ -285,7 +284,7 @@ class gallery_installer {
`cache` text,
PRIMARY KEY (`id`),
KEY (`tags`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("gallery", $version = 4);
}
@@ -302,7 +301,42 @@ class gallery_installer {
$db->query("ALTER TABLE {caches} ADD COLUMN `id` int(9) NOT NULL auto_increment PRIMARY KEY");
module::set_version("gallery", $version = 6);
}
- }
+
+ if ($version == 6) {
+ module::clear_var("gallery", "version");
+ module::set_version("gallery", $version = 7);
+ }
+
+ if ($version == 7) {
+ $groups = ORM::factory("group")->find_all();
+ $permissions = ORM::factory("permission")->find_all();
+ foreach($groups as $group) {
+ foreach($permissions as $permission) {
+ // Update access intents
+ $db->query("ALTER TABLE {access_intents} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT NULL");
+ // Update access cache
+ if ($permission->name === "view") {
+ $db->query("ALTER TABLE {items} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) DEFAULT FALSE");
+ } else {
+ $db->query("ALTER TABLE {access_caches} MODIFY COLUMN {$permission->name}_{$group->id} BINARY(1) NOT NULL DEFAULT FALSE");
+ }
+ }
+ }
+ module::set_version("gallery", $version = 8);
+ }
+
+ if ($version == 8) {
+ $db->query("ALTER TABLE {items} CHANGE COLUMN `left` `left_ptr` INT(9) NOT NULL;");
+ $db->query("ALTER TABLE {items} CHANGE COLUMN `right` `right_ptr` INT(9) NOT NULL;");
+ module::set_version("gallery", $version = 9);
+ }
+
+ if ($version == 9) {
+ $db->query("ALTER TABLE {items} ADD KEY `weight` (`weight` DESC);");
+
+ module::set_version("gallery", $version = 10);
+ }
+}
static function uninstall() {
$db = Database::instance();
diff --git a/modules/gallery/helpers/gallery_menu.php b/modules/gallery/helpers/gallery_menu.php
deleted file mode 100644
index 1f1e1ce2..00000000
--- a/modules/gallery/helpers/gallery_menu.php
+++ /dev/null
@@ -1,163 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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 gallery_menu_Core {
- static function site($menu, $theme) {
- $is_admin = user::active()->admin;
-
- $menu->append(Menu::factory("link")
- ->id("home")
- ->label(t("Home"))
- ->url(url::site("albums/1")));
-
- $item = $theme->item();
-
- $can_edit = $item && access::can("edit", $item) || $is_admin;
- $can_add = $item && (access::can("add", $item) || $is_admin);
-
- if ($can_add) {
- $menu->append(Menu::factory("dialog")
- ->id("add_photos_item")
- ->label(t("Add photos"))
- ->url(url::site("simple_uploader/app/$item->id")));
- }
-
- if ($item && $can_edit || $can_add) {
- $menu->append($options_menu = Menu::factory("submenu")
- ->id("options_menu")
- ->label(t("Options")));
-
- if ($can_edit) {
- $options_menu
- ->append(Menu::factory("dialog")
- ->id("edit_item")
- ->label($item->is_album() ? t("Edit album") : t("Edit photo"))
- ->url(url::site("form/edit/{$item->type}s/$item->id")));
- }
-
- // @todo Move album options menu to the album quick edit pane
- if ($item->is_album()) {
- if ($can_add) {
- $options_menu
- ->append(Menu::factory("dialog")
- ->id("add_album")
- ->label(t("Add an album"))
- ->url(url::site("form/add/albums/$item->id?type=album")));
- }
-
- if ($can_edit) {
- $options_menu
- ->append(Menu::factory("dialog")
- ->id("edit_permissions")
- ->label(t("Edit permissions"))
- ->url(url::site("permissions/browse/$item->id")));
- }
- }
- }
-
- if ($is_admin) {
- $menu->append($admin_menu = Menu::factory("submenu")
- ->id("admin_menu")
- ->label(t("Admin")));
- self::admin($admin_menu, $theme);
- foreach (module::active() as $module) {
- if ($module->name == "gallery") {
- continue;
- }
- $class = "{$module->name}_menu";
- if (method_exists($class, "admin")) {
- call_user_func_array(array($class, "admin"), array(&$admin_menu, $theme));
- }
- }
- }
- }
-
- static function album($menu, $theme) {
- }
-
- static function tag($menu, $theme) {
- }
-
- static function thumb($menu, $theme, $item) {
- }
-
- static function photo($menu, $theme) {
- if (access::can("view_full", $theme->item())) {
- $menu->append(Menu::factory("link")
- ->id("fullsize")
- ->label(t("View full size"))
- ->url($theme->item()->file_url())
- ->css_class("gFullSizeLink"));
- }
- }
-
- static function admin($menu, $theme) {
- $menu
- ->append(Menu::factory("link")
- ->id("dashboard")
- ->label(t("Dashboard"))
- ->url(url::site("admin")))
- ->append(Menu::factory("submenu")
- ->id("settings_menu")
- ->label(t("Settings"))
- ->append(Menu::factory("link")
- ->id("graphics_toolkits")
- ->label(t("Graphics"))
- ->url(url::site("admin/graphics")))
- ->append(Menu::factory("link")
- ->id("languages")
- ->label(t("Languages"))
- ->url(url::site("admin/languages")))
- ->append(Menu::factory("link")
- ->id("l10n_mode")
- ->label(Session::instance()->get("l10n_mode", false)
- ? t("Stop translating") : t("Start translating"))
- ->url(url::site("l10n_client/toggle_l10n_mode?csrf=" .
- access::csrf_token())))
- ->append(Menu::factory("link")
- ->id("advanced")
- ->label(t("Advanced"))
- ->url(url::site("admin/advanced_settings"))))
- ->append(Menu::factory("link")
- ->id("modules")
- ->label(t("Modules"))
- ->url(url::site("admin/modules")))
- ->append(Menu::factory("submenu")
- ->id("content_menu")
- ->label(t("Content")))
- ->append(Menu::factory("submenu")
- ->id("appearance_menu")
- ->label(t("Appearance"))
- ->append(Menu::factory("link")
- ->id("themes")
- ->label(t("Theme Choice"))
- ->url(url::site("admin/themes")))
- ->append(Menu::factory("link")
- ->id("theme_options")
- ->label(t("Theme Options"))
- ->url(url::site("admin/theme_options"))))
- ->append(Menu::factory("submenu")
- ->id("statistics_menu")
- ->label(t("Statistics")))
- ->append(Menu::factory("link")
- ->id("maintenance")
- ->label(t("Maintenance"))
- ->url(url::site("admin/maintenance")));
- }
-}
diff --git a/modules/gallery/helpers/gallery_quick.php b/modules/gallery/helpers/gallery_quick.php
deleted file mode 100644
index d0ffc584..00000000
--- a/modules/gallery/helpers/gallery_quick.php
+++ /dev/null
@@ -1,144 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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 gallery_quick_Core {
- static function get_quick_buttons($item, $page_type) {
- $buttons = self::buttons($item, $page_type);
- foreach (module::active() as $module) {
- if ($module->name == "gallery") {
- continue;
- }
- $class_name = "{$module->name}_quick";
- if (method_exists($class_name, "buttons")) {
- $module_buttons = call_user_func(array($class_name, "buttons"), $item, $page_type);
- foreach (array("left", "center", "right", "additional") as $position) {
- if (!empty($module_buttons[$position])) {
- $buttons[$position] = array_merge($buttons[$position], $module_buttons[$position]);
- }
- }
- }
- }
-
- $sorted_buttons->main = array();
- foreach (array("left", "center", "right") as $position) {
- $sorted_buttons->main = array_merge($sorted_buttons->main, $buttons[$position]);
- }
-
- $sorted_buttons->additional = $buttons["additional"];
- $max_display = empty($sorted_buttons->additional) ? 6 : 5;
- if (count($sorted_buttons->main) >= $max_display) {
- $to_move = array_slice($sorted_buttons->main, 5);
- $sorted_buttons->additional = array_merge($to_move, $sorted_buttons->additional);
- for ($i = count($sorted_buttons->main); $i >= 5; $i--) {
- unset($sorted_buttons->main[$i]);
- }
- }
-
- return $sorted_buttons;
- }
-
- static function buttons($item, $page_type) {
- $elements = array("left" => array(), "center" => array(), "right" => array(),
- "additional" => array());
- switch ($item->type) {
- case "movie":
- $edit_title = t("Edit this movie");
- $move_title = t("Move this movie to another album");
- $cover_title = t("Choose this movie as the album cover");
- $delete_title = t("Delete this movie");
- break;
- case "album":
- $edit_title = t("Edit this album");
- $move_title = t("Move this album to another album");
- $cover_title = t("Choose this album as the album cover");
- $delete_title = t("Delete this album");
- break;
- default:
- $edit_title = t("Edit this photo");
- $move_title = t("Move this photo to another album");
- $cover_title = t("Choose this photo as the album cover");
- $delete_title = t("Delete this photo");
- break;
- }
-
- $csrf = access::csrf_token();
- $elements["left"][] = (object)array(
- "title" => $edit_title,
- "class" => "gDialogLink gButtonLink",
- "icon" => "ui-icon-pencil",
- "href" => url::site("quick/form_edit/$item->id?page_type=$page_type"));
-
- if ($item->is_photo() && graphics::can("rotate")) {
- $elements["left"][] =
- (object)array(
- "title" => t("Rotate 90 degrees counter clockwise"),
- "class" => "gButtonLink",
- "icon" => "ui-icon-rotate-ccw",
- "href" => url::site("quick/rotate/$item->id/ccw?csrf=$csrf&page_type=$page_type"));
- $elements["left"][] =
- (object)array(
- "title" => t("Rotate 90 degrees clockwise"),
- "class" => "gButtonLink",
- "icon" => "ui-icon-rotate-cw",
- "href" => url::site("quick/rotate/$item->id/cw?csrf=$csrf&page_type=$page_type"));
- }
-
- // Don't move photos from the photo page; we don't yet have a good way of redirecting after move
- if ($page_type == "album") {
- $elements["left"][] = (object)array(
- "title" => $move_title,
- "class" => "gDialogLink gButtonLink",
- "icon" => "ui-icon-folder-open",
- "href" => url::site("move/browse/$item->id"));
- }
-
- if (access::can("edit", $item->parent())) {
- $disabledState =
- $item->type == "album" && empty($item->album_cover_item_id) ? " ui-state-disabled" : "";
- $elements["right"][] = (object)array(
- "title" => $cover_title,
- "class" => "gButtonLink{$disabledState}",
- "icon" => "ui-icon-star",
- "href" => url::site("quick/make_album_cover/$item->id?csrf=$csrf&page_type=$page_type"));
-
- $elements["right"][] = (object)array(
- "title" => $delete_title,
- "class" => "gDialogLink gButtonLink",
- "icon" => "ui-icon-trash",
- "id" => "gQuickDelete",
- "href" => url::site("quick/form_delete/$item->id?csrf=$csrf&page_type=$page_type"));
- }
-
- if ($item->is_album()) {
- $elements["additional"][] = (object)array(
- "title" => t("Add a photo"),
- "class" => "add_item gDialogLink",
- "href" => url::site("simple_uploader/app/$item->id"));
- $elements["additional"][] = (object)array(
- "title" => t("Add an album"),
- "class" => "add_album gDialogLink",
- "href" => url::site("form/add/albums/$item->id?type=album"));
- $elements["additional"][] = (object)array(
- "title" => t("Edit permissions"),
- "class" => "permissions gDialogLink",
- "href" => url::site("permissions/browse/$item->id"));
- }
- return $elements;
- }
-}
diff --git a/modules/gallery/helpers/gallery_rss.php b/modules/gallery/helpers/gallery_rss.php
index 7daf6170..8e887368 100644
--- a/modules/gallery/helpers/gallery_rss.php
+++ b/modules/gallery/helpers/gallery_rss.php
@@ -50,8 +50,9 @@ class gallery_rss_Core {
$feed->children = $item
->viewable()
- ->descendants($limit, $offset, "photo");
- $feed->max_pages = ceil($item->viewable()->descendants_count("photo") / $limit);
+ ->descendants($limit, $offset, array("type" => "photo"));
+ $feed->max_pages = ceil(
+ $item->viewable()->descendants_count(array("type" => "photo")) / $limit);
$feed->title = p::purify($item->title);
$feed->link = url::abs_site("albums/{$item->id}");
$feed->description = nl2br(p::purify($item->description));
diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php
index 1152cda2..9edc3acd 100644
--- a/modules/gallery/helpers/gallery_task.php
+++ b/modules/gallery/helpers/gallery_task.php
@@ -45,131 +45,158 @@ class gallery_task_Core {
* @param Task_Model the task
*/
static function rebuild_dirty_images($task) {
- $result = graphics::find_dirty_images_query();
- $completed = $task->get("completed", 0);
- $ignored = $task->get("ignored", array());
- $remaining = $result->count() - count($ignored);
-
- $i = 0;
- foreach ($result as $row) {
- if (array_key_exists($row->id, $ignored)) {
- continue;
- }
+ $errors = array();
+ try {
+ $result = graphics::find_dirty_images_query();
+ $completed = $task->get("completed", 0);
+ $ignored = $task->get("ignored", array());
+ $remaining = $result->count() - count($ignored);
+
+ $i = 0;
+ foreach ($result as $row) {
+ if (array_key_exists($row->id, $ignored)) {
+ continue;
+ }
- $item = ORM::factory("item", $row->id);
- if ($item->loaded) {
- $success = graphics::generate($item);
- if (!$success) {
- $ignored[$item->id] = 1;
+ $item = ORM::factory("item", $row->id);
+ if ($item->loaded) {
+ $success = graphics::generate($item);
+ if (!$success) {
+ $ignored[$item->id] = 1;
+ $errors[] = t("Unable to rebuild images for '%title'",
+ array("title" => p::purify($item->title)));
+ } else {
+ $errors[] = t("Successfully rebuilt images for '%title'",
+ array("title" => p::purify($item->title)));
+ }
}
- }
- $completed++;
- $remaining--;
+ $completed++;
+ $remaining--;
- if (++$i == 2) {
- break;
+ if (++$i == 2) {
+ break;
+ }
}
- }
- $task->status = t2("Updated: 1 image. Total: %total_count.",
- "Updated: %count images. Total: %total_count.",
- $completed,
- array("total_count" => ($remaining + $completed)));
+ $task->status = t2("Updated: 1 image. Total: %total_count.",
+ "Updated: %count images. Total: %total_count.",
+ $completed,
+ array("total_count" => ($remaining + $completed)));
- if ($completed + $remaining > 0) {
- $task->percent_complete = (int)(100 * $completed / ($completed + $remaining));
- } else {
- $task->percent_complete = 100;
- }
+ if ($completed + $remaining > 0) {
+ $task->percent_complete = (int)(100 * $completed / ($completed + $remaining));
+ } else {
+ $task->percent_complete = 100;
+ }
- $task->set("completed", $completed);
- $task->set("ignored", $ignored);
- if ($remaining == 0) {
+ $task->set("completed", $completed);
+ $task->set("ignored", $ignored);
+ if ($remaining == 0) {
+ $task->done = true;
+ $task->state = "success";
+ site_status::clear("graphics_dirty");
+ }
+ } catch (Exception $e) {
$task->done = true;
- $task->state = "success";
- site_status::clear("graphics_dirty");
+ $task->state = "error";
+ $task->status = $e->getMessage();
+ $errors[] = $e->__toString();
+ }
+ if ($errors) {
+ $task->log($errors);
}
}
static function update_l10n(&$task) {
- $start = microtime(true);
- $dirs = $task->get("dirs");
- $files = $task->get("files");
- $cache = $task->get("cache", array());
- $i = 0;
-
- switch ($task->get("mode", "init")) {
- case "init": // 0%
- $dirs = array("gallery", "modules", "themes", "installer");
- $files = array();
- $task->set("mode", "find_files");
- $task->status = t("Finding files");
- break;
-
- case "find_files": // 0% - 10%
- while (($dir = array_pop($dirs)) && microtime(true) - $start < 0.5) {
- if (in_array(basename($dir), array("tests", "lib"))) {
- continue;
- }
+ $errors = array();
+ try {
+ $start = microtime(true);
+ $dirs = $task->get("dirs");
+ $files = $task->get("files");
+ $cache = $task->get("cache", array());
+ $i = 0;
+
+ switch ($task->get("mode", "init")) {
+ case "init": // 0%
+ $dirs = array("gallery", "modules", "themes", "installer");
+ $files = array();
+ $task->set("mode", "find_files");
+ $task->status = t("Finding files");
+ break;
- foreach (glob(DOCROOT . "$dir/*") as $path) {
- $relative_path = str_replace(DOCROOT, "", $path);
- if (is_dir($path)) {
- $dirs[] = $relative_path;
- } else {
- $files[] = $relative_path;
+ case "find_files": // 0% - 10%
+ while (($dir = array_pop($dirs)) && microtime(true) - $start < 0.5) {
+ if (in_array(basename($dir), array("tests", "lib"))) {
+ continue;
+ }
+
+ foreach (glob(DOCROOT . "$dir/*") as $path) {
+ $relative_path = str_replace(DOCROOT, "", $path);
+ if (is_dir($path)) {
+ $dirs[] = $relative_path;
+ } else {
+ $files[] = $relative_path;
+ }
}
}
- }
- $task->status = t2("Finding files: found 1 file",
- "Finding files: found %count files", count($files));
+ $task->status = t2("Finding files: found 1 file",
+ "Finding files: found %count files", count($files));
- if (!$dirs) {
- $task->set("mode", "scan_files");
- $task->set("total_files", count($files));
- $task->status = t("Scanning files");
- $task->percent_complete = 10;
- }
- break;
-
- case "scan_files": // 10% - 90%
- while (($file = array_pop($files)) && microtime(true) - $start < 0.5) {
- $file = DOCROOT . $file;
- switch (pathinfo($file, PATHINFO_EXTENSION)) {
- case "php":
- l10n_scanner::scan_php_file($file, $cache);
- break;
+ if (!$dirs) {
+ $task->set("mode", "scan_files");
+ $task->set("total_files", count($files));
+ $task->status = t("Scanning files");
+ $task->percent_complete = 10;
+ }
+ break;
- case "info":
- l10n_scanner::scan_info_file($file, $cache);
- break;
+ case "scan_files": // 10% - 90%
+ while (($file = array_pop($files)) && microtime(true) - $start < 0.5) {
+ $file = DOCROOT . $file;
+ switch (pathinfo($file, PATHINFO_EXTENSION)) {
+ case "php":
+ l10n_scanner::scan_php_file($file, $cache);
+ break;
+
+ case "info":
+ l10n_scanner::scan_info_file($file, $cache);
+ break;
+ }
}
- }
- $total_files = $task->get("total_files");
- $task->status = t2("Scanning files: scanned 1 file",
- "Scanning files: scanned %count files", $total_files - count($files));
+ $total_files = $task->get("total_files");
+ $task->status = t2("Scanning files: scanned 1 file",
+ "Scanning files: scanned %count files", $total_files - count($files));
+
+ $task->percent_complete = 10 + 80 * ($total_files - count($files)) / $total_files;
+ if (empty($files)) {
+ $task->set("mode", "fetch_updates");
+ $task->status = t("Fetching updates");
+ $task->percent_complete = 90;
+ }
+ break;
- $task->percent_complete = 10 + 80 * ($total_files - count($files)) / $total_files;
- if (empty($files)) {
- $task->set("mode", "fetch_updates");
- $task->status = t("Fetching updates");
- $task->percent_complete = 90;
+ case "fetch_updates": // 90% - 100%
+ l10n_client::fetch_updates();
+ $task->done = true;
+ $task->state = "success";
+ $task->status = t("Translations installed/updated");
+ $task->percent_complete = 100;
}
- break;
- case "fetch_updates": // 90% - 100%
- l10n_client::fetch_updates();
+ $task->set("files", $files);
+ $task->set("dirs", $dirs);
+ $task->set("cache", $cache);
+ } catch (Exception $e) {
$task->done = true;
- $task->state = "success";
- $task->status = t("Translations installed/updated");
- $task->percent_complete = 100;
+ $task->state = "error";
+ $task->status = $e->getMessage();
+ $errors[] = $e->__toString();
+ }
+ if ($errors) {
+ $task->log($errors);
}
-
- $task->set("files", $files);
- $task->set("dirs", $dirs);
- $task->set("cache", $cache);
}
} \ No newline at end of file
diff --git a/modules/gallery/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php
index 0e3150bc..69c5a091 100644
--- a/modules/gallery/helpers/gallery_theme.php
+++ b/modules/gallery/helpers/gallery_theme.php
@@ -22,67 +22,41 @@ class gallery_theme_Core {
$session = Session::instance();
$buf = "";
if ($session->get("debug")) {
- $theme->css("modules/gallery/css/debug.css");
- }
- if (($theme->page_type == "album" || $theme->page_type == "photo")
- && access::can("edit", $theme->item())) {
- $theme->css("modules/gallery/css/quick.css");
- $theme->script("modules/gallery/js/quick.js");
+ $theme->css("debug.css");
}
if (module::is_active("rss")) {
if ($item = $theme->item()) {
- $buf .= rss::feed_link("gallery/album/{$item->id}");
+ if ($item->is_album()) {
+ $buf .= rss::feed_link("gallery/album/{$item->id}");
+ } else {
+ $buf .= rss::feed_link("gallery/album/{$item->parent()->id}");
+ }
} else if ($tag = $theme->tag()) {
$buf .= rss::feed_link("tag/tag/{$tag->id}");
}
}
if ($session->get("l10n_mode", false)) {
- $theme->css("modules/gallery/css/l10n_client.css");
- $theme->script("lib/jquery.cookie.js");
- $theme->script("modules/gallery/js/l10n_client.js");
+ $theme->css("l10n_client.css");
+ $theme->script("jquery.cookie.js");
+ $theme->script("l10n_client.js");
}
return $buf;
}
- static function resize_top($theme, $item) {
- if (access::can("edit", $item)) {
- $edit_link = url::site("quick/pane/$item->id?page_type=photo");
- return "<div class=\"gQuick\" href=\"$edit_link\">";
- }
- }
-
- static function resize_bottom($theme, $item) {
- if (access::can("edit", $item)) {
- return "</div>";
- }
- }
-
- static function thumb_top($theme, $child) {
- if (access::can("edit", $child)) {
- $edit_link = url::site("quick/pane/$child->id?page_type=album");
- return "<div class=\"gQuick\" href=\"$edit_link\">";
- }
- }
-
- static function thumb_bottom($theme, $child) {
- if (access::can("edit", $child)) {
- return "</div>";
- }
- }
-
static function admin_head($theme) {
+ $theme->script("gallery.panel.js");
$session = Session::instance();
if ($session->get("debug")) {
- $theme->css("modules/gallery/css/debug.css");
+ $theme->css("debug.css");
}
if ($session->get("l10n_mode", false)) {
- $theme->css("modules/gallery/css/l10n_client.css");
- $theme->script("lib/jquery.cookie.js");
- $theme->script("modules/gallery/js/l10n_client.js");
+ $theme->css("l10n_client.css");
+ $theme->script("jquery.cookie.js");
+ $theme->script("l10n_client.js");
}
}
@@ -116,12 +90,17 @@ class gallery_theme_Core {
static function credits() {
return "<li class=\"first\">" .
t(module::get_var("gallery", "credits"),
- array("url" => "http://gallery.menalto.com",
- "version" => module::get_var("gallery", "version"))) .
+ array("url" => "http://gallery.menalto.com", "version" => gallery::VERSION)) .
"</li>";
}
static function admin_credits() {
return gallery_theme::credits();
}
+
+ static function body_attributes() {
+ if (locales::is_rtl()) {
+ return 'class="rtl"';
+ }
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php
index bbae0602..7dc46eeb 100644
--- a/modules/gallery/helpers/graphics.php
+++ b/modules/gallery/helpers/graphics.php
@@ -195,6 +195,8 @@ class graphics_Core {
self::init_toolkit();
}
+ module::event("graphics_resize", $input_file, $output_file, $options);
+
if (@filesize($input_file) == 0) {
throw new Exception("@todo EMPTY_INPUT_FILE");
}
@@ -209,6 +211,8 @@ class graphics_Core {
->quality(module::get_var("gallery", "image_quality"))
->save($output_file);
}
+
+ module::event("graphics_resize_completed", $input_file, $output_file, $options);
}
/**
@@ -223,10 +227,14 @@ class graphics_Core {
self::init_toolkit();
}
+ module::event("graphics_rotate", $input_file, $output_file, $options);
+
Image::factory($input_file)
->quality(module::get_var("gallery", "image_quality"))
->rotate($options["degrees"])
->save($output_file);
+
+ module::event("graphics_rotate_completed", $input_file, $output_file, $options);
}
/**
@@ -249,6 +257,8 @@ class graphics_Core {
self::init_toolkit();
}
+ module::event("graphics_composite", $input_file, $output_file, $options);
+
list ($width, $height) = getimagesize($input_file);
list ($w_width, $w_height) = getimagesize($options["file"]);
@@ -276,6 +286,9 @@ class graphics_Core {
->composite($options["file"], $x, $y, $options["transparency"])
->quality(module::get_var("gallery", "image_quality"))
->save($output_file);
+
+
+ module::event("graphics_composite_completed", $input_file, $output_file, $options);
}
/**
@@ -326,15 +339,90 @@ class graphics_Core {
* GraphicsMagick we return the path to the directory containing the appropriate binaries.
*/
static function detect_toolkits() {
+ $toolkits = new stdClass();
+
+ // GD is special, it doesn't use exec()
$gd = function_exists("gd_info") ? gd_info() : array();
- $exec = function_exists("exec");
+ $toolkits->gd->name = "GD";
if (!isset($gd["GD Version"])) {
- $gd["GD Version"] = false;
+ $toolkits->gd->installed = false;
+ $toolkits->gd->error = t("GD is not installed");
+ } else {
+ $toolkits->gd->installed = true;
+ $toolkits->gd->version = $gd["GD Version"];
+ $toolkits->gd->rotate = function_exists("imagerotate");
+ $toolkits->gd->binary = "";
+ $toolkits->gd->dir = "";
+
+ if (!$toolkits->gd->rotate) {
+ $toolkits->gd->error =
+ t("You have GD version %version, but it lacks image rotation.",
+ array("version" => $gd["GD Version"]));
+ }
}
- putenv("PATH=" . getenv("PATH") . ":/usr/local/bin:/opt/local/bin");
- return array("gd" => $gd,
- "imagemagick" => $exec ? dirname(exec("which convert")) : false,
- "graphicsmagick" => $exec ? dirname(exec("which gm")) : false);
+
+ if (!function_exists("exec")) {
+ $toolkits->imagemagick->installed = false;
+ $toolkits->imagemagick->error = t("ImageMagick requires the <b>exec</b> function");
+
+ $toolkits->graphicsmagick->installed = false;
+ $toolkits->graphicsmagick->error = t("GraphicsMagick requires the <b>exec</b> function");
+ } else {
+ putenv("PATH=" . getenv("PATH") . ":/usr/local/bin:/opt/local/bin:/opt/bin");
+
+ // @todo: consider refactoring the two segments below into a loop since they are so
+ // similar.
+
+ // ImageMagick
+ $path = exec("which convert");
+ $toolkits->imagemagick->name = "ImageMagick";
+ if ($path) {
+ if (@is_file($path)) {
+ preg_match('/Version: \S+ (\S+)/', `convert -v`, $matches);
+ $version = $matches[1];
+
+ $toolkits->imagemagick->installed = true;
+ $toolkits->imagemagick->version = $version;
+ $toolkits->imagemagick->binary = $path;
+ $toolkits->imagemagick->dir = dirname($path);
+ $toolkits->imagemagick->rotate = true;
+ } else {
+ $toolkits->imagemagick->installed = false;
+ $toolkits->imagemagick->error =
+ t("ImageMagick is installed, but PHP's open_basedir restriction " .
+ "prevents Gallery from using it.");
+ }
+ } else {
+ $toolkits->imagemagick->installed = false;
+ $toolkits->imagemagick->error = t("We could not locate ImageMagick on your system.");
+ }
+
+ // GraphicsMagick
+ $path = exec("which gm");
+ $toolkits->graphicsmagick->name = "GraphicsMagick";
+ if ($path) {
+ if (@is_file($path)) {
+ preg_match('/\S+ (\S+)/', `gm version`, $matches);
+ $version = $matches[1];
+
+ $toolkits->graphicsmagick->installed = true;
+ $toolkits->graphicsmagick->version = $version;
+ $toolkits->graphicsmagick->binary = $path;
+ $toolkits->graphicsmagick->dir = dirname($path);
+ $toolkits->graphicsmagick->rotate = true;
+ } else {
+ $toolkits->graphicsmagick->installed = false;
+ $toolkits->graphicsmagick->error =
+ t("GraphicsMagick is installed, but PHP's open_basedir restriction " .
+ "prevents Gallery from using it.");
+ }
+ } else {
+ $toolkits->graphicsmagick->installed = false;
+ $toolkits->graphicsmagick->error = t("We could not locate GraphicsMagick on your system.");
+ }
+ }
+
+ return $toolkits;
}
/**
@@ -344,12 +432,13 @@ class graphics_Core {
// Detect a graphics toolkit
$toolkits = graphics::detect_toolkits();
foreach (array("imagemagick", "graphicsmagick", "gd") as $tk) {
- if ($toolkits[$tk]) {
+ if ($toolkits->$tk->installed) {
module::set_var("gallery", "graphics_toolkit", $tk);
- module::set_var("gallery", "graphics_toolkit_path", $tk == "gd" ? "" : $toolkits[$tk]);
+ module::set_var("gallery", "graphics_toolkit_path", $toolkits->$tk->dir);
break;
}
}
+
if (!module::get_var("gallery", "graphics_toolkit")) {
site_status::warning(
t("Graphics toolkit missing! Please <a href=\"%url\">choose a toolkit</a>",
diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php
index f40b5c97..a2d3859f 100644
--- a/modules/gallery/helpers/item.php
+++ b/modules/gallery/helpers/item.php
@@ -53,7 +53,7 @@ class item_Core {
access::required("view", $parent);
access::required("edit", $parent);
- model_cache::clear("item", $parent->album_cover_item_id);
+ model_cache::clear();
$parent->album_cover_item_id = $item->is_album() ? $item->album_cover_item_id : $item->id;
$parent->thumb_dirty = 1;
$parent->save();
@@ -69,7 +69,7 @@ class item_Core {
access::required("edit", $album);
@unlink($album->thumb_path());
- model_cache::clear("item", $album->album_cover_item_id) ;
+ model_cache::clear();
$album->album_cover_item_id = null;
$album->thumb_width = 0;
$album->thumb_height = 0;
@@ -129,7 +129,7 @@ class item_Core {
if (Input::instance()->get("page_type") == "album") {
$page_type = "album";
} else {
- $page_type = "item";
+ $page_type = "photo";
}
$form = new Forge("quick/delete/$item->id?page_type=$page_type", "", "post", array("id" => "gConfirmDelete"));
$form->hidden("_method")->value("put");
@@ -137,4 +137,18 @@ class item_Core {
$group->submit("")->value(t("Delete"));
return $form;
}
+
+ /**
+ * Get the next weight value
+ */
+ static function get_max_weight() {
+ // Guard against an empty result when we create the first item. It's unfortunate that we
+ // have to check this every time.
+ // @todo: figure out a better way to bootstrap the weight.
+ $result = Database::instance()
+ ->select("weight")->from("items")
+ ->orderby("weight", "desc")->limit(1)
+ ->get()->current();
+ return ($result ? $result->weight : 0) + 1;
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/l10n_client.php b/modules/gallery/helpers/l10n_client.php
index e153532c..3460cc65 100644
--- a/modules/gallery/helpers/l10n_client.php
+++ b/modules/gallery/helpers/l10n_client.php
@@ -67,11 +67,14 @@ class l10n_client_Core {
return true;
}
+ /**
+ * @return an array of messages that will be written to the task log
+ */
static function fetch_updates() {
$request->locales = array();
$request->messages = new stdClass();
- $locales = locale::installed();
+ $locales = locales::installed();
foreach ($locales as $locale => $locale_data) {
$request->locales[] = $locale;
}
@@ -101,8 +104,7 @@ class l10n_client_Core {
throw new Exception("@todo TRANSLATIONS_FETCH_REQUEST_FAILED " . $response_status);
}
if (empty($response_data)) {
- log::info("translations", "Translations fetch request resulted in an empty response");
- return;
+ return array(t("Translations fetch request resulted in an empty response"));
}
$response = json_decode($response_data);
@@ -111,11 +113,6 @@ class l10n_client_Core {
// [{key:<key_1>, translation: <JSON encoded translation>, rev:<rev>, locale:<locale>},
// {key:<key_2>, ...}
// ]
- $count = count($response);
- log::info("translations",
- t2("Installed 1 new / updated translation message",
- "Installed %count new / updated translation messages", $count));
-
foreach ($response as $message_data) {
// @todo Better input validation
if (empty($message_data->key) || empty($message_data->translation) ||
diff --git a/modules/gallery/helpers/locale.php b/modules/gallery/helpers/locales.php
index 41b78834..3762b97b 100644
--- a/modules/gallery/helpers/locale.php
+++ b/modules/gallery/helpers/locales.php
@@ -21,7 +21,7 @@
/**
* This is the API for handling locales.
*/
-class locale_Core {
+class locales_Core {
private static $locales;
/**
diff --git a/modules/gallery/helpers/model_cache.php b/modules/gallery/helpers/model_cache.php
index 2649fdbd..a3e09862 100644
--- a/modules/gallery/helpers/model_cache.php
+++ b/modules/gallery/helpers/model_cache.php
@@ -32,10 +32,8 @@ class model_cache_Core {
return self::$cache->$model_name->$field_name->$id;
}
- static function clear($model_name, $id, $field_name="id") {
- if (!empty(self::$cache->$model_name->$field_name->$id)) {
- unset(self::$cache->$model_name->$field_name->$id);
- }
+ static function clear() {
+ self::$cache = new stdClass();
}
static function set($model) {
diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php
index 0d483206..03d538a9 100644
--- a/modules/gallery/helpers/module.php
+++ b/modules/gallery/helpers/module.php
@@ -274,11 +274,9 @@ class module_Core {
array_shift($args);
$function = str_replace(".", "_", $name);
- foreach (self::$modules as $module) {
- if (!$module->active) {
- continue;
- }
-
+ // @todo: consider calling gallery_event first, since for things menus we need it to do some
+ // setup
+ foreach (self::$active as $module) {
$class = "{$module->name}_event";
if (method_exists($class, $function)) {
call_user_func_array(array($class, $function), $args);
diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php
index fcf1cc54..4f4169d5 100644
--- a/modules/gallery/helpers/movie.php
+++ b/modules/gallery/helpers/movie.php
@@ -82,7 +82,7 @@ class movie_Core {
$movie->rand_key = ((float)mt_rand()) / (float)mt_getrandmax();
// Randomize the name if there's a conflict
- while (ORM::Factory("item")
+ while (ORM::factory("item")
->where("parent_id", $parent->id)
->where("name", $movie->name)
->find()->id) {
@@ -102,6 +102,8 @@ class movie_Core {
copy($filename, $movie->file_path());
+ // @todo: publish this from inside Item_Model::save() when we refactor to the point where
+ // there's only one save() happening here.
module::event("item_created", $movie);
// Build our thumbnail
@@ -145,7 +147,7 @@ class movie_Core {
static function find_ffmpeg() {
if (!$ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) {
- putenv("PATH=" . getenv("PATH") . ":/usr/local/bin:/opt/local/bin");
+ putenv("PATH=" . getenv("PATH") . ":/usr/local/bin:/opt/local/bin:/opt/bin");
if (function_exists("exec")) {
$ffmpeg_path = exec("which ffmpeg");
}
diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php
index a4bc853b..5cf37de1 100644
--- a/modules/gallery/helpers/photo.php
+++ b/modules/gallery/helpers/photo.php
@@ -81,7 +81,7 @@ class photo_Core {
$photo->rand_key = ((float)mt_rand()) / (float)mt_getrandmax();
// Randomize the name if there's a conflict
- while (ORM::Factory("item")
+ while (ORM::factory("item")
->where("parent_id", $parent->id)
->where("name", $photo->name)
->find()->id) {
@@ -105,6 +105,8 @@ class photo_Core {
copy($filename, $photo->file_path());
+ // @todo: publish this from inside Item_Model::save() when we refactor to the point where
+ // there's only one save() happening here.
module::event("item_created", $photo);
// Build our thumbnail/resizes
@@ -135,7 +137,7 @@ class photo_Core {
static function get_edit_form($photo) {
$form = new Forge("photos/$photo->id", "", "post", array("id" => "gEditPhotoForm"));
$form->hidden("_method")->value("put");
- $group = $form->group("edit_photo")->label(t("Edit Photo"));
+ $group = $form->group("edit_item")->label(t("Edit Photo"));
$group->input("title")->label(t("Title"))->value($photo->title);
$group->textarea("description")->label(t("Description"))->value($photo->description);
$group->input("filename")->label(t("Filename"))->value($photo->name)
@@ -145,6 +147,8 @@ class photo_Core {
->callback("item::validate_no_trailing_period")
->error_messages("no_trailing_period", t("The photo name can't end in \".\""));
+ module::event("item_edit_form", $photo, $form);
+
$group->submit("")->value(t("Modify"));
$form->add_rules_from(ORM::factory("item"));
return $form;
diff --git a/modules/gallery/helpers/task.php b/modules/gallery/helpers/task.php
index 6a9f63c2..9fa04305 100644
--- a/modules/gallery/helpers/task.php
+++ b/modules/gallery/helpers/task.php
@@ -84,10 +84,11 @@ class task_Core {
}
$task->save();
} catch (Exception $e) {
+ Kohana::log("error", $e->__toString());
$task->log($e->__toString());
$task->state = "error";
$task->done = true;
- $task->status = $e->getMessage();
+ $task->status = substr($e->getMessage(), 0, 255);
$task->save();
}
diff --git a/modules/gallery/js/quick.js b/modules/gallery/js/quick.js
deleted file mode 100644
index 4ebdac47..00000000
--- a/modules/gallery/js/quick.js
+++ /dev/null
@@ -1,90 +0,0 @@
-$(document).ready(function() {
- if ($("#gAlbumGrid").length) {
- // @todo Add quick edit pane for album (meta, move, permissions, delete)
- $(".gItem").hover(show_quick, function() {});
- }
- if ($("#gPhoto").length) {
- $("#gPhoto").hover(show_quick, function() {});
- }
-});
-
-var show_quick = function() {
- var cont = $(this);
- var quick = $(this).find(".gQuick");
- $("#gQuickPane").remove();
- cont.append("<div id=\"gQuickPane\"></div>");
- var img = cont.find(".gThumbnail,.gResize");
- var pos = cont.position();
- $("#gQuickPane").css({
- "position": "absolute",
- "top": pos.top,
- "left": pos.left,
- "text-align": "center",
- "width": cont.innerWidth() + 1,
- "height": "auto"
- }).hide();
- cont.hover(function() {}, hide_quick);
- $.get(
- quick.attr("href"),
- {},
- function(data, textStatus) {
- $("#gQuickPane").html(data).slideDown("fast");
- $(".ui-state-default").hover(
- function(){
- $(this).addClass("ui-state-hover");
- },
- function(){
- $(this).removeClass("ui-state-hover");
- }
- );
- $("#gQuickPane a:not(.options)").click(function(e) {
- e.preventDefault();
- quick_do(cont, $(this), img);
- });
- $("#gQuickPane a.options").click(function(e) {
- e.preventDefault();
- $("#gQuickPaneOptions").slideToggle("fast");
- });
- }
- );
-};
-
-var quick_do = function(cont, pane, img) {
- if (pane.hasClass("ui-state-disabled")) {
- return false;
- }
- if (pane.hasClass("gDialogLink")) {
- openDialog(pane, function() { window.location.reload(); });
- } else {
- img.css("opacity", "0.1");
- cont.addClass("gLoadingLarge");
- $.ajax({
- type: "GET",
- url: pane.attr("href"),
- dataType: "json",
- success: function(data) {
- img.css("opacity", "1");
- cont.removeClass("gLoadingLarge");
- if (data.src) {
- img.attr("width", data.width);
- img.attr("height", data.height);
- img.attr("src", data.src);
- if (data.height > data.width) {
- img.css("margin-top", -32);
- } else {
- img.css("margin-top", 0);
- }
- } else if (data.location) {
- window.location = data.location;
- } else if (data.reload) {
- window.location.reload();
- }
- }
- });
- }
- return false;
-};
-
-var hide_quick = function() {
- $("#gQuickPane").remove();
-};
diff --git a/modules/gallery/lib/HTMLPurifier/HTMLPurifier.includes.php b/modules/gallery/lib/HTMLPurifier/HTMLPurifier.includes.php
index 6ea32f72..e57f2ab3 100644
--- a/modules/gallery/lib/HTMLPurifier/HTMLPurifier.includes.php
+++ b/modules/gallery/lib/HTMLPurifier/HTMLPurifier.includes.php
@@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
- * @version 3.3.0
+ * @version 4.0.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
diff --git a/modules/gallery/lib/HTMLPurifier/HTMLPurifier.php b/modules/gallery/lib/HTMLPurifier/HTMLPurifier.php
index 0b53d1b4..71e90632 100644
--- a/modules/gallery/lib/HTMLPurifier/HTMLPurifier.php
+++ b/modules/gallery/lib/HTMLPurifier/HTMLPurifier.php
@@ -19,7 +19,7 @@
*/
/*
- HTML Purifier 3.3.0 - Standards Compliant HTML Filtering
+ HTML Purifier 4.0.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@@ -55,10 +55,10 @@ class HTMLPurifier
{
/** Version of HTML Purifier */
- public $version = '3.3.0';
+ public $version = '4.0.0';
/** Constant with version of HTML Purifier */
- const VERSION = '3.3.0';
+ const VERSION = '4.0.0';
/** Global configuration object */
public $config;
diff --git a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Config.php b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Config.php
index 5b2592b5..28529e7f 100644
--- a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Config.php
+++ b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Config.php
@@ -20,7 +20,7 @@ class HTMLPurifier_Config
/**
* HTML Purifier's version
*/
- public $version = '3.3.0';
+ public $version = '4.0.0';
/**
* Bool indicator whether or not to automatically finalize
diff --git a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer.php b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer.php
index 3d8010f4..9f20a412 100644
--- a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer.php
+++ b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer.php
@@ -285,7 +285,7 @@ class HTMLPurifier_Lexer
*/
public function extractBody($html) {
$matches = array();
- $result = preg_match('!<body[^>]*>(.+?)</body>!is', $html, $matches);
+ $result = preg_match('!<body[^>]*>(.*)</body>!is', $html, $matches);
if ($result) {
return $matches[1];
} else {
diff --git a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php
index 731c3171..0d20c0ce 100644
--- a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php
+++ b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php
@@ -3903,4 +3903,4 @@ class HTML5TreeConstructer {
return $this->dom;
}
}
-?>
+
diff --git a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php
index 19676e51..16969bed 100644
--- a/modules/gallery/lib/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php
+++ b/modules/gallery/lib/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php
@@ -23,6 +23,10 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter
if (is_null($uri->host) || empty($scheme_obj->browsable)) {
return true;
}
+ // don't redirect if target host is our host
+ if ($uri->host === $config->getDefinition('URI')->host) {
+ return true;
+ }
$this->makeReplace($uri, $config, $context);
$this->replace = array_map('rawurlencode', $this->replace);
diff --git a/modules/gallery/libraries/Admin_View.php b/modules/gallery/libraries/Admin_View.php
index 47770a90..21b70df6 100644
--- a/modules/gallery/libraries/Admin_View.php
+++ b/modules/gallery/libraries/Admin_View.php
@@ -46,20 +46,10 @@ class Admin_View_Core extends Gallery_View {
public function admin_menu() {
$menu = Menu::factory("root");
- gallery_menu::admin($menu, $this);
-
- foreach (module::active() as $module) {
- if ($module->name == "gallery") {
- continue;
- }
- $class = "{$module->name}_menu";
- if (method_exists($class, "admin")) {
- call_user_func_array(array($class, "admin"), array(&$menu, $this));
- }
- }
-
+ gallery::admin_menu($menu, $this);
+ module::event("admin_menu", $menu, $this);
$menu->compact();
- print $menu;
+ return $menu;
}
/**
@@ -88,6 +78,7 @@ class Admin_View_Core extends Gallery_View {
case "admin_page_bottom":
case "admin_page_top":
case "admin_head":
+ case "body_attributes":
$blocks = array();
foreach (module::active() as $module) {
$helper_class = "{$module->name}_theme";
diff --git a/modules/gallery/libraries/Form_Script.php b/modules/gallery/libraries/Form_Script.php
new file mode 100644
index 00000000..e841408d
--- /dev/null
+++ b/modules/gallery/libraries/Form_Script.php
@@ -0,0 +1,66 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 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 Form_Script_Core extends Forge {
+ protected $data = array(
+ "name" => false,
+ "type" => "script",
+ "url" => "",
+ "text" => "");
+
+ public function __construct($name) {
+ // Set dummy data so we don"t get errors
+ $this->attr["action"] = "";
+ $this->attr["method"] = "post";
+ $this->data["name"] = $name;
+ }
+
+ public function __get($key) {
+ return isset($this->data[$key]) ? $this->data[$key] : null;
+ }
+
+ /**
+ * Sets url attribute
+ */
+ public function url($url) {
+ $this->data["url"] = $url;
+
+ return $this;
+ }
+
+ public function text($script_text) {
+ $this->data["text"] = $script_text;
+
+ return $this;
+ }
+
+ public function render() {
+ $script = array();
+ if (!empty($this->data["url"])) {
+ $script[] = html::script($this->data["url"]);
+ }
+
+ if (!empty($this->data["text"])) {
+ $script[] = "<script type=\"text/javascript\">\n{$this->data['text']}\n</script>\n";
+ }
+
+ return implode("\n", $script);
+ }
+
+} // End Form Script \ No newline at end of file
diff --git a/modules/gallery/libraries/Gallery_View.php b/modules/gallery/libraries/Gallery_View.php
index 8a0be7f2..219cc883 100644
--- a/modules/gallery/libraries/Gallery_View.php
+++ b/modules/gallery/libraries/Gallery_View.php
@@ -27,24 +27,20 @@ class Gallery_View_Core extends View {
* @param $file the relative path to a script from the gallery3 directory
*/
public function script($file) {
- $this->scripts[$file] = 1;
- }
-
- /**
- * Add a script to the combined scripts list.
- * @param $file the relative path to a script from the base of the active theme
- * @param
- */
- public function theme_script($file) {
- $file = "themes/{$this->theme_name}/$file";
- $this->scripts[$file] = 1;
+ $base_file = str_replace(".js", "", $file);
+ if (($path = Kohana::find_file("js", $base_file, false, "js")) ||
+ file_exists($path = DOCROOT . "lib/$file")) {
+ $this->scripts[$path] = 1;
+ } else {
+ Kohana::log("error", "Can't find script file: $file");
+ }
}
/**
* Provide a url to a resource within the current theme. This allows us to refer to theme
* resources without naming the theme itself which makes themes easier to copy.
*/
- public function theme_url($path, $absolute_url=false) {
+ public function url($path, $absolute_url=false) {
$arg = "themes/{$this->theme_name}/$path";
return $absolute_url ? url::abs_file($arg) : url::file($arg);
}
@@ -53,40 +49,34 @@ class Gallery_View_Core extends View {
* Add a css file to the combined css list.
* @param $file the relative path to a script from the gallery3 directory
*/
- public function css($file, $theme_relative=false) {
- $this->css[$file] = 1;
- }
-
- /**
- * Add a css file to the combined css list.
- * @param $file the relative path to a script from the base of the active theme
- * @param
- */
- public function theme_css($file) {
- $file = "themes/{$this->theme_name}/$file";
- $this->css[$file] = 1;
+ public function css($file) {
+ $base_file = str_replace(".css", "", $file);
+ if (($path = Kohana::find_file("css", $base_file, false, "css")) ||
+ file_exists($path = DOCROOT . "lib/$file")) {
+ $this->css[$path] = 1;
+ } else {
+ Kohana::log("error", "Can't find css file: $file");
+ }
}
/**
* Combine a series of files into a single one and cache it in the database.
*/
- protected function combine_files($files, $type) {
+ protected function combine_files($paths, $type) {
$links = array();
+ if (empty($paths)) {
+ return;
+ }
+
// Include the url in the cache key so that if the Gallery moves, we don't use old cached
// entries.
$key = array(url::abs_file(""));
- foreach (array_keys($files) as $file) {
- $path = DOCROOT . $file;
- if (file_exists($path)) {
- $stats = stat($path);
- $links[$file] = $path;
- // 7 == size, 9 == mtime, see http://php.net/stat
- $key[] = "$file $stats[7] $stats[9]";
- } else {
- Kohana::log("error", "missing file ($type): $file");
- }
+ foreach (array_keys($paths) as $path) {
+ $stats = stat($path);
+ // 7 == size, 9 == mtime, see http://php.net/stat
+ $key[] = "$path $stats[7] $stats[9]";
}
$key = md5(join(" ", $key));
@@ -95,16 +85,21 @@ class Gallery_View_Core extends View {
if (empty($contents)) {
$contents = "";
- foreach ($links as $file => $link) {
+ $docroot_len = strlen(DOCROOT);
+ foreach (array_keys($paths) as $path) {
+ $relative = substr($path, $docroot_len);
if ($type == "css") {
- $contents .= "/* $file */\n" . $this->process_css($link) . "\n";
+ $contents .= "/* $relative */\n" . $this->process_css($path) . "\n";
} else {
- $contents .= "/* $file */\n" . file_get_contents($link) . "\n";
+ $contents .= "/* $relative */\n" . file_get_contents($path) . "\n";
}
}
$cache->set($key, $contents, array($type), 30 * 84600);
- if (function_exists("gzencode")) {
+
+ $use_gzip = function_exists("gzencode") &&
+ (int) ini_get("zlib.output_compression") === 0;
+ if ($use_gzip) {
$cache->set("{$key}_gz", gzencode($contents, 9, FORCE_GZIP),
array($type, "gzip"), 30 * 84600);
}
@@ -140,6 +135,7 @@ class Gallery_View_Core extends View {
Kohana::log("error", "Missing URL reference '{$match[1]}' in CSS file '$css_file'");
}
}
+ $replace = str_replace(DIRECTORY_SEPARATOR, "/", $replace);
$css = str_replace($search, $replace, $css);
}
$imports = preg_match_all("#@import\s*['|\"]{0,1}(.*?)['|\"]{0,1};#",
diff --git a/modules/gallery/libraries/HtmlPurifier.php b/modules/gallery/libraries/HtmlPurifier.php
index f9d5353b..daa5896e 100644
--- a/modules/gallery/libraries/HtmlPurifier.php
+++ b/modules/gallery/libraries/HtmlPurifier.php
@@ -20,11 +20,6 @@
class HtmlPurifier_Core {
private static $_instance;
- public function __construct($name = NULL, $data = NULL, $type = NULL) {
- parent::__construct($name, $data, $type);
- $this->set_global("csrf", access::csrf_token());
- }
-
static function instance($config=null) {
require_once(dirname(__file__) . "/HTMLPurifier/HTMLPurifier.auto.php");
if (self::$_instance == NULL) {
diff --git a/modules/gallery/libraries/I18n.php b/modules/gallery/libraries/I18n.php
index 03a6d8f6..d0531b9a 100644
--- a/modules/gallery/libraries/I18n.php
+++ b/modules/gallery/libraries/I18n.php
@@ -77,7 +77,12 @@ class I18n_Core {
// TODO: See G2 for better fallack code.
$locale_prefs = array($locale);
$locale_prefs[] = 'en_US';
- setlocale(LC_ALL, $locale_prefs);
+ $new_locale = setlocale(LC_ALL, $locale_prefs);
+ if (is_string($new_locale) && strpos($new_locale, 'tr') === 0) {
+ // Make PHP 5 work with Turkish (the localization results are mixed though).
+ // Hack for http://bugs.php.net/18556
+ setlocale(LC_CTYPE, 'C');
+ }
}
return $this->_config['default_locale'];
}
@@ -178,7 +183,7 @@ class I18n_Core {
static function is_plural_message($message) {
return is_array($message);
}
-
+
private function interpolate($locale, $string, $values) {
// TODO: Handle locale specific number formatting.
diff --git a/modules/gallery/libraries/MY_ORM.php b/modules/gallery/libraries/MY_ORM.php
index 2bd9b4eb..de8adc1d 100644
--- a/modules/gallery/libraries/MY_ORM.php
+++ b/modules/gallery/libraries/MY_ORM.php
@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class ORM extends ORM_Core {
+ // Track the original value of this ORM so that we can look it up in ORM::original()
+ protected $original = null;
+
public function open_paren() {
$this->db->open_paren();
return $this;
@@ -29,8 +32,30 @@ class ORM extends ORM_Core {
}
public function save() {
- model_cache::clear($this->object_name, $this->{$this->primary_key}, $this->primary_key);
- return parent::save();
+ model_cache::clear();
+ $result = parent::save();
+ $this->original = clone $this;
+ return $result;
+ }
+
+ public function __set($column, $value) {
+ if (!isset($this->original)) {
+ $this->original = clone $this;
+ }
+
+ return parent::__set($column, $value);
+ }
+
+ public function __unset($column) {
+ if (!isset($this->original)) {
+ $this->original = clone $this;
+ }
+
+ return parent::__unset($column);
+ }
+
+ public function original() {
+ return $this->original;
}
}
diff --git a/modules/gallery/libraries/MY_View.php b/modules/gallery/libraries/MY_View.php
index 96dcc71b..eb55aca6 100644
--- a/modules/gallery/libraries/MY_View.php
+++ b/modules/gallery/libraries/MY_View.php
@@ -38,16 +38,8 @@ class View extends View_Core {
try {
return parent::render($print, $renderer);
} catch (Exception $e) {
- Kohana::Log('error', $e->getTraceAsString());
- Kohana::Log('debug', $e->getMessage());
+ Kohana::Log("error", $e->getMessage() . "\n" . $e->getTraceAsString());
return "";
}
}
-
- public function body_attributes() {
- if (locale::is_rtl()) {
- return 'class="rtl"';
- }
- return '';
- }
}
diff --git a/modules/gallery/libraries/Menu.php b/modules/gallery/libraries/Menu.php
index 6d0881ce..07b2b2b8 100644
--- a/modules/gallery/libraries/Menu.php
+++ b/modules/gallery/libraries/Menu.php
@@ -91,12 +91,43 @@ class Menu_Element_Link extends Menu_Element {
} else {
$css_class = "";
}
- return "<li><a$css_id class=\"gMenuElement$css_class\" href=\"$this->url\" " .
+ return "<li><a$css_id class=\"gMenuLink $css_class\" href=\"$this->url\" " .
"title=\"$this->label\">$this->label</a></li>";
}
}
/**
+ * Menu element that provides an AJAX link.
+ */
+class Menu_Element_Ajax_Link extends Menu_Element {
+ public $ajax_handler;
+
+ /**
+ * Set the AJAX handler
+ * @chainable
+ */
+ public function ajax_handler($ajax_handler) {
+ $this->ajax_handler = $ajax_handler;
+ return $this;
+ }
+
+ public function __toString() {
+ if (isset($this->css_id) && !empty($this->css_id)) {
+ $css_id = " id=\"$this->css_id\"";
+ } else {
+ $css_id = "";
+ }
+ if (isset($this->css_class) && !empty($this->css_class)) {
+ $css_class = " $this->css_class";
+ } else {
+ $css_class = "";
+ }
+ return "<li><a$css_id class=\"gAjaxLink $css_class\" href=\"$this->url\" " .
+ "title=\"$this->label\" ajax_handler=\"$this->ajax_handler\">$this->label</a></li>";
+ }
+}
+
+/**
* Menu element that provides a pop-up dialog
*/
class Menu_Element_Dialog extends Menu_Element {
@@ -111,7 +142,7 @@ class Menu_Element_Dialog extends Menu_Element {
} else {
$css_class = "";
}
- return "<li><a$css_id class=\"gMenuLink$css_class\" href=\"$this->url\" " .
+ return "<li><a$css_id class=\"gDialogLink $css_class\" href=\"$this->url\" " .
"title=\"$this->label\">$this->label</a></li>";
}
}
@@ -132,11 +163,16 @@ class Menu_Core extends Menu_Element {
case "link":
return new Menu_Element_Link($type);
+ case "ajax_link":
+ return new Menu_Element_Ajax_Link($type);
+
case "dialog":
return new Menu_Element_Dialog($type);
case "root":
- return new Menu("root");
+ $menu = new Menu("root");
+ $menu->css_class("gMenu");
+ return $menu;
case "submenu":
return new Menu("submenu");
@@ -156,6 +192,7 @@ class Menu_Core extends Menu_Element {
}
}
}
+ return $this;
}
public function __construct($type) {
@@ -206,8 +243,8 @@ class Menu_Core extends Menu_Element {
}
public function __toString() {
- $html = $this->is_root ? "<ul class=\"gMenu\">" :
- "<li><a href=#>$this->label</a><ul class=\"gMenu\">";
+ $html = $this->is_root ? "<ul class=\"$this->css_class\">" :
+ "<li title=\"$this->label\"><a href=\"#\">$this->label</a><ul>";
$html .= implode("\n", $this->elements);
$html .= $this->is_root ? "</ul>" : "</ul></li>";
return $html;
diff --git a/modules/gallery/libraries/ORM_MPTT.php b/modules/gallery/libraries/ORM_MPTT.php
index 46280d95..a7defba9 100644
--- a/modules/gallery/libraries/ORM_MPTT.php
+++ b/modules/gallery/libraries/ORM_MPTT.php
@@ -52,14 +52,14 @@ class ORM_MPTT_Core extends ORM {
try {
// Make a hole in the parent for this new item
$this->db->query(
- "UPDATE {{$this->table_name}} SET `left` = `left` + 2 WHERE `left` >= {$parent->right}");
+ "UPDATE {{$this->table_name}} SET `left_ptr` = `left_ptr` + 2 WHERE `left_ptr` >= {$parent->right_ptr}");
$this->db->query(
- "UPDATE {{$this->table_name}} SET `right` = `right` + 2 WHERE `right` >= {$parent->right}");
- $parent->right += 2;
+ "UPDATE {{$this->table_name}} SET `right_ptr` = `right_ptr` + 2 WHERE `right_ptr` >= {$parent->right_ptr}");
+ $parent->right_ptr += 2;
// Insert this item into the hole
- $this->left = $parent->right - 2;
- $this->right = $parent->right - 1;
+ $this->left_ptr = $parent->right_ptr - 2;
+ $this->right_ptr = $parent->right_ptr - 1;
$this->parent_id = $parent->id;
$this->level = $parent->level + 1;
$this->save();
@@ -81,7 +81,7 @@ class ORM_MPTT_Core extends ORM {
if ($children) {
foreach ($this->children() as $item) {
// Deleting children affects the MPTT tree, so we have to reload each child before we
- // delete it so that we have current left/right pointers. This is inefficient.
+ // delete it so that we have current left_ptr/right_ptr pointers. This is inefficient.
// @todo load each child once, not twice.
$item->reload()->delete();
}
@@ -93,9 +93,9 @@ class ORM_MPTT_Core extends ORM {
$this->lock();
try {
$this->db->query(
- "UPDATE {{$this->table_name}} SET `left` = `left` - 2 WHERE `left` > {$this->right}");
+ "UPDATE {{$this->table_name}} SET `left_ptr` = `left_ptr` - 2 WHERE `left_ptr` > {$this->right_ptr}");
$this->db->query(
- "UPDATE {{$this->table_name}} SET `right` = `right` - 2 WHERE `right` > {$this->right}");
+ "UPDATE {{$this->table_name}} SET `right_ptr` = `right_ptr` - 2 WHERE `right_ptr` > {$this->right_ptr}");
} catch (Exception $e) {
$this->unlock();
throw $e;
@@ -111,7 +111,7 @@ class ORM_MPTT_Core extends ORM {
* @return boolean
*/
function is_descendant($target) {
- return ($this->left <= $target->left && $this->right >= $target->right);
+ return ($this->left_ptr <= $target->left_ptr && $this->right_ptr >= $target->right_ptr);
}
/**
@@ -133,10 +133,10 @@ class ORM_MPTT_Core extends ORM {
*/
function parents() {
return $this
- ->where("`left` <= {$this->left}")
- ->where("`right` >= {$this->right}")
+ ->where("`left_ptr` <= {$this->left_ptr}")
+ ->where("`right_ptr` >= {$this->right_ptr}")
->where("id <> {$this->id}")
- ->orderby("left", "ASC")
+ ->orderby("left_ptr", "ASC")
->find_all();
}
@@ -146,69 +146,62 @@ class ORM_MPTT_Core extends ORM {
* @chainable
* @param integer SQL limit
* @param integer SQL offset
+ * @param array additional where clauses
* @param array orderby
* @return array ORM
*/
- function children($limit=null, $offset=0, $orderby=null) {
- $this->where("parent_id", $this->id);
- if (empty($orderby)) {
- $this->orderby("id", "ASC");
- } else {
- $this->orderby($orderby);
- }
- return $this->find_all($limit, $offset);
+ function children($limit=null, $offset=0, $where=array(), $orderby=array("id" => "ASC")) {
+ return $this
+ ->where("parent_id", $this->id)
+ ->where($where)
+ ->orderby($orderby)
+ ->find_all($limit, $offset);
}
/**
* Return all of the children of this node, ordered by id.
*
* @chainable
- * @param integer SQL limit
- * @param integer SQL offset
+ * @param array additional where clauses
* @return array ORM
*/
- function children_count() {
- return $this->where("parent_id", $this->id)->count_all();
+ function children_count($where=array()) {
+ return $this
+ ->where($where)
+ ->where("parent_id", $this->id)
+ ->count_all();
}
/**
- * Return all of the children of the specified type, ordered by id.
+ * Return all of the decendents of the specified type, ordered by id.
*
* @param integer SQL limit
* @param integer SQL offset
- * @param string type to return
+ * @param array additional where clauses
* @param array orderby
* @return object ORM_Iterator
*/
- function descendants($limit=null, $offset=0, $type=null, $orderby=null) {
- $this->where("left >", $this->left)
- ->where("right <=", $this->right);
- if ($type) {
- $this->where("type", $type);
- }
-
- if (empty($orderby)) {
- $this->orderby("id", "ASC");
- } else {
- $this->orderby($orderby);
- }
-
- return $this->find_all($limit, $offset);
+ function descendants($limit=null, $offset=0, $where=array(), $orderby=array("id" => "ASC")) {
+ return $this
+ ->where("left_ptr >", $this->left_ptr)
+ ->where("right_ptr <=", $this->right_ptr)
+ ->where($where)
+ ->orderby($orderby)
+ ->find_all($limit, $offset);
}
/**
* Return the count of all the children of the specified type.
*
- * @param string type to count
+ * @param array additional where clauses
* @return integer child count
*/
- function descendants_count($type=null) {
- $this->where("left >", $this->left)
- ->where("right <=", $this->right);
- if ($type) {
- $this->where("type", $type);
- }
- return $this->count_all();
+ function descendants_count($where=array()) {
+ return $this
+ ->where("left_ptr >", $this->left_ptr)
+ ->where("right_ptr <=", $this->right_ptr)
+ ->where($where)
+ ->count_all();
}
/**
@@ -219,16 +212,16 @@ class ORM_MPTT_Core extends ORM {
* @return ORM_MTPP
*/
function move_to($target) {
- if ($this->left <= $target->left &&
- $this->right >= $target->right) {
+ if ($this->left_ptr <= $target->left_ptr &&
+ $this->right_ptr >= $target->right_ptr) {
throw new Exception("@todo INVALID_TARGET can't move item inside itself");
}
- $number_to_move = (int)(($this->right - $this->left) / 2 + 1);
+ $number_to_move = (int)(($this->right_ptr - $this->left_ptr) / 2 + 1);
$size_of_hole = $number_to_move * 2;
- $original_left = $this->left;
- $original_right = $this->right;
- $target_right = $target->right;
+ $original_left_ptr = $this->left_ptr;
+ $original_right_ptr = $this->right_ptr;
+ $target_right_ptr = $target->right_ptr;
$level_delta = ($target->level + 1) - $this->level;
$this->lock();
@@ -237,45 +230,45 @@ class ORM_MPTT_Core extends ORM {
// Update the levels for the to-be-moved items
$this->db->query(
"UPDATE {{$this->table_name}} SET `level` = `level` + $level_delta" .
- " WHERE `left` >= $original_left AND `right` <= $original_right");
+ " WHERE `left_ptr` >= $original_left_ptr AND `right_ptr` <= $original_right_ptr");
}
// Make a hole in the target for the move
$target->db->query(
- "UPDATE {{$this->table_name}} SET `left` = `left` + $size_of_hole" .
- " WHERE `left` >= $target_right");
+ "UPDATE {{$this->table_name}} SET `left_ptr` = `left_ptr` + $size_of_hole" .
+ " WHERE `left_ptr` >= $target_right_ptr");
$target->db->query(
- "UPDATE {{$this->table_name}} SET `right` = `right` + $size_of_hole" .
- " WHERE `right` >= $target_right");
+ "UPDATE {{$this->table_name}} SET `right_ptr` = `right_ptr` + $size_of_hole" .
+ " WHERE `right_ptr` >= $target_right_ptr");
// Change the parent.
$this->db->query(
"UPDATE {{$this->table_name}} SET `parent_id` = {$target->id}" .
" WHERE `id` = {$this->id}");
- // If the source is to the right of the target then we just adjusted its left and right above.
- $left = $original_left;
- $right = $original_right;
- if ($original_left > $target_right) {
- $left += $size_of_hole;
- $right += $size_of_hole;
+ // If the source is to the right of the target then we just adjusted its left_ptr and right_ptr above.
+ $left_ptr = $original_left_ptr;
+ $right_ptr = $original_right_ptr;
+ if ($original_left_ptr > $target_right_ptr) {
+ $left_ptr += $size_of_hole;
+ $right_ptr += $size_of_hole;
}
- $new_offset = $target->right - $left;
+ $new_offset = $target->right_ptr - $left_ptr;
$this->db->query(
"UPDATE {{$this->table_name}}" .
- " SET `left` = `left` + $new_offset," .
- " `right` = `right` + $new_offset" .
- " WHERE `left` >= $left" .
- " AND `right` <= $right");
+ " SET `left_ptr` = `left_ptr` + $new_offset," .
+ " `right_ptr` = `right_ptr` + $new_offset" .
+ " WHERE `left_ptr` >= $left_ptr" .
+ " AND `right_ptr` <= $right_ptr");
// Close the hole in the source's parent after the move
$this->db->query(
- "UPDATE {{$this->table_name}} SET `left` = `left` - $size_of_hole" .
- " WHERE `left` > $right");
+ "UPDATE {{$this->table_name}} SET `left_ptr` = `left_ptr` - $size_of_hole" .
+ " WHERE `left_ptr` > $right_ptr");
$this->db->query(
- "UPDATE {{$this->table_name}} SET `right` = `right` - $size_of_hole" .
- " WHERE `right` > $right");
+ "UPDATE {{$this->table_name}} SET `right_ptr` = `right_ptr` - $size_of_hole" .
+ " WHERE `right_ptr` > $right_ptr");
} catch (Exception $e) {
$this->unlock();
throw $e;
@@ -285,6 +278,7 @@ class ORM_MPTT_Core extends ORM {
// Lets reload to get the changes.
$this->reload();
+ $target->reload();
return $this;
}
diff --git a/modules/gallery/libraries/Theme_View.php b/modules/gallery/libraries/Theme_View.php
index 898574d7..541bce88 100644
--- a/modules/gallery/libraries/Theme_View.php
+++ b/modules/gallery/libraries/Theme_View.php
@@ -80,54 +80,47 @@ class Theme_View_Core extends Gallery_View {
public function site_menu() {
$menu = Menu::factory("root");
- if ($this->page_type != "login") {
- gallery_menu::site($menu, $this);
-
- foreach (module::active() as $module) {
- if ($module->name == "gallery") {
- continue;
- }
- $class = "{$module->name}_menu";
- if (method_exists($class, "site")) {
- call_user_func_array(array($class, "site"), array(&$menu, $this));
- }
- }
- }
-
- $menu->compact();
- print $menu;
+ gallery::site_menu($menu, $this);
+ module::event("site_menu", $menu, $this);
+ return $menu->compact();
}
public function album_menu() {
- $this->_menu("album");
+ $menu = Menu::factory("root");
+ module::event("album_menu", $menu, $this);
+ return $menu->compact();
}
public function tag_menu() {
- $this->_menu("tag");
+ $menu = Menu::factory("root");
+ module::event("tag_menu", $menu, $this);
+ return $menu->compact();
}
public function photo_menu() {
- $this->_menu("photo");
- }
+ $menu = Menu::factory("root");
+ if (access::can("view_full", $this->item())) {
+ $menu->append(Menu::factory("link")
+ ->id("fullsize")
+ ->label(t("View full size"))
+ ->url($this->item()->file_url())
+ ->css_class("gFullSizeLink"));
+ }
- public function thumb_menu($item) {
- $this->_menu("thumb", $item);
+ module::event("photo_menu", $menu, $this);
+ return $menu->compact();
}
- private function _menu($type, $item=null) {
- $menu = Menu::factory("root");
- call_user_func_array(array("gallery_menu", $type), array(&$menu, $this, $item));
- foreach (module::active() as $module) {
- if ($module->name == "gallery") {
- continue;
- }
- $class = "{$module->name}_menu";
- if (method_exists($class, $type)) {
- call_user_func_array(array($class, $type), array(&$menu, $this, $item));
- }
- }
+ public function context_menu($item, $thumbnail_css_selector) {
+ $menu = Menu::factory("root")
+ ->append(Menu::factory("submenu")
+ ->id("context_menu")
+ ->label(t("Options")))
+ ->css_class("gContextMenu");
- print $menu;
+ gallery::context_menu($menu, $this, $item, $thumbnail_css_selector);
+ module::event("context_menu", $menu, $this, $item, $thumbnail_css_selector);
+ return $menu->compact();
}
public function pager() {
@@ -164,6 +157,7 @@ class Theme_View_Core extends Gallery_View {
case "album_blocks":
case "album_bottom":
case "album_top":
+ case "body_attributes":
case "credits";
case "dynamic_bottom":
case "dynamic_top":
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index 51037073..7a3a2ba7 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -93,6 +93,7 @@ class Item_Model extends ORM_MPTT {
}
public function delete() {
+ $old = clone $this;
module::event("item_before_delete", $this);
$parent = $this->parent();
@@ -114,13 +115,15 @@ class Item_Model extends ORM_MPTT {
@unlink($resize_path);
@unlink($thumb_path);
}
+
+ module::event("item_deleted", $old);
}
/**
* Move this item to the specified target.
* @chainable
- * @param Item_Model $target Target item (must be an album
- * @return ORM_MTPP
+ * @param Item_Model $target Target item (must be an album)
+ * @return ORM_MPTT
*/
function move_to($target) {
if (!$target->is_album()) {
@@ -134,8 +137,10 @@ class Item_Model extends ORM_MPTT {
$original_path = $this->file_path();
$original_resize_path = $this->resize_path();
$original_thumb_path = $this->thumb_path();
+ $original_parent = $this->parent();
parent::move_to($target, true);
+ model_cache::clear();
$this->relative_path_cache = null;
rename($original_path, $this->file_path());
@@ -145,12 +150,13 @@ class Item_Model extends ORM_MPTT {
Database::instance()
->update("items",
array("relative_path_cache" => null),
- array("left >" => $this->left, "right <" => $this->right));
+ array("left_ptr >" => $this->left_ptr, "right_ptr <" => $this->right_ptr));
} else {
@rename($original_resize_path, $this->resize_path());
@rename($original_thumb_path, $this->thumb_path());
}
+ module::event("item_moved", $this, $original_parent);
return $this;
}
@@ -180,7 +186,7 @@ class Item_Model extends ORM_MPTT {
Database::instance()
->update("items",
array("relative_path_cache" => null),
- array("left >" => $this->left, "right <" => $this->right));
+ array("left_ptr >" => $this->left_ptr, "right_ptr <" => $this->right_ptr));
}
return $this;
@@ -296,10 +302,10 @@ class Item_Model extends ORM_MPTT {
foreach (Database::instance()
->select("name")
->from("items")
- ->where("left <=", $this->left)
- ->where("right >=", $this->right)
+ ->where("left_ptr <=", $this->left_ptr)
+ ->where("right_ptr >=", $this->right_ptr)
->where("id <>", 1)
- ->orderby("left", "ASC")
+ ->orderby("left_ptr", "ASC")
->get() as $row) {
$paths[] = $row->name;
}
@@ -345,11 +351,16 @@ class Item_Model extends ORM_MPTT {
$this->updated = time();
if (!$this->loaded) {
$this->created = $this->updated;
- $r = ORM::factory("item")->select("MAX(weight) as max_weight")->find();
- $this->weight = $r->max_weight + 1;
+ $this->weight = item::get_max_weight();
+ } else {
+ $send_event = 1;
}
}
- return parent::save();
+ parent::save();
+ if (isset($send_event)) {
+ module::event("item_updated", $this->original(), $this);
+ }
+ return $this;
}
/**
@@ -387,10 +398,10 @@ class Item_Model extends ORM_MPTT {
$db = Database::instance();
$position = $db->query("
SELECT COUNT(*) AS position FROM {items}
- WHERE parent_id = {$this->id}
+ WHERE `parent_id` = {$this->id}
AND `{$this->sort_column}` $comp (SELECT `{$this->sort_column}`
- FROM {items} WHERE id = $child_id)
- ORDER BY `{$this->sort_column}` {$this->sort_order}")->current()->position;
+ FROM {items} WHERE `id` = $child_id)")
+ ->current()->position;
// We stopped short of our target value in the sort (notice that we're using a < comparator
// above) because it's possible that we have duplicate values in the sort column. An
@@ -402,9 +413,10 @@ class Item_Model extends ORM_MPTT {
// our base value.
$result = $db->query("
SELECT id FROM {items}
- WHERE parent_id = {$this->id}
+ WHERE `parent_id` = {$this->id}
AND `{$this->sort_column}` = (SELECT `{$this->sort_column}`
- FROM {items} WHERE id = $child_id)");
+ FROM {items} WHERE `id` = $child_id)
+ ORDER BY `id` ASC");
foreach ($result as $row) {
$position++;
if ($row->id == $child_id) {
@@ -502,26 +514,38 @@ class Item_Model extends ORM_MPTT {
}
/**
- * Return all of the children of this node, ordered by the defined sort order.
+ * Return all of the children of this album. Unless you specify a specific sort order, the
+ * results will be ordered by this album's sort order.
*
* @chainable
* @param integer SQL limit
* @param integer SQL offset
+ * @param array additional where clauses
+ * @param array orderby
* @return array ORM
*/
- function children($limit=null, $offset=0) {
- return parent::children($limit, $offset, array($this->sort_column => $this->sort_order));
+ function children($limit=null, $offset=0, $where=array(), $orderby=null) {
+ if (empty($orderby)) {
+ $orderby = array($this->sort_column => $this->sort_order);
+ }
+ return parent::children($limit, $offset, $where, $orderby);
}
/**
- * Return all of the children of the specified type, ordered by the defined sort order.
+ * Return the children of this album, and all of it's sub-albums. Unless you specify a specific
+ * sort order, the results will be ordered by this album's sort order. Note that this
+ * album's sort order is imposed on all sub-albums, regardless of their sort order.
+ *
+ * @chainable
* @param integer SQL limit
* @param integer SQL offset
- * @param string type to return
+ * @param array additional where clauses
* @return object ORM_Iterator
*/
- function descendants($limit=null, $offset=0, $type=null) {
- return parent::descendants($limit, $offset, $type,
- array($this->sort_column => $this->sort_order));
+ function descendants($limit=null, $offset=0, $where=array(), $orderby=null) {
+ if (empty($orderby)) {
+ $orderby = array($this->sort_column => $this->sort_order);
+ }
+ return parent::descendants($limit, $offset, $where, $orderby);
}
}
diff --git a/modules/gallery/module.info b/modules/gallery/module.info
index c184aba7..dfb1a7a2 100644
--- a/modules/gallery/module.info
+++ b/modules/gallery/module.info
@@ -1,3 +1,3 @@
-name = Gallery 3
-description = Gallery core application
-version = 6
+name = "Gallery 3"
+description = "Gallery core application"
+version = 10
diff --git a/modules/gallery/tests/Access_Helper_Test.php b/modules/gallery/tests/Access_Helper_Test.php
index d71bf971..59cec453 100644
--- a/modules/gallery/tests/Access_Helper_Test.php
+++ b/modules/gallery/tests/Access_Helper_Test.php
@@ -64,6 +64,43 @@ class Access_Helper_Test extends Unit_Test_Case {
$this->assert_false(array_key_exists("access_test_{$group->id}", $fields));
}
+ public function user_can_access_test() {
+ $access_test = group::create("access_test");
+
+ $root = ORM::factory("item", 1);
+ access::allow($access_test, "view", $root);
+
+ $item = album::create($root, rand(), "test album");
+
+ access::deny(group::everybody(), "view", $item);
+ access::deny(group::registered_users(), "view", $item);
+
+ $user = user::create("access_test", "Access Test", "");
+ foreach ($user->groups as $group) {
+ $user->remove($group);
+ }
+ $user->add($access_test);
+ $user->save();
+
+ $this->assert_true(access::user_can($user, "view", $item), "Should be able to view");
+ }
+
+ public function user_can_no_access_test() {
+ $root = ORM::factory("item", 1);
+ $item = album::create($root, rand(), "test album");
+
+ access::deny(group::everybody(), "view", $item);
+ access::deny(group::registered_users(), "view", $item);
+
+ $user = user::create("access_test", "Access Test", "");
+ foreach ($user->groups as $group) {
+ $user->remove($group);
+ }
+ $user->save();
+
+ $this->assert_false(access::user_can($user, "view", $item), "Should be unable to view");
+ }
+
public function adding_and_removing_items_adds_ands_removes_rows_test() {
$root = ORM::factory("item", 1);
$item = album::create($root, rand(), "test album");
@@ -324,4 +361,40 @@ class Access_Helper_Test extends Unit_Test_Case {
$this->assert_false(file_exists($album->resize_path() . "/.htaccess"));
$this->assert_false(file_exists($album->thumb_path() . "/.htaccess"));
}
+
+ public function moved_items_inherit_new_permissions_test() {
+ user::set_active(user::lookup_by_name("admin"));
+
+ $root = ORM::factory("item", 1);
+ $public_album = album::create($root, rand(), "public album");
+ $public_photo = photo::create($public_album, MODPATH . "gallery/images/gallery.png", "", "");
+ access::allow(group::everybody(), "view", $public_album);
+
+ $root->reload(); // Account for MPTT changes
+
+ $private_album = album::create($root, rand(), "private album");
+ access::deny(group::everybody(), "view", $private_album);
+ $private_photo = photo::create($private_album, MODPATH . "gallery/images/gallery.png", "", "");
+
+ // Make sure that we now have a public photo and private photo.
+ $this->assert_true(access::group_can(group::everybody(), "view", $public_photo));
+ $this->assert_false(access::group_can(group::everybody(), "view", $private_photo));
+
+ // Swap the photos
+ item::move($public_photo, $private_album);
+ $private_album->reload(); // Reload to get new MPTT pointers and cached perms.
+ $public_album->reload();
+ $private_photo->reload();
+ $public_photo->reload();
+
+ item::move($private_photo, $public_album);
+ $private_album->reload(); // Reload to get new MPTT pointers and cached perms.
+ $public_album->reload();
+ $private_photo->reload();
+ $public_photo->reload();
+
+ // Make sure that the public_photo is now private, and the private_photo is now public.
+ $this->assert_false(access::group_can(group::everybody(), "view", $public_photo));
+ $this->assert_true(access::group_can(group::everybody(), "view", $private_photo));
+ }
}
diff --git a/modules/gallery/tests/Database_Test.php b/modules/gallery/tests/Database_Test.php
index bd3d2f53..d83212ad 100644
--- a/modules/gallery/tests/Database_Test.php
+++ b/modules/gallery/tests/Database_Test.php
@@ -103,15 +103,15 @@ class Database_Test extends Unit_Test_Case {
$sql = "UPDATE {test_tables} SET `name` = '{test string}' " .
"WHERE `item_id` IN " .
" (SELECT `id` FROM {items} " .
- " WHERE `left` >= 1 " .
- " AND `right` <= 6)";
+ " WHERE `left_ptr` >= 1 " .
+ " AND `right_ptr` <= 6)";
$sql = $db->add_table_prefixes($sql);
$expected = "UPDATE g3test_test_tables SET `name` = '{test string}' " .
"WHERE `item_id` IN " .
" (SELECT `id` FROM g3test_items " .
- " WHERE `left` >= 1 " .
- " AND `right` <= 6)";
+ " WHERE `left_ptr` >= 1 " .
+ " AND `right_ptr` <= 6)";
$this->assert_same($expected, $sql);
}
diff --git a/modules/gallery/tests/DrawForm_Test.php b/modules/gallery/tests/DrawForm_Test.php
index 2c5aaba4..dde54257 100644
--- a/modules/gallery/tests/DrawForm_Test.php
+++ b/modules/gallery/tests/DrawForm_Test.php
@@ -80,5 +80,44 @@ class DrawForm_Test extends Unit_Test_Case {
$this->assert_same($expected, $rendered);
}
+ function form_script_test() {
+ $form = new Forge("test/controller", "", "post", array("id" => "gTestGroupForm"));
+ $group = $form->group("test_group")->label(t("Test Group"));
+ $group->input("title")->label(t("Title"));
+ $group->textarea("description")->label(t("Text Area"));
+ $form->script("")
+ ->url(url::file("test.js"))
+ ->text("alert('Test Javascript');");
+ $group->submit("")->value(t("Submit"));
+ $rendered = $form->__toString();
+
+ $expected = "<form action=\"http://./index.php/test/controller\" method=\"post\" " .
+ "id=\"gTestGroupForm\">\n" .
+ "<input type=\"hidden\" name=\"csrf\" value=\"" . access::csrf_token() . "\" />\n" .
+ " <fieldset>\n" .
+ " <legend>Test Group</legend>\n" .
+ " <ul>\n" .
+ " <li>\n" .
+ " <label for=\"title\" >Title</label>\n" .
+ " <input type=\"text\" id=\"title\" name=\"title\" value=\"\" " .
+ "class=\"textbox\" />\n" .
+ " </li>\n" .
+ " <li>\n" .
+ " <label for=\"description\" >Text Area</label>\n" .
+ " <textarea id=\"description\" name=\"description\" " .
+ "class=\"textarea\" ></textarea>\n" .
+ " </li>\n" .
+ " <li>\n" .
+ " <input type=\"submit\" value=\"Submit\" class=\"submit\" />\n" .
+ " </li>\n" .
+ " </ul>\n" .
+ " </fieldset>\n" .
+ "<script type=\"text/javascript\" src=\"http://./test.js\"></script>\n\n" .
+ "<script type=\"text/javascript\">\n" .
+ "alert('Test Javascript');\n" .
+ "</script>\n" .
+ "</form>\n";
+ $this->assert_same($expected, $rendered);
+ }
}
diff --git a/modules/gallery/tests/File_Structure_Test.php b/modules/gallery/tests/File_Structure_Test.php
index 06f456ff..8a97e00b 100644
--- a/modules/gallery/tests/File_Structure_Test.php
+++ b/modules/gallery/tests/File_Structure_Test.php
@@ -213,6 +213,43 @@ class File_Structure_Test extends Unit_Test_Case {
}
}
}
+
+ public function module_info_is_well_formed_test() {
+ $info_files = array_merge(
+ glob("modules/*/module.info"),
+ glob("themes/*/module.info"));
+
+ $errors = array();
+ foreach ($info_files as $file) {
+ foreach (file($file) as $line) {
+ $parts = explode("=", $line, 2);
+ $values[trim($parts[0])] = trim($parts[1]);
+ }
+
+ $module = dirname($file);
+ // Certain keys must exist
+ foreach (array("name", "description", "version") as $key) {
+ if (!array_key_exists($key, $values)) {
+ $errors[] = "$module: missing key $key";
+ }
+ }
+
+ // Any values containing spaces must be quoted
+ foreach ($values as $key => $value) {
+ if (strpos($value, " ") !== false && !preg_match('/^".*"$/', $value)) {
+ $errors[] = "$module: value for $key must be quoted";
+ }
+ }
+
+ // The file must parse
+ if (!is_array(parse_ini_file($file))) {
+ $errors[] = "$module: info file is not parseable";
+ }
+ }
+ if ($errors) {
+ $this->assert_true(false, $errors);
+ }
+ }
}
class PhpCodeFilterIterator extends FilterIterator {
diff --git a/modules/gallery/tests/Gallery_Installer_Test.php b/modules/gallery/tests/Gallery_Installer_Test.php
index 27157d6e..36ced2bb 100644
--- a/modules/gallery/tests/Gallery_Installer_Test.php
+++ b/modules/gallery/tests/Gallery_Installer_Test.php
@@ -34,13 +34,13 @@ class Gallery_Installer_Test extends Unit_Test_Case {
}
public function install_creates_root_item_test() {
- $max_right = ORM::factory("item")
- ->select("MAX(`right`) AS `right`")
- ->find()->right;
+ $max_right_ptr = ORM::factory("item")
+ ->select("MAX(`right_ptr`) AS `right_ptr`")
+ ->find()->right_ptr;
$root = ORM::factory('item')->find(1);
$this->assert_equal("Gallery", $root->title);
- $this->assert_equal(1, $root->left);
- $this->assert_equal($max_right, $root->right);
+ $this->assert_equal(1, $root->left_ptr);
+ $this->assert_equal($max_right_ptr, $root->right_ptr);
$this->assert_equal(null, $root->parent_id);
$this->assert_equal(1, $root->level);
}
diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php
index 615b8997..0940d076 100644
--- a/modules/gallery/tests/Item_Model_Test.php
+++ b/modules/gallery/tests/Item_Model_Test.php
@@ -140,4 +140,14 @@ class Item_Model_Test extends Unit_Test_Case {
}
$this->assert_false(true, "Item_Model::rename should not accept / characters");
}
+
+ public function save_original_values_test() {
+ $item = $this->create_random_item();
+ $item->title = "ORIGINAL_VALUE";
+ $item->save();
+ $item->title = "NEW_VALUE";
+
+ $this->assert_same("ORIGINAL_VALUE", $item->original()->title);
+ $this->assert_same("NEW_VALUE", $item->title);
+ }
}
diff --git a/modules/gallery/tests/ORM_MPTT_Test.php b/modules/gallery/tests/ORM_MPTT_Test.php
index 200c8a74..f77f1f34 100644
--- a/modules/gallery/tests/ORM_MPTT_Test.php
+++ b/modules/gallery/tests/ORM_MPTT_Test.php
@@ -33,8 +33,8 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$album->sort_order = "ASC";
$album->add_to_parent($root);
- $this->assert_equal($album->parent()->right - 2, $album->left);
- $this->assert_equal($album->parent()->right - 1, $album->right);
+ $this->assert_equal($album->parent()->right_ptr - 2, $album->left_ptr);
+ $this->assert_equal($album->parent()->right_ptr - 1, $album->right_ptr);
$this->assert_equal($album->parent()->level + 1, $album->level);
$this->assert_equal($album->parent()->id, $album->parent_id);
}
@@ -48,10 +48,10 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$album1_1_2 = self::create_item_and_add_to_parent($album1_1);
$album1->reload();
- $this->assert_equal(9, $album1->right - $album1->left);
+ $this->assert_equal(9, $album1->right_ptr - $album1->left_ptr);
$album1_1->reload();
- $this->assert_equal(5, $album1_1->right - $album1_1->left);
+ $this->assert_equal(5, $album1_1->right_ptr - $album1_1->left_ptr);
}
public function delete_hierarchy_test() {
@@ -66,7 +66,7 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$album1->reload();
// Now album1 contains only album1_2
- $this->assert_equal(3, $album1->right - $album1->left);
+ $this->assert_equal(3, $album1->right_ptr - $album1->left_ptr);
}
public function move_to_test() {
@@ -85,8 +85,8 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$album1_1->reload();
$album1_2->reload();
- $this->assert_equal(3, $album1_1->right - $album1_1->left);
- $this->assert_equal(3, $album1_2->right - $album1_2->left);
+ $this->assert_equal(3, $album1_1->right_ptr - $album1_1->left_ptr);
+ $this->assert_equal(3, $album1_2->right_ptr - $album1_2->left_ptr);
$this->assert_equal(
array($album1_1_2->id => "move_to_test_1_1_2"),
@@ -177,8 +177,8 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$parent->reload();
$this->assert_equal(3, $parent->descendants()->count());
- $this->assert_equal(2, $parent->descendants(null, 0, "photo")->count());
- $this->assert_equal(1, $parent->descendants(null, 0, "album")->count());
+ $this->assert_equal(2, $parent->descendants(null, 0, array("type" => "photo"))->count());
+ $this->assert_equal(1, $parent->descendants(null, 0, array("type" => "album"))->count());
}
public function descendant_limit_test() {
@@ -215,7 +215,7 @@ class ORM_MPTT_Test extends Unit_Test_Case {
$parent->reload();
$this->assert_equal(3, $parent->descendants_count());
- $this->assert_equal(2, $parent->descendants_count("photo"));
- $this->assert_equal(1, $parent->descendants_count("album"));
+ $this->assert_equal(2, $parent->descendants_count(array("type" => "photo")));
+ $this->assert_equal(1, $parent->descendants_count(array("type" => "album")));
}
}
diff --git a/modules/gallery/tests/Photo_Helper_Test.php b/modules/gallery/tests/Photo_Helper_Test.php
index cc1f20da..c0641ef4 100644
--- a/modules/gallery/tests/Photo_Helper_Test.php
+++ b/modules/gallery/tests/Photo_Helper_Test.php
@@ -43,8 +43,8 @@ class Photo_Helper_Test extends Unit_Test_Case {
$this->assert_equal($image_info[0], $photo->width);
$this->assert_equal($image_info[1], $photo->height);
- $this->assert_equal($photo->parent()->right - 2, $photo->left);
- $this->assert_equal($photo->parent()->right - 1, $photo->right);
+ $this->assert_equal($photo->parent()->right_ptr - 2, $photo->left_ptr);
+ $this->assert_equal($photo->parent()->right_ptr - 1, $photo->right_ptr);
}
public function create_conflicting_photo_test() {
diff --git a/modules/gallery/tests/Xss_Security_Test.php b/modules/gallery/tests/Xss_Security_Test.php
index e179482c..9bde11dc 100644
--- a/modules/gallery/tests/Xss_Security_Test.php
+++ b/modules/gallery/tests/Xss_Security_Test.php
@@ -36,7 +36,7 @@ class Xss_Security_Test extends Unit_Test_Case {
// If we find a "(" after a "p::clean" then start counting levels of parens and assume
// that we're inside a p::clean() call until we find the matching close paren.
- if ($token[0] == "(" && $str == "p::clean") {
+ if ($token[0] == "(" && ($str == "p::clean" || $str == "p::purify")) {
$in_p_clean = 1;
} else if ($token[0] == "(" && $in_p_clean) {
$in_p_clean++;
diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt
index 982343f6..0e118ce7 100644
--- a/modules/gallery/tests/xss_data.txt
+++ b/modules/gallery/tests/xss_data.txt
@@ -2,7 +2,7 @@ modules/akismet/views/admin_akismet.html.php 14 DIRTY $form
modules/akismet/views/admin_akismet_stats.html.php 9 DIRTY $api_key
modules/akismet/views/admin_akismet_stats.html.php 9 DIRTY $blog_url
modules/comment/views/admin_block_recent_comments.html.php 4 DIRTY $i
-modules/comment/views/admin_block_recent_comments.html.php 5 DIRTY $comment->author()->avatar_url(32, $theme->theme_url("images/avatar.jpg", true))
+modules/comment/views/admin_block_recent_comments.html.php 5 DIRTY $comment->author()->avatar_url(32, $theme->url("images/avatar.jpg", true))
modules/comment/views/admin_block_recent_comments.html.php 7 $comment->author_name()
modules/comment/views/admin_block_recent_comments.html.php 10 DIRTY $comment->created
modules/comment/views/admin_block_recent_comments.html.php 12 $comment->author_name()
@@ -15,7 +15,7 @@ modules/comment/views/admin_comments.html.php 72 DIRTY $counts->
modules/comment/views/admin_comments.html.php 75 DIRTY $csrf
modules/comment/views/admin_comments.html.php 106 DIRTY $comment->id
modules/comment/views/admin_comments.html.php 106 DIRTY $i
-modules/comment/views/admin_comments.html.php 109 DIRTY $comment->author()->avatar_url(40, $theme->theme_url("images/avatar.jpg", true))
+modules/comment/views/admin_comments.html.php 109 DIRTY $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true))
modules/comment/views/admin_comments.html.php 111 $comment->author_name()
modules/comment/views/admin_comments.html.php 115 $comment->author_email()
modules/comment/views/admin_comments.html.php 116 $comment->author_email()
@@ -35,7 +35,7 @@ modules/comment/views/admin_comments.html.php 175 DIRTY $comment-
modules/comment/views/admin_comments.html.php 183 DIRTY $comment->id
modules/comment/views/admin_comments.html.php 196 DIRTY $pager
modules/comment/views/comment.html.php 2 DIRTY $comment->id
-modules/comment/views/comment.html.php 5 DIRTY $comment->author()->avatar_url(40, $theme->theme_url("images/avatar.jpg", true))
+modules/comment/views/comment.html.php 5 DIRTY $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true))
modules/comment/views/comment.html.php 7 $comment->author_name()
modules/comment/views/comment.html.php 12 DIRTY $comment->created
modules/comment/views/comment.html.php 13 $comment->author_name()
@@ -58,7 +58,7 @@ modules/comment/views/comment.mrss.php 34 DIRTY $child->t
modules/comment/views/comment.mrss.php 35 DIRTY $child->thumb_height
modules/comment/views/comment.mrss.php 35 DIRTY $child->thumb_width
modules/comment/views/comments.html.php 10 DIRTY $comment->id
-modules/comment/views/comments.html.php 13 DIRTY $comment->author()->avatar_url(40, $theme->theme_url("images/avatar.jpg", true))
+modules/comment/views/comments.html.php 13 DIRTY $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true))
modules/comment/views/comments.html.php 15 $comment->author_name()
modules/comment/views/comments.html.php 20 DIRTY $comment->created
modules/comment/views/comments.html.php 21 $comment->author_name()
@@ -108,7 +108,7 @@ modules/gallery/views/admin_block_photo_stream.html.php 6 DIRTY $photo->w
modules/gallery/views/admin_block_photo_stream.html.php 6 DIRTY $photo->height
modules/gallery/views/admin_block_photo_stream.html.php 7 DIRTY $photo->thumb_url()
modules/gallery/views/admin_block_photo_stream.html.php 7 $photo->title
-modules/gallery/views/admin_block_platform.html.php 16 DIRTY $load_average
+modules/gallery/views/admin_block_platform.html.php 19 DIRTY $load_average
modules/gallery/views/admin_block_stats.html.php 7 DIRTY $album_count
modules/gallery/views/admin_block_stats.html.php 10 DIRTY $photo_count
modules/gallery/views/admin_dashboard.html.php 5 DIRTY $csrf
@@ -141,25 +141,31 @@ modules/gallery/views/admin_maintenance.html.php 75 DIRTY $task->na
modules/gallery/views/admin_maintenance.html.php 86 DIRTY $task->percent_complete
modules/gallery/views/admin_maintenance.html.php 90 DIRTY $task->status
modules/gallery/views/admin_maintenance.html.php 93 $task->owner()->name
-modules/gallery/views/admin_maintenance.html.php 97 DIRTY $task->id
-modules/gallery/views/admin_maintenance.html.php 97 DIRTY $csrf
-modules/gallery/views/admin_maintenance.html.php 101 DIRTY $task->id
-modules/gallery/views/admin_maintenance.html.php 101 DIRTY $csrf
-modules/gallery/views/admin_maintenance.html.php 113 DIRTY $csrf
-modules/gallery/views/admin_maintenance.html.php 140 DIRTY $task->state
-modules/gallery/views/admin_maintenance.html.php 142 DIRTY $task->updated
-modules/gallery/views/admin_maintenance.html.php 145 DIRTY $task->name
-modules/gallery/views/admin_maintenance.html.php 157 DIRTY $task->status
-modules/gallery/views/admin_maintenance.html.php 160 DIRTY $task->owner()->name
-modules/gallery/views/admin_maintenance.html.php 164 DIRTY $task->id
-modules/gallery/views/admin_maintenance.html.php 164 DIRTY $csrf
-modules/gallery/views/admin_maintenance.html.php 168 DIRTY $task->id
-modules/gallery/views/admin_maintenance.html.php 168 DIRTY $csrf
-modules/gallery/views/admin_maintenance.html.php 171 DIRTY $task->id
-modules/gallery/views/admin_maintenance.html.php 171 DIRTY $csrf
-modules/gallery/views/admin_maintenance_task.html.php 5 DIRTY $task->id
-modules/gallery/views/admin_maintenance_task.html.php 5 DIRTY $csrf
-modules/gallery/views/admin_maintenance_task.html.php 26 DIRTY $task->name
+modules/gallery/views/admin_maintenance.html.php 98 DIRTY $task->id
+modules/gallery/views/admin_maintenance.html.php 98 DIRTY $csrf
+modules/gallery/views/admin_maintenance.html.php 102 DIRTY $task->id
+modules/gallery/views/admin_maintenance.html.php 102 DIRTY $csrf
+modules/gallery/views/admin_maintenance.html.php 115 DIRTY $csrf
+modules/gallery/views/admin_maintenance.html.php 142 DIRTY $task->state
+modules/gallery/views/admin_maintenance.html.php 144 DIRTY $task->updated
+modules/gallery/views/admin_maintenance.html.php 147 DIRTY $task->name
+modules/gallery/views/admin_maintenance.html.php 159 DIRTY $task->status
+modules/gallery/views/admin_maintenance.html.php 162 DIRTY $task->owner()->name
+modules/gallery/views/admin_maintenance.html.php 166 DIRTY $task->id
+modules/gallery/views/admin_maintenance.html.php 166 DIRTY $csrf
+modules/gallery/views/admin_maintenance.html.php 170 DIRTY $task->id
+modules/gallery/views/admin_maintenance.html.php 170 DIRTY $csrf
+modules/gallery/views/admin_maintenance.html.php 175 DIRTY $task->id
+modules/gallery/views/admin_maintenance.html.php 175 DIRTY $csrf
+modules/gallery/views/admin_maintenance.html.php 178 DIRTY $task->id
+modules/gallery/views/admin_maintenance.html.php 178 DIRTY $csrf
+modules/gallery/views/admin_maintenance_show_log.html.php 8 DIRTY $task->id
+modules/gallery/views/admin_maintenance_show_log.html.php 8 DIRTY $csrf
+modules/gallery/views/admin_maintenance_show_log.html.php 13 DIRTY $task->name
+modules/gallery/views/admin_maintenance_show_log.html.php 15 $task->get_log()
+modules/gallery/views/admin_maintenance_task.html.php 30 DIRTY $task->id
+modules/gallery/views/admin_maintenance_task.html.php 30 DIRTY $csrf
+modules/gallery/views/admin_maintenance_task.html.php 54 DIRTY $task->name
modules/gallery/views/admin_modules.html.php 19 DIRTY $i
modules/gallery/views/admin_modules.html.php 22 DIRTY $data
modules/gallery/views/admin_modules.html.php 22 DIRTY $module_name
@@ -201,10 +207,10 @@ modules/gallery/views/admin_themes_preview.html.php 4 DIRTY $info->na
modules/gallery/views/admin_themes_preview.html.php 7 DIRTY $url
modules/gallery/views/after_install.html.php 11 $user->name
modules/gallery/views/after_install.html.php 15 DIRTY $user->id
-modules/gallery/views/kohana_error_page.php 98 DIRTY $message
-modules/gallery/views/kohana_error_page.php 100 DIRTY $file
-modules/gallery/views/kohana_error_page.php 100 DIRTY $line
-modules/gallery/views/kohana_error_page.php 112 DIRTY $trace
+modules/gallery/views/kohana_error_page.php 102 DIRTY $message
+modules/gallery/views/kohana_error_page.php 104 DIRTY $file
+modules/gallery/views/kohana_error_page.php 104 DIRTY $line
+modules/gallery/views/kohana_error_page.php 116 DIRTY $trace
modules/gallery/views/kohana_profiler.php 32 DIRTY $profile->render()
modules/gallery/views/kohana_profiler.php 34 DIRTY $execution_time
modules/gallery/views/l10n_client.html.php 17 DIRTY $string
@@ -212,8 +218,8 @@ modules/gallery/views/l10n_client.html.php 19 DIRTY $string
modules/gallery/views/l10n_client.html.php 20 DIRTY $string
modules/gallery/views/l10n_client.html.php 22 DIRTY $string
modules/gallery/views/l10n_client.html.php 28 DIRTY $l10n_search_form
-modules/gallery/views/l10n_client.html.php 72 DIRTY $string_list
-modules/gallery/views/l10n_client.html.php 73 DIRTY $plural_forms
+modules/gallery/views/l10n_client.html.php 74 DIRTY $string_list
+modules/gallery/views/l10n_client.html.php 75 DIRTY $plural_forms
modules/gallery/views/move_browse.html.php 4 DIRTY $source->id
modules/gallery/views/move_browse.html.php 39 DIRTY $tree
modules/gallery/views/move_browse.html.php 42 DIRTY $source->id
@@ -231,7 +237,7 @@ modules/gallery/views/move_tree.html.php 15 DIRTY $child->i
modules/gallery/views/move_tree.html.php 15 $child->title
modules/gallery/views/movieplayer.html.php 2 DIRTY $item->file_url(true)
modules/gallery/views/movieplayer.html.php 2 DIRTY $attrs
-modules/gallery/views/movieplayer.html.php 4 DIRTY $attrs
+modules/gallery/views/movieplayer.html.php 5 DIRTY $attrs
modules/gallery/views/permissions_browse.html.php 15 DIRTY $csrf
modules/gallery/views/permissions_browse.html.php 37 DIRTY $parent->id
modules/gallery/views/permissions_browse.html.php 38 $parent->title
@@ -280,8 +286,8 @@ modules/gallery/views/simple_uploader.html.php 7 DIRTY $csrf
modules/gallery/views/simple_uploader.html.php 9 $item->title
modules/gallery/views/simple_uploader.html.php 29 $parent->title
modules/gallery/views/simple_uploader.html.php 31 $item->title
-modules/gallery/views/simple_uploader.html.php 85 DIRTY $item->id
-modules/gallery/views/simple_uploader.html.php 89 DIRTY $csrf
+modules/gallery/views/simple_uploader.html.php 86 DIRTY $item->id
+modules/gallery/views/simple_uploader.html.php 90 DIRTY $csrf
modules/gallery/views/upgrader.html.php 44 DIRTY $module->version
modules/gallery/views/upgrader.html.php 44 DIRTY $module->code_version
modules/gallery/views/upgrader.html.php 45 DIRTY $id
@@ -297,8 +303,8 @@ modules/info/views/info_block.html.php 10 $item->de
modules/info/views/info_block.html.php 16 $item->name
modules/info/views/info_block.html.php 22 DIRTY $item->captured
modules/info/views/info_block.html.php 29 DIRTY $item->owner->url
-modules/info/views/info_block.html.php 29 $item->owner->full_name
-modules/info/views/info_block.html.php 31 $item->owner->name
+modules/info/views/info_block.html.php 29 $item->owner->display_name()
+modules/info/views/info_block.html.php 31 $item->owner->display_name()
modules/notification/views/comment_published.html.php 4 $subject
modules/notification/views/comment_published.html.php 7 $subject
modules/notification/views/comment_published.html.php 11 $comment->text
@@ -320,12 +326,12 @@ modules/notification/views/item_deleted.html.php 18 DIRTY $item->pa
modules/notification/views/item_deleted.html.php 19 DIRTY $item->parent()->url(array(), true)
modules/notification/views/item_updated.html.php 4 $subject
modules/notification/views/item_updated.html.php 7 $subject
-modules/notification/views/item_updated.html.php 12 $new->title
-modules/notification/views/item_updated.html.php 15 $new->title
-modules/notification/views/item_updated.html.php 20 DIRTY $new->url(array(), true)
-modules/notification/views/item_updated.html.php 20 DIRTY $new->url(array(), true)
-modules/notification/views/item_updated.html.php 25 $new->description
-modules/notification/views/item_updated.html.php 30 $new->description
+modules/notification/views/item_updated.html.php 12 $item->title
+modules/notification/views/item_updated.html.php 15 $item->title
+modules/notification/views/item_updated.html.php 20 DIRTY $item->url(array(), true)
+modules/notification/views/item_updated.html.php 20 DIRTY $item->url(array(), true)
+modules/notification/views/item_updated.html.php 25 $item->description
+modules/notification/views/item_updated.html.php 30 $item->description
modules/organize/views/organize.html.php 10 DIRTY $item->id
modules/organize/views/organize.html.php 12 DIRTY $csrf
modules/organize/views/organize.html.php 13 DIRTY $csrf
@@ -417,16 +423,17 @@ modules/server_add/views/admin_server_add.html.php 14 DIRTY $csrf
modules/server_add/views/admin_server_add.html.php 15 DIRTY $id
modules/server_add/views/admin_server_add.html.php 19 DIRTY $path
modules/server_add/views/admin_server_add.html.php 24 DIRTY $form
-modules/server_add/views/server_add_tree.html.php 4 DIRTY $tree_id
-modules/server_add/views/server_add_tree.html.php 6 DIRTY $file_info
-modules/server_add/views/server_add_tree.html.php 10 $file_info
-modules/server_add/views/server_add_tree.html.php 10 DIRTY $checked
-modules/server_add/views/server_add_tree.html.php 10 $file
-modules/server_add/views/server_add_tree_dialog.html.php 10 $album_title
-modules/server_add/views/server_add_tree_dialog.html.php 15 $parent->title
-modules/server_add/views/server_add_tree_dialog.html.php 17 $album_title
-modules/server_add/views/server_add_tree_dialog.html.php 20 DIRTY $action
-modules/server_add/views/server_add_tree_dialog.html.php 22 DIRTY $tree
+modules/server_add/views/server_add_tree.html.php 12 DIRTY $dir
+modules/server_add/views/server_add_tree.html.php 13 DIRTY $dir
+modules/server_add/views/server_add_tree.html.php 20 DIRTY $file
+modules/server_add/views/server_add_tree.html.php 25 DIRTY $file
+modules/server_add/views/server_add_tree.html.php 27 $file
+modules/server_add/views/server_add_tree_dialog.html.php 4 DIRTY $item->id
+modules/server_add/views/server_add_tree_dialog.html.php 4 DIRTY $csrf
+modules/server_add/views/server_add_tree_dialog.html.php 8 $item->title
+modules/server_add/views/server_add_tree_dialog.html.php 14 $parent->title
+modules/server_add/views/server_add_tree_dialog.html.php 18 $item->title
+modules/server_add/views/server_add_tree_dialog.html.php 23 DIRTY $tree
modules/tag/views/admin_tags.html.php 13 DIRTY $csrf
modules/tag/views/admin_tags.html.php 27 DIRTY $tags->count()
modules/tag/views/admin_tags.html.php 35 DIRTY $current_letter
@@ -435,8 +442,8 @@ modules/tag/views/admin_tags.html.php 50 DIRTY $tag->id
modules/tag/views/admin_tags.html.php 50 $tag->name
modules/tag/views/admin_tags.html.php 51 DIRTY $tag->count
modules/tag/views/admin_tags.html.php 52 DIRTY $tag->id
-modules/tag/views/tag_block.html.php 3 DIRTY $cloud
-modules/tag/views/tag_block.html.php 5 DIRTY $form
+modules/tag/views/tag_block.html.php 15 DIRTY $cloud
+modules/tag/views/tag_block.html.php 17 DIRTY $form
modules/tag/views/tag_cloud.html.php 4 DIRTY $tag->count
modules/tag/views/tag_cloud.html.php 4 DIRTY $max_count
modules/tag/views/tag_cloud.html.php 5 DIRTY $tag->count
@@ -447,7 +454,7 @@ modules/user/views/admin_users.html.php 36 DIRTY $csrf
modules/user/views/admin_users.html.php 67 DIRTY $user->id
modules/user/views/admin_users.html.php 67 DIRTY $user->admin
modules/user/views/admin_users.html.php 68 DIRTY $user->id
-modules/user/views/admin_users.html.php 69 DIRTY $user->avatar_url(20, $theme->theme_url("images/avatar.jpg", true))
+modules/user/views/admin_users.html.php 69 DIRTY $user->avatar_url(20, $theme->url("images/avatar.jpg", true))
modules/user/views/admin_users.html.php 71 $user->name
modules/user/views/admin_users.html.php 74 $user->name
modules/user/views/admin_users.html.php 77 $user->full_name
@@ -468,9 +475,7 @@ modules/user/views/admin_users_group.html.php 22 DIRTY $group->i
modules/user/views/admin_users_group.html.php 25 $user->name
modules/user/views/admin_users_group.html.php 25 $group->name
modules/user/views/login.html.php 12 DIRTY $user->id
-modules/user/views/login.html.php 15 $user->full_name
-modules/user/views/login.html.php 15 $user->name
-modules/user/views/login.html.php 15 $user->full_name
+modules/user/views/login.html.php 15 $user->display_name()
modules/user/views/login.html.php 18 DIRTY $csrf
modules/user/views/login_ajax.html.php 37 DIRTY $form
modules/user/views/reset_password.html.php 9 $user->full_name
@@ -481,34 +486,34 @@ modules/watermark/views/admin_watermarks.html.php 19 DIRTY $width
modules/watermark/views/admin_watermarks.html.php 19 DIRTY $height
modules/watermark/views/admin_watermarks.html.php 19 DIRTY $url
modules/watermark/views/admin_watermarks.html.php 21 DIRTY $position
-themes/admin_default/views/admin.html.php 10 DIRTY $theme->css("lib/yui/reset-fonts-grids.css")
-themes/admin_default/views/admin.html.php 11 DIRTY $theme->css("lib/themeroller/ui.base.css")
-themes/admin_default/views/admin.html.php 12 DIRTY $theme->css("lib/superfish/css/superfish.css")
-themes/admin_default/views/admin.html.php 13 DIRTY $theme->css("themes/default/css/screen.css")
-themes/admin_default/views/admin.html.php 14 DIRTY $theme->theme_css("css/screen.css")
-themes/admin_default/views/admin.html.php 16 DIRTY $theme->theme_url("css/fix-ie.css")
-themes/admin_default/views/admin.html.php 20 DIRTY $theme->script("lib/jquery.js")
-themes/admin_default/views/admin.html.php 21 DIRTY $theme->script("lib/jquery.form.js")
-themes/admin_default/views/admin.html.php 22 DIRTY $theme->script("lib/jquery-ui.js")
-themes/admin_default/views/admin.html.php 23 DIRTY $theme->script("lib/gallery.common.js")
-themes/admin_default/views/admin.html.php 28 DIRTY $theme->script("lib/gallery.dialog.js")
-themes/admin_default/views/admin.html.php 29 DIRTY $theme->script("lib/superfish/js/superfish.js")
-themes/admin_default/views/admin.html.php 30 DIRTY $theme->theme_script("js/jquery.dropshadow.js")
-themes/admin_default/views/admin.html.php 31 DIRTY $theme->theme_script("js/ui.init.js")
+themes/admin_default/views/admin.html.php 10 DIRTY $theme->css("yui/reset-fonts-grids.css")
+themes/admin_default/views/admin.html.php 11 DIRTY $theme->css("themeroller/ui.base.css")
+themes/admin_default/views/admin.html.php 12 DIRTY $theme->css("superfish/css/superfish.css")
+themes/admin_default/views/admin.html.php 13 DIRTY $theme->css("screen.css")
+themes/admin_default/views/admin.html.php 14 DIRTY $theme->css("admin_screen.css")
+themes/admin_default/views/admin.html.php 16 DIRTY $theme->url("fix-ie.css")
+themes/admin_default/views/admin.html.php 20 DIRTY $theme->script("jquery.js")
+themes/admin_default/views/admin.html.php 21 DIRTY $theme->script("jquery.form.js")
+themes/admin_default/views/admin.html.php 22 DIRTY $theme->script("jquery-ui.js")
+themes/admin_default/views/admin.html.php 23 DIRTY $theme->script("gallery.common.js")
+themes/admin_default/views/admin.html.php 28 DIRTY $theme->script("gallery.dialog.js")
+themes/admin_default/views/admin.html.php 29 DIRTY $theme->script("superfish/js/superfish.js")
+themes/admin_default/views/admin.html.php 30 DIRTY $theme->script("jquery.dropshadow.js")
+themes/admin_default/views/admin.html.php 31 DIRTY $theme->script("ui.init.js")
themes/admin_default/views/admin.html.php 33 DIRTY $theme->admin_head()
themes/admin_default/views/admin.html.php 36 DIRTY $theme->body_attributes()
themes/admin_default/views/admin.html.php 37 DIRTY $theme->admin_page_top()
themes/admin_default/views/admin.html.php 43 DIRTY $theme->site_status()
themes/admin_default/views/admin.html.php 45 DIRTY $theme->admin_header_top()
themes/admin_default/views/admin.html.php 48 DIRTY $csrf
-themes/admin_default/views/admin.html.php 52 DIRTY $theme->admin_menu()
-themes/admin_default/views/admin.html.php 54 DIRTY $theme->admin_header_bottom()
-themes/admin_default/views/admin.html.php 60 DIRTY $theme->messages()
-themes/admin_default/views/admin.html.php 61 DIRTY $content
-themes/admin_default/views/admin.html.php 67 DIRTY $sidebar
-themes/admin_default/views/admin.html.php 72 DIRTY $theme->admin_footer()
-themes/admin_default/views/admin.html.php 74 DIRTY $theme->admin_credits()
-themes/admin_default/views/admin.html.php 78 DIRTY $theme->admin_page_bottom()
+themes/admin_default/views/admin.html.php 54 DIRTY $theme->admin_menu()
+themes/admin_default/views/admin.html.php 56 DIRTY $theme->admin_header_bottom()
+themes/admin_default/views/admin.html.php 62 DIRTY $theme->messages()
+themes/admin_default/views/admin.html.php 63 DIRTY $content
+themes/admin_default/views/admin.html.php 69 DIRTY $sidebar
+themes/admin_default/views/admin.html.php 74 DIRTY $theme->admin_footer()
+themes/admin_default/views/admin.html.php 76 DIRTY $theme->admin_credits()
+themes/admin_default/views/admin.html.php 80 DIRTY $theme->admin_page_bottom()
themes/admin_default/views/block.html.php 2 DIRTY $id
themes/admin_default/views/block.html.php 2 DIRTY $css_id
themes/admin_default/views/block.html.php 5 DIRTY $id
@@ -544,7 +549,7 @@ themes/default/views/block.html.php 3 DIRTY $css_id
themes/default/views/block.html.php 4 DIRTY $title
themes/default/views/block.html.php 6 DIRTY $content
themes/default/views/dynamic.html.php 4 DIRTY $theme->dynamic_top()
-themes/default/views/dynamic.html.php 6 $tag->name
+themes/default/views/dynamic.html.php 6 $title
themes/default/views/dynamic.html.php 11 DIRTY $child->is_album()
themes/default/views/dynamic.html.php 12 DIRTY $theme->thumb_top($child)
themes/default/views/dynamic.html.php 13 DIRTY $child->url()
@@ -560,11 +565,11 @@ themes/default/views/dynamic.html.php 29 DIRTY $theme->p
themes/default/views/footer.html.php 2 DIRTY $theme->footer()
themes/default/views/footer.html.php 4 DIRTY $footer_text
themes/default/views/footer.html.php 9 DIRTY $theme->credits()
-themes/default/views/header.html.php 2 DIRTY $theme->header_top()
-themes/default/views/header.html.php 4 DIRTY $header_text
-themes/default/views/header.html.php 7 DIRTY $theme->theme_url("images/logo.png")
+themes/default/views/header.html.php 3 DIRTY $theme->header_top()
+themes/default/views/header.html.php 5 DIRTY $header_text
+themes/default/views/header.html.php 8 DIRTY $theme->url("images/logo.png")
themes/default/views/header.html.php 12 DIRTY $theme->site_menu()
-themes/default/views/header.html.php 15 DIRTY $theme->header_bottom()
+themes/default/views/header.html.php 14 DIRTY $theme->header_bottom()
themes/default/views/header.html.php 21 DIRTY $parent->id
themes/default/views/header.html.php 21 DIRTY $item->id
themes/default/views/header.html.php 22 $parent->title
@@ -583,27 +588,27 @@ themes/default/views/page.html.php 13 $theme->i
themes/default/views/page.html.php 15 $theme->item()->title
themes/default/views/page.html.php 17 $theme->item()->title
themes/default/views/page.html.php 20 $theme->tag()->name
-themes/default/views/page.html.php 26 DIRTY $theme->theme_url("images/favicon.ico")
-themes/default/views/page.html.php 27 DIRTY $theme->css("lib/yui/reset-fonts-grids.css")
-themes/default/views/page.html.php 28 DIRTY $theme->css("lib/superfish/css/superfish.css")
-themes/default/views/page.html.php 29 DIRTY $theme->css("lib/themeroller/ui.base.css")
-themes/default/views/page.html.php 30 DIRTY $theme->theme_css("css/screen.css")
-themes/default/views/page.html.php 32 DIRTY $theme->theme_url("css/fix-ie.css")
+themes/default/views/page.html.php 26 DIRTY $theme->url("images/favicon.ico")
+themes/default/views/page.html.php 27 DIRTY $theme->css("yui/reset-fonts-grids.css")
+themes/default/views/page.html.php 28 DIRTY $theme->css("superfish/css/superfish.css")
+themes/default/views/page.html.php 29 DIRTY $theme->css("themeroller/ui.base.css")
+themes/default/views/page.html.php 30 DIRTY $theme->css("screen.css")
+themes/default/views/page.html.php 32 DIRTY $theme->url("css/fix-ie.css")
themes/default/views/page.html.php 41 DIRTY $new_width
themes/default/views/page.html.php 42 DIRTY $new_height
themes/default/views/page.html.php 43 DIRTY $thumb_proportion
-themes/default/views/page.html.php 48 DIRTY $theme->script("lib/jquery.js")
-themes/default/views/page.html.php 49 DIRTY $theme->script("lib/jquery.form.js")
-themes/default/views/page.html.php 50 DIRTY $theme->script("lib/jquery-ui.js")
-themes/default/views/page.html.php 51 DIRTY $theme->script("lib/gallery.common.js")
-themes/default/views/page.html.php 56 DIRTY $theme->script("lib/gallery.dialog.js")
-themes/default/views/page.html.php 57 DIRTY $theme->script("lib/gallery.form.js")
-themes/default/views/page.html.php 58 DIRTY $theme->script("lib/superfish/js/superfish.js")
-themes/default/views/page.html.php 59 DIRTY $theme->script("lib/jquery.localscroll.js")
-themes/default/views/page.html.php 60 DIRTY $theme->theme_script("js/ui.init.js")
-themes/default/views/page.html.php 64 DIRTY $theme->script("lib/jquery.scrollTo.js")
-themes/default/views/page.html.php 65 DIRTY $theme->script("lib/gallery.show_full_size.js")
-themes/default/views/page.html.php 67 DIRTY $theme->script("lib/flowplayer.js")
+themes/default/views/page.html.php 48 DIRTY $theme->script("jquery.js")
+themes/default/views/page.html.php 49 DIRTY $theme->script("jquery.form.js")
+themes/default/views/page.html.php 50 DIRTY $theme->script("jquery-ui.js")
+themes/default/views/page.html.php 51 DIRTY $theme->script("gallery.common.js")
+themes/default/views/page.html.php 56 DIRTY $theme->script("gallery.dialog.js")
+themes/default/views/page.html.php 57 DIRTY $theme->script("gallery.form.js")
+themes/default/views/page.html.php 58 DIRTY $theme->script("superfish/js/superfish.js")
+themes/default/views/page.html.php 59 DIRTY $theme->script("jquery.localscroll.js")
+themes/default/views/page.html.php 60 DIRTY $theme->script("ui.init.js")
+themes/default/views/page.html.php 64 DIRTY $theme->script("jquery.scrollTo.js")
+themes/default/views/page.html.php 65 DIRTY $theme->script("gallery.show_full_size.js")
+themes/default/views/page.html.php 67 DIRTY $theme->script("flowplayer.js")
themes/default/views/page.html.php 70 DIRTY $theme->head()
themes/default/views/page.html.php 73 DIRTY $theme->body_attributes()
themes/default/views/page.html.php 74 DIRTY $theme->page_top()
diff --git a/modules/gallery/views/admin_block_platform.html.php b/modules/gallery/views/admin_block_platform.html.php
index 6b79f047..f27b9e7a 100644
--- a/modules/gallery/views/admin_block_platform.html.php
+++ b/modules/gallery/views/admin_block_platform.html.php
@@ -1,7 +1,10 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<ul>
<li>
- <?= t("Operating System: %operating_system", array("operating_system" => PHP_OS)) ?>
+ <?= t("Host name: %host_name", array("host_name" => php_uname("n"))) ?>
+ </li>
+ <li>
+ <?= t("Operating System: %os %version", array("os" => php_uname("s"), "version" => php_uname("r"))) ?>
</li>
<li>
<?= t("Apache: %apache_version", array("apache_version" => function_exists("apache_get_version") ? apache_get_version() : t("Unknown"))) ?>
diff --git a/modules/gallery/views/admin_block_stats.html.php b/modules/gallery/views/admin_block_stats.html.php
index 395ed71d..1dec8ccd 100644
--- a/modules/gallery/views/admin_block_stats.html.php
+++ b/modules/gallery/views/admin_block_stats.html.php
@@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<ul>
<li>
- <?= t("Version: %version", array("version" => module::get_var("gallery", "version"))) ?>
+ <?= t("Version: %version", array("version" => gallery::VERSION)) ?>
</li>
<li>
<?= t("Albums: %count", array("count" => $album_count)) ?>
diff --git a/modules/gallery/views/admin_graphics.html.php b/modules/gallery/views/admin_graphics.html.php
index 08374471..c4a2f5c6 100644
--- a/modules/gallery/views/admin_graphics.html.php
+++ b/modules/gallery/views/admin_graphics.html.php
@@ -9,8 +9,8 @@
};
$("#gAdminGraphics div.gAvailable .gBlock").click(select_toolkit);
});
-
</script>
+
<div id="gAdminGraphics">
<h1> <?= t("Graphics Settings") ?> </h1>
<p>
@@ -18,11 +18,19 @@
</p>
<h2> <?= t("Active Toolkit") ?> </h2>
- <?= $active ?>
+ <? if ($active == "none"): ?>
+ <?= new View("admin_graphics_none.html") ?>
+ <? else: ?>
+ <?= new View("admin_graphics_$active.html", array("tk" => $tk->$active, "is_active" => true)) ?>
+ <? endif ?>
<div class="gAvailable">
<h2> <?= t("Available Toolkits") ?> </h2>
- <?= $available ?>
+ <? foreach (array_keys((array)$tk) as $id): ?>
+ <? if ($id != $active): ?>
+ <?= new View("admin_graphics_$id.html", array("tk" => $tk->$id, "is_active" => false)) ?>
+ <? endif ?>
+ <? endforeach ?>
</div>
</div>
diff --git a/modules/gallery/views/admin_graphics_gd.html.php b/modules/gallery/views/admin_graphics_gd.html.php
index b77da8e3..aa9ee67c 100644
--- a/modules/gallery/views/admin_graphics_gd.html.php
+++ b/modules/gallery/views/admin_graphics_gd.html.php
@@ -1,23 +1,26 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="gd" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->gd["GD Version"] ? " gInstalledToolkit" : " gUnavailable" ?>">
+<div id="gd" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->installed ? " gInstalledToolkit" : " gUnavailable" ?>">
<img class="logo" width="170" height="110" src="<?= url::file("modules/gallery/images/gd.png"); ?>" alt="<? t("Visit the GD lib project site") ?>" />
<h3> <?= t("GD") ?> </h3>
<p>
<?= t("The GD graphics library is an extension to PHP commonly installed most webservers. Please refer to the <a href=\"%url\">GD website</a> for more information.",
array("url" => "http://www.boutell.com/gd")) ?>
</p>
- <? if ($tk->gd["GD Version"] && function_exists('imagerotate')): ?>
+ <? if ($tk->installed && $tk->rotate): ?>
<p class="gSuccess">
- <?= t("You have GD version %version.", array("version" => $tk->gd["GD Version"])) ?>
+ <?= t("You have GD version %version.", array("version" => $tk->version)) ?>
</p>
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate GD") ?></a>
</p>
- <? elseif ($tk->gd["GD Version"]): ?>
+ <? elseif ($tk->installed): ?>
+
+ <? if ($tk->error): ?>
<p class="gWarning">
- <?= t("You have GD version %version, but it lacks image rotation.",
- array("version" => $tk->gd["GD Version"])) ?>
+ <?= $tk->error ?>
</p>
+ <? endif ?>
+
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate GD") ?></a>
</p>
diff --git a/modules/gallery/views/admin_graphics_graphicsmagick.html.php b/modules/gallery/views/admin_graphics_graphicsmagick.html.php
index e2cd0777..bf3ad339 100644
--- a/modules/gallery/views/admin_graphics_graphicsmagick.html.php
+++ b/modules/gallery/views/admin_graphics_graphicsmagick.html.php
@@ -1,21 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="graphicsmagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->graphicsmagick ? " gInstalledToolkit" : " gUnavailable" ?>">
+<div id="graphicsmagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->installed ? " gInstalledToolkit" : " gUnavailable" ?>">
<h3> <?= t("GraphicsMagick") ?> </h3>
<img class="logo" width="107" height="76" src="<?= url::file("modules/gallery/images/graphicsmagick.png"); ?>" alt="<? t("Visit the GraphicsMagick project site") ?>" />
<p>
<?= t("GraphicsMagick is a standalone graphics program available on most Linux systems. Please refer to the <a href=\"%url\">GraphicsMagick website</a> for more information.",
array("url" => "http://www.graphicsmagick.org")) ?>
</p>
- <? if ($tk->graphicsmagick): ?>
+ <? if ($tk->installed): ?>
<p class="gSuccess">
- <?= t("GraphicsMagick is available in %path", array("path" => $tk->graphicsmagick)) ?>
+ <?= t("GraphicsMagick version %version is available in %dir", array("version" => $tk->version, "dir" => $tk->dir)) ?>
</p>
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate Graphics Magic") ?></a>
</p>
<? else: ?>
- <p class="gInfo">
- <?= t("GraphicsMagick is not available on your system.") ?>
+ <p class="gWarning">
+ <?= $tk->error ?>
</p>
<? endif ?>
</div>
diff --git a/modules/gallery/views/admin_graphics_imagemagick.html.php b/modules/gallery/views/admin_graphics_imagemagick.html.php
index 081ddc15..b8f7ffb8 100644
--- a/modules/gallery/views/admin_graphics_imagemagick.html.php
+++ b/modules/gallery/views/admin_graphics_imagemagick.html.php
@@ -1,21 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="imagemagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->imagemagick ? " gInstalledToolkit" : " gUnavailable" ?>">
+<div id="imagemagick" class="gBlock<?= $is_active ? " gSelected" : "" ?><?= $tk->installed ? " gInstalledToolkit" : " gUnavailable" ?>">
<h3> <?= t("ImageMagick") ?> </h3>
<img class="logo" width="114" height="118" src="<?= url::file("modules/gallery/images/imagemagick.jpg"); ?>" alt="<? t("Visit the ImageMagick project site") ?>" />
<p>
<?= t("ImageMagick is a standalone graphics program available on most Linux systems. Please refer to the <a href=\"%url\">ImageMagick website</a> for more information.",
array("url" => "http://www.imagemagick.org")) ?>
</p>
- <? if ($tk->imagemagick): ?>
+ <? if ($tk->installed): ?>
<p class="gSuccess">
- <?= t("ImageMagick is available in %path", array("path" => $tk->imagemagick)) ?>
+ <?= t("ImageMagick version %version is available in %dir", array("version" => $tk->version, "dir" => $tk->dir)) ?>
</p>
<p>
<a class="gButtonLink ui-state-default ui-corner-all"><?= t("Activate ImageMagick") ?></a>
</p>
- <? else: ?>
- <p class="gInfo">
- <?= t("ImageMagick is not available on your system.") ?>
+ <? elseif ($tk->error): ?>
+ <p class="gWarning">
+ <?= $tk->error ?>
</p>
<? endif ?>
</div>
diff --git a/modules/gallery/views/admin_graphics_none.html.php b/modules/gallery/views/admin_graphics_none.html.php
index 5306a70d..be2a580d 100644
--- a/modules/gallery/views/admin_graphics_none.html.php
+++ b/modules/gallery/views/admin_graphics_none.html.php
@@ -2,6 +2,6 @@
<div id="none" class="gBlock">
<h3 class="gWarning"> <?= t("No Active Toolkit") ?> </h3>
<p>
- <?= t("We were unable to detect a graphics program. You must install one of the toolkits below in order to many Gallery features.") ?>
+ <?= t("We were unable to detect a graphics program. You must install one of the toolkits below in order to use many Gallery features.") ?>
</p>
</div>
diff --git a/modules/gallery/views/admin_maintenance.html.php b/modules/gallery/views/admin_maintenance.html.php
index eecc045c..450eb754 100644
--- a/modules/gallery/views/admin_maintenance.html.php
+++ b/modules/gallery/views/admin_maintenance.html.php
@@ -29,7 +29,7 @@
</td>
<td>
<a href="<?= url::site("admin/maintenance/start/$task->callback?csrf=$csrf") ?>"
- class="gDialogLink">
+ class="gDialogLink gButtonLink ui-icon-left ui-state-default ui-corner-all">
<?= t("run") ?>
</a>
</td>
@@ -79,7 +79,7 @@
<? if ($task->state == "cancelled"): ?>
<?= t("Cancelled") ?>
<? endif ?>
- <?= t("Done") ?>
+ <?= t("Close") ?>
<? elseif ($task->state == "stalled"): ?>
<?= t("Stalled") ?>
<? else: ?>
@@ -94,11 +94,13 @@
</td>
<td>
<? if ($task->state == "stalled"): ?>
- <a class="gDialogLink" href="<?= url::site("admin/maintenance/resume/$task->id?csrf=$csrf") ?>">
+ <a class="gDialogLink gButtonLink ui-icon-left ui-state-default ui-corner-all"
+ href="<?= url::site("admin/maintenance/resume/$task->id?csrf=$csrf") ?>">
<?= t("resume") ?>
</a>
<? endif ?>
- <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>">
+ <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>"
+ class="gButtonLink ui-icon-left ui-state-default ui-corner-all right">
<?= t("cancel") ?>
</a>
</td>
@@ -161,22 +163,23 @@
</td>
<td>
<? if ($task->done): ?>
- <a href="<?= url::site("admin/maintenance/remove/$task->id?csrf=$csrf") ?>">
+ <a href="<?= url::site("admin/maintenance/remove/$task->id?csrf=$csrf") ?>" class="gButtonLink ui-state-default ui-corner-all">
<?= t("remove") ?>
</a>
<? if ($task->get_log()): ?>
- <a class="gDialogLink" href="<?= url::site("admin/maintenance/show_log/$task->id?csrf=$csrf") ?>">
+ <a href="<?= url::site("admin/maintenance/show_log/$task->id?csrf=$csrf") ?>" class="gDialogLink gButtonLink ui-state-default ui-corner-all">
<?= t("browse log") ?>
</a>
<? endif ?>
<? else: ?>
- <a class="gDialogLink" href="<?= url::site("admin/maintenance/resume/$task->id?csrf=$csrf") ?>">
+ <a href="<?= url::site("admin/maintenance/resume/$task->id?csrf=$csrf") ?>" class="gDialogLink gButtonLink" ui-state-default ui-corner-all>
<?= t("resume") ?>
</a>
- <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>">
+ <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>" class="gButtonLink ui-state-default ui-corner-all">
<?= t("cancel") ?>
</a>
<? endif ?>
+ </ul>
</td>
</tr>
<? endforeach ?>
diff --git a/modules/gallery/views/admin_maintenance_task.html.php b/modules/gallery/views/admin_maintenance_task.html.php
index d9aecc60..0eb0b38c 100644
--- a/modules/gallery/views/admin_maintenance_task.html.php
+++ b/modules/gallery/views/admin_maintenance_task.html.php
@@ -1,11 +1,39 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script type="text/javascript">
+ var target_value;
+ var animation = null;
+ var delta = 1;
+ animate_progress_bar = function() {
+ var current_value = Number($(".gProgressBar div").css("width").replace("%", ""));
+ if (target_value > current_value) {
+ // speed up
+ delta = Math.min(delta + 0.04, 3);
+ } else {
+ // slow down
+ delta = Math.max(delta - 0.05, 1);
+ }
+
+ if (target_value == 100) {
+ $(".gProgressBar").progressbar("value", 100);
+ } else if (current_value != target_value || delta != 1) {
+ var new_value = Math.min(current_value + delta, target_value);
+ $(".gProgressBar").progressbar("value", new_value);
+ animation = setTimeout(function() { animate_progress_bar(target_value); }, 100);
+ } else {
+ animation = null;
+ delta = 1;
+ }
+ }
+
update = function() {
$.ajax({
url: "<?= url::site("admin/maintenance/run/$task->id?csrf=$csrf") ?>",
dataType: "json",
success: function(data) {
- $(".gProgressBar").progressbar("value", data.task.percent_complete);
+ target_value = data.task.percent_complete;
+ if (!animation) {
+ animate_progress_bar();
+ }
$("#gStatus").html("" + data.task.status);
if (data.task.done) {
$("#gPauseButton").hide();
@@ -30,6 +58,6 @@
</div>
<div>
<button id="gPauseButton" class="ui-state-default ui-corner-all" onclick="dismiss()"><?= t("Pause") ?></button>
- <button id="gDoneButton" class="ui-state-default ui-corner-all" style="display: none" onclick="dismiss()"><?= t("Done") ?></button>
+ <button id="gDoneButton" class="ui-state-default ui-corner-all" style="display: none" onclick="dismiss()"><?= t("Close") ?></button>
</div>
</div>
diff --git a/modules/gallery/views/after_install.html.php b/modules/gallery/views/after_install.html.php
index d6ba8e7c..bfce46f0 100644
--- a/modules/gallery/views/after_install.html.php
+++ b/modules/gallery/views/after_install.html.php
@@ -16,12 +16,12 @@
title="<?= t("Edit Your Profile") ?>"
id="gAfterInstallChangePasswordLink" class="gButtonLink ui-state-default ui-corners-all"><?= t("Change Password Now") ?></a>
<script>
- $("#gAfterInstallChangePasswordLink").bind("click", handleDialogEvent);
+ $("#gAfterInstallChangePasswordLink").gallery_dialog();
</script>
</p>
<p>
- <?= t("Want to learn more? The <a href=\"%url\">Gallery website</a> has news and information about Gallery Project and community.", array("url" => "http://gallery.menalto.com")) ?>
+ <?= t("Want to learn more? The <a href=\"%url\">Gallery website</a> has news and information about the Gallery project and community.", array("url" => "http://gallery.menalto.com")) ?>
</p>
<p>
diff --git a/modules/gallery/views/after_install_loader.html.php b/modules/gallery/views/after_install_loader.html.php
index baf91eed..54484963 100644
--- a/modules/gallery/views/after_install_loader.html.php
+++ b/modules/gallery/views/after_install_loader.html.php
@@ -3,5 +3,5 @@
title="<?= t("Welcome to Gallery 3") ?>"
href="<?= url::site("after_install") ?>"/>
<script type="text/javascript">
- $(document).ready(function(){openDialog($("#gAfterInstall"));});
+ $(document).ready(function(){$("#gAfterInstall").gallery_dialog({immediate: true});});
</script>
diff --git a/modules/gallery/views/form.html.php b/modules/gallery/views/form.html.php
index ec2a56a9..730d77cb 100644
--- a/modules/gallery/views/form.html.php
+++ b/modules/gallery/views/form.html.php
@@ -40,6 +40,8 @@ if (!function_exists("DrawForm")) {
print "$prefix {$hidden->render()}\n";
}
print "$prefix</fieldset>\n";
+ } else if ($input->type == 'script') {
+ print $input->render();
} else {
if ($input->error_messages()) {
print "$prefix<li class=\"gError\">\n";
diff --git a/modules/gallery/views/l10n_client.html.php b/modules/gallery/views/l10n_client.html.php
index c0cbbfa2..c73719ca 100644
--- a/modules/gallery/views/l10n_client.html.php
+++ b/modules/gallery/views/l10n_client.html.php
@@ -9,7 +9,7 @@
</h2></div>
<div class="label source"><h2><?= t("Source") ?></div>
<div class="label translation"><h2><?= t("Translation to %language",
- array("language" => locale::display_name())) ?></h2></div>
+ array("language" => locales::display_name())) ?></h2></div>
</div>
<div id="l10n-client-string-select">
<ul class="string-list">
diff --git a/modules/gallery/views/movieplayer.html.php b/modules/gallery/views/movieplayer.html.php
index e8cabd31..e9783eb8 100644
--- a/modules/gallery/views/movieplayer.html.php
+++ b/modules/gallery/views/movieplayer.html.php
@@ -1,15 +1,22 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= html::anchor($item->file_url(true), "", $attrs) ?>
<script>
- flowplayer("<?= $attrs["id"] ?>", "<?= url::abs_file("lib/flowplayer.swf") ?>", {
- plugins: {
- h264streaming: {
- url: "<?= url::abs_file("lib/flowplayer.h264streaming.swf") ?>"
- },
- controls: {
- autoHide: 'always',
- hideDelay: 2000
+ flowplayer(
+ "<?= $attrs["id"] ?>",
+ {
+ src: "<?= url::abs_file("lib/flowplayer.swf") ?>",
+ wmode: "transparent"
+ },
+ {
+ plugins: {
+ h264streaming: {
+ url: "<?= url::abs_file("lib/flowplayer.h264streaming.swf") ?>"
+ },
+ controls: {
+ autoHide: 'always',
+ hideDelay: 2000
+ }
}
}
- })
+ )
</script>
diff --git a/modules/gallery/views/permissions_form.html.php b/modules/gallery/views/permissions_form.html.php
index 0f60070a..ee5e3a24 100644
--- a/modules/gallery/views/permissions_form.html.php
+++ b/modules/gallery/views/permissions_form.html.php
@@ -26,7 +26,7 @@
</a>
</td>
<? else: ?>
- <? if ($intent === null): ?>
+ <? if ($intent === access::INHERIT): ?>
<? if ($allowed): ?>
<td class="gAllowed">
<a href="javascript:set('allow',<?= $group->id ?>,<?= $permission->id ?>,<?= $item->id ?>)"
diff --git a/modules/gallery/views/quick_pane.html.php b/modules/gallery/views/quick_pane.html.php
deleted file mode 100644
index eabf4a67..00000000
--- a/modules/gallery/views/quick_pane.html.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<? foreach ($button_list->main as $button): ?>
-<a class="<?= $button->class ?> ui-corner-all ui-state-default" href="<?= $button->href ?>"
- title="<?= $button->title ?>">
- <span class="ui-icon <?= $button->icon ?>">
- <?= $button->title ?>
- </span>
-</a>
-<? endforeach ?>
-
-<? if (!empty($button_list->additional)): ?>
-<a class="gButtonLink ui-corner-all ui-state-default options" href="#" title="<?= t("additional options") ?>">
- <span class="ui-icon ui-icon-triangle-1-s">
- <?= t("Additional options") ?>
- </span>
-</a>
-
-<ul id="gQuickPaneOptions" style="display: none">
- <? foreach ($button_list->additional as $button): ?>
- <li><a class="<?= $button->class ?>" href="<?= $button->href ?>"
- title="<?= $button->title ?>">
- <?= $button->title ?>
- </a></li>
- <? endforeach ?>
-</ul>
-<? endif ?>
diff --git a/modules/gallery/views/simple_uploader.html.php b/modules/gallery/views/simple_uploader.html.php
index 56b1c656..38ac518c 100644
--- a/modules/gallery/views/simple_uploader.html.php
+++ b/modules/gallery/views/simple_uploader.html.php
@@ -32,8 +32,9 @@
</ul>
<p>
- <?= t("Upload Queue") ?>
- <span id="gUploadQueueInfo"></span>
+ <span id="gUploadQueueInfo">
+ <?= t("Upload Queue") ?>
+ </span>
<a id="gUploadCancel" title="<?= t("Cancel all the pending uploads") ?>" onclick="swfu.cancelQueue();"><?= t("cancel") ?></a>
</p>
<div id="gAddPhotosCanvas" style="text-align: center;">
@@ -51,7 +52,7 @@
<!-- Proxy the done request back to our form, since its been ajaxified -->
<button class="ui-state-default ui-corner-all" onclick="$('#gAddPhotosForm').submit()">
- <?= t("Done") ?>
+ <?= t("Close") ?>
</button>
</div>
@@ -181,9 +182,7 @@
function file_dialog_complete(num_files_selected, num_files_queued) {
if (num_files_selected > 0) {
$("#gUploadCancel").show();
- var stats = this.getStats();
- $("#gUploadQueueInfo").text("(completed " + stats.successful_uploads +
- " of " + (stats.files_queued + stats.successful_uploads + stats.upload_errors + stats.upload_cancelled + stats.queue_errors) + ")");
+ $("#gUploadQueueInfo").text(get_completed_status_msg(this.getStats()));
}
// Auto start the upload
@@ -254,13 +253,20 @@
function upload_complete(file) {
var stats = this.getStats();
- $("#gUploadQueueInfo").text("(completed " + stats.successful_uploads +
- " of " + (stats.files_queued + stats.successful_uploads + stats.upload_errors + stats.upload_cancelled + stats.queue_errors) + ")");
+ $("#gUploadQueueInfo").text(get_completed_status_msg(stats));
if (stats.files_queued === 0) {
$("#gUploadCancel").hide();
}
}
+ function get_completed_status_msg(stats) {
+ var msg = "<?= t("Upload Queue (completed %completed of %total)", array("completed" => "__COMPLETED__", "total" => "__TOTAL__")) ?>";
+ msg = msg.replace("__COMPLETED__", stats.successful_uploads);
+ msg = msg.replace("__TOTAL__", stats.files_queued + stats.successful_uploads +
+ stats.upload_errors + stats.upload_cancelled + stats.queue_errors);
+ return msg;
+ }
+
// This event comes from the Queue Plugin
function queue_complete(num_files_uploaded) {
var status_msg = "<?= t("Uploaded: __COUNT__") ?>";
diff --git a/modules/image_block/module.info b/modules/image_block/module.info
index 8852d33c..e6d85048 100644
--- a/modules/image_block/module.info
+++ b/modules/image_block/module.info
@@ -1,3 +1,3 @@
-name = Image Block
-description = Display a random image in the sidebar
+name = "Image Block"
+description = "Display a random image in the sidebar"
version = 1
diff --git a/modules/info/helpers/info_theme.php b/modules/info/helpers/info_theme.php
index 863317a8..51378e54 100644
--- a/modules/info/helpers/info_theme.php
+++ b/modules/info/helpers/info_theme.php
@@ -37,7 +37,11 @@ class info_theme_Core {
}
if ($item->owner) {
$results .= "<li>";
- $results .= t("By: %owner_name", array("owner_name" => "<a href=\"#\">{$item->owner->full_name}</a>"));
+ if ($item->owner->url) {
+ $results .= t("By: %owner_name", array("owner_name" => "<a href=\"{$item->owner->url}\">{$item->owner->full_name}</a>"));
+ } else {
+ $results .= t("By: %owner_name", array("owner_name" => "{$item->owner->full_name}"));
+ }
$results .= "</li>";
}
return $results;
diff --git a/modules/info/module.info b/modules/info/module.info
index ce03473e..e352213c 100644
--- a/modules/info/module.info
+++ b/modules/info/module.info
@@ -1,3 +1,3 @@
-name = Info
-description = Display extra information about photos and albums
+name = "Info"
+description = "Display extra information about photos and albums"
version = 1
diff --git a/modules/info/views/info_block.html.php b/modules/info/views/info_block.html.php
index 9f544376..762e989b 100644
--- a/modules/info/views/info_block.html.php
+++ b/modules/info/views/info_block.html.php
@@ -12,7 +12,7 @@
<? endif ?>
<? if ($item->id != 1): ?>
<li>
- <strong class="caption"><?= t("Folder name:") ?></strong>
+ <strong class="caption"><?= $theme->page_type == 'album' ? t("Folder name:"): t("File name:"); ?></strong>
<?= p::clean($item->name) ?>
</li>
<? endif ?>
@@ -26,9 +26,9 @@
<li>
<strong class="caption"><?= t("Owner:") ?></strong>
<? if ($item->owner->url): ?>
- <a href="<?= $item->owner->url ?>"><?= p::clean($item->owner->full_name) ?></a>
+ <a href="<?= $item->owner->url ?>"><?= p::clean($item->owner->display_name()) ?></a>
<? else: ?>
- <?= p::clean($item->owner->name) ?>
+ <?= p::clean($item->owner->display_name()) ?>
<? endif ?>
</li>
<? endif ?>
diff --git a/modules/notification/helpers/notification.php b/modules/notification/helpers/notification.php
index 8ee0c6ba..92c40d4f 100644
--- a/modules/notification/helpers/notification.php
+++ b/modules/notification/helpers/notification.php
@@ -67,32 +67,35 @@ class notification {
}
static function get_subscribers($item) {
+ // @todo don't access the user table directly
+ // @todo only return distinct email addresses
$users = ORM::factory("user")
->join("subscriptions", "users.id", "subscriptions.user_id")
->join("items", "subscriptions.item_id", "items.id")
->where("email IS NOT", null)
- ->where("items.left <=", $item->left)
- ->where("items.right >", $item->right)
+ ->where("items.left_ptr <=", $item->left_ptr)
+ ->where("items.right_ptr >", $item->right_ptr)
->find_all();
$subscribers = array();
foreach ($users as $user) {
- $subscribers[] = $user->email;
+ if (access::user_can($user, "view", $item)) {
+ $subscribers[$user->email] = 1;
+ }
}
- return $subscribers;
+ return array_keys($subscribers);
}
- static function send_item_updated($old, $new) {
+ static function send_item_updated($item) {
$v = new View("item_updated.html");
- $v->old = $old;
- $v->new = $new;
- $v->subject = $old->is_album() ?
- t("Album %title updated", array("title" => $old->title)) :
- ($old->is_photo() ?
- t("Photo %title updated", array("title" => $old->title))
- : t("Movie %title updated", array("title" => $old->title)));
-
- self::_notify_subscribers($old, $v->render(), $v->subject);
+ $v->item = $item;
+ $v->subject = $item->is_album() ?
+ t("Album %title updated", array("title" => $item->original("title"))) :
+ ($item->is_photo() ?
+ t("Photo %title updated", array("title" => $item->original("title")))
+ : t("Movie %title updated", array("title" => $item->original("title"))));
+
+ self::_notify_subscribers($item, $v->render(), $v->subject);
}
static function send_item_add($item) {
@@ -104,8 +107,8 @@ class notification {
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)) :
+ t("Movie %title added to %parent_title",
array("title" => $item->title, "parent_title" => $parent->title)));
self::_notify_subscribers($item, $v->render(), $v->subject);
diff --git a/modules/notification/helpers/notification_event.php b/modules/notification/helpers/notification_event.php
index 1cf9ff58..d1b76e93 100644
--- a/modules/notification/helpers/notification_event.php
+++ b/modules/notification/helpers/notification_event.php
@@ -18,15 +18,15 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class notification_event_Core {
- static function item_updated($old, $new) {
- notification::send_item_updated($old, $new);
+ static function item_updated($original, $new) {
+ notification::send_item_updated($new);
}
static function item_created($item) {
notification::send_item_add($item);
}
- static function item_before_delete($item) {
+ static function item_deleted($item) {
notification::send_item_deleted($item);
if (notification::is_watching($item)) {
@@ -40,8 +40,8 @@ class notification_event_Core {
}
}
- static function comment_updated($old, $new) {
- if ($new->state == "published" && $old->state != "published") {
+ static function comment_updated($original, $new) {
+ if ($new->state == "published" && $original->state != "published") {
notification::send_comment_published($new);
}
}
@@ -55,4 +55,23 @@ class notification_event_Core {
static function batch_complete() {
notification::send_pending_notifications();
}
+
+ static function site_menu($menu, $theme) {
+ if (!user::active()->guest) {
+ $item = $theme->item();
+
+ if ($item && $item->is_album() && access::can("view", $item)) {
+ $watching = notification::is_watching($item);
+
+ $label = $watching ? t("Remove notifications") : t("Enable notifications");
+
+ $menu->get("options_menu")
+ ->append(Menu::factory("link")
+ ->id("watch")
+ ->label($label)
+ ->css_id("gNotifyLink")
+ ->url(url::site("notification/watch/$item->id?csrf=" . access::csrf_token())));
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/modules/notification/helpers/notification_installer.php b/modules/notification/helpers/notification_installer.php
index 3d450258..aa2e09f7 100644
--- a/modules/notification/helpers/notification_installer.php
+++ b/modules/notification/helpers/notification_installer.php
@@ -27,14 +27,14 @@ class notification_installer {
PRIMARY KEY (`id`),
UNIQUE KEY (`item_id`, `user_id`),
UNIQUE KEY (`user_id`, `item_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {pending_notifications} (
`id` int(9) NOT NULL auto_increment,
`email` varchar(128) NOT NULL,
`subject` varchar(255) NOT NULL,
`text` text,
PRIMARY KEY (`id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("notification", 1);
}
diff --git a/modules/notification/helpers/notification_menu.php b/modules/notification/helpers/notification_menu.php
deleted file mode 100644
index 696aad62..00000000
--- a/modules/notification/helpers/notification_menu.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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 notification_menu_Core {
- static function site($menu, $theme) {
- if (!user::active()->guest) {
- $item = $theme->item();
-
- if ($item && $item->is_album()) {
- $watching = notification::is_watching($item);
-
- $watching ? $label = t("Remove notifications") : $label = t("Enable notifications");
-
- $menu->get("options_menu")
- ->append(Menu::factory("link")
- ->id("watch")
- ->label($label)
- ->css_id("gNotifyLink")
- ->url(url::site("notification/watch/$item->id?csrf=" . access::csrf_token())));
- }
- }
- }
-}
diff --git a/modules/notification/module.info b/modules/notification/module.info
index d4dc34e0..31684ccf 100644
--- a/modules/notification/module.info
+++ b/modules/notification/module.info
@@ -1,3 +1,3 @@
-name = Notification
+name = "Notification"
description = "Send notifications to users when changes are made to watched albums."
version = 1
diff --git a/modules/notification/views/item_added.html.php b/modules/notification/views/item_added.html.php
index 87ea90fa..86724927 100644
--- a/modules/notification/views/item_added.html.php
+++ b/modules/notification/views/item_added.html.php
@@ -8,7 +8,7 @@
<table>
<tr>
<td><?= t("Title:") ?></td>
- <td><?= p::purifys($item->title) ?></td>
+ <td><?= p::purify($item->title) ?></td>
</tr>
<tr>
<td><?= t("Url:") ?></td>
diff --git a/modules/notification/views/item_updated.html.php b/modules/notification/views/item_updated.html.php
index 0620c50c..39f9113b 100644
--- a/modules/notification/views/item_updated.html.php
+++ b/modules/notification/views/item_updated.html.php
@@ -7,27 +7,27 @@
<h2> <?= p::clean($subject) ?> </h2>
<table>
<tr>
- <? if ($old->title != $new->title): ?>
+ <? if ($item->original("title") != $item->title): ?>
<td><?= t("New Title:") ?></td>
- <td><?= p::clean($new->title) ?></td>
+ <td><?= p::clean($item->title) ?></td>
<? else: ?>
<td><?= t("Title:") ?></td>
- <td><?= p::clean($new->title) ?></td>
+ <td><?= p::clean($item->title) ?></td>
<? endif ?>
</tr>
<tr>
<td><?= t("Url:") ?></td>
- <td><a href="<?= $new->url(array(), true) ?>"><?= $new->url(array(), true) ?></a></td>
+ <td><a href="<?= $item->url(array(), true) ?>"><?= $item->url(array(), true) ?></a></td>
</tr>
- <? if ($old->description != $new->description): ?>
+ <? if ($item->original("description") != $item->description): ?>
<tr>
<td><?= t("New Description:") ?></td>
- <td><?= p::clean($new->description) ?></td>
+ <td><?= p::clean($item->description) ?></td>
</tr>
- <? elseif (!empty($new->description)): ?>
+ <? elseif (!empty($item->description)): ?>
<tr>
<td><?= t("Description:") ?></td>
- <td><?= p::clean($new->description) ?></td>
+ <td><?= p::clean($item->description) ?></td>
</tr>
<? endif ?>
</table>
diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php
index 6792573d..898be509 100644
--- a/modules/organize/controllers/organize.php
+++ b/modules/organize/controllers/organize.php
@@ -279,8 +279,6 @@ class Organize_Controller extends Controller {
$item->rename($form->dirname->value);
$item->save();
- module::event("item_updated", $orig, $item);
-
if ($item->is_album()) {
log::success("content", "Updated album", "<a href=\"albums/$item->id\">view</a>");
$message = t("Saved album %album_title", array("album_title" => p::purify($item->title)));
@@ -322,8 +320,6 @@ class Organize_Controller extends Controller {
$item->sort_order = $form->direction->value;
$item->save();
- module::event("item_updated", $orig, $item);
-
log::success("content", "Updated album", "<a href=\"albums/$item->id\">view</a>");
$message = t("Saved album %album_title", array("album_title" => p::purify($item->title)));
print json_encode(array("form" => $form->__toString(), "message" => $message));
@@ -520,7 +516,7 @@ class Organize_Controller extends Controller {
break;
case "delete":
- return array("description" => t("Delete selected photos and albums"),
+ return array("description" => t("Delete selected photos / albums"),
"name" => t("Delete images in %name", array("name" => $item->title)),
"type" => "delete",
"runningMsg" => t("Delete images in progress"),
@@ -541,4 +537,4 @@ class Organize_Controller extends Controller {
throw new Exception("Operation '$operation' is not implmented");
}
}
-} \ No newline at end of file
+}
diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css
index 1e608beb..e58cd5a5 100644
--- a/modules/organize/css/organize.css
+++ b/modules/organize/css/organize.css
@@ -163,7 +163,6 @@
}
#gOrganizeEditHandleLeft {
- background-image: url(organize_edit_drawer.png);
background-color: #FFF;
float: left;
height: 30px;
@@ -200,7 +199,6 @@
#gOrganizeEditHandleRight {
background-color: #FFF;
- background-image: url(organize_edit_drawer.png);
background-position: -15px 0;
float: right;
height: 30px;
diff --git a/modules/organize/helpers/organize.php b/modules/organize/helpers/organize.php
index 9bf4e986..25284771 100644
--- a/modules/organize/helpers/organize.php
+++ b/modules/organize/helpers/organize.php
@@ -43,7 +43,7 @@ class organize_Core {
$sortPane->hidden("item[]")->value($item->id);
$sortPane->dropdown("column", array("id" => "gAlbumSortColumn"))
->label(t("Sort by"))
- ->options(array("weight" => t("Default"),
+ ->options(array("weight" => t("Order Added"),
"captured" => t("Capture Date"),
"created" => t("Creation Date"),
"title" => t("Title"),
diff --git a/modules/organize/helpers/organize_menu.php b/modules/organize/helpers/organize_event.php
index 850c1eab..99a28673 100644
--- a/modules/organize/helpers/organize_menu.php
+++ b/modules/organize/helpers/organize_event.php
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class organize_menu {
- static function site($menu, $theme) {
+class organize_event_Core {
+ static function site_menu($menu, $theme) {
$item = $theme->item();
if ($item && access::can("edit", $item) && $item->is_album()) {
diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php
index 02f1f589..e4feba2b 100644
--- a/modules/organize/helpers/organize_theme.php
+++ b/modules/organize/helpers/organize_theme.php
@@ -20,8 +20,8 @@
class organize_theme {
static function head($theme) {
// @tdo remove the addition css and organize.js (just here to test)
- $theme->script("modules/organize/js/organize_init.js");
- $theme->script("modules/organize/js/organize.js");
- $theme->css("modules/organize/css/organize.css");
+ $theme->script("organize_init.js");
+ $theme->script("organize.js");
+ $theme->css("organize.css");
}
}
diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js
index f10cbcc9..31657d3a 100644
--- a/modules/organize/js/organize.js
+++ b/modules/organize/js/organize.js
@@ -391,7 +391,7 @@ function organize_dialog_init() {
$(".gBranchText").droppable(treeDroppable);
$(".gBranchText").click(organizeOpenFolder);
retrieveMicroThumbs(item_id);
- //showLoading("#gDialog");
+ //$.gallery_show_loading("#gDialog");
$("#gMicroThumbPanel").droppable(thumbDroppable);
$("#gMicroThumbPanel").selectable(selectable);
diff --git a/modules/organize/js/organize_init.js b/modules/organize/js/organize_init.js
index ed036fdb..30bc78dd 100644
--- a/modules/organize/js/organize_init.js
+++ b/modules/organize/js/organize_init.js
@@ -17,7 +17,7 @@ $("document").ready(function() {
zIndex: 75
});
- //showLoading("#gDialog");
+ //$.gallery_show_loading("#gDialog");
$.get(href, function(data) {
$("#gDialog").html(data);
diff --git a/modules/organize/module.info b/modules/organize/module.info
index b3ae94a3..5c6b1de0 100644
--- a/modules/organize/module.info
+++ b/modules/organize/module.info
@@ -1,3 +1,3 @@
-name = Organize
-description = Organize your gallery by apply tags or moving images
+name = "Organize"
+description = "Organize your gallery by apply tags or moving images"
version = 1
diff --git a/modules/organize/views/organize.html.php b/modules/organize/views/organize.html.php
index 65d67d04..1686d255 100644
--- a/modules/organize/views/organize.html.php
+++ b/modules/organize/views/organize.html.php
@@ -33,7 +33,7 @@ var CONFIRM_DELETE = "<?= t("Do you really want to delete the selected albums an
<?= $album_tree ?>
</div>
<div id="gMicroThumbPanel" class="yui-u"
- ref="<?= url::site("organize/content/__ITEM_ID__?width=__WIDTH__&height=__HEIGHT__&offset=__OFFSET__") ?>">
+ ref="<?= url::site("organize/content/__ITEM_ID__?width=__WIDTH__&amp;height=__HEIGHT__&amp;offset=__OFFSET__") ?>">
<ul id="gMicroThumbGrid"></ul>
</div>
<div id="gOrganizeEditDrawer" class="yui-u">
diff --git a/modules/organize/views/organize_button_pane.html.php b/modules/organize/views/organize_button_pane.html.php
index cd780d5e..c5839a44 100644
--- a/modules/organize/views/organize_button_pane.html.php
+++ b/modules/organize/views/organize_button_pane.html.php
@@ -46,5 +46,5 @@
<div id="gOrganizeEditHandleButtonsRight">
<a id="gMicroThumbSelectAll" href="#" ref="select-all" class="gButtonLink ui-corner-all ui-state-default"><?= t("Select all") ?></a>
<a id="gMicroThumbUnselectAll" href="#" ref="unselect-all" style="display: none" class="gButtonLink ui-corner-all ui-state-default"><?= t("Deselect all") ?></a>
- <a id="gMicroThumbDone" href="#" ref="done" class="gButtonLink ui-corner-all ui-state-default"><?= t("Done") ?></a>
+ <a id="gMicroThumbDone" href="#" ref="done" class="gButtonLink ui-corner-all ui-state-default"><?= t("Close") ?></a>
</div>
diff --git a/modules/recaptcha/helpers/recaptcha_event.php b/modules/recaptcha/helpers/recaptcha_event.php
index 932ddee6..d23a0c74 100644
--- a/modules/recaptcha/helpers/recaptcha_event.php
+++ b/modules/recaptcha/helpers/recaptcha_event.php
@@ -23,4 +23,12 @@ class recaptcha_event_Core {
$form->add_comment->recaptcha("recaptcha")->label("")->id("gRecaptcha");
}
}
+
+ static function admin_menu($menu, $theme) {
+ $menu->get("settings_menu")
+ ->append(Menu::factory("link")
+ ->id("recaptcha")
+ ->label(t("reCAPTCHA"))
+ ->url(url::site("admin/recaptcha")));
+ }
}
diff --git a/modules/recaptcha/helpers/recaptcha_menu.php b/modules/recaptcha/helpers/recaptcha_menu.php
deleted file mode 100644
index 047abf8f..00000000
--- a/modules/recaptcha/helpers/recaptcha_menu.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-2009 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 recaptcha_menu_Core {
- static function admin($menu, $theme) {
- $menu->get("settings_menu")
- ->append(Menu::factory("link")
- ->id("recaptcha")
- ->label(t("reCAPTCHA"))
- ->url(url::site("admin/recaptcha")));
- }
-}
diff --git a/modules/recaptcha/libraries/Form_Recaptcha.php b/modules/recaptcha/libraries/Form_Recaptcha.php
index 4c0c4997..f4e9d4ac 100644
--- a/modules/recaptcha/libraries/Form_Recaptcha.php
+++ b/modules/recaptcha/libraries/Form_Recaptcha.php
@@ -28,7 +28,7 @@ class Form_Recaptcha_Core extends Form_Input {
public function __construct($name) {
parent::__construct($name);
$this->error_messages("incorrect-captcha-sol",
- t("The values supplied to recaptcha are incorrect."));
+ t("The values supplied to reCAPTCHA are incorrect."));
$this->error_messages("invalid-site-private-key", t("The site private key is incorrect."));
}
diff --git a/modules/recaptcha/module.info b/modules/recaptcha/module.info
index 9f44648a..cfa1bf7a 100644
--- a/modules/recaptcha/module.info
+++ b/modules/recaptcha/module.info
@@ -1,3 +1,3 @@
-name = reCAPTCHA
+name = "reCAPTCHA"
description = "reCAPTCHA displays a graphical verification that protects the input form from abuse from 'bots,' or automated programs usually written to generate spam (http://recaptcha.net)."
version = 1
diff --git a/modules/recaptcha/views/admin_recaptcha.html.php b/modules/recaptcha/views/admin_recaptcha.html.php
index 9c2911ef..43b4da8a 100644
--- a/modules/recaptcha/views/admin_recaptcha.html.php
+++ b/modules/recaptcha/views/admin_recaptcha.html.php
@@ -14,7 +14,7 @@
<div id="gAdminRecaptchaTest" class="gBlock">
<h2> <?= t("reCAPTCHA Test") ?> </h2>
<p>
- <?= t("If you see a captcha form below, then reCAPTCHA is functioning properly.") ?>
+ <?= t("If you see a CAPTCHA form below, then reCAPTCHA is functioning properly.") ?>
</p>
<div id="gRecaptcha"/>
diff --git a/modules/rss/module.info b/modules/rss/module.info
index ffd26192..81ee7848 100644
--- a/modules/rss/module.info
+++ b/modules/rss/module.info
@@ -1,3 +1,3 @@
-name = RSS
-description = Provide a RSS feeds
+name = "RSS"
+description = "Provide a RSS feeds"
version = 1
diff --git a/modules/search/helpers/search.php b/modules/search/helpers/search.php
index ea8dad81..355c4493 100644
--- a/modules/search/helpers/search.php
+++ b/modules/search/helpers/search.php
@@ -24,7 +24,7 @@ class search_Core {
if (!user::active()->admin) {
foreach (user::group_ids() as $id) {
- $fields[] = "`view_$id` = " . access::ALLOW;
+ $fields[] = "`view_$id` = TRUE"; // access::ALLOW
}
$access_sql = "AND (" . join(" AND ", $fields) . ")";
} else {
@@ -50,6 +50,9 @@ class search_Core {
return array($count, new ORM_Iterator(ORM::factory("item"), $db->query($query)));
}
+ /**
+ * @return string An error message suitable for inclusion in the task log
+ */
static function check_index() {
list ($remaining) = search::stats();
if ($remaining) {
@@ -61,19 +64,14 @@ class search_Core {
}
static function update($item) {
- $data = array();
+ $data = new ArrayObject();
$record = ORM::factory("search_record")->where("item_id", $item->id)->find();
if (!$record->loaded) {
$record->item_id = $item->id;
}
- foreach (module::active() as $module) {
- $class_name = "{$module->name}_search";
- if (method_exists($class_name, "item_index_data")) {
- $data[] = call_user_func(array($class_name, "item_index_data"), $record->item());
- }
- }
- $record->data = join(" ", $data);
+ module::event("item_index_data", $record->item(), $data);
+ $record->data = join(" ", (array)$data);
$record->dirty = 0;
$record->save();
}
diff --git a/modules/search/helpers/search_event.php b/modules/search/helpers/search_event.php
index b9657395..836bbe15 100644
--- a/modules/search/helpers/search_event.php
+++ b/modules/search/helpers/search_event.php
@@ -22,11 +22,11 @@ class search_event_Core {
search::update($item);
}
- static function item_updated($old_item, $new_item) {
- search::update($new_item);
+ static function item_updated($original, $new) {
+ search::update($new);
}
- static function item_before_delete($item) {
+ static function item_deleted($item) {
ORM::factory("search_record")
->where("item_id", $item->id)
->delete_all();
@@ -35,9 +35,4 @@ class search_event_Core {
static function item_related_update($item) {
search::update($item);
}
-
- static function item_related_update_batch($sql) {
- $db = Database::instance();
- $db->query("UPDATE {search_records} SET `dirty` = 1 WHERE item_id IN ($sql)");
- }
}
diff --git a/modules/search/helpers/search_installer.php b/modules/search/helpers/search_installer.php
index cd253be4..10d8211f 100644
--- a/modules/search/helpers/search_installer.php
+++ b/modules/search/helpers/search_installer.php
@@ -28,7 +28,7 @@ class search_installer {
PRIMARY KEY (`id`),
KEY(`item_id`),
FULLTEXT INDEX (`data`))
- ENGINE=MyISAM DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("search", 1);
}
diff --git a/modules/search/helpers/search_task.php b/modules/search/helpers/search_task.php
index 876661e4..5643573a 100644
--- a/modules/search/helpers/search_task.php
+++ b/modules/search/helpers/search_task.php
@@ -39,34 +39,40 @@ class search_task_Core {
}
static function update_index($task) {
- $completed = $task->get("completed", 0);
+ try {
+ $completed = $task->get("completed", 0);
- $start = microtime(true);
- foreach (ORM::factory("item")
- ->join("search_records", "items.id", "search_records.item_id", "left")
- ->where("search_records.item_id", null)
- ->orwhere("search_records.dirty", 1)
- ->find_all() as $item) {
- if (microtime(true) - $start > 1.5) {
- break;
- }
+ $start = microtime(true);
+ foreach (ORM::factory("item")
+ ->join("search_records", "items.id", "search_records.item_id", "left")
+ ->where("search_records.item_id", null)
+ ->orwhere("search_records.dirty", 1)
+ ->find_all() as $item) {
+ if (microtime(true) - $start > 1.5) {
+ break;
+ }
- search::update($item);
- $completed++;
- }
+ search::update($item);
+ $completed++;
+ }
- list ($remaining, $total, $percent) = search::stats();
- $task->set("completed", $completed);
- if ($remaining == 0 || !($remaining + $completed)) {
+ list ($remaining, $total, $percent) = search::stats();
+ $task->set("completed", $completed);
+ if ($remaining == 0 || !($remaining + $completed)) {
+ $task->done = true;
+ $task->state = "success";
+ site_status::clear("search_index_out_of_date");
+ $task->percent_complete = 100;
+ } else {
+ $task->percent_complete = round(100 * $completed / ($remaining + $completed));
+ }
+ $task->status = t2("one record updated, index is %percent% up-to-date",
+ "%count records updated, index is %percent% up-to-date",
+ $completed, array("percent" => $percent));
+ } catch (Exception $e) {
$task->done = true;
- $task->state = "success";
- site_status::clear("search_index_out_of_date");
- $task->percent_complete = 100;
- } else {
- $task->percent_complete = round(100 * $completed / ($remaining + $completed));
+ $task->state = "error";
+ $task->status = $e->getMessage();
}
- $task->status = t2("one record updated, index is %percent% up-to-date",
- "%count records updated, index is %percent% up-to-date",
- $completed, array("percent" => $percent));
}
}
diff --git a/modules/search/module.info b/modules/search/module.info
index b286ab6c..f417c4fa 100644
--- a/modules/search/module.info
+++ b/modules/search/module.info
@@ -1,3 +1,3 @@
-name = Search
-description = Allows users to search their Gallery
+name = "Search"
+description = "Allows users to search their Gallery"
version = 1
diff --git a/modules/server_add/controllers/admin_server_add.php b/modules/server_add/controllers/admin_server_add.php
index a30215b8..30109f42 100644
--- a/modules/server_add/controllers/admin_server_add.php
+++ b/modules/server_add/controllers/admin_server_add.php
@@ -38,10 +38,7 @@ class Admin_Server_Add_Controller extends Admin_Controller {
$path = $form->add_path->path->value;
$paths[$path] = 1;
module::set_var("server_add", "authorized_paths", serialize($paths));
- $form->add_path->inputs->path->value = "";
-
message::success(t("Added path %path", array("path" => p::clean($path))));
-
server_add::check_config($paths);
url::redirect("admin/server_add");
} else {
@@ -61,11 +58,12 @@ class Admin_Server_Add_Controller extends Admin_Controller {
$path = $this->input->get("path");
$paths = unserialize(module::get_var("server_add", "authorized_paths"));
- unset($paths[$path]);
- message::success(t("Removed path %path", array("path" => p::clean($path))));
- module::set_var("server_add", "authorized_paths", serialize($paths));
- server_add::check_config($paths);
-
+ if (isset($paths[$path])) {
+ unset($paths[$path]);
+ message::success(t("Removed path %path", array("path" => p::clean($path))));
+ module::set_var("server_add", "authorized_paths", serialize($paths));
+ server_add::check_config($paths);
+ }
url::redirect("admin/server_add");
}
diff --git a/modules/server_add/controllers/server_add.php b/modules/server_add/controllers/server_add.php
index 05ea5058..bfb96506 100644
--- a/modules/server_add/controllers/server_add.php
+++ b/modules/server_add/controllers/server_add.php
@@ -17,258 +17,244 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class Server_Add_Controller extends Controller {
- public function index($id) {
+class Server_Add_Controller extends Admin_Controller {
+ public function browse($id) {
$paths = unserialize(module::get_var("server_add", "authorized_paths"));
-
- if (!user::active()->admin) {
- access::forbidden();
+ foreach (array_keys($paths) as $path) {
+ $files[] = $path;
}
$item = ORM::factory("item", $id);
$view = new View("server_add_tree_dialog.html");
- $view->action = url::abs_site("__ARGS__/{$id}__TASK_ID__?csrf=" . access::csrf_token());
- $view->parents = $item->parents();
- $view->album_title = $item->title;
-
- $tree = new View("server_add_tree.html");
- $tree->data = array();
- $tree->checked = false;
- $tree->tree_id = "tree_$id";
- foreach (array_keys($paths) as $path) {
- $tree->data[$path] = array("path" => $path, "is_dir" => true);
- }
- $view->tree = $tree->__toString();
+ $view->item = $item;
+ $view->tree = new View("server_add_tree.html");
+ $view->tree->files = $files;
+ $view->tree->parents = array();
print $view;
}
public function children() {
- if (!user::active()->admin) {
- access::forbidden();
- }
+ $path = $this->input->get("path");
- $paths = unserialize(module::get_var("server_add", "authorized_paths"));
- $path_valid = false;
- $path = $this->input->post("path");
- $checked = $this->input->post("checked") == "true";
+ $tree = new View("server_add_tree.html");
+ $tree->files = array();
+ $tree->parents = array();
- foreach (array_keys($paths) as $valid_path) {
- if ($path_valid = strpos($path, $valid_path) === 0) {
- break;
+ // Make a tree with the parents back up to the authorized path, and all the children under the
+ // current path.
+ if (server_add::is_valid_path($path)) {
+ $tree->parents[] = $path;
+ while (server_add::is_valid_path(dirname($tree->parents[0]))) {
+ array_unshift($tree->parents, dirname($tree->parents[0]));
}
- }
- if (empty($path_valid)) {
- throw new Exception("@todo BAD_PATH");
- }
- if (!is_readable($path) || is_link($path)) {
- kohana::show_404();
- }
+ foreach (glob("$path/*") as $file) {
+ if (!is_readable($file)) {
+ continue;
+ }
+ if (!is_dir($file)) {
+ $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
+ if (!in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4"))) {
+ continue;
+ }
+ }
- $tree = new View("server_add_tree.html");
- $tree->data = $this->_get_children($path);
- $tree->checked = $checked;
- $tree->tree_id = "tree_" . md5($path);
+ $tree->files[] = $file;
+ }
+ } else {
+ // Missing or invalid path; print out the list of authorized path
+ $paths = unserialize(module::get_var("server_add", "authorized_paths"));
+ foreach (array_keys($paths) as $path) {
+ $tree->files[] = $path;
+ }
+ }
print $tree;
}
- function start($id) {
- if (!user::active()->admin) {
- access::forbidden();
- }
+ /**
+ * Begin the task of adding photos.
+ */
+ public function start() {
access::verify_csrf();
+ $item = ORM::factory("item", Input::instance()->get("item_id"));
- $item = ORM::factory("item", $id);
- $paths = unserialize(module::get_var("server_add", "authorized_paths"));
- $input_files = $this->input->post("path");
- $collapsed = $this->input->post("collapsed");
- $files = array();
- $total_count = 0;
- foreach (array_keys($paths) as $valid_path) {
- $path_length = strlen($valid_path);
- foreach ($input_files as $key => $path) {
- if (!empty($path)) {
- if ($valid_path != $path && strpos($path, $valid_path) === 0) {
- $relative_path = substr(dirname($path), $path_length);
- $name = basename($path);
- $files[$valid_path][] = array("path" => $relative_path,
- "parent_id" => $id, "name" => basename($path),
- "type" => is_dir($path) ? "album" : "file");
- $total_count++;
- }
- if ($collapsed[$key] === "true") {
- $total_count += $this->_select_children($id, $valid_path, $path, $files[$valid_path]);
- }
- unset($input_files[$key]);
- unset($collapsed[$key]);
- }
+ foreach (Input::instance()->post("paths") as $path) {
+ if (server_add::is_valid_path($path)) {
+ $paths[] = array($path, null);
}
}
- if ($total_count == 0) {
- print json_encode(array("result" => "success",
- "url" => "",
- "task" => array(
- "id" => -1, "done" => 1, "percent_complete" => 100,
- "status" => t("No eligible files, import cancelled"))));
- return;
- }
-
$task_def = Task_Definition::factory()
- ->callback("server_add_task::add_from_server")
+ ->callback("Server_Add_Controller::add")
->description(t("Add photos or movies from the local server"))
->name(t("Add from server"));
- $task = task::create($task_def, array("item_id" => $id, "next_path" => 0, "files" => $files,
- "counter" => 0, "position" => 0, "total" => $total_count));
+ $task = task::create($task_def, array("item_id" => $item->id, "queue" => $paths));
- batch::start();
- print json_encode(array("result" => "started",
- "url" => url::site("server_add/add_photo/{$task->id}?csrf=" .
- access::csrf_token()),
- "task" => array(
- "id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "status" => $task->status,
- "done" => $task->done)));
+ print json_encode(
+ array("result" => "started",
+ "status" => $task->status,
+ "url" => url::site("server_add/run/$task->id?csrf=" . access::csrf_token())));
}
- function add_photo($task_id) {
- if (!user::active()->admin) {
- access::forbidden();
- }
+ /**
+ * Run the task of adding photos
+ */
+ function run($task_id) {
access::verify_csrf();
- $task = task::run($task_id);
- // @todo the task is already run... its a little late to check the access
- if (!$task->loaded || $task->owner_id != user::active()->id) {
- access::forbidden();
- }
-
- if ($task->done) {
- switch ($task->state) {
- case "success":
- message::success(t("Add from server completed"));
- break;
-
- case "error":
- message::warning(t("Add from server completed with errors"));
- break;
- }
- print json_encode(array("result" => "success",
- "task" => array(
- "id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "status" => $task->status,
- "done" => $task->done)));
-
- } else {
- print json_encode(array("result" => "in_progress",
- "task" => array(
- "id" => $task->id,
- "percent_complete" => $task->percent_complete,
- "status" => $task->status,
- "done" => $task->done)));
- }
- }
-
- public function finish($id, $task_id) {
- if (!user::active()->admin) {
- access::forbidden();
- }
- access::verify_csrf();
$task = ORM::factory("task", $task_id);
-
if (!$task->loaded || $task->owner_id != user::active()->id) {
access::forbidden();
}
- if (!$task->done) {
- message::warning(t("Add from server was cancelled prior to completion"));
- }
-
- batch::stop();
- print json_encode(array("result" => "success"));
+ $task = task::run($task_id);
+ print json_encode(array("done" => $task->done,
+ "status" => $task->status,
+ "percent_complete" => $task->percent_complete));
}
- public function pause($id, $task_id) {
- if (!user::active()->admin) {
- access::forbidden();
- }
- access::verify_csrf();
- $task = ORM::factory("task", $task_id);
- if (!$task->loaded || $task->owner_id != user::active()->id) {
- access::forbidden();
- }
+ /**
+ * This is the task code that adds photos and albums. It first examines all the target files
+ * and creates a set of Server_Add_File_Models, then runs through the list of models and adds
+ * them one at a time.
+ */
+ static function add($task) {
+ $mode = $task->get("mode", "init");
+ $start = microtime(true);
- message::warning(t("Add from server was cancelled prior to completion"));
- batch::stop();
- print json_encode(array("result" => "success"));
- }
+ switch ($mode) {
+ case "init":
+ $task->set("mode", "build-file-list");
+ $task->percent_complete = 0;
+ $task->status = t("Starting up");
+ batch::start();
+ break;
- private function _select_children($id, $valid_path, $path, &$files) {
- $count = 0;
- $children = new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($path),
- RecursiveIteratorIterator::SELF_FIRST);
+ case "build-file-list": // 0% to 10%
+ // We can't fit an arbitrary number of paths in a task, so store them in a separate table.
+ // Don't use an iterator here because we can't get enough control over it when we're dealing
+ // with a deep hierarchy and we don't want to go over our time quota. The queue is in the
+ // form [path, parent_id] where the parent_id refers to another Server_Add_File_Model. We
+ // have this extra level of abstraction because we don't know its Item_Model id yet.
+ $queue = $task->get("queue");
+ while ($queue && microtime(true) - $start < 0.5) {
+ list($file, $parent_entry_id) = array_shift($queue);
+ $entry = ORM::factory("server_add_file");
+ $entry->task_id = $task->id;
+ $entry->file = $file;
+ $entry->parent_id = $parent_entry_id;
+ $entry->save();
- $path_length = strlen($valid_path);
- foreach($children as $name => $file){
- if ($file->isLink()) {
- continue;
- }
- $filename = $file->getFilename();
- if ($filename[0] != ".") {
- if ($file->isDir()) {
- $relative_path = substr(dirname($file->getPathname()), $path_length);
- $files[] = array("path" => $relative_path,
- "parent_id" => $id, "name" => $filename, "type" => "album");
- $count++;
- } else {
- $extension = strtolower(substr(strrchr($filename, '.'), 1));
- if ($file->isReadable() &&
- in_array($extension, array("gif", "jpeg", "jpg", "png", "flv", "mp4"))) {
- $relative_path = substr(dirname($file->getPathname()), $path_length);
- $files[] = array("path" => $relative_path,
- "parent_id" => $id, "name" => $filename, "type" => "file");
- $count++;
+ foreach (glob("$file/*") as $child) {
+ if (is_dir($child)) {
+ $queue[] = array($child, $entry->id);
+ } else {
+ $ext = strtolower(pathinfo($child, PATHINFO_EXTENSION));
+ if (in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4")) &&
+ filesize($child) > 0) {
+ $child_entry = ORM::factory("server_add_file");
+ $child_entry->task_id = $task->id;
+ $child_entry->file = $child;
+ $child_entry->parent_id = $entry->id;
+ $child_entry->save();
+ }
}
}
}
- }
+ // We have no idea how long this can take because we have no idea how deep the tree
+ // hierarchy rabbit hole goes. Leave ourselves room here for 100 iterations and don't go
+ // over 10% in percent_complete.
+ $task->set("queue", $queue);
+ $task->percent_complete = min($task->percent_complete + 0.1, 10);
+ $task->status = t2("Found one file", "Found %count files",
+ Database::instance()
+ ->where("task_id", $task->id)
+ ->count_records("server_add_files"));
- return $count;
- }
+ if (!$queue) {
+ $task->set("mode", "add-files");
+ $task->set(
+ "total_files", database::instance()->count_records(
+ "server_add_files", array("task_id" => $task->id)));
+ $task->percent_complete = 10;
+ }
+ break;
+
+ case "add-files": // 10% to 100%
+ $completed_files = $task->get("completed_files", 0);
+ $total_files = $task->get("total_files");
- private function _get_children($path) {
- $directory_list = $file_list = array();
- $files = new DirectoryIterator($path);
- foreach ($files as $file) {
- if ($file->isDot() || $file->isLink()) {
- continue;
+ // Ordering by id ensures that we add them in the order that we created the entries, which
+ // will create albums first. Ignore entries which already have an Item_Model attached,
+ // they're done.
+ $entries = ORM::factory("server_add_file")
+ ->where("task_id", $task->id)
+ ->where("item_id", null)
+ ->orderby("id", "ASC")
+ ->limit(10)
+ ->find_all();
+ if ($entries->count() == 0) {
+ // Out of entries, we're done.
+ $task->set("mode", "done");
}
- $filename = $file->getFilename();
- if ($filename[0] != ".") {
- if ($file->isDir()) {
- $directory_list[$filename] = array("path" => $file->getPathname(), "is_dir" => true);
+
+ $owner_id = user::active()->id;
+ foreach ($entries as $entry) {
+ if (microtime(true) - $start > 0.5) {
+ break;
+ }
+
+ // Look up the parent item for this entry. By now it should exist, but if none was
+ // specified, then this belongs as a child of the current item.
+ $parent_entry = ORM::factory("server_add_file", $entry->parent_id);
+ if (!$parent_entry->loaded) {
+ $parent = ORM::factory("item", $task->get("item_id"));
} else {
- $extension = strtolower(substr(strrchr($filename, '.'), 1));
- if ($file->isReadable() &&
- in_array($extension, array("gif", "jpeg", "jpg", "png", "flv", "mp4"))) {
- $file_list[$filename] = array("path" => $file->getPathname(), "is_dir" => false);
+ $parent = ORM::factory("item", $parent_entry->item_id);
+ }
+
+ $name = basename($entry->file);
+ $title = item::convert_filename_to_title($name);
+ if (is_dir($entry->file)) {
+ $album = album::create($parent, $name, $title, null, $owner_id);
+ $entry->item_id = $album->id;
+ } else {
+ $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION));
+ if (in_array($extension, array("gif", "png", "jpg", "jpeg"))) {
+ $photo = photo::create($parent, $entry->file, $name, $title, null, $owner_id);
+ $entry->item_id = $photo->id;
+ } else if (in_array($extension, array("flv", "mp4"))) {
+ $movie = movie::create($parent, $entry->file, $name, $title, null, $owner_id);
+ $entry->item_id = $movie->id;
+ } else {
+ // This should never happen, because we don't add stuff to the list that we can't
+ // process. But just in, case.. set this to a non-null value so that we skip this
+ // entry.
+ $entry->item_id = 0;
+ $task->log("Skipping unknown file type: $entry->file");
}
}
- }
- }
- ksort($directory_list);
- ksort($file_list);
+ $completed_files++;
+ $entry->save();
+ }
+ $task->set("completed_files", $completed_files);
+ $task->status = t("Adding photos / albums (%completed of %total)",
+ array("completed" => $completed_files,
+ "total" => $total_files));
+ $task->percent_complete = 10 + 100 * ($completed_files / $total_files);
+ break;
- // We can't use array_merge here because if a file name is numeric, it will
- // get renumbered, so lets do it ourselves
- foreach ($file_list as $file => $fileinfo) {
- $directory_list[$file] = $fileinfo;
+ case "done":
+ batch::stop();
+ $task->done = true;
+ $task->state = "success";
+ $task->percent_complete = 100;
+ ORM::factory("server_add_file")->where("task_id", $task->id)->delete_all();
+ message::info(t2("Successfully added one photo / album",
+ "Successfully added %count photos / albums",
+ $task->get("completed_files")));
}
- return $directory_list;
}
-} \ No newline at end of file
+}
diff --git a/modules/server_add/helpers/server_add.php b/modules/server_add/helpers/server_add.php
index f75a09d2..74f51ad9 100644
--- a/modules/server_add/helpers/server_add.php
+++ b/modules/server_add/helpers/server_add.php
@@ -31,4 +31,19 @@ class server_add_Core {
site_status::clear("server_add_configuration");
}
}
+
+ static function is_valid_path($path) {
+ if (!is_readable($path) || is_link($path)) {
+ return false;
+ }
+
+ $authorized_paths = unserialize(module::get_var("server_add", "authorized_paths"));
+ foreach (array_keys($authorized_paths) as $valid_path) {
+ if (strpos($path, $valid_path) === 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/modules/server_add/helpers/server_add_menu.php b/modules/server_add/helpers/server_add_event.php
index 23878913..b53e72d1 100644
--- a/modules/server_add/helpers/server_add_menu.php
+++ b/modules/server_add/helpers/server_add_event.php
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class server_add_menu_Core {
- static function admin($menu, $theme) {
+class server_add_event_Core {
+ static function admin_menu($menu, $theme) {
$menu->get("settings_menu")
->append(Menu::factory("link")
->id("server_add")
@@ -26,7 +26,7 @@ class server_add_menu_Core {
->url(url::site("admin/server_add")));
}
- static function site($menu, $theme) {
+ static function site_menu($menu, $theme) {
$item = $theme->item();
$paths = unserialize(module::get_var("server_add", "authorized_paths"));
@@ -38,7 +38,7 @@ class server_add_menu_Core {
$server_add = Menu::factory("dialog")
->id("server_add")
->label(t("Add from server"))
- ->url(url::site("server_add/index/$item->id"));
+ ->url(url::site("server_add/browse/$item->id"));
$add_photos_item = $menu->get("add_photos_item");
$add_photos_menu = $menu->get("add_photos_menu");
diff --git a/modules/server_add/helpers/server_add_installer.php b/modules/server_add/helpers/server_add_installer.php
index c9d92e69..c3c1572d 100644
--- a/modules/server_add/helpers/server_add_installer.php
+++ b/modules/server_add/helpers/server_add_installer.php
@@ -19,10 +19,38 @@
*/
class server_add_installer {
static function install() {
- module::set_version("server_add", 1);
+ $db = Database::instance();
+ $db->query("CREATE TABLE {server_add_files} (
+ `id` int(9) NOT NULL auto_increment,
+ `file` varchar(255) NOT NULL,
+ `item_id` int(9),
+ `parent_id` int(9),
+ `task_id` int(9) NOT NULL,
+ PRIMARY KEY (`id`))
+ DEFAULT CHARSET=utf8;");
+ module::set_version("server_add", 3);
server_add::check_config();
}
+ static function upgrade($version) {
+ $db = Database::instance();
+ if ($version == 1) {
+ $db->query("CREATE TABLE {server_add_files} (
+ `id` int(9) NOT NULL auto_increment,
+ `task_id` int(9) NOT NULL,
+ `file` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`))
+ DEFAULT CHARSET=utf8;");
+ module::set_version("server_add", $version = 2);
+ }
+
+ if ($version == 2) {
+ $db->query("ALTER TABLE {server_add_files} ADD COLUMN `item_id` int(9)");
+ $db->query("ALTER TABLE {server_add_files} ADD COLUMN `parent_id` int(9)");
+ module::set_version("server_add", $version = 3);
+ }
+ }
+
static function deactivate() {
site_status::clear("server_add_configuration");
}
diff --git a/modules/server_add/helpers/server_add_task.php b/modules/server_add/helpers/server_add_task.php
deleted file mode 100644
index 0482b47c..00000000
--- a/modules/server_add/helpers/server_add_task.php
+++ /dev/null
@@ -1,85 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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 server_add_task_Core {
- static function available_tasks() {
- // Return empty array so nothing appears in the maintenance screen
- return array();
- }
-
- static function add_from_server($task) {
- $context = unserialize($task->context);
- try {
- $paths = array_keys(unserialize(module::get_var("server_add", "authorized_paths")));
- $path = $paths[$context["next_path"]];
- if (!empty($context["files"][$path])) {
- $file = $context["files"][$path][$context["position"]];
- $parent = ORM::factory("item", $file["parent_id"]);
- access::required("add", $parent);
- if (!$parent->is_album()) {
- throw new Exception("@todo BAD_ALBUM");
- }
-
- $name = $file["name"];
- if ($file["type"] == "album") {
- $album = ORM::factory("item")
- ->where("name", $name)
- ->where("parent_id", $parent->id)
- ->find();
- if (!$album->loaded) {
- $album = album::create($parent, $name, $name, null, user::active()->id);
- }
- // Now that we have a new album. Go through the remaining files to import and change the
- // parent_id of any file that has the same relative path as this album's path.
- $album_path = "{$file['path']}/$name";
- for ($idx = $context["position"] + 1; $idx < count($context["files"][$path]); $idx++) {
- if (strpos($context["files"][$path][$idx]["path"], $album_path) === 0) {
- $context["files"][$path][$idx]["parent_id"] = $album->id;
- }
- }
- } else {
- $extension = strtolower(substr(strrchr($name, '.'), 1));
- $source_path = "$path{$file['path']}/$name";
- $title = item::convert_filename_to_title($name);
- if (in_array($extension, array("flv", "mp4"))) {
- $movie = movie::create($parent, $source_path, $name, $title,
- null, user::active()->id);
- } else {
- $photo = photo::create($parent, $source_path, $name, $title,
- null, user::active()->id);
- }
- }
-
- $context["counter"]++;
- if (++$context["position"] >= count($context["files"][$path])) {
- $context["next_path"]++;
- $context["position"] = 0;
- }
- } else {
- $context["next_path"]++;
- }
- } catch(Exception $e) {
- $context["errors"][$path] = $e->getMessage();
- }
- $task->context = serialize($context);
- $task->state = "success";
- $task->percent_complete = ($context["counter"] / (float)$context["total"]) * 100;
- $task->done = $context["counter"] == (float)$context["total"];
- }
-} \ No newline at end of file
diff --git a/modules/server_add/helpers/server_add_theme.php b/modules/server_add/helpers/server_add_theme.php
index 02f99690..2ba2e167 100644
--- a/modules/server_add/helpers/server_add_theme.php
+++ b/modules/server_add/helpers/server_add_theme.php
@@ -20,20 +20,20 @@
class server_add_theme_Core {
static function head($theme) {
if (user::active()->admin) {
- $theme->script("modules/server_add/js/server_add.js");
+ $theme->script("server_add.js");
}
}
static function admin_head($theme) {
$head = array();
if (strpos(Router::$current_uri, "admin/server_add") !== false) {
- $theme->css("lib/jquery.autocomplete.css");
+ $theme->css("jquery.autocomplete.css");
$base = url::site("__ARGS__");
$csrf = access::csrf_token();
$head[] = "<script> var base_url = \"$base\"; var csrf = \"$csrf\";</script>";
- $theme->script("lib/jquery.autocomplete.js");
- $theme->script("modules/server_add/js/admin.js");
+ $theme->script("jquery.autocomplete.js");
+ $theme->script("admin.js");
}
return implode("\n", $head);
diff --git a/modules/server_add/js/server_add.js b/modules/server_add/js/server_add.js
index e2526dbe..fbd61dcc 100644
--- a/modules/server_add/js/server_add.js
+++ b/modules/server_add/js/server_add.js
@@ -1,205 +1,62 @@
-var paused = false;
-var task = null;
-
-$("#gServerAdd").ready(function() {
- init_server_add_form();
-});
-
-function init_server_add_form() {
- $("#gServerAdd #gServerAddButton").click(function(event) {
- do_add(this, event);
- });
- $("#gServerAdd #gServerPauseButton").click(function(event) {
- event.preventDefault();
- paused = true;
- });
- $(".gProgressBar").progressbar();
- $("#gServerAddTree ul").css("display", "block");
- $("#gServerAdd form").bind("form_closing", function(target) {
- if (task != null && !task.done) {
- $.ajax({async: false,
- success: function(data, textStatus) {
- document.location.reload();
- },
- dataType: "json",
- type: "POST",
- url: get_url("server_add/pause", task.id)
- });
- } else {
- document.location.reload();
- }
- });
- set_click_events();
-}
-
-function set_click_events() {
- $(".ui-icon").unbind("click");
- $(":checkbox").unbind("click");
- $(".ui-icon").click(function(event) {
- open_close_branch(this, event);
- });
-
- $("input[type=checkbox]").click(function(event) {
- checkbox_click(this);
- });
-}
-
-function open_close_branch(icon, event) {
- var parent = icon.parentNode;
- var closed = $(icon).hasClass("ui-icon-plus");
- var children = $(parent).find(".gCheckboxTree");
-
- if (closed) {
- if (children.length == 0) {
- load_children(icon);
- } else {
- toggle_branch("open", icon);
- }
+/**
+ * Manage file selection state.
+ */
+function select_file(li) {
+ $(li).toggleClass("selected");
+ if ($("#gServerAdd span.selected").length) {
+ $("#gServerAddAddButton").enable(true).removeClass("ui-state-disabled");
} else {
- toggle_branch("close", icon);
+ $("#gServerAddAddButton").enable(false).addClass("ui-state-disabled");
}
}
-function toggle_branch(direction, icon) {
- var parent = icon.parentNode;
- var branch = $(parent).children(".gServerAddChildren");
- $(branch).slideToggle("fast", function() {
- if (direction == "open") {
- $(icon).addClass("ui-icon-minus");
- $(icon).removeClass("ui-icon-plus");
- $(parent).removeClass("gCollapsed");
- } else {
- $(icon).addClass("ui-icon-plus");
- $(icon).removeClass("ui-icon-minus");
+/**
+ * Load a new directory
+ */
+function open_dir(path) {
+ $.ajax({
+ url: GET_CHILDREN_URL.replace("__PATH__", path),
+ success: function(data, textStatus) {
+ $("#gServerAddTree").html(data);
}
});
}
-function get_url(uri, task_id) {
- var url = $("#gServerAdd form").attr("action");
- url = url.replace("__ARGS__", uri);
- url = url.replace("__TASK_ID__", !task_id ? "" : "/" + task_id);
- return url;
-}
-
-function checkbox_click(checkbox) {
- var parent = $(checkbox).parents("li").get(0);
- var checked = $(checkbox).attr("checked");
- if (!$(parent).hasClass("gCollapsed")) {
- $(parent).find(".gCheckboxTree input[type=checkbox]").attr("checked", checked);
- }
- var checkboxes = $("#gServerAdd :checkbox[checked]");
- $("#gServerAdd form :submit").attr("disabled", checkboxes.length == 0);
-}
-
-function load_children(icon) {
- $("#gDialog").addClass("gDialogLoadingLarge");
- var parent = icon.parentNode;
- var checkbox = $(parent).find("input[type=checkbox]");
- var parms = "&path=" + $(checkbox).attr("value");
- parms += "&checked=" + $(checkbox).is(":checked");
- parms += "&collapsed=" + $(parent).hasClass("gCollapsed");
+function start_add() {
+ var paths = [];
+ $.each($("#gServerAdd span.selected"), function () {
+ paths.push($(this).attr("file"));
+ });
- $.ajax({success: function(data, textStatus) {
- $(parent).children(".gServerAddChildren").html(data);
- set_click_events();
- $("#gDialog").removeClass("gDialogLoadingLarge");
- toggle_branch("open", icon);
- },
- data: parms,
- dataType: "html",
- type: "POST",
- url: get_url("server_add/children")
+ $.ajax({
+ url: START_URL,
+ type: "POST",
+ async: false,
+ data: { "paths[]": paths },
+ dataType: "json",
+ success: function(data, textStatus) {
+ $("#gStatus").html(data.status);
+ $("#gServerAdd .gProgressBar").progressbar("value", data.percent_complete);
+ setTimeout(function() { run_add(data.url); }, 0);
+ }
});
+ return false;
}
-function do_add(submit, event) {
- event.preventDefault();
-
- $("#gServerAdd #gServerAddButton").hide();
- $("#gServerAdd #gServerPauseButton").show();
-
- var parms = "";
- if (!paused) {
- $(".gProgressBar").progressbar("value", 0);
- $(".gProgressBar").css("visibility", "visible");
- var check_list = $("#gServerAdd :checkbox[checked]");
-
- var paths = "";
- var collapsed = "";
- $.each(check_list, function () {
- var parent = $(this).parents("li")[0];
- paths += "&path[]=" + this.value;
- collapsed += "&collapsed[]=" + $(parent).hasClass("gCollapsed");
- });
- parms = paths + collapsed;
- }
- paused = false;
-
- $.ajax({async: false,
- data: parms,
+function run_add(url) {
+ $.ajax({
+ url: url,
+ async: false,
dataType: "json",
success: function(data, textStatus) {
- var done = data.task.done;
- if (done) {
- task = null;
- $("body").append("<div id='gNoFilesDialog'>" + data.task.status + "</div>");
-
- $("#gNoFilesDialog").dialog({modal: true,
- autoOpen: true,
- title: FILE_IMPORT_WARNING});
- $(".gProgressBar").css("visibility", "hidden");
- $("#gServerAdd #gServerAddButton").show();
- $("#gServerAdd #gServerPauseButton").hide();
- return;
- }
- task = data.task;
- var url = data.url;
- while (!done && !paused) {
- $.ajax({async: false,
- success: function(data, textStatus) {
- $(".gProgressBar").progressbar("value", data.task.percent_complete);
- done = data.task.done;
- },
- error: function(XMLHttpRequest, textStatus, errorThrown) {
- paused = true;
- display_upload_error(XMLHttpRequest.responseText);
- },
- dataType: "json",
- type: "POST",
- url: url
- });
- }
- if (!paused) {
- $.ajax({async: false,
- success: function(data, textStatus) {
- document.location.reload();
- },
- dataType: "json",
- type: "POST",
- url: get_url("server_add/finish", task.id)
- });
+ $("#gStatus").html(data.status);
+ $("#gServerAdd .gProgressBar").progressbar("value", data.percent_complete);
+ if (data.done) {
+ $("#gServerAddProgress").slideUp();
} else {
- $("#gServerAdd #gServerAddButton").show();
- $("#gServerAdd #gServerPauseButton").hide();
+ setTimeout(function() { run_add(url); }, 0);
}
- },
- type: "POST",
- url: get_url("server_add/start")
+ }
});
-
- return false;
-}
-
-function display_upload_error(error) {
- $("body").append("<div id=\"gServerAddError\" title=\"" + FATAL_ERROR + "\">" + error + "</div>");
- $("#gServerAddError").dialog({
- autoOpen: true,
- autoResize: false,
- modal: true,
- resizable: true,
- width: 610,
- height: $("#gDialog").height()
- });
}
diff --git a/modules/gallery/helpers/gallery_search.php b/modules/server_add/models/server_add_file.php
index 2a4029d3..8b1ed924 100644
--- a/modules/gallery/helpers/gallery_search.php
+++ b/modules/server_add/models/server_add_file.php
@@ -17,8 +17,5 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class gallery_search_Core {
- static function item_index_data($item) {
- return join(" ", array($item->description, $item->name, $item->title));
- }
+class Server_Add_File_Model extends ORM {
}
diff --git a/modules/server_add/module.info b/modules/server_add/module.info
index 04e2b2ba..23acab94 100644
--- a/modules/server_add/module.info
+++ b/modules/server_add/module.info
@@ -1,3 +1,3 @@
-name = Server Add
-description = Allows authorized users to load images directly from your web server
-version = 1
+name = "Server Add"
+description = "Allows authorized users to load images directly from your web server"
+version = 3
diff --git a/modules/server_add/views/admin_server_add.html.php b/modules/server_add/views/admin_server_add.html.php
index 588a9fca..30ab3536 100644
--- a/modules/server_add/views/admin_server_add.html.php
+++ b/modules/server_add/views/admin_server_add.html.php
@@ -11,7 +11,7 @@
<ul id="gPathList">
<? foreach ($paths as $id => $path): ?>
<li class="ui-icon-left">
- <a href="<?= url::site("admin/server_add/remove_path?path=$path&csrf=$csrf") ?>"
+ <a href="<?= url::site("admin/server_add/remove_path?path=$path&amp;csrf=$csrf") ?>"
id="icon_<?= $id?>"
class="gRemoveDir ui-icon ui-icon-trash">
X
diff --git a/modules/server_add/views/server_add_tree.html.php b/modules/server_add/views/server_add_tree.html.php
index 33047fb3..254a9da0 100644
--- a/modules/server_add/views/server_add_tree.html.php
+++ b/modules/server_add/views/server_add_tree.html.php
@@ -1,14 +1,41 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<script type="text/javascript">
-</script>
-<ul id="<?= $tree_id ?>" class="gCheckboxTree">
- <? foreach ($data as $file => $file_info): ?>
- <li class="<?= empty($file_info["is_dir"]) ? "gFile" : "gDirectory gCollapsed ui-icon-left" ?>">
- <? if (!empty($file_info["is_dir"])): ?>
- <span class="ui-icon ui-icon-plus"></span>
- <? endif ?>
- <label> <?= form::checkbox("checkbox[]", p::clean($file_info["path"]), $checked) . " " . p::clean($file) ?> </label>
- <div class="gServerAddChildren" style="display: none"></div>
- </li>
- <? endforeach ?>
-</ul>
+<li class="ui-icon-left">
+ <span class="ui-icon ui-icon-folder-open"></span>
+ <span ondblclick="open_dir('')">
+ <?= t("All") ?>
+ </span>
+ <ul>
+
+ <? foreach ($parents as $dir): ?>
+ <li class="ui-icon-left">
+ <span class="ui-icon ui-icon-folder-open"></span>
+ <span ondblclick="open_dir('<?= $dir ?>')">
+ <?= basename($dir) ?>
+ </span>
+ <ul>
+ <? endforeach ?>
+
+ <? foreach ($files as $file): ?>
+ <li class="ui-icon-left">
+ <span class="ui-icon <?= is_dir($file) ? "ui-icon-folder-collapsed" : "ui-icon-document" ?>"></span>
+ <span onclick="select_file(this)"
+ <? if (is_dir($file)): ?>
+ ondblclick="open_dir($(this).attr('file'))"
+ <? endif ?>
+ file="<?= $file ?>"
+ >
+ <?= p::clean(basename($file)) ?>
+ </span>
+ </li>
+ <? endforeach ?>
+ <? if (!$files): ?>
+ <li> <i> <?= t("empty") ?> </i> </li>
+ <? endif ?>
+
+ <? foreach ($parents as $dir): ?>
+ </ul>
+ </li>
+ <? endforeach ?>
+
+ </ul>
+</li>
diff --git a/modules/server_add/views/server_add_tree_dialog.html.php b/modules/server_add/views/server_add_tree_dialog.html.php
index 8b296987..431635f8 100644
--- a/modules/server_add/views/server_add_tree_dialog.html.php
+++ b/modules/server_add/views/server_add_tree_dialog.html.php
@@ -1,30 +1,57 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<script>
- var FATAL_ERROR = "<?= t("Fatal Error") ?>";
- var FILE_IMPORT_WARNING = "<?= t("Add from server warning") ?>";
- $("#gServerAdd").ready(function() {
- init_server_add_form();
- });
+<script type="text/javascript">
+ var GET_CHILDREN_URL = "<?= url::site("server_add/children?path=__PATH__") ?>";
+ var START_URL = "<?= url::site("server_add/start?item_id={$item->id}&csrf=$csrf") ?>";
</script>
+
<div id="gServerAdd">
- <h1 style="display: none;"><?= t("Add Photos to '%title'", array("title" => p::clean($album_title))) ?></h1>
+ <h1 style="display: none;"><?= t("Add Photos to '%title'", array("title" => p::purify($item->title))) ?></h1>
<p id="gDescription"><?= t("Photos will be added to album:") ?></p>
<ul class="gBreadcrumbs">
- <? foreach ($parents as $parent): ?>
- <li><?= p::clean($parent->title) ?></li>
+ <? foreach ($item->parents() as $parent): ?>
+ <li>
+ <?= p::purify($parent->title) ?>
+ </li>
<? endforeach ?>
- <li class="active"><?= p::clean($album_title) ?></li>
+ <li class="active">
+ <?= p::purify($item->title) ?>
+ </li>
</ul>
- <?= form::open($action, array("method" => "post")) ?>
- <div id="gServerAddTree" >
+ <ul id="gServerAddTree" class="gCheckboxTree">
<?= $tree ?>
+ </ul>
+
+ <div id="gServerAddProgress" style="display: none">
+ <div class="gProgressBar"></div>
+ <div id="gStatus"></div>
</div>
+
<span>
- <?= form::submit(array("id" => "gServerPauseButton", "name" => "add", "disabled" => true, "class" => "submit", "style" => "display:none"), t("Pause")) ?>
- <?= form::submit(array("id" => "gServerAddButton", "name" => "add", "disabled" => true, "class" => "submit"), t("Add")) ?>
+ <button id="gServerAddAddButton" class="ui-state-default ui-state-disabled ui-corner-all"
+ disabled="disabled">
+ <?= t("Add") ?>
+ </button>
+
+ <button id="gServerCloseButton" class="ui-state-default ui-corner-all">
+ <?= t("Close") ?>
+ </button>
</span>
- <?= form::close() ?>
- <div class="gProgressBar" style="visibility: hidden" ></div>
+
+ <script type="text/javascript">
+ $("#gServerAddAddButton").ready(function() {
+ $("#gServerAddAddButton").click(function(event) {
+ event.preventDefault();
+ $("#gServerAdd .gProgressBar").
+ progressbar().
+ progressbar("value", 0);
+ $("#gServerAddProgress").slideDown("fast", function() { start_add() });
+ });
+ $("#gServerCloseButton").click(function(event) {
+ $("#gDialog").dialog("close");
+ });
+ });
+ </script>
+
</div>
diff --git a/modules/slideshow/helpers/slideshow_menu.php b/modules/slideshow/helpers/slideshow_menu.php
deleted file mode 100644
index ee975d88..00000000
--- a/modules/slideshow/helpers/slideshow_menu.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.");
-/**
- * Gallery - a web based photo album viewer and editor
- * Copyright (C) 2000-2009 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 slideshow_menu_Core {
- static function album($menu, $theme) {
- $menu
- ->append(Menu::factory("link")
- ->id("slideshow")
- ->label(t("View slideshow"))
- ->url("javascript:PicLensLite.start(" .
- "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})")
- ->css_id("gSlideshowLink"));
- }
-
- static function photo($menu, $theme) {
- $menu
- ->append(Menu::factory("link")
- ->id("slideshow")
- ->label(t("View slideshow"))
- ->url("javascript:PicLensLite.start(" .
- "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})")
- ->css_id("gSlideshowLink"));
- }
-
- static function tag($menu, $theme) {
- $menu
- ->append(Menu::factory("link")
- ->id("slideshow")
- ->label(t("View slideshow"))
- ->url("javascript:PicLensLite.start(" .
- "{maxScale:0,feedUrl:PicLensLite.indexFeeds()[0].url})")
- ->css_id("gSlideshowLink"));
- }
-
-}
diff --git a/modules/slideshow/helpers/slideshow_theme.php b/modules/slideshow/helpers/slideshow_theme.php
index 125d175c..269a93ce 100644
--- a/modules/slideshow/helpers/slideshow_theme.php
+++ b/modules/slideshow/helpers/slideshow_theme.php
@@ -20,7 +20,7 @@
class slideshow_theme_Core {
static function head($theme) {
$proto = (empty($_SERVER["HTTPS"]) || $_SERVER["HTTPS"] === "off") ? "http" : "https";
- return "<script src=\"$proto://lite.piclens.com/current/piclens_optimized.js\"" .
+ return "<script src=\"$proto://lite.piclens.com/current/piclens_optimized.js\" " .
"type=\"text/javascript\"></script>";
}
}
diff --git a/modules/slideshow/module.info b/modules/slideshow/module.info
index 5eb69ce3..6841199a 100644
--- a/modules/slideshow/module.info
+++ b/modules/slideshow/module.info
@@ -1,3 +1,3 @@
-name = Slideshow
-description = Allows users to view a slideshow of photos
+name = "Slideshow"
+description = "Allows users to view a slideshow of photos"
version = 1
diff --git a/modules/tag/controllers/tags.php b/modules/tag/controllers/tags.php
index 85f6d16e..c993e374 100644
--- a/modules/tag/controllers/tags.php
+++ b/modules/tag/controllers/tags.php
@@ -53,7 +53,7 @@ class Tags_Controller extends REST_Controller {
$form = tag::get_add_form($item);
if ($form->validate()) {
- foreach (split("[\,\ \;]", $form->add_tag->inputs["name"]->value) as $tag_name) {
+ foreach (split(",", $form->add_tag->inputs["name"]->value) as $tag_name) {
$tag_name = trim($tag_name);
if ($tag_name) {
$tag = tag::add($item, $tag_name);
@@ -78,4 +78,21 @@ class Tags_Controller extends REST_Controller {
return tag::get_add_form($item);
}
+
+ public function autocomplete() {
+ $tags = array();
+ $tag_parts = preg_split("#,#", $this->input->get("q"));
+ $limit = $this->input->get("limit");
+ $tag_part = end($tag_parts);
+ $tag_list = ORM::factory("tag")
+ ->like("name", "{$tag_part}%", false)
+ ->orderby("name", "ASC")
+ ->limit($limit)
+ ->find_all();
+ foreach ($tag_list as $tag) {
+ $tags[] = $tag->name;
+ }
+
+ print implode("\n", $tags);
+ }
}
diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php
index 7c4b56ba..be5461a4 100644
--- a/modules/tag/helpers/tag.php
+++ b/modules/tag/helpers/tag.php
@@ -79,6 +79,24 @@ class tag_Core {
}
}
+
+ /**
+ * Return all the tags for a given item.
+ * @return array
+ */
+ static function item_tags($item) {
+ $tags = array();
+ foreach (Database::instance()
+ ->select("name")
+ ->from("tags")
+ ->join("items_tags", "tags.id", "items_tags.tag_id", "left")
+ ->where("items_tags.item_id", $item->id)
+ ->get() as $row) {
+ $tags[] = $row->name;
+ }
+ return $tags;
+ }
+
static function get_add_form($item) {
$form = new Forge("tags", "", "post", array("id" => "gAddTagForm"));
$label = $item->is_album() ?
@@ -86,7 +104,7 @@ class tag_Core {
($item->is_photo() ? t("Add tag to photo") : t("Add tag to movie"));
$group = $form->group("add_tag")->label("Add Tag");
- $group->input("name")->label($label)->rules("required|length[1,64]");
+ $group->input("name")->label($label)->rules("required");
$group->hidden("item_id")->value($item->id);
$group->submit("")->value(t("Add Tag"));
return $form;
@@ -108,4 +126,24 @@ class tag_Core {
$group->submit("")->value(t("Delete Tag"));
return $form;
}
+
+ /**
+ * Delete all tags associated with an item
+ */
+ static function clear_all($item) {
+ $db = Database::instance();
+ $db->query("UPDATE {tags} SET `count` = `count` - 1 WHERE `count` > 0 " .
+ "AND `id` IN (SELECT `tag_id` from {items_tags} WHERE `item_id` = $item->id)");
+ $db->delete("items_tags", array("item_id" => "$item->id"));
+ }
+
+ /**
+ * Get rid of any tags that have no associated items.
+ */
+ static function compact() {
+ // @todo There's a potential race condition here which we can solve by adding a lock around
+ // this and all the cases where we create/update tags. I'm loathe to do that since it's an
+ // extremely rare case.
+ Database::instance() ->delete("tags", array("count" => 0));
+ }
} \ No newline at end of file
diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php
index 946326c0..57986e40 100644
--- a/modules/tag/helpers/tag_event.php
+++ b/modules/tag/helpers/tag_event.php
@@ -34,10 +34,13 @@ class tag_event_Core {
if (!empty($iptc["2#025"])) {
foreach($iptc["2#025"] as $tag) {
$tag = str_replace("\0", "", $tag);
- if (function_exists("mb_detect_encoding") && mb_detect_encoding($tag) != "UTF-8") {
- $tag = utf8_encode($tag);
+ foreach (preg_split("/,/", $tag) as $word) {
+ $word = trim($word);
+ if (function_exists("mb_detect_encoding") && mb_detect_encoding($word) != "UTF-8") {
+ $word = utf8_encode($word);
+ }
+ $tags[$word] = 1;
}
- $tags[$tag] = 1;
}
}
}
@@ -56,12 +59,42 @@ class tag_event_Core {
return;
}
- static function item_before_delete($item) {
- $db = Database::instance();
- $db->query("UPDATE {tags} SET `count` = `count` - 1 WHERE `count` > 0 " .
- "AND `id` IN (SELECT `tag_id` from {items_tags} WHERE `item_id` = $item->id)");
- $db->query("DELETE FROM {tags} WHERE `count` = 0 AND `id` IN (" .
- "SELECT `tag_id` from {items_tags} WHERE `item_id` = $item->id)");
- $db->delete("items_tags", array("item_id" => "$item->id"));
+ static function item_deleted($item) {
+ tag::clear_all($item);
+ tag::compact();
+ }
+
+ static function item_edit_form($item, $form) {
+ $url = url::site("tags/autocomplete");
+ $form->script("")
+ ->text("$('form input[id=tags]').ready(function() {
+ $('form input[id=tags]').autocomplete(
+ '$url', {max: 30, multiple: true, multipleSeparator: ',', cacheLength: 1});
+ });");
+ $tag_value = implode(", ", tag::item_tags($item));
+ $form->edit_item->input("tags")->label(t("Tags (comma separated)"))
+ ->value($tag_value);
+ }
+
+ static function item_edit_form_completed($item, $form) {
+ tag::clear_all($item);
+ foreach (preg_split("/,/", $form->edit_item->tags->value) as $tag_name) {
+ if ($tag_name) {
+ tag::add($item, trim($tag_name));
+ }
+ }
+ tag::compact();
+ }
+
+ static function admin_menu($menu, $theme) {
+ $menu->get("content_menu")
+ ->append(Menu::factory("link")
+ ->id("tags")
+ ->label(t("Tags"))
+ ->url(url::site("admin/tags")));
+ }
+
+ static function item_index_data($item, $data) {
+ $data[] = join(" ", tag::item_tags($item));
}
}
diff --git a/modules/tag/helpers/tag_installer.php b/modules/tag/helpers/tag_installer.php
index 3c16e3f3..bcb830e4 100644
--- a/modules/tag/helpers/tag_installer.php
+++ b/modules/tag/helpers/tag_installer.php
@@ -26,7 +26,7 @@ class tag_installer {
`count` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {items_tags} (
`id` int(9) NOT NULL auto_increment,
@@ -35,7 +35,7 @@ class tag_installer {
PRIMARY KEY (`id`),
KEY(`tag_id`, `id`),
KEY(`item_id`, `id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
module::set_version("tag", 1);
}
diff --git a/modules/tag/helpers/tag_menu.php b/modules/tag/helpers/tag_menu.php
deleted file mode 100644
index e1b61a93..00000000
--- a/modules/tag/helpers/tag_menu.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-2009 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_menu_Core {
- static function admin($menu, $theme) {
- $menu->get("content_menu")
- ->append(Menu::factory("link")
- ->id("tags")
- ->label(t("Tags"))
- ->url(url::site("admin/tags")));
- }
-}
diff --git a/modules/tag/helpers/tag_theme.php b/modules/tag/helpers/tag_theme.php
index fe30354f..1bce9bd8 100644
--- a/modules/tag/helpers/tag_theme.php
+++ b/modules/tag/helpers/tag_theme.php
@@ -19,11 +19,13 @@
*/
class tag_theme_Core {
static function head($theme) {
- $theme->script("modules/tag/js/tag.js");
+ $theme->css("jquery.autocomplete.css");
+ $theme->script("jquery.autocomplete.js");
+ $theme->script("tag.js");
}
static function admin_head($theme) {
- $theme->script("modules/tag/js/tag.js");
+ $theme->script("tag.js");
}
static function sidebar_blocks($theme) {
diff --git a/modules/tag/js/tag.js b/modules/tag/js/tag.js
index a1eaeecd..61ac73f4 100644
--- a/modules/tag/js/tag.js
+++ b/modules/tag/js/tag.js
@@ -7,7 +7,7 @@ function ajaxify_tag_form() {
dataType: "json",
success: function(data) {
if (data.result == "success") {
- $.get($("#gTagCloud").attr("src"), function(data, textStatus) {
+ $.get($("#gTagCloud").attr("title"), function(data, textStatus) {
$("#gTagCloud").html(data);
});
}
@@ -23,7 +23,7 @@ function closeEditInPlaceForms() {
$("#gRenameTagForm").parent().html($("#gRenameTagForm").parent().data("revert"));
li.height("");
$(".gEditable", li).bind("click", editInPlace);
- $(".gDialogLink", li).bind("click", handleDialogEvent);
+ $(".gDialogLink", li).gallery_dialog();
}
}
@@ -66,3 +66,4 @@ function editInPlace(element) {
};
ajaxify_editInPlaceForm();
}
+
diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php
index 7a85dbab..d9488e1c 100644
--- a/modules/tag/models/tag.php
+++ b/modules/tag/models/tag.php
@@ -44,10 +44,62 @@ class Tag_Model extends ORM {
* @return integer
*/
public function items_count($type=null) {
- return ORM::factory("item")
+ $model = ORM::factory("item")
->viewable()
->join("items_tags", "items.id", "items_tags.item_id")
- ->where("items_tags.tag_id", $this->id)
- ->count_all();
+ ->where("items_tags.tag_id", $this->id);
+
+ if ($type) {
+ $model->where("items.type", $type);
+ }
+ return $model->count_all();
+ }
+
+ /**
+ * Overload ORM::save() to trigger an item_related_update event for all items that are related
+ * to this tag. Since items can be added or removed as part of the save, we need to trigger an
+ * event for the union of all related items before and after the save.
+ */
+ public function save() {
+ $db = Database::instance();
+ $related_item_ids = array();
+ foreach ($db->getwhere("items_tags", array("tag_id" => $this->id)) as $row) {
+ $related_item_ids[$row->item_id] = 1;
+ }
+
+ $result = parent::save();
+
+ foreach ($db->getwhere("items_tags", array("tag_id" => $this->id)) as $row) {
+ $related_item_ids[$row->item_id] = 1;
+ }
+
+ if ($related_item_ids) {
+ foreach (ORM::factory("item")->in("id", array_keys($related_item_ids))->find_all() as $item) {
+ module::event("item_related_update", $item);
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Overload ORM::delete() to trigger an item_related_update event for all items that are
+ * related to this tag.
+ */
+ public function delete() {
+ $related_item_ids = array();
+ $db = Database::Instance();
+ foreach ($db->getwhere("items_tags", array("tag_id" => $this->id)) as $row) {
+ $related_item_ids[$row->item_id] = 1;
+ }
+
+ $result = parent::delete();
+
+ if ($related_item_ids) {
+ foreach (ORM::factory("item")->in("id", array_keys($related_item_ids))->find_all() as $item) {
+ module::event("item_related_update", $item);
+ }
+ }
+ return $result;
}
} \ No newline at end of file
diff --git a/modules/tag/module.info b/modules/tag/module.info
index 562d5c32..e505dd81 100644
--- a/modules/tag/module.info
+++ b/modules/tag/module.info
@@ -1,3 +1,3 @@
-name = Tags
-description = Allows users to tag photos and albums
+name = "Tags"
+description = "Allows users to tag photos and albums"
version = 1
diff --git a/modules/tag/views/tag_block.html.php b/modules/tag/views/tag_block.html.php
index 9c8f3de5..59a4ef88 100644
--- a/modules/tag/views/tag_block.html.php
+++ b/modules/tag/views/tag_block.html.php
@@ -1,5 +1,17 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<div id="gTagCloud" src="<?= url::site("tags") ?>">
+<script>
+ $("#gAddTagForm").ready(function() {
+ var url = $("#gTagCloud").attr("title") + "/autocomplete";
+ $("#gAddTagForm input:text").autocomplete(
+ url, {
+ max: 30,
+ multiple: true,
+ multipleSeparator: ',',
+ cacheLength: 1}
+ );
+ });
+</script>
+<div id="gTagCloud" title="<?= url::site("tags") ?>">
<?= $cloud ?>
</div>
<?= $form ?> \ No newline at end of file
diff --git a/modules/user/controllers/admin_users.php b/modules/user/controllers/admin_users.php
index b5dc6cb5..f87602b8 100644
--- a/modules/user/controllers/admin_users.php
+++ b/modules/user/controllers/admin_users.php
@@ -48,8 +48,9 @@ class Admin_Users_Controller extends Controller {
$desired_locale = $form->add_user->locale->value;
$user->locale = $desired_locale == "none" ? null : $desired_locale;
}
-
$user->save();
+ module::event("user_add_form_admin_completed", $user, $form);
+
message::success(t("Created user %user_name", array("user_name" => p::clean($user->name))));
print json_encode(array("result" => "success"));
} else {
@@ -128,6 +129,7 @@ class Admin_Users_Controller extends Controller {
$user->password = $form->edit_user->password->value;
}
$user->email = $form->edit_user->email->value;
+ $user->url = $form->edit_user->url->value;
if ($form->edit_user->locale) {
$desired_locale = $form->edit_user->locale->value;
$user->locale = $desired_locale == "none" ? null : $desired_locale;
@@ -138,6 +140,7 @@ class Admin_Users_Controller extends Controller {
$user->admin = $form->edit_user->admin->checked;
}
$user->save();
+ module::event("user_edit_form_admin_completed", $user, $form);
message::success(t("Changed user %user_name", array("user_name" => p::clean($user->name))));
print json_encode(array("result" => "success"));
diff --git a/modules/user/controllers/logout.php b/modules/user/controllers/logout.php
index 63971789..099b1952 100644
--- a/modules/user/controllers/logout.php
+++ b/modules/user/controllers/logout.php
@@ -19,18 +19,19 @@
*/
class Logout_Controller extends Controller {
public function index() {
- access::verify_csrf();
+ //access::verify_csrf();
$user = user::active();
user::logout();
log::info("user", t("User %name logged out", array("name" => p::clean($user->name))),
html::anchor("user/$user->id", p::clean($user->name)));
- if ($this->input->get("continue")) {
- $item = url::get_item_from_uri($this->input->get("continue"));
+ if ($continue_url = $this->input->get("continue")) {
+ $item = url::get_item_from_uri($continue_url);
if (access::can("view", $item)) {
- url::redirect($this->input->get("continue"));
+ // Don't use url::redirect() because it'll call url::site() and munge the continue url.
+ header("Location: $continue_url");
} else {
- url::redirect("");
+ url::redirect("albums/1");
}
}
}
diff --git a/modules/user/controllers/password.php b/modules/user/controllers/password.php
index ed3b9736..7c432701 100644
--- a/modules/user/controllers/password.php
+++ b/modules/user/controllers/password.php
@@ -29,8 +29,6 @@ class Password_Controller extends Controller {
}
public function do_reset() {
- access::verify_csrf();
-
if (request::method() == "post") {
$this->_change_password();
} else {
@@ -74,7 +72,7 @@ class Password_Controller extends Controller {
log::success(
"user",
- t("Password reset email sent for user %name", array("name" => p::clean($user->name)));
+ t("Password reset email sent for user %name", array("name" => p::clean($user->name))));
} else {
// Don't include the username here until you're sure that it's XSS safe
log::warning(
diff --git a/modules/user/controllers/users.php b/modules/user/controllers/users.php
index 46f799c5..0bf2e81d 100644
--- a/modules/user/controllers/users.php
+++ b/modules/user/controllers/users.php
@@ -39,6 +39,7 @@ class Users_Controller extends REST_Controller {
$user->locale = $desired_locale == "none" ? null : $desired_locale;
}
$user->save();
+ module::event("user_edit_form_completed", $user, $form);
message::success(t("User information updated."));
print json_encode(
diff --git a/modules/user/helpers/group.php b/modules/user/helpers/group.php
index 1dace840..04e6efd6 100644
--- a/modules/user/helpers/group.php
+++ b/modules/user/helpers/group.php
@@ -39,7 +39,6 @@ class group_Core {
$group->name = $name;
$group->save();
- module::event("group_created", $group);
return $group;
}
diff --git a/modules/user/helpers/user.php b/modules/user/helpers/user.php
index a59588f8..69a6ecb3 100644
--- a/modules/user/helpers/user.php
+++ b/modules/user/helpers/user.php
@@ -34,13 +34,16 @@ class user_Core {
->matches($group->password);
$group->input("email")->label(t("Email"))->id("gEmail")->value($user->email);
$group->input("url")->label(t("URL"))->id("gUrl")->value($user->url);
- $group->submit("")->value(t("Save"));
$form->add_rules_from($user);
+
+ module::event("user_edit_form", $user, $form);
+ $group->submit("")->value(t("Save"));
return $form;
}
static function get_edit_form_admin($user) {
- $form = new Forge("admin/users/edit_user/$user->id", "", "post", array("id" => "gEditUserForm"));
+ $form = new Forge(
+ "admin/users/edit_user/$user->id", "", "post", array("id" => "gEditUserForm"));
$group = $form->group("edit_user")->label(t("Edit User"));
$group->input("name")->label(t("Username"))->id("gUsername")->value($user->name);
$group->inputs["name"]->error_messages(
@@ -53,9 +56,11 @@ class user_Core {
$group->input("email")->label(t("Email"))->id("gEmail")->value($user->email);
$group->input("url")->label(t("URL"))->id("gUrl")->value($user->url);
$group->checkbox("admin")->label(t("Admin"))->id("gAdmin")->checked($user->admin);
- $group->submit("")->value(t("Modify User"));
$form->add_rules_from($user);
$form->edit_user->password->rules("-required");
+
+ module::event("user_edit_form_admin", $user, $form);
+ $group->submit("")->value(t("Modify User"));
return $form;
}
@@ -72,14 +77,16 @@ class user_Core {
$group->input("url")->label(t("URL"))->id("gUrl");
self::_add_locale_dropdown($group);
$group->checkbox("admin")->label(t("Admin"))->id("gAdmin");
- $group->submit("")->value(t("Add User"));
$user = ORM::factory("user");
$form->add_rules_from($user);
+
+ module::event("user_add_form_admin", $user, $form);
+ $group->submit("")->value(t("Add User"));
return $form;
}
private static function _add_locale_dropdown(&$form, $user=null) {
- $locales = locale::installed();
+ $locales = locales::installed();
if (count($locales) > 1) {
// Put "none" at the first position in the array
$locales = array_merge(array("" => t("« none »")), $locales);
@@ -202,7 +209,6 @@ class user_Core {
$user->add(group::registered_users());
$user->save();
- module::event("user_created", $user);
return $user;
}
diff --git a/modules/user/helpers/user_event.php b/modules/user/helpers/user_event.php
index 6515fbfb..4bde224b 100644
--- a/modules/user/helpers/user_event.php
+++ b/modules/user/helpers/user_event.php
@@ -30,4 +30,12 @@ class user_event_Core {
I18n::instance()->locale($locale);
}
}
+
+ static function admin_menu($menu, $theme) {
+ $menu->add_after("appearance_menu",
+ Menu::factory("link")
+ ->id("users_groups")
+ ->label(t("Users/Groups"))
+ ->url(url::site("admin/users")));
+ }
}
diff --git a/modules/user/helpers/user_installer.php b/modules/user/helpers/user_installer.php
index 1959d038..8ef4f13d 100644
--- a/modules/user/helpers/user_installer.php
+++ b/modules/user/helpers/user_installer.php
@@ -36,7 +36,7 @@ class user_installer {
PRIMARY KEY (`id`),
UNIQUE KEY(`hash`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {groups} (
`id` int(9) NOT NULL auto_increment,
@@ -44,14 +44,14 @@ class user_installer {
`special` BOOLEAN default 0,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$db->query("CREATE TABLE IF NOT EXISTS {groups_users} (
`group_id` int(9) NOT NULL,
`user_id` int(9) NOT NULL,
PRIMARY KEY (`group_id`, `user_id`),
UNIQUE KEY(`user_id`, `group_id`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
$everybody = group::create("Everybody");
$everybody->special = true;
diff --git a/modules/user/helpers/user_menu.php b/modules/user/helpers/user_menu.php
deleted file mode 100644
index 05e401f9..00000000
--- a/modules/user/helpers/user_menu.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-2009 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 user_menu_Core {
- static function admin($menu, $theme) {
- $menu->add_after("appearance_menu",
- Menu::factory("link")
- ->id("users_groups")
- ->label(t("Users/Groups"))
- ->url(url::site("admin/users")));
- }
-}
diff --git a/modules/user/helpers/user_theme.php b/modules/user/helpers/user_theme.php
index ad9d4c63..8de2d248 100644
--- a/modules/user/helpers/user_theme.php
+++ b/modules/user/helpers/user_theme.php
@@ -19,14 +19,10 @@
*/
class user_theme_Core {
static function header_top($theme) {
- $view = new View("login.html");
- $view->user = user::active();
- return $view->render();
- }
-
- static function admin_head($theme) {
- if (strpos(Router::$current_uri, "admin/users") !== false) {
- $theme->script("lib/gallery.panel.js");
+ if ($theme->page_type != "login") {
+ $view = new View("login.html");
+ $view->user = user::active();
+ return $view->render();
}
}
}
diff --git a/modules/user/models/group.php b/modules/user/models/group.php
index 45948887..8af78012 100644
--- a/modules/user/models/group.php
+++ b/modules/user/models/group.php
@@ -27,7 +27,22 @@ class Group_Model extends ORM {
* @see ORM::delete()
*/
public function delete($id=null) {
+ $old = clone $this;
module::event("group_before_delete", $this);
parent::delete($id);
+ module::event("group_deleted", $old);
+ }
+
+ public function save() {
+ if (!$this->loaded) {
+ $created = 1;
+ }
+ parent::save();
+ if (isset($created)) {
+ module::event("group_created", $this);
+ } else {
+ module::event("group_updated", $this->original(), $this);
+ }
+ return $this;
}
} \ No newline at end of file
diff --git a/modules/user/models/user.php b/modules/user/models/user.php
index b447892e..55562f34 100644
--- a/modules/user/models/user.php
+++ b/modules/user/models/user.php
@@ -25,6 +25,7 @@ class User_Model extends ORM {
"full_name" => "length[0,255]",
"email" => "valid_email|length[1,255]",
"password" => "length[1,40]",
+ "url" => "valid_url",
"locale" => "length[2,10]");
public function __set($column, $value) {
@@ -44,8 +45,10 @@ class User_Model extends ORM {
* @see ORM::delete()
*/
public function delete($id=null) {
+ $old = clone $this;
module::event("user_before_delete", $this);
parent::delete($id);
+ module::event("user_deleted", $old);
}
/**
@@ -57,4 +60,26 @@ class User_Model extends ORM {
return sprintf("http://www.gravatar.com/avatar/%s.jpg?s=%d&r=pg%s",
md5($this->email), $size, $default ? "&d=" . urlencode($default) : "");
}
+
+ public function save() {
+ if (!$this->loaded) {
+ $created = 1;
+ }
+ parent::save();
+ if (isset($created)) {
+ module::event("user_created", $this);
+ } else {
+ module::event("user_updated", $this->original(), $this);
+ }
+ return $this;
+ }
+
+ /**
+ * Return the best version of the user's name. Either their specified full name, or fall back
+ * to the user name.
+ * @return string
+ */
+ public function display_name() {
+ return empty($this->full_name) ? $this->name : $this->full_name;
+ }
} \ No newline at end of file
diff --git a/modules/user/module.info b/modules/user/module.info
index 2dba517d..8a9af407 100644
--- a/modules/user/module.info
+++ b/modules/user/module.info
@@ -1,3 +1,3 @@
-name = Users and Groups
-description = Provides user and group management
+name = "Users and Groups"
+description = "Provides user and group management"
version = 1
diff --git a/modules/user/views/admin_users.html.php b/modules/user/views/admin_users.html.php
index b469f82d..9bd4c068 100644
--- a/modules/user/views/admin_users.html.php
+++ b/modules/user/views/admin_users.html.php
@@ -28,7 +28,7 @@
{},
function(data) {
$("#group-" + group_id).html(data);
- $("#group-" + group_id + " .gDialogLink").bind("click", handleDialogEvent);
+ $("#group-" + group_id + " .gDialogLink").gallery_dialog();
});
}
@@ -66,7 +66,7 @@
<? foreach ($users as $i => $user): ?>
<tr id="gUser-<?= $user->id ?>" class="<?= text::alternate("gOddRow", "gEvenRow") ?> user <?= $user->admin ? "admin" : "" ?>">
<td id="user-<?= $user->id ?>" class="core-info gDraggable">
- <img src="<?= $user->avatar_url(20, $theme->theme_url("images/avatar.jpg", true)) ?>"
+ <img src="<?= $user->avatar_url(20, $theme->url("images/avatar.jpg", true)) ?>"
title="<?= t("Drag user onto group below to add as a new member") ?>"
alt="<?= p::clean($user->name) ?>"
width="20"
diff --git a/modules/user/views/login.html.php b/modules/user/views/login.html.php
index 7617d131..10ed31b2 100644
--- a/modules/user/views/login.html.php
+++ b/modules/user/views/login.html.php
@@ -12,10 +12,10 @@
'<a href="' . url::site("form/edit/users/{$user->id}") .
'" title="' . t("Edit Your Profile") .
'" id="gUserProfileLink" class="gDialogLink">' .
- p::clean(empty($user->full_name) ? $user->name : $user->full_name) . '</a>')) ?>
+ p::clean($user->display_name()) . '</a>')) ?>
</li>
<li>
- <a href="<?= url::site("logout?csrf=$csrf&continue=" . url::current(true)) ?>"
+ <a href="<?= url::site("logout?csrf=$csrf&amp;continue=" . urlencode(url::current(true))) ?>"
id="gLogoutLink"><?= t("Logout") ?></a>
</li>
<? endif ?>
diff --git a/modules/user/views/login_ajax.html.php b/modules/user/views/login_ajax.html.php
index 56a6f111..d697c958 100644
--- a/modules/user/views/login_ajax.html.php
+++ b/modules/user/views/login_ajax.html.php
@@ -38,7 +38,7 @@
</div>
</li>
<li>
- <a href="#" id="gForgotPasswordLink"><?= t("Forgot your Password?") ?></a>
+ <a href="#" id="gForgotPasswordLink"><?= t("Forgot Your Password?") ?></a>
</li>
</ul>
</div>
diff --git a/modules/watermark/helpers/watermark_menu.php b/modules/watermark/helpers/watermark_event.php
index bc3a4fed..45b410f9 100644
--- a/modules/watermark/helpers/watermark_menu.php
+++ b/modules/watermark/helpers/watermark_event.php
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class watermark_menu_Core {
- static function admin($menu, $theme) {
+class watermark_event_Core {
+ static function admin_menu($menu, $theme) {
$menu->get("content_menu")
->append(
Menu::factory("link")
diff --git a/modules/watermark/helpers/watermark_installer.php b/modules/watermark/helpers/watermark_installer.php
index 705b89d4..b3e91044 100644
--- a/modules/watermark/helpers/watermark_installer.php
+++ b/modules/watermark/helpers/watermark_installer.php
@@ -30,7 +30,7 @@ class watermark_installer {
`mime_type` varchar(64) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY(`name`))
- ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+ DEFAULT CHARSET=utf8;");
@mkdir(VARPATH . "modules/watermark");
module::set_version("watermark", 1);
diff --git a/modules/watermark/module.info b/modules/watermark/module.info
index 7f866695..abd4a3cf 100644
--- a/modules/watermark/module.info
+++ b/modules/watermark/module.info
@@ -1,3 +1,3 @@
-name = Watermarks
-description = Allows users to watermark their photos
+name = "Watermarks"
+description = "Allows users to watermark their photos"
version = 1
diff --git a/system/libraries/Database.php b/system/libraries/Database.php
index 6267f63a..2039371c 100644
--- a/system/libraries/Database.php
+++ b/system/libraries/Database.php
@@ -2,7 +2,7 @@
/**
* Provides database access in a platform agnostic way, using simple query building blocks.
*
- * $Id: Database.php 4342 2009-05-08 16:56:01Z jheathco $
+ * $Id: Database.php 4438 2009-07-06 04:11:16Z kiall $
*
* @package Core
* @author Kohana Team
@@ -1144,7 +1144,12 @@ class Database_Core {
$query = $this->select('COUNT(*) AS '.$this->escape_column('records_found'))->get()->result(TRUE);
- return (int) $query->current()->records_found;
+ $query = $query->current();
+
+ if ( ! $query)
+ return 0;
+ else
+ return (int) $query->records_found;
}
/**
diff --git a/system/libraries/ORM.php b/system/libraries/ORM.php
index c1048604..5196ba27 100644
--- a/system/libraries/ORM.php
+++ b/system/libraries/ORM.php
@@ -1295,7 +1295,9 @@ class ORM_Core {
$value = (float) $value;
break;
case 'boolean':
- $value = (bool) $value;
+ if ($value === "t") $value = true; // For PgSQL
+ else if ($value === "f") $value = false; // For PgSQL
+ else $value = (bool) $value;
break;
case 'string':
$value = (string) $value;
diff --git a/system/libraries/drivers/Database.php b/system/libraries/drivers/Database.php
index 807469f6..27f6ea8e 100644
--- a/system/libraries/drivers/Database.php
+++ b/system/libraries/drivers/Database.php
@@ -120,7 +120,7 @@ abstract class Database_Driver {
$key .= ' =';
}
- $value = ($value == TRUE) ? ' 1' : ' 0';
+ $value = ($value == TRUE) ? ' TRUE' : ' FALSE';
}
else
{
@@ -310,7 +310,7 @@ abstract class Database_Driver {
$value = '\''.$this->escape_str($value).'\'';
break;
case 'boolean':
- $value = (int) $value;
+ $value = ($value == TRUE) ? 'TRUE' : 'FALSE';
break;
case 'double':
// Convert to non-locale aware float to prevent possible commas
diff --git a/themes/admin_default/css/admin_screen.css b/themes/admin_default/css/admin_screen.css
new file mode 100644
index 00000000..d408acf0
--- /dev/null
+++ b/themes/admin_default/css/admin_screen.css
@@ -0,0 +1,458 @@
+/**
+ * Gallery 3 Default Admin Theme Screen Styles
+ *
+ * Extends themes/default/css/screen.css
+ *
+ * 1) Basic HTML elements
+ * 2) Reusable content blocks
+ * 3) Page layout containers
+ * 4) Content blocks in specific layout containers
+ * 5) Browser hacks
+ * 6) jQuery and jQuery UI
+ * 7) Server Add
+ * 8) Digibug Print Administration
+ */
+
+/** *******************************************************************
+ * 1) Basic HTML elements
+ **********************************************************************/
+
+/** *******************************************************************
+ * 2) Reusable content blocks
+ **********************************************************************/
+
+.gBlock {
+ background-color: #fff;
+ border: 1px solid #ccc;
+ margin-bottom: 1em;
+ padding: 1em;
+}
+
+#gSidebar .gBlockContent {
+ padding: 0;
+}
+
+.gSelected img,
+.gAvailable .gBlock img {
+ float: left;
+ margin-right: 1em;
+}
+
+.rtl .gSelected img,
+.rtl .gAvailable .gBlock img {
+ float: right;
+ margin-left: 1em;
+}
+
+.gSelected {
+ background: #e8e8e8;
+}
+
+.gAvailable .gInstalledToolkit:hover {
+ cursor: pointer;
+ background: #eee;
+}
+
+.gAvailable .gButtonLink {
+ width: 96%;
+}
+
+.gSelected .gButtonLink {
+ display: none;
+}
+
+.gUnavailable {
+ border-color: #999;
+ opacity: 0.4;
+}
+
+.gOddRow {
+ background-color: #eee;
+}
+
+.gEvenRow {
+ background-color: #fff;
+}
+
+/** *******************************************************************
+ * 3) Page layout containers
+ **********************************************************************/
+
+.gView {
+ min-width: 974px !important;
+}
+
+#gHeader {
+ background-color: #e8e8e8;
+ border-bottom: 1px solid #ccc;
+ margin-bottom: 20px;
+ padding: 0 20px;
+}
+
+#gContent {
+ font-size: 1.1em;
+ width: 96%;
+}
+
+/** *******************************************************************
+ * 4) Content blocks in specific layout containers
+ *********************************************************************/
+
+#gHeader #gLogo {
+ float: left;
+ margin: -22px 10px 0 0;
+ display: block;
+ padding-left: 2px;
+ width: 105px; /* 107px - padding-left */
+ height: 48px;
+ background-image: url('../../default/images/logo.png');
+ color: #A5A5A5 ! important;
+}
+#gHeader #gLogo:hover {
+ color: #FF6600 ! important;
+ text-decoration: none;
+}
+
+#gHeader #gLoginMenu {
+ float: none;
+ margin: 0;
+ padding: 5px 0 10px 0;
+ text-align: right;
+}
+
+
+.rtl #gHeader #gLoginMenu {
+ text-align: left;
+}
+
+#gHeader #gSiteAdminMenu {
+ float: left;
+ font-size: 1.2em;
+}
+
+.rtl #gHeader #gSiteAdminMenu {
+ float: right;
+}
+
+#gHeader #gSiteAdminMenu ul {
+ margin-bottom: 0;
+}
+
+.gBlock .ui-dialog-titlebar {
+ margin: -1em -1em 0;
+}
+
+#gSidebar .gBlock h2 {
+ background: none;
+}
+
+#gPhotoStream {
+ background-color: #e8e8e8;
+}
+
+#gPhotoStream .gBlockContent ul {
+ border-right: 1px solid #e8e8e8;
+ height: 135px;
+ overflow: auto;
+ overflow: -moz-scrollbars-horizontal; /* for FF */
+ overflow-x: scroll; /* scroll horizontal */
+ overflow-y: hidden; /* Hide vertical*/
+}
+
+#gContent #gPhotoStream .gItem {
+ background-color: #fff;
+ border: 1px solid #e8e8e8;
+ border-right-color: #ccc;
+ border-bottom-color: #ccc;
+ float: left;
+ height: 90px;
+ overflow: hidden;
+ text-align: center;
+ width: 90px;
+}
+
+.rtl #gContent #gPhotoStream .gItem {
+ float: right;
+}
+
+#gSiteStatus {
+ margin-bottom: 0;
+}
+
+#gContent .gItem {
+ background-color: #fff;
+ border: 1px solid #e8e8e8;
+ border-right-color: #ccc;
+ border-bottom-color: #ccc;
+ height: 90px;
+ padding: 14px 8px;
+ text-align: center;
+ width: 90px;
+}
+
+#gAdminCommentsMenu {
+ margin: 1em 0;
+}
+
+#gAdminCommentsMenu a {
+ margin: 0;
+ padding: .2em .6em;
+}
+
+#gAdminGraphics .gAvailable .gBlock {
+ clear: none;
+ float: left;
+ height: 16em;
+ margin-right: 1em;
+ width: 30%;
+}
+
+.rtl #gAdminGraphics .gAvailable .gBlock {
+ float: right;
+ margin-left: 1em;
+ margin-right: 0em;
+}
+
+#gSiteTheme,
+#gAdminTheme {
+ float: left;
+ width: 48%;
+}
+
+.rtl #gSiteTheme,
+.rtl #gAdminTheme {
+ float: right;
+}
+
+#gSiteTheme {
+ margin-right: 1em;
+}
+
+#gUserAdminList {
+ margin-bottom: 1em;
+}
+#gUserAdminList td {
+ vertical-align: bottom;
+}
+
+#gUserAdminList .gDraggable:hover {
+ border: 1px dashed black;
+}
+
+#gUserAdminList .admin {
+ color: #55f;
+ font-weight: bold;
+}
+
+.gActions a,
+.gActions span {
+ margin-right: 3em;
+}
+
+li.gGroup {
+ float: left;
+ display: block;
+ width: 200px;
+ border: 1px solid gray;
+ padding: 0;
+ margin: 0 1em 1em 0;
+}
+
+.rtl li.gGroup {
+ float: right;
+}
+
+li.gGroup h4 {
+ background-color: #EEEEEE;
+ border-bottom: 1px dashed #CCCCCC;
+ padding: .5em 0 .5em .5em;
+}
+li.gGroup .gButtonLink {
+ padding: 0;
+}
+li.gGroup ul, li.gGroup div {
+ height: 180px;
+ margin: 1px;
+ overflow: auto;
+ padding-top: .2em;
+}
+li.gGroup div p {
+ color: gray;
+ text-align: center;
+ padding: 2em .5em 0 .5em
+}
+li.gGroup .gUser {
+ padding: .2em 0 0 .5em;
+}
+li.gGroup .gUser .gButtonLink {
+ vertical-align: middle;
+}
+
+li.gDefaultGroup h4, li.gDefaultGroup .gUser {
+ color: gray;
+}
+
+#gAdminAdvancedSettings tr.setting:hover {
+ background: #ffc;
+}
+
+/** *******************************************************************
+ * 5) Browser hacks
+ *********************************************************************/
+
+#gHeader:after,
+#gAdminCommentsMenu:after,
+#gGroupAdmin:after,
+.gSelected:after,
+.gAvailable .gBlock:after,
+#gModuleCreateForm ul li ul:after,
+#gDeveloperTools:after,
+#gPhotoStream:after {
+ clear: both;
+ content: ".";
+ display: block;
+ height: 0;
+ visibility: hidden;
+}
+
+/** *******************************************************************
+ * 6) jQuery and jQuery UI
+ *********************************************************************/
+
+#gPanel {
+ display: none;
+ padding: 1em;
+}
+
+#gPanel legend {
+ display: none;
+}
+
+#gPanel fieldset {
+ border: none;
+}
+
+.ui-draggable {
+ cursor: move;
+}
+
+.gButtonSetVertical a {
+ width: 8em !important;
+}
+
+#gAdminDashboard .ui-dialog-titlebar,
+#gAdminDashboardSidebar .ui-dialog-titlebar {
+ padding: .2em .4em;
+}
+
+/**** Stuff that needs a home! ****/
+#gTagAdmin {
+ table-layout: fixed;
+}
+#gTagAdmin td {
+ border: 0;
+}
+#gTagAdmin ul {
+ padding-bottom: .3em;
+}
+#gTagAdmin li {
+ padding: .1em 0 .2em .3em;
+}
+#gTagAdmin .gColumn {
+ float: left;
+ width: 200px;
+}
+.rtl #gTagAdmin .gColumn {
+ float: right;
+}
+.gEditable {
+ padding: .1em .3em .2em .3em;
+}
+.gEditable:hover {
+ background-color: #ffc;
+ cursor: text;
+}
+#gRenameTagForm input {
+ padding: 0 .2em 0 .2em;
+ clear: none;
+ float: left;
+ margin: 0 .2em 0 0;
+}
+.rtl #gRenameTagForm input {
+ float: right;
+}
+#gRenameTagForm input[type="submit"] {
+ height: 25px;
+}
+#gRenameTagForm a, #gRenameTagForm span {
+ display: block;
+ float: left;
+ padding: .2em .2em 0 .1em;
+}
+.rtl #gRenameTagForm a, #gRenameTagForm span {
+ float: right;
+}
+#gProgress button {
+ float: right;
+ margin-top: 1em;
+}
+.rtl #gProgress button {
+ float: left;
+}
+
+#gTaskLogDialog h1 {
+ font-size: 1.1em;
+}
+
+.gTaskLog {
+ border: 1pt solid;
+ font-size: .9em;
+ height: 400px;
+ margin: .5em 0;
+ overflow: auto;
+ padding: .5em
+}
+
+
+/** *******************************************************************
+ * 7) Server Add
+ *********************************************************************/
+#gServerAddAdmin {
+ margin:auto;
+ text-align: left;
+}
+
+.rtl #gServerAddAdmin {
+ text-align: right;
+}
+
+#gServerAddAdmin form fieldset {
+ border: medium none;
+}
+
+#gServerAddAdmin legend {
+ display: none;
+}
+
+#gServerAddAdmin .gWarning {
+ background-color: #FFFF99;
+}
+
+#gAuthorizedPath {
+ margin: 0 !important;
+ padding: 0.3em 1.5em 0.3em 1em;
+}
+
+#gServerAdd Admin #path {
+ width: 80%;
+}
+
+.gRemoveDir:hover {
+ cursor: pointer;
+}
+
+#gLanguageSettingsForm .checklist li {
+ width: 150px;
+ overflow: hidden;
+}
+
diff --git a/themes/admin_default/css/screen.css b/themes/admin_default/css/screen.css
index d408acf0..88631e81 100644
--- a/themes/admin_default/css/screen.css
+++ b/themes/admin_default/css/screen.css
@@ -1,313 +1,774 @@
/**
- * Gallery 3 Default Admin Theme Screen Styles
+ * Gallery 3 Default Theme Screen Styles
*
- * Extends themes/default/css/screen.css
+ * @requires YUI reset, font, grids CSS
*
- * 1) Basic HTML elements
- * 2) Reusable content blocks
- * 3) Page layout containers
- * 4) Content blocks in specific layout containers
- * 5) Browser hacks
- * 6) jQuery and jQuery UI
- * 7) Server Add
- * 8) Digibug Print Administration
+ * Sheet organization:
+ * 1) Basic HTML elements
+ * 2) Reusable classes
+ * 3) Reusable content blocks
+ * 4) Page layout containers
+ * 5) Content blocks in specific layout containers
+ * 6) Navigation and menus
+ * 7) Browser hacks
+ * 8) jQuery and jQuery UI
+ * 9) Right-to-left language styles
*/
/** *******************************************************************
* 1) Basic HTML elements
**********************************************************************/
-/** *******************************************************************
- * 2) Reusable content blocks
- **********************************************************************/
+body, html {
+ background-color: #ccc;
+ font-family: 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
+}
-.gBlock {
- background-color: #fff;
- border: 1px solid #ccc;
+p {
margin-bottom: 1em;
- padding: 1em;
}
-#gSidebar .gBlockContent {
- padding: 0;
+em {
+ font-style: oblique;
+}
+
+h1, h2, h3, h4, h5, strong, th {
+ font-weight: bold;
+}
+
+h1 {
+ font-size: 1.7em;
+}
+
+#gSearchResults h1 {
+ margin-bottom: 1em;
+}
+
+#gProgress h1 {
+ font-size: 1.1em;
+}
+
+h2 {
+ font-size: 1.4em;
+}
+
+#gSidebar .gBlock h2 {
+ font-size: 1.2em;
+}
+
+#gSidebar .gBlock li {
+ margin-bottom: .6em;
}
-.gSelected img,
-.gAvailable .gBlock img {
+h3 {
+ font-size: 1.2em;
+}
+
+/* Links ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+a,
+.gMenu a,
+#gDialog a,
+.gButtonLink,
+.gButtonLink:hover,
+.gButtonLink:active {
+ color: #5382BF !important;
+ text-decoration: none;
+ -moz-outline-style: none;
+}
+
+a:hover,
+#gDialog a:hover {
+ text-decoration: underline;
+}
+
+.gMenu a:hover {
+ text-decoration: none;
+}
+
+#gDialog .gCancel {
+ clear: none;
float: left;
- margin-right: 1em;
+ margin: .3em 1em;
}
-.rtl .gSelected img,
-.rtl .gAvailable .gBlock img {
+#gForgotPasswordLink {
float: right;
- margin-left: 1em;
+ font-size: .9em;
}
-.gSelected {
- background: #e8e8e8;
+#gDialog .gCancel {
+ float: left;
}
-.gAvailable .gInstalledToolkit:hover {
- cursor: pointer;
- background: #eee;
+/* Tables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+table {
+ width: 100%;
+}
+
+#gContent table {
+ margin: 1em 0;
+}
+
+caption,
+th {
+ text-align: left;
+}
+
+th,
+td {
+ border: none;
+ border-bottom: 1px solid #ccc;
+ padding: .5em;
+ vertical-align: top;
+}
+
+/* Forms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+fieldset {
+ border: 1px solid #ccc;
+ padding-bottom: .8em;
+}
+
+#gHeader fieldset,
+#gSidebar fieldset,
+.gShortForm fieldset {
+ border: none;
}
-.gAvailable .gButtonLink {
- width: 96%;
+legend {
+ font-weight: bold;
+ margin-left: 1em;
}
-.gSelected .gButtonLink {
+#gHeader legend,
+#gSidebar legend,
+#gContent #gSearchForm legend,
+input[type="hidden"],
+.gShortForm label {
display: none;
}
-.gUnavailable {
- border-color: #999;
- opacity: 0.4;
+label {
+ cursor: help;
}
-.gOddRow {
- background-color: #eee;
+input[type="text"],
+input[type="password"] {
+ width: 50%;
}
-.gEvenRow {
- background-color: #fff;
+input[type="text"],
+input[type="password"],
+textarea {
+ border: 1px solid #e8e8e8;
+ border-top-color: #ccc;
+ border-left-color: #ccc;
+ color: #333;
}
-/** *******************************************************************
- * 3) Page layout containers
- **********************************************************************/
+textarea {
+ width: 100%;
+ height: 12em;
+}
-.gView {
- min-width: 974px !important;
+input:focus,
+textarea:focus,
+option:focus {
+ background-color: #ffc;
+ color: #000;
}
-#gHeader {
- background-color: #e8e8e8;
- border-bottom: 1px solid #ccc;
- margin-bottom: 20px;
- padding: 0 20px;
+/* Form layout ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+form li {
+ margin: 0 !important;
+ padding: .3em 1.5em .3em 1em;
}
-#gContent {
- font-size: 1.1em;
- width: 96%;
+form ul ul {
+ clear: both;
+}
+
+form ul ul li {
+ float: left;
+}
+
+input,
+select,
+textarea {
+ display: block;
+ clear: both;
+ padding: .2em;
+}
+
+input[type="submit"],
+input[type="reset"] {
+ display: inline;
+ clear: none;
+ float: left;
+}
+
+/* Form validation ~~~~~~~~~~~~~~~~~~~~~~~ */
+
+.gValidationRule {
+ font-size: 80%;
+ margin-top: .5em;
+}
+
+form.gError input[type="text"],
+li.gError input[type="text"],
+form.gError input[type="password"],
+li.gError input[type="password"],
+form.gError input[type="checkbox"],
+li.gError input[type="checkbox"],
+form.gError input[type="radio"],
+li.gError input[type="radio"],
+form.gError textarea,
+li.gError textarea,
+form.gError select,
+li.gError select {
+ border: 2px solid red;
}
/** *******************************************************************
- * 4) Content blocks in specific layout containers
+ * 2) Reusable generic classes
*********************************************************************/
-#gHeader #gLogo {
+.inactive, .understate {
+ color: #ccc;
+ font-weight: normal;
+}
+
+.left {
float: left;
- margin: -22px 10px 0 0;
- display: block;
- padding-left: 2px;
- width: 105px; /* 107px - padding-left */
- height: 48px;
- background-image: url('../../default/images/logo.png');
- color: #A5A5A5 ! important;
-}
-#gHeader #gLogo:hover {
- color: #FF6600 ! important;
- text-decoration: none;
+ margin: 1em 1em 1em 0;
}
-#gHeader #gLoginMenu {
- float: none;
- margin: 0;
- padding: 5px 0 10px 0;
+.right {
+ float: right;
+ margin: 1em 0 1em 1em;
+}
+
+.txtright {
text-align: right;
}
+/** *******************************************************************
+ * 3) Reusable content blocks
+ *********************************************************************/
+
+.gBlock {
+ clear: both;
+ margin-bottom: 2.5em;
+}
+
+.gBlock h2 {
+ background-color: #e8e8e8;
+ padding: .3em .8em;
+}
-.rtl #gHeader #gLoginMenu {
- text-align: left;
+.gBlockContent {
+ margin-top: 1em;
}
-#gHeader #gSiteAdminMenu {
- float: left;
- font-size: 1.2em;
+/* Status messages ~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gMessage {
+ width: 99%;
}
-.rtl #gHeader #gSiteAdminMenu {
- float: right;
+#gAdminAkismet .gSuccess,
+#gSiteStatus li,
+#gMessage li {
+ border: 1px solid #ccc;
+ margin-bottom: .4em;
}
-#gHeader #gSiteAdminMenu ul {
+#gSiteStatus li {
margin-bottom: 0;
+ border: none;
+ border-bottom: 1px solid #ccc;
}
-.gBlock .ui-dialog-titlebar {
- margin: -1em -1em 0;
+#gSiteStatus .gError,
+#gMessage .gError,
+form p.gError,
+#gSiteStatus .gInfo,
+#gMessage .gInfo,
+#gSiteStatus .gSuccess,
+#gMessage .gSuccess,
+#gSiteStatus .gWarning,
+#gMessage .gWarning {
+ background-position: .4em 50%;
+ background-repeat: no-repeat;
+ padding: .4em .5em .4em 30px;
}
-#gSidebar .gBlock h2 {
- background: none;
+.gError {
+ background-color: #fcc;
+}
+
+form .gError {
+ color: #f00;
+}
+
+#gSiteStatus .gError,
+#gMessage .gError,
+form p.gError {
+ background-image: url('../images/ico-error.png');
}
-#gPhotoStream {
+.gInfo {
background-color: #e8e8e8;
}
-#gPhotoStream .gBlockContent ul {
- border-right: 1px solid #e8e8e8;
- height: 135px;
- overflow: auto;
- overflow: -moz-scrollbars-horizontal; /* for FF */
- overflow-x: scroll; /* scroll horizontal */
- overflow-y: hidden; /* Hide vertical*/
+#gSiteStatus .gInfo,
+#gMessage .gInfo {
+ background-image: url('../images/ico-info.png');
+}
+
+.gSuccess {
+ background-color: #96EF95;
+}
+
+#gSiteStatus .gSuccess,
+#gMessage .gSuccess {
+ background-image: url('../images/ico-success.png');
+}
+
+.gWarning {
+ background-color: #ff9;
+}
+
+#gSiteStatus .gWarning,
+#gMessage .gWarning {
+ background-image: url('../images/ico-warning.png');
}
-#gContent #gPhotoStream .gItem {
+form .gError,
+.gPager .gInfo {
background-color: #fff;
- border: 1px solid #e8e8e8;
- border-right-color: #ccc;
- border-bottom-color: #ccc;
+}
+
+#gAdminMaintenance .gError,
+#gAdminMaintenance .gInfo,
+#gAdminMaintenance .gWarning,
+#gAdminMaintenance .gSuccess {
+ background-image: none;
+}
+
+/* Inline layout (forms, lists) ~~~~~~~~~~ */
+
+.gShortForm li {
float: left;
- height: 90px;
- overflow: hidden;
- text-align: center;
- width: 90px;
+ padding: .4em 0;
}
-.rtl #gContent #gPhotoStream .gItem {
- float: right;
+.gShortForm input[type="text"] {
+ color: #666;
+ padding: .3em .6em;
+ width: 11em;
}
-#gSiteStatus {
- margin-bottom: 0;
+/*** ******************************************************************
+ * 4) Page layout containers
+ *********************************************************************/
+
+/* View container ~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+.gView {
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-bottom: none;
+}
+
+/* Layout containers ~~~~~~~~~~~~~~~~~~~~~ */
+
+#gHeader {
+ background-color: #e8e8e8;
+ border-bottom: 1px solid #fff;
+ font-size: .8em;
+ margin-bottom: 1em;
+ padding: 1em 20px 0 20px;
}
-#gContent .gItem {
+#gContent {
+ font-size: 1.2em;
+ padding-left: 20px;
+ width: 696px;
+}
+
+#gSidebar {
background-color: #fff;
+ font-size: .9em;
+ padding: 0 20px;
+ width: 220px;
+}
+
+#gFooter {
+ background-color: #e8e8e8;
+ border-top: 1px solid #ccc;
+ font-size: .8em;
+ margin-top: 20px;
+ padding: 10px 20px;
+}
+
+/** *******************************************************************
+ * 5) Content blocks in specific layout containers
+ *********************************************************************/
+
+/* Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gHeader #gLogo img {
+ float: left;
+ margin: -4px 10px 0 0;
+}
+
+#gHeader #gQuickSearchForm {
+ clear: right;
+ float: right;
+ margin: 1em 0;
+}
+
+#gHeader #gQuickSearchForm input[type='text'] {
+ width: 17em;
+}
+
+#gContent .gBlock h2 {
+ background-color: transparent;
+ padding-left: 0;
+}
+
+#gSidebar .gBlockContent {
+ padding-left: 1em;
+}
+
+/* Album content ~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gContent #gAlbumGrid {
+ margin: 1em 0;
+}
+
+#gContent #gAlbumGrid .gItem {
border: 1px solid #e8e8e8;
border-right-color: #ccc;
border-bottom-color: #ccc;
- height: 90px;
- padding: 14px 8px;
+ float: left;
+ font-size: .7em;
+ height: 240px;
+ overflow: hidden;
+ padding: 15px 8px 30px 8px;
+ position: relative;
text-align: center;
- width: 90px;
+ width: 213px;
+}
+
+#gContent #gAlbumGrid .gItem h2 {
+ margin: 5px 0;
}
-#gAdminCommentsMenu {
+#gContent #gAlbumGrid .gAlbum {
+ background-color: #e8e8e8;
+}
+
+#gContent #gAlbumGrid .gAlbum h2 span {
+ background: transparent url('../images/ico-album.png') no-repeat top left !important;
+ display: inline-block;
+ height: 16px;
+ margin-right: 5px;
+ width: 16px;
+}
+
+/* Individual photo content ~~~~~~~~~~~~~~ */
+
+#gContent #gItem {
+ width: 99%;
+}
+
+#gContent #gPhoto {
+ position: relative;
+}
+
+#gContent #gItem .gFullSizeLink img {
+ display: block;
+ margin: 1em auto !important;
+}
+
+#gContent #gComments {
+ margin-top: 2em;
+}
+
+#gContent #gComments ul li {
margin: 1em 0;
}
-#gAdminCommentsMenu a {
- margin: 0;
- padding: .2em .6em;
+#gContent #gComments .gAuthor {
+ border-bottom: 1px solid #ccc;
+ color: #999;
+ height: 32px;
+ line-height: 32px;
}
-#gAdminGraphics .gAvailable .gBlock {
- clear: none;
- float: left;
- height: 16em;
- margin-right: 1em;
- width: 30%;
+#gContent #gComments ul li div {
+ padding: 0 8px 8px 43px;
+}
+
+#gContent #gComments ul li #gRecaptcha {
+ padding: 0;
+}
+
+#gContent #gComments ul li #gRecaptcha div {
+ padding: 0;
+}
+
+#gContent #gComments .gAvatar {
+ height: 32px;
+ margin-right: .4em;
+ width: 32px;
+}
+
+#gContent #gAddCommentForm {
+ margin-top: 2em;
+}
+
+/* Footer content ~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gHeader #gLoginMenu li,
+#gFooter #gCredits li {
+ display: inline;
+}
+
+#gHeader #gLoginMenu li {
+ padding-left: 1.2em;
+}
+
+#gFooter #gCredits li {
+ padding-right: 1.2em;
+}
+
+#gContent #gSearchResults {
+ margin-top: 1em;
+ padding-top: 1em;
+}
+
+/** *******************************************************************
+ * 5) Navigation and menus
+ *********************************************************************/
+
+#gSiteMenu,
+.gBreadcrumbs,
+#gTagCloud ul {
+ font-size: 1.2em;
}
-.rtl #gAdminGraphics .gAvailable .gBlock {
+/* Login menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gHeader #gLoginMenu {
+ color: #999;
float: right;
- margin-left: 1em;
- margin-right: 0em;
}
-#gSiteTheme,
-#gAdminTheme {
+/* Site Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gSiteMenu {
float: left;
- width: 48%;
+ margin-top: 20px;
+ padding: 0 20px 0 0;
}
-.rtl #gSiteTheme,
-.rtl #gAdminTheme {
- float: right;
+#gSiteMenu ul {
+ margin-bottom: 0;
+}
+
+/* Thumb Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gContent .gThumbMenu {
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ width: 100%;
}
-#gSiteTheme {
- margin-right: 1em;
+#gContent .gThumbMenu li {
+ border-left: none;
+ border-right: none;
+ border-bottom: none;
}
-#gUserAdminList {
+#gContent .gThumbMenu li li {
+ padding: .3em;
+}
+
+#gContent .gThumbMenu a:hover {
+ text-decoration: none;
+}
+
+/* View Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gViewMenu {
margin-bottom: 1em;
}
-#gUserAdminList td {
- vertical-align: bottom;
+
+#gViewMenu a {
+ background-repeat: no-repeat;
+ background-position: 50% 50%;
+ height: 28px !important;
+ width: 43px !important;
}
-#gUserAdminList .gDraggable:hover {
- border: 1px dashed black;
+#gViewMenu #gHybridLink {
+ background-image: url('../images/ico-view-hybrid.png');
}
-#gUserAdminList .admin {
- color: #55f;
- font-weight: bold;
+#gViewMenu #gSlideshowLink {
+ background-image: url('../images/ico-view-slideshow.png');
+}
+
+#gViewMenu .gFullSizeLink {
+ background-image: url('../images/ico-view-fullsize.png');
}
-.gActions a,
-.gActions span {
- margin-right: 3em;
+#gViewMenu #gCommentsLink {
+ background-image: url('../images/ico-view-comments.png');
+}
+
+#gViewMenu #gDigibugLink {
+ background-image: url('../images/ico-print.png');
+}
+
+/* Breadcrumbs ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+.gBreadcrumbs {
+ background-color: #fff;
+ border-top: 1px solid #ccc;
+ clear: both;
+ margin: 0 -20px;
+ padding-left: 20px;
}
-li.gGroup {
+.gBreadcrumbs li {
+ background: transparent url('../images/ico-separator.gif') no-repeat scroll left center;
float: left;
+ padding: 10px 6px 10px 16px !important;
+}
+
+.gBreadcrumbs li.root {
+ background: transparent;
+}
+
+.gBreadcrumbs li a,
+.gBreadcrumbs li span {
display: block;
- width: 200px;
- border: 1px solid gray;
- padding: 0;
- margin: 0 1em 1em 0;
}
-.rtl li.gGroup {
- float: right;
+.gBreadcrumbs li.active,
+.gBreadcrumbs li.active span {
+ font-weight: bold;
}
-li.gGroup h4 {
- background-color: #EEEEEE;
- border-bottom: 1px dashed #CCCCCC;
- padding: .5em 0 .5em .5em;
+#gAddPhotos .gBreadcrumbs {
+ font-size: .9em;
}
-li.gGroup .gButtonLink {
- padding: 0;
+
+/* Tags and cloud ~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gTagCloud ul {
+ text-align: justify;
}
-li.gGroup ul, li.gGroup div {
- height: 180px;
- margin: 1px;
- overflow: auto;
- padding-top: .2em;
+
+#gTagCloud ul li {
+ display: inline;
+ line-height: 1.5em;
+ text-align: justify;
}
-li.gGroup div p {
- color: gray;
- text-align: center;
- padding: 2em .5em 0 .5em
+
+#gTagCloud ul li a {
+ text-decoration: none;
}
-li.gGroup .gUser {
- padding: .2em 0 0 .5em;
+
+#gTagCloud ul li span {
+ display: none;
}
-li.gGroup .gUser .gButtonLink {
- vertical-align: middle;
+
+#gTagCloud ul li.size1 a {
+ color: #9cf;
+ font-size: 80%;
+ font-weight: 100;
+}
+
+#gTagCloud ul li.size2 a {
+ color: #69f;
+ font-size: 90%;
+ font-weight: 300;
+}
+
+#gTagCloud ul li.size3 a {
+ color: #69c;
+ font-size: 100%;
+ font-weight: 500;
+}
+
+#gTagCloud ul li.size4 a {
+ color: #369;
+ font-size: 110%;
+ font-weight: 700;
}
-li.gDefaultGroup h4, li.gDefaultGroup .gUser {
- color: gray;
+#gTagCloud ul li.size5 a {
+ color: #0e2b52;
+ font-size: 120%;
+ font-weight: 900;
}
-#gAdminAdvancedSettings tr.setting:hover {
- background: #ffc;
+#gTagCloud ul li.size6 a {
+ color: #0e2b52;
+ font-size: 130%;
+ font-weight: 900;
+}
+
+#gTagCloud ul li.size7 a {
+ color: #0e2b52;
+ font-size: 140%;
+ font-weight: 900;
+}
+
+#gTagCloud ul li a:hover {
+ color: #f30;
+ text-decoration: underline;
+}
+
+/* Pagination ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+.gPager {
+ clear: both;
+ margin: 0;
+ padding: 5px 0 !important;
+ width: 100%;
+}
+
+.gPager li {
+ float: left;
+ margin: 0;
+ width: 30%;
+}
+
+.gPager .gInfo {
+ text-align: center;
+ width: 40%;
}
/** *******************************************************************
- * 5) Browser hacks
+ * 6) Browser hacks
*********************************************************************/
+#gSiteMenu:after,
#gHeader:after,
-#gAdminCommentsMenu:after,
-#gGroupAdmin:after,
-.gSelected:after,
-.gAvailable .gBlock:after,
-#gModuleCreateForm ul li ul:after,
-#gDeveloperTools:after,
-#gPhotoStream:after {
+.gBreadcrumbs:after,
+#gAlbumGrid:after,
+.gPager:after,
+#gViewMenu:after {
clear: both;
content: ".";
display: block;
@@ -316,143 +777,315 @@ li.gDefaultGroup h4, li.gDefaultGroup .gUser {
}
/** *******************************************************************
- * 6) jQuery and jQuery UI
+ * 7) jQuery and jQuery UI
*********************************************************************/
-#gPanel {
- display: none;
- padding: 1em;
+/* Superfish menu overrides ~~~~~~~~~~~~~~ */
+
+.sf-menu li li, .sf-menu li li ul li {
+ background-color: #bdd2ff;
}
-#gPanel legend {
- display: none;
+.sf-menu li:hover {
+ background-color: #dfe9ff;
}
-#gPanel fieldset {
- border: none;
+/* Ajax loading indicator ~~~~~~~~~~~~~~~~ */
+
+.gLoadingLarge {
+ background: #e8e8e8 url('../images/loading-lg.gif') no-repeat center center;
+ font-size: 0;
+}
+
+.gDialogLoadingLarge {
+ background: url('../images/loading-lg.gif') no-repeat center center !important;
+ font-size: 0;
}
-.ui-draggable {
+.gLoadingSmall {
+ background: #e8e8e8 url('../images/loading-sm.gif') no-repeat center center;
+ font-size: 0;
+}
+
+.gDraggable {
cursor: move;
}
-.gButtonSetVertical a {
- width: 8em !important;
+.gDropTarget {
+ background-color: #cfdeff;
+ border: 1px dotted #999;
+ height: 100px;
+ margin: 1em 0;
+}
+
+/* jQuery UI Dialog ~~~~~~~~~~~~~~~~~~~~~~ */
+
+.ui-widget-overlay {
+ background: #000;
+ opacity: .7;
+ filter: Alpha(Opacity=70);
}
-#gAdminDashboard .ui-dialog-titlebar,
-#gAdminDashboardSidebar .ui-dialog-titlebar {
- padding: .2em .4em;
+#gDialog {
+ text-align: left;
}
-/**** Stuff that needs a home! ****/
-#gTagAdmin {
- table-layout: fixed;
+#gDialog li {
+ padding-left: 0;
}
-#gTagAdmin td {
- border: 0;
+
+#gDialog form input[type="text"],
+#gDialog form input[type="password"] {
+ width: 100%;
}
-#gTagAdmin ul {
- padding-bottom: .3em;
+
+#gDialog #gLoginForm,
+#gDialog #gAddUserForm,
+#gDialog #gAddGroupForm {
+ margin: 0 auto;
+ width: 270px;
}
-#gTagAdmin li {
- padding: .1em 0 .2em .3em;
+
+#gDialog fieldset {
+ border: none;
}
-#gTagAdmin .gColumn {
- float: left;
- width: 200px;
+
+#gDialog legend {
+ display: none;
}
-.rtl #gTagAdmin .gColumn {
- float: right;
+
+/* jQuery UI ThemeRoller buttons */
+
+.gButtonLink {
+ display: inline-block;
+ margin: 0 4px 0 0;
+ padding: .2em .4em;
+ outline: 0;
}
-.gEditable {
- padding: .1em .3em .2em .3em;
+
+.gButtonSet {
+ padding-left: 1px;
}
-.gEditable:hover {
- background-color: #ffc;
- cursor: text;
+
+.gButtonSet li {
+ float: left;
}
-#gRenameTagForm input {
- padding: 0 .2em 0 .2em;
- clear: none;
+
+.gButtonSet .gButtonLink {
+ margin: 0;
+}
+
+.ui-icon-left .ui-icon {
float: left;
- margin: 0 .2em 0 0;
+ margin-right: .2em;
}
-.rtl #gRenameTagForm input {
+
+.ui-icon-right .ui-icon {
float: right;
+ margin-left: .2em;
}
-#gRenameTagForm input[type="submit"] {
- height: 25px;
+
+.ui-icon-rotate-ccw {
+ background-position: -192px -64px;
}
-#gRenameTagForm a, #gRenameTagForm span {
- display: block;
- float: left;
- padding: .2em .2em 0 .1em;
+
+.ui-icon-rotate-cw {
+ background-position: -208px -64px;
}
-.rtl #gRenameTagForm a, #gRenameTagForm span {
- float: right;
+
+/* STUFF THAT NEEDS A HOME */
+
+#gMove ul {
+ padding-left: 1em;
}
-#gProgress button {
- float: right;
- margin-top: 1em;
+
+#gMove .selected {
+ background: #999;
}
-.rtl #gProgress button {
+
+/* Server Add */
+
+#gServerAdd button {
float: left;
+ margin-bottom: .5em;
}
-#gTaskLogDialog h1 {
- font-size: 1.1em;
+#gServerAddTree {
+ cursor: pointer;
+ padding-left: 4px;
}
-.gTaskLog {
- border: 1pt solid;
- font-size: .9em;
- height: 400px;
- margin: .5em 0;
+#gServerAddTree li {
+ padding: 0;
+ float: none;
+}
+
+#gServerAddTree span.selected {
+ background: #ddd;
+}
+
+#gServerAddTree {
+ border: 1px solid #ccc;
+ height: 25em;
overflow: auto;
- padding: .5em
+ margin-bottom: .5em;
+ padding-top: .5em;
+ padding-bottom: .5em;
}
+#gServerAdd ul ul li {
+ padding-left: 1.2em;
+}
-/** *******************************************************************
- * 7) Server Add
- *********************************************************************/
-#gServerAddAdmin {
- margin:auto;
- text-align: left;
+#gServerAdd .gBreadcrumbs {
+ font-size: 1em;
+ padding: 0;
+ margin: 0;
+ border-top-width: 0;
}
-.rtl #gServerAddAdmin {
- text-align: right;
+#gServerAdd p {
+ margin: 0;
}
-#gServerAddAdmin form fieldset {
- border: medium none;
+#gServerAdd .gBreadcrumbs li {
+ padding: 10px 6px 10px 16px;
}
-#gServerAddAdmin legend {
- display: none;
+/* Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+#gPermissions .gDenied,
+#gPermissions .gAllowed {
+ text-align: center;
+ vertical-align: middle;
+}
+#gPermissions .gDenied {
+ background-color: #fcc;
}
+#gPermissions .gAllowed {
+ background-color: #cfc;
+}
+
+/*************** STUFF THAT NEEDS A HOME ****************/
-#gServerAddAdmin .gWarning {
- background-color: #FFFF99;
+.gProgressBar {
+ height: 1em;
+ width: 100%;
+ margin-top: .5em;
+ display: inline-block;
}
-#gAuthorizedPath {
- margin: 0 !important;
- padding: 0.3em 1.5em 0.3em 1em;
+#gAddPhotos p {
+ margin: 0;
+ padding: 0;
}
-#gServerAdd Admin #path {
- width: 80%;
+#gAddPhotosCanvas {
+ height: 325px;
+ width: 450px;
+ overflow: auto;
}
-.gRemoveDir:hover {
- cursor: pointer;
+#gAddPhotosQueue .progressbar {
+ height: 4px;
}
-#gLanguageSettingsForm .checklist li {
- width: 150px;
- overflow: hidden;
+#gAddPhotosQueue .title {
+ font-size: 1.25em;
+}
+
+#gAddPhotosQueue .status {
+ font-size: .75em;
+}
+
+#gAddPhotosQueue .box {
+ margin-bottom: 8px;
+ padding: 4px;
+}
+
+#gAddPhotosQueue .pending {
+ background-color: #e8e8e8;
+ border: 1px solid #d7d7d7;
+}
+
+#gAddPhotosQueue .error {
+ background-color: #fcc;
+ border: 1px solid #ebb;
+}
+
+#gAddPhotosQueue .uploading {
+ background-color: #ff9;
+ border: 1px solid #ee8;
+}
+
+#gAddPhotosQueue .complete {
+ background-color: #cfc;
+ border: 1px solid #beb;
+}
+
+#gAdminG2ImportNotes {
+ padding-bottom: 20px;
+}
+
+#gAdminG2ImportDetails {
+ padding-top: 20px;
+}
+
+#gAdminG2ImportDetails .gWarning {
+ margin-top: 4px;
+}
+
+#gAdminG2ImportDetails .gInfo {
+ padding: 2px;
+ border: 1px solid #999;
+ margin-bottom: 10px;
+}
+
+#gAdminG2ImportNotes p,
+#gAdminG2ImportDetails .gInfo p {
+ padding: 0;
+ margin: 0;
+}
+
+#gAdminG2ImportNotes ul li,
+#gAdminG2Import .gInfo ul li {
+ padding-left: 0;
+ margin-left: 20px;
+ list-style-type: disc;
+}
+
+/* Right to left styles ~~~~~~~~~~~~~~~~~~~~ */
+
+.rtl {
+ direction: rtl;
+}
+
+.rtl caption,
+.rtl th,
+.rtl #gDialog {
+ text-align: right;
+}
+
+.rtl #gHeader #gQuickSearchForm,
+.rtl #gForgotPasswordLink,
+.rtl #gHeader #gLoginMenu,
+.rtl .ui-icon-right .ui-icon {
+ clear: left;
+ float: left;
+}
+
+.rtl #gDialog .gCancel,
+.rtl form ul ul li,
+.rtl input[type="submit"],
+.rtl input[type="reset"],
+.rtl .gShortForm li,
+.rtl #gHeader #gLogo img,
+.rtl #gContent #gAlbumGrid .gItem,
+.rtl #gSiteMenu,
+.rtl .gBreadcrumbs li,
+.rtl .gPager li,
+.rtl .gButtonSet li,
+.rtl .ui-icon-left .ui-icon {
+ float: right;
}
diff --git a/themes/admin_default/images/ico-album.png b/themes/admin_default/images/ico-album.png
new file mode 100644
index 00000000..affa1b84
--- /dev/null
+++ b/themes/admin_default/images/ico-album.png
Binary files differ
diff --git a/themes/admin_default/images/ico-error.png b/themes/admin_default/images/ico-error.png
new file mode 100644
index 00000000..c37bd062
--- /dev/null
+++ b/themes/admin_default/images/ico-error.png
Binary files differ
diff --git a/themes/admin_default/images/ico-info.png b/themes/admin_default/images/ico-info.png
new file mode 100644
index 00000000..12cd1aef
--- /dev/null
+++ b/themes/admin_default/images/ico-info.png
Binary files differ
diff --git a/themes/admin_default/images/ico-print.png b/themes/admin_default/images/ico-print.png
new file mode 100644
index 00000000..b82a8e1e
--- /dev/null
+++ b/themes/admin_default/images/ico-print.png
Binary files differ
diff --git a/themes/admin_default/images/ico-separator.gif b/themes/admin_default/images/ico-separator.gif
new file mode 100644
index 00000000..3de2d0d3
--- /dev/null
+++ b/themes/admin_default/images/ico-separator.gif
Binary files differ
diff --git a/themes/admin_default/images/ico-success.png b/themes/admin_default/images/ico-success.png
new file mode 100644
index 00000000..a9925a06
--- /dev/null
+++ b/themes/admin_default/images/ico-success.png
Binary files differ
diff --git a/themes/admin_default/images/ico-view-comments.png b/themes/admin_default/images/ico-view-comments.png
new file mode 100644
index 00000000..e5d3630f
--- /dev/null
+++ b/themes/admin_default/images/ico-view-comments.png
Binary files differ
diff --git a/themes/admin_default/images/ico-view-fullsize.png b/themes/admin_default/images/ico-view-fullsize.png
new file mode 100644
index 00000000..0be23e9b
--- /dev/null
+++ b/themes/admin_default/images/ico-view-fullsize.png
Binary files differ
diff --git a/themes/admin_default/images/ico-view-hybrid.png b/themes/admin_default/images/ico-view-hybrid.png
new file mode 100644
index 00000000..ee902e55
--- /dev/null
+++ b/themes/admin_default/images/ico-view-hybrid.png
Binary files differ
diff --git a/themes/admin_default/images/ico-view-slideshow.png b/themes/admin_default/images/ico-view-slideshow.png
new file mode 100644
index 00000000..82f61f63
--- /dev/null
+++ b/themes/admin_default/images/ico-view-slideshow.png
Binary files differ
diff --git a/themes/admin_default/images/ico-warning.png b/themes/admin_default/images/ico-warning.png
new file mode 100644
index 00000000..628cf2da
--- /dev/null
+++ b/themes/admin_default/images/ico-warning.png
Binary files differ
diff --git a/themes/admin_default/images/loading-lg.gif b/themes/admin_default/images/loading-lg.gif
new file mode 100644
index 00000000..cc70a7a8
--- /dev/null
+++ b/themes/admin_default/images/loading-lg.gif
Binary files differ
diff --git a/themes/admin_default/images/loading-sm.gif b/themes/admin_default/images/loading-sm.gif
new file mode 100644
index 00000000..d0bce154
--- /dev/null
+++ b/themes/admin_default/images/loading-sm.gif
Binary files differ
diff --git a/themes/admin_default/js/ui.init.js b/themes/admin_default/js/ui.init.js
index 3f062a27..daa6dd70 100644
--- a/themes/admin_default/js/ui.init.js
+++ b/themes/admin_default/js/ui.init.js
@@ -1,5 +1,4 @@
$(document).ready(function(){
-
// Initialize Superfish menus
$("#gSiteAdminMenu ul.gMenu").addClass("sf-menu");
$("ul.gMenu").addClass("sf-menu");
@@ -15,23 +14,20 @@ $(document).ready(function(){
$("#gSiteAdminMenu").css("display", "block");
// Initialize status message effects
- $("#gMessage li").showMessage();
+ $("#gMessage li").gallery_show_message();
// Initialize modal dialogs
- var dialogLinks = $(".gDialogLink");
- for (var i=0; i < dialogLinks.length; i++) {
- $(dialogLinks[i]).bind("click", handleDialogEvent);
- }
+ $(".gDialogLink").gallery_dialog();
+
+ // Initialize ajax links
+ $(".gDialogLink").gallery_ajax();
// Initialize panels
- var panelLinks = $(".gPanelLink");
- for (i=0; i<panelLinks.length; i++) {
- $(panelLinks[i]).bind("click", handlePanelEvent);
- }
+ $(".gPanelLink").gallery_panel();
if ($("#gPhotoStream").length) {
// Vertically align thumbs in photostream
- $(".gItem").vAlign();
+ $(".gItem").gallery_valign();
}
// Apply jQuery UI button css to submit inputs
diff --git a/themes/admin_default/theme.info b/themes/admin_default/theme.info
index d21b0ff5..b3d9741d 100644
--- a/themes/admin_default/theme.info
+++ b/themes/admin_default/theme.info
@@ -1,6 +1,6 @@
-name = Gallery Default
-description = A crisp Site Administration theme with soft colors and drop down menus.
+name = "Gallery Default"
+description = "A crisp Site Administration theme with soft colors and drop down menus."
version = 1
-author = Gallery Team
+author = "Gallery Team"
admin = 1
site = 0
diff --git a/themes/admin_default/views/admin.html.php b/themes/admin_default/views/admin.html.php
index 575f8a96..3f4128cb 100644
--- a/themes/admin_default/views/admin.html.php
+++ b/themes/admin_default/views/admin.html.php
@@ -7,28 +7,29 @@
<title><?= t("Admin Dashboard") ?></title>
<link rel="shortcut icon" href="<?= url::file("themes/default/images/favicon.ico") ?>" type="image/x-icon" />
- <?= $theme->css("lib/yui/reset-fonts-grids.css") ?>
- <?= $theme->css("lib/themeroller/ui.base.css") ?>
- <?= $theme->css("lib/superfish/css/superfish.css") ?>
- <?= $theme->css("themes/default/css/screen.css") ?>
- <?= $theme->theme_css("css/screen.css") ?>
+ <?= $theme->css("yui/reset-fonts-grids.css") ?>
+ <?= $theme->css("themeroller/ui.base.css") ?>
+ <?= $theme->css("superfish/css/superfish.css") ?>
+ <?= $theme->css("screen.css") ?>
+ <?= $theme->css("admin_screen.css") ?>
<!--[if lt IE 8]>
- <link rel="stylesheet" type="text/css" href="<?= $theme->theme_url("css/fix-ie.css") ?>"
+ <link rel="stylesheet" type="text/css" href="<?= $theme->url("fix-ie.css") ?>"
media="screen,print,projection" />
<![endif]-->
- <?= $theme->script("lib/jquery.js") ?>
- <?= $theme->script("lib/jquery.form.js") ?>
- <?= $theme->script("lib/jquery-ui.js") ?>
- <?= $theme->script("lib/gallery.common.js") ?>
+ <?= $theme->script("jquery.js") ?>
+ <?= $theme->script("jquery.form.js") ?>
+ <?= $theme->script("jquery-ui.js") ?>
+ <?= $theme->script("gallery.common.js") ?>
<? /* MSG_CANCEL is required by gallery.dialog.js */ ?>
<script type="text/javascript">
var MSG_CANCEL = "<?= t('Cancel') ?>";
</script>
- <?= $theme->script("lib/gallery.dialog.js") ?>
- <?= $theme->script("lib/superfish/js/superfish.js") ?>
- <?= $theme->theme_script("js/jquery.dropshadow.js") ?>
- <?= $theme->theme_script("js/ui.init.js") ?>
+ <?= $theme->script("gallery.ajax.js") ?>
+ <?= $theme->script("gallery.dialog.js") ?>
+ <?= $theme->script("superfish/js/superfish.js") ?>
+ <?= $theme->script("jquery.dropshadow.js") ?>
+ <?= $theme->script("ui.init.js") ?>
<?= $theme->admin_head() ?>
</head>
@@ -45,7 +46,7 @@
<?= $theme->admin_header_top() ?>
<ul id="gLoginMenu">
<li class="first"><?= html::anchor("albums/1", "&larr; ".t("Back to the Gallery")) ?></li>
- <li id="gLogoutLink"><a href="<?= url::site("logout?continue=albums/1&csrf=$csrf") ?>"><?= t("Logout") ?></a></li>
+ <li id="gLogoutLink"><a href="<?= url::site("logout?continue=albums/1&amp;csrf=$csrf") ?>"><?= t("Logout") ?></a></li>
</ul>
<a id="gLogo" href="<?= url::site("albums/1") ?>" title="<?= t("go back to the Gallery") ?>">
&larr; <?= t("back to the ...") ?>
diff --git a/themes/default/css/fix-ie.css b/themes/default/css/fix-ie.css
index 3d9604e6..eee88c15 100644
--- a/themes/default/css/fix-ie.css
+++ b/themes/default/css/fix-ie.css
@@ -1,26 +1,17 @@
/**
* Fix display in IE 6, 7
*/
-#gHeader,
-#gSiteMenu,
+
+#gBanner,
.gBreadcrumbs,
#gAlbumGrid,
#gPager,
-#gViewMenu {
+#gViewMenu {
zoom: 1;
}
-#gHeader #gLogo img {
- margin-top: 5px;
- margin-bottom: 0;
-}
-
-#gHeader #gSiteMenu {
- margin-top: 28px;
-}
-
-#gHeader #gQuickSearchForm {
- margin-bottom: 0;
+#gBanner {
+ z-index: 2;
}
input.submit {
@@ -44,7 +35,3 @@ input.submit {
.gPager .ui-icon-right {
width: 60px;
}
-
-#gQuickPane {
- height: 32px !important;
-} \ No newline at end of file
diff --git a/themes/default/css/screen.css b/themes/default/css/screen.css
index 41e51623..55839c57 100644
--- a/themes/default/css/screen.css
+++ b/themes/default/css/screen.css
@@ -131,7 +131,7 @@ fieldset {
padding-bottom: .8em;
}
-#gHeader fieldset,
+#gBanner fieldset,
#gSidebar fieldset,
.gShortForm fieldset {
border: none;
@@ -142,7 +142,7 @@ legend {
margin-left: 1em;
}
-#gHeader legend,
+#gBanner legend,
#gSidebar legend,
#gContent #gSearchForm legend,
input[type="hidden"],
@@ -387,16 +387,21 @@ form .gError,
/* Layout containers ~~~~~~~~~~~~~~~~~~~~~ */
#gHeader {
+ margin-bottom: 1em;
+}
+
+#gBanner {
background-color: #e8e8e8;
- border-bottom: 1px solid #fff;
+ border-bottom: 1px solid #ccc;
font-size: .8em;
- margin-bottom: 1em;
- padding: 1em 20px 0 20px;
+ padding: 1em 20px;
+ position: relative;
}
#gContent {
font-size: 1.2em;
padding-left: 20px;
+ position: relative;
width: 696px;
}
@@ -421,18 +426,17 @@ form .gError,
/* Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-#gHeader #gLogo img {
- float: left;
- margin: -4px 10px 0 0;
+#gBanner #gLogo img {
+ margin: 0;
}
-#gHeader #gQuickSearchForm {
+#gBanner #gQuickSearchForm {
clear: right;
float: right;
- margin: 1em 0;
+ margin-top: 1em;
}
-#gHeader #gQuickSearchForm input[type='text'] {
+#gBanner #gQuickSearchForm input[type='text'] {
width: 17em;
}
@@ -449,45 +453,74 @@ form .gError,
#gContent #gAlbumGrid {
margin: 1em 0;
+ position: relative;
+ z-index: 1;
}
#gContent #gAlbumGrid .gItem {
- border: 1px solid #e8e8e8;
- border-right-color: #ccc;
- border-bottom-color: #ccc;
+ background-color: #fff;
+ border: 1px solid #fff;
float: left;
font-size: .7em;
- height: 240px;
+ height: 220px;
overflow: hidden;
- padding: 14px 8px;
+ padding: .6em 8px;
+ position: relative;
text-align: center;
width: 213px;
+ z-index: 1;
}
#gContent #gAlbumGrid .gItem h2 {
margin: 5px 0;
}
+#gContent .gPhoto h2,
+#gContent .gItem .gMetadata {
+ display: none;
+}
+
#gContent #gAlbumGrid .gAlbum {
background-color: #e8e8e8;
}
#gContent #gAlbumGrid .gAlbum h2 span {
- background: transparent url('../images/ico-album.png') no-repeat top left !important;
+ background: transparent url('../images/ico-album.png') no-repeat top left;
display: inline-block;
height: 16px;
margin-right: 5px;
width: 16px;
}
+#gContent #gAlbumGrid #gHoverItem {
+ background-color: #fff;
+ border: 1px solid #000;
+ display: none;
+ height: auto;
+ padding: 0;
+ position: absolute;
+ width: auto;
+ z-index: 100;
+}
+
+#gContent #gAlbumGrid #gHoverItem .gItem {
+ border: none;
+}
+
+#gContent #gHoverItem .gItem h2,
+#gContent #gHoverItem .gItem .gMetadata {
+ display: block;
+}
+
/* Individual photo content ~~~~~~~~~~~~~~ */
#gContent #gItem {
+ position: relative;
width: 99%;
}
#gContent #gPhoto {
-
+ position: relative;
}
#gContent #gItem .gFullSizeLink img {
@@ -534,12 +567,12 @@ form .gError,
/* Footer content ~~~~~~~~~~~~~~~~~~~~~~~~ */
-#gHeader #gLoginMenu li,
+#gBanner #gLoginMenu li,
#gFooter #gCredits li {
display: inline;
}
-#gHeader #gLoginMenu li {
+#gBanner #gLoginMenu li {
padding-left: 1.2em;
}
@@ -557,14 +590,13 @@ form .gError,
*********************************************************************/
#gSiteMenu,
-.gBreadcrumbs,
#gTagCloud ul {
font-size: 1.2em;
}
/* Login menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-#gHeader #gLoginMenu {
+#gBanner #gLoginMenu {
color: #999;
float: right;
}
@@ -572,15 +604,63 @@ form .gError,
/* Site Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#gSiteMenu {
- float: left;
- margin-top: 20px;
- padding: 0 20px 0 0;
+ bottom: 0;
+ display: none;
+ left: 140px;
+ position: absolute;
}
#gSiteMenu ul {
- margin-bottom: 0;
+ margin-bottom: 0 !important;
}
+/* Context Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+.gContextMenu {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+}
+
+.gItem .gContextMenu {
+ display: none;
+ margin-top: 2em;
+ width: 100%;
+}
+
+#gItem .gContextMenu {
+ font-size: .7em;
+}
+
+#gItem .gContextMenu ul {
+ display: none;
+}
+
+.gContextMenu li {
+ border-left: none;
+ border-right: none;
+ border-bottom: none;
+}
+
+.gContextMenu li a {
+ display: block;
+ line-height: 1.6em;
+}
+
+#gHoverItem .gContextMenu {
+ display: block;
+}
+
+#gHoverItem .gContextMenu li {
+ text-align: left;
+}
+
+#gHoverItem .gContextMenu a:hover {
+ text-decoration: none;
+}
+
+/* View Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
#gViewMenu {
margin-bottom: 1em;
}
@@ -615,11 +695,7 @@ form .gError,
/* Breadcrumbs ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
.gBreadcrumbs {
- background-color: #fff;
- border-top: 1px solid #ccc;
- clear: both;
- margin: 0 -20px;
- padding-left: 20px;
+ padding: 0 20px;
}
.gBreadcrumbs li {
@@ -737,9 +813,7 @@ form .gError,
* 6) Browser hacks
*********************************************************************/
-#gSiteMenu:after,
#gHeader:after,
-.gBreadcrumbs:after,
#gAlbumGrid:after,
.gPager:after,
#gViewMenu:after {
@@ -797,7 +871,6 @@ form .gError,
.ui-widget-overlay {
background: #000;
opacity: .7;
- filter: Alpha(Opacity=70);
}
#gDialog {
@@ -879,24 +952,26 @@ form .gError,
/* Server Add */
-.gCheckboxTree input {
- display: inline;
+#gServerAdd button {
+ float: left;
+ margin-bottom: .5em;
}
-.gCheckboxTree li {
- padding: 0;
- float: none;
+#gServerAddTree {
+ cursor: pointer;
+ padding-left: 4px;
}
-.gCheckboxTree .ui-icon {
- cursor: pointer;
+#gServerAddTree li {
+ padding: 0;
+ float: none;
}
-.gFile {
- padding-left: 2.5em;
+#gServerAddTree span.selected {
+ background: #ddd;
}
-#gServerAdd #gServerAddTree {
+#gServerAddTree {
border: 1px solid #ccc;
height: 25em;
overflow: auto;
@@ -909,10 +984,6 @@ form .gError,
padding-left: 1.2em;
}
-#gServerAdd ul li .gFile {
- padding-left: 2.5em;
-}
-
#gServerAdd .gBreadcrumbs {
font-size: 1em;
padding: 0;
diff --git a/themes/default/js/ui.init.js b/themes/default/js/ui.init.js
index 9d9d3079..2391f638 100644
--- a/themes/default/js/ui.init.js
+++ b/themes/default/js/ui.init.js
@@ -1,8 +1,5 @@
/**
- * Initialize jQuery UI and Plugin elements
- *
- * @todo Standardize how elements requiring listeners are handled
- * http://docs.jquery.com/Events/live
+ * Initialize jQuery UI and Gallery Plugin elements
*/
var shortForms = new Array(
@@ -26,15 +23,11 @@ $(document).ready(function() {
$("#gSiteMenu").css("display", "block");
// Initialize status message effects
- $("#gMessage li").showMessage();
+ $("#gMessage li").gallery_show_message();
// Initialize dialogs
- $(".gMenuLink").addClass("gDialogLink");
$("#gLoginLink").addClass("gDialogLink");
- var dialogLinks = $(".gDialogLink");
- for (var i=0; i < dialogLinks.length; i++) {
- $(dialogLinks[i]).bind("click", handleDialogEvent);
- }
+ $(".gDialogLink").gallery_dialog();
// Initialize view menu
if ($("#gViewMenu").length) {
@@ -50,21 +43,78 @@ $(document).ready(function() {
// Apply jQuery UI button css to submit inputs
$("input[type=submit]:not(.gShortForm input)").addClass("ui-state-default ui-corner-all");
+ // Apply styles and icon classes to gContextMenu
+ if ($(".gContextMenu").length) {
+ $(".gContextMenu li").addClass("ui-state-default");
+ $(".gContextMenu a").addClass("gButtonLink ui-icon-left");
+ $(".gContextMenu a").prepend("<span class=\"ui-icon\"></span>");
+ $(".gContextMenu a span").each(function() {
+ var iconClass = $(this).parent().attr("class").match(/ui-icon-.[^\s]+/).toString();
+ $(this).addClass(iconClass);
+ });
+ }
+
// Album view only
if ($("#gAlbumGrid").length) {
// Vertical align thumbnails/metadata in album grid
- $(".gItem").vAlign();
+ $(".gItem").gallery_valign();
+
+ // Initialize context menus
+ $(".gItem").hover(
+ function(){
+ var position = $(this).position();
+ var item_classes = $(this).attr("class");
+ var bg_color = $(this).css("background-color");
+ var container = $(this).parent();
+ $("#gHoverItem").remove();
+ container.append("<div id=\"gHoverItem\"><div class=\"" + item_classes + "\">"
+ + $(this).html() + "</div></div>");
+ $("#gHoverItem").css("top", position.top);
+ $("#gHoverItem").css("left", position.left);
+ $("#gHoverItem").css("background-color", bg_color);
+ $.fn.gallery_hover_init();
+ var v_align = $(this).find(".gValign");
+ var title = $(this).find("h2");
+ var meta = $(this).find(".gMetadata");
+ var context = $(this).find(".gContextMenu");
+ var context_label = $(this).find(".gContextMenu li:first");
+ $("#gHoverItem .gItem").height(
+ $(v_align).gallery_height()
+ + $(title).gallery_height()
+ + $(meta).gallery_height()
+ + parseInt($(context).css("margin-top").replace("px",""))
+ + $(context_label).gallery_height()
+ );
+
+ $("#gHoverItem").fadeIn("fast");
+ $("#gHoverItem").hover(
+ function(){
+ $(this).gallery_context_menu();
+ },
+ function() {
+ $(this).hide();
+ }
+ );
+ }
+ );
}
- // Photo/Item item view only
+ // Photo/Item item view
if ($("#gItem").length) {
- // Ensure that sized image versions
- // fit inside their container
- sizedImage();
+ // Ensure the resized image fits within its container
+ $("#gItem").gallery_fit_photo();
+
+ // Initialize context menus
+ var resize = $("#gItem").gallery_get_photo();
+ $(resize).hover(function(){
+ $(this).gallery_context_menu();
+ });
// Collapse comments form, insert button to expand
if ($("#gAddCommentForm").length) {
- var showCommentForm = '<a href="#add_comment_form" class="showCommentForm gButtonLink ui-corner-all ui-icon-left ui-state-default right"><span class="ui-icon ui-icon-comment"></span>' + ADD_A_COMMENT + '</a>';
+ var showCommentForm = '<a href="#add_comment_form"'
+ + ' class="showCommentForm gButtonLink ui-corner-all ui-icon-left ui-state-default right">'
+ + '<span class="ui-icon ui-icon-comment"></span>' + ADD_A_COMMENT + '</a>';
$("#gAddCommentForm").hide();
$("#gComments").prepend(showCommentForm);
$(".showCommentForm").click(function(){
@@ -78,32 +128,9 @@ $(document).ready(function() {
duration: 1000,
hash: true
});
-
}
- // Add hover state for buttons
- $(".ui-state-default").hover(
- function(){
- $(this).addClass("ui-state-hover");
- },
- function(){
- $(this).removeClass("ui-state-hover");
- }
- );
+ // Initialize button hover effect
+ $.fn.gallery_hover_init();
});
-
-/**
- * Reduce width of sized photo if it's wider than its parent container
- */
-function sizedImage() {
- var containerWidth = $("#gItem").width();
- var oPhoto = $("#gItem img").filter(function() {
- return this.id.match(/gPhotoId-/);
- });
- if (containerWidth < oPhoto.width()) {
- var proportion = containerWidth / oPhoto.width();
- oPhoto.width(containerWidth);
- oPhoto.height(proportion * oPhoto.height());
- }
-}
diff --git a/themes/default/theme.info b/themes/default/theme.info
index 71e8a740..5f19d0d7 100644
--- a/themes/default/theme.info
+++ b/themes/default/theme.info
@@ -1,6 +1,6 @@
-name = Gallery Default
-description = A crisp and distinctive theme that uses large fonts and icons for easy navigation and an enjoyable browsing experience.
+name = "Gallery Default"
+description = "A crisp and distinctive theme that uses large fonts and icons for easy navigation and an enjoyable browsing experience."
version = 1
-author = Gallery Team
+author = "Gallery Team"
site = 1
admin = 0
diff --git a/themes/default/views/album.html.php b/themes/default/views/album.html.php
index 65ea3381..e2890482 100644
--- a/themes/default/views/album.html.php
+++ b/themes/default/views/album.html.php
@@ -19,7 +19,7 @@
<?= $child->thumb_img(array("class" => "gThumbnail")) ?>
</a>
<?= $theme->thumb_bottom($child) ?>
- <?= $theme->thumb_menu($child) ?>
+ <?= $theme->context_menu($child, "#gItemId-{$child->id} .gThumbnail") ?>
<h2><span></span><a href="<?= $child->url() ?>"><?= p::clean($child->title) ?></a></h2>
<ul class="gMetadata">
<?= $theme->thumb_info($child) ?>
diff --git a/themes/default/views/header.html.php b/themes/default/views/header.html.php
index 5428d9fd..2ba1e923 100644
--- a/themes/default/views/header.html.php
+++ b/themes/default/views/header.html.php
@@ -1,19 +1,19 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<?= $theme->header_top() ?>
-<? if ($header_text = module::get_var("gallery", "header_text")): ?>
-<?= $header_text ?>
-<? else: ?>
-<a id="gLogo" href="<?= url::site("albums/1") ?>" title="<?= t("go back to the Gallery home") ?>">
- <img width="107" height="48" alt="<?= t("Gallery logo: Your photos on your web site") ?>" src="<?= $theme->theme_url("images/logo.png") ?>" />
-</a>
-<? endif ?>
-
-<div id="gSiteMenu" style="display: none">
-<?= $theme->site_menu() ?>
+<div id="gBanner">
+ <?= $theme->header_top() ?>
+ <? if ($header_text = module::get_var("gallery", "header_text")): ?>
+ <?= $header_text ?>
+ <? else: ?>
+ <a id="gLogo" href="<?= url::site("albums/1") ?>" title="<?= t("go back to the Gallery home") ?>">
+ <img width="107" height="48" alt="<?= t("Gallery logo: Your photos on your web site") ?>" src="<?= $theme->url("images/logo.png") ?>" />
+ </a>
+ <? endif ?>
+ <div id="gSiteMenu">
+ <?= $theme->site_menu() ?>
+ </div>
+ <?= $theme->header_bottom() ?>
</div>
-<?= $theme->header_bottom() ?>
-
<? if (!empty($parents)): ?>
<ul class="gBreadcrumbs">
<? foreach ($parents as $parent): ?>
diff --git a/themes/default/views/movie.html.php b/themes/default/views/movie.html.php
index 66c80ded..c8ecd769 100644
--- a/themes/default/views/movie.html.php
+++ b/themes/default/views/movie.html.php
@@ -2,16 +2,29 @@
<div id="gItem">
<?= $theme->photo_top() ?>
- <ul id="gPager">
- <li><?= t("%position of %total", array("position" => $position, "total" => $sibling_count)) ?></li>
- <? if ($previous_item): ?>
- <li><span class="ui-icon ui-icon-seek-prev"></span><a href="<?= $previous_item->url() ?>"><?= t("previous") ?></a></li>
- <? endif ?>
- <? if ($next_item): ?>
- <li><a href="<?= $next_item->url() ?>"><?= t("next") ?></a><span class="ui-icon ui-icon-seek-next"></span></li>
- <? endif ?>
+ <ul class="gPager">
+ <li>
+ <? if ($previous_item): ?>
+ <a href="<?= $previous_item->url() ?>" class="gButtonLink ui-icon-left ui-state-default ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-w"></span><?= t("previous") ?></a>
+ <? else: ?>
+ <a class="gButtonLink ui-icon-left ui-state-disabled ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-w"></span><?= t("previous") ?></a>
+ <? endif; ?>
+ </li>
+ <li class="gInfo"><?= t("%position of %total", array("position" => $position, "total" => $sibling_count)) ?></li>
+ <li class="txtright">
+ <? if ($next_item): ?>
+ <a href="<?= $next_item->url() ?>" class="gButtonLink ui-icon-right ui-state-default ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-e"></span><?= t("next") ?></a>
+ <? else: ?>
+ <a class="gButtonLink ui-icon-right ui-state-disabled ui-corner-all">
+ <span class="ui-icon ui-icon-triangle-1-e"></span><?= t("next") ?></a>
+ <? endif ?>
+ </li>
</ul>
+
<?= $item->movie_img(array("class" => "gMovie", "id" => "gMovieId-{$item->id}")) ?>
<div id="gInfo">
@@ -23,4 +36,5 @@
var ADD_A_COMMENT = "<?= t("Add a comment") ?>";
</script>
<?= $theme->photo_bottom() ?>
+ <?= $theme->context_menu($item, "#gMovieId-{$item->id}") ?>
</div>
diff --git a/themes/default/views/page.html.php b/themes/default/views/page.html.php
index 181a2c46..2cb71b9e 100644
--- a/themes/default/views/page.html.php
+++ b/themes/default/views/page.html.php
@@ -23,13 +23,13 @@
<? endif ?>
<? endif ?>
</title>
- <link rel="shortcut icon" href="<?= $theme->theme_url("images/favicon.ico") ?>" type="image/x-icon" />
- <?= $theme->css("lib/yui/reset-fonts-grids.css") ?>
- <?= $theme->css("lib/superfish/css/superfish.css") ?>
- <?= $theme->css("lib/themeroller/ui.base.css") ?>
- <?= $theme->theme_css("css/screen.css") ?>
+ <link rel="shortcut icon" href="<?= $theme->url("images/favicon.ico") ?>" type="image/x-icon" />
+ <?= $theme->css("yui/reset-fonts-grids.css") ?>
+ <?= $theme->css("superfish/css/superfish.css") ?>
+ <?= $theme->css("themeroller/ui.base.css") ?>
+ <?= $theme->css("screen.css") ?>
<!--[if lt IE 8]>
- <link rel="stylesheet" type="text/css" href="<?= $theme->theme_url("css/fix-ie.css") ?>"
+ <link rel="stylesheet" type="text/css" href="<?= $theme->url("css/fix-ie.css") ?>"
media="screen,print,projection" />
<![endif]-->
<? if ($theme->page_type == 'album'): ?>
@@ -45,26 +45,27 @@
</style>
<? endif ?>
<? endif ?>
- <?= $theme->script("lib/jquery.js") ?>
- <?= $theme->script("lib/jquery.form.js") ?>
- <?= $theme->script("lib/jquery-ui.js") ?>
- <?= $theme->script("lib/gallery.common.js") ?>
+ <?= $theme->script("jquery.js") ?>
+ <?= $theme->script("jquery.form.js") ?>
+ <?= $theme->script("jquery-ui.js") ?>
+ <?= $theme->script("gallery.common.js") ?>
<? /* MSG_CANCEL is required by gallery.dialog.js */ ?>
<script type="text/javascript">
var MSG_CANCEL = "<?= t('Cancel') ?>";
</script>
- <?= $theme->script("lib/gallery.dialog.js") ?>
- <?= $theme->script("lib/gallery.form.js") ?>
- <?= $theme->script("lib/superfish/js/superfish.js") ?>
- <?= $theme->script("lib/jquery.localscroll.js") ?>
- <?= $theme->theme_script("js/ui.init.js") ?>
+ <?= $theme->script("gallery.ajax.js") ?>
+ <?= $theme->script("gallery.dialog.js") ?>
+ <?= $theme->script("gallery.form.js") ?>
+ <?= $theme->script("superfish/js/superfish.js") ?>
+ <?= $theme->script("jquery.localscroll.js") ?>
+ <?= $theme->script("ui.init.js") ?>
<? /* These are page specific, but if we put them before $theme->head() they get combined */ ?>
<? if ($theme->page_type == "photo"): ?>
- <?= $theme->script("lib/jquery.scrollTo.js") ?>
- <?= $theme->script("lib/gallery.show_full_size.js") ?>
+ <?= $theme->script("jquery.scrollTo.js") ?>
+ <?= $theme->script("gallery.show_full_size.js") ?>
<? elseif ($theme->page_type == "movie"): ?>
- <?= $theme->script("lib/flowplayer.js") ?>
+ <?= $theme->script("flowplayer.js") ?>
<? endif ?>
<?= $theme->head() ?>
diff --git a/themes/default/views/photo.html.php b/themes/default/views/photo.html.php
index bf4d9da3..fa5def47 100644
--- a/themes/default/views/photo.html.php
+++ b/themes/default/views/photo.html.php
@@ -5,7 +5,7 @@
<script>
$(document).ready(function() {
$(".gFullSizeLink").click(function() {
- show_full_size("<?= $theme->item()->file_url() ?>", "<?= $theme->item()->width ?>", "<?= $theme->item()->height ?>");
+ $.gallery_show_full_size("<?= $theme->item()->file_url() ?>", "<?= $theme->item()->width ?>", "<?= $theme->item()->height ?>");
return false;
});
});
@@ -47,6 +47,7 @@
</a>
<? endif ?>
<?= $theme->resize_bottom($item) ?>
+ <?= $theme->context_menu($item, "#gPhotoId-{$item->id}") ?>
</div>
<div id="gInfo">