Merge branch 'master' into es_17_01

# Conflicts:
#	examples/demo/demo.ecf
#	modules/node/node-safe.ecf
This commit is contained in:
2017-03-01 08:51:23 +01:00
38 changed files with 1188 additions and 225 deletions

View File

@@ -153,6 +153,11 @@ feature -- Access: Node
Result := node_storage.nodes_count
end
nodes_of_type_count (a_content_type: CMS_CONTENT_TYPE): NATURAL_64
do
Result := node_storage.nodes_of_type_count (a_content_type)
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
@@ -179,6 +184,12 @@ feature -- Access: Node
Result := node_storage.recent_nodes (params.offset.to_integer_32, params.size.to_integer_32)
end
recent_nodes_of_type (a_content_type: CMS_CONTENT_TYPE; params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_NODE]
-- Most recent `a_content_type` nodes according to `params.offset' and `params.size'.
do
Result := node_storage.recent_nodes_of_type (a_content_type, 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
@@ -356,6 +367,85 @@ feature -- Change: Node
error_handler.append (node_storage.error_handler)
end
feature -- path_alias suggestion
path_alias_uri_suggestion (a_node: detachable CMS_NODE; a_content_type: CMS_CONTENT_TYPE): STRING
local
dt: DATE_TIME
uri: URI
do
create uri.make_from_string ("/")
uri.add_unencoded_path_segment (a_content_type.name)
if a_node /= Void then
dt := a_node.creation_date
else
create dt.make_now_utc
end
if attached cms_api.user as u and then not cms_api.user_api.is_admin_user (u) then
uri.add_unencoded_path_segment (cms_api.user_api.user_display_name (u))
end
uri.add_unencoded_path_segment (dt.year.out)
if dt.month <= 9 then
uri.add_unencoded_path_segment ("0" + dt.month.out)
else
uri.add_unencoded_path_segment (dt.month.out)
end
if a_node /= Void and then attached a_node.title as l_title then
uri.add_unencoded_path_segment (safe_path_alias_uri_segment_text (l_title))
else
uri.add_unencoded_path_segment ("")
end
Result := uri.string
end
safe_path_alias_uri_segment_text (s: READABLE_STRING_GENERAL): STRING_32
local
i,n: INTEGER
c, prev: CHARACTER_32
l_words: ITERABLE [READABLE_STRING_GENERAL]
w: STRING_32
do
l_words := << "a", "an", "as", "at", "before", "but", "by", "for", "from", "is", "in", "into", "like", "of", "off", "on", "onto", "per", "since", "than", "the", "this", "that", "to", "up", "via", "with" >>
from
i := 1
n := s.count
create Result.make (n)
create w.make_empty
until
i > n
loop
c := s[i].as_lower
if c.is_alpha_numeric then
w.append_character (c)
prev := c
else
if w.is_empty then
-- Ignore
else
if across l_words as ic some w.same_string_general (ic.item) end then
-- Ignore
w.wipe_out
else
if not Result.is_empty then
Result.append_character ('-')
end
Result.append (w)
w.wipe_out
end
end
end
i := i + 1
end
if not w.is_empty then
if not Result.is_empty then
Result.append_character ('-')
end
Result.append (w)
w.wipe_out
end
end
feature -- Node status
Not_published: INTEGER = 0

View File

@@ -150,13 +150,13 @@ feature -- Access
Result.force ("restore own " + l_type_name)
Result.force ("view unpublished " + l_type_name)
Result.force ("view revisions own " + l_type_name)
Result.force ("export " + l_type_name)
end
end
Result.force ("view trash")
Result.force ("view own trash")
end
end
@@ -195,6 +195,7 @@ feature -- Access: router
create l_nodes_handler.make (a_api, a_node_api)
create l_uri_mapping.make_trailing_slash_ignored ("/nodes", l_nodes_handler)
a_router.map (l_uri_mapping, a_router.methods_get)
a_router.handle ("/nodes/{type}", l_nodes_handler, a_router.methods_get)
-- Trash
create l_trash_handler.make (a_api, a_node_api)

View File

@@ -92,7 +92,15 @@ feature -- Status reports
do
Result := status = {CMS_NODE_API}.published
ensure
Result implies not is_trashed
Result implies not is_trashed and not is_not_published
end
is_not_published: BOOLEAN
-- Is Current not published?
do
Result := status = {CMS_NODE_API}.not_published
ensure
Result implies not is_published
end
is_trashed: BOOLEAN

View File

@@ -107,10 +107,14 @@ feature -- Forms ...
populate_form_with_path_alias (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
local
ti: WSF_FORM_TEXT_INPUT
thi: WSF_FORM_HIDDEN_INPUT
l_uri: detachable READABLE_STRING_8
l_iri: detachable READABLE_STRING_32
l_auto_path_alias: READABLE_STRING_8
do
-- Path alias
l_auto_path_alias := node_api.path_alias_uri_suggestion (a_node, content_type)
create ti.make ("path_alias")
ti.set_label ("Path")
ti.set_pattern ("^([A-Za-z0-9-_+ ]).+")
@@ -119,13 +123,19 @@ feature -- Forms ...
if a_node /= Void and then a_node.has_id then
if attached a_node.link as lnk then
l_uri := lnk.location
if l_uri.same_string (node_api.node_path (a_node)) then
l_uri := ""
end
else
l_iri := percent_encoder.percent_decoded_string (response.api.location_alias (response.node_api.node_path (a_node)))
l_uri := l_iri.to_string_8
end
ti.set_text_value (l_uri)
ti.set_description ("Optionally specify an alternative URL path by which this content can be accessed. For example, type 'about' when writing an about page. Use a relative path or the URL alias won't work.")
ti.set_description ("Optionally specify an alternative URL path by which this content can be accessed.<br/>%NFor example, type 'about' when writing an about page. Use a relative path or the URL alias won't work.")
else
l_uri := ""
end
ti.set_text_value (l_uri)
ti.set_placeholder (l_auto_path_alias)
ti.set_validation_action (agent (fd: WSF_FORM_DATA; ia_response: NODE_RESPONSE; ia_node: detachable CMS_NODE)
do
if
@@ -163,6 +173,11 @@ feature -- Forms ...
else
f.extend (ti)
end
-- Auto path alias / suggestion
create thi.make ("auto_path_alias")
thi.set_text_value (l_auto_path_alias)
thi.set_is_readonly (True)
f.insert_after (thi, ti)
end
update_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: CMS_NODE)
@@ -291,9 +306,12 @@ feature -- Output
a_response.add_to_primary_tabs (lnk)
if a_node.status = {CMS_NODE_API}.trashed then
create lnk.make ("Delete", l_node_api.node_path (a_node) + "/delete")
create lnk.make ("Restore", l_node_api.node_path (a_node) + "/trash")
lnk.set_weight (2)
a_response.add_to_primary_tabs (lnk)
create lnk.make ("Delete", l_node_api.node_path (a_node) + "/delete")
lnk.set_weight (3)
a_response.add_to_primary_tabs (lnk)
elseif a_node.has_id then
-- Node in {{CMS_NODE_API}.published} or {CMS_NODE_API}.not_published} status.
create lnk.make ("Edit", l_node_api.node_path (a_node) + "/edit")
@@ -320,7 +338,17 @@ feature -- Output
if is_teaser then
a_output.append (" cms-teaser")
end
a_output.append ("cms-node node-" + a_node.content_type + "%">")
a_output.append ("cms-node node-" + a_node.content_type)
if a_node.is_published then
a_output.append (" cms-status-published")
elseif a_node.is_trashed then
a_output.append (" cms-status-trashed")
elseif a_node.is_not_published then
a_output.append (" cms-status-unpublished")
else
a_output.append (" cms-status-" + a_node.status.out)
end
a_output.append ("%">")
a_output.append ("<div class=%"info%"> ")
if attached a_node.author as l_author then
@@ -430,6 +458,4 @@ feature -- Output
end
a_output.append ("</li>")
end
end

View File

@@ -159,7 +159,6 @@ feature {NONE} -- Create a new node
end
end
delete_node (a_node: CMS_NODE; a_type: CMS_NODE_TYPE [CMS_NODE]; b: STRING_8)
local
f: like new_edit_form
@@ -187,7 +186,7 @@ feature {NONE} -- Create a new node
f.append_to_html (wsf_theme, b)
end
else
--
b.append ("ERROR: node is not in the trash!")
end
end
@@ -254,7 +253,7 @@ feature -- Form
l_node: detachable CMS_NODE
s: STRING
l_node_path: READABLE_STRING_8
l_path_alias, l_existing_path_alias: detachable READABLE_STRING_8
l_path_alias, l_existing_path_alias, l_auto_path_alias: detachable READABLE_STRING_8
do
fixme ("Refactor code per operacion: Preview, Save")
l_preview := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Preview")
@@ -302,10 +301,13 @@ feature -- Form
add_success_message ("Node #" + l_node.id.out + " saved.")
end
-- Path aliase
l_node_path := node_api.node_path (l_node)
l_existing_path_alias := api.location_alias (l_node_path)
l_auto_path_alias := node_api.path_alias_uri_suggestion (l_node, a_type)
if attached fd.string_item ("path_alias") as f_path_alias then
l_node_path := node_api.node_path (l_node)
l_path_alias := percent_encoder.partial_encoded_string (f_path_alias, <<'/'>>)
l_existing_path_alias := api.location_alias (l_node_path)
if
l_existing_path_alias /= Void and then
l_path_alias.same_string (l_existing_path_alias)
@@ -315,7 +317,10 @@ feature -- Form
elseif l_existing_path_alias /= Void and then l_path_alias.is_whitespace then
-- Reset to builtin alias.
if api.has_permission ("edit path_alias") then
api.set_path_alias (l_node_path, l_node_path, True)
api.set_path_alias (l_node_path, l_auto_path_alias, True)
elseif l_existing_path_alias.same_string (l_node_path) then
-- not aliased! Use default.
api.set_path_alias (l_node_path, l_auto_path_alias, True)
else
add_error_message ("Permission denied to reset path alias on node #" + l_node.id.out + "!")
end
@@ -330,6 +335,12 @@ feature -- Form
l_node.set_link (node_api.node_link (l_node))
end
end
elseif l_existing_path_alias /= Void then
l_node.set_link (create {CMS_LOCAL_LINK}.make (l_node.title, l_existing_path_alias))
elseif l_auto_path_alias /= Void then
-- Use auto path alias
api.set_path_alias (l_node_path, l_auto_path_alias, True)
l_node.set_link (create {CMS_LOCAL_LINK}.make (l_node.title, l_auto_path_alias))
else
l_node.set_link (node_api.node_link (l_node))
end
@@ -381,7 +392,7 @@ feature -- Form
create f.make (a_url, a_name)
f.extend_html_text ("<br/>")
f.extend_html_text ("<legend>Are you sure you want to delete?</legend>")
f.extend_html_text ("<legend>Are you sure you want to delete? (impossible to undo)</legend>")
-- TODO check if we need to check for has_permissions!!
if
@@ -400,46 +411,42 @@ feature -- Form
ts.set_formmethod ("GET")
f.extend (ts)
end
f.extend_html_text ("<br/>")
f.extend_html_text ("<legend>Do you want to restore the current node?</legend>")
if
a_node /= Void and then
a_node.id > 0
then
create ts.make ("op")
ts.set_default_value ("Restore")
ts.set_formaction ("/node/"+a_node.id.out+"/delete")
ts.set_formmethod ("POST")
fixme ("[
ts.set_default_value (translation ("Restore"))
]")
f.extend (ts)
end
Result := f
end
new_trash_form (a_node: detachable CMS_NODE; a_url: READABLE_STRING_8; a_name: STRING; a_node_type: CMS_NODE_TYPE [CMS_NODE]): CMS_FORM
-- Create a web form named `a_name' for node `a_node' (if set), using form action url `a_url', and for type of node `a_node_type'.
new_trash_form (a_node: CMS_NODE; a_url: READABLE_STRING_8; a_name: STRING; a_node_type: CMS_NODE_TYPE [CMS_NODE]): CMS_FORM
-- Create a web form named `a_name' for node `a_node', using form action url `a_url', and for type of node `a_node_type'.
local
f: CMS_FORM
ts: WSF_FORM_SUBMIT_INPUT
do
create f.make (a_url, a_name)
f.set_method_post
f.extend_html_text ("<br/>")
f.extend_html_text ("<legend>Are you sure you want to trash the current node?</legend>")
if
a_node /= Void and then
a_node.id > 0
then
if a_node.is_trashed then
f.extend_html_text ("<legend>Are you sure you want to restore the current node?</legend>")
create ts.make ("op")
ts.set_default_value ("Trash")
ts.set_default_value ("Restore")
ts.set_formaction ("/node/" + a_node.id.out + "/trash")
ts.set_formmethod ("POST")
fixme ("[
ts.set_default_value (translation ("Trash"))
]")
f.extend (ts)
else
f.extend_html_text ("<legend>Are you sure you want to trash the current node?</legend>")
create ts.make ("op")
ts.set_default_value ("Trash")
ts.set_formaction ("/node/" + a_node.id.out + "/trash")
ts.set_formmethod ("POST")
fixme ("[
ts.set_default_value (translation ("Trash"))
]")
end
f.extend (ts)
Result := f
end

View File

@@ -174,18 +174,20 @@ feature -- HTTP Methods
l_op.value.same_string ("Delete")
then
do_delete (req, res)
elseif
attached {WSF_STRING} req.form_parameter ("op") as l_op and then
l_op.value.same_string ("Restore")
then
do_restore (req, res)
else
send_bad_request (req, res)
end
elseif req.percent_encoded_path_info.ends_with ("/trash") then
if
attached {WSF_STRING} req.form_parameter ("op") as l_op and then
l_op.value.same_string ("Trash")
then
do_trash (req, res)
if attached {WSF_STRING} req.form_parameter ("op") as l_op then
if l_op.is_case_insensitive_equal ("Trash") then
do_trash (req, res)
elseif l_op.is_case_insensitive_equal ("Restore") then
do_restore (req, res)
else
send_bad_request (req, res)
end
else
send_bad_request (req, res)
end
elseif req.percent_encoded_path_info.starts_with ("/node/add/") then
create edit_response.make (req, res, api, node_api)
@@ -206,6 +208,14 @@ feature -- HTTP Methods
send_not_implemented ("REST API not yet implemented", req, res)
end
process_node_creation (req: WSF_REQUEST; res: WSF_RESPONSE; a_user: CMS_USER)
do
to_implement ("REST API")
send_not_implemented ("REST API not yet implemented", req, res)
end
feature {NONE} -- Trash:Restore
do_trash (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Trash a node, soft delete.
do
@@ -233,14 +243,6 @@ feature -- HTTP Methods
end
end
process_node_creation (req: WSF_REQUEST; res: WSF_RESPONSE; a_user: CMS_USER)
do
to_implement ("REST API")
send_not_implemented ("REST API not yet implemented", req, res)
end
feature {NONE} -- Trash:Restore
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Delete a node from the database.
local
@@ -283,7 +285,7 @@ feature {NONE} -- Trash:Restore
then
if node_api.has_permission_for_action_on_node ("restore", l_node, l_user) then
node_api.restore_node (l_node)
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("/" + node_api.node_path (l_node))))
else
send_access_denied (req, res)
-- send_not_authorized ?

View File

@@ -11,7 +11,16 @@ inherit
WSF_URI_HANDLER
rename
new_mapping as new_uri_mapping
new_mapping as new_uri_mapping,
execute as execute_uri
end
WSF_URI_TEMPLATE_HANDLER
rename
new_mapping as new_uri_template_mapping,
execute as execute_uri_template
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
@@ -26,6 +35,16 @@ create
feature -- execute
execute_uri (req: WSF_REQUEST; res: WSF_RESPONSE)
do
execute (req, res)
end
execute_uri_template (req: WSF_REQUEST; res: WSF_RESPONSE)
do
execute (req, res)
end
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
@@ -39,30 +58,57 @@ feature -- HTTP Methods
local
l_response: CMS_RESPONSE
s: STRING
l_content_type: detachable CMS_CONTENT_TYPE
n: CMS_NODE
lnk: CMS_LOCAL_LINK
l_page_helper: CMS_PAGINATION_GENERATOR
s_pager: STRING
l_count: NATURAL_64
inc: BOOLEAN
l_include_trashed: BOOLEAN
lst: detachable ITERABLE [CMS_NODE]
do
-- At the moment the template are hardcoded, but we can
-- get them from the configuration file and load them into
-- the setup class.
l_count := node_api.nodes_count
if attached {WSF_STRING} req.path_parameter ("type") as p_node_type and then attached api.content_type (p_node_type.value) as ct then
l_content_type := api.content_type (p_node_type.value)
end
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
create s.make_empty
if l_count > 1 then
l_response.set_title ("Listing " + l_count.out + " nodes")
else
l_response.set_title ("Listing " + l_count.out + " node")
across
api.content_types as ic
loop
if attached {CMS_NODE_TYPE [CMS_NODE]} ic.item as l_note_type then
create lnk.make (l_note_type.name, "nodes/" + l_note_type.name)
if l_note_type = l_content_type then
lnk.set_is_active (True)
end
l_response.add_to_primary_tabs (lnk)
end
end
create s_pager.make_empty
create l_page_helper.make ("nodes/?page={page}&size={size}", node_api.nodes_count, 25) -- FIXME: Make this default page size a global CMS settings
if l_content_type /= Void then
l_count := node_api.nodes_of_type_count (l_content_type)
if l_count > 1 then
l_response.set_title ("Listing " + l_count.out + " " + l_content_type.name + " nodes")
else
l_response.set_title ("Listing " + l_count.out + " " + l_content_type.name + " node")
end
create l_page_helper.make ("nodes/" + l_content_type.name + "/?page={page}&size={size}", l_count, 25) -- FIXME: Make this default page size a global CMS settings
else
l_count := node_api.nodes_count
if l_count > 1 then
l_response.set_title ("Listing " + l_count.out + " nodes")
else
l_response.set_title ("Listing " + l_count.out + " node")
end
create l_page_helper.make ("nodes/?page={page}&size={size}", l_count, 25) -- FIXME: Make this default page size a global CMS settings
end
l_page_helper.get_setting_from_request (req)
if l_page_helper.has_upper_limit and then l_page_helper.pages_count > 1 then
l_page_helper.append_to_html (l_response, s_pager)
@@ -71,7 +117,12 @@ feature -- HTTP Methods
end
end
if attached node_api.recent_nodes (create {CMS_DATA_QUERY_PARAMETERS}.make (l_page_helper.current_page_offset, l_page_helper.page_size)) as lst then
if l_content_type /= Void then
lst := node_api.recent_nodes_of_type (l_content_type, create {CMS_DATA_QUERY_PARAMETERS}.make (l_page_helper.current_page_offset, l_page_helper.page_size))
else
lst := node_api.recent_nodes (create {CMS_DATA_QUERY_PARAMETERS}.make (l_page_helper.current_page_offset, l_page_helper.page_size))
end
if lst /= Void then
if attached {WSF_STRING} req.query_parameter ("include_trash") as v and then v.is_case_insensitive_equal ("yes") then
l_include_trashed := l_response.has_permissions (<<"view trash", "view any trash">>)
end
@@ -80,7 +131,14 @@ feature -- HTTP Methods
lst as ic
loop
n := ic.item
if not n.is_trashed or else l_include_trashed then
inc := True
if not n.is_published then
inc := view_unpublished_node_permitted (n)
end
if inc and n.is_trashed then
inc := l_include_trashed
end
if inc then
lnk := node_api.node_link (n)
s.append ("<li class=%"cms_type_"+ n.content_type)
if not n.is_published then
@@ -131,4 +189,15 @@ feature -- HTTP Methods
l_response.execute
end
feature -- Helper
view_unpublished_node_permitted (n: CMS_NODE): BOOLEAN
do
if api.has_permission ("view unpublished " + n.content_type) then
Result := True
elseif attached api.user as u then
Result := u.same_as (n.author)
end
end
end

View File

@@ -22,6 +22,7 @@
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html.ecf" readonly="false"/>

View File

@@ -100,6 +100,13 @@ feature -- Access
deferred
end
recent_nodes_of_type (a_node_type: CMS_CONTENT_TYPE; a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- Recent `a_count` nodes of type `a_node_type` with an offset of `lower`.
deferred
ensure
across Result as ic all ic.item.is_typed_as (a_node_type.name) 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.
deferred
@@ -120,6 +127,12 @@ feature -- Access
deferred
end
nodes_of_type_count (a_node_type: CMS_CONTENT_TYPE): NATURAL_64
-- Count of nodes of type `a_node_type`.
do
Result := nodes_of_type (a_node_type).count.to_natural_64
end
nodes_of_type (a_node_type: CMS_CONTENT_TYPE): LIST [CMS_NODE]
-- List of nodes of type `a_node_type'.
--| Redefine to optimize!
@@ -137,7 +150,7 @@ feature -- Access
end
end
ensure
expected_type: across Result as ic all ic.item.content_type.same_string (a_node_type.name) end
expected_type: across Result as ic all ic.item.is_typed_as (a_node_type.name) end
end
nodes_of_type_with_title (a_node_type: CMS_CONTENT_TYPE; a_title: READABLE_STRING_GENERAL): LIST [CMS_NODE]

View File

@@ -59,6 +59,12 @@ feature -- Access: node
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
recent_nodes_of_type (a_node_type: CMS_CONTENT_TYPE; a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- Recent `a_count` nodes of type `a_node_type` with an offset of `lower`.
do
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

View File

@@ -13,6 +13,7 @@ inherit
CMS_NODE_STORAGE_I
redefine
nodes_of_type_count,
nodes_of_type,
nodes_of_type_with_title
end
@@ -38,6 +39,22 @@ feature -- Access
sql_finalize
end
nodes_of_type_count (a_node_type: CMS_CONTENT_TYPE): NATURAL_64
-- Count of nodes of type `a_node_type`.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
create l_parameters.make (1)
l_parameters.force (a_node_type.name, "node_type")
sql_query (sql_select_nodes_of_type_count, l_parameters)
if not has_error and not sql_after then
Result := sql_read_natural_64 (1)
end
sql_finalize
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
@@ -145,6 +162,31 @@ feature -- Access
sql_finalize
end
recent_nodes_of_type (a_node_type: CMS_CONTENT_TYPE; a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- Recent `a_count` nodes of type `a_node_type` with an offset of `lower`.
local
l_parameters: STRING_TABLE [detachable ANY]
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
from
create l_parameters.make (3)
l_parameters.put (a_node_type.name, "node_type")
l_parameters.put (a_count, "size")
l_parameters.put (a_lower, "offset")
sql_query (sql_select_recent_nodes_of_type, l_parameters)
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
sql_finalize
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
@@ -270,7 +312,7 @@ feature -- Access
sql_after
loop
if attached fetch_node as l_node then
check expected_node_type: l_node.content_type.same_string (a_node_type.name) end
check expected_node_type: l_node.is_typed_as (a_node_type.name) end
Result.force (l_node)
end
sql_forth
@@ -474,6 +516,10 @@ feature {NONE} -- Queries
-- Nodes count (Published and not Published)
--| note: {CMS_NODE_API}.trashed = -1
sql_select_nodes_of_type_count: STRING = "SELECT count(*) FROM nodes WHERE type=:node_type AND status != -1 ;"
-- Nodes of type `:node_type` count (Published and not Published)
--| note: {CMS_NODE_API}.trashed = -1
sql_select_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes WHERE status != -1 ;"
-- SQL Query to retrieve all nodes.
--| note: {CMS_NODE_API}.trashed = -1
@@ -503,6 +549,8 @@ feature {NONE} -- Queries
sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes ORDER BY changed DESC, publish DESC LIMIT :size OFFSET :offset ;"
sql_select_recent_nodes_of_type: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes WHERE type=:node_type ORDER BY changed 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);"