From 50146985deb5e3aecb47e255b2842d1e253bdb75 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 12 Oct 2015 19:03:12 +0200 Subject: [PATCH] Added CMS_HOOK_CACHE, and admin cache. Prepared evolution of feed module, by allowing json object to list feeds locations. The associated key will be used to identify the location, and have category filter by location. --- modules/admin/cms_admin_module.e | 15 +++ .../admin/handler/cms_admin_cache_handler.e | 101 ++++++++++++++++++ modules/feed_aggregator/feed_aggregator_api.e | 30 ++++-- .../feed_aggregator/feed_aggregator_module.e | 16 +++ src/hooks/cms_hook_cache.e | 31 ++++++ src/hooks/cms_hook_core_manager.e | 24 ++++- 6 files changed, 207 insertions(+), 10 deletions(-) create mode 100644 modules/admin/handler/cms_admin_cache_handler.e create mode 100644 src/hooks/cms_hook_cache.e diff --git a/modules/admin/cms_admin_module.e b/modules/admin/cms_admin_module.e index 59311bb..3477c31 100644 --- a/modules/admin/cms_admin_module.e +++ b/modules/admin/cms_admin_module.e @@ -53,6 +53,8 @@ feature -- Access: router l_user_handler: CMS_USER_HANDLER l_role_handler: CMS_ROLE_HANDLER + l_admin_cache_handler: CMS_ADMIN_CACHE_HANDLER + l_uri_mapping: WSF_URI_MAPPING do create l_admin_handler.make (a_api) @@ -67,6 +69,10 @@ feature -- Access: router create l_uri_mapping.make_trailing_slash_ignored ("/admin/roles", l_roles_handler) a_router.map (l_uri_mapping, a_router.methods_get_post) + create l_admin_cache_handler.make (a_api) + create l_uri_mapping.make_trailing_slash_ignored ("/admin/cache", l_admin_cache_handler) + a_router.map (l_uri_mapping, a_router.methods_get_post) + create l_user_handler.make (a_api) a_router.handle ("/admin/add/user", l_user_handler, a_router.methods_get_post) a_router.handle ("/admin/user/{id}", l_user_handler, a_router.methods_get) @@ -78,6 +84,8 @@ feature -- Access: router a_router.handle ("/admin/role/{id}", l_role_handler, a_router.methods_get) a_router.handle ("/admin/role/{id}/edit", l_role_handler, a_router.methods_get_post) a_router.handle ("/admin/role/{id}/delete", l_role_handler, a_router.methods_get_post) + + end feature -- Security @@ -120,6 +128,13 @@ feature -- Hooks lnk.set_permission_arguments (<<"manage " + {CMS_ADMIN_MODULE}.name>>) a_menu_system.management_menu.extend (lnk) end + if + a_response.has_permission ("admin cache") -- Note: admin user has all permissions enabled by default. + then + create lnk.make ("Cache", "admin/cache") + lnk.set_permission_arguments (<<"admin cache">>) + a_menu_system.management_menu.extend (lnk) + end end note diff --git a/modules/admin/handler/cms_admin_cache_handler.e b/modules/admin/handler/cms_admin_cache_handler.e new file mode 100644 index 0000000..09aef60 --- /dev/null +++ b/modules/admin/handler/cms_admin_cache_handler.e @@ -0,0 +1,101 @@ +note + description: "[ + Administrate cache functionality. + ]" + date: "$Date$" + revision: "$Revision$" + +class + CMS_ADMIN_CACHE_HANDLER + +inherit + CMS_HANDLER + + WSF_URI_HANDLER + rename + new_mapping as new_uri_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get, + do_post + end + + REFACTORING_HELPER + +create + make + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + local + l_response: CMS_RESPONSE + s: STRING + f: CMS_FORM + do + create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api) + if l_response.has_permission ("admin cache") then + f := clear_cache_web_form (l_response) + create s.make_empty + f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s) + l_response.set_main_content (s) + else + create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api) + end + l_response.execute + end + + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) + local + l_response: CMS_RESPONSE + s: STRING + f: CMS_FORM + do + create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api) + if l_response.has_permission ("admin cache") then + f := clear_cache_web_form (l_response) + f.process (l_response) + if + attached f.last_data as fd and then + fd.is_valid + then + if attached fd.string_item ("op") as l_op and then l_op.same_string (text_clear_all_caches) then + l_response.hooks.invoke_clear_cache (Void, l_response) + l_response.add_notice_message ("Cache cleared!") + else + fd.report_error ("Invalid form data!") + end + end + create s.make_empty + f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s) + l_response.set_main_content (s) + else + create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api) + end + l_response.execute + end + +feature -- Widget + + clear_cache_web_form (a_response: CMS_RESPONSE): CMS_FORM + local + but: WSF_FORM_SUBMIT_INPUT + do + create Result.make (a_response.url (a_response.location, Void), "form_clear_cache") + create but.make_with_text ("op", text_clear_all_caches) + Result.extend (but) + end + +feature -- Interface text. + + text_clear_all_caches: STRING_32 = "Clear all caches" + +end diff --git a/modules/feed_aggregator/feed_aggregator_api.e b/modules/feed_aggregator/feed_aggregator_api.e index ea777da..a5166c4 100644 --- a/modules/feed_aggregator/feed_aggregator_api.e +++ b/modules/feed_aggregator/feed_aggregator_api.e @@ -20,7 +20,7 @@ feature -- Access agg: FEED_AGGREGATION l_feed_id: READABLE_STRING_32 l_title: detachable READABLE_STRING_GENERAL - l_location_list: detachable LIST [READABLE_STRING_32] + l_locations: detachable STRING_TABLE [READABLE_STRING_8] utf: UTF_CONVERTER l_table: like internal_aggregations do @@ -36,16 +36,28 @@ feature -- Access l_ids as ic loop l_feed_id := ic.item - l_location_list := cfg.text_list_item ({STRING_32} "feeds." + l_feed_id + ".locations") + create l_locations.make (1) + + if attached cfg.text_list_item ({STRING_32} "feeds." + l_feed_id + ".locations") as l_location_list then + across + l_location_list as loc_ic + loop + l_locations.force (utf.utf_32_string_to_utf_8_string_8 (loc_ic.item), loc_ic.item) + end + end + if attached cfg.text_table_item ({STRING_32} "feeds." + l_feed_id + ".locations") as l_location_table then + across + l_location_table as loc_tb_ic + loop + l_locations.force (utf.utf_32_string_to_utf_8_string_8 (loc_tb_ic.item), loc_tb_ic.key) + end + end if attached cfg.text_item ({STRING_32} "feeds." + l_feed_id + ".location") as l_location then - if l_location_list = Void then - create {ARRAYED_LIST [READABLE_STRING_32]} l_location_list.make (1) - end - l_location_list.force (l_location) + l_locations.force (utf.utf_32_string_to_utf_8_string_8 (l_location), l_location) end - if l_location_list /= Void and then not l_location_list.is_empty then + if l_locations /= Void and then not l_locations.is_empty then l_title := cfg.text_item ({STRING_32} "feeds." + l_feed_id + ".title") if l_title = Void then l_title := l_feed_id @@ -62,10 +74,10 @@ feature -- Access end end if attached cfg.text_item ({STRING_32} "feeds." + l_feed_id + ".option_description") as l_description_opt then - agg.set_description_enabled (not l_description_opt.is_case_insensitive_equal_general ("disabled")) + agg.set_description_enabled (not l_description_opt.is_case_insensitive_equal_general ("disabled")) end across - l_location_list as loc_ic + l_locations as loc_ic loop agg.locations.force (utf.utf_32_string_to_utf_8_string_8 (loc_ic.item)) end diff --git a/modules/feed_aggregator/feed_aggregator_module.e b/modules/feed_aggregator/feed_aggregator_module.e index 2c22012..4b0441f 100644 --- a/modules/feed_aggregator/feed_aggregator_module.e +++ b/modules/feed_aggregator/feed_aggregator_module.e @@ -23,6 +23,8 @@ inherit CMS_HOOK_MENU_SYSTEM_ALTER + CMS_HOOK_CACHE + create make @@ -181,10 +183,24 @@ feature -- Hooks configuration a_response.hooks.subscribe_to_block_hook (Current) a_response.hooks.subscribe_to_response_alter_hook (Current) a_response.hooks.subscribe_to_menu_system_alter_hook (Current) + a_response.hooks.subscribe_to_cache_hook (Current) end feature -- Hook + clear_cache (a_cache_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]; a_response: CMS_RESPONSE) + -- . + local + p: PATH + dir: DIRECTORY + do + p := a_response.api.files_location.extended (".cache").extended (name) + create dir.make_with_path (p) + if dir.exists then + dir.recursive_delete + end + end + block_list: ITERABLE [like {CMS_BLOCK}.name] -- List of block names, managed by current object. local diff --git a/src/hooks/cms_hook_cache.e b/src/hooks/cms_hook_cache.e new file mode 100644 index 0000000..0bd775b --- /dev/null +++ b/src/hooks/cms_hook_cache.e @@ -0,0 +1,31 @@ +note + description: "[ + Hook providing cache related management facilities. + ]" + date: "$Date: 2014-11-19 20:00:19 +0100 (mer., 19 nov. 2014) $" + revision: "$Revision: 96123 $" + +deferred class + CMS_HOOK_CACHE + +inherit + CMS_HOOK + +feature -- Hook + + clear_cache (a_cache_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]; a_response: CMS_RESPONSE) + -- Clear caches identified by `a_cache_id_list', + -- or clear all caches if `a_cache_id_list' is Void. + deferred + end + + cache_identifiers: detachable ITERABLE [like {CMS_BLOCK}.name] + -- Optional list of cache id, if any. + do + -- To redefine if needed. + end + +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/src/hooks/cms_hook_core_manager.e b/src/hooks/cms_hook_core_manager.e index 18f9f03..15f7608 100644 --- a/src/hooks/cms_hook_core_manager.e +++ b/src/hooks/cms_hook_core_manager.e @@ -104,7 +104,6 @@ feature -- Hook: menu_alter end end - feature -- Hook: form_alter subscribe_to_form_alter_hook (h: CMS_HOOK_FORM_ALTER) @@ -177,6 +176,29 @@ feature -- Hook: block end end +feature -- Hook: cache + + subscribe_to_cache_hook (h: CMS_HOOK_CACHE) + -- Add `h' as subscriber of cache hooks CMS_HOOK_CACHE, + -- and response `a_response'. + do + subscribe_to_hook (h, {CMS_HOOK_CACHE}) + end + + invoke_clear_cache (a_cache_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]; a_response: CMS_RESPONSE) + -- Invoke cache hook for identifiers `a_cache_id_list'. + do + if attached subscribers ({CMS_HOOK_CACHE}) as lst then + across + lst as c + loop + if attached {CMS_HOOK_CACHE} c.item as h then + h.clear_cache (a_cache_id_list, a_response) + end + end + end + end + note copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"