Improved the recent changes modules:
- extracted from populate_recent_changes, the recent_changes_sources that enables to filter early. Added author_name to the CMS_RECENT_CHANGE_ITEM to support author which is not related to any CMS_USER. Implemented the simple filtering on source and add parameters size and date.
This commit is contained in:
@@ -280,7 +280,27 @@ feature -- Hooks
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_sources: LIST [READABLE_STRING_8])
|
recent_changes_sources: detachable LIST [READABLE_STRING_8]
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
lst: ARRAYED_LIST [READABLE_STRING_8]
|
||||||
|
do
|
||||||
|
if
|
||||||
|
attached node_api as l_node_api and then
|
||||||
|
attached l_node_api.content_types as l_types and then
|
||||||
|
not l_types.is_empty
|
||||||
|
then
|
||||||
|
create lst.make (l_types.count)
|
||||||
|
across
|
||||||
|
l_types as ic
|
||||||
|
loop
|
||||||
|
lst.force (ic.item.name)
|
||||||
|
end
|
||||||
|
Result := lst
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_current_user: detachable CMS_USER)
|
||||||
local
|
local
|
||||||
params: CMS_DATA_QUERY_PARAMETERS
|
params: CMS_DATA_QUERY_PARAMETERS
|
||||||
ch: CMS_RECENT_CHANGE_ITEM
|
ch: CMS_RECENT_CHANGE_ITEM
|
||||||
@@ -288,23 +308,20 @@ feature -- Hooks
|
|||||||
l_info: STRING_8
|
l_info: STRING_8
|
||||||
l_src: detachable READABLE_STRING_8
|
l_src: detachable READABLE_STRING_8
|
||||||
l_nodes: ITERABLE [CMS_NODE]
|
l_nodes: ITERABLE [CMS_NODE]
|
||||||
|
l_date: detachable DATE_TIME
|
||||||
do
|
do
|
||||||
create params.make (0, a_changes.limit)
|
create params.make (0, a_changes.limit)
|
||||||
if attached node_api as l_node_api then
|
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
|
l_src := a_changes.source
|
||||||
if attached a_changes.date as l_date then
|
l_date := a_changes.date
|
||||||
l_nodes := l_node_api.recent_node_changes_before (params, l_date)
|
if l_date = Void then
|
||||||
else
|
create l_date.make_now_utc
|
||||||
l_nodes := l_node_api.recent_node_changes_before (params, create {DATE_TIME}.make_now_utc)
|
|
||||||
end
|
end
|
||||||
|
l_nodes := l_node_api.recent_node_changes_before (params, l_date)
|
||||||
across l_nodes as ic loop
|
across l_nodes as ic loop
|
||||||
n := ic.item
|
n := ic.item
|
||||||
if l_src = Void or else l_src.is_case_insensitive_equal_general (n.content_type) then
|
if l_src = Void or else l_src.is_case_insensitive_equal_general (n.content_type) then
|
||||||
|
if l_node_api.has_permission_for_action_on_node ("view", n, a_current_user) then
|
||||||
n := l_node_api.full_node (n)
|
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)
|
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
|
if n.creation_date ~ n.modification_date then
|
||||||
@@ -325,6 +342,10 @@ feature -- Hooks
|
|||||||
ch.set_information (l_info)
|
ch.set_information (l_info)
|
||||||
ch.set_author (n.author)
|
ch.set_author (n.author)
|
||||||
a_changes.force (ch)
|
a_changes.force (ch)
|
||||||
|
else
|
||||||
|
-- Forbidden
|
||||||
|
-- FIXME: provide a visual indication!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
<library name="cms" location="..\..\cms.ecf"/>
|
<library name="cms" location="..\..\cms.ecf"/>
|
||||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||||
|
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes.ecf" readonly="false"/>
|
||||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
|
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ feature -- Access
|
|||||||
date: DATE_TIME
|
date: DATE_TIME
|
||||||
-- Time of the event item.
|
-- Time of the event item.
|
||||||
|
|
||||||
|
author_name: detachable READABLE_STRING_32
|
||||||
|
-- Optional author name.
|
||||||
|
-- It is possible to have author_name /= Void and author = Void.
|
||||||
|
|
||||||
author: detachable CMS_USER
|
author: detachable CMS_USER
|
||||||
-- Optional author.
|
-- Optional author.
|
||||||
|
|
||||||
@@ -41,10 +45,19 @@ feature -- Access
|
|||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
|
set_author_name (n: like author_name)
|
||||||
|
-- Set `author_name' to `n'.
|
||||||
|
do
|
||||||
|
author_name := n
|
||||||
|
end
|
||||||
|
|
||||||
set_author (u: like author)
|
set_author (u: like author)
|
||||||
-- Set `author' to `u'.
|
-- Set `author' to `u'.
|
||||||
do
|
do
|
||||||
author := u
|
author := u
|
||||||
|
if u /= Void and author_name = Void then
|
||||||
|
set_author_name (u.name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
set_information (a_info: like information)
|
set_information (a_info: like information)
|
||||||
|
|||||||
@@ -11,9 +11,13 @@ inherit
|
|||||||
|
|
||||||
feature -- Invocation
|
feature -- Invocation
|
||||||
|
|
||||||
populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_sources: LIST [READABLE_STRING_8])
|
recent_changes_sources: detachable LIST [READABLE_STRING_8]
|
||||||
|
-- Source provided by Current hook.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_current_user: detachable CMS_USER)
|
||||||
-- Populate recent changes inside `a_changes' according to associated parameters.
|
-- Populate recent changes inside `a_changes' according to associated parameters.
|
||||||
-- Also provide sources of information.
|
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -58,25 +58,33 @@ feature -- Handler
|
|||||||
r: CMS_RESPONSE
|
r: CMS_RESPONSE
|
||||||
l_changes: CMS_RECENT_CHANGE_CONTAINER
|
l_changes: CMS_RECENT_CHANGE_CONTAINER
|
||||||
l_sources: ARRAYED_LIST [READABLE_STRING_8]
|
l_sources: ARRAYED_LIST [READABLE_STRING_8]
|
||||||
dt, prev_dt: detachable DATE
|
dt, prev_dt: detachable DATE_TIME
|
||||||
|
prev_info: detachable READABLE_STRING_8
|
||||||
ch: detachable CMS_RECENT_CHANGE_ITEM
|
ch: detachable CMS_RECENT_CHANGE_ITEM
|
||||||
htdate: HTTP_DATE
|
htdate: HTTP_DATE
|
||||||
l_content: STRING
|
l_content: STRING
|
||||||
l_form: CMS_FORM
|
l_form: CMS_FORM
|
||||||
l_select: WSF_FORM_SELECT
|
l_select: WSF_FORM_SELECT
|
||||||
|
l_size_field: WSF_FORM_NUMBER_INPUT
|
||||||
|
l_submit: WSF_FORM_SUBMIT_INPUT
|
||||||
l_until_date: detachable DATE_TIME
|
l_until_date: detachable DATE_TIME
|
||||||
l_filter_source: detachable READABLE_STRING_8
|
l_filter_source: detachable READABLE_STRING_8
|
||||||
l_size: NATURAL_32
|
l_size: NATURAL_32
|
||||||
l_query: STRING
|
l_query: STRING
|
||||||
opt: WSF_FORM_SELECT_OPTION
|
opt: WSF_FORM_SELECT_OPTION
|
||||||
|
l_user: detachable CMS_USER
|
||||||
|
i: INTEGER
|
||||||
do
|
do
|
||||||
if attached {WSF_STRING} req.query_parameter ("date") as p_until_date then
|
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)
|
create htdate.make_from_timestamp (p_until_date.value.to_integer_64)
|
||||||
l_until_date := htdate.date_time
|
l_until_date := htdate.date_time
|
||||||
-- l_until_date.second_add (-1)
|
-- l_until_date.second_add (-1)
|
||||||
end
|
end
|
||||||
if attached {WSF_STRING} req.query_parameter ("filter") as p_filter then
|
if attached {WSF_STRING} req.query_parameter ("source") as p_filter then
|
||||||
l_filter_source := p_filter.url_encoded_value
|
l_filter_source := p_filter.url_encoded_value
|
||||||
|
if l_filter_source.is_empty then
|
||||||
|
l_filter_source := Void
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if attached {WSF_STRING} req.query_parameter ("size") as p_size then
|
if attached {WSF_STRING} req.query_parameter ("size") as p_size then
|
||||||
l_size := p_size.integer_value.to_natural_32
|
l_size := p_size.integer_value.to_natural_32
|
||||||
@@ -87,22 +95,33 @@ feature -- Handler
|
|||||||
|
|
||||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||||
if r.has_permission ("view recent changes") then
|
if r.has_permission ("view recent changes") then
|
||||||
|
l_user := r.user
|
||||||
create l_changes.make (l_size, l_until_date, l_filter_source)
|
create l_changes.make (l_size, l_until_date, l_filter_source)
|
||||||
|
|
||||||
create l_content.make (1024)
|
create l_content.make (1024)
|
||||||
if attached r.hooks.subscribers ({CMS_RECENT_CHANGES_HOOK}) as lst then
|
if attached r.hooks.subscribers ({CMS_RECENT_CHANGES_HOOK}) as lst then
|
||||||
create l_sources.make (lst.count)
|
create l_sources.make (lst.count)
|
||||||
|
|
||||||
across
|
across
|
||||||
lst as ic
|
lst as ic
|
||||||
loop
|
loop
|
||||||
if attached {CMS_RECENT_CHANGES_HOOK} ic.item as h then
|
if attached {CMS_RECENT_CHANGES_HOOK} ic.item as h then
|
||||||
h.populate_recent_changes (l_changes, l_sources)
|
if attached h.recent_changes_sources as h_sources then
|
||||||
|
l_sources.append (h_sources)
|
||||||
|
if
|
||||||
|
l_filter_source = Void
|
||||||
|
or else across h_sources as h_ic some h_ic.item.is_case_insensitive_equal (l_filter_source) end
|
||||||
|
then
|
||||||
|
h.populate_recent_changes (l_changes, l_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
create l_form.make (req.percent_encoded_path_info, "recent-changes")
|
create l_form.make (req.percent_encoded_path_info, "recent-changes")
|
||||||
|
l_form.set_method_get
|
||||||
create l_select.make ("source")
|
create l_select.make ("source")
|
||||||
l_select.set_label ("Sources")
|
l_select.set_label ("Sources")
|
||||||
create opt.make ("", "...")
|
create opt.make ("", "Any source")
|
||||||
l_select.add_option (opt)
|
l_select.add_option (opt)
|
||||||
across
|
across
|
||||||
l_sources as ic
|
l_sources as ic
|
||||||
@@ -114,12 +133,19 @@ feature -- Handler
|
|||||||
l_select.add_option (opt)
|
l_select.add_option (opt)
|
||||||
end
|
end
|
||||||
l_form.extend (l_select)
|
l_form.extend (l_select)
|
||||||
|
|
||||||
|
create l_size_field.make_with_text ("size", l_size.out)
|
||||||
|
l_size_field.set_size (25)
|
||||||
|
l_size_field.set_label ("Items per page")
|
||||||
|
l_form.extend (l_size_field)
|
||||||
|
create l_submit.make_with_text ("op", "Filter")
|
||||||
|
l_form.extend (l_submit)
|
||||||
l_form.extend_html_text ("<br/>")
|
l_form.extend_html_text ("<br/>")
|
||||||
l_form.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), l_content)
|
l_form.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), l_content)
|
||||||
end
|
end
|
||||||
|
|
||||||
l_changes.reverse_sort
|
l_changes.reverse_sort
|
||||||
l_content.append ("<table class=%"recent-changes%" style=%"border-spacing: 5px;%">")
|
l_content.append ("<table class=%"recent-changes%">")
|
||||||
l_content.append ("<thead>")
|
l_content.append ("<thead>")
|
||||||
l_content.append ("<tr>")
|
l_content.append ("<tr>")
|
||||||
l_content.append ("<th>Date</th>")
|
l_content.append ("<th>Date</th>")
|
||||||
@@ -135,20 +161,24 @@ feature -- Handler
|
|||||||
l_changes as ic
|
l_changes as ic
|
||||||
loop
|
loop
|
||||||
ch := ic.item
|
ch := ic.item
|
||||||
dt := ch.date.date
|
dt := ch.date
|
||||||
if dt /~ prev_dt then
|
if prev_dt = Void or else dt.date /~ prev_dt.date then
|
||||||
l_content.append ("<tr>")
|
l_content.append ("<tr>")
|
||||||
l_content.append ("<td class=%"title%" colspan=%"5%">")
|
l_content.append ("<td class=%"title%" colspan=%"5%">")
|
||||||
l_content.append (dt.formatted_out ("ddd, dd mmm yyyy"))
|
l_content.append (dt.date.formatted_out ("ddd, dd mmm yyyy"))
|
||||||
l_content.append ("</td>")
|
l_content.append ("</td>")
|
||||||
l_content.append ("</tr>")
|
l_content.append ("</tr>")
|
||||||
end
|
end
|
||||||
prev_dt := dt
|
|
||||||
l_content.append ("<tr>")
|
l_content.append ("<tr>")
|
||||||
l_content.append ("<td class=%"date%">")
|
l_content.append ("<td class=%"date%">")
|
||||||
create htdate.make_from_date_time (ch.date)
|
if dt /~ prev_dt then
|
||||||
|
create htdate.make_from_date_time (dt)
|
||||||
htdate.append_to_rfc1123_string (l_content)
|
htdate.append_to_rfc1123_string (l_content)
|
||||||
|
else
|
||||||
|
l_content.append ("<span class=%"same-value%">''</span>")
|
||||||
|
end
|
||||||
l_content.append ("</td>")
|
l_content.append ("</td>")
|
||||||
|
|
||||||
l_content.append ("<td class=%"source%">" + ch.source + "</td>")
|
l_content.append ("<td class=%"source%">" + ch.source + "</td>")
|
||||||
l_content.append ("<td class=%"resource%">")
|
l_content.append ("<td class=%"resource%">")
|
||||||
l_content.append (r.link (ch.link.title, ch.link.location, Void))
|
l_content.append (r.link (ch.link.title, ch.link.location, Void))
|
||||||
@@ -156,14 +186,32 @@ feature -- Handler
|
|||||||
l_content.append ("<td class=%"user%">")
|
l_content.append ("<td class=%"user%">")
|
||||||
if attached ch.author as u then
|
if attached ch.author as u then
|
||||||
l_content.append (r.link (u.name, "user/" + u.id.out, Void))
|
l_content.append (r.link (u.name, "user/" + u.id.out, Void))
|
||||||
|
elseif attached ch.author_name as un then
|
||||||
|
l_content.append (r.html_encoded (un))
|
||||||
end
|
end
|
||||||
l_content.append ("</td>")
|
l_content.append ("</td>")
|
||||||
l_content.append ("<td class=%"info%">")
|
l_content.append ("<td class=%"info%">")
|
||||||
if attached ch.information as l_info then
|
if attached ch.information as l_info and then not l_info.is_empty then
|
||||||
l_content.append ("<strong>" + l_info + "</strong> ")
|
if prev_dt ~ dt and prev_info ~ l_info then
|
||||||
|
l_content.append ("<span class=%"same-value%">''</span>")
|
||||||
|
else
|
||||||
|
i := l_info.index_of ('%N', 1)
|
||||||
|
if i > 0 and i < l_info.count then
|
||||||
|
l_content.append (l_info.substring (1, i - 1))
|
||||||
|
l_content.append ("<span class=%"tooltip%">")
|
||||||
|
l_content.append (l_info.substring (i, l_info.count))
|
||||||
|
l_content.append ("</span>")
|
||||||
|
else
|
||||||
|
l_content.append (l_info)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
prev_info := l_info
|
||||||
|
else
|
||||||
|
prev_info := Void
|
||||||
end
|
end
|
||||||
l_content.append ("</td>")
|
l_content.append ("</td>")
|
||||||
l_content.append ("</tr>%N")
|
l_content.append ("</tr>%N")
|
||||||
|
prev_dt := dt
|
||||||
end
|
end
|
||||||
l_content.append ("</tbody>")
|
l_content.append ("</tbody>")
|
||||||
l_content.append ("</table>%N")
|
l_content.append ("</table>%N")
|
||||||
|
|||||||
Reference in New Issue
Block a user