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)"