From 6353a7c2decd62098ebc96951c38c9aade44fc4c Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Thu, 11 Feb 2010 14:28:32 -0800 Subject: Security: Fix leaking of album / photo names. Reject previous fix for ticket 1009. Side effect: Renaming auth::required_login() to login_page(). --- modules/gallery/helpers/access.php | 7 ++++++- modules/gallery/helpers/auth.php | 7 ++++--- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'modules/gallery/helpers') 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..8b0ce470 100644 --- a/modules/gallery/helpers/auth.php +++ b/modules/gallery/helpers/auth.php @@ -132,15 +132,16 @@ class auth_Core { } /** - * Redirect to the login page. + * Returns the themed login page. */ - static function require_login() { + static function login_page($continue_url=null) { $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)); + $continue_url or $continue_url = url::current(true); + Session::instance()->set("continue_url", $continue_url); return $view; } } \ No newline at end of file -- cgit v1.2.3 From 3439671bcfb99c1884285e4b4e53295f044e688f Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Fri, 12 Feb 2010 09:52:57 -0800 Subject: 1) Add a depth parameter to retrieving an item thru the rest api 2) Standardize the structure of members so that client programs can consistently parse the return information. 3) Added a summary parameter so that client programs can easily determine if the information returned is summary (item type, item title) or the full meal deal --- modules/gallery/helpers/item_rest.php | 14 ++++-------- modules/gallery/models/item.php | 41 +++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 17 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php index c0fc422a..72230d8b 100644 --- a/modules/gallery/helpers/item_rest.php +++ b/modules/gallery/helpers/item_rest.php @@ -30,6 +30,9 @@ class item_rest_Core { * name= * only return items where the name contains this substring * + * depth= + * return the children to the depth specified. + * * random=true * return a single random item * @@ -70,16 +73,7 @@ class item_rest_Core { $orm->where("type", "IN", explode(",", $p->type)); } - $members = array(); - foreach ($orm->find_all() as $child) { - $members[] = rest::url("item", $child); - } - - return array( - "url" => $request->url, - "entity" => $item->as_restful_array(), - "members" => $members, - "relationships" => rest::relationships("item", $item)); + return $item->as_restful_array(isset($p->depth) ? $p->depth : 0); } static function put($request) { diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index dbd56fa2..a1be4fbc 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -918,22 +918,49 @@ class Item_Model extends ORM_MPTT { /** * Same as ORM::as_array() but convert id fields into their RESTful form. */ - public function as_restful_array() { + public function as_restful_array($depth=0, $level=0) { // Convert item ids to rest URLs for consistency - $data = $this->as_array(); + $data = array("url" => rest::url("item", $this), + "entity" => $this->as_array(), + "members" => array(), + "relationships" => array()); + if ($tmp = $this->parent()) { - $data["parent"] = rest::url("item", $tmp); + $data["entity"]["parent"] = rest::url("item", $tmp); } - unset($data["parent_id"]); + unset($data["entity"]["parent_id"]); if ($tmp = $this->album_cover()) { - $data["album_cover"] = rest::url("item", $tmp); + $data["entity"]["album_cover"] = rest::url("item", $tmp); } - unset($data["album_cover_item_id"]); + unset($data["entity"]["album_cover_item_id"]); // 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) { - unset($data[$key]); + unset($data["entity"][$key]); + } + + // check that we have given enough information. At this point we don't + // return relationships and we give enough information to determine how to handle + // the children. + $summarize = $depth < $level; + if (!$summarize) { + $data["relationships"] = rest::relationships("item", $this); + } + + $next_level = $level + 1; + foreach ($this->children() as $child) { + if ($summarize) { + $data["members"][] = array("url" => rest::url("item", $child), + "entity" => array("title" => $child->title, + "type" => $child->type), + "members" => array(), + "summary" => true, + "relationships" => array()); + } else { + $data["members"][] = $child->as_restful_array($depth, $next_level); + } } + $data["summary"] = $summarize; return $data; } } -- cgit v1.2.3 From ce71ea6aa7eac72e54b1a9d7722c87beb61327de Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Fri, 12 Feb 2010 04:53:26 -0800 Subject: Revert "1) Add a depth parameter to retrieving an item thru the rest api" This reverts commit 3439671bcfb99c1884285e4b4e53295f044e688f. --- modules/gallery/helpers/item_rest.php | 14 ++++++++---- modules/gallery/models/item.php | 41 ++++++----------------------------- 2 files changed, 17 insertions(+), 38 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php index 72230d8b..c0fc422a 100644 --- a/modules/gallery/helpers/item_rest.php +++ b/modules/gallery/helpers/item_rest.php @@ -30,9 +30,6 @@ class item_rest_Core { * name= * only return items where the name contains this substring * - * depth= - * return the children to the depth specified. - * * random=true * return a single random item * @@ -73,7 +70,16 @@ class item_rest_Core { $orm->where("type", "IN", explode(",", $p->type)); } - return $item->as_restful_array(isset($p->depth) ? $p->depth : 0); + $members = array(); + foreach ($orm->find_all() as $child) { + $members[] = rest::url("item", $child); + } + + return array( + "url" => $request->url, + "entity" => $item->as_restful_array(), + "members" => $members, + "relationships" => rest::relationships("item", $item)); } static function put($request) { diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index a1be4fbc..dbd56fa2 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -918,49 +918,22 @@ class Item_Model extends ORM_MPTT { /** * Same as ORM::as_array() but convert id fields into their RESTful form. */ - public function as_restful_array($depth=0, $level=0) { + public function as_restful_array() { // Convert item ids to rest URLs for consistency - $data = array("url" => rest::url("item", $this), - "entity" => $this->as_array(), - "members" => array(), - "relationships" => array()); - + $data = $this->as_array(); if ($tmp = $this->parent()) { - $data["entity"]["parent"] = rest::url("item", $tmp); + $data["parent"] = rest::url("item", $tmp); } - unset($data["entity"]["parent_id"]); + unset($data["parent_id"]); if ($tmp = $this->album_cover()) { - $data["entity"]["album_cover"] = rest::url("item", $tmp); + $data["album_cover"] = rest::url("item", $tmp); } - unset($data["entity"]["album_cover_item_id"]); + unset($data["album_cover_item_id"]); // 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) { - unset($data["entity"][$key]); - } - - // check that we have given enough information. At this point we don't - // return relationships and we give enough information to determine how to handle - // the children. - $summarize = $depth < $level; - if (!$summarize) { - $data["relationships"] = rest::relationships("item", $this); - } - - $next_level = $level + 1; - foreach ($this->children() as $child) { - if ($summarize) { - $data["members"][] = array("url" => rest::url("item", $child), - "entity" => array("title" => $child->title, - "type" => $child->type), - "members" => array(), - "summary" => true, - "relationships" => array()); - } else { - $data["members"][] = $child->as_restful_array($depth, $next_level); - } + unset($data[$key]); } - $data["summary"] = $summarize; return $data; } } -- cgit v1.2.3 From d53f6d0e052fb455059170a311640fcd06cad798 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Fri, 12 Feb 2010 16:40:44 -0800 Subject: Fix for tickets 1009 and 603: Show a themed error page to guests / registered users (not to admins though). And show a login form to guests for 404 (incl. insufficient view permissions) errors. --- modules/gallery/controllers/albums.php | 13 +-- modules/gallery/controllers/items.php | 2 +- modules/gallery/controllers/movies.php | 2 +- modules/gallery/controllers/photos.php | 2 +- modules/gallery/helpers/access.php | 2 +- modules/gallery/helpers/auth.php | 14 --- modules/gallery/libraries/MY_Kohana_Exception.php | 59 +++++++++- modules/gallery/views/error.html.php | 12 ++ modules/gallery/views/error_404.html.php | 21 ++++ modules/gallery/views/kohana_error_page.php | 127 ---------------------- 10 files changed, 97 insertions(+), 157 deletions(-) create mode 100644 modules/gallery/views/error.html.php create mode 100644 modules/gallery/views/error_404.html.php delete mode 100644 modules/gallery/views/kohana_error_page.php (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index c2b474ee..1cc3b1ec 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -26,19 +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 - throw new Kohana_404_Exception(); + Event::run('system.404'); } - if (!access::can("view", $album)) { - if ($album->id == 1) { - // Even show the login page to logged in users. - // It's a better user experience than a "Dang" error page. - print auth::login_page(); - return; - } else { - access::required("view", $album); - } - } + access::required("view", $album); $page_size = module::get_var("gallery", "page_size", 9); $input = Input::instance(); diff --git a/modules/gallery/controllers/items.php b/modules/gallery/controllers/items.php index f261e3a9..0bd47b2d 100644 --- a/modules/gallery/controllers/items.php +++ b/modules/gallery/controllers/items.php @@ -21,7 +21,7 @@ class Items_Controller extends Controller { public function __call($function, $args) { $item = ORM::factory("item", (int)$function); if (!$item->loaded()) { - throw new Kohana_404_Exception(); + Event::run('system.404'); } // Redirect to the more specific resource type, since it will render diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php index 78a56e81..1dbcb481 100644 --- a/modules/gallery/controllers/movies.php +++ b/modules/gallery/controllers/movies.php @@ -22,7 +22,7 @@ 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 - throw new Kohana_404_Exception(); + Event::run('system.404'); } access::required("view", $movie); diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php index f2d47eec..2a77aea4 100644 --- a/modules/gallery/controllers/photos.php +++ b/modules/gallery/controllers/photos.php @@ -22,7 +22,7 @@ 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 - throw new Kohana_404_Exception(); + Event::run('system.404'); } access::required("view", $photo); diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php index 7e8b079a..c4c100ca 100644 --- a/modules/gallery/helpers/access.php +++ b/modules/gallery/helpers/access.php @@ -120,7 +120,7 @@ class access_Core { if (!self::can($perm_name, $item)) { if ($perm_name == "view") { // Treat as if the item didn't exist, don't leak any information. - throw new Kohana_404_Exception(); + Event::run('system.404'); } else { self::forbidden(); } diff --git a/modules/gallery/helpers/auth.php b/modules/gallery/helpers/auth.php index 8b0ce470..c3e9e6e9 100644 --- a/modules/gallery/helpers/auth.php +++ b/modules/gallery/helpers/auth.php @@ -130,18 +130,4 @@ class auth_Core { $session->set("admin_area_activity_timestamp", time()); return false; } - - /** - * Returns the themed login page. - */ - static function login_page($continue_url=null) { - $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. - $continue_url or $continue_url = url::current(true); - Session::instance()->set("continue_url", $continue_url); - return $view; - } } \ No newline at end of file diff --git a/modules/gallery/libraries/MY_Kohana_Exception.php b/modules/gallery/libraries/MY_Kohana_Exception.php index 1c40091a..d6f1f467 100644 --- a/modules/gallery/libraries/MY_Kohana_Exception.php +++ b/modules/gallery/libraries/MY_Kohana_Exception.php @@ -33,6 +33,63 @@ 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; } } \ No newline at end of file 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 @@ + +
+

+ +

+

+ +

+

+ +

+
\ 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..e5846e65 --- /dev/null +++ b/modules/gallery/views/error_404.html.php @@ -0,0 +1,21 @@ + +
+

+ +

+ +

+ +

+

+ + +

+ + +

+ + +

+ +
\ No newline at end of file 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 @@ - - - - - - <?= t("Something went wrong!") ?> - - - - admin ?> -
-

- -

-

- -

- -

- -

- -
- -
-

- -

- - - - - - - getTraceAsString(); ?> - - - - - - -- cgit v1.2.3 From 8412aeb1337c4060a77af7c94441ca8cbc6bb4ad Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Fri, 12 Feb 2010 19:05:44 -0800 Subject: For consistency, use straight Kohana_404_Exception instead of the event system. --- modules/gallery/controllers/albums.php | 2 +- modules/gallery/controllers/items.php | 2 +- modules/gallery/controllers/movies.php | 2 +- modules/gallery/controllers/photos.php | 2 +- modules/gallery/helpers/access.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index 1cc3b1ec..036dade0 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -26,7 +26,7 @@ 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 - Event::run('system.404'); + throw new Kohana_404_Exception(); } access::required("view", $album); diff --git a/modules/gallery/controllers/items.php b/modules/gallery/controllers/items.php index 0bd47b2d..f261e3a9 100644 --- a/modules/gallery/controllers/items.php +++ b/modules/gallery/controllers/items.php @@ -21,7 +21,7 @@ class Items_Controller extends Controller { public function __call($function, $args) { $item = ORM::factory("item", (int)$function); if (!$item->loaded()) { - Event::run('system.404'); + throw new Kohana_404_Exception(); } // Redirect to the more specific resource type, since it will render diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php index 1dbcb481..78a56e81 100644 --- a/modules/gallery/controllers/movies.php +++ b/modules/gallery/controllers/movies.php @@ -22,7 +22,7 @@ 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 - Event::run('system.404'); + throw new Kohana_404_Exception(); } access::required("view", $movie); diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php index 2a77aea4..f2d47eec 100644 --- a/modules/gallery/controllers/photos.php +++ b/modules/gallery/controllers/photos.php @@ -22,7 +22,7 @@ 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 - Event::run('system.404'); + throw new Kohana_404_Exception(); } access::required("view", $photo); diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php index c4c100ca..7e8b079a 100644 --- a/modules/gallery/helpers/access.php +++ b/modules/gallery/helpers/access.php @@ -120,7 +120,7 @@ class access_Core { if (!self::can($perm_name, $item)) { if ($perm_name == "view") { // Treat as if the item didn't exist, don't leak any information. - Event::run('system.404'); + throw new Kohana_404_Exception(); } else { self::forbidden(); } -- cgit v1.2.3 From 2dad1d7cd15bed3c89de11cadf4b3b5c43134f69 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Fri, 12 Feb 2010 20:59:26 -0800 Subject: Some HTML validation fixes (don't render empty
-- cgit v1.2.3 From 0f66db51efc427482aaf3b575fff84f015a3a2ab Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sat, 13 Feb 2010 18:03:46 -0800 Subject: Change JavaScript reauthentication check to check via XHR. Benefit: Getting the real deadline this way, not interfering with an ongoing maintenance task. --- modules/gallery/controllers/admin.php | 21 +++++++++++++++++++++ modules/gallery/helpers/gallery_theme.php | 17 +++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) (limited to 'modules/gallery/helpers') 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/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php index 9ffeb911..ec650e1c 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 = ''; + 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); + '; print $admin_session_redirect_check; if ($session->get("l10n_mode", false)) { -- cgit v1.2.3 From 141595e7096befe63d5c8a7176986f2e7bacbb5c Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Sun, 14 Feb 2010 07:35:03 -0800 Subject: Create an items REST collection requests that accepts a list of resource urls and returns the items associated with them. --- modules/gallery/helpers/items_rest.php | 44 ++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 modules/gallery/helpers/items_rest.php (limited to 'modules/gallery/helpers') 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 @@ +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; + } +} -- cgit v1.2.3 From 667d65aea460ea601858c54976495d294d93f017 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 14 Feb 2010 18:33:38 -0800 Subject: Fix for ticket 901: Wrap Gallery version string into bdo tag to override the BiDi algorithm. Also, properly marking the "Powere by" string for translation. See: http://www.w3.org/International/tutorials/bidi-xhtml/#Slide0420 --- installer/install.sql | 4 ++-- modules/gallery/helpers/gallery_installer.php | 13 ++++++++++--- modules/gallery/helpers/gallery_theme.php | 7 +++++-- modules/gallery/module.info | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/installer/install.sql b/installer/install.sql index dea324eb..28a9caa5 100644 --- a/installer/install.sql +++ b/installer/install.sql @@ -239,7 +239,7 @@ CREATE TABLE {modules} ( UNIQUE KEY `name` (`name`) ) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; SET character_set_client = @saved_cs_client; -INSERT INTO {modules} VALUES (1,1,'gallery',28); +INSERT INTO {modules} VALUES (1,1,'gallery',29); INSERT INTO {modules} VALUES (2,1,'user',3); INSERT INTO {modules} VALUES (3,1,'comment',2); INSERT INTO {modules} VALUES (4,1,'organize',1); @@ -389,7 +389,7 @@ INSERT INTO {vars} VALUES (NULL,'gallery','image_quality','75'); INSERT INTO {vars} VALUES (NULL,'gallery','image_sharpen','15'); INSERT INTO {vars} VALUES (NULL,'gallery','time_format','H:i:s'); INSERT INTO {vars} VALUES (NULL,'gallery','show_credits','1'); -INSERT INTO {vars} VALUES (NULL,'gallery','credits','Powered by Gallery %version'); +INSERT INTO {vars} VALUES (NULL,'gallery','credits','Powered by %gallery_version'); INSERT INTO {vars} VALUES (NULL,'gallery','simultaneous_upload_limit','5'); INSERT INTO {vars} VALUES (NULL,'gallery','admin_area_timeout','5400'); INSERT INTO {vars} VALUES (NULL,'gallery','blocks_dashboard_sidebar','a:4:{i:2;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"block_adder\";}i:3;a:2:{i:0;s:7:\"gallery\";i:1;s:5:\"stats\";}i:4;a:2:{i:0;s:7:\"gallery\";i:1;s:13:\"platform_info\";}i:5;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"project_news\";}}'); diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index dd53cf43..45d991af 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -284,11 +284,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 Gallery %version"); + // Mark string for translation + $powered_by_string = t("Powered by %gallery_version", + array("locale" => "root")); + module::set_var("gallery", "credits", $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", 29); } static function upgrade($version) { @@ -538,6 +540,11 @@ 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 %gallery_version"); + module::set_version("gallery", $version = 29); + } } static function uninstall() { diff --git a/modules/gallery/helpers/gallery_theme.php b/modules/gallery/helpers/gallery_theme.php index ec650e1c..d6944323 100644 --- a/modules/gallery/helpers/gallery_theme.php +++ b/modules/gallery/helpers/gallery_theme.php @@ -112,9 +112,12 @@ class gallery_theme_Core { } static function credits() { - return "
  • " . + $version_string = SafeString::of_safe_html( + 'Gallery ' . gallery::VERSION . ''); + return "
  • " . 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)) . "
  • "; } diff --git a/modules/gallery/module.info b/modules/gallery/module.info index ae300399..39615e1c 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 = 29 -- cgit v1.2.3 From 409121942590e12692eaf4e6e9e8b71bfe5ed60c Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 14 Feb 2010 19:26:34 -0800 Subject: Fix for ticket #491: Make user and group names translatable. Also fixed a UI bug: No longer showing the edit user buttons to admins in the profile view (to be consistent with the requirements in the controller). --- modules/gallery/controllers/user_profile.php | 5 +++-- modules/gallery/helpers/gallery_event.php | 3 +++ modules/gallery/views/permissions_form.html.php | 2 +- modules/user/helpers/user_installer.php | 8 ++++---- modules/user/models/user.php | 2 +- modules/user/views/admin_users.html.php | 2 +- modules/user/views/admin_users_group.html.php | 6 +++--- 7 files changed, 16 insertions(+), 12 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php index 327d2ff1..05373466 100644 --- a/modules/gallery/controllers/user_profile.php +++ b/modules/gallery/controllers/user_profile.php @@ -23,7 +23,8 @@ class User_Profile_Controller extends Controller { $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); + $can_edit = $is_current_active && !$active_user->guest; + $display_all = $active_user->admin || $can_edit; $v = new Theme_View("page.html", "other", "profile"); $v->page_title = t("%name Profile", array("name" => $user->display_name())); @@ -32,7 +33,7 @@ class User_Profile_Controller extends Controller { // @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->editable = identity::is_writable() && $can_edit; $event_data = (object)array("user" => $user, "display_all" => $display_all, "content" => array()); module::event("show_user_profile", $event_data); diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index faf1c0c6..3f77bc42 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -423,6 +423,9 @@ class gallery_event_Core { if ($field == "locale") { $value = locales::display_name($value); } + if ($field == "full_name") { + $value = t($value); + } $v->user_profile_data[(string) $label] = $value; } } diff --git a/modules/gallery/views/permissions_form.html.php b/modules/gallery/views/permissions_form.html.php index f1714119..b486acb7 100644 --- a/modules/gallery/views/permissions_form.html.php +++ b/modules/gallery/views/permissions_form.html.php @@ -5,7 +5,7 @@ - name) ?> + name)) ?> diff --git a/modules/user/helpers/user_installer.php b/modules/user/helpers/user_installer.php index 729f087a..c57ad010 100644 --- a/modules/user/helpers/user_installer.php +++ b/modules/user/helpers/user_installer.php @@ -98,25 +98,25 @@ class user_installer { DEFAULT CHARSET=utf8;"); $everybody = ORM::factory("group"); - $everybody->name = "Everybody"; + $everybody->name = t("Everybody", array("locale" => "root")); $everybody->special = true; $everybody->save(); $registered = ORM::factory("group"); - $registered->name = "Registered Users"; + $registered->name = t("Registered Users", array("locale" => "root")); $registered->special = true; $registered->save(); $guest = ORM::factory("user"); $guest->name = "guest"; - $guest->full_name = "Guest User"; + $guest->full_name = t("Guest User", array("locale" => "root")); $guest->password = ""; $guest->guest = true; $guest->save(); $admin = ORM::factory("user"); $admin->name = "admin"; - $admin->full_name = "Gallery Administrator"; + $admin->full_name = t("Gallery Administrator", array("locale" => "root")); $admin->password = "admin"; $admin->email = "unknown@unknown.com"; $admin->admin = true; diff --git a/modules/user/models/user.php b/modules/user/models/user.php index 4404ee63..aa752203 100644 --- a/modules/user/models/user.php +++ b/modules/user/models/user.php @@ -113,7 +113,7 @@ class User_Model extends ORM implements User_Definition { * @return string */ public function display_name() { - return empty($this->full_name) ? $this->name : $this->full_name; + return empty($this->full_name) ? $this->name : t($this->full_name); } /** diff --git a/modules/user/views/admin_users.html.php b/modules/user/views/admin_users.html.php index 270a7207..69d97547 100644 --- a/modules/user/views/admin_users.html.php +++ b/modules/user/views/admin_users.html.php @@ -78,7 +78,7 @@ name) ?> - full_name) ?> + full_name)) ?> email) ?> diff --git a/modules/user/views/admin_users_group.html.php b/modules/user/views/admin_users_group.html.php index 6c6c341e..8317d393 100644 --- a/modules/user/views/admin_users_group.html.php +++ b/modules/user/views/admin_users_group.html.php @@ -1,9 +1,9 @@

    - name) ?> + name)) ?> special): ?> id") ?>" - title=" $group->name))->for_html_attr() ?>" + title=" t(html::clean($group->name))))->for_html_attr() ?>" class="g-dialog-link g-button g-right"> @@ -22,7 +22,7 @@ $user->name, "group" => $group->name))->for_html_attr() ?>"> + array("user" => $user->name, "group" => t(html::clean($group->name))))->for_html_attr() ?>"> -- cgit v1.2.3 From dcddc68f58dac2f0fe71f5a00ea4af32618efa13 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Mon, 15 Feb 2010 13:12:38 -0800 Subject: Never assign a SafeString instance to a Model member (or hell will break loose). --- modules/gallery/helpers/gallery_installer.php | 2 +- modules/user/helpers/user_installer.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index 45d991af..b594ddcf 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -287,7 +287,7 @@ class gallery_installer { // Mark string for translation $powered_by_string = t("Powered by %gallery_version", array("locale" => "root")); - module::set_var("gallery", "credits", $powered_by_string); + 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", 29); diff --git a/modules/user/helpers/user_installer.php b/modules/user/helpers/user_installer.php index c57ad010..9e757ecd 100644 --- a/modules/user/helpers/user_installer.php +++ b/modules/user/helpers/user_installer.php @@ -98,25 +98,25 @@ class user_installer { DEFAULT CHARSET=utf8;"); $everybody = ORM::factory("group"); - $everybody->name = t("Everybody", array("locale" => "root")); + $everybody->name = (string) t("Everybody", array("locale" => "root")); $everybody->special = true; $everybody->save(); $registered = ORM::factory("group"); - $registered->name = t("Registered Users", array("locale" => "root")); + $registered->name = (string) t("Registered Users", array("locale" => "root")); $registered->special = true; $registered->save(); $guest = ORM::factory("user"); $guest->name = "guest"; - $guest->full_name = t("Guest User", array("locale" => "root")); + $guest->full_name = (string) t("Guest User", array("locale" => "root")); $guest->password = ""; $guest->guest = true; $guest->save(); $admin = ORM::factory("user"); $admin->name = "admin"; - $admin->full_name = t("Gallery Administrator", array("locale" => "root")); + $admin->full_name = (string) t("Gallery Administrator", array("locale" => "root")); $admin->password = "admin"; $admin->email = "unknown@unknown.com"; $admin->admin = true; -- cgit v1.2.3 From 99c131e845b5bbfa22b93fa783b5ce671bc27e40 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 18 Feb 2010 16:20:23 -0800 Subject: Revert "Never assign a SafeString instance to a Model member (or hell will break loose)." This reverts commit dcddc68f58dac2f0fe71f5a00ea4af32618efa13. --- modules/gallery/helpers/gallery_installer.php | 2 +- modules/user/helpers/user_installer.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index b594ddcf..45d991af 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -287,7 +287,7 @@ class gallery_installer { // Mark string for translation $powered_by_string = t("Powered by %gallery_version", array("locale" => "root")); - module::set_var("gallery", "credits", (string) $powered_by_string); + module::set_var("gallery", "credits", $powered_by_string); module::set_var("gallery", "simultaneous_upload_limit", 5); module::set_var("gallery", "admin_area_timeout", 90 * 60); module::set_version("gallery", 29); diff --git a/modules/user/helpers/user_installer.php b/modules/user/helpers/user_installer.php index 9e757ecd..c57ad010 100644 --- a/modules/user/helpers/user_installer.php +++ b/modules/user/helpers/user_installer.php @@ -98,25 +98,25 @@ class user_installer { DEFAULT CHARSET=utf8;"); $everybody = ORM::factory("group"); - $everybody->name = (string) t("Everybody", array("locale" => "root")); + $everybody->name = t("Everybody", array("locale" => "root")); $everybody->special = true; $everybody->save(); $registered = ORM::factory("group"); - $registered->name = (string) t("Registered Users", array("locale" => "root")); + $registered->name = t("Registered Users", array("locale" => "root")); $registered->special = true; $registered->save(); $guest = ORM::factory("user"); $guest->name = "guest"; - $guest->full_name = (string) t("Guest User", array("locale" => "root")); + $guest->full_name = t("Guest User", array("locale" => "root")); $guest->password = ""; $guest->guest = true; $guest->save(); $admin = ORM::factory("user"); $admin->name = "admin"; - $admin->full_name = (string) t("Gallery Administrator", array("locale" => "root")); + $admin->full_name = t("Gallery Administrator", array("locale" => "root")); $admin->password = "admin"; $admin->email = "unknown@unknown.com"; $admin->admin = true; -- cgit v1.2.3 From 7d98d4b7b9d16f32ed98c8eeb051be4149468dc6 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 18 Feb 2010 16:20:59 -0800 Subject: Revert "Fix for ticket #491: Make user and group names translatable." This reverts commit 409121942590e12692eaf4e6e9e8b71bfe5ed60c. --- modules/gallery/controllers/user_profile.php | 5 ++--- modules/gallery/helpers/gallery_event.php | 3 --- modules/gallery/views/permissions_form.html.php | 2 +- modules/user/helpers/user_installer.php | 8 ++++---- modules/user/models/user.php | 2 +- modules/user/views/admin_users.html.php | 2 +- modules/user/views/admin_users_group.html.php | 6 +++--- 7 files changed, 12 insertions(+), 16 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php index 05373466..327d2ff1 100644 --- a/modules/gallery/controllers/user_profile.php +++ b/modules/gallery/controllers/user_profile.php @@ -23,8 +23,7 @@ class User_Profile_Controller extends Controller { $user = identity::lookup_user($id); $active_user = identity::active_user(); $is_current_active = $active_user->id == $id; - $can_edit = $is_current_active && !$active_user->guest; - $display_all = $active_user->admin || $can_edit; + $display_all = $active_user->admin || ($is_current_active && !$active_user->guest); $v = new Theme_View("page.html", "other", "profile"); $v->page_title = t("%name Profile", array("name" => $user->display_name())); @@ -33,7 +32,7 @@ class User_Profile_Controller extends Controller { // @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() && $can_edit; + $v->content->editable = identity::is_writable() && $display_all; $event_data = (object)array("user" => $user, "display_all" => $display_all, "content" => array()); module::event("show_user_profile", $event_data); diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 3f77bc42..faf1c0c6 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -423,9 +423,6 @@ class gallery_event_Core { if ($field == "locale") { $value = locales::display_name($value); } - if ($field == "full_name") { - $value = t($value); - } $v->user_profile_data[(string) $label] = $value; } } diff --git a/modules/gallery/views/permissions_form.html.php b/modules/gallery/views/permissions_form.html.php index b486acb7..f1714119 100644 --- a/modules/gallery/views/permissions_form.html.php +++ b/modules/gallery/views/permissions_form.html.php @@ -5,7 +5,7 @@ - name)) ?> + name) ?> diff --git a/modules/user/helpers/user_installer.php b/modules/user/helpers/user_installer.php index c57ad010..729f087a 100644 --- a/modules/user/helpers/user_installer.php +++ b/modules/user/helpers/user_installer.php @@ -98,25 +98,25 @@ class user_installer { DEFAULT CHARSET=utf8;"); $everybody = ORM::factory("group"); - $everybody->name = t("Everybody", array("locale" => "root")); + $everybody->name = "Everybody"; $everybody->special = true; $everybody->save(); $registered = ORM::factory("group"); - $registered->name = t("Registered Users", array("locale" => "root")); + $registered->name = "Registered Users"; $registered->special = true; $registered->save(); $guest = ORM::factory("user"); $guest->name = "guest"; - $guest->full_name = t("Guest User", array("locale" => "root")); + $guest->full_name = "Guest User"; $guest->password = ""; $guest->guest = true; $guest->save(); $admin = ORM::factory("user"); $admin->name = "admin"; - $admin->full_name = t("Gallery Administrator", array("locale" => "root")); + $admin->full_name = "Gallery Administrator"; $admin->password = "admin"; $admin->email = "unknown@unknown.com"; $admin->admin = true; diff --git a/modules/user/models/user.php b/modules/user/models/user.php index aa752203..4404ee63 100644 --- a/modules/user/models/user.php +++ b/modules/user/models/user.php @@ -113,7 +113,7 @@ class User_Model extends ORM implements User_Definition { * @return string */ public function display_name() { - return empty($this->full_name) ? $this->name : t($this->full_name); + return empty($this->full_name) ? $this->name : $this->full_name; } /** diff --git a/modules/user/views/admin_users.html.php b/modules/user/views/admin_users.html.php index 69d97547..270a7207 100644 --- a/modules/user/views/admin_users.html.php +++ b/modules/user/views/admin_users.html.php @@ -78,7 +78,7 @@ name) ?> - full_name)) ?> + full_name) ?> email) ?> diff --git a/modules/user/views/admin_users_group.html.php b/modules/user/views/admin_users_group.html.php index 8317d393..6c6c341e 100644 --- a/modules/user/views/admin_users_group.html.php +++ b/modules/user/views/admin_users_group.html.php @@ -1,9 +1,9 @@

    - name)) ?> + name) ?> special): ?> id") ?>" - title=" t(html::clean($group->name))))->for_html_attr() ?>" + title=" $group->name))->for_html_attr() ?>" class="g-dialog-link g-button g-right"> @@ -22,7 +22,7 @@ $user->name, "group" => t(html::clean($group->name))))->for_html_attr() ?>"> + array("user" => $user->name, "group" => $group->name))->for_html_attr() ?>"> -- cgit v1.2.3 From 0d72daf3d2d831ca3588ebabe720029bab3ccb8f Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 18 Feb 2010 16:32:25 -0800 Subject: Restore the gallery_installer change from reverted dcddc68f58dac2f0fe71f5a00ea4af32618efa13 that casts $powered_by_string from SafeString to string. --- modules/gallery/helpers/gallery_installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index 45d991af..b594ddcf 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -287,7 +287,7 @@ class gallery_installer { // Mark string for translation $powered_by_string = t("Powered by %gallery_version", array("locale" => "root")); - module::set_var("gallery", "credits", $powered_by_string); + 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", 29); -- cgit v1.2.3 From d388e4bb868602f293b73918981bee1de6176a24 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Fri, 19 Feb 2010 11:40:49 -0800 Subject: Refactor away the "display_all" construct in User_Profile_Controller. "display_all" is too coarse, and we should be letting event handlers make the appropriate decision on what to display and when. This duplicates some code, but it's now very clear in the event handlers what's getting shown. Throw a 404 if we try to view the user profile for a missing user. The only feature change in this should be that we now display the name, full name and website for a user to any other registered user, which makes sense since these are typically public fields. Don't show any of the edit buttons unless identity::is_writable() --- modules/gallery/controllers/user_profile.php | 16 +++++----- modules/gallery/helpers/gallery_event.php | 2 +- modules/gallery/views/user_profile.html.php | 4 +-- .../notification/helpers/notification_event.php | 36 +++++++++++++--------- modules/rest/helpers/rest_event.php | 28 +++++++++++------ 5 files changed, 51 insertions(+), 35 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php index 05373466..b89bc358 100644 --- a/modules/gallery/controllers/user_profile.php +++ b/modules/gallery/controllers/user_profile.php @@ -21,21 +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; - $can_edit = $is_current_active && !$active_user->guest; - $display_all = $active_user->admin || $can_edit; + 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() && $can_edit; + $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/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index faf1c0c6..36f91142 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -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/views/user_profile.html.php b/modules/gallery/views/user_profile.html.php index 53e8dc1e..257bd7ca 100644 --- a/modules/gallery/views/user_profile.html.php +++ b/modules/gallery/views/user_profile.html.php @@ -12,18 +12,18 @@ + id}") ?>"> id}") ?>"> - id}") ?>"> - guest && $not_current && !empty($user->email)): ?> + id}") ?>"> diff --git a/modules/notification/helpers/notification_event.php b/modules/notification/helpers/notification_event.php index c8628ae4..19e8dedb 100644 --- a/modules/notification/helpers/notification_event.php +++ b/modules/notification/helpers/notification_event.php @@ -128,23 +128,31 @@ class notification_event_Core { } static function show_user_profile($data) { - if ($data->display_all) { - $view = new View("user_profile_notification.html"); - $view->subscriptions = array(); - foreach(ORM::factory("subscription") - ->where("user_id", "=", $data->user->id) - ->find_all() as $subscription) { - $item = ORM::factory("item") + // Guests don't see comment listings + if (identity::active_user()->guest) { + return; + } + + // Only logged in users can see their comment listings + if (identity::active_user()->id != $data->user->id) { + return; + } + + $view = new View("user_profile_notification.html"); + $view->subscriptions = array(); + foreach(ORM::factory("subscription") + ->where("user_id", "=", $data->user->id) + ->find_all() as $subscription) { + $item = ORM::factory("item") ->where("id", "=", $subscription->item_id) ->find(); - if ($item->loaded()) { - $view->subscriptions[] = (object)array("id" => $subscription->id, "title" => $item->title, - "url" => $item->url()); - } - } - if (count($view->subscriptions) > 0) { - $data->content[] = (object)array("title" => t("Watching"), "view" => $view); + if ($item->loaded()) { + $view->subscriptions[] = (object)array("id" => $subscription->id, "title" => $item->title, + "url" => $item->url()); } } + if (count($view->subscriptions) > 0) { + $data->content[] = (object)array("title" => t("Watching"), "view" => $view); + } } } \ No newline at end of file diff --git a/modules/rest/helpers/rest_event.php b/modules/rest/helpers/rest_event.php index f9aa34e3..c46e65c4 100644 --- a/modules/rest/helpers/rest_event.php +++ b/modules/rest/helpers/rest_event.php @@ -76,19 +76,27 @@ class rest_event { } static function show_user_profile($data) { - if ($data->display_all) { - $view = new View("user_profile_rest.html"); - $key = ORM::factory("user_access_token") + // Guests can't see a REST key + if (identity::active_user()->guest) { + return; + } + + // Only logged in users can see their own REST key + if (identity::active_user()->id != $data->user->id) { + return; + } + + $view = new View("user_profile_rest.html"); + $key = ORM::factory("user_access_token") ->where("user_id", "=", $data->user->id) ->find(); - if (!$key->loaded()) { - $key->user_id = $data->user->id; - $key->access_key = md5($data->user->name . rand()); - $key->save(); - } - $view->rest_key = $key->access_key; - $data->content[] = (object)array("title" => t("Rest api"), "view" => $view); + if (!$key->loaded()) { + $key->user_id = $data->user->id; + $key->access_key = md5($data->user->name . rand()); + $key->save(); } + $view->rest_key = $key->access_key; + $data->content[] = (object)array("title" => t("Rest api"), "view" => $view); } } -- cgit v1.2.3 From 5ddd7c9677b644396981de7df8176a3b168ffe21 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 21 Feb 2010 20:04:06 -0800 Subject: Fix Kohana's internal cache for Gallery's usage pattern. Adds a core.internal_cache_read_only config variable to Kohana's internals. Kohana's internal_cache for find_file wasn't working in Gallery because the cache would be emptied on each request after reading it from disk and before most lookups would run. 1. Bootstrap sets initial core.modules (= include path): forge, kohana23_compat, gallery. 2. Kohana::setup() loads find_file cache from disk. 3. Gallery loads list of active modules and themes, and updates the core.modules value (=include path), which forces the internal find_file cache to be empties (which makes sense). 4. Request processing starts, and thus 80% of all Kohana::find_file() triggered is_file() invocations start off with an empty find_file cache. In the case of my small Gallery installation, we're talking about 3100 is_file() invocations per request with or without internal_cache enabled. With this fix, this number is down to 800 invocations. The basic idea is that we treat the cache as read only and don't write any (possibly dirty) values to it in memory until we're sure that the include path won't change later on in the request processing. Once we know the list of active modules and themes, we can update core.modules and finally flip the read-only state of the cache and start writing to it. --- application/config/config.php | 6 ++++ modules/gallery/helpers/gallery_event.php | 1 + system/core/Kohana.php | 47 ++++++++++++++++++++----------- 3 files changed, 37 insertions(+), 17 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/application/config/config.php b/application/config/config.php index aecc400c..1c5bccb7 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -67,6 +67,12 @@ $config["url_suffix"] = ""; * can give significant speed improvements at the expense of delayed updating. */ $config["internal_cache"] = FALSE; +/** + * Enable or disable writing to the internal cache. Used by Gallery to treat + * the cache as read-only until all active modules and themes are in the + * include path. + */ +$config["internal_cache_read_only"] = TRUE; $config["internal_cache_path"] = VARPATH . "tmp/"; /** diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 36f91142..a6783bc6 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -25,6 +25,7 @@ class gallery_event_Core { static function gallery_ready() { identity::load_user(); theme::load_themes(); + Kohana_Config::instance()->set('core.internal_cache_read_only', false); locales::set_request_locale(); } diff --git a/system/core/Kohana.php b/system/core/Kohana.php index ae056d0e..1ed6d725 100644 --- a/system/core/Kohana.php +++ b/system/core/Kohana.php @@ -365,13 +365,17 @@ abstract class Kohana_Core { // Add SYSPATH as the last path Kohana::$include_paths[] = SYSPATH; - // Clear cached include paths - self::$internal_cache['find_file_paths'] = array(); - if ( ! isset(self::$write_cache['find_file_paths'])) + if ( ! Kohana::config('core.internal_cache_read_only')) { - // Write cache at shutdown - self::$write_cache['find_file_paths'] = TRUE; - } + // Clear cached include paths + self::$internal_cache['find_file_paths'] = array(); + + if ( ! isset(self::$write_cache['find_file_paths'])) + { + // Write cache at shutdown + self::$write_cache['find_file_paths'] = TRUE; + } + } } @@ -818,13 +822,17 @@ abstract class Kohana_Core { } } - if ( ! isset(Kohana::$write_cache['find_file_paths'])) + if ( ! Kohana::config('core.internal_cache_read_only')) { - // Write cache at shutdown - Kohana::$write_cache['find_file_paths'] = TRUE; - } + Kohana::$internal_cache['find_file_paths'][$search] = $found; - return Kohana::$internal_cache['find_file_paths'][$search] = $found; + if ( ! isset(Kohana::$write_cache['find_file_paths'])) + { + // Write cache at shutdown + Kohana::$write_cache['find_file_paths'] = TRUE; + } + } + return $found; } /** @@ -900,8 +908,7 @@ abstract class Kohana_Core { public static function message($key, $args = array()) { // Extract the main group from the key - $group = explode('.', $key, 2); - $group = $group[0]; + list ($group, $subkey) = explode('.', $key, 2); if ( ! isset(Kohana::$internal_cache['messages'][$group])) { @@ -913,17 +920,23 @@ abstract class Kohana_Core { include $file[0]; } - if ( ! isset(Kohana::$write_cache['messages'])) + if ( ! isset(Kohana::$write_cache['messages']) && ! Kohana::config('core.internal_cache_read_only')) { // Write language cache Kohana::$write_cache['messages'] = TRUE; } - - Kohana::$internal_cache['messages'][$group] = $messages; + if ( ! Kohana::config('core.internal_cache_read_only')) + { + Kohana::$internal_cache['messages'][$group] = $messages; + } + } + else + { + $messages = Kohana::$internal_cache['messages'][$group]; } // Get the line from cache - $line = Kohana::key_string(Kohana::$internal_cache['messages'], $key); + $line = Kohana::key_string($messages, $subkey); if ($line === NULL) { -- cgit v1.2.3 From 6cbe0f78aa80a2810908a76ca163f1dfff2f0726 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 21 Feb 2010 21:07:55 -0800 Subject: Revert "Fix Kohana's internal cache for Gallery's usage pattern." This reverts commit 5ddd7c9677b644396981de7df8176a3b168ffe21. --- application/config/config.php | 6 ---- modules/gallery/helpers/gallery_event.php | 1 - system/core/Kohana.php | 47 +++++++++++-------------------- 3 files changed, 17 insertions(+), 37 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/application/config/config.php b/application/config/config.php index 1c5bccb7..aecc400c 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -67,12 +67,6 @@ $config["url_suffix"] = ""; * can give significant speed improvements at the expense of delayed updating. */ $config["internal_cache"] = FALSE; -/** - * Enable or disable writing to the internal cache. Used by Gallery to treat - * the cache as read-only until all active modules and themes are in the - * include path. - */ -$config["internal_cache_read_only"] = TRUE; $config["internal_cache_path"] = VARPATH . "tmp/"; /** diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index a6783bc6..36f91142 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -25,7 +25,6 @@ class gallery_event_Core { static function gallery_ready() { identity::load_user(); theme::load_themes(); - Kohana_Config::instance()->set('core.internal_cache_read_only', false); locales::set_request_locale(); } diff --git a/system/core/Kohana.php b/system/core/Kohana.php index 1ed6d725..ae056d0e 100644 --- a/system/core/Kohana.php +++ b/system/core/Kohana.php @@ -365,17 +365,13 @@ abstract class Kohana_Core { // Add SYSPATH as the last path Kohana::$include_paths[] = SYSPATH; - if ( ! Kohana::config('core.internal_cache_read_only')) + // Clear cached include paths + self::$internal_cache['find_file_paths'] = array(); + if ( ! isset(self::$write_cache['find_file_paths'])) { - // Clear cached include paths - self::$internal_cache['find_file_paths'] = array(); - - if ( ! isset(self::$write_cache['find_file_paths'])) - { - // Write cache at shutdown - self::$write_cache['find_file_paths'] = TRUE; - } - } + // Write cache at shutdown + self::$write_cache['find_file_paths'] = TRUE; + } } @@ -822,17 +818,13 @@ abstract class Kohana_Core { } } - if ( ! Kohana::config('core.internal_cache_read_only')) + if ( ! isset(Kohana::$write_cache['find_file_paths'])) { - Kohana::$internal_cache['find_file_paths'][$search] = $found; - - if ( ! isset(Kohana::$write_cache['find_file_paths'])) - { - // Write cache at shutdown - Kohana::$write_cache['find_file_paths'] = TRUE; - } + // Write cache at shutdown + Kohana::$write_cache['find_file_paths'] = TRUE; } - return $found; + + return Kohana::$internal_cache['find_file_paths'][$search] = $found; } /** @@ -908,7 +900,8 @@ abstract class Kohana_Core { public static function message($key, $args = array()) { // Extract the main group from the key - list ($group, $subkey) = explode('.', $key, 2); + $group = explode('.', $key, 2); + $group = $group[0]; if ( ! isset(Kohana::$internal_cache['messages'][$group])) { @@ -920,23 +913,17 @@ abstract class Kohana_Core { include $file[0]; } - if ( ! isset(Kohana::$write_cache['messages']) && ! Kohana::config('core.internal_cache_read_only')) + if ( ! isset(Kohana::$write_cache['messages'])) { // Write language cache Kohana::$write_cache['messages'] = TRUE; } - if ( ! Kohana::config('core.internal_cache_read_only')) - { - Kohana::$internal_cache['messages'][$group] = $messages; - } - } - else - { - $messages = Kohana::$internal_cache['messages'][$group]; + + Kohana::$internal_cache['messages'][$group] = $messages; } // Get the line from cache - $line = Kohana::key_string($messages, $subkey); + $line = Kohana::key_string(Kohana::$internal_cache['messages'], $key); if ($line === NULL) { -- cgit v1.2.3 From 334cd2368de24a76cd49681a14295350e85714d0 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 21 Feb 2010 23:50:01 -0800 Subject: Performance improvement: Load all translations of a locale as one serialized array from the Cache. Until now, we loaded hundreds of translation messages row by row, and unserializing one by one at bootstrap time. That amounted to a significant percentage of the complete request time. This approach is more than 10x faster. --- modules/gallery/controllers/l10n_client.php | 2 ++ modules/gallery/helpers/gallery_task.php | 2 ++ modules/gallery/libraries/Gallery_I18n.php | 45 ++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 13 deletions(-) (limited to 'modules/gallery/helpers') 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/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/libraries/Gallery_I18n.php b/modules/gallery/libraries/Gallery_I18n.php index ac0588e3..0e9c0bdc 100644 --- a/modules/gallery/libraries/Gallery_I18n.php +++ b/modules/gallery/libraries/Gallery_I18n.php @@ -150,33 +150,43 @@ 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 (empty($translations)) { 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) { @@ -256,6 +266,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]; -- cgit v1.2.3 From 6ce01328422cc587dedf555d0ba3eb8a0ee05a9f Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Mon, 22 Feb 2010 00:30:54 -0800 Subject: Fix for ticket #1027: Add index on cache key column. (and fix the packager to truncate the cache table before packaging) --- installer/install.sql | 3 ++- modules/gallery/controllers/packager.php | 1 + modules/gallery/helpers/gallery_installer.php | 12 +++++++++++- modules/gallery/module.info | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/installer/install.sql b/installer/install.sql index 28a9caa5..ebe3651d 100644 --- a/installer/install.sql +++ b/installer/install.sql @@ -42,6 +42,7 @@ CREATE TABLE {caches} ( `expiration` int(9) NOT NULL, `cache` longblob, PRIMARY KEY (`id`), + KEY `key` (`key`), KEY `tags` (`tags`) ) DEFAULT CHARSET=utf8; SET character_set_client = @saved_cs_client; @@ -239,7 +240,7 @@ CREATE TABLE {modules} ( UNIQUE KEY `name` (`name`) ) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; SET character_set_client = @saved_cs_client; -INSERT INTO {modules} VALUES (1,1,'gallery',29); +INSERT INTO {modules} VALUES (1,1,'gallery',30); INSERT INTO {modules} VALUES (2,1,'user',3); INSERT INTO {modules} VALUES (3,1,'comment',2); INSERT INTO {modules} VALUES (4,1,'organize',1); 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/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index b594ddcf..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;"); @@ -290,7 +295,7 @@ class gallery_installer { 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", 29); + module::set_version("gallery", 30); } static function upgrade($version) { @@ -545,6 +550,11 @@ class gallery_installer { module::set_var("gallery", "credits", "Powered by %gallery_version"); 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/module.info b/modules/gallery/module.info index 39615e1c..df2be978 100644 --- a/modules/gallery/module.info +++ b/modules/gallery/module.info @@ -1,3 +1,3 @@ name = "Gallery 3" description = "Gallery core application" -version = 29 +version = 30 -- cgit v1.2.3 From fb5503be09047def6efd24a74188ad55af7a80f2 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 23 Feb 2010 11:10:32 -0800 Subject: Name this release "Santa Fe". Fixes ticket #683. --- modules/gallery/helpers/gallery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/gallery/helpers') 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 -- cgit v1.2.3 From c38bee203b8e89cfb1446ecacd133f3c679ffbcc Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Wed, 24 Feb 2010 16:21:54 -0800 Subject: Add Faroese to the language list. Verified that it uses the default plural rules, thus no changes in Gallery_I18n.php or on the server side required. --- modules/gallery/helpers/locales.php | 1 + 1 file changed, 1 insertion(+) (limited to 'modules/gallery/helpers') 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 -- cgit v1.2.3