diff options
Diffstat (limited to 'modules/gallery')
37 files changed, 516 insertions, 223 deletions
diff --git a/modules/gallery/controllers/admin_modules.php b/modules/gallery/controllers/admin_modules.php index f5af9a5a..650b7e9e 100644 --- a/modules/gallery/controllers/admin_modules.php +++ b/modules/gallery/controllers/admin_modules.php @@ -95,12 +95,17 @@ class Admin_Modules_Controller extends Admin_Controller { $activated_names[] = t($info->name); } } catch (Exception $e) { + message::warning(t("An error occurred while installing the <b>%module_name</b> module", + array("module_name" => $info->name))); Kohana_Log::add("error", (string)$e); } } module::event("module_change", $changes); + // If modules need upgrading, this will get recreated + site_status::clear("upgrade_now"); + // @todo this type of collation is questionable from an i18n perspective if ($activated_names) { message::success(t("Activated: %names", array("names" => join(", ", $activated_names)))); diff --git a/modules/gallery/controllers/items.php b/modules/gallery/controllers/items.php index f205bf86..39b0f638 100644 --- a/modules/gallery/controllers/items.php +++ b/modules/gallery/controllers/items.php @@ -31,4 +31,13 @@ class Items_Controller extends Controller { access::required("view", $item); url::redirect($item->abs_url()); } + + // Return the width/height dimensinons for the given item + public function dimensions($id) { + $item = ORM::factory("item", $id); + access::required("view", $item); + json::reply(array("thumb" => array((int)$item->thumb_width, (int)$item->thumb_height), + "resize" => array((int)$item->resize_width, (int)$item->resize_height), + "full" => array((int)$item->width, (int)$item->height))); + } } diff --git a/modules/gallery/controllers/quick.php b/modules/gallery/controllers/quick.php index c34209da..3db4f5df 100644 --- a/modules/gallery/controllers/quick.php +++ b/modules/gallery/controllers/quick.php @@ -36,7 +36,8 @@ class Quick_Controller extends Controller { } if ($degrees) { - $tmpfile = tempnam(TMPPATH, "rotate"); + $tmpfile = tempnam(TMPPATH, "rotate") . "." . + pathinfo($item->file_path(), PATHINFO_EXTENSION); gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $degrees)); $item->set_data_file($tmpfile); $item->save(); diff --git a/modules/gallery/controllers/reauthenticate.php b/modules/gallery/controllers/reauthenticate.php index 0486c0fe..53a96374 100644 --- a/modules/gallery/controllers/reauthenticate.php +++ b/modules/gallery/controllers/reauthenticate.php @@ -19,12 +19,19 @@ */ class Reauthenticate_Controller extends Controller { public function index() { + $is_ajax = Session::instance()->get_once("is_ajax_request", request::is_ajax()); if (!identity::active_user()->admin) { - access::forbidden(); + if ($is_ajax) { + // We should never be able to get here since Admin_Controller::_reauth_check() won't work + // for non-admins. + access::forbidden(); + } else { + url::redirect(item::root()->abs_url()); + } } + // On redirects from the admin controller, the ajax request indicator is lost, // so we store it in the session. - $is_ajax = Session::instance()->get_once("is_ajax_request", request::is_ajax()); if ($is_ajax) { $v = new View("reauthenticate.html"); $v->form = self::_form(); diff --git a/modules/gallery/controllers/upgrader.php b/modules/gallery/controllers/upgrader.php index cb940b46..b2646874 100644 --- a/modules/gallery/controllers/upgrader.php +++ b/modules/gallery/controllers/upgrader.php @@ -39,10 +39,12 @@ class Upgrader_Controller extends Controller { } } + $failed = Input::instance()->get("failed"); $view = new View("upgrader.html"); $view->can_upgrade = identity::active_user()->admin || $session->get("can_upgrade"); $view->upgrade_token = $upgrade_token; $view->available = module::available(); + $view->failed = $failed ? explode(",", $failed) : array(); $view->done = $available_upgrades == 0; print $view; } @@ -52,8 +54,16 @@ class Upgrader_Controller extends Controller { // @todo this may screw up some module installers, but we don't have a better answer at // this time. $_SERVER["HTTP_HOST"] = "example.com"; - } else if (!identity::active_user()->admin && !Session::instance()->get("can_upgrade", false)) { - access::forbidden(); + } else { + if (!identity::active_user()->admin && !Session::instance()->get("can_upgrade", false)) { + access::forbidden(); + } + + try { + access::verify_csrf(); + } catch (Exception $e) { + url::redirect("upgrader"); + } } $available = module::available(); @@ -65,20 +75,36 @@ class Upgrader_Controller extends Controller { } // Then upgrade the rest + $failed = array(); foreach (module::available() as $id => $module) { if ($id == "gallery") { continue; } if ($module->active && $module->code_version != $module->version) { - module::upgrade($id); + try { + module::upgrade($id); + } catch (Exception $e) { + // @todo assume it's MODULE_FAILED_TO_UPGRADE for now + $failed[] = $id; + } } } + // If the upgrade failed, this will get recreated + site_status::clear("upgrade_now"); + if (php_sapi_name() == "cli") { - print "Upgrade complete\n"; + if ($failed) { + print "Upgrade completed ** WITH FAILURES **\n"; + print "The following modules were not successfully upgraded:\n"; + print " " . implode($failed, "\n ") . "\n"; + print "Try getting newer versions or deactivating those modules\n"; + } else { + print "Upgrade complete\n"; + } } else { - url::redirect("upgrader"); + url::redirect("upgrader?failed=" . join(",", $failed)); } } } diff --git a/modules/gallery/controllers/uploader.php b/modules/gallery/controllers/uploader.php index fb496f60..168e8b2d 100644 --- a/modules/gallery/controllers/uploader.php +++ b/modules/gallery/controllers/uploader.php @@ -103,11 +103,14 @@ class Uploader_Controller extends Controller { } public function status($success_count, $error_count) { - // The "errors" won't be properly pluralized :-/ - print t2("Uploaded %count photo (%error errors)", - "Uploaded %count photos (%error errors)", - $success_count, - array("error" => $error_count)); + if ($error_count) { + // The "errors" won't be properly pluralized :-/ + print t2("Uploaded %count photo (%error errors)", + "Uploaded %count photos (%error errors)", + $success_count, + array("error" => $error_count)); + } else { + print t2("Uploaded %count photo", "Uploaded %count photos", $success_count);} } public function finish() { diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php index e992655b..4922416c 100644 --- a/modules/gallery/controllers/user_profile.php +++ b/modules/gallery/controllers/user_profile.php @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class User_Profile_Controller extends Controller { + public function show($id) { // If we get here, then we should have a user id other than guest. $user = identity::lookup_user($id); @@ -25,6 +26,10 @@ class User_Profile_Controller extends Controller { throw new Kohana_404_Exception(); } + if (!$this->_can_view_profile_pages($user)) { + throw new Kohana_404_Exception(); + } + $v = new Theme_View("page.html", "other", "profile"); $v->page_title = t("%name Profile", array("name" => $user->display_name())); $v->content = new View("user_profile.html"); @@ -44,12 +49,20 @@ class User_Profile_Controller extends Controller { public function contact($id) { $user = identity::lookup_user($id); + if (!$this->_can_view_profile_pages($user)) { + throw new Kohana_404_Exception(); + } + print user_profile::get_contact_form($user); } public function send($id) { access::verify_csrf(); $user = identity::lookup_user($id); + if (!$this->_can_view_profile_pages($user)) { + throw new Kohana_404_Exception(); + } + $form = user_profile::get_contact_form($user); if ($form->validate()) { Sendmail::factory() @@ -66,4 +79,30 @@ class User_Profile_Controller extends Controller { json::reply(array("result" => "error", "html" => (string)$form)); } } + + private function _can_view_profile_pages($user) { + if (!$user->loaded()) { + return false; + } + + if ($user->id == identity::active_user()->id) { + // You can always view your own profile + return true; + } + + switch (module::get_var("gallery", "show_user_profiles_to")) { + case "admin_users": + return identity::active_user()->admin; + + case "registered_users": + return !identity::active_user()->guest; + + case "everybody": + return true; + + default: + // Fail in private mode on an invalid setting + return false; + } + } } diff --git a/modules/gallery/css/upgrader.css b/modules/gallery/css/upgrader.css index d1b74c31..8610016e 100644 --- a/modules/gallery/css/upgrader.css +++ b/modules/gallery/css/upgrader.css @@ -58,6 +58,10 @@ tr.upgradeable td.gallery { color: #00d; } +tr.failed td { + color: red; +} + p { font-size: .9em; } @@ -120,12 +124,28 @@ div#dialog div { opacity: 0.5; } +.failed { + color: red; +} + pre { display: inline; margin: 0px; padding: 0px; } +div#upgrade_button { + margin-bottom: 20px; +} + +div#welcome_message { + margin-left: 30px; +} + +#logo { + margin-left: 14px; +} + .rtl { direction: rtl; } @@ -153,3 +173,11 @@ pre { .rtl div#dialog a.close { float: left; } + +.rtl div#welcome_message { + padding-right: 30px; +} + +.rtl #logo { + padding-right: 12px; +} diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php index f1ea00c0..52a36298 100644 --- a/modules/gallery/helpers/access.php +++ b/modules/gallery/helpers/access.php @@ -263,15 +263,15 @@ class access_Core { } /** - * Recalculate the permissions for a given item and its hierarchy. $item must be an album. + * Recalculate the permissions for an album's hierarchy. */ - static function recalculate_permissions($item) { + static function recalculate_album_permissions($album) { foreach (self::_get_all_groups() as $group) { foreach (ORM::factory("permission")->find_all() as $perm) { if ($perm->name == "view") { - self::_update_access_view_cache($group, $item); + self::_update_access_view_cache($group, $album); } else { - self::_update_access_non_view_cache($group, $perm->name, $item); + self::_update_access_non_view_cache($group, $perm->name, $album); } } } @@ -279,6 +279,28 @@ class access_Core { } /** + * Recalculate the permissions for a single photo. + */ + static function recalculate_photo_permissions($photo) { + $parent = $photo->parent(); + $parent_access_cache = ORM::factory("access_cache")->where("item_id", "=", $parent->id)->find(); + $photo_access_cache = ORM::factory("access_cache")->where("item_id", "=", $photo->id)->find(); + foreach (self::_get_all_groups() as $group) { + foreach (ORM::factory("permission")->find_all() as $perm) { + $field = "{$perm->name}_{$group->id}"; + if ($perm->name == "view") { + $photo->$field = $parent->$field; + } else { + $photo_access_cache->$field = $parent_access_cache->$field; + } + } + } + $photo_access_cache->save(); + $photo->save(); + model_cache::clear(); + } + + /** * Register a permission so that modules can use it. * * @param string $name The internal name for for this permission @@ -694,6 +716,7 @@ class access_Core { @mkdir(VARPATH . "security_test"); try { if ($fp = @fopen(VARPATH . "security_test/.htaccess", "w+")) { + fwrite($fp, "Options +FollowSymLinks\n"); fwrite($fp, "RewriteEngine On\n"); fwrite($fp, "RewriteRule verify $success_url [L]\n"); fclose($fp); diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php index 0ac5e8b0..89185e50 100644 --- a/modules/gallery/helpers/album.php +++ b/modules/gallery/helpers/album.php @@ -114,6 +114,7 @@ class album_Core { "captured" => t("Date captured"), "created" => t("Date uploaded"), "title" => t("Title"), + "name" => t("File name"), "updated" => t("Date modified"), "view_count" => t("Number of views"), "rand_key" => t("Random")); diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php index 3f83b23d..ca8c92c9 100644 --- a/modules/gallery/helpers/gallery.php +++ b/modules/gallery/helpers/gallery.php @@ -37,6 +37,30 @@ class gallery_Core { } /** + * If the gallery is only available to registered users and the user is not logged in, present + * the login page. + */ + static function private_gallery() { + if (Router::$controller != "login" && + Router::$controller != "combined" && + identity::active_user()->guest && + !access::user_can(identity::guest(), "view", item::root()) && + php_sapi_name() != "cli") { + if (Router::$controller == "admin") { + // At this point we're in the admin theme and it doesn't have a themed login page, so + // we can't just swap in the login controller and have it work. So redirect back to the + // root item where we'll run this code again with the site theme. + url::redirect(item::root()->abs_url()); + } else { + Session::instance()->set("continue_url", url::abs_current()); + Router::$controller = "login"; + Router::$controller_path = MODPATH . "gallery/controllers/login.php"; + Router::$method = "html"; + } + } + } + + /** * This function is called when the Gallery is fully initialized. We relay it to modules as the * "gallery_ready" event. Any module that wants to perform an action at the start of every * request should implement the <module>_event::gallery_ready() handler. diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index df5394c9..b59bb9b9 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -63,6 +63,8 @@ class gallery_event_Core { ->update("logs") ->set("user_id", $admin->id) ->execute(); + module::set_var("gallery", "email_from", $admin->email); + module::set_var("gallery", "email_reply_to", $admin->email); } static function group_created($group) { @@ -116,8 +118,8 @@ class gallery_event_Core { $batch_missing_album_cover[$parent->id] = 1; Session::instance()->set("batch_missing_album_cover", $batch_missing_album_cover); } else { - // Choose the first child as the new cover. - if ($child = $parent->children(1)->current()) { + // Choose the first viewable child as the new cover. + if ($child = $parent->viewable()->children(1)->current()) { item::make_album_cover($child); } } @@ -155,7 +157,11 @@ class gallery_event_Core { } static function item_moved($item, $old_parent) { - access::recalculate_permissions($item->parent()); + if ($item->is_album()) { + access::recalculate_album_permissions($item->parent()); + } else { + access::recalculate_photo_permissions($item); + } // If the new parent doesn't have an album cover, make this it. if (!$item->parent()->album_cover_item_id) { @@ -208,10 +214,10 @@ class gallery_event_Core { ->label($user->display_name())); if (Router::$controller == "admin") { - $continue_url = url::site(""); - } else if (isset($theme->item)) { + $continue_url = url::abs_site(""); + } else if ($item = $theme->item()) { if (access::user_can(identity::guest(), "view", $theme->item)) { - $continue_url = $theme->item->abs_url(); + $continue_url = $item->abs_url(); } else { $continue_url = item::root()->abs_url(); } @@ -547,4 +553,17 @@ class gallery_event_Core { $data->content[] = (object) array("title" => t("User information"), "view" => $v); } + + static function user_updated($original_user, $updated_user) { + // If the default from/reply-to email address is set to the install time placeholder value + // of unknown@unknown.com then adopt the value from the first admin to set their own email + // address so that we at least have a valid address for the Gallery. + if ($updated_user->admin) { + $email = module::get_var("gallery", "email_from", ""); + if ($email == "unknown@unknown.com") { + module::set_var("gallery", "email_from", $updated_user->email); + module::set_var("gallery", "email_reply_to", $updated_user->email); + } + } + } } diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index d5264fcc..83961d6b 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -302,14 +302,14 @@ class gallery_installer { module::set_var("gallery", "maintenance_mode", 0); module::set_var("gallery", "visible_title_length", 15); module::set_var("gallery", "favicon_url", "lib/images/favicon.ico"); - - // Sendmail configuration - module::set_var("gallery", "email_from", "admin@example.com"); - module::set_var("gallery", "email_reply_to", "public@example.com"); + module::set_var("gallery", "email_from", ""); + module::set_var("gallery", "email_reply_to", ""); module::set_var("gallery", "email_line_length", 70); module::set_var("gallery", "email_header_separator", serialize("\n")); + module::set_var("gallery", "show_user_profiles_to", "registered_users"); + module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin"); - module::set_version("gallery", 37); + module::set_version("gallery", 40); } static function upgrade($version) { @@ -550,7 +550,9 @@ class gallery_installer { } if ($version == 26) { - $db->query("RENAME TABLE {failed_logins} TO {failed_auths}"); + if (in_array("failed_logins", Database::instance()->list_tables())) { + $db->query("RENAME TABLE {failed_logins} TO {failed_auths}"); + } module::set_version("gallery", $version = 27); } @@ -611,6 +613,30 @@ class gallery_installer { module::set_var("gallery", "email_header_separator", serialize("\n")); module::set_version("gallery", $version = 37); } + + // Changed our minds and decided that the initial value should be empty + // But don't just reset it blindly, only do it if the value is version 37 default + if ($version == 37) { + $email = module::get_var("gallery", "email_from", ""); + if ($email == "admin@example.com") { + module::set_var("gallery", "email_from", ""); + } + $email = module::get_var("gallery", "email_reply_to", ""); + if ($email == "admin@example.com") { + module::set_var("gallery", "email_reply_to", ""); + } + module::set_version("gallery", $version = 38); + } + + if ($version == 38) { + module::set_var("gallery", "show_user_profiles_to", "registered_users"); + module::set_version("gallery", $version = 39); + } + + if ($version == 39) { + module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin"); + module::set_version("gallery", $version = 40); + } } static function uninstall() { diff --git a/modules/gallery/helpers/gallery_rss.php b/modules/gallery/helpers/gallery_rss.php index bec34912..fb617934 100644 --- a/modules/gallery/helpers/gallery_rss.php +++ b/modules/gallery/helpers/gallery_rss.php @@ -40,7 +40,7 @@ class gallery_rss_Core { ->order_by("created", "DESC"); $feed->max_pages = ceil($all_items->find_all()->count() / $limit); - $feed->title = t("Recent updates"); + $feed->title = t("%site_title - Recent updates", array("site_title" => item::root()->title)); $feed->description = t("Recent updates"); return $feed; @@ -53,7 +53,13 @@ class gallery_rss_Core { ->descendants($limit, $offset, array(array("type", "=", "photo"))); $feed->max_pages = ceil( $item->viewable()->descendants_count(array(array("type", "=", "photo"))) / $limit); - $feed->title = html::purify($item->title); + if ($item->id == item::root()->id) { + $feed->title = html::purify($item->title); + } else { + $feed->title = t("%site_title - %item_title", + array("site_title" => item::root()->title, + "item_title" => $item->title)); + } $feed->description = nl2br(html::purify($item->description)); return $feed; diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php index 0886aad0..3b173928 100644 --- a/modules/gallery/helpers/gallery_task.php +++ b/modules/gallery/helpers/gallery_task.php @@ -571,7 +571,7 @@ class gallery_task_Core { // The new cache rows are there, but they're incorrectly populated so we have to fix // them. If this turns out to be too slow, we'll have to refactor // access::recalculate_permissions to allow us to do it in slices. - access::recalculate_permissions(item::root()); + access::recalculate_album_permissions(item::root()); $state = self::FIX_STATE_DONE; } break; @@ -596,7 +596,7 @@ class gallery_task_Core { static function find_dupe_slugs() { return db::build() ->select_distinct( - array("parent_slug" => new Database_Expression("CONCAT(`parent_id`, ':', `slug`)"))) + array("parent_slug" => new Database_Expression("CONCAT(`parent_id`, ':', LOWER(`slug`))"))) ->select("id") ->select(array("C" => "COUNT(\"*\")")) ->from("items") @@ -608,7 +608,7 @@ class gallery_task_Core { static function find_dupe_names() { return db::build() ->select_distinct( - array("parent_name" => new Database_Expression("CONCAT(`parent_id`, ':', `name`)"))) + array("parent_name" => new Database_Expression("CONCAT(`parent_id`, ':', LOWER(`name`))"))) ->select("id") ->select(array("C" => "COUNT(\"*\")")) ->from("items") diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index bb085ea5..2868a28d 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -314,9 +314,10 @@ class graphics_Core { $toolkits->graphicsmagick->error = t("GraphicsMagick requires the <b>exec</b> function"); } else { $graphics_path = module::get_var("gallery", "graphics_toolkit_path", null); + $extra_binary_paths = module::get_var("gallery", "extra_binary_paths", null); putenv("PATH=" . getenv("PATH") . (empty($graphics_path) ? "" : ":$graphics_path") . - ":/usr/local/bin:/opt/local/bin:/opt/bin"); + ":" . $extra_binary_paths); // @todo: consider refactoring the two segments below into a loop since they are so // similar. diff --git a/modules/gallery/helpers/identity.php b/modules/gallery/helpers/identity.php index 5de05948..5ca024e9 100644 --- a/modules/gallery/helpers/identity.php +++ b/modules/gallery/helpers/identity.php @@ -233,14 +233,14 @@ class identity_Core { /** * @see IdentityProvider_Driver::add_user_to_group. */ - static function add_user_to_group($user, $group_id) { - return IdentityProvider::instance()->add_user_to_group($user, $group_id); + static function add_user_to_group($user, $group) { + return IdentityProvider::instance()->add_user_to_group($user, $group); } /** * @see IdentityProvider_Driver::remove_user_to_group. */ - static function remove_user_from_group($user, $group_id) { - return IdentityProvider::instance()->remove_user_from_group($user, $group_id); + static function remove_user_from_group($user, $group) { + return IdentityProvider::instance()->remove_user_from_group($user, $group); } }
\ No newline at end of file diff --git a/modules/gallery/helpers/locales.php b/modules/gallery/helpers/locales.php index aacb37ca..d1e72260 100644 --- a/modules/gallery/helpers/locales.php +++ b/modules/gallery/helpers/locales.php @@ -92,6 +92,7 @@ class locales_Core { $l["ko_KR"] = "한국어"; // Korean $l["lt_LT"] = "Lietuvių"; // Lithuanian $l["lv_LV"] = "Latviešu"; // Latvian + $l["mk_MK"] = "Македонски јазик"; // Macedonian $l["nl_NL"] = "Nederlands"; // Dutch $l["no_NO"] = "Norsk bokmål"; // Norwegian $l["pl_PL"] = "Polski"; // Polish @@ -103,6 +104,7 @@ class locales_Core { $l["sl_SI"] = "Slovenščina"; // Slovenian $l["sr_CS"] = "Srpski"; // Serbian $l["sv_SE"] = "Svenska"; // Swedish + $l["tn_ZA"] = "Setswana"; // Setswana $l["tr_TR"] = "Türkçe"; // Turkish $l["uk_UA"] = "українська"; // Ukrainian $l["vi_VN"] = "Tiếng Việt"; // Vietnamese diff --git a/modules/gallery/helpers/module.php b/modules/gallery/helpers/module.php index ca6651f1..7863520e 100644 --- a/modules/gallery/helpers/module.php +++ b/modules/gallery/helpers/module.php @@ -99,6 +99,10 @@ class module_Core { $m->code_version = $m->version; $m->version = self::get_version($module_name); $m->locked = false; + + if ($m->active && $m->version != $m->code_version) { + site_status::warning(t("Some of your modules are out of date. <a href=\"%upgrader_url\">Upgrade now!</a>", array("upgrader_url" => url::site("upgrader"))), "upgrade_now"); + } } // Lock certain modules @@ -139,7 +143,7 @@ class module_Core { } /** - * Allow modules to indicate the impact of deactivating the specifeid module + * Allow modules to indicate the impact of deactivating the specified module * @param string $module_name * @return array an array of warning or error messages to be displayed */ @@ -214,10 +218,10 @@ class module_Core { static function upgrade($module_name) { $version_before = module::get_version($module_name); $installer_class = "{$module_name}_installer"; + $available = module::available(); if (method_exists($installer_class, "upgrade")) { call_user_func_array(array($installer_class, "upgrade"), array($version_before)); } else { - $available = module::available(); if (isset($available->$module_name->code_version)) { module::set_version($module_name, $available->$module_name->code_version); } else { @@ -234,6 +238,10 @@ class module_Core { "version_before" => $version_before, "version_after" => $version_after))); } + + if ($version_after != $available->$module_name->code_version) { + throw new Exception("@todo MODULE_FAILED_TO_UPGRADE"); + } } /** @@ -448,7 +456,17 @@ class module_Core { $cache->module_name = "gallery"; $cache->name = "_cache"; $cache->value = serialize(self::$var_cache); - $cache->save(); + try { + $cache->save(); + } catch (Database_Exception $e) { + // There's a potential race condition here. Don't fail if that happens because it's + // bound to be transient and not a huge deal, but at least put something in the logs. + if (stristr($e->getMessage(), "duplicate entry")) { + Kohana_Log::add("error", "Failed to cache vars"); + } else { + throw $e; + } + } } } diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 3e55eefe..50339541 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -86,9 +86,10 @@ class movie_Core { static function find_ffmpeg() { if (!($ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) || !file_exists($ffmpeg_path)) { $graphics_path = module::get_var("gallery", "graphics_toolkit_path", null); + $extra_binary_paths = module::get_var("gallery", "extra_binary_paths", null); putenv("PATH=" . getenv("PATH") . (empty($graphics_path) ? "" : ":$graphics_path") . - ":/usr/local/bin:/opt/local/bin:/opt/bin"); + ":" . $extra_binary_paths); if (function_exists("exec")) { $ffmpeg_path = exec("which ffmpeg"); } diff --git a/modules/gallery/hooks/init_gallery.php b/modules/gallery/hooks/init_gallery.php index 64e44b56..10a74733 100644 --- a/modules/gallery/hooks/init_gallery.php +++ b/modules/gallery/hooks/init_gallery.php @@ -38,6 +38,7 @@ Event::add("system.ready", array("module", "load_modules")); Event::add("system.ready", array("gallery", "ready")); Event::add("system.post_routing", array("url", "parse_url")); Event::add("system.post_routing", array("gallery", "maintenance_mode")); +Event::add("system.post_routing", array("gallery", "private_gallery")); Event::add("system.shutdown", array("gallery", "shutdown")); // @todo once we convert to Kohana 2.4 this doesn't have to be here diff --git a/modules/gallery/libraries/Gallery_I18n.php b/modules/gallery/libraries/Gallery_I18n.php index f8068eec..6cb36f07 100644 --- a/modules/gallery/libraries/Gallery_I18n.php +++ b/modules/gallery/libraries/Gallery_I18n.php @@ -44,7 +44,7 @@ function t($message, $options=array()) { */ function t2($singular, $plural, $count, $options=array()) { return Gallery_I18n::instance()->translate(array("one" => $singular, "other" => $plural), - array_merge($options, array("count" => $count))); + array_merge($options, array("count" => $count))); } class Gallery_I18n_Core { @@ -175,7 +175,7 @@ class Gallery_I18n_Core { ->execute() as $row) { $translations[$row->key] = unserialize($row->translation); } - + // Override incoming with outgoing... foreach (db::build() ->select("key", "translation") @@ -184,7 +184,7 @@ class Gallery_I18n_Core { ->execute() as $row) { $translations[$row->key] = unserialize($row->translation); } - + $cache->set($cache_key, $translations, array("translation"), 0); } return $translations; diff --git a/modules/gallery/libraries/Sendmail.php b/modules/gallery/libraries/Sendmail.php index 0fa554b4..a93be736 100644 --- a/modules/gallery/libraries/Sendmail.php +++ b/modules/gallery/libraries/Sendmail.php @@ -35,12 +35,11 @@ class Sendmail_Core { public function __construct() { $this->headers = array(); - $domain = Input::instance()->server("HTTP_HOST"); - $this->from(module::get_var("gallery", "email_from", "admin@$domain")); - $this->reply_to(module::get_var("gallery", "email_reply_to", "public@$domain")); + $this->from(module::get_var("gallery", "email_from", "")); + $this->reply_to(module::get_var("gallery", "email_reply_to", "")); $this->line_length(module::get_var("gallery", "email_line_length", 70)); $separator = module::get_var("gallery", "email_header_separator", null); - $this->header_separator(empty($separator) ? "\n" : deserialize($separator)); + $this->header_separator(empty($separator) ? "\n" : unserialize($separator)); } public function __get($key) { diff --git a/modules/gallery/libraries/drivers/IdentityProvider.php b/modules/gallery/libraries/drivers/IdentityProvider.php index 3e85a57b..ac2473f5 100644 --- a/modules/gallery/libraries/drivers/IdentityProvider.php +++ b/modules/gallery/libraries/drivers/IdentityProvider.php @@ -116,17 +116,17 @@ interface IdentityProvider_Driver { /** * Add the user to the specified group - * @param User_Definition the user to add to the group - * @param int the group_id + * @param User_Definition the user to add + * @param Group_Definition the target group */ - static function add_user_to_group($user, $group_id); + public function add_user_to_group($user, $group); /** * Remove the user to the specified group - * @param User_Definition the user to add to the group - * @param int the group id + * @param User_Definition the user to remove + * @param Group_Definition the owning group */ - static function remove_user_from_group($user, $group_id); + public function remove_user_from_group($user, $group); } // End Identity Driver Definition interface Group_Definition {} diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 1db766e9..7bcf1f31 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Item_Model extends ORM_MPTT { +class Item_Model_Core extends ORM_MPTT { protected $children = "items"; protected $sorting = array(); protected $data_file = null; @@ -357,26 +357,7 @@ class Item_Model extends ORM_MPTT { } } - // Randomize the name or slug if there's a conflict. Preserve the extension. - // @todo Improve this. Random numbers are not user friendly - $base_name = pathinfo($this->name, PATHINFO_FILENAME); - $base_ext = pathinfo($this->name, PATHINFO_EXTENSION); - $base_slug = $this->slug; - while (ORM::factory("item") - ->where("parent_id", "=", $this->parent_id) - ->and_open() - ->where("name", "=", $this->name) - ->or_where("slug", "=", $this->slug) - ->close() - ->find()->id) { - $rand = rand(); - if ($base_ext) { - $this->name = "$base_name-$rand.$base_ext"; - } else { - $this->name = "$base_name-$rand"; - } - $this->slug = "$base_slug-$rand"; - } + $this->_randomize_name_or_slug_on_conflict(); parent::save(); @@ -427,6 +408,8 @@ class Item_Model extends ORM_MPTT { $this->relative_url_cache = null; } + $this->_randomize_name_or_slug_on_conflict(); + parent::save(); // Now update the filesystem and any database caches if there were significant value @@ -505,6 +488,33 @@ class Item_Model extends ORM_MPTT { } /** + * Check to see if there's another item that occupies the same name or slug that this item + * intends to use, and if so choose a new name/slug while preserving the extension. + * @todo Improve this. Random numbers are not user friendly + */ + private function _randomize_name_or_slug_on_conflict() { + $base_name = pathinfo($this->name, PATHINFO_FILENAME); + $base_ext = pathinfo($this->name, PATHINFO_EXTENSION); + $base_slug = $this->slug; + while (ORM::factory("item") + ->where("parent_id", "=", $this->parent_id) + ->where("id", "<>", $this->id) + ->and_open() + ->where("name", "=", $this->name) + ->or_where("slug", "=", $this->slug) + ->close() + ->find()->id) { + $rand = rand(); + if ($base_ext) { + $this->name = "$base_name-$rand.$base_ext"; + } else { + $this->name = "$base_name-$rand"; + } + $this->slug = "$base_slug-$rand"; + } + } + + /** * Return the Item_Model representing the cover for this album. * @return Item_Model or null if there's no cover */ @@ -530,7 +540,7 @@ class Item_Model extends ORM_MPTT { * the first child in the album is at position 1. */ public function get_position($child, $where=array()) { - if ($this->sort_order == "DESC") { + if (!strcasecmp($this->sort_order, "DESC")) { $comp = ">"; } else { $comp = "<"; @@ -975,23 +985,32 @@ class Item_Model extends ORM_MPTT { } unset($data["album_cover_item_id"]); - if (access::can("view_full", $this) && !$this->is_album()) { - $data["file_url"] = rest::url("data", $this, "full"); - } - if (access::user_can(identity::guest(), "view_full", $this)) { - $data["file_url_public"] = $this->file_url(true); + $data["web_url"] = $this->abs_url(); + + if (!$this->is_album()) { + if (access::can("view_full", $this)) { + $data["file_url"] = rest::url("data", $this, "full"); + $data["file_size"] = filesize($this->file_path()); + } + if (access::user_can(identity::guest(), "view_full", $this)) { + $data["file_url_public"] = $this->file_url(true); + } } if ($this->is_photo()) { $data["resize_url"] = rest::url("data", $this, "resize"); + $data["resize_size"] = filesize($this->resize_path()); if (access::user_can(identity::guest(), "view", $this)) { $data["resize_url_public"] = $this->resize_url(true); } } - $data["thumb_url"] = rest::url("data", $this, "thumb"); - if (access::user_can(identity::guest(), "view", $this)) { - $data["thumb_url_public"] = $this->thumb_url(true); + if ($this->has_thumb()) { + $data["thumb_url"] = rest::url("data", $this, "thumb"); + $data["thumb_size"] = filesize($this->thumb_path()); + if (access::user_can(identity::guest(), "view", $this)) { + $data["thumb_url_public"] = $this->thumb_url(true); + } } $data["can_edit"] = access::can("edit", $this); diff --git a/modules/gallery/module.info b/modules/gallery/module.info index 901158b5..1155ddf7 100644 --- a/modules/gallery/module.info +++ b/modules/gallery/module.info @@ -1,3 +1,3 @@ name = "Gallery 3" description = "Gallery core application" -version = 37 +version = 40 diff --git a/modules/gallery/tests/Access_Helper_Test.php b/modules/gallery/tests/Access_Helper_Test.php index c092e3fd..32b3020f 100644 --- a/modules/gallery/tests/Access_Helper_Test.php +++ b/modules/gallery/tests/Access_Helper_Test.php @@ -359,11 +359,13 @@ class Access_Helper_Test extends Gallery_Unit_Test_Case { $public_album = test::random_album(); $public_photo = test::random_photo($public_album); access::allow(identity::everybody(), "view", $public_album); + access::allow(identity::everybody(), "edit", $public_album); item::root()->reload(); // Account for MPTT changes $private_album = test::random_album(); access::deny(identity::everybody(), "view", $private_album); + access::deny(identity::everybody(), "edit", $private_album); $private_photo = test::random_photo($private_album); // Make sure that we now have a public photo and private photo. @@ -385,6 +387,8 @@ class Access_Helper_Test extends Gallery_Unit_Test_Case { // Make sure that the public_photo is now private, and the private_photo is now public. $this->assert_false(access::group_can(identity::everybody(), "view", $public_photo)); + $this->assert_false(access::group_can(identity::everybody(), "edit", $public_photo)); $this->assert_true(access::group_can(identity::everybody(), "view", $private_photo)); + $this->assert_true(access::group_can(identity::everybody(), "edit", $private_photo)); } } diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php index bd123098..90c54e3c 100644 --- a/modules/gallery/tests/Item_Model_Test.php +++ b/modules/gallery/tests/Item_Model_Test.php @@ -136,20 +136,17 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { $this->assert_true(false, "Shouldn't get here"); } - public function item_rename_fails_with_existing_name_test() { + public function item_rename_over_existing_name_gets_uniqified_test() { // Create a test photo $item = test::random_photo(); $item2 = test::random_photo(); - try { - $item->name = $item2->name; - $item->save(); - } catch (ORM_Validation_Exception $e) { - $this->assert_true(in_array("conflict", $e->validation->errors())); - return; - } + $item->name = $item2->name; + $item->save(); - $this->assert_false(true, "rename should conflict"); + // foo.jpg should become foo-####.jpg + $this->assert_true( + preg_match("/" . str_replace(".jpg", "", $item2->name) . "-\d+\.jpg/", $item->name)); } public function move_album_test() { @@ -208,24 +205,21 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { $this->assert_equal("file", file_get_contents($photo->file_path())); } - public function move_album_fails_conflicting_target_test() { + public function move_album_with_conflicting_target_gets_uniqified_test() { $album = test::random_album(); $source = test::random_album_unsaved($album); $source->name = $album->name; $source->save(); // $source and $album have the same name, so if we move $source into the root they should - // conflict. + // conflict and get randomized - try { - $source->parent_id = item::root()->id; - $source->save(); - } catch (ORM_Validation_Exception $e) { - $this->assert_equal( - array("name" => "conflict", "slug" => "conflict"), $e->validation->errors()); - return; - } - $this->assert_true(false, "Shouldn't get here"); + $source->parent_id = item::root()->id; + $source->save(); + + // foo should become foo-#### + $this->assert_true(preg_match("/{$album->name}-\d+/", $source->name)); + $this->assert_true(preg_match("/{$album->slug}-\d+/", $source->slug)); } public function move_album_fails_wrong_target_type_test() { @@ -245,7 +239,7 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { $this->assert_true(false, "Shouldn't get here"); } - public function move_photo_fails_conflicting_target_test() { + public function move_photo_with_conflicting_target_gets_uniqified_test() { $photo1 = test::random_photo(); $album = test::random_album(); $photo2 = test::random_photo_unsaved($album); @@ -253,18 +247,17 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { $photo2->save(); // $photo1 and $photo2 have the same name, so if we move $photo1 into the root they should - // conflict. + // conflict and get uniqified. - try { - $photo2->parent_id = item::root()->id; - $photo2->save(); - } catch (Exception $e) { - // pass - $this->assert_equal( - array("name" => "conflict", "slug" => "conflict"), $e->validation->errors()); - return; - } - $this->assert_true(false, "Shouldn't get here"); + $photo2->parent_id = item::root()->id; + $photo2->save(); + + // foo.jpg should become foo-####.jpg + $this->assert_true( + preg_match("/" . str_replace(".jpg", "", $photo1->name) . "-\d+\.jpg/", $photo2->name)); + + // foo should become foo + $this->assert_true(preg_match("/{$photo1->slug}/", $photo2->name)); } public function move_album_inside_descendent_fails_test() { diff --git a/modules/gallery/tests/Sendmail_Test.php b/modules/gallery/tests/Sendmail_Test.php index 92974e5c..aee6abf5 100644 --- a/modules/gallery/tests/Sendmail_Test.php +++ b/modules/gallery/tests/Sendmail_Test.php @@ -19,24 +19,18 @@ */ class Sendmail_Test extends Gallery_Unit_Test_Case { public function setup() { - Kohana_Config::instance()->set("sendmail.from", "from@gallery3.com"); + module::set_var("gallery", "email_from", "from@gallery3.com"); + module::set_var("gallery", "email_reply_to", "reply_to@gallery3.com"); } - public function sendmail_test() { - $domain = Input::instance()->server("HTTP_HOST"); + public function sendmail_basic_test() { $expected = "To: receiver@someemail.com\r\n" . "From: from@gallery3.com\n" . - "Reply-To: public@$domain\r\n" . + "Reply-To: reply_to@gallery3.com\r\n" . "Subject: Test Email Unit test\r\n\r\n" . "The mail message body"; $result = Sendmail_For_Test::factory() ->to("receiver@someemail.com") - /* - * @todo figure out why this test fails so badly, when the following - * line is not supplied. It doesn't seem to be set by setup method - * as you would expect. - */ - ->from("from@gallery3.com") ->subject("Test Email Unit test") ->message("The mail message body") ->send() @@ -46,16 +40,15 @@ class Sendmail_Test extends Gallery_Unit_Test_Case { } public function sendmail_reply_to_test() { - $domain = Input::instance()->server("HTTP_HOST"); $expected = "To: receiver@someemail.com\r\n" . - "From: admin@$domain\n" . - "Reply-To: reply-to@gallery3.com\r\n" . + "From: from@gallery3.com\n" . + "Reply-To: reply_to@gallery3.com\r\n" . "Subject: Test Email Unit test\r\n\r\n" . "The mail message body"; $result = Sendmail_For_Test::factory() ->to("receiver@someemail.com") ->subject("Test Email Unit test") - ->reply_to("reply-to@gallery3.com") + ->reply_to("reply_to@gallery3.com") ->message("The mail message body") ->send() ->send_text; @@ -63,10 +56,9 @@ class Sendmail_Test extends Gallery_Unit_Test_Case { } public function sendmail_html_message_test() { - $domain = Input::instance()->server("HTTP_HOST"); $expected = "To: receiver@someemail.com\r\n" . - "From: admin@$domain\n" . - "Reply-To: public@$domain\n" . + "From: from@gallery3.com\n" . + "Reply-To: reply_to@gallery3.com\n" . "MIME-Version: 1.0\n" . "Content-Type: text/html; charset=UTF-8\r\n" . "Subject: Test Email Unit test\r\n\r\n" . @@ -85,8 +77,8 @@ class Sendmail_Test extends Gallery_Unit_Test_Case { public function sendmail_wrapped_message_test() { $domain = Input::instance()->server("HTTP_HOST"); $expected = "To: receiver@someemail.com\r\n" . - "From: admin@$domain\n" . - "Reply-To: public@$domain\r\n" . + "From: from@gallery3.com\n" . + "Reply-To: reply_to@gallery3.com\r\n" . "Subject: Test Email Unit test\r\n\r\n" . "This is a long message that needs to go\n" . "over forty characters If we get lucky we\n" . diff --git a/modules/gallery/tests/controller_auth_data.txt b/modules/gallery/tests/controller_auth_data.txt index 8b776fb9..03032fd9 100644 --- a/modules/gallery/tests/controller_auth_data.txt +++ b/modules/gallery/tests/controller_auth_data.txt @@ -15,8 +15,9 @@ modules/gallery/controllers/login.php html modules/gallery/controllers/login.php auth_html DIRTY_AUTH modules/gallery/controllers/logout.php index DIRTY_AUTH modules/gallery/controllers/quick.php form_edit DIRTY_CSRF -modules/gallery/controllers/upgrader.php index DIRTY_AUTH +modules/gallery/controllers/upgrader.php index DIRTY_CSRF|DIRTY_AUTH modules/gallery/controllers/uploader.php start DIRTY_AUTH +modules/gallery/controllers/uploader.php status DIRTY_AUTH modules/gallery/controllers/uploader.php finish DIRTY_AUTH modules/gallery/controllers/user_profile.php show DIRTY_AUTH modules/gallery/controllers/user_profile.php contact DIRTY_AUTH diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt index 3eae3d07..6821c963 100644 --- a/modules/gallery/tests/xss_data.txt +++ b/modules/gallery/tests/xss_data.txt @@ -42,7 +42,7 @@ modules/digibug/views/digibug_form.html.php 4 DIRTY form:: modules/digibug/views/digibug_form.html.php 6 DIRTY form::hidden($key,$value) modules/exif/views/exif_dialog.html.php 14 DIRTY $details[$i]["caption"] modules/exif/views/exif_dialog.html.php 21 DIRTY $details[$i]["caption"] -modules/g2_import/views/admin_g2_import.html.php 30 DIRTY $form +modules/g2_import/views/admin_g2_import.html.php 9 DIRTY $form modules/gallery/views/admin_advanced_settings.html.php 21 DIRTY_ATTR text::alternate("g-odd","g-even") modules/gallery/views/admin_advanced_settings.html.php 22 DIRTY $var->module_name modules/gallery/views/admin_block_log_entries.html.php 4 DIRTY_ATTR log::severity_class($entry->severity) @@ -88,15 +88,15 @@ modules/gallery/views/admin_maintenance.html.php 87 DIRTY_ATTR $tas modules/gallery/views/admin_maintenance.html.php 88 DIRTY gallery::date_time($task->updated) modules/gallery/views/admin_maintenance.html.php 91 DIRTY $task->name modules/gallery/views/admin_maintenance.html.php 106 DIRTY $task->status -modules/gallery/views/admin_maintenance.html.php 157 DIRTY_ATTR text::alternate("g-odd","g-even") -modules/gallery/views/admin_maintenance.html.php 157 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" -modules/gallery/views/admin_maintenance.html.php 158 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" -modules/gallery/views/admin_maintenance.html.php 159 DIRTY gallery::date_time($task->updated) -modules/gallery/views/admin_maintenance.html.php 162 DIRTY $task->name -modules/gallery/views/admin_maintenance.html.php 174 DIRTY $task->status +modules/gallery/views/admin_maintenance.html.php 162 DIRTY_ATTR text::alternate("g-odd","g-even") +modules/gallery/views/admin_maintenance.html.php 162 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" +modules/gallery/views/admin_maintenance.html.php 163 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" +modules/gallery/views/admin_maintenance.html.php 164 DIRTY gallery::date_time($task->updated) +modules/gallery/views/admin_maintenance.html.php 167 DIRTY $task->name +modules/gallery/views/admin_maintenance.html.php 179 DIRTY $task->status modules/gallery/views/admin_maintenance_show_log.html.php 8 DIRTY_JS url::site("admin/maintenance/save_log/$task->id?csrf=$csrf") modules/gallery/views/admin_maintenance_show_log.html.php 13 DIRTY $task->name -modules/gallery/views/admin_maintenance_task.html.php 55 DIRTY $task->name +modules/gallery/views/admin_maintenance_task.html.php 75 DIRTY $task->name modules/gallery/views/admin_modules.html.php 51 DIRTY access::csrf_form_field() modules/gallery/views/admin_modules.html.php 60 DIRTY_ATTR text::alternate("g-odd","g-even") modules/gallery/views/admin_modules.html.php 63 DIRTY form::checkbox($data,'1',module::is_active($module_name)) @@ -109,7 +109,7 @@ modules/gallery/views/admin_sidebar.html.php 50 DIRTY $avail modules/gallery/views/admin_sidebar.html.php 58 DIRTY $active modules/gallery/views/admin_sidebar_blocks.html.php 4 DIRTY_ATTR $ref modules/gallery/views/admin_sidebar_blocks.html.php 4 DIRTY $text -modules/gallery/views/admin_theme_options.html.php 36 DIRTY $form +modules/gallery/views/admin_theme_options.html.php 5 DIRTY $form modules/gallery/views/admin_themes.html.php 3 DIRTY_JS url::site("admin/themes/choose") modules/gallery/views/admin_themes.html.php 5 DIRTY_JS $csrf modules/gallery/views/admin_themes.html.php 22 DIRTY $themes[$site]->name @@ -168,10 +168,13 @@ modules/gallery/views/error_admin.html.php 284 DIRTY $var modules/gallery/views/error_admin.html.php 285 DIRTY_ATTR $env_id modules/gallery/views/error_admin.html.php 291 DIRTY $key modules/gallery/views/error_admin.html.php 295 DIRTY Kohana_Exception::safe_dump($value,$key) -modules/gallery/views/form_uploadify.html.php 9 DIRTY_JS url::file("lib/uploadify/uploadify.swf") -modules/gallery/views/form_uploadify.html.php 10 DIRTY_JS url::site("uploader/add_photo/{$album->id}") -modules/gallery/views/form_uploadify.html.php 14 DIRTY_JS url::file("lib/uploadify/cancel.png") -modules/gallery/views/form_uploadify.html.php 15 DIRTY_JS $simultaneous_upload_limit +modules/gallery/views/form_uploadify.html.php 16 DIRTY_JS url::site("uploader/status/_S/_E") +modules/gallery/views/form_uploadify.html.php 24 DIRTY_JS $flash_minimum_version +modules/gallery/views/form_uploadify.html.php 28 DIRTY_JS url::file("lib/uploadify/uploadify.swf") +modules/gallery/views/form_uploadify.html.php 29 DIRTY_JS url::site("uploader/add_photo/{$album->id}") +modules/gallery/views/form_uploadify.html.php 33 DIRTY_JS url::file("lib/uploadify/cancel.png") +modules/gallery/views/form_uploadify.html.php 34 DIRTY_JS $simultaneous_upload_limit +modules/gallery/views/form_uploadify.html.php 160 DIRTY_ATTR request::protocol() modules/gallery/views/in_place_edit.html.php 2 DIRTY form::open($action,array("method"=>"post","id"=>"g-in-place-edit-form","class"=>"g-short-form")) modules/gallery/views/in_place_edit.html.php 3 DIRTY access::csrf_form_field() modules/gallery/views/in_place_edit.html.php 6 DIRTY form::input("input",$form["input"]," class=\"textbox\"") @@ -207,17 +210,6 @@ modules/gallery/views/menu_dialog.html.php 5 DIRTY_JS $menu- modules/gallery/views/menu_link.html.php 3 DIRTY $menu->css_id?"id='{$menu->css_id}'":"" modules/gallery/views/menu_link.html.php 4 DIRTY_ATTR $menu->css_class modules/gallery/views/menu_link.html.php 5 DIRTY_JS $menu->url -modules/gallery/views/move_browse.html.php 5 DIRTY_JS url::site("move/show_sub_tree/{$source->id}/__TARGETID__") -modules/gallery/views/move_browse.html.php 40 DIRTY $tree -modules/gallery/views/move_browse.html.php 44 DIRTY access::csrf_form_field() -modules/gallery/views/move_tree.html.php 2 DIRTY $parent->thumb_img(array(),25); -modules/gallery/views/move_tree.html.php 4 DIRTY_JS $parent->id -modules/gallery/views/move_tree.html.php 6 DIRTY_JS $parent->id -modules/gallery/views/move_tree.html.php 8 DIRTY_ATTR $parent->id -modules/gallery/views/move_tree.html.php 10 DIRTY_ATTR $child->id -modules/gallery/views/move_tree.html.php 11 DIRTY $child->thumb_img(array(),25); -modules/gallery/views/move_tree.html.php 13 DIRTY_JS $child->id -modules/gallery/views/move_tree.html.php 15 DIRTY_JS $child->id modules/gallery/views/movieplayer.html.php 2 DIRTY html::anchor($item->file_url(true),"",$attrs) modules/gallery/views/movieplayer.html.php 5 DIRTY_JS $attrs["id"] modules/gallery/views/movieplayer.html.php 7 DIRTY_JS url::abs_file("lib/flowplayer.swf") @@ -256,14 +248,15 @@ modules/gallery/views/permissions_form.html.php 80 DIRTY_JS $permi modules/gallery/views/permissions_form.html.php 80 DIRTY_JS $item->id modules/gallery/views/quick_delete_confirm.html.php 11 DIRTY $form modules/gallery/views/reauthenticate.html.php 9 DIRTY $form -modules/gallery/views/upgrader.html.php 59 DIRTY_ATTR $done?"muted":"" -modules/gallery/views/upgrader.html.php 63 DIRTY_ATTR $done?"muted":"" -modules/gallery/views/upgrader.html.php 71 DIRTY_ATTR $module->version==$module->code_version?"current":"upgradeable" -modules/gallery/views/upgrader.html.php 72 DIRTY_ATTR $id -modules/gallery/views/upgrader.html.php 76 DIRTY $module->version -modules/gallery/views/upgrader.html.php 79 DIRTY $module->code_version -modules/gallery/views/upgrader.html.php 101 DIRTY_ATTR $done?"muted":"" -modules/gallery/views/upgrader.html.php 104 DIRTY_ATTR $done?"muted":"" +modules/gallery/views/upgrader.html.php 76 DIRTY_ATTR $done?"muted":"" +modules/gallery/views/upgrader.html.php 94 DIRTY_ATTR $done?"muted":"" +modules/gallery/views/upgrader.html.php 102 DIRTY_ATTR $module->version==$module->code_version?"current":"upgradeable" +modules/gallery/views/upgrader.html.php 102 DIRTY_ATTR in_array($id,$failed)?"failed":"" +modules/gallery/views/upgrader.html.php 103 DIRTY_ATTR $id +modules/gallery/views/upgrader.html.php 107 DIRTY $module->version +modules/gallery/views/upgrader.html.php 110 DIRTY $module->code_version +modules/gallery/views/upgrader.html.php 120 DIRTY_ATTR $done?"muted":"" +modules/gallery/views/upgrader.html.php 123 DIRTY_ATTR $done?"muted":"" modules/gallery/views/user_languages_block.html.php 2 DIRTY form::dropdown("g-select-session-locale",$installed_locales,$selected) modules/gallery/views/user_profile.html.php 34 DIRTY_ATTR $user->avatar_url(40,$theme->url(,true)) modules/gallery/views/user_profile.html.php 43 DIRTY $info->view @@ -288,10 +281,11 @@ modules/organize/views/organize_dialog.html.php 93 DIRTY_JS $file_ modules/organize/views/organize_dialog.html.php 94 DIRTY_JS $sort_order modules/organize/views/organize_dialog.html.php 95 DIRTY_JS $sort_fields modules/organize/views/organize_dialog.html.php 96 DIRTY_JS $album->id -modules/organize/views/organize_dialog.html.php 97 DIRTY_JS $rest_uri -modules/organize/views/organize_dialog.html.php 98 DIRTY_JS $controller_uri -modules/organize/views/organize_dialog.html.php 104 DIRTY_JS $flash_minimum_version="10.0.0" -modules/organize/views/organize_dialog.html.php 122 DIRTY_JS $swf_uri +modules/organize/views/organize_dialog.html.php 97 DIRTY_JS $selected_id +modules/organize/views/organize_dialog.html.php 98 DIRTY_JS $rest_uri +modules/organize/views/organize_dialog.html.php 99 DIRTY_JS $controller_uri +modules/organize/views/organize_dialog.html.php 105 DIRTY_JS $flash_minimum_version="10.0.0" +modules/organize/views/organize_dialog.html.php 123 DIRTY_JS $swf_uri modules/organize/views/organize_dialog.html.php 136 DIRTY_ATTR request::protocol() modules/recaptcha/views/admin_recaptcha.html.php 11 DIRTY $form modules/recaptcha/views/admin_recaptcha.html.php 23 DIRTY_JS $public_key @@ -337,23 +331,25 @@ modules/server_add/views/server_add_tree_dialog.html.php 4 DIRTY_JS url::s modules/server_add/views/server_add_tree_dialog.html.php 21 DIRTY $tree modules/tag/views/admin_tags.html.php 45 DIRTY_ATTR $tag->id modules/tag/views/admin_tags.html.php 46 DIRTY $tag->count -modules/tag/views/tag_block.html.php 25 DIRTY $cloud -modules/tag/views/tag_block.html.php 27 DIRTY $form +modules/tag/views/tag_block.html.php 26 DIRTY $cloud +modules/tag/views/tag_block.html.php 28 DIRTY $form modules/tag/views/tag_cloud.html.php 4 DIRTY_ATTR (int)(($tag->count/$max_count)*7) modules/tag/views/tag_cloud.html.php 5 DIRTY $tag->count modules/tag/views/tag_cloud.html.php 6 DIRTY_JS $tag->url() modules/user/views/admin_users.html.php 3 DIRTY_JS url::site("admin/users/add_user_to_group/__USERID__/__GROUPID__?csrf=$csrf") modules/user/views/admin_users.html.php 26 DIRTY_JS url::site("admin/users/group/__GROUPID__") modules/user/views/admin_users.html.php 36 DIRTY_JS url::site("admin/users/remove_user_from_group/__USERID__/__GROUPID__?csrf=$csrf") -modules/user/views/admin_users.html.php 71 DIRTY_ATTR $user->id -modules/user/views/admin_users.html.php 71 DIRTY_ATTR text::alternate("g-odd","g-even") -modules/user/views/admin_users.html.php 71 DIRTY_ATTR $user->admin?"g-admin":"" modules/user/views/admin_users.html.php 72 DIRTY_ATTR $user->id -modules/user/views/admin_users.html.php 73 DIRTY_ATTR $user->avatar_url(20,$theme->url(,true)) -modules/user/views/admin_users.html.php 87 DIRTY ($user->last_login==0)?"":gallery::date($user->last_login) -modules/user/views/admin_users.html.php 123 DIRTY_ATTR $group->id -modules/user/views/admin_users.html.php 123 DIRTY_ATTR ($group->special?"g-default-group":"") -modules/user/views/admin_users.html.php 125 DIRTY $v +modules/user/views/admin_users.html.php 72 DIRTY_ATTR text::alternate("g-odd","g-even") +modules/user/views/admin_users.html.php 72 DIRTY_ATTR $user->admin?"g-admin":"" +modules/user/views/admin_users.html.php 73 DIRTY_ATTR $user->id +modules/user/views/admin_users.html.php 74 DIRTY_ATTR $user->avatar_url(20,$theme->url(,true)) +modules/user/views/admin_users.html.php 88 DIRTY ($user->last_login==0)?"":gallery::date($user->last_login) +modules/user/views/admin_users.html.php 91 DIRTY db::build()->from("items")->where("owner_id","=",$user->id)->count_records() +modules/user/views/admin_users.html.php 127 DIRTY_ATTR $group->id +modules/user/views/admin_users.html.php 127 DIRTY_ATTR ($group->special?"g-default-group":"") +modules/user/views/admin_users.html.php 129 DIRTY $v +modules/user/views/admin_users_delete_user.html.php 6 DIRTY $form modules/user/views/admin_users_group.html.php 24 DIRTY_JS $user->id modules/user/views/admin_users_group.html.php 24 DIRTY_JS $group->id modules/watermark/views/admin_watermarks.html.php 20 DIRTY_ATTR $width @@ -385,10 +381,10 @@ themes/admin_wind/views/pager.html.php 37 DIRTY_JS str_re themes/wind/views/album.html.php 16 DIRTY_ATTR $child->id themes/wind/views/album.html.php 16 DIRTY_ATTR $item_class themes/wind/views/album.html.php 18 DIRTY_JS $child->url() -themes/wind/views/album.html.php 19 DIRTY $child->thumb_img(array("class"=>"g-thumbnail")) -themes/wind/views/album.html.php 23 DIRTY_ATTR $item_class -themes/wind/views/album.html.php 24 DIRTY_JS $child->url() -themes/wind/views/album.html.php 42 DIRTY $theme->paginator() +themes/wind/views/album.html.php 20 DIRTY $child->thumb_img(array("class"=>"g-thumbnail")) +themes/wind/views/album.html.php 25 DIRTY_ATTR $item_class +themes/wind/views/album.html.php 26 DIRTY_JS $child->url() +themes/wind/views/album.html.php 44 DIRTY $theme->paginator() themes/wind/views/block.html.php 3 DIRTY_ATTR $anchor themes/wind/views/block.html.php 5 DIRTY_ATTR $css_id themes/wind/views/block.html.php 6 DIRTY $title @@ -410,16 +406,17 @@ themes/wind/views/page.html.php 44 DIRTY $thumb themes/wind/views/page.html.php 81 DIRTY $header_text themes/wind/views/page.html.php 83 DIRTY_JS item::root()->url() themes/wind/views/page.html.php 87 DIRTY $theme->user_menu() -themes/wind/views/page.html.php 108 DIRTY_JS $parent->url($parent==$theme->item()->parent()?"show={$theme->item()->id}":null) -themes/wind/views/page.html.php 126 DIRTY $content -themes/wind/views/page.html.php 132 DIRTY newView("sidebar.html") -themes/wind/views/page.html.php 139 DIRTY $footer_text +themes/wind/views/page.html.php 108 DIRTY_JS $parent->url($parent->id==$theme->item()->parent_id?"show={$theme->item()->id}":null) +themes/wind/views/page.html.php 129 DIRTY $content +themes/wind/views/page.html.php 135 DIRTY newView("sidebar.html") +themes/wind/views/page.html.php 142 DIRTY $footer_text themes/wind/views/paginator.html.php 33 DIRTY_JS $first_page_url themes/wind/views/paginator.html.php 42 DIRTY_JS $previous_page_url themes/wind/views/paginator.html.php 70 DIRTY_JS $next_page_url themes/wind/views/paginator.html.php 79 DIRTY_JS $last_page_url -themes/wind/views/photo.html.php 8 DIRTY_JS $theme->item()->width -themes/wind/views/photo.html.php 8 DIRTY_JS $theme->item()->height -themes/wind/views/photo.html.php 18 DIRTY $theme->paginator() -themes/wind/views/photo.html.php 23 DIRTY_JS $item->file_url() -themes/wind/views/photo.html.php 25 DIRTY $item->resize_img(array("id"=>"g-item-id-{$item->id}","class"=>"g-resize")) +themes/wind/views/photo.html.php 7 DIRTY_JS $theme->item()->width +themes/wind/views/photo.html.php 7 DIRTY_JS $theme->item()->height +themes/wind/views/photo.html.php 17 DIRTY_JS url::site("items/dimensions/".$theme->item()->id) +themes/wind/views/photo.html.php 31 DIRTY $theme->paginator() +themes/wind/views/photo.html.php 36 DIRTY_JS $item->file_url() +themes/wind/views/photo.html.php 38 DIRTY $item->resize_img(array("id"=>"g-item-id-{$item->id}","class"=>"g-resize")) diff --git a/modules/gallery/views/admin_block_platform.html.php b/modules/gallery/views/admin_block_platform.html.php index b1b8a2f9..379ab0aa 100644 --- a/modules/gallery/views/admin_block_platform.html.php +++ b/modules/gallery/views/admin_block_platform.html.php @@ -18,4 +18,7 @@ <li> <?= t("Server load: %load_average", array("load_average" => $load_average)) ?> </li> + <li> + <?= t("Graphics toolkit: %toolkit", array("toolkit" => module::get_var("gallery", "graphics_toolkit"))) ?> + </li> </ul> diff --git a/modules/gallery/views/admin_graphics.html.php b/modules/gallery/views/admin_graphics.html.php index 3a48e087..ae76f1e1 100644 --- a/modules/gallery/views/admin_graphics.html.php +++ b/modules/gallery/views/admin_graphics.html.php @@ -16,6 +16,7 @@ <h1> <?= t("Graphics settings") ?> </h1> <p> <?= t("Gallery needs a graphics toolkit in order to manipulate your photos. Please choose one from the list below.") ?> + <?= t("Can't decide which toolkit to choose? <a href=\"%url\">We can help!</a>", array("url" => "http://codex.gallery2.org/Gallery3:Choosing_A_Graphics_Toolkit")) ?> </p> <div class="g-block-content"> diff --git a/modules/gallery/views/admin_maintenance.html.php b/modules/gallery/views/admin_maintenance.html.php index 4bfc57f0..c28def1d 100644 --- a/modules/gallery/views/admin_maintenance.html.php +++ b/modules/gallery/views/admin_maintenance.html.php @@ -109,16 +109,21 @@ <?= html::clean($task->owner()->name) ?> </td> <td> - <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>" - class="g-button g-right ui-icon-left ui-state-default ui-corner-all"> - <?= t("cancel") ?> - </a> <? if ($task->state == "stalled"): ?> <a class="g-dialog-link g-button ui-icon-left ui-state-default ui-corner-all" href="<?= url::site("admin/maintenance/resume/$task->id?csrf=$csrf") ?>"> <?= t("resume") ?> </a> <? endif ?> + <? if ($task->get_log()): ?> + <a href="<?= url::site("admin/maintenance/show_log/$task->id?csrf=$csrf") ?>" class="g-dialog-link g-button ui-state-default ui-corner-all"> + <?= t("view log") ?> + </a> + <? endif ?> + <a href="<?= url::site("admin/maintenance/cancel/$task->id?csrf=$csrf") ?>" + class="g-button ui-icon-left ui-state-default ui-corner-all"> + <?= t("cancel") ?> + </a> </td> </tr> <? endforeach ?> @@ -183,7 +188,7 @@ </a> <? if ($task->get_log()): ?> <a href="<?= url::site("admin/maintenance/show_log/$task->id?csrf=$csrf") ?>" class="g-dialog-link g-button ui-state-default ui-corner-all"> - <?= t("browse log") ?> + <?= t("view log") ?> </a> <? endif ?> <? else: ?> diff --git a/modules/gallery/views/admin_maintenance_task.html.php b/modules/gallery/views/admin_maintenance_task.html.php index 76756b66..013ac01f 100644 --- a/modules/gallery/views/admin_maintenance_task.html.php +++ b/modules/gallery/views/admin_maintenance_task.html.php @@ -3,6 +3,7 @@ var target_value; var animation = null; var delta = 1; + var consecutive_error_count = 0; animate_progress_bar = function() { var current_value = parseInt($(".g-progress-bar div").css("width").replace("%", "")); if (target_value > current_value) { @@ -26,12 +27,15 @@ $.fn.gallery_hover_init(); } + var FAILED_MSG = <?= t("Something went wrong...sorry! <a>Retry</a> or check the task log for details")->for_js() ?>; + var ERROR_MSG = <?= t("Something went wrong! Trying again in a moment... (__COUNT__)")->for_js() ?>; update = function() { $.ajax({ url: <?= html::js_string(url::site("admin/maintenance/run/$task->id?csrf=$csrf")) ?>, dataType: "json", success: function(data) { target_value = data.task.percent_complete; + consecutive_error_count = 0; if (!animation) { animate_progress_bar(); } @@ -42,6 +46,22 @@ } else { setTimeout(update, 100); } + }, + error: function(req, textStatus, errorThrown) { + if (textStatus == "timeout" || textStatus == "parsererror") { + consecutive_error_count++; + if (consecutive_error_count == 5) { + $("#g-status").html(FAILED_MSG); + $("#g-pause-button").hide(); + $("#g-done-button").show(); + consecutive_error_count = 0; // in case of a manual retry + $("#g-status a").attr("href", "javascript:update()"); + } else { + $("#g-status").html(ERROR_MSG.replace("__COUNT__", consecutive_error_count)); + // Give a little time to back off before retrying + setTimeout(update, 1500 * consecutive_error_count); + } + } } }); } diff --git a/modules/gallery/views/form_uploadify.html.php b/modules/gallery/views/form_uploadify.html.php index 36f5f284..893bb3b9 100644 --- a/modules/gallery/views/form_uploadify.html.php +++ b/modules/gallery/views/form_uploadify.html.php @@ -60,7 +60,7 @@ $("#g-add-photos-status ul").append( "<li id=\"q" + queueID + "\" class=\"g-success\">" + fileObj.name + " - " + <?= t("Completed")->for_js() ?> + "</li>"); - setTimeout(function() { $("#q" + queueID).slideUp("slow") }, 5000); + setTimeout(function() { $("#q" + queueID).slideUp("slow").remove() }, 5000); success_count++; update_status(); return true; @@ -87,8 +87,8 @@ .replace("__TYPE__", errorObj.type)); } $("#g-add-photos-status ul").append( - "<li class=\"g-error\">" + fileObj.name + msg + "</li>"); - $("#g-uploadify" + queueID).remove(); + "<li id=\"q" + queueID + "\" class=\"g-error\">" + fileObj.name + msg + "</li>"); + $("#g-uploadify").uploadifyCancel(queueID); error_count++; update_status(); }, diff --git a/modules/gallery/views/upgrader.html.php b/modules/gallery/views/upgrader.html.php index 0ce24ef8..1ec49c77 100644 --- a/modules/gallery/views/upgrader.html.php +++ b/modules/gallery/views/upgrader.html.php @@ -10,7 +10,7 @@ </head> <body<? if (locales::is_rtl()) { echo ' class="rtl"'; } ?>> <div id="outer"> - <img src="<?= url::file("modules/gallery/images/gallery.png") ?>" /> + <img id="logo" src="<?= url::file("modules/gallery/images/gallery.png") ?>" /> <div id="inner"> <? if ($can_upgrade): ?> <div id="dialog" style="visibility: hidden"> @@ -31,6 +31,12 @@ array("url" => html::mark_clean(url::base()))) ?> </p> </div> + <div id="failed" style="display: none"> + <h1> <?= t("Some modules failed to upgrade!") ?> </h1> + <p> + <?= t("Failed modules are <span class=\"failed\">highlighted</span>. Try getting newer versions or <a href=\"%admin_modules\">deactivating those modules</a>.", array("admin_modules" => url::site("admin/modules"))) ?> + </p> + </div> </div> <script type="text/javascript"> $(document).ready(function() { @@ -41,6 +47,10 @@ <? if ($done): ?> show_done(); <? endif ?> + + <? if ($failed): ?> + show_failed(); + <? endif ?> }); var show_busy = function() { @@ -55,10 +65,31 @@ $("#done").show(); $("#dialog_close_link").show(); } + + var show_failed = function() { + $("#dialog").css("visibility", "visible"); + $("#failed").show(); + $("#dialog_close_link").show(); + } </script> - <p class="<?= $done ? "muted" : "" ?>"> - <?= t("Welcome to the Gallery upgrader. One click and you're done!") ?> - </p> + <div id="welcome_message"> + <p class="<?= $done ? "muted" : "" ?>"> + <?= t("Welcome to the Gallery upgrader. One click and you're done!") ?> + </p> + </div> + + <? if ($done): ?> + <div id="upgrade_button" class="button muted"> + <?= t("Upgrade all") ?> + </div> + <? else: ?> + <div id="upgrade_button" class="button button-active"> + <a id="upgrade_link" href="<?= url::site("upgrader/upgrade?csrf=" . access::csrf_token()) ?>"> + <?= t("Upgrade all") ?> + </a> + </div> + <? endif ?> + <table> <tr class="<?= $done ? "muted" : "" ?>"> <th class="name"> <?= t("Module name") ?> </th> @@ -68,7 +99,7 @@ <? foreach ($available as $id => $module): ?> <? if ($module->active): ?> - <tr class="<?= $module->version == $module->code_version ? "current" : "upgradeable" ?>" > + <tr class="<?= $module->version == $module->code_version ? "current" : "upgradeable" ?> <?= in_array($id, $failed) ? "failed" : "" ?>" > <td class="name <?= $id ?>"> <?= t($module->name) ?> </td> @@ -85,18 +116,6 @@ <? endforeach ?> </table> - <? if ($done): ?> - <div class="button muted"> - <?= t("Upgrade all") ?> - </div> - <? else: ?> - <div class="button button-active"> - <a id="upgrade_link" href="<?= url::site("upgrader/upgrade") ?>"> - <?= t("Upgrade all") ?> - </a> - </div> - <? endif ?> - <? if (@$inactive): ?> <p class="<?= $done ? "muted" : "" ?>"> <?= t("The following modules are inactive and don't require an upgrade.") ?> |