diff --git a/examples/demo/demo-safe.ecf b/examples/demo/demo-safe.ecf index 5cd5d17..1c12f20 100644 --- a/examples/demo/demo-safe.ecf +++ b/examples/demo/demo-safe.ecf @@ -24,6 +24,7 @@ + -
+
{unless isempty="$page.region_highlighted"}
{$page.region_highlighted/}
diff --git a/examples/demo/site/themes/bootstrap/theme.info b/examples/demo/site/themes/bootstrap/theme.info index b084985..6c96570 100644 --- a/examples/demo/site/themes/bootstrap/theme.info +++ b/examples/demo/site/themes/bootstrap/theme.info @@ -8,7 +8,7 @@ regions[content] = Content regions[highlighted] = Highlighted regions[help] = Help regions[footer] = Footer -regions[first_sidebar] = first sidebar -regions[second_sidebar] = second sidebar +regions[sidebar_first] = first sidebar +regions[sidebar_second] = second sidebar regions[page_bottom] = Bottom -navigation=default_nav \ No newline at end of file +navigation=default_nav diff --git a/examples/demo/src/ewf_roc_server_execution.e b/examples/demo/src/ewf_roc_server_execution.e index f2a45de..40c16c4 100644 --- a/examples/demo/src/ewf_roc_server_execution.e +++ b/examples/demo/src/ewf_roc_server_execution.e @@ -78,6 +78,11 @@ feature -- CMS setup create {CMS_BLOG_MODULE} m.make a_setup.register_module (m) + -- Recent changes + create {CMS_RECENT_CHANGES_MODULE} m.make + a_setup.register_module (m) + + -- Miscellanious create {CMS_DEBUG_MODULE} m.make a_setup.register_module (m) diff --git a/modules/admin/cms_admin_module.e b/modules/admin/cms_admin_module.e index fc59d7d..174e305 100644 --- a/modules/admin/cms_admin_module.e +++ b/modules/admin/cms_admin_module.e @@ -97,8 +97,8 @@ feature -- Hooks register_hooks (a_response: CMS_RESPONSE) -- do - a_response.subscribe_to_menu_system_alter_hook (Current) - a_response.subscribe_to_response_alter_hook (Current) + a_response.hooks.subscribe_to_menu_system_alter_hook (Current) + a_response.hooks.subscribe_to_response_alter_hook (Current) end response_alter (a_response: CMS_RESPONSE) @@ -117,7 +117,7 @@ feature -- Hooks -- TODO: we should probably use more side menu and less primary_menu. create lnk.make ("Admin", "admin") lnk.set_permission_arguments (<<"manage " + {CMS_ADMIN_MODULE}.name>>) - a_menu_system.primary_menu.extend (lnk) + a_menu_system.management_menu.extend (lnk) end end diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index d27138d..2a32c2d 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -95,8 +95,8 @@ feature -- Hooks configuration -- Module hooks configuration. do auto_subscribe_to_hooks (a_response) - a_response.subscribe_to_block_hook (Current) - a_response.subscribe_to_value_table_alter_hook (Current) + a_response.hooks.subscribe_to_block_hook (Current) + a_response.hooks.subscribe_to_value_table_alter_hook (Current) end value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE) diff --git a/modules/basic_auth/cms_basic_auth_module.e b/modules/basic_auth/cms_basic_auth_module.e index f39e650..132ced8 100644 --- a/modules/basic_auth/cms_basic_auth_module.e +++ b/modules/basic_auth/cms_basic_auth_module.e @@ -105,8 +105,8 @@ feature -- Hooks configuration -- Module hooks configuration. do auto_subscribe_to_hooks (a_response) - a_response.subscribe_to_block_hook (Current) - a_response.subscribe_to_value_table_alter_hook (Current) + a_response.hooks.subscribe_to_block_hook (Current) + a_response.hooks.subscribe_to_value_table_alter_hook (Current) end feature -- Hooks diff --git a/modules/blog/cms_blog_module.e b/modules/blog/cms_blog_module.e index bca251e..5e6f13b 100644 --- a/modules/blog/cms_blog_module.e +++ b/modules/blog/cms_blog_module.e @@ -151,8 +151,8 @@ feature -- Hooks register_hooks (a_response: CMS_RESPONSE) do - a_response.subscribe_to_menu_system_alter_hook (Current) - a_response.subscribe_to_response_alter_hook (Current) + a_response.hooks.subscribe_to_menu_system_alter_hook (Current) + a_response.hooks.subscribe_to_response_alter_hook (Current) end response_alter (a_response: CMS_RESPONSE) diff --git a/modules/node/cms_node_api.e b/modules/node/cms_node_api.e index 3ee8c61..b575968 100644 --- a/modules/node/cms_node_api.e +++ b/modules/node/cms_node_api.e @@ -236,28 +236,43 @@ feature -- Access: Node end recent_nodes (params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_NODE] - -- List of the `a_rows' most recent nodes starting from `a_offset'. + -- List of most recent nodes according to `params.offset' and `params.size'. do Result := node_storage.recent_nodes (params.offset.to_integer_32, params.size.to_integer_32) end + recent_node_changes_before (params: CMS_DATA_QUERY_PARAMETERS; a_date: DATE_TIME): ITERABLE [CMS_NODE] + -- List of recent changes, before `a_date', according to `params' settings. + do + Result := node_storage.recent_node_changes_before (params.offset.to_integer_32, params.size.to_integer_32, a_date) + end + node (a_id: INTEGER_64): detachable CMS_NODE -- Node by ID. do debug ("refactor_fixme") fixme ("Check preconditions") end - Result := full_node (node_storage.node_by_id (a_id)) + Result := safe_full_node (node_storage.node_by_id (a_id)) end revision_node (a_node_id: INTEGER_64; a_revision_id: INTEGER_64): detachable CMS_NODE do - Result := full_node (node_storage.node_by_id_and_revision (a_node_id, a_revision_id)) + Result := safe_full_node (node_storage.node_by_id_and_revision (a_node_id, a_revision_id)) end - full_node (a_node: detachable CMS_NODE): detachable CMS_NODE + safe_full_node (a_node: detachable CMS_NODE): detachable CMS_NODE + do + if a_node /= Void then + Result := full_node (a_node) + end + end + + full_node (a_node: CMS_NODE): CMS_NODE -- If `a_node' is partial, return the full node from `a_node', -- otherwise return directly `a_node'. + require + a_node_set: a_node /= Void do if attached {CMS_PARTIAL_NODE} a_node as l_partial_node then if attached node_type_for (l_partial_node) as ct then diff --git a/modules/node/cms_node_module.e b/modules/node/cms_node_module.e index 0e0c3b8..07c8066 100644 --- a/modules/node/cms_node_module.e +++ b/modules/node/cms_node_module.e @@ -23,6 +23,8 @@ inherit CMS_HOOK_BLOCK + CMS_RECENT_CHANGES_HOOK + create make @@ -222,9 +224,12 @@ feature -- Hooks register_hooks (a_response: CMS_RESPONSE) -- do - a_response.subscribe_to_menu_system_alter_hook (Current) - a_response.subscribe_to_block_hook (Current) - a_response.subscribe_to_response_alter_hook (Current) + a_response.hooks.subscribe_to_menu_system_alter_hook (Current) + a_response.hooks.subscribe_to_block_hook (Current) + a_response.hooks.subscribe_to_response_alter_hook (Current) + + -- Module specific hook, if available. + a_response.hooks.subscribe_to_hook (Current, {CMS_RECENT_CHANGES_HOOK}) end response_alter (a_response: CMS_RESPONSE) @@ -253,13 +258,63 @@ feature -- Hooks do debug create lnk.make ("List of nodes", "nodes") - a_menu_system.primary_menu.extend (lnk) + a_menu_system.navigation_menu.extend (lnk) end create lnk.make ("Trash", "trash") - a_menu_system.primary_menu.extend (lnk) + a_menu_system.navigation_menu.extend (lnk) create lnk.make ("Create ..", "node") - a_menu_system.primary_menu.extend (lnk) + a_menu_system.navigation_menu.extend (lnk) + end + + populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_sources: LIST [READABLE_STRING_8]) + local + params: CMS_DATA_QUERY_PARAMETERS + ch: CMS_RECENT_CHANGE_ITEM + n: CMS_NODE + l_info: STRING_8 + l_src: detachable READABLE_STRING_8 + l_nodes: ITERABLE [CMS_NODE] + do + create params.make (0, a_changes.limit) + if attached node_api as l_node_api then + across + l_node_api.content_types as ic + loop + a_sources.force (ic.item.name) + end + l_src := a_changes.source + if attached a_changes.date as l_date then + l_nodes := l_node_api.recent_node_changes_before (params, l_date) + else + l_nodes := l_node_api.recent_node_changes_before (params, create {DATE_TIME}.make_now_utc) + end + across l_nodes as ic loop + n := ic.item + if l_src = Void or else l_src.is_case_insensitive_equal_general (n.content_type) then + n := l_node_api.full_node (n) + create ch.make (n.content_type, create {CMS_LOCAL_LINK}.make (n.title, "node/" + n.id.out), n.modification_date) + if n.creation_date ~ n.modification_date then + l_info := "new" + if not n.is_published then + l_info.append (" (unpublished)") + end + else + if n.is_trashed then + l_info := "trashed" + else + l_info := "updated" + if not n.is_published then + l_info.append (" (unpublished)") + end + end + end + ch.set_information (l_info) + ch.set_author (n.author) + a_changes.force (ch) + end + end + end end end diff --git a/modules/node/handler/cms_node_type_webform_manager.e b/modules/node/handler/cms_node_type_webform_manager.e index bfc6565..adab09b 100644 --- a/modules/node/handler/cms_node_type_webform_manager.e +++ b/modules/node/handler/cms_node_type_webform_manager.e @@ -300,6 +300,7 @@ feature -- Output end end create s.make_empty + s.append ("
") s.append ("
") if attached a_node.author as l_author then s.append (" by ") @@ -339,6 +340,7 @@ feature -- Output s.append ("

") end + s.append ("
") a_response.set_title (a_node.title) a_response.set_main_content (s) diff --git a/modules/node/handler/node_handler.e b/modules/node/handler/node_handler.e index 1805969..1262432 100644 --- a/modules/node/handler/node_handler.e +++ b/modules/node/handler/node_handler.e @@ -274,7 +274,6 @@ feature {NONE} -- Trash:Restore r: GENERIC_VIEW_CMS_RESPONSE b: STRING n: CMS_NODE - l_link: CMS_LOCAL_LINK do if attached {WSF_STRING} req.path_parameter ("id") as l_id then if diff --git a/modules/node/node-safe.ecf b/modules/node/node-safe.ecf index bd3c460..fccaeea 100644 --- a/modules/node/node-safe.ecf +++ b/modules/node/node-safe.ecf @@ -13,6 +13,7 @@ + diff --git a/modules/node/persistence/cms_node_storage_i.e b/modules/node/persistence/cms_node_storage_i.e index 5021203..48ead87 100644 --- a/modules/node/persistence/cms_node_storage_i.e +++ b/modules/node/persistence/cms_node_storage_i.e @@ -90,6 +90,11 @@ feature -- Access deferred end + recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE] + -- List of recent changes, before `a_date', according to `params' settings. + deferred + end + node_by_id (a_id: INTEGER_64): detachable CMS_NODE -- Retrieve node by id `a_id', if any. require diff --git a/modules/node/persistence/cms_node_storage_null.e b/modules/node/persistence/cms_node_storage_null.e index 25b6f51..695a23e 100644 --- a/modules/node/persistence/cms_node_storage_null.e +++ b/modules/node/persistence/cms_node_storage_null.e @@ -59,6 +59,12 @@ feature -- Access: node create {ARRAYED_LIST [CMS_NODE]} Result.make (0) end + recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE] + -- List of recent changes, before `a_date', according to `params' settings. + do + create {ARRAYED_LIST [CMS_NODE]} Result.make (0) + end + node_by_id (a_id: INTEGER_64): detachable CMS_NODE -- do diff --git a/modules/node/persistence/cms_node_storage_sql.e b/modules/node/persistence/cms_node_storage_sql.e index d9f6a28..adf1b75 100644 --- a/modules/node/persistence/cms_node_storage_sql.e +++ b/modules/node/persistence/cms_node_storage_sql.e @@ -128,7 +128,7 @@ feature -- Access from create l_parameters.make (2) - l_parameters.put (a_count, "rows") + l_parameters.put (a_count, "size") l_parameters.put (a_lower, "offset") sql_query (sql_select_recent_nodes, l_parameters) sql_start @@ -142,6 +142,34 @@ feature -- Access end end + recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE] + -- List of recent changes, before `a_date', according to `params' settings. + local + l_parameters: STRING_TABLE [detachable ANY] + do + create {ARRAYED_LIST [CMS_NODE]} Result.make (0) + + error_handler.reset + write_information_log (generator + ".nodes") + + from + create l_parameters.make (3) + l_parameters.put (a_count, "size") + l_parameters.put (a_lower, "offset") + l_parameters.put (a_date, "date") + + sql_query (sql_select_recent_node_changes_before, l_parameters) + sql_start + until + sql_after + loop + if attached fetch_node as l_node then + Result.force (l_node) + end + sql_forth + end + end + node_by_id (a_id: INTEGER_64): detachable CMS_NODE -- Retrieve node by id `a_id', if any. local @@ -402,7 +430,9 @@ feature {NONE} -- Queries sql_select_node_by_id_and_revision: STRING = "SELECT nodes.nid, node_revisions.revision, nodes.type, node_revisions.title, node_revisions.summary, node_revisions.content, node_revisions.format, node_revisions.author, nodes.publish, nodes.created, node_revisions.changed, node_revisions.status FROM nodes INNER JOIN node_revisions ON nodes.nid = node_revisions.nid WHERE nodes.nid = :nid AND node_revisions.revision = :revision ORDER BY node_revisions.revision DESC;" - sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes ORDER BY nid DESC, publish DESC LIMIT :rows OFFSET :offset ;" + sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes ORDER BY nid DESC, publish DESC LIMIT :size OFFSET :offset ;" + + sql_select_recent_node_changes_before: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes WHERE changed <= :date ORDER BY changed DESC, nid DESC LIMIT :size OFFSET :offset ;" sql_insert_node: STRING = "INSERT INTO nodes (revision, type, title, summary, content, format, publish, created, changed, status, author) VALUES (:revision, :type, :title, :summary, :content, :format, :publish, :created, :changed, :status, :author);" -- SQL Insert to add a new node. diff --git a/modules/oauth20/cms_oauth_20_module.e b/modules/oauth20/cms_oauth_20_module.e index 99ff73f..a68227f 100644 --- a/modules/oauth20/cms_oauth_20_module.e +++ b/modules/oauth20/cms_oauth_20_module.e @@ -192,8 +192,8 @@ feature -- Hooks configuration -- Module hooks configuration. do auto_subscribe_to_hooks (a_response) - a_response.subscribe_to_block_hook (Current) - a_response.subscribe_to_value_table_alter_hook (Current) + a_response.hooks.subscribe_to_block_hook (Current) + a_response.hooks.subscribe_to_value_table_alter_hook (Current) end feature -- Hooks diff --git a/modules/openid/cms_openid_module.e b/modules/openid/cms_openid_module.e index 70fa7c8..988085b 100644 --- a/modules/openid/cms_openid_module.e +++ b/modules/openid/cms_openid_module.e @@ -170,8 +170,8 @@ feature -- Hooks configuration -- Module hooks configuration. do auto_subscribe_to_hooks (a_response) - a_response.subscribe_to_block_hook (Current) - a_response.subscribe_to_value_table_alter_hook (Current) + a_response.hooks.subscribe_to_block_hook (Current) + a_response.hooks.subscribe_to_value_table_alter_hook (Current) end feature -- Hooks diff --git a/modules/recent_changes/cms_recent_change_container.e b/modules/recent_changes/cms_recent_change_container.e new file mode 100644 index 0000000..70c0cb9 --- /dev/null +++ b/modules/recent_changes/cms_recent_change_container.e @@ -0,0 +1,82 @@ +note + description: "Container of recent change items, and associated parameters." + date: "$Date$" + revision: "$Revision$" + +class + CMS_RECENT_CHANGE_CONTAINER + +inherit + ITERABLE [CMS_RECENT_CHANGE_ITEM] + +create + make + +feature -- Initialization + + make (a_limit: NATURAL_32; a_date: detachable DATE_TIME; a_source: detachable READABLE_STRING_8) + do + limit := a_limit + date := a_date + source := a_source + create items.make (a_limit.to_integer_32) + end + +feature -- Settings + + limit: NATURAL_32 + + date: detachable DATE_TIME + + source: detachable READABLE_STRING_8 + +feature -- Access + + items: ARRAYED_LIST [CMS_RECENT_CHANGE_ITEM] + -- List of recent events. + + count: INTEGER + -- Number of change items. + do + Result := items.count + end + +feature -- Access + + new_cursor: ITERATION_CURSOR [CMS_RECENT_CHANGE_ITEM] + -- + do + Result := items.new_cursor + end + +feature -- Change + + force (a_item: CMS_RECENT_CHANGE_ITEM) + -- Add `a_item'. + do + items.force (a_item) + end + +feature -- Sorting + + sort + -- Sort `items' from older, to newer. + do + change_item_sorter.sort (items) + end + + reverse_sort + -- Sort `items' from newer to older. + do + change_item_sorter.reverse_sort (items) + end + +feature {NONE} -- Implementation + + change_item_sorter: QUICK_SORTER [CMS_RECENT_CHANGE_ITEM] + -- New change item sorter. + once + create Result.make (create {COMPARABLE_COMPARATOR [CMS_RECENT_CHANGE_ITEM]}) + end + +end diff --git a/modules/recent_changes/cms_recent_change_item.e b/modules/recent_changes/cms_recent_change_item.e new file mode 100644 index 0000000..8b65e89 --- /dev/null +++ b/modules/recent_changes/cms_recent_change_item.e @@ -0,0 +1,64 @@ +note + description: "Information related to change event." + date: "$Date$" + revision: "$Revision$" + +class + CMS_RECENT_CHANGE_ITEM + +inherit + COMPARABLE + +create + make + +feature {NONE} -- Initialization + + make (a_source: READABLE_STRING_8; lnk: CMS_LOCAL_LINK; a_date_time: DATE_TIME) + do + source := a_source + link := lnk + date := a_date_time + end + +feature -- Access + + link: CMS_LOCAL_LINK + -- Local link associated with the resource. + + date: DATE_TIME + -- Time of the event item. + + author: detachable CMS_USER + -- Optional author. + + source: READABLE_STRING_8 + -- Source of Current event. + + information: detachable READABLE_STRING_8 + -- Optional information related to Current event. + --| For instance: creation, trashed, modified, ... + +feature -- Element change + + set_author (u: like author) + -- Set `author' to `u'. + do + author := u + end + + set_information (a_info: like information) + -- Set `information' to `a_info'. + do + information := a_info + end + +feature -- Comparison + + is_less alias "<" (other: like Current): BOOLEAN + -- + do + Result := date < other.date + end + +end diff --git a/modules/recent_changes/cms_recent_changes_hook.e b/modules/recent_changes/cms_recent_changes_hook.e new file mode 100644 index 0000000..a44cbe5 --- /dev/null +++ b/modules/recent_changes/cms_recent_changes_hook.e @@ -0,0 +1,20 @@ +note + description: "Hook provided by module {CMS_RECENT_CHANGES_MODULE}." + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_RECENT_CHANGES_HOOK + +inherit + CMS_HOOK + +feature -- Invocation + + populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_sources: LIST [READABLE_STRING_8]) + -- Populate recent changes inside `a_changes' according to associated parameters. + -- Also provide sources of information. + deferred + end + +end diff --git a/modules/recent_changes/cms_recent_changes_module.e b/modules/recent_changes/cms_recent_changes_module.e new file mode 100644 index 0000000..833b9ac --- /dev/null +++ b/modules/recent_changes/cms_recent_changes_module.e @@ -0,0 +1,234 @@ +note + description: "CMS module that bring support for recent changes." + date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $" + revision: "$Revision: 96616 $" + +class + CMS_RECENT_CHANGES_MODULE + +inherit + CMS_MODULE + rename + module_api as recent_changes_api + redefine + register_hooks + end + + CMS_HOOK_MENU_SYSTEM_ALTER + + CMS_HOOK_RESPONSE_ALTER + +create + make + +feature {NONE} -- Initialization + + make + -- Create Current module, disabled by default. + do + version := "1.0" + description := "Service to access recent changes" + package := "notification" + end + +feature -- Access + + name: STRING = "recent_changes" + +feature -- Access: router + + setup_router (a_router: WSF_ROUTER; a_api: CMS_API) + -- + do + a_router.handle ("/recent_changes/", create {WSF_URI_AGENT_HANDLER}.make (agent handle_recent_changes (a_api, ?, ?)), a_router.methods_head_get) + end + +feature -- Handler + + handle_recent_changes (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) + local + r: CMS_RESPONSE + l_changes: CMS_RECENT_CHANGE_CONTAINER + l_sources: ARRAYED_LIST [READABLE_STRING_8] + dt, prev_dt: detachable DATE + ch: detachable CMS_RECENT_CHANGE_ITEM + htdate: HTTP_DATE + l_content: STRING + l_form: CMS_FORM + l_select: WSF_FORM_SELECT + l_until_date: detachable DATE_TIME + l_filter_source: detachable READABLE_STRING_8 + l_size: NATURAL_32 + l_query: STRING + opt: WSF_FORM_SELECT_OPTION + do + if attached {WSF_STRING} req.query_parameter ("date") as p_until_date then + create htdate.make_from_timestamp (p_until_date.value.to_integer_64) + l_until_date := htdate.date_time +-- l_until_date.second_add (-1) + end + if attached {WSF_STRING} req.query_parameter ("filter") as p_filter then + l_filter_source := p_filter.url_encoded_value + end + if attached {WSF_STRING} req.query_parameter ("size") as p_size then + l_size := p_size.integer_value.to_natural_32 + end + if l_size = 0 then + l_size := 25 + end + + create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) + create l_changes.make (l_size, l_until_date, l_filter_source) + + create l_content.make (1024) + if attached r.hooks.subscribers ({CMS_RECENT_CHANGES_HOOK}) as lst then + create l_sources.make (lst.count) + across + lst as ic + loop + if attached {CMS_RECENT_CHANGES_HOOK} ic.item as h then + h.populate_recent_changes (l_changes, l_sources) + end + end + create l_form.make (req.percent_encoded_path_info, "recent-changes") + create l_select.make ("source") + l_select.set_label ("Sources") + create opt.make ("", "...") + l_select.add_option (opt) + across + l_sources as ic + loop + create opt.make (ic.item, ic.item) + if l_filter_source /= Void and then ic.item.is_case_insensitive_equal (l_filter_source) then + opt.set_is_selected (True) + end + l_select.add_option (opt) + end + l_form.extend (l_select) + l_form.extend_html_text ("
") + l_form.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), l_content) + end + + l_changes.reverse_sort + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + + across + l_changes as ic + loop + ch := ic.item + dt := ch.date.date + if dt /~ prev_dt then + l_content.append ("") + l_content.append ("") + l_content.append ("") + end + prev_dt := dt + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("") + l_content.append ("%N") + end + l_content.append ("") + l_content.append ("
DateSourceResourceUserInformation
") + l_content.append (dt.formatted_out ("ddd, dd mmm yyyy")) + l_content.append ("
") + create htdate.make_from_date_time (ch.date) + htdate.append_to_rfc1123_string (l_content) + l_content.append ("" + ch.source + "") + l_content.append (r.link (ch.link.title, ch.link.location, Void)) + l_content.append ("") + if attached ch.author as u then + l_content.append (r.link (u.name, "user/" + u.id.out, Void)) + end + l_content.append ("") + if attached ch.information as l_info then + l_content.append ("" + l_info + " ") + end + l_content.append ("
%N") + + if ch /= Void then + if l_until_date /= Void then + l_content.append (" << ") + end + + if l_until_date /~ ch.date then + create htdate.make_from_date_time (ch.date) + create l_query.make_from_string ("size=" + l_size.out) + l_query.append ("&date=") + l_query.append (htdate.timestamp.out) + if l_filter_source /= Void then + l_query.append ("&filter=") + l_query.append (l_filter_source) + end + l_content.append (">))) + l_content.append ("%">More ...") + end + end + + r.set_main_content (l_content) + if l_until_date = Void then + r.set_title ("Recent changes") + else + create htdate.make_from_date_time (l_until_date) + r.set_title ("Recent changes before " + htdate.string) + end + + r.execute + end + +feature -- Hooks configuration + + register_hooks (a_response: CMS_RESPONSE) + -- Module hooks configuration. + do + a_response.hooks.subscribe_to_menu_system_alter_hook (Current) + a_response.hooks.subscribe_to_response_alter_hook (Current) + end + +feature -- Hook + + response_alter (a_response: CMS_RESPONSE) + do + a_response.add_additional_head_line ("[ + + ]", True) + end + + menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) + -- Hook execution on collection of menu contained by `a_menu_system' + -- for related response `a_response'. + local + lnk: CMS_LOCAL_LINK + do + create lnk.make ("Recent changes", "recent_changes/") + lnk.set_permission_arguments (<<"view recent changes">>) + a_menu_system.navigation_menu.extend (lnk) + end + +-- populate_recent_changes (lst: LIST [CMS_RECENT_CHANGE_ITEM]; a_date: detachable DATE_TIME; a_limit: INTEGER) +-- do +-- end + + +end diff --git a/modules/recent_changes/recent_changes-safe.ecf b/modules/recent_changes/recent_changes-safe.ecf new file mode 100644 index 0000000..a2f8acd --- /dev/null +++ b/modules/recent_changes/recent_changes-safe.ecf @@ -0,0 +1,25 @@ + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + + + + + + + + + + + + diff --git a/src/hooks/cms_hook.e b/src/hooks/cms_hook.e index 5a73009..7a4afb6 100644 --- a/src/hooks/cms_hook.e +++ b/src/hooks/cms_hook.e @@ -8,4 +8,7 @@ note deferred class CMS_HOOK +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_auto_register.e b/src/hooks/cms_hook_auto_register.e index 4f359ee..9ce4852 100644 --- a/src/hooks/cms_hook_auto_register.e +++ b/src/hooks/cms_hook_auto_register.e @@ -17,24 +17,27 @@ inherit feature -- Hook auto_subscribe_to_hooks (a_response: CMS_RESPONSE) + local + l_manager: CMS_HOOK_CORE_MANAGER do + l_manager := a_response.hooks if attached {CMS_HOOK_MENU_SYSTEM_ALTER} Current as h_menu_system_alter then - a_response.subscribe_to_menu_system_alter_hook (h_menu_system_alter) + l_manager.subscribe_to_menu_system_alter_hook (h_menu_system_alter) end if attached {CMS_HOOK_MENU_ALTER} Current as h_menu_alter then - a_response.subscribe_to_menu_alter_hook (h_menu_alter) + l_manager.subscribe_to_menu_alter_hook (h_menu_alter) end if attached {CMS_HOOK_BLOCK} Current as h_block then - a_response.subscribe_to_block_hook (h_block) + l_manager.subscribe_to_block_hook (h_block) end if attached {CMS_HOOK_FORM_ALTER} Current as h_form then - a_response.subscribe_to_form_alter_hook (h_form) + l_manager.subscribe_to_form_alter_hook (h_form) end if attached {CMS_HOOK_VALUE_TABLE_ALTER} Current as h_value then - a_response.subscribe_to_value_table_alter_hook (h_value) + l_manager.subscribe_to_value_table_alter_hook (h_value) end if attached {CMS_HOOK_RESPONSE_ALTER} Current as h_resp then - a_response.subscribe_to_response_alter_hook (h_resp) + l_manager.subscribe_to_response_alter_hook (h_resp) end end diff --git a/src/hooks/cms_hook_core_manager.e b/src/hooks/cms_hook_core_manager.e new file mode 100644 index 0000000..285d782 --- /dev/null +++ b/src/hooks/cms_hook_core_manager.e @@ -0,0 +1,160 @@ +note + description: "[ + Hook manager specific for Core hooks. + - Value Table Alter + - + ]" + date: "$Date$" + revision: "$Revision$" + +class + CMS_HOOK_CORE_MANAGER + +inherit + CMS_HOOK_MANAGER + +create + make + +feature -- Hook: value alter + + subscribe_to_value_table_alter_hook (h: CMS_HOOK_VALUE_TABLE_ALTER) + -- Add `h' as subscriber of value table alter hooks CMS_HOOK_VALUE_TABLE_ALTER. + do + subscribe_to_hook (h, {CMS_HOOK_VALUE_TABLE_ALTER}) + end + + invoke_value_table_alter (a_table: CMS_VALUE_TABLE; a_response: CMS_RESPONSE) + -- Invoke value table alter hook for table `a_table'. + do + if attached subscribers ({CMS_HOOK_VALUE_TABLE_ALTER}) as lst then + across + lst as ic + loop + if attached {CMS_HOOK_VALUE_TABLE_ALTER} ic.item as h then + h.value_table_alter (a_table, a_response) + end + end + end + end + +feature -- Hook: response + + subscribe_to_response_alter_hook (h: CMS_HOOK_RESPONSE_ALTER) + -- Add `h' as subscriber of response alter hooks CMS_HOOK_RESPONSE_ALTER. + do + subscribe_to_hook (h, {CMS_HOOK_RESPONSE_ALTER}) + end + + invoke_response_alter (a_response: CMS_RESPONSE) + -- Invoke response alter hook for response `a_response'. + do + if attached subscribers ({CMS_HOOK_RESPONSE_ALTER}) as lst then + across + lst as ic + loop + if attached {CMS_HOOK_RESPONSE_ALTER} ic.item as h then + h.response_alter (a_response) + end + end + end + end + +feature -- Hook: menu_system_alter + + subscribe_to_menu_system_alter_hook (h: CMS_HOOK_MENU_SYSTEM_ALTER) + -- Add `h' as subscriber of menu system alter hooks CMS_HOOK_MENU_SYSTEM_ALTER. + do + subscribe_to_hook (h, {CMS_HOOK_MENU_SYSTEM_ALTER}) + end + + invoke_menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) + -- Invoke menu system alter hook for menu `a_menu_system', and response `a_response'. + do + if attached subscribers ({CMS_HOOK_MENU_SYSTEM_ALTER}) as lst then + across + lst as ic + loop + if attached {CMS_HOOK_MENU_SYSTEM_ALTER} ic.item as h then + h.menu_system_alter (a_menu_system, a_response) + end + end + end + end + +feature -- Hook: menu_alter + + subscribe_to_menu_alter_hook (h: CMS_HOOK_MENU_ALTER) + -- Add `h' as subscriber of menu alter hooks CMS_HOOK_MENU_ALTER. + do + subscribe_to_hook (h, {CMS_HOOK_MENU_ALTER}) + end + + invoke_menu_alter (a_menu: CMS_MENU; a_response: CMS_RESPONSE) + -- Invoke menu alter hook for menu `a_menu', and response `a_response'. + do + if attached subscribers ({CMS_HOOK_MENU_ALTER}) as lst then + across + lst as c + loop + if attached {CMS_HOOK_MENU_ALTER} c.item as h then + h.menu_alter (a_menu, a_response) + end + end + end + end + + +feature -- Hook: form_alter + + subscribe_to_form_alter_hook (h: CMS_HOOK_FORM_ALTER) + -- Add `h' as subscriber of form alter hooks CMS_HOOK_FORM_ALTER, + -- and response `a_response'. + do + subscribe_to_hook (h, {CMS_HOOK_MENU_ALTER}) + end + + invoke_form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; a_response: CMS_RESPONSE) + -- Invoke form alter hook for form `a_form' and associated data `a_form_data' + do + if attached subscribers ({CMS_HOOK_FORM_ALTER}) as lst then + across + lst as c + loop + if attached {CMS_HOOK_FORM_ALTER} c.item as h then + h.form_alter (a_form, a_form_data, a_response) + end + end + end + end + +feature -- Hook: block + + subscribe_to_block_hook (h: CMS_HOOK_BLOCK) + -- Add `h' as subscriber of hooks CMS_HOOK_BLOCK. + do + subscribe_to_hook (h, {CMS_HOOK_BLOCK}) + end + + invoke_block (a_response: CMS_RESPONSE) + -- Invoke block hook for response `a_response' in order to get block from modules. + do + if attached subscribers ({CMS_HOOK_BLOCK}) as lst then + across + lst as c + loop + if attached {CMS_HOOK_BLOCK} c.item as h then + across + h.block_list as blst + loop + h.get_block_view (blst.item, a_response) + end + 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)" +end diff --git a/src/hooks/cms_hook_manager.e b/src/hooks/cms_hook_manager.e new file mode 100644 index 0000000..038136e --- /dev/null +++ b/src/hooks/cms_hook_manager.e @@ -0,0 +1,55 @@ +note + description: "Hooks manager." + date: "$Date$" + revision: "$Revision$" + +class + CMS_HOOK_MANAGER + +create + make + +feature {NONE} -- Initialization + + make + do + create all_subscribers.make (0) + end + +feature -- Access + + subscribers (a_type: TYPE [CMS_HOOK]): detachable LIST [CMS_HOOK] + -- Subscribers of hook typed `a_type'. + do + Result := all_subscribers.item (a_type) + end + +feature -- Change + + subscribe_to_hook (h: CMS_HOOK; a_hook_type: TYPE [CMS_HOOK]) + -- Subscribe `h' to hooks identified by `a_hook_type'. + local + lst: detachable LIST [CMS_HOOK] + do + lst := all_subscribers.item (a_hook_type) + if lst = Void then + create {ARRAYED_LIST [CMS_HOOK]} lst.make (1) + all_subscribers.force (lst, a_hook_type) + end + if not lst.has (h) then + lst.force (h) + end + end + +feature {NONE} -- Implementation + + all_subscribers: HASH_TABLE [LIST [CMS_HOOK], TYPE [CMS_HOOK]] + +invariant + all_subscribers /= Void + +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/kernel/form/cms_form.e b/src/kernel/form/cms_form.e index 1799394..46063d2 100644 --- a/src/kernel/form/cms_form.e +++ b/src/kernel/form/cms_form.e @@ -39,4 +39,7 @@ feature -- Basic operation 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)" end diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 4b240e3..98a2033 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -33,7 +33,7 @@ feature {NONE} -- Initialization get_theme create menu_system.make initialize_block_region_settings - create hook_subscribers.make (0) + create hooks.make register_hooks end @@ -409,9 +409,9 @@ feature -- Blocks initialization l_table["help"] := "help" l_table["content"] := "content" l_table["footer"] := "footer" - l_table["management"] := "first_sidebar" - l_table["navigation"] := "first_sidebar" - l_table["user"] := "first_sidebar" + l_table["management"] := "sidebar_first" + l_table["navigation"] := "sidebar_first" + l_table["user"] := "sidebar_first" l_table["bottom"] := "page_bottom" block_region_settings := l_table end @@ -474,13 +474,13 @@ feature -- Blocks add_block (content_block, "content") if attached management_menu_block as l_block then - add_block (l_block, "first_sidebar") + add_block (l_block, "sidebar_first") end if attached navigation_menu_block as l_block then - add_block (l_block, "first_sidebar") + add_block (l_block, "sidebar_first") end if attached user_menu_block as l_block then - add_block (l_block, "first_sidebar") + add_block (l_block, "sidebar_second") end invoke_block @@ -596,132 +596,77 @@ feature -- Blocks feature -- Hooks - hook_subscribers: HASH_TABLE [LIST [CMS_HOOK], TYPE [CMS_HOOK]] - -- Hook indexed by hook identifier. - - subscribe_to_hook (h: CMS_HOOK; a_hook_type: TYPE [CMS_HOOK]) - -- Subscribe `h' to hooks identified by `a_hook_type'. - local - lst: detachable LIST [CMS_HOOK] - do - lst := hook_subscribers.item (a_hook_type) - if lst = Void then - create {ARRAYED_LIST [CMS_HOOK]} lst.make (1) - hook_subscribers.force (lst, a_hook_type) - end - if not lst.has (h) then - lst.force (h) - end - end + hooks: CMS_HOOK_CORE_MANAGER + -- Manager handling hook subscriptions. feature -- Hook: value alter - subscribe_to_value_table_alter_hook (h: CMS_HOOK_VALUE_TABLE_ALTER) - -- Add `h' as subscriber of value table alter hooks CMS_HOOK_VALUE_TABLE_ALTER. - do - subscribe_to_hook (h, {CMS_HOOK_VALUE_TABLE_ALTER}) - end +-- subscribe_to_value_table_alter_hook (h: CMS_HOOK_VALUE_TABLE_ALTER) +-- -- Add `h' as subscriber of value table alter hooks CMS_HOOK_VALUE_TABLE_ALTER. +-- do +-- hooks.subscribe_to_value_table_alter_hook (h) +-- end invoke_value_table_alter (a_table: CMS_VALUE_TABLE) -- Invoke value table alter hook for table `a_table'. do - if attached hook_subscribers.item ({CMS_HOOK_VALUE_TABLE_ALTER}) as lst then - across - lst as c - loop - if attached {CMS_HOOK_VALUE_TABLE_ALTER} c.item as h then - h.value_table_alter (a_table, Current) - end - end - end + hooks.invoke_value_table_alter (a_table, Current) end feature -- Hook: response - subscribe_to_response_alter_hook (h: CMS_HOOK_RESPONSE_ALTER) - -- Add `h' as subscriber of response alter hooks CMS_HOOK_RESPONSE_ALTER. - do - subscribe_to_hook (h, {CMS_HOOK_RESPONSE_ALTER}) - end +-- subscribe_to_response_alter_hook (h: CMS_HOOK_RESPONSE_ALTER) +-- -- Add `h' as subscriber of response alter hooks CMS_HOOK_RESPONSE_ALTER. +-- do +-- hooks.subscribe_to_response_alter_hook (h) +-- end invoke_response_alter (a_response: CMS_RESPONSE) - -- Invoke value table alter hook for table `a_table'. + -- Invoke response alter hook for response `a_response'. do - if attached hook_subscribers.item ({CMS_HOOK_RESPONSE_ALTER}) as lst then - across - lst as c - loop - if attached {CMS_HOOK_RESPONSE_ALTER} c.item as h then - h.response_alter (a_response) - end - end - end + hooks.invoke_response_alter (a_response) end feature -- Hook: menu_system_alter - subscribe_to_menu_system_alter_hook (h: CMS_HOOK_MENU_SYSTEM_ALTER) - -- Add `h' as subscriber of menu system alter hooks CMS_HOOK_MENU_SYSTEM_ALTER. - do - subscribe_to_hook (h, {CMS_HOOK_MENU_SYSTEM_ALTER}) - end +-- subscribe_to_menu_system_alter_hook (h: CMS_HOOK_MENU_SYSTEM_ALTER) +-- -- Add `h' as subscriber of menu system alter hooks CMS_HOOK_MENU_SYSTEM_ALTER. +-- do +-- hooks.subscribe_to_menu_system_alter_hook (h) +-- end invoke_menu_system_alter (a_menu_system: CMS_MENU_SYSTEM) -- Invoke menu system alter hook for menu `a_menu_system'. do - if attached hook_subscribers.item ({CMS_HOOK_MENU_SYSTEM_ALTER}) as lst then - across - lst as c - loop - if attached {CMS_HOOK_MENU_SYSTEM_ALTER} c.item as h then - h.menu_system_alter (a_menu_system, Current) - end - end - end + hooks.invoke_menu_system_alter (menu_system, Current) end feature -- Hook: menu_alter - subscribe_to_menu_alter_hook (h: CMS_HOOK_MENU_ALTER) - -- Add `h' as subscriber of menu alter hooks CMS_HOOK_MENU_ALTER. - do - subscribe_to_hook (h, {CMS_HOOK_MENU_ALTER}) - end +-- subscribe_to_menu_alter_hook (h: CMS_HOOK_MENU_ALTER) +-- -- Add `h' as subscriber of menu alter hooks CMS_HOOK_MENU_ALTER. +-- do +-- hooks.subscribe_to_menu_alter_hook (h) +-- end invoke_menu_alter (a_menu: CMS_MENU) -- Invoke menu alter hook for menu `a_menu'. do - if attached hook_subscribers.item ({CMS_HOOK_MENU_ALTER}) as lst then - across - lst as c - loop - if attached {CMS_HOOK_MENU_ALTER} c.item as h then - h.menu_alter (a_menu, Current) - end - end - end + hooks.invoke_menu_alter (a_menu, Current) end feature -- Hook: form_alter - subscribe_to_form_alter_hook (h: CMS_HOOK_FORM_ALTER) - -- Add `h' as subscriber of form alter hooks CMS_HOOK_FORM_ALTER. - do - subscribe_to_hook (h, {CMS_HOOK_MENU_ALTER}) - end +-- subscribe_to_form_alter_hook (h: CMS_HOOK_FORM_ALTER) +-- -- Add `h' as subscriber of form alter hooks CMS_HOOK_FORM_ALTER. +-- do +-- hooks.subscribe_to_form_alter_hook (h) +-- end invoke_form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA) -- Invoke form alter hook for form `a_form' and associated data `a_form_data' do - if attached hook_subscribers.item ({CMS_HOOK_FORM_ALTER}) as lst then - across - lst as c - loop - if attached {CMS_HOOK_FORM_ALTER} c.item as h then - h.form_alter (a_form, a_form_data, Current) - end - end - end + hooks.invoke_form_alter (a_form, a_form_data, Current) end feature -- Hook: block @@ -729,25 +674,13 @@ feature -- Hook: block subscribe_to_block_hook (h: CMS_HOOK_BLOCK) -- Add `h' as subscriber of hooks CMS_HOOK_BLOCK. do - subscribe_to_hook (h, {CMS_HOOK_BLOCK}) + hooks.subscribe_to_hook (h, {CMS_HOOK_BLOCK}) end invoke_block -- Invoke block hook in order to get block from modules. do - if attached hook_subscribers.item ({CMS_HOOK_BLOCK}) as lst then - across - lst as c - loop - if attached {CMS_HOOK_BLOCK} c.item as h then - across - h.block_list as blst - loop - h.get_block_view (blst.item, Current) - end - end - end - end + hooks.invoke_block (Current) end feature -- Menu: change