diff options
Diffstat (limited to 'modules/gallery')
47 files changed, 707 insertions, 347 deletions
diff --git a/modules/gallery/config/session.php b/modules/gallery/config/session.php index 990fa31f..6905e299 100644 --- a/modules/gallery/config/session.php +++ b/modules/gallery/config/session.php @@ -39,7 +39,7 @@ $config['name'] = 'g3sid'; /** * Session parameters to validate: user_agent, ip_address, expiration. */ -$config['validate'] = array('user_agent'); +$config['validate'] = array('user_agent', 'expiration'); /** * Enable or disable session encryption. diff --git a/modules/gallery/controllers/admin.php b/modules/gallery/controllers/admin.php index 7706e9fc..838c2b50 100644 --- a/modules/gallery/controllers/admin.php +++ b/modules/gallery/controllers/admin.php @@ -29,6 +29,9 @@ class Admin_Controller extends Controller { } public function __call($controller_name, $args) { + if (Input::instance()->get("reauth_check")) { + return self::_reauth_check(); + } if (auth::must_reauth_for_admin_area()) { return self::_prompt_for_reauth($controller_name, $args); } @@ -54,6 +57,24 @@ class Admin_Controller extends Controller { call_user_func_array(array(new $controller_name, $method), $args); } + private static function _reauth_check() { + $session = Session::instance(); + $last_active_auth = $session->get("active_auth_timestamp", 0); + $last_admin_area_activity = $session->get("admin_area_activity_timestamp", 0); + $admin_area_timeout = module::get_var("gallery", "admin_area_timeout"); + + $time_remaining = max($last_active_auth, $last_admin_area_activity) + + $admin_area_timeout - time(); + + $result = new stdClass(); + $result->result = "success"; + if ($time_remaining < 30) { + $result->location = url::abs_site(""); + } + + print json_encode($result); + } + private static function _prompt_for_reauth($controller_name, $args) { if (request::method() == "get" && !request::is_ajax()) { // Avoid anti-phishing protection by passing the url as session variable. diff --git a/modules/gallery/controllers/admin_maintenance.php b/modules/gallery/controllers/admin_maintenance.php index d90fe0ea..c16c5c41 100644 --- a/modules/gallery/controllers/admin_maintenance.php +++ b/modules/gallery/controllers/admin_maintenance.php @@ -209,9 +209,10 @@ class Admin_Maintenance_Controller extends Admin_Controller { message::success(t("Task failed")); break; } + // Using sprintf("%F") to avoid comma as decimal separator. print json_encode(array("result" => "success", "task" => array( - "percent_complete" => $task->percent_complete, + "percent_complete" => sprintf("%F", $task->percent_complete), "status" => (string) $task->status, "done" => (bool) $task->done), "location" => url::site("admin/maintenance"))); @@ -219,7 +220,7 @@ class Admin_Maintenance_Controller extends Admin_Controller { } else { print json_encode(array("result" => "in_progress", "task" => array( - "percent_complete" => $task->percent_complete, + "percent_complete" => sprintf("%F", $task->percent_complete), "status" => (string) $task->status, "done" => (bool) $task->done))); } diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index e1985cfb..036dade0 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -26,13 +26,10 @@ class Albums_Controller extends Items_Controller { if (!is_object($album)) { // show() must be public because we route to it in url::parse_url(), so make // sure that we're actually receiving an object - Kohana::show_404(); + throw new Kohana_404_Exception(); } - if (!access::can("view", $album)) { - print auth::require_login(); - return; - } + access::required("view", $album); $page_size = module::get_var("gallery", "page_size", 9); $input = Input::instance(); diff --git a/modules/gallery/controllers/l10n_client.php b/modules/gallery/controllers/l10n_client.php index e20bab50..be0aaa11 100644 --- a/modules/gallery/controllers/l10n_client.php +++ b/modules/gallery/controllers/l10n_client.php @@ -80,6 +80,8 @@ class L10n_Client_Controller extends Controller { $entry->save(); + Gallery_I18n::clear_cache($locale); + print json_encode(new stdClass()); } diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php index 8041066e..78a56e81 100644 --- a/modules/gallery/controllers/movies.php +++ b/modules/gallery/controllers/movies.php @@ -22,13 +22,10 @@ class Movies_Controller extends Items_Controller { if (!is_object($movie)) { // show() must be public because we route to it in url::parse_url(), so make // sure that we're actually receiving an object - Kohana::show_404(); + throw new Kohana_404_Exception(); } - if (!access::can("view", $movie)) { - print auth::require_login(); - return; - } + access::required("view", $movie); $where = array(array("type", "!=", "album")); $position = $movie->parent()->get_position($movie, $where); diff --git a/modules/gallery/controllers/packager.php b/modules/gallery/controllers/packager.php index 66626483..aef032a0 100644 --- a/modules/gallery/controllers/packager.php +++ b/modules/gallery/controllers/packager.php @@ -82,6 +82,7 @@ class Packager_Controller extends Controller { module::set_var("gallery", "blocks_{$key}", serialize($blocks)); } + Database::instance()->query("TRUNCATE {caches}"); Database::instance()->query("TRUNCATE {sessions}"); Database::instance()->query("TRUNCATE {logs}"); db::build() diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php index 778e9ae7..f2d47eec 100644 --- a/modules/gallery/controllers/photos.php +++ b/modules/gallery/controllers/photos.php @@ -22,14 +22,11 @@ class Photos_Controller extends Items_Controller { if (!is_object($photo)) { // show() must be public because we route to it in url::parse_url(), so make // sure that we're actually receiving an object - Kohana::show_404(); + throw new Kohana_404_Exception(); } - - if (!access::can("view", $photo)) { - print auth::require_login(); - return; - } - + + access::required("view", $photo); + $where = array(array("type", "!=", "album")); $position = $photo->parent()->get_position($photo, $where); if ($position > 1) { diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php index 327d2ff1..b89bc358 100644 --- a/modules/gallery/controllers/user_profile.php +++ b/modules/gallery/controllers/user_profile.php @@ -21,20 +21,21 @@ 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); - $active_user = identity::active_user(); - $is_current_active = $active_user->id == $id; - $display_all = $active_user->admin || ($is_current_active && !$active_user->guest); + if (!$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"); - // @todo modify user_home to supply a link to their album, $v->content->user = $user; - $v->content->not_current = !$is_current_active; - $v->content->editable = identity::is_writable() && $display_all; + $v->content->contactable = + !$user->guest && $user->id != identity::active_user()->id && $user->email; + $v->content->editable = + identity::is_writable() && !$user->guest && $user->id == identity::active_user()->id; - $event_data = (object)array("user" => $user, "display_all" => $display_all, "content" => array()); + $event_data = (object)array("user" => $user, "content" => array()); module::event("show_user_profile", $event_data); $v->content->info_parts = $event_data->content; diff --git a/modules/gallery/css/gallery.css b/modules/gallery/css/gallery.css index e06c4dd9..f3e5ec6d 100644 --- a/modules/gallery/css/gallery.css +++ b/modules/gallery/css/gallery.css @@ -55,6 +55,34 @@ margin: 0; } +/* User profile ~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#g-user-profile h1 { + margin: 1em 0; +} + +#g-user-profile .g-avatar { + margin-right: .6em; +} + +#g-user-profile .g-block { + margin-top: 0; +} + +#g-user-profile .g-block-content { + margin-top: 0; +} + +#g-user-profile th, +#g-user-profile td { + border: none; +} + +#g-user-profile th { + white-space: nowrap; + width: 1%; +} + /** ******************************************************************* * 2) Admin **********************************************************************/ @@ -96,4 +124,8 @@ .rtl #g-block-admin .g-left { margin-left: 1em; margin-right: 0; -}
\ No newline at end of file +} + +.rtl #g-user-profile .g-avatar { + margin-left: .6em; +} diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php index 29b981e8..7e8b079a 100644 --- a/modules/gallery/helpers/access.php +++ b/modules/gallery/helpers/access.php @@ -118,7 +118,12 @@ class access_Core { */ static function required($perm_name, $item) { if (!self::can($perm_name, $item)) { - self::forbidden(); + if ($perm_name == "view") { + // Treat as if the item didn't exist, don't leak any information. + throw new Kohana_404_Exception(); + } else { + self::forbidden(); + } } } diff --git a/modules/gallery/helpers/auth.php b/modules/gallery/helpers/auth.php index f5454f85..c3e9e6e9 100644 --- a/modules/gallery/helpers/auth.php +++ b/modules/gallery/helpers/auth.php @@ -130,17 +130,4 @@ class auth_Core { $session->set("admin_area_activity_timestamp", time()); return false; } - - /** - * Redirect to the login page. - */ - static function require_login() { - $view = new Theme_View("page.html", "other", "login"); - $view->page_title = t("Log in to Gallery"); - $view->content = new View("login_ajax.html"); - $view->content->form = auth::get_login_form("login/auth_html"); - // Avoid anti-phishing protection by passing the url as session variable. - Session::instance()->set("continue_url", url::current(true)); - return $view; - } }
\ No newline at end of file diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php index 84f8a7fb..a43b180b 100644 --- a/modules/gallery/helpers/gallery.php +++ b/modules/gallery/helpers/gallery.php @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class gallery_Core { - const VERSION = "3.0 git (pre-RC1)"; + const VERSION = "3.0 RC1 (Santa Fe)"; /** * If Gallery is in maintenance mode, then force all non-admins to get routed to a "This site is diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 63f33c12..36f91142 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -336,7 +336,7 @@ class gallery_event_Core { ->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&from_id=$theme_item->id&page_type=$page_type"))) + ->url(url::site("quick/rotate/$item->id/ccw?csrf=$csrf&from_id=$theme_item->id&page_type=$page_type"))) ->append( Menu::factory("ajax_link") ->id("rotate_cw") @@ -344,7 +344,7 @@ class gallery_event_Core { ->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&from_id=$theme_item->id&page_type=$page_type"))); + ->url(url::site("quick/rotate/$item->id/cw?csrf=$csrf&from_id=$theme_item->id&page_type=$page_type"))); } // @todo Don't move photos from the photo page; we don't yet have a good way of redirecting @@ -384,7 +384,7 @@ class gallery_event_Core { ->label($delete_title) ->css_class("ui-icon-trash") ->css_id("g-quick-delete") - ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&from_id=$theme_item->id&page_type=$page_type"))); + ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&from_id=$theme_item->id&page_type=$page_type"))); } if ($item->is_album()) { @@ -413,7 +413,7 @@ class gallery_event_Core { $fields = array("name" => t("Name"), "locale" => t("Language Preference"), "email" => t("Email"), "full_name" => t("Full name"), "url" => "Web site"); - if (!$data->display_all) { + if (!$data->user->guest) { $fields = array("name" => t("Name"), "full_name" => t("Full name"), "url" => "Web site"); } $v->user_profile_data = array(); diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index dd53cf43..6f8a6688 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -32,6 +32,10 @@ class gallery_installer { PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;"); + // Using a simple index instead of a unique key for the + // key column to avoid handling of concurrency issues + // on insert. Thus allowing concurrent inserts on the + // same cache key, as does Memcache / xcache. $db->query("CREATE TABLE {caches} ( `id` int(9) NOT NULL auto_increment, `key` varchar(255) NOT NULL, @@ -39,6 +43,7 @@ class gallery_installer { `expiration` int(9) NOT NULL, `cache` longblob, PRIMARY KEY (`id`), + KEY (`key`), KEY (`tags`)) DEFAULT CHARSET=utf8;"); @@ -284,11 +289,13 @@ class gallery_installer { 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", "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>"); + // Mark string for translation + $powered_by_string = t("Powered by <a href=\"%url\">%gallery_version</a>", + array("locale" => "root")); + module::set_var("gallery", "credits", (string) $powered_by_string); module::set_var("gallery", "simultaneous_upload_limit", 5); module::set_var("gallery", "admin_area_timeout", 90 * 60); - module::set_version("gallery", 28); + module::set_version("gallery", 30); } static function upgrade($version) { @@ -538,6 +545,16 @@ class gallery_installer { module::set_var("gallery", "admin_area_timeout", 90 * 60); module::set_version("gallery", $version = 28); } + + if ($version == 28) { + module::set_var("gallery", "credits", "Powered by <a href=\"%url\">%gallery_version</a>"); + module::set_version("gallery", $version = 29); + } + + if ($version == 29) { + $db->query("ALTER TABLE {caches} ADD KEY (`key`);"); + module::set_version("gallery", $version = 30); + } } static function uninstall() { diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php index 3e6278e5..617f7f48 100644 --- a/modules/gallery/helpers/gallery_task.php +++ b/modules/gallery/helpers/gallery_task.php @@ -201,6 +201,8 @@ class gallery_task_Core { $total = $num_fetched + $num_remaining; $task->percent_complete = 70 + 30 * ((float) $num_fetched / $total); } else { + Gallery_I18n::clear_cache(); + $task->done = true; $task->state = "success"; $task->status = t("Translations installed/updated"); diff --git a/modules/gallery/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php index 9ffeb911..d6944323 100644 --- a/modules/gallery/helpers/gallery_theme.php +++ b/modules/gallery/helpers/gallery_theme.php @@ -92,13 +92,18 @@ class gallery_theme_Core { } // Redirect to the root album when the admin session expires. - $redirect_url = url::abs_site(""); - $admin_area_timeout = 1000 * module::get_var("gallery", "admin_area_timeout"); $admin_session_redirect_check = '<script type="text/javascript"> - var page_loaded_timestamp = new Date(); - setInterval("if (new Date() - page_loaded_timestamp > ' . $admin_area_timeout . - ') document.location = \'' . $redirect_url . '\';", 60 * 1000); - </script>'; + var adminReauthCheck = function() { + $.ajax({url: "' . url::site("admin?reauth_check=1") . '", + dataType: "json", + success: function(data){ + if ("location" in data) { + document.location = data.location; + } + }}); + }; + setInterval("adminReauthCheck();", 60 * 1000); + </script>'; print $admin_session_redirect_check; if ($session->get("l10n_mode", false)) { @@ -107,9 +112,12 @@ class gallery_theme_Core { } static function credits() { - return "<li class=\"g-first\">" . + $version_string = SafeString::of_safe_html( + '<bdo dir="ltr">Gallery ' . gallery::VERSION . '</bdo>'); + return "<li class=\"g-first\">" . t(module::get_var("gallery", "credits"), - array("url" => "http://gallery.menalto.com", "version" => gallery::VERSION)) . + array("url" => "http://gallery.menalto.com", + "gallery_version" => $version_string)) . "</li>"; } diff --git a/modules/gallery/helpers/items_rest.php b/modules/gallery/helpers/items_rest.php new file mode 100644 index 00000000..c4dd4a5f --- /dev/null +++ b/modules/gallery/helpers/items_rest.php @@ -0,0 +1,44 @@ +<?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 items_rest_Core { + static function get($request) { + + $items = array(); + if (isset($request->params->url)) { + foreach($request->params->url as $url) { + $item = rest::resolve($url); + if (access::can("view", $item)) { + $members = array(); + if ($item->type == "album") { + foreach ($item->children() as $child) { + $members[] = rest::url("item", $child); + } + } + $items[] = array("url" => $url, + "entity" => $item->as_restful_array(), + "members" => $members, + "relationship" => rest::relationships("item", $item)); + } + } + } + + return $items; + } +} diff --git a/modules/gallery/helpers/locales.php b/modules/gallery/helpers/locales.php index e72d7ed9..62b08fb9 100644 --- a/modules/gallery/helpers/locales.php +++ b/modules/gallery/helpers/locales.php @@ -81,6 +81,7 @@ class locales_Core { $l["eu_ES"] = "Euskara"; // Basque $l["fa_IR"] = "فارس"; // Farsi $l["fi_FI"] = "Suomi"; // Finnish + $l["fo_FO"] = "Føroyskt"; // Faroese $l["fr_FR"] = "Français"; // French $l["ga_IE"] = "Gaeilge"; // Irish $l["he_IL"] = "עברית"; // Hebrew diff --git a/modules/gallery/libraries/Gallery_I18n.php b/modules/gallery/libraries/Gallery_I18n.php index cfed046a..f1e77744 100644 --- a/modules/gallery/libraries/Gallery_I18n.php +++ b/modules/gallery/libraries/Gallery_I18n.php @@ -73,12 +73,26 @@ class Gallery_I18n_Core { public function locale($locale=null) { if ($locale) { $this->_config['default_locale'] = $locale; - // Attempt to set PHP's locale as well (for number formatting, collation, etc.) - // TODO: See G2 for better fallack code. - $locale_prefs = array($locale); - $locale_prefs[] = 'en_US'; - $new_locale = setlocale(LC_ALL, $locale_prefs); - if (is_string($new_locale) && strpos($new_locale, 'tr') === 0) { + $php_locale = setlocale(LC_ALL, 0); + list ($php_locale, $unused) = explode('.', $php_locale . '.'); + if ($php_locale != $locale) { + // Attempt to set PHP's locale as well (for number formatting, collation, etc.) + $locale_prefs = array($locale); + // Try appending some character set names; some systems (like FreeBSD) need this. + // Some systems require a format with hyphen (eg. Gentoo) and others without (eg. FreeBSD). + $charsets = array('utf8', 'UTF-8', 'UTF8', 'ISO8859-1', 'ISO-8859-1'); + if (substr($locale, 0, 2) != 'en') { + $charsets = array_merge($charsets, array( + 'EUC', 'Big5', 'euc', 'ISO8859-2', 'ISO8859-5', 'ISO8859-7', + 'ISO8859-9', 'ISO-8859-2', 'ISO-8859-5', 'ISO-8859-7', 'ISO-8859-9')); + } + foreach ($charsets as $charset) { + $locale_prefs[] = $locale . '.' . $charset; + } + $locale_prefs[] = 'en_US'; + $php_locale = setlocale(LC_ALL, $locale_prefs); + } + if (is_string($php_locale) && substr($php_locale, 0, 2) == 'tr') { // Make PHP 5 work with Turkish (the localization results are mixed though). // Hack for http://bugs.php.net/18556 setlocale(LC_CTYPE, 'C'); @@ -136,33 +150,44 @@ class Gallery_I18n_Core { private function lookup($locale, $message) { if (!isset($this->_cache[$locale])) { - $this->_cache[$locale] = array(); - // TODO: Load data from locale file instead of the DB. + $this->_cache[$locale] = self::load_translations($locale); + } + + $key = self::get_message_key($message); + + if (isset($this->_cache[$locale][$key])) { + return $this->_cache[$locale][$key]; + } else { + return null; + } + } + + private static function load_translations($locale) { + $cache_key = "translation|" . $locale; + $cache = Cache::instance(); + $translations = $cache->get($cache_key); + if (!isset($translations) || !is_array($translations)) { + $translations = array(); foreach (db::build() ->select("key", "translation") ->from("incoming_translations") ->where("locale", "=", $locale) ->execute() as $row) { - $this->_cache[$locale][$row->key] = unserialize($row->translation); + $translations[$row->key] = unserialize($row->translation); } - + // Override incoming with outgoing... foreach (db::build() ->select("key", "translation") ->from("outgoing_translations") ->where("locale", "=", $locale) ->execute() as $row) { - $this->_cache[$locale][$row->key] = unserialize($row->translation); + $translations[$row->key] = unserialize($row->translation); } + + $cache->set($cache_key, $translations, array("translation"), 0); } - - $key = self::get_message_key($message); - - if (isset($this->_cache[$locale][$key])) { - return $this->_cache[$locale][$key]; - } else { - return null; - } + return $translations; } public function has_translation($message, $options=null) { @@ -242,6 +267,15 @@ class Gallery_I18n_Core { return $this->_call_log; } + public static function clear_cache($locale=null) { + $cache = Cache::instance(); + if ($locale) { + $cache->delete("translation|" . $locale); + } else { + $cache->delete_tag("translation"); + } + } + private static function get_plural_key($locale, $count) { $parts = explode('_', $locale); $language = $parts[0]; diff --git a/modules/gallery/libraries/IdentityProvider.php b/modules/gallery/libraries/IdentityProvider.php index 3f1666eb..01ea9ad7 100644 --- a/modules/gallery/libraries/IdentityProvider.php +++ b/modules/gallery/libraries/IdentityProvider.php @@ -66,6 +66,11 @@ class IdentityProvider_Core { } static function change_provider($new_provider) { + if (!identity::active_user()->admin && PHP_SAPI != "cli") { + // Below, the active user is set to the primary admin. + access::forbidden(); + } + $current_provider = module::get_var("gallery", "identity_provider"); if (!empty($current_provider)) { module::uninstall($current_provider); diff --git a/modules/gallery/libraries/MY_Kohana_Exception.php b/modules/gallery/libraries/MY_Kohana_Exception.php index 1c40091a..1712d895 100644 --- a/modules/gallery/libraries/MY_Kohana_Exception.php +++ b/modules/gallery/libraries/MY_Kohana_Exception.php @@ -33,6 +33,120 @@ class Kohana_Exception extends Kohana_Exception_Core { if ($e instanceof ORM_Validation_Exception) { Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); } - return parent::handle($e); + try { + $user = identity::active_user(); + $try_themed_view = $user && !$user->admin; + } catch (Exception $e2) { + $try_themed_view = false; + } + + if ($try_themed_view) { + try { + return self::_show_themed_error_page($e); + } catch (Exception $e3) { + Kohana_Log::add("error", "Exception in exception handling code: " . self::text($e3)); + return parent::handle($e); + } + } else { + return parent::handle($e); + } + } + + /** + * Shows a themed error page. + * @see Kohana_Exception::handle + */ + private static function _show_themed_error_page(Exception $e) { + // Create a text version of the exception + $error = Kohana_Exception::text($e); + + // Add this exception to the log + Kohana_Log::add('error', $error); + + // Manually save logs after exceptions + Kohana_Log::save(); + + if (!headers_sent()) { + if ($e instanceof Kohana_Exception) { + $e->sendHeaders(); + } else { + header("HTTP/1.1 500 Internal Server Error"); + } + } + + $view = new Theme_View("page.html", "other", "error"); + if ($e instanceof Kohana_404_Exception) { + $view->page_title = t("Dang... Page not found!"); + $view->content = new View("error_404.html"); + $user = identity::active_user(); + $view->content->is_guest = $user && $user->guest; + if ($view->content->is_guest) { + $view->content->login_form = new View("login_ajax.html"); + $view->content->login_form->form = auth::get_login_form("login/auth_html"); + // Avoid anti-phishing protection by passing the url as session variable. + Session::instance()->set("continue_url", url::current(true)); + } + } else { + $view->page_title = t("Dang... Something went wrong!"); + $view->content = new View("error.html"); + } + print $view; + } + + /** + * @see Kohana_Exception::dump() + */ + public static function dump($value, $length=128, $max_level=5) { + return self::safe_dump($value, null, $length, $max_level); + } + + /** + * A safer version of dump(), eliding sensitive information in the dumped + * data, such as session ids and passwords / hashes. + */ + public static function safe_dump($value, $key, $length=128, $max_level=5) { + return parent::dump(self::_sanitize_for_dump($value, $key), $length, $max_level); + } + + /** + * Elides sensitive data which shouldn't be echoed to the client, + * such as passwords, and other secrets. + */ + /* Visible for testing*/ static function _sanitize_for_dump($value, $key=null) { + // Better elide too much than letting something through. + // Note: unanchored match is intended. + $sensitive_info_pattern = + '/(password|pass|email|hash|private_key|session_id|session|g3sid|csrf|secret)/i'; + if (preg_match($sensitive_info_pattern, $key) || + (is_string($value) && preg_match('/[a-f0-9]{20,}/i', $value))) { + return 'removed for display'; + } else if (is_object($value)) { + if ($value instanceof Database) { + // Elide database password, host, name, user, etc. + return get_class($value) . ' object - details omitted for display'; + } else if ($value instanceof User_Model) { + return get_class($value) . ' object for "' . $value->name . '" - details omitted for display'; + } + return self::_sanitize_for_dump((array) $value, $key); + } else if (is_array($value)) { + $result = array(); + foreach ($value as $k => $v) { + $actual_key = $k; + $key_for_display = $k; + if ($k[0] === "\x00") { + // Remove the access level from the variable name + $actual_key = substr($k, strrpos($k, "\x00") + 1); + $access = $k[1] === '*' ? 'protected' : 'private'; + $key_for_display = "$access: $actual_key"; + } + if (is_object($v)) { + $key_for_display .= ' (type: ' . get_class($v) . ')'; + } + $result[$key_for_display] = self::_sanitize_for_dump($v, $actual_key); + } + } else { + $result = $value; + } + return $result; } }
\ No newline at end of file diff --git a/modules/gallery/libraries/Menu.php b/modules/gallery/libraries/Menu.php index e2b68d1a..fef07916 100644 --- a/modules/gallery/libraries/Menu.php +++ b/modules/gallery/libraries/Menu.php @@ -184,7 +184,7 @@ class Menu_Core extends Menu_Element { } /** - * Add a new element to this menu + * Add a new element to this menu, after the specific element */ public function add_after($target_id, $new_menu_element) { $copy = array(); @@ -199,6 +199,21 @@ class Menu_Core extends Menu_Element { } /** + * Add a new element to this menu, before the specific element + */ + public function add_before($target_id, $new_menu_element) { + $copy = array(); + foreach ($this->elements as $id => $menu_element) { + if ($id == $target_id) { + $copy[$new_menu_element->id] = $new_menu_element; + } + $copy[$id] = $menu_element; + } + $this->elements = $copy; + return $this; + } + + /** * Remove an element from the menu */ public function remove($target_id) { @@ -216,6 +231,19 @@ class Menu_Core extends Menu_Element { return null; } + public function is_empty() { + foreach ($this->elements as $element) { + if ($element instanceof Menu) { + if (!$element->is_empty()) { + return false; + } + } else { + return false; + } + } + return true; + } + public function render() { $view = new View(isset($this->view) ? $this->view : "menu.html"); $view->menu = $this; diff --git a/modules/gallery/libraries/drivers/Cache/Database.php b/modules/gallery/libraries/drivers/Cache/Database.php index 82a09ab9..ff982396 100644 --- a/modules/gallery/libraries/drivers/Cache/Database.php +++ b/modules/gallery/libraries/drivers/Cache/Database.php @@ -130,7 +130,7 @@ class Cache_Database_Driver extends Cache_Driver { // Make sure the expiration is valid and that the hash matches if ($cache->expiration != 0 && $cache->expiration <= time()) { // Cache is not valid, delete it now - $this->delete($cache->id); + $this->delete(array($cache->id)); } else { // Disable notices for unserializing $ER = error_reporting(~E_NOTICE); @@ -153,15 +153,17 @@ class Cache_Database_Driver extends Cache_Driver { * @param bool delete a tag * @return bool */ - public function delete($id, $tag=false) { + public function delete($keys, $is_tag=false) { $db = db::build() ->delete("caches"); - if ($id === true) { + if ($keys === true) { // Delete all caches - } else if ($tag === true) { - $db->where("tags", "LIKE", "%<$id>%"); + } else if ($is_tag === true) { + foreach ($keys as $tag) { + $db->where("tags", "LIKE", "%<$tag>%"); + } } else { - $db->where("key", "=", $id); + $db->where("key", "IN", $keys); } $status = $db->execute(); diff --git a/modules/gallery/libraries/drivers/IdentityProvider.php b/modules/gallery/libraries/drivers/IdentityProvider.php index b7b1fbe8..09cdd093 100644 --- a/modules/gallery/libraries/drivers/IdentityProvider.php +++ b/modules/gallery/libraries/drivers/IdentityProvider.php @@ -26,7 +26,7 @@ interface IdentityProvider_Driver { public function guest(); /** - * Return the admins user. + * Return the primary admin user. * * @return User_Definition the user object */ diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index dbd56fa2..d747b84d 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -930,8 +930,18 @@ class Item_Model extends ORM_MPTT { } unset($data["album_cover_item_id"]); + if (access::can("view_full", $this) && $this->is_photo()) { + $data["file_url"] = $this->file_url(true); + } + + if (($tmp = $this->resize_url(true)) && $this->is_photo()) { + $data["resize_url"] = $tmp; + } + $data["thumb_url"] = $this->thumb_url(true); + // Elide some internal-only data that is going to cause confusion in the client. - foreach (array("relative_path_cache", "relative_url_cache", "left_ptr", "right_ptr") as $key) { + foreach (array("relative_path_cache", "relative_url_cache", "left_ptr", "right_ptr", + "thumb_dirty", "resize_dirty") as $key) { unset($data[$key]); } return $data; diff --git a/modules/gallery/module.info b/modules/gallery/module.info index ae300399..df2be978 100644 --- a/modules/gallery/module.info +++ b/modules/gallery/module.info @@ -1,3 +1,3 @@ name = "Gallery 3" description = "Gallery core application" -version = 28 +version = 30 diff --git a/modules/gallery/tests/Access_Helper_Test.php b/modules/gallery/tests/Access_Helper_Test.php index 5331117d..6eca396c 100644 --- a/modules/gallery/tests/Access_Helper_Test.php +++ b/modules/gallery/tests/Access_Helper_Test.php @@ -20,6 +20,10 @@ class Access_Helper_Test extends Gallery_Unit_Test_Case { private $_group; + public function setup() { + identity::set_active_user(identity::guest()); + } + public function teardown() { try { $group = identity::lookup_group_by_name("access_test"); @@ -41,10 +45,7 @@ class Access_Helper_Test extends Gallery_Unit_Test_Case { // Reset some permissions that we mangle below access::allow(identity::everybody(), "view", item::root()); - } - - public function setup() { - identity::set_active_user(identity::guest()); + identity::set_active_user(identity::admin_user()); } public function groups_and_permissions_are_bound_to_columns_test() { diff --git a/modules/gallery/tests/Cache_Test.php b/modules/gallery/tests/Cache_Test.php index 1023568b..a942a292 100644 --- a/modules/gallery/tests/Cache_Test.php +++ b/modules/gallery/tests/Cache_Test.php @@ -118,7 +118,7 @@ class Cache_Test extends Gallery_Unit_Test_Case { $value3 = array("field5" => "value5", "field6" => "value6"); $this->_driver->set(array($id3 => $value3), array("tag3", "tag4"), 84600); - $this->_driver->delete($id1); + $this->_driver->delete(array($id1)); $this->assert_false($this->_driver->exists($id1), "$id1 should have been deleted"); $this->assert_true($this->_driver->exists($id2), "$id2 should not have been deleted"); @@ -138,7 +138,7 @@ class Cache_Test extends Gallery_Unit_Test_Case { $value3 = array("field5" => "value5", "field6" => "value6"); $this->_driver->set(array($id3 => $value3), array("tag3", "tag4"), 84600); - $data = $this->_driver->delete("tag3", true); + $data = $this->_driver->delete_tag(array("tag3")); $this->assert_true($this->_driver->exists($id1), "$id1 should not have been deleted"); $this->assert_false($this->_driver->exists($id2), "$id2 should have been deleted"); diff --git a/modules/gallery/tests/Item_Helper_Test.php b/modules/gallery/tests/Item_Helper_Test.php index 50587702..90106562 100644 --- a/modules/gallery/tests/Item_Helper_Test.php +++ b/modules/gallery/tests/Item_Helper_Test.php @@ -18,8 +18,7 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class Item_Helper_Test extends Gallery_Unit_Test_Case { - - public function setup() { + public function teardown() { identity::set_active_user(identity::admin_user()); } diff --git a/modules/gallery/tests/Item_Rest_Helper_Test.php b/modules/gallery/tests/Item_Rest_Helper_Test.php index 6d1dd864..7b86c153 100644 --- a/modules/gallery/tests/Item_Rest_Helper_Test.php +++ b/modules/gallery/tests/Item_Rest_Helper_Test.php @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { + public function teardown() { + identity::set_active_user(identity::admin_user()); + } + public function resolve_test() { $album = test::random_album(); $resolved = rest::resolve(rest::url("item", $album)); diff --git a/modules/gallery/tests/Kohana_Exception_Test.php b/modules/gallery/tests/Kohana_Exception_Test.php new file mode 100644 index 00000000..d2dbb4dc --- /dev/null +++ b/modules/gallery/tests/Kohana_Exception_Test.php @@ -0,0 +1,170 @@ +<?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 Kohana_Exception_Test extends Gallery_Unit_Test_Case { + + public function dump_test() { + // Verify the override. + $this->assert_equal('<small>string</small><span>(19)</span> "removed for display"', + Kohana_Exception::dump("1a62761b836138c6198313911")); + $this->assert_equal('<small>string</small><span>(14)</span> "original value"', + Kohana_Exception::dump("original value")); + } + + public function safe_dump_test() { + // Verify the delegation. + $this->assert_equal('<small>string</small><span>(19)</span> "removed for display"', + Kohana_Exception::safe_dump("original value", "password")); + $this->assert_equal('<small>string</small><span>(14)</span> "original value"', + Kohana_Exception::safe_dump("original value", "meow")); + } + + public function sanitize_for_dump_match_key_test() { + $this->assert_equal("removed for display", + Kohana_Exception::_sanitize_for_dump("original value", "password")); + $this->assert_equal("original value", + Kohana_Exception::_sanitize_for_dump("original value", "meow")); + } + + public function sanitize_for_dump_match_key_loosely_test() { + $this->assert_equal("removed for display", + Kohana_Exception::_sanitize_for_dump("original value", "this secret key")); + } + + public function sanitize_for_dump_match_value_test() { + // Looks like a hash / secret value. + $this->assert_equal("removed for display", + Kohana_Exception::_sanitize_for_dump("p$2a178b841c6391d6368f131", "meow")); + $this->assert_equal("original value", + Kohana_Exception::_sanitize_for_dump("original value", "meow")); + } + + public function sanitize_for_dump_array_test() { + $var = array("safe" => "original value 1", + "some hash" => "original value 2", + "three" => "2a3728788982938293b9292"); + $expected = array("safe" => "original value 1", + "some hash" => "removed for display", + "three" => "removed for display"); + + $this->assert_equal($expected, + Kohana_Exception::_sanitize_for_dump($var, "ignored")); + } + + public function sanitize_for_dump_nested_array_test() { + $var = array("safe" => "original value 1", + "safe 2" => array("some hash" => "original value 2")); + $expected = array("safe" => "original value 1", + "safe 2" => array("some hash" => "removed for display")); + $this->assert_equal($expected, + Kohana_Exception::_sanitize_for_dump($var, "ignored")); + } + + public function sanitize_for_dump_user_test() { + $user = new User_Model(); + $user->name = "john"; + $user->hash = "value 1"; + $user->email = "value 2"; + $user->full_name = "value 3"; + $this->assert_equal('User_Model object for "john" - details omitted for display', + Kohana_Exception::_sanitize_for_dump($user, "ignored")); + } + + public function sanitize_for_dump_database_test() { + $db = new Kohana_Exception_Test_Database( + array("connection" => array("user" => "john", "name" => "gallery_3"), + "cache" => array())); + $this->assert_equal("Kohana_Exception_Test_Database object - details omitted for display", + Kohana_Exception::_sanitize_for_dump($db, "ignored")); + } + + public function sanitize_for_dump_nested_database_test() { + $db = new Kohana_Exception_Test_Database( + array("connection" => array("user" => "john", "name" => "gallery_3"), + "cache" => array())); + $var = array("some" => "foo", + "bar" => $db); + $this->assert_equal( + array("some" => "foo", + "bar (type: Kohana_Exception_Test_Database)" => + "Kohana_Exception_Test_Database object - details omitted for display"), + Kohana_Exception::_sanitize_for_dump($var, "ignored")); + } + + public function sanitize_for_dump_object_test() { + $obj = new Kohana_Exception_Test_Class(); + $obj->password = "original value"; + $expected = array("var_1" => "val 1", + "protected: var_2" => "val 2", + "private: var_3" => "val 3", + "protected: hash" => "removed for display", + "private: email_address" => "removed for display", + "password" => "removed for display"); + $this->assert_equal($expected, + Kohana_Exception::_sanitize_for_dump($obj, "ignored")); + } + + public function sanitize_for_dump_nested_object_test() { + $user = new User_Model(); + $user->name = "john"; + $obj = new Kohana_Exception_Test_Class(); + $obj->meow = new Kohana_Exception_Test_Class(); + $obj->woof = "original value"; + $obj->foo = array("bar" => $user); + $expected = array("var_1" => "val 1", + "protected: var_2" => "val 2", + "private: var_3" => "val 3", + "protected: hash" => "removed for display", + "private: email_address" => "removed for display", + "meow (type: Kohana_Exception_Test_Class)" => + array("var_1" => "val 1", + "protected: var_2" => "val 2", + "private: var_3" => "val 3", + "protected: hash" => "removed for display", + "private: email_address" => "removed for display"), + "woof" => "original value", + "foo" => array("bar (type: User_Model)" => + 'User_Model object for "john" - details omitted for display')); + $this->assert_equal($expected, + Kohana_Exception::_sanitize_for_dump($obj, "ignored")); + } +} + +class Kohana_Exception_Test_Database extends Database { + function __construct($config) { parent::__construct($config); } + public function connect() {} + public function disconnect() {} + public function set_charset($charset) {} + public function query_execute($sql) {} + public function escape($value) {} + public function list_constraints($table) {} + public function list_fields($table) {} + public function list_tables() {} +} + +class Kohana_Exception_Test_Class { + public $var_1 = "val 1"; + protected $var_2 = "val 2"; + private $var_3 = "val 3"; + protected $hash = "val 4"; + private $email_address = "val 5"; + function __set($name, $val) { + $this->$name = $val; + } +}
\ No newline at end of file diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt index e53502ee..a3ca31f4 100644 --- a/modules/gallery/tests/xss_data.txt +++ b/modules/gallery/tests/xss_data.txt @@ -32,8 +32,8 @@ modules/comment/views/comment.mrss.php 29 DIRTY $child modules/comment/views/comment.mrss.php 34 DIRTY_ATTR $child->thumb_url modules/comment/views/comment.mrss.php 35 DIRTY_ATTR $child->thumb_height modules/comment/views/comment.mrss.php 35 DIRTY_ATTR $child->thumb_width -modules/comment/views/comments.html.php 16 DIRTY_ATTR $comment->id -modules/comment/views/comments.html.php 19 DIRTY_ATTR $comment->author()->avatar_url(40,$theme->url(,true)) +modules/comment/views/comments.html.php 18 DIRTY_ATTR $comment->id +modules/comment/views/comments.html.php 21 DIRTY_ATTR $comment->author()->avatar_url(40,$theme->url(,true)) modules/comment/views/user_profile_comments.html.php 5 DIRTY_ATTR $comment->id modules/comment/views/user_profile_comments.html.php 10 DIRTY_JS $comment->item()->url() modules/comment/views/user_profile_comments.html.php 11 DIRTY $comment->item()->thumb_img(array(),50) @@ -81,19 +81,18 @@ modules/gallery/views/admin_maintenance.html.php 24 DIRTY_ATTR log: modules/gallery/views/admin_maintenance.html.php 25 DIRTY_ATTR log::severity_class($task->severity) modules/gallery/views/admin_maintenance.html.php 26 DIRTY $task->name modules/gallery/views/admin_maintenance.html.php 29 DIRTY $task->description -modules/gallery/views/admin_maintenance.html.php 33 DIRTY_JS "{$button->url}/$task->callback?csrf=$csrf" -modules/gallery/views/admin_maintenance.html.php 76 DIRTY_ATTR text::alternate("g-odd","g-even") -modules/gallery/views/admin_maintenance.html.php 76 DIRTY_ATTR $task->state=="stalled"?"g-warning":"" -modules/gallery/views/admin_maintenance.html.php 77 DIRTY_ATTR $task->state=="stalled"?"g-warning":"" -modules/gallery/views/admin_maintenance.html.php 78 DIRTY gallery::date_time($task->updated) -modules/gallery/views/admin_maintenance.html.php 81 DIRTY $task->name -modules/gallery/views/admin_maintenance.html.php 96 DIRTY $task->status -modules/gallery/views/admin_maintenance.html.php 147 DIRTY_ATTR text::alternate("g-odd","g-even") -modules/gallery/views/admin_maintenance.html.php 147 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" -modules/gallery/views/admin_maintenance.html.php 148 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" -modules/gallery/views/admin_maintenance.html.php 149 DIRTY gallery::date_time($task->updated) -modules/gallery/views/admin_maintenance.html.php 152 DIRTY $task->name -modules/gallery/views/admin_maintenance.html.php 164 DIRTY $task->status +modules/gallery/views/admin_maintenance.html.php 70 DIRTY_ATTR text::alternate("g-odd","g-even") +modules/gallery/views/admin_maintenance.html.php 70 DIRTY_ATTR $task->state=="stalled"?"g-warning":"" +modules/gallery/views/admin_maintenance.html.php 71 DIRTY_ATTR $task->state=="stalled"?"g-warning":"" +modules/gallery/views/admin_maintenance.html.php 72 DIRTY gallery::date_time($task->updated) +modules/gallery/views/admin_maintenance.html.php 75 DIRTY $task->name +modules/gallery/views/admin_maintenance.html.php 90 DIRTY $task->status +modules/gallery/views/admin_maintenance.html.php 141 DIRTY_ATTR text::alternate("g-odd","g-even") +modules/gallery/views/admin_maintenance.html.php 141 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" +modules/gallery/views/admin_maintenance.html.php 142 DIRTY_ATTR $task->state=="success"?"g-success":"g-error" +modules/gallery/views/admin_maintenance.html.php 143 DIRTY gallery::date_time($task->updated) +modules/gallery/views/admin_maintenance.html.php 146 DIRTY $task->name +modules/gallery/views/admin_maintenance.html.php 158 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 @@ -121,6 +120,7 @@ modules/gallery/views/admin_themes.html.php 62 DIRTY $theme modules/gallery/views/admin_themes.html.php 76 DIRTY $info->name modules/gallery/views/admin_themes.html.php 78 DIRTY $info->description modules/gallery/views/admin_themes_preview.html.php 7 DIRTY_ATTR $url +modules/gallery/views/error_404.html.php 14 DIRTY $login_form modules/gallery/views/form_uploadify.html.php 30 DIRTY_JS url::file("lib/uploadify/uploadify.swf") modules/gallery/views/form_uploadify.html.php 31 DIRTY_JS url::site("simple_uploader/add_photo/{$album->id}") modules/gallery/views/form_uploadify.html.php 35 DIRTY_JS url::file("lib/uploadify/cancel.png") @@ -128,8 +128,7 @@ modules/gallery/views/form_uploadify.html.php 36 DIRTY_JS $simul 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\"") -modules/gallery/views/kohana_error_page.php 102 DIRTY $message -modules/gallery/views/kohana_error_page.php 116 DIRTY $trace +modules/gallery/views/in_place_edit.html.php 14 DIRTY $errors["input"] modules/gallery/views/kohana_profiler.php 32 DIRTY $profile->render(); modules/gallery/views/l10n_client.html.php 21 DIRTY_ATTR $string["translation"]===""?"untranslated":"translated" modules/gallery/views/l10n_client.html.php 23 DIRTY $string["source"]["one"] @@ -148,18 +147,18 @@ modules/gallery/views/l10n_client.html.php 67 DIRTY form:: modules/gallery/views/login_ajax.html.php 6 DIRTY_JS url::site("password/reset") modules/gallery/views/login_ajax.html.php 37 DIRTY $form modules/gallery/views/maintenance.html.php 46 DIRTY auth::get_login_form("login/auth_html") -modules/gallery/views/menu.html.php 4 DIRTY isset($menu->css_id)?"id='$menu->css_id'":"" +modules/gallery/views/menu.html.php 4 DIRTY $menu->css_id?"id='$menu->css_id'":"" modules/gallery/views/menu.html.php 4 DIRTY_ATTR $menu->css_class modules/gallery/views/menu.html.php 6 DIRTY $element->render() modules/gallery/views/menu.html.php 18 DIRTY $element->render() -modules/gallery/views/menu_ajax_link.html.php 3 DIRTY_ATTR $menu->css_id +modules/gallery/views/menu_ajax_link.html.php 3 DIRTY $menu->css_id?"id='{$menu->css_id}'":"" modules/gallery/views/menu_ajax_link.html.php 4 DIRTY_ATTR $menu->css_class modules/gallery/views/menu_ajax_link.html.php 5 DIRTY_JS $menu->url modules/gallery/views/menu_ajax_link.html.php 7 DIRTY $menu->ajax_handler -modules/gallery/views/menu_dialog.html.php 3 DIRTY_ATTR $menu->css_id +modules/gallery/views/menu_dialog.html.php 3 DIRTY $menu->css_id?"id='{$menu->css_id}'":"" modules/gallery/views/menu_dialog.html.php 4 DIRTY_ATTR $menu->css_class modules/gallery/views/menu_dialog.html.php 5 DIRTY_JS $menu->url -modules/gallery/views/menu_link.html.php 3 DIRTY_ATTR $menu->css_id +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 4 DIRTY_JS url::site("move/show_sub_tree/{$source->id}/__TARGETID__") @@ -209,6 +208,7 @@ modules/gallery/views/permissions_form.html.php 75 DIRTY_JS $item- modules/gallery/views/permissions_form.html.php 80 DIRTY_JS $group->id modules/gallery/views/permissions_form.html.php 80 DIRTY_JS $permission->id modules/gallery/views/permissions_form.html.php 80 DIRTY_JS $item->id +modules/gallery/views/reauthenticate.html.php 9 DIRTY $form modules/gallery/views/upgrader.html.php 57 DIRTY_ATTR $done?"muted":"" modules/gallery/views/upgrader.html.php 61 DIRTY_ATTR $done?"muted":"" modules/gallery/views/upgrader.html.php 69 DIRTY_ATTR $module->version==$module->code_version?"current":"upgradeable" @@ -218,8 +218,8 @@ modules/gallery/views/upgrader.html.php 77 DIRTY $modul modules/gallery/views/upgrader.html.php 99 DIRTY_ATTR $done?"muted":"" modules/gallery/views/upgrader.html.php 102 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 36 DIRTY_ATTR $user->avatar_url(40,$theme->url(,true)) -modules/gallery/views/user_profile.html.php 47 DIRTY $info->view +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 modules/image_block/views/image_block_block.html.php 3 DIRTY_JS $item->url() modules/image_block/views/image_block_block.html.php 4 DIRTY $item->thumb_img(array("class"=>"g-thumbnail")) modules/info/views/info_block.html.php 22 DIRTY date("M j, Y H:i:s",$item->captured) @@ -239,23 +239,22 @@ modules/organize/views/organize_dialog.html.php 4 DIRTY_JS url::s modules/organize/views/organize_dialog.html.php 5 DIRTY_JS url::site("organize/sort_order/__ALBUM_ID__/__COL__/__DIR__?csrf=$csrf") modules/organize/views/organize_dialog.html.php 6 DIRTY_JS url::site("organize/tree/__ALBUM_ID__") modules/organize/views/organize_dialog.html.php 14 DIRTY $album_tree -modules/organize/views/organize_dialog.html.php 24 DIRTY $micro_thumb_grid +modules/organize/views/organize_dialog.html.php 23 DIRTY $micro_thumb_grid modules/organize/views/organize_dialog.html.php 32 DIRTY form::dropdown(array("id"=>"g-organize-sort-column"),album::get_sort_order_options(),$album->sort_column) -modules/organize/views/organize_dialog.html.php 33 DIRTY form::dropdown(array("id"=>"g-organize-sort-order"),array("ASC"=>"Ascending","DESC"=>"Descending"),$album->sort_order) -modules/organize/views/organize_thumb_grid.html.php 3 DIRTY_ATTR $child->id +modules/organize/views/organize_thumb_grid.html.php 3 DIRTY_ATTR $child->is_album()?"g-album":"g-photo" modules/organize/views/organize_thumb_grid.html.php 4 DIRTY_ATTR $child->id -modules/organize/views/organize_thumb_grid.html.php 5 DIRTY_ATTR $child->is_album()?"g-album":"g-photo" -modules/organize/views/organize_thumb_grid.html.php 6 DIRTY $child->thumb_img(array("class"=>"g-thumbnail","ref"=>$child->id),90,true) -modules/organize/views/organize_thumb_grid.html.php 7 DIRTY $child->is_album()?" class=\"ui-icon ui-icon-note\"":"" -modules/organize/views/organize_thumb_grid.html.php 15 DIRTY_JS url::site("organize/album/$album->id/".($offset+25)) +modules/organize/views/organize_thumb_grid.html.php 5 DIRTY $child->thumb_img(array("class"=>"g-thumbnail","ref"=>$child->id),90,true) +modules/organize/views/organize_thumb_grid.html.php 6 DIRTY $child->is_album()?" class=\"ui-icon ui-icon-note\"":"" +modules/organize/views/organize_thumb_grid.html.php 13 DIRTY_JS url::site("organize/album/$album->id/".($offset+25)) modules/organize/views/organize_tree.html.php 2 DIRTY_ATTR access::can("edit",$album)?"":"g-view-only" modules/organize/views/organize_tree.html.php 3 DIRTY_ATTR $album->id modules/organize/views/organize_tree.html.php 6 DIRTY_ATTR $selected&&$album->id==$selected->id?"ui-state-focus":"" modules/organize/views/organize_tree.html.php 7 DIRTY_ATTR $album->id -modules/organize/views/organize_tree.html.php 13 DIRTY View::factory("organize_tree.html",array("selected"=>$selected,"album"=>$child)); -modules/organize/views/organize_tree.html.php 15 DIRTY_ATTR access::can("edit",$child)?"":"g-view-only" -modules/organize/views/organize_tree.html.php 16 DIRTY_ATTR $child->id +modules/organize/views/organize_tree.html.php 15 DIRTY View::factory("organize_tree.html",array("selected"=>$selected,"album"=>$child)); +modules/organize/views/organize_tree.html.php 17 DIRTY_ATTR access::can("edit",$child)?"":"g-view-only" modules/organize/views/organize_tree.html.php 18 DIRTY_ATTR $child->id +modules/organize/views/organize_tree.html.php 20 DIRTY_ATTR $selected&&$child->id==$selected->id?"ui-state-focus":"" +modules/organize/views/organize_tree.html.php 20 DIRTY_ATTR $child->id modules/recaptcha/views/admin_recaptcha.html.php 11 DIRTY $form modules/recaptcha/views/admin_recaptcha.html.php 23 DIRTY_JS $public_key modules/recaptcha/views/form_recaptcha.html.php 7 DIRTY_JS $public_key @@ -275,21 +274,16 @@ modules/rss/views/feed.mrss.php 42 DIRTY_ATTR $chi modules/rss/views/feed.mrss.php 48 DIRTY_ATTR $child->thumb_url(true) modules/rss/views/feed.mrss.php 49 DIRTY_ATTR $child->thumb_height modules/rss/views/feed.mrss.php 50 DIRTY_ATTR $child->thumb_width -modules/rss/views/feed.mrss.php 54 DIRTY_ATTR $child->resize_url(true) -modules/rss/views/feed.mrss.php 55 DIRTY_ATTR @filesize($child->resize_path()) -modules/rss/views/feed.mrss.php 56 DIRTY_ATTR $child->mime_type -modules/rss/views/feed.mrss.php 57 DIRTY_ATTR $child->resize_height -modules/rss/views/feed.mrss.php 58 DIRTY_ATTR $child->resize_width -modules/rss/views/feed.mrss.php 61 DIRTY_ATTR $child->file_url(true) -modules/rss/views/feed.mrss.php 62 DIRTY_ATTR @filesize($child->file_path()) -modules/rss/views/feed.mrss.php 63 DIRTY_ATTR $child->mime_type -modules/rss/views/feed.mrss.php 64 DIRTY_ATTR $child->height -modules/rss/views/feed.mrss.php 65 DIRTY_ATTR $child->width -modules/rss/views/feed.mrss.php 70 DIRTY_ATTR $child->file_url(true) -modules/rss/views/feed.mrss.php 71 DIRTY_ATTR @filesize($child->file_path()) -modules/rss/views/feed.mrss.php 72 DIRTY_ATTR $child->height -modules/rss/views/feed.mrss.php 73 DIRTY_ATTR $child->width -modules/rss/views/feed.mrss.php 74 DIRTY_ATTR $child->mime_type +modules/rss/views/feed.mrss.php 57 DIRTY_ATTR $child->resize_url(true) +modules/rss/views/feed.mrss.php 58 DIRTY_ATTR @filesize($child->resize_path()) +modules/rss/views/feed.mrss.php 59 DIRTY_ATTR $child->mime_type +modules/rss/views/feed.mrss.php 60 DIRTY_ATTR $child->resize_height +modules/rss/views/feed.mrss.php 61 DIRTY_ATTR $child->resize_width +modules/rss/views/feed.mrss.php 65 DIRTY_ATTR $child->file_url(true) +modules/rss/views/feed.mrss.php 66 DIRTY_ATTR @filesize($child->file_path()) +modules/rss/views/feed.mrss.php 67 DIRTY_ATTR $child->mime_type +modules/rss/views/feed.mrss.php 68 DIRTY_ATTR $child->height +modules/rss/views/feed.mrss.php 69 DIRTY_ATTR $child->width modules/rss/views/rss_block.html.php 6 DIRTY_JS rss::url($url) modules/search/views/search.html.php 27 DIRTY_ATTR $item_class modules/search/views/search.html.php 28 DIRTY_JS $item->url() @@ -321,9 +315,8 @@ modules/user/views/admin_users.html.php 87 DIRTY ($user 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_group.html.php 22 DIRTY_JS $user->id -modules/user/views/admin_users_group.html.php 22 DIRTY_JS $group->id -modules/user/views/user_form.html.php 7 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 modules/watermark/views/admin_watermarks.html.php 20 DIRTY_ATTR $height modules/watermark/views/admin_watermarks.html.php 20 DIRTY_ATTR $url diff --git a/modules/gallery/views/admin_languages.html.php b/modules/gallery/views/admin_languages.html.php index 07134475..d4b7b0c1 100644 --- a/modules/gallery/views/admin_languages.html.php +++ b/modules/gallery/views/admin_languages.html.php @@ -49,13 +49,14 @@ </tr> <? $i = 0 ?> <? foreach ($available_locales as $code => $display_name): ?> - <? if ($i == (count($available_locales)/2)): ?> - <table> - <tr> - <th> <?= t("Installed") ?> </th> - <th> <?= t("Language") ?> </th> - <th> <?= t("Default language") ?> </th> - </tr> + <? if ($i == (int) (count($available_locales)/2)): ?> + </table> + <table> + <tr> + <th> <?= t("Installed") ?> </th> + <th> <?= t("Language") ?> </th> + <th> <?= t("Default language") ?> </th> + </tr> <? endif ?> <tr class="<?= (isset($installed_locales[$code])) ? "g-available" : "" ?><?= ($default_locale == $code) ? " g-selected" : "" ?>"> <td> <?= form::checkbox("installed_locales[]", $code, isset($installed_locales[$code])) ?> </td> diff --git a/modules/gallery/views/error.html.php b/modules/gallery/views/error.html.php new file mode 100644 index 00000000..5d81b651 --- /dev/null +++ b/modules/gallery/views/error.html.php @@ -0,0 +1,12 @@ +<?php defined("SYSPATH") or die("No direct script access.") ?> +<div id="g-error"> + <h1> + <?= t("Dang... Something went wrong!") ?> + </h1> + <h2> + <?= t("We tried really hard, but it's broken.") ?> + </h2> + <p> + <?= t("Talk to your Gallery administrator for help fixing this!") ?> + </p> +</div>
\ No newline at end of file diff --git a/modules/gallery/views/error_404.html.php b/modules/gallery/views/error_404.html.php new file mode 100644 index 00000000..4b037a79 --- /dev/null +++ b/modules/gallery/views/error_404.html.php @@ -0,0 +1,21 @@ +<?php defined("SYSPATH") or die("No direct script access.") ?> +<div id="g-error"> + <h1> + <?= t("Dang... Page not found!") ?> + </h1> + <? if ($is_guest): ?> + <h2> + <?= t("Hey wait, you're not signed in yet!") ?> + </h2> + <p> + <?= t("Maybe the page exists, but is only visible to authorized users.") ?> + <?= t("Please sign in to find out.") ?> + </p> + <?= $login_form ?> + <? else: ?> + <p> + <?= t("Maybe the page exists, but is only visible to authorized users.") ?> + <?= t("If you think this is an error, talk to your Gallery administrator!") ?> + </p> + <? endif; ?> +</div>
\ No newline at end of file diff --git a/modules/gallery/views/kohana/error.php b/modules/gallery/views/kohana/error.php index 26628cf2..d55105a0 100644 --- a/modules/gallery/views/kohana/error.php +++ b/modules/gallery/views/kohana/error.php @@ -204,7 +204,7 @@ <pre><?= $name?></pre> </td> <td class="value"> - <pre><?= Kohana_Exception::dump($arg) ?></pre> + <pre><?= Kohana_Exception::safe_dump($arg, $name) ?></pre> </td> </tr> <? endforeach?> @@ -265,7 +265,7 @@ </code> </td> <td class="value"> - <pre><?= Kohana_Exception::dump($value) ?></pre> + <pre><?= Kohana_Exception::safe_dump($value, $key) ?></pre> </td> </tr> <? endforeach?> diff --git a/modules/gallery/views/kohana_error_page.php b/modules/gallery/views/kohana_error_page.php deleted file mode 100644 index b9fdcc19..00000000 --- a/modules/gallery/views/kohana_error_page.php +++ /dev/null @@ -1,127 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access.") ?> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <style type="text/css"> - body { - background: #fff; - font-size: 14px; - line-height: 130%; - } - - div.big_box { - padding: 10px; - background: #eee; - border: solid 1px #ccc; - font-family: sans-serif; - color: #111; - width: 42em; - margin: 20px auto; - } - - div#framework_error { - text-align: center; - } - - div#error_details { - text-align: left; - } - - code { - font-family: monospace; - font-size: 12px; - margin: 20px; - color: #333; - white-space: pre-wrap; - white-space: -moz-pre-wrap; - word-wrap: break-word; - } - - h3 { - font-family: sans-serif; - margin: 2px 0px 0px 0px; - padding: 8px 0px 0px 0px; - border-top: 1px solid #ddd; - } - - p { - padding: 0px; - margin: 0px 0px 10px 0px; - } - - li, pre { - padding: 0px; - margin: 0px; - } - </style> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> - <title><?= t("Something went wrong!") ?></title> - </head> - <body> - <? try { $user = identity::active_user(); } catch (Exception $e) { } ?> - <? $admin = php_sapi_name() == "cli" || isset($user) && $user->admin ?> - <div class="big_box" id="framework_error"> - <h1> - <?= t("Dang... Something went wrong!") ?> - </h1> - <h2> - <?= t("We tried really hard, but it's broken.") ?> - </h2> - <? if (!$admin): ?> - <p> - <?= t("Talk to your Gallery administrator for help fixing this!") ?> - </p> - <? endif ?> - </div> - <? if ($admin): ?> - <div class="big_box" id="error_details"> - <h2> - <?= t("Hey wait, you're an admin! We can tell you stuff.") ?> - </h2> - <script type="text/javascript"> - var show_details = function() { - document.getElementById("stuff").style.display = "block"; - document.getElementById("toggle").style.display = "none"; - } - </script> - <a id="toggle" href="#" onclick="javascript:show_details(); return false;"> - <b><?= t("Ok.. tell me stuff!") ?></b> - </a> - <div id="stuff" style="display: none"> - <? if (!empty($line) and !empty($file)): ?> - <div id="summary"> - <h3> - <?= t("Help!") ?> - </h3> - <p> - <?= t("If this stuff doesn't make any sense to you, <a href=\"%url\">ask for help in the Gallery forums</a>!", array("url" => "http://gallery.menalto.com/forum/96")) ?> - </p> - <h3> - <?= t("So here's the error:") ?> - </h3> - - <code class="block"><?= $message ?></code> - <p> - <?= t("File: <b>%file</b>, line: <b>%line</b>", array("file" => $file, "line" => $line)) ?> - </p> - </div> - <? endif ?> - - <? $trace = $PHP_ERROR ? array_slice(debug_backtrace(), 1) : $exception->getTrace(); ?> - <? $trace = Kohana::backtrace($trace); ?> - <? if (!empty($trace)): ?> - <div id="stack_trace"> - <h3> - <?= t("And here's how we got there:") ?> - </h3> - <?= $trace ?> - <? endif ?> - </div> - </div> - <? else: ?> - <? $trace = $PHP_ERROR ? array_slice(debug_backtrace(), 1) : $exception->getTraceAsString(); ?> - <? if (!empty($trace)): ?> - <? Kohana_Log::add("error", print_r($trace, 1)); ?> - <? endif ?> - <? endif ?> - </body> -</html> diff --git a/modules/gallery/views/menu.html.php b/modules/gallery/views/menu.html.php index cb49bcdf..17a249dd 100644 --- a/modules/gallery/views/menu.html.php +++ b/modules/gallery/views/menu.html.php @@ -1,7 +1,7 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> -<? if ($menu->elements): // Don't show the menu if it has no choices ?> +<? if (!$menu->is_empty()): // Don't show the menu if it has no choices ?> <? if ($menu->is_root): ?> -<ul <?= isset($menu->css_id) ? "id='$menu->css_id'" : "" ?> class="<?= $menu->css_class ?>"> +<ul <?= $menu->css_id ? "id='$menu->css_id'" : "" ?> class="<?= $menu->css_class ?>"> <? foreach ($menu->elements as $element): ?> <?= $element->render() ?> <? endforeach ?> diff --git a/modules/gallery/views/menu_ajax_link.html.php b/modules/gallery/views/menu_ajax_link.html.php index 00a394bc..06cd6f92 100644 --- a/modules/gallery/views/menu_ajax_link.html.php +++ b/modules/gallery/views/menu_ajax_link.html.php @@ -1,6 +1,6 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> <li> - <a id="<?= $menu->css_id ?>" + <a <?= $menu->css_id ? "id='{$menu->css_id}'" : "" ?> class="g-ajax-link <?= $menu->css_class ?>" href="<?= $menu->url ?>" title="<?= $menu->label->for_html_attr() ?>" diff --git a/modules/gallery/views/menu_dialog.html.php b/modules/gallery/views/menu_dialog.html.php index 99b1b013..b44080c3 100644 --- a/modules/gallery/views/menu_dialog.html.php +++ b/modules/gallery/views/menu_dialog.html.php @@ -1,6 +1,6 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> <li> - <a id="<?= $menu->css_id ?>" + <a <?= $menu->css_id ? "id='{$menu->css_id}'" : "" ?> class="g-dialog-link <?= $menu->css_class ?>" href="<?= $menu->url ?>" title="<?= $menu->label->for_html_attr() ?>"> diff --git a/modules/gallery/views/menu_link.html.php b/modules/gallery/views/menu_link.html.php index 8e4cdb95..a36d2754 100644 --- a/modules/gallery/views/menu_link.html.php +++ b/modules/gallery/views/menu_link.html.php @@ -1,6 +1,6 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> <li> - <a id="<?= $menu->css_id ?>" + <a <?= $menu->css_id ? "id='{$menu->css_id}'" : "" ?> class="g-menu-link <?= $menu->css_class ?>" href="<?= $menu->url ?>" title="<?= $menu->label->for_html_attr() ?>"> diff --git a/modules/gallery/views/reauthenticate.html.php b/modules/gallery/views/reauthenticate.html.php index 8611d0f7..9a6696fb 100644 --- a/modules/gallery/views/reauthenticate.html.php +++ b/modules/gallery/views/reauthenticate.html.php @@ -7,4 +7,9 @@ <?= t("You are currently logged in as %user_name.", array("user_name" => $user_name)) ?> </p> <?= $form ?> + <script type="text/javascript"> + $("#g-reauthenticate-form").ready(function() { + $("#g-password").focus(); + }); + </script> </div>
\ No newline at end of file diff --git a/modules/gallery/views/upgrader.html.php b/modules/gallery/views/upgrader.html.php index 55731440..c7a96cb5 100644 --- a/modules/gallery/views/upgrader.html.php +++ b/modules/gallery/views/upgrader.html.php @@ -112,7 +112,7 @@ <? else: // can_upgrade ?> <h1> <?= t("Who are you?") ?> </h1> <p> - <?= t("You're not logged in as an administrator, so we have to verify you to make sure it's ok for you to do an upgrade. To prove you can run an upgrade, create a file called <b>%name</b> in your <b>%tmp_dir_path</b> directory.", + <?= t("You're not logged in as an administrator, so we have to verify you to make sure it's ok for you to do an upgrade. To prove you can run an upgrade, create a file called <b> %name </b> in your <b>%tmp_dir_path</b> directory.", array("name" => "$upgrade_token", "tmp_dir_path" => "gallery3/var/tmp")) ?> </p> diff --git a/modules/gallery/views/user_profile.html.php b/modules/gallery/views/user_profile.html.php index 1c3e4ea2..257bd7ca 100644 --- a/modules/gallery/views/user_profile.html.php +++ b/modules/gallery/views/user_profile.html.php @@ -1,28 +1,5 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> -<style> - #g-user-profile div { - margin-top: 1em; - } - - #g-user-profile fieldset { - border: 1px solid #CCCCCC; - padding: 0 1em 0.8em; - } - - #g-user-profile fieldset label { - font-weight: bold; - } - - #g-user-profile fieldset div { - padding-left: 1em; - } - - #g-user-profile td { - border: none; - padding: 0; - } -</style> -<script> +<script type="text/javascript"> $(document).ready(function() { $("#g-profile-return").click(function(event) { history.go(-1); @@ -31,45 +8,40 @@ }); </script> <div id="g-user-profile"> - <h1> - <a href="#"> - <img src="<?= $user->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>" - alt="<?= html::clean_attribute($user->display_name()) ?>" - class="g-avatar" width="40" height="40" /> - </a> - <?= t("%name Profile", array("name" => $user->display_name())) ?> - </h1> - <? foreach ($info_parts as $info): ?> - <div> - <fieldset> - <label><?= html::purify($info->title) ?></label> - <div> - <?= $info->view ?> - </div> - </fieldset> - </div> - <? endforeach ?> - <div id="g-profile-buttons" class="ui-helper-clearfix g-right"> - <? if (!$user->guest && $not_current && !empty($user->email)): ?> - <a class="g-button ui-icon-right ui-state-default ui-corner-all g-dialog-link" - href="<?= url::site("user_profile/contact/{$user->id}") ?>"> - <?= t("Contact") ?> + <div class="ui-helper-clearfix"> + <a id="g-profile-return" class="g-button g-right ui-state-default ui-corner-all" href="#"> + <?= t("Return") ?> </a> - <? endif ?> <? if ($editable): ?> - <a class="g-button ui-icon-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("form/edit/users/{$user->id}") ?>"> - <?= t("Edit") ?> + <a class="g-button g-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("users/form_change_email/{$user->id}") ?>"> + <?= t("Change email") ?> </a> - <a class="g-button ui-icon-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("users/form_change_password/{$user->id}") ?>"> + <a class="g-button g-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("users/form_change_password/{$user->id}") ?>"> <?= t("Change password") ?> </a> - <a class="g-button ui-icon-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("users/form_change_email/{$user->id}") ?>"> - <?= t("Change email") ?> + <a class="g-button g-right ui-state-default ui-corner-all g-dialog-link" href="<?= url::site("form/edit/users/{$user->id}") ?>"> + <?= t("Edit") ?> </a> <? endif ?> - - <a id="g-profile-return" class="g-button ui-icon-right ui-state-default ui-corner-all" href="#"> - <?= t("Return") ?> + <? if ($contactable): ?> + <a class="g-button g-right ui-state-default ui-corner-all g-dialog-link" + href="<?= url::site("user_profile/contact/{$user->id}") ?>"> + <?= t("Contact") ?> </a> + <? endif ?> </div> + <h1> + <img src="<?= $user->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>" + alt="<?= html::clean_attribute($user->display_name()) ?>" + class="g-avatar g-left" width="40" height="40" /> + <?= t("User profile: %name", array("name" => $user->display_name())) ?> + </h1> + <? foreach ($info_parts as $info): ?> + <div class="g-block"> + <h2><?= html::purify($info->title) ?></h2> + <div class="g-block-content"> + <?= $info->view ?> + </div> + </div> + <? endforeach ?> </div> diff --git a/modules/gallery/views/user_profile_info.html.php b/modules/gallery/views/user_profile_info.html.php index 58e134bb..e559abda 100644 --- a/modules/gallery/views/user_profile_info.html.php +++ b/modules/gallery/views/user_profile_info.html.php @@ -2,7 +2,7 @@ <table> <? foreach ($user_profile_data as $label => $value): ?> <tr> - <td><?= html::clean($label) ?></td> + <th><?= html::clean($label) ?></th> <td><?= html::purify($value) ?></td> </tr> <? endforeach ?> diff --git a/modules/gallery/views/welcome_message.html.php b/modules/gallery/views/welcome_message.html.php index caeeff66..4d6ed726 100644 --- a/modules/gallery/views/welcome_message.html.php +++ b/modules/gallery/views/welcome_message.html.php @@ -15,12 +15,15 @@ </p> <p> - <a href="<?= url::site("user_profile/show/{$user->id}") ?>" + <a href="<?= url::site("admin/users/edit_user_form/{$user->id}") ?>" title="<?= t("Edit your profile")->for_html_attr() ?>" id="g-after-install-change-password-link" class="g-button ui-state-default ui-corners-all"> <?= t("Change password and email now") ?> </a> + <script type="text/javascript"> + $("#g-after-install-change-password-link").gallery_dialog(); + </script> </p> <p> |