Files
ROC/modules/node/handler/node_handler.e
Jocelyn Fiat 2d698f604b Extracted page support from cms_node_module, and add a proper CMS_PAGE_MODULE.
- now, the CMS_PAGE_MODULE has to be declared in the related CMS_SETUP via CMS_EXECUTION.
   (See demo for example)

Improved the export facilities.
  Implemented blog and page export.
Added import facilities.
  Implemented blog and page import.

Improved node revision web interface (allow to edit a past revision, in order to restore it as latest revisionm i.e current).
Removed specific tag from blog module, and reuse the taxonomy module for that purpose.

Added WIKITEXT module that provide a WIKITEXT_FILTER, so now we can have wikitext content.
   - for now, no support for wiki links such as [[Foobar]].
2017-01-20 16:05:40 +01:00

400 lines
11 KiB
Plaintext

note
description: "[
handler for CMS node in the CMS interface.
TODO: implement REST API.
]"
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
class
NODE_HANDLER
inherit
CMS_NODE_HANDLER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put,
do_delete
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute (req, res)
end
feature -- Query
node_id_path_parameter (req: WSF_REQUEST): INTEGER_64
-- Node id passed as path parameter for request `req'.
local
s: STRING
do
if attached {WSF_STRING} req.path_parameter ("id") as p_nid then
s := p_nid.value
if s.is_integer_64 then
Result := s.to_integer_64
end
end
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_node: detachable CMS_NODE
l_nid, l_rev: INTEGER_64
edit_response: NODE_FORM_RESPONSE
view_response: NODE_VIEW_RESPONSE
do
if req.percent_encoded_path_info.ends_with ("/edit") then
check valid_url: req.percent_encoded_path_info.starts_with ("/node/") end
create edit_response.make (req, res, api, node_api)
edit_response.execute
elseif req.percent_encoded_path_info.ends_with ("/delete") then
check valid_url: req.percent_encoded_path_info.starts_with ("/node/") end
create edit_response.make (req, res, api, node_api)
edit_response.execute
elseif req.percent_encoded_path_info.ends_with ("/trash") then
check valid_url: req.percent_encoded_path_info.starts_with ("/node/") end
create edit_response.make (req, res, api, node_api)
edit_response.execute
elseif req.percent_encoded_path_info.ends_with ("/revision") then
do_revisions (req, res)
-- elseif req.percent_encoded_path_info.ends_with ("/add_child/page") then
-- -- Add child node
-- l_nid := node_id_path_parameter (req)
-- if l_nid > 0 then
-- -- create a new child node with node id `l_id' as parent.
-- create_new_node (req, res)
-- else
-- send_not_found (req, res)
-- end
else
-- Display existing node
l_nid := node_id_path_parameter (req)
if l_nid > 0 then
if
attached {WSF_STRING} req.query_parameter ("revision") as p_rev and then
p_rev.value.is_integer_64
then
l_rev := p_rev.value.to_integer_64
end
l_node := node_api.node (l_nid)
if
l_node /= Void and then
l_rev > 0 and then
l_rev < l_node.revision and then
node_api.has_permission_for_action_on_node ("view revisions", l_node, api.user)
then
l_node := node_api.revision_node (l_nid, l_rev)
end
if l_node = Void then
send_not_found (req, res)
else
if
l_rev > 0 or else l_node.is_published
then
create view_response.make (req, res, api, node_api)
view_response.set_node (l_node)
view_response.set_revision (l_rev)
view_response.execute
elseif
attached api.user as l_user and then
( node_api.is_author_of_node (l_user, l_node)
or else api.user_has_permission (l_user, "view unpublished " + l_node.content_type)
)
then
create view_response.make (req, res, api, node_api)
view_response.set_node (l_node)
view_response.set_revision (l_rev)
view_response.execute
else
send_access_denied (req, res)
end
end
else
-- redirect_to (req.absolute_script_url ("/node/"), res) -- New node.
-- send_bad_request (req, res)
create_new_node (req, res)
end
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
edit_response: NODE_FORM_RESPONSE
do
fixme ("Refactor code: extract methods: edit_node and add_node")
if req.percent_encoded_path_info.ends_with ("/edit") then
create edit_response.make (req, res, api, node_api)
edit_response.execute
elseif req.percent_encoded_path_info.ends_with ("/delete") then
if
attached {WSF_STRING} req.form_parameter ("op") as l_op and then
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)
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)
end
elseif req.percent_encoded_path_info.starts_with ("/node/add/") then
create edit_response.make (req, res, api, node_api)
edit_response.execute
elseif req.percent_encoded_path_info.ends_with ("/add_child/page") then
create edit_response.make (req, res, api, node_api)
edit_response.execute
else
to_implement ("REST API")
send_not_implemented ("REST API not yet implemented", req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
to_implement ("REST API")
send_not_implemented ("REST API not yet implemented", req, res)
end
do_trash (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Trash a node, soft delete.
do
if attached api.user as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached node_api.node (l_id.integer_value) as l_node
then
if node_api.has_permission_for_action_on_node ("trash", l_node, l_user) then
node_api.trash_node (l_node)
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
else
send_access_denied (req, res)
-- send_not_authorized ?
end
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
send_access_denied (req, res)
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
l_source: STRING
do
if attached api.user as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached {CMS_NODE} node_api.node (l_id.integer_value) as l_node
then
if node_api.has_permission_for_action_on_node ("delete", l_node, l_user) then
node_api.delete_node (l_node)
l_source := node_api.node_path (l_node)
api.unset_path_alias (l_source, api.location_alias (l_source))
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
else
send_access_denied (req, res)
-- send_not_authorized ?
end
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
send_access_denied (req, res)
end
end
do_restore (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Restore a node: From {CMS_NODE_API}.trashed to {CMS_NODE_API}.not_published.
do
if attached api.user as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached node_api.node (l_id.integer_value) as l_node
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 ("")))
else
send_access_denied (req, res)
-- send_not_authorized ?
end
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
send_access_denied (req, res)
end
end
do_revisions (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Display revisions of a node.
local
r: GENERIC_VIEW_CMS_RESPONSE
b: STRING
n: CMS_NODE
do
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached node_api.node (l_id.integer_value) as l_node
then
if node_api.has_permission_for_action_on_node ("view revisions", l_node, api.user) then
create r.make (req, res, api)
create b.make_empty
b.append ("<ul>")
across
node_api.node_revisions (l_node) as ic
loop
n := ic.item
b.append ("<li>")
b.append ("<a href=%"")
b.append (r.url (node_api.node_path (n) + "?revision=" + n.revision.out, Void))
b.append ("%">")
if n.revision = l_node.revision then
b.append ("Current ")
else
b.append ("Revision")
end
b.append (" #")
b.append (n.revision.out)
b.append (" : ")
b.append (n.modification_date.out)
b.append ("</a>")
if attached n.author as l_author then
b.append (" by ")
b.append (r.link (l_author.name, "user/" + l_author.id.out, Void))
end
if node_api.has_permission_for_action_on_node ("edit revisions", l_node, api.user) then
b.append (" (<a href=%"")
b.append (r.url (node_api.node_path (n) + "/edit?revision=" + n.revision.out, Void))
b.append ("%">edit</a>)")
end
b.append ("</li>")
end
b.append ("</ul>")
r.set_title ("Revisions for " + html_encoded (l_node.title))
r.set_main_content (b)
r.execute
else
send_access_denied (req, res)
-- send_not_authorized ?
end
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: detachable WSF_STRING)
-- Handling error.
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.set_value (req.absolute_script_url (req.percent_encoded_path_info), "request")
if a_id /= Void and then a_id.is_integer then
-- resource not found
l_page.set_value ("404", "code")
l_page.set_status_code (404)
else
-- bad request
l_page.set_value ("400", "code")
l_page.set_status_code (400)
end
l_page.execute
end
feature {NONE} -- Node
create_new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
local
edit_response: NODE_FORM_RESPONSE
do
if req.percent_encoded_path_info.starts_with_general ("/node/") then
create edit_response.make (req, res, api, node_api)
edit_response.execute
elseif req.is_get_request_method then
redirect_to (req.absolute_script_url ("/node/"), res)
else
send_bad_request (req, res)
end
end
end