Display /nodes sorted by changed date. Improved the import form, and report wrong import folder. Only import from folder inside site/import for security reason.
371 lines
9.3 KiB
Plaintext
371 lines
9.3 KiB
Plaintext
note
|
|
description: "[
|
|
API to manage CMS Nodes
|
|
]"
|
|
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
|
revision: "$Revision: 96616 $"
|
|
|
|
class
|
|
CMS_NODE_API
|
|
|
|
inherit
|
|
CMS_MODULE_API
|
|
|
|
REFACTORING_HELPER
|
|
|
|
create {CMS_NODE_MODULE}
|
|
make_with_storage
|
|
|
|
feature {NONE} -- Initialization
|
|
|
|
make_with_storage (a_api: CMS_API; a_node_storage: CMS_NODE_STORAGE_I)
|
|
do
|
|
node_storage := a_node_storage
|
|
make (a_api)
|
|
-- error_handler.add_synchronization (a_node_storage.error_handler)
|
|
end
|
|
|
|
feature {CMS_MODULE} -- Access nodes storage.
|
|
|
|
node_storage: CMS_NODE_STORAGE_I
|
|
|
|
feature -- Content type
|
|
|
|
add_node_type (a_type: CMS_NODE_TYPE [CMS_NODE])
|
|
-- Register node content type `a_type'.
|
|
do
|
|
cms_api.add_content_type (a_type)
|
|
end
|
|
|
|
node_types: ARRAYED_LIST [attached like node_type]
|
|
-- Node content types.
|
|
do
|
|
create Result.make (cms_api.content_types.count)
|
|
across
|
|
cms_api.content_types as ic
|
|
loop
|
|
if attached {like node_type} ic.item as l_node_type then
|
|
Result.extend (l_node_type)
|
|
end
|
|
end
|
|
end
|
|
|
|
node_type (a_name: READABLE_STRING_GENERAL): detachable CMS_NODE_TYPE [CMS_NODE]
|
|
-- Content type named `a_named' if any.
|
|
do
|
|
across
|
|
cms_api.content_types as ic
|
|
until
|
|
Result /= Void
|
|
loop
|
|
if
|
|
attached {like node_type} ic.item as l_node_type and then
|
|
a_name.is_case_insensitive_equal (l_node_type.name)
|
|
then
|
|
Result := l_node_type
|
|
end
|
|
end
|
|
end
|
|
|
|
node_type_for (a_node: CMS_NODE): like node_type
|
|
-- Content type for node `a_node' if any.
|
|
local
|
|
l_type_name: READABLE_STRING_8
|
|
do
|
|
l_type_name := a_node.content_type
|
|
Result := node_type (l_type_name)
|
|
end
|
|
|
|
feature -- Content type webform
|
|
|
|
content_type_webform_managers: ARRAYED_LIST [CMS_CONTENT_TYPE_WEBFORM_MANAGER [CMS_CONTENT]]
|
|
-- Available content types
|
|
do
|
|
Result := cms_api.content_type_webform_managers
|
|
end
|
|
|
|
add_node_type_webform_manager (a_manager: CMS_NODE_TYPE_WEBFORM_MANAGER [CMS_NODE])
|
|
-- Register webform manager `a_manager'.
|
|
do
|
|
cms_api.add_content_type_webform_manager (a_manager)
|
|
end
|
|
|
|
node_type_webform_manager (a_node_type: CMS_CONTENT_TYPE): detachable CMS_NODE_TYPE_WEBFORM_MANAGER_I [CMS_NODE]
|
|
-- Web form manager for node type `a_node_type' if any.
|
|
local
|
|
l_type_name: READABLE_STRING_GENERAL
|
|
do
|
|
l_type_name := a_node_type.name
|
|
across
|
|
content_type_webform_managers as ic
|
|
until
|
|
Result /= Void
|
|
loop
|
|
if
|
|
attached {like node_type_webform_manager} ic.item as l_manager and then
|
|
l_type_name.is_case_insensitive_equal (l_manager.name)
|
|
then
|
|
Result := l_manager
|
|
end
|
|
end
|
|
end
|
|
|
|
feature -- URL
|
|
|
|
new_content_path (ct: detachable CMS_CONTENT_TYPE): STRING
|
|
-- URI path for new content of type `ct'
|
|
-- or URI of path for selection of new content possibilities if ct is Void.
|
|
do
|
|
if ct /= Void then
|
|
Result := "node/add/" + ct.name
|
|
else
|
|
Result := "node/"
|
|
end
|
|
end
|
|
|
|
node_link (a_node: CMS_NODE): CMS_LOCAL_LINK
|
|
-- CMS link for node `a_node'.
|
|
require
|
|
a_node.has_id
|
|
do
|
|
create Result.make (a_node.title, cms_api.location_alias (node_path (a_node)))
|
|
end
|
|
|
|
node_path (a_node: CMS_NODE): STRING
|
|
-- URI path for node `a_node'.
|
|
-- using the /node/{nid} url.
|
|
require
|
|
a_node.has_id
|
|
do
|
|
Result := "node/" + a_node.id.out
|
|
end
|
|
|
|
nodes_path: STRING
|
|
-- URI path for list of nodes.
|
|
do
|
|
Result := "nodes"
|
|
end
|
|
|
|
feature -- Access: Node
|
|
|
|
nodes_count: NATURAL_64
|
|
do
|
|
Result := node_storage.nodes_count
|
|
end
|
|
|
|
nodes: LIST [CMS_NODE]
|
|
-- List of nodes.
|
|
do
|
|
Result := node_storage.nodes
|
|
end
|
|
|
|
node_revisions (a_node: CMS_NODE): LIST [CMS_NODE]
|
|
-- List of revisions for node `a_node'.
|
|
do
|
|
Result := node_storage.node_revisions (a_node)
|
|
Result := full_nodes (Result)
|
|
end
|
|
|
|
trashed_nodes (a_user: detachable CMS_USER): LIST [CMS_NODE]
|
|
-- List of nodes with status in {CMS_NODE_API}.trashed.
|
|
-- if `a_user' is set, return nodes related to this user.
|
|
do
|
|
Result := node_storage.trashed_nodes (a_user)
|
|
end
|
|
|
|
recent_nodes (params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_NODE]
|
|
-- 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 := 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 := safe_full_node (node_storage.node_by_id_and_revision (a_node_id, a_revision_id))
|
|
end
|
|
|
|
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
|
|
Result := ct.new_node (l_partial_node)
|
|
node_storage.fill_node (Result)
|
|
else
|
|
Result := l_partial_node
|
|
end
|
|
-- Update link with aliasing.
|
|
if Result /= Void and then Result.has_id then
|
|
Result.set_link (node_link (Result))
|
|
end
|
|
else
|
|
Result := a_node
|
|
if Result.has_id and Result.link = Void then
|
|
Result.set_link (node_link (Result))
|
|
end
|
|
end
|
|
check has_link: Result.has_id implies attached Result.link as lnk and then lnk.location.same_string (node_link (Result).location) end
|
|
|
|
-- Update partial user if needed.
|
|
if
|
|
Result /= Void and then
|
|
attached {CMS_PARTIAL_USER} Result.author as l_partial_author
|
|
then
|
|
if attached cms_api.user_api.user_by_id (l_partial_author.id) as l_author then
|
|
Result.set_author (l_author)
|
|
else
|
|
check
|
|
valid_author_id: False
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
full_nodes (a_nodes: LIST [CMS_NODE]): LIST [CMS_NODE]
|
|
-- Convert list of nodes into a list of nodes when possible.
|
|
do
|
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_nodes.count)
|
|
|
|
across
|
|
a_nodes as ic
|
|
loop
|
|
if attached full_node (ic.item) as l_full then
|
|
Result.force (l_full)
|
|
end
|
|
end
|
|
end
|
|
|
|
is_author_of_node (u: CMS_USER; a_node: CMS_NODE): BOOLEAN
|
|
-- Is the user `u' owner of the node `n'.
|
|
do
|
|
Result := u.same_as (a_node.author)
|
|
end
|
|
|
|
nodes_of_type (a_node_type: CMS_CONTENT_TYPE): LIST [CMS_NODE]
|
|
-- List of nodes of type `a_node_type'.
|
|
do
|
|
Result := node_storage.nodes_of_type (a_node_type)
|
|
ensure
|
|
expected_type: across Result as ic all ic.item.content_type.same_string (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]
|
|
do
|
|
Result := node_storage.nodes_of_type_with_title (a_node_type, a_title)
|
|
end
|
|
|
|
feature -- Permission Scope: Node
|
|
|
|
has_permission_for_action_on_node (a_action: READABLE_STRING_8; a_node: CMS_NODE; a_user: detachable CMS_USER; ): BOOLEAN
|
|
-- Has permission to execute action `a_action' on node `a_node', by eventual user `a_user'?
|
|
local
|
|
l_type_name: READABLE_STRING_8
|
|
do
|
|
l_type_name := a_node.content_type
|
|
Result := cms_api.user_has_permission (a_user, a_action + " any " + l_type_name)
|
|
if not Result and a_user /= Void then
|
|
if is_author_of_node (a_user, a_node) then
|
|
Result := cms_api.user_has_permission (a_user, a_action + " own " + l_type_name)
|
|
end
|
|
end
|
|
end
|
|
|
|
feature -- Change: Node
|
|
|
|
save_node (a_node: CMS_NODE)
|
|
-- Save `a_node'.
|
|
local
|
|
now: DATE_TIME
|
|
do
|
|
reset_error
|
|
create now.make_now_utc
|
|
a_node.set_modification_date (now)
|
|
node_storage.save_node (a_node)
|
|
error_handler.append (node_storage.error_handler)
|
|
end
|
|
|
|
import_node (a_node: CMS_NODE)
|
|
-- Same as `save_node` but keep modification_date unchanged.
|
|
do
|
|
reset_error
|
|
node_storage.save_node (a_node)
|
|
error_handler.append (node_storage.error_handler)
|
|
end
|
|
|
|
new_node (a_node: CMS_NODE)
|
|
-- Add a new node `a_node'
|
|
require
|
|
no_id: not a_node.has_id
|
|
do
|
|
reset_error
|
|
node_storage.new_node (a_node)
|
|
error_handler.append (node_storage.error_handler)
|
|
end
|
|
|
|
delete_node (a_node: CMS_NODE)
|
|
-- Delete `a_node'.
|
|
--! remove the node from the storage.
|
|
do
|
|
reset_error
|
|
if a_node.has_id then
|
|
node_storage.delete_node (a_node)
|
|
error_handler.append (node_storage.error_handler)
|
|
end
|
|
end
|
|
|
|
trash_node (a_node: CMS_NODE)
|
|
-- Trash node `a_node'.
|
|
-- Soft delete
|
|
do
|
|
reset_error
|
|
node_storage.trash_node (a_node)
|
|
error_handler.append (node_storage.error_handler)
|
|
end
|
|
|
|
restore_node (a_node: CMS_NODE)
|
|
-- Restore node `a_node'.
|
|
-- From {CMS_NODE_API}.trashed to {CMS_NODE_API}.not_published.
|
|
do
|
|
reset_error
|
|
node_storage.restore_node (a_node)
|
|
error_handler.append (node_storage.error_handler)
|
|
end
|
|
|
|
feature -- Node status
|
|
|
|
Not_published: INTEGER = 0
|
|
-- The node is not published.
|
|
|
|
Published: INTEGER = 1
|
|
-- The node is published.
|
|
|
|
Trashed: INTEGER = -1
|
|
-- The node is trashed (soft delete), ready to be deleted/destroyed from storage.
|
|
|
|
end
|