Added CMS_HOOK_RESPONSE_ALTER to give a last chance to alter the response before rendering. This hook should not be used, when there are other alternative hook that answer the need, but this is proposed for now, as a way to alter response by adding css, js url, ... Moved blog under official modules folder. Cleaned theme of demo example project. Renamed NODE_MODULE as CMS_NODE_MODULE.
355 lines
8.1 KiB
Plaintext
355 lines
8.1 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
|
|
redefine
|
|
initialize
|
|
end
|
|
|
|
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)
|
|
end
|
|
|
|
initialize
|
|
-- <Precursor>
|
|
do
|
|
Precursor
|
|
initialize_node_types
|
|
end
|
|
|
|
initialize_node_types
|
|
-- Initialize content type system.
|
|
local
|
|
ct: CMS_PAGE_NODE_TYPE
|
|
do
|
|
create content_types.make (1)
|
|
create content_type_webform_managers.make (1)
|
|
create ct
|
|
add_content_type (ct)
|
|
add_content_type_webform_manager (create {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}.make (ct))
|
|
end
|
|
|
|
feature {CMS_MODULE} -- Access nodes storage.
|
|
|
|
node_storage: CMS_NODE_STORAGE_I
|
|
|
|
feature -- Content type
|
|
|
|
content_types: ARRAYED_LIST [CMS_CONTENT_TYPE]
|
|
-- Available content types
|
|
|
|
node_types: ARRAYED_LIST [attached like node_type]
|
|
-- Node content types.
|
|
do
|
|
create Result.make (content_types.count)
|
|
across
|
|
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
|
|
|
|
add_content_type (a_type: CMS_CONTENT_TYPE)
|
|
-- Register content type `a_type'.
|
|
do
|
|
content_types.force (a_type)
|
|
end
|
|
|
|
content_type (a_name: READABLE_STRING_GENERAL): detachable CMS_CONTENT_TYPE
|
|
-- Content type named `a_named' if any.
|
|
do
|
|
across
|
|
content_types as ic
|
|
until
|
|
Result /= Void
|
|
loop
|
|
Result := ic.item
|
|
if not a_name.is_case_insensitive_equal (Result.name) then
|
|
Result := Void
|
|
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
|
|
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]
|
|
-- Available content types
|
|
|
|
add_content_type_webform_manager (a_manager: CMS_CONTENT_TYPE_WEBFORM_MANAGER)
|
|
-- Register webform manager `a_manager'.
|
|
do
|
|
content_type_webform_managers.force (a_manager)
|
|
end
|
|
|
|
content_type_webform_manager (a_content_type: CMS_CONTENT_TYPE): detachable CMS_CONTENT_TYPE_WEBFORM_MANAGER
|
|
-- Web form manager for content type `a_content_type' if any.
|
|
local
|
|
l_type_name: READABLE_STRING_GENERAL
|
|
do
|
|
l_type_name := a_content_type.name
|
|
across
|
|
content_type_webform_managers as ic
|
|
until
|
|
Result /= Void
|
|
loop
|
|
Result := ic.item
|
|
if not l_type_name.is_case_insensitive_equal (Result.name) then
|
|
Result := Void
|
|
end
|
|
end
|
|
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.path_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
|
|
|
|
trashed_nodes (a_user: CMS_USER): LIST [CMS_NODE]
|
|
-- List of nodes with status in {CMS_NODE_API}.trashed.
|
|
-- if the current user is admin, it will retrieve all the trashed nodes
|
|
do
|
|
Result := node_storage.trashed_nodes (a_user.id)
|
|
end
|
|
|
|
recent_nodes (params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_NODE]
|
|
-- List of the `a_rows' most recent nodes starting from `a_offset'.
|
|
do
|
|
Result := node_storage.recent_nodes (params.offset.to_integer_32, params.size.to_integer_32)
|
|
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))
|
|
end
|
|
|
|
full_node (a_node: detachable CMS_NODE): detachable CMS_NODE
|
|
-- If `a_node' is partial, return the full node from `a_node',
|
|
-- otherwise return directly `a_node'.
|
|
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
|
|
else
|
|
Result := a_node
|
|
end
|
|
|
|
-- Update link with aliasing.
|
|
if a_node /= Void and then a_node.has_id then
|
|
a_node.set_link (node_link (a_node))
|
|
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
|
|
|
|
is_author_of_node (u: CMS_USER; a_node: CMS_NODE): BOOLEAN
|
|
-- Is the user `u' owner of the node `n'.
|
|
do
|
|
if attached node_storage.node_author (a_node.id) as l_author then
|
|
Result := u.same_as (l_author)
|
|
end
|
|
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'.
|
|
do
|
|
node_storage.save_node (a_node)
|
|
end
|
|
|
|
new_node (a_node: CMS_NODE)
|
|
-- Add a new node `a_node'
|
|
require
|
|
no_id: not a_node.has_id
|
|
do
|
|
node_storage.new_node (a_node)
|
|
end
|
|
|
|
delete_node (a_node: CMS_NODE)
|
|
-- Delete `a_node'.
|
|
do
|
|
if a_node.has_id then
|
|
node_storage.delete_node (a_node)
|
|
end
|
|
end
|
|
|
|
update_node (a_node: CMS_NODE)
|
|
-- Update node `a_node' data.
|
|
do
|
|
node_storage.update_node (a_node)
|
|
end
|
|
|
|
trash_node (a_node: CMS_NODE)
|
|
-- Trash node `a_node'.
|
|
--! remove the node from the storage.
|
|
do
|
|
node_storage.trash_node (a_node)
|
|
end
|
|
|
|
|
|
restore_node (a_node: CMS_NODE)
|
|
-- Restore node `a_node'.
|
|
-- From {CMS_NODE_API}.trashed to {CMS_NODE_API}.not_published.
|
|
do
|
|
node_storage.restore_node (a_node)
|
|
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
|