Moved src/modules under modules cluster.
This commit is contained in:
42
modules/node/cms_content_type.e
Normal file
42
modules/node/cms_content_type.e
Normal file
@@ -0,0 +1,42 @@
|
||||
note
|
||||
description: "[
|
||||
Interface defining a CMS content type.
|
||||
]"
|
||||
status: "draft"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_CONTENT_TYPE
|
||||
|
||||
inherit
|
||||
CMS_API_ACCESS
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: READABLE_STRING_8
|
||||
-- Internal name.
|
||||
deferred
|
||||
end
|
||||
|
||||
title: READABLE_STRING_32
|
||||
-- Human readable name.
|
||||
deferred
|
||||
end
|
||||
|
||||
description: detachable READABLE_STRING_32
|
||||
-- Optional description
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
available_formats: LIST [CONTENT_FORMAT]
|
||||
-- Available formats for Current type.
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
310
modules/node/cms_node_api.e
Normal file
310
modules/node/cms_node_api.e
Normal file
@@ -0,0 +1,310 @@
|
||||
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
|
||||
make
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
initialize
|
||||
-- <Precursor>
|
||||
do
|
||||
Precursor
|
||||
if attached {CMS_STORAGE_SQL_I} storage as l_storage_sql then
|
||||
create {CMS_NODE_STORAGE_SQL} node_storage.make (l_storage_sql)
|
||||
else
|
||||
create {CMS_NODE_STORAGE_NULL} node_storage.make
|
||||
end
|
||||
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_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: INTEGER_64
|
||||
do
|
||||
Result := node_storage.nodes_count
|
||||
end
|
||||
|
||||
nodes: LIST [CMS_NODE]
|
||||
-- List of nodes.
|
||||
do
|
||||
Result := node_storage.nodes
|
||||
end
|
||||
|
||||
recent_nodes (a_offset, a_rows: INTEGER): LIST [CMS_NODE]
|
||||
-- List of the `a_rows' most recent nodes starting from `a_offset'.
|
||||
do
|
||||
Result := node_storage.recent_nodes (a_offset, a_rows)
|
||||
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 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
|
||||
|
||||
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
|
||||
|
||||
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||
-- -- Update node title, with user identified by `a_id', with node id `a_node_id' and a new title `a_title'.
|
||||
-- do
|
||||
-- debug ("refactor_fixme")
|
||||
-- fixme ("Check preconditions")
|
||||
-- end
|
||||
-- node_storage.update_node_title (a_user_id, a_node_id, a_title)
|
||||
-- end
|
||||
|
||||
-- update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||
-- -- Update node summary, with user identified by `a_user_id', with node id `a_node_id' and a new summary `a_summary'.
|
||||
-- do
|
||||
-- debug ("refactor_fixme")
|
||||
-- fixme ("Check preconditions")
|
||||
-- end
|
||||
-- node_storage.update_node_summary (a_user_id, a_node_id, a_summary)
|
||||
-- end
|
||||
|
||||
-- update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||
-- -- Update node content, with user identified by `a_user_id', with node id `a_node_id' and a new content `a_content'.
|
||||
-- do
|
||||
-- debug ("refactor_fixme")
|
||||
-- fixme ("Check preconditions")
|
||||
-- end
|
||||
-- node_storage.update_node_content (a_user_id, a_node_id, a_content)
|
||||
-- end
|
||||
|
||||
|
||||
end
|
||||
30
modules/node/cms_node_type.e
Normal file
30
modules/node/cms_node_type.e
Normal file
@@ -0,0 +1,30 @@
|
||||
note
|
||||
description: "[
|
||||
Interface defining a CMS content type.
|
||||
]"
|
||||
status: "draft"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_NODE_TYPE [G -> CMS_NODE]
|
||||
|
||||
inherit
|
||||
CMS_CONTENT_TYPE
|
||||
|
||||
feature -- Factory
|
||||
|
||||
new_node_with_title (a_title: READABLE_STRING_32; a_partial_node: detachable CMS_NODE): like new_node
|
||||
-- New node with `a_title' and fill from partial `a_partial_node' if set.
|
||||
deferred
|
||||
end
|
||||
|
||||
new_node (a_partial_node: detachable CMS_NODE): G
|
||||
-- New node based on partial `a_partial_node' if set.
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
217
modules/node/content/cms_node.e
Normal file
217
modules/node/content/cms_node.e
Normal file
@@ -0,0 +1,217 @@
|
||||
note
|
||||
description: "[
|
||||
CMS abstraction for CMS content entity, named "node".
|
||||
]"
|
||||
status: "draft"
|
||||
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||
revision: "$Revision: 96542 $"
|
||||
|
||||
deferred class
|
||||
CMS_NODE
|
||||
|
||||
inherit
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
--create
|
||||
-- make,
|
||||
-- make_empty
|
||||
|
||||
feature{NONE} -- Initialization
|
||||
|
||||
make_empty
|
||||
-- Create empty node.
|
||||
do
|
||||
make ({STRING_32} "")
|
||||
end
|
||||
|
||||
make (a_title: READABLE_STRING_32)
|
||||
-- Create current node with `a_title'.
|
||||
local
|
||||
l_time: DATE_TIME
|
||||
do
|
||||
create l_time.make_now_utc
|
||||
set_title (a_title)
|
||||
set_creation_date (l_time)
|
||||
set_modification_date (l_time)
|
||||
set_publication_date (l_time)
|
||||
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Remove default harcoded format")
|
||||
end
|
||||
ensure
|
||||
title_set: title = a_title
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
import_node (a_node: CMS_NODE)
|
||||
-- Import `a_node' into current node.
|
||||
do
|
||||
set_id (a_node.id)
|
||||
set_revision (a_node.revision)
|
||||
set_title (a_node.title)
|
||||
set_creation_date (a_node.creation_date)
|
||||
set_modification_date (a_node.modification_date)
|
||||
set_publication_date (a_node.publication_date)
|
||||
set_author (a_node.author)
|
||||
set_content (
|
||||
a_node.content,
|
||||
a_node.summary,
|
||||
a_node.format
|
||||
)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
id: INTEGER_64 assign set_id
|
||||
-- Unique id.
|
||||
--| Should we use NATURAL_64 instead?
|
||||
|
||||
revision: INTEGER_64 assign set_revision
|
||||
-- Revision value.
|
||||
--| Note: for now version is not supported.
|
||||
|
||||
content_type: READABLE_STRING_8
|
||||
-- Associated content type name.
|
||||
-- Page, Article, Blog, News, etc.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
title: READABLE_STRING_32
|
||||
-- Full title of the node.
|
||||
-- Required!
|
||||
|
||||
summary: detachable READABLE_STRING_8
|
||||
-- A short summary of the node.
|
||||
deferred
|
||||
end
|
||||
|
||||
content: detachable READABLE_STRING_8
|
||||
-- Content of the node.
|
||||
deferred
|
||||
end
|
||||
|
||||
format: detachable READABLE_STRING_8
|
||||
-- Format associated with `content' and `summary'.
|
||||
-- For example: text, mediawiki, html, etc
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access: date
|
||||
|
||||
modification_date: DATE_TIME
|
||||
-- When the node was updated.
|
||||
|
||||
creation_date: DATE_TIME
|
||||
-- When the node was created.
|
||||
|
||||
publication_date: DATE_TIME
|
||||
-- When the node was published.
|
||||
|
||||
publication_date_output: READABLE_STRING_32
|
||||
-- Formatted output.
|
||||
|
||||
feature -- Access: author
|
||||
|
||||
author: detachable CMS_USER
|
||||
-- Author of current node.
|
||||
|
||||
feature -- status report
|
||||
|
||||
has_id: BOOLEAN
|
||||
-- Has unique identifier?
|
||||
do
|
||||
Result := id > 0
|
||||
end
|
||||
|
||||
same_node (a_node: CMS_NODE): BOOLEAN
|
||||
-- Is `a_node' same node as Current?
|
||||
do
|
||||
-- FIXME: if we introduce notion of revision, update this part!
|
||||
Result := Current = a_node or id = a_node.id
|
||||
ensure
|
||||
valid_result: Result implies a_node.id = id
|
||||
end
|
||||
|
||||
is_typed_as (a_content_type: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is current node of type `a_content_type' ?
|
||||
do
|
||||
Result := a_content_type.is_case_insensitive_equal (content_type)
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_content (a_content: like content; a_summary: like summary; a_format: like format)
|
||||
-- Set `content', `summary' and `format' to `a_content', `a_summary' and `a_format'.
|
||||
-- The `format' is associated with both `content' and `summary'
|
||||
deferred
|
||||
ensure
|
||||
content_assigned: content = a_content
|
||||
summary_assigned: summary = a_summary
|
||||
format_assigned: format = a_format
|
||||
end
|
||||
|
||||
set_title (a_title: like title)
|
||||
-- Assign `title' with `a_title'.
|
||||
do
|
||||
title := a_title
|
||||
ensure
|
||||
title_assigned: title = a_title
|
||||
end
|
||||
|
||||
set_modification_date (a_modification_date: like modification_date)
|
||||
-- Assign `modification_date' with `a_modification_date'.
|
||||
do
|
||||
modification_date := a_modification_date
|
||||
ensure
|
||||
modification_date_assigned: modification_date = a_modification_date
|
||||
end
|
||||
|
||||
set_creation_date (a_creation_date: like creation_date)
|
||||
-- Assign `creation_date' with `a_creation_date'.
|
||||
do
|
||||
creation_date := a_creation_date
|
||||
ensure
|
||||
creation_date_assigned: creation_date = a_creation_date
|
||||
end
|
||||
|
||||
set_publication_date (a_publication_date: like publication_date)
|
||||
-- Assign `publication_date' with `a_publication_date'.
|
||||
do
|
||||
publication_date := a_publication_date
|
||||
publication_date_output := publication_date.formatted_out ("yyyy/[0]mm/[0]dd")
|
||||
ensure
|
||||
publication_date_assigned: publication_date = a_publication_date
|
||||
end
|
||||
|
||||
set_id (a_id: like id)
|
||||
-- Assign `id' with `a_id'.
|
||||
do
|
||||
id := a_id
|
||||
ensure
|
||||
id_assigned: id = a_id
|
||||
end
|
||||
|
||||
set_revision (a_revision: like revision)
|
||||
-- Assign `revision' with `a_revision'.
|
||||
do
|
||||
revision := a_revision
|
||||
ensure
|
||||
revision_assigned: revision = a_revision
|
||||
end
|
||||
|
||||
set_author (u: like author)
|
||||
-- Assign 'author' with `u'
|
||||
do
|
||||
author := u
|
||||
ensure
|
||||
auther_set: author = u
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
85
modules/node/content/cms_partial_node.e
Normal file
85
modules/node/content/cms_partial_node.e
Normal file
@@ -0,0 +1,85 @@
|
||||
note
|
||||
description: "Node object representing the CMS_NODE data in database."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_PARTIAL_NODE
|
||||
|
||||
inherit
|
||||
CMS_NODE
|
||||
rename
|
||||
make_empty as make_empty_node,
|
||||
set_content as set_all_content
|
||||
end
|
||||
|
||||
create
|
||||
make_empty
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_empty (a_content_type: READABLE_STRING_8)
|
||||
require
|
||||
type_not_blank: not a_content_type.is_whitespace
|
||||
do
|
||||
content_type := a_content_type
|
||||
make_empty_node
|
||||
end
|
||||
|
||||
feature -- Access: code
|
||||
|
||||
content_type: READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access: content
|
||||
|
||||
summary: detachable READABLE_STRING_8
|
||||
-- A short summary of the node.
|
||||
|
||||
content: detachable READABLE_STRING_8
|
||||
-- Content of the node.
|
||||
|
||||
format: detachable READABLE_STRING_8
|
||||
-- Format associated with `content' and `summary'.
|
||||
-- For example: text, mediawiki, html, etc
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_all_content (a_content: like content; a_summary: like summary; a_format: like format)
|
||||
-- <Precursor>
|
||||
do
|
||||
set_content (a_content)
|
||||
set_summary (a_summary)
|
||||
set_format (a_format)
|
||||
end
|
||||
|
||||
set_content (a_content: like content)
|
||||
-- Assign `content' with `a_content', and set the associated `format'.
|
||||
do
|
||||
content := a_content
|
||||
ensure
|
||||
content_assigned: content = a_content
|
||||
end
|
||||
|
||||
set_summary (a_summary: like summary)
|
||||
-- Assign `summary' with `a_summary'.
|
||||
do
|
||||
summary := a_summary
|
||||
ensure
|
||||
summary_assigned: summary = a_summary
|
||||
end
|
||||
|
||||
set_format (a_format: like format)
|
||||
-- Assign `format' with `a_format'.
|
||||
do
|
||||
format := a_format
|
||||
ensure
|
||||
format_assigned: format = a_format
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
95
modules/node/content_type/cms_page.e
Normal file
95
modules/node/content_type/cms_page.e
Normal file
@@ -0,0 +1,95 @@
|
||||
note
|
||||
description: "A page node."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_PAGE
|
||||
|
||||
inherit
|
||||
CMS_NODE
|
||||
redefine
|
||||
make_empty,
|
||||
import_node
|
||||
end
|
||||
|
||||
create
|
||||
make_empty,
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_empty
|
||||
do
|
||||
Precursor
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
import_node (a_node: CMS_NODE)
|
||||
-- <Precursor>
|
||||
do
|
||||
Precursor (a_node)
|
||||
if attached {CMS_PAGE} a_node as l_page then
|
||||
set_parent (l_page.parent)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: READABLE_STRING_8
|
||||
once
|
||||
Result := {CMS_PAGE_NODE_TYPE}.name
|
||||
end
|
||||
|
||||
feature -- Access: content
|
||||
|
||||
summary: detachable READABLE_STRING_8
|
||||
-- A short summary of the node.
|
||||
|
||||
content: detachable READABLE_STRING_8
|
||||
-- Content of the node.
|
||||
|
||||
format: detachable READABLE_STRING_8
|
||||
-- Format associated with `content' and `summary'.
|
||||
-- For example: text, mediawiki, html, etc
|
||||
|
||||
parent: detachable CMS_PAGE
|
||||
-- Eventual parent page.
|
||||
--| Used to describe a book structure.
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_content (a_content: like content; a_summary: like summary; a_format: like format)
|
||||
do
|
||||
content := a_content
|
||||
summary := a_summary
|
||||
format := a_format
|
||||
end
|
||||
|
||||
set_parent (a_page: detachable CMS_PAGE)
|
||||
-- Set `parent' to `a_page'
|
||||
require
|
||||
Current_is_not_parent_of_a_page: not is_parent_of (a_page)
|
||||
do
|
||||
parent := a_page
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_parent_of (a_page: detachable CMS_PAGE): BOOLEAN
|
||||
-- Is Current page, a parent of `a_page' ?
|
||||
do
|
||||
if
|
||||
a_page /= Void and then
|
||||
attached a_page.parent as l_parent
|
||||
then
|
||||
if l_parent.same_node (a_page) then
|
||||
Result := True
|
||||
else
|
||||
Result := is_parent_of (l_parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
63
modules/node/content_type/cms_page_node_type.e
Normal file
63
modules/node/content_type/cms_page_node_type.e
Normal file
@@ -0,0 +1,63 @@
|
||||
note
|
||||
description: "Summary description for {CMS_PAGE_NODE_TYPE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_PAGE_NODE_TYPE
|
||||
|
||||
inherit
|
||||
CMS_NODE_TYPE [CMS_PAGE]
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
do
|
||||
Precursor
|
||||
create {ARRAYED_LIST [like available_formats.item]} available_formats.make (3)
|
||||
available_formats.extend (create {PLAIN_TEXT_CONTENT_FORMAT})
|
||||
available_formats.extend (create {FILTERED_HTML_CONTENT_FORMAT})
|
||||
available_formats.extend (create {FULL_HTML_CONTENT_FORMAT})
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "page"
|
||||
-- Internal name.
|
||||
|
||||
title: STRING_32 = "Page"
|
||||
-- Human readable name.
|
||||
|
||||
description: STRING_32 = "Use basic pages for your content, such as an 'About us' page."
|
||||
-- Optional description
|
||||
|
||||
feature -- Access
|
||||
|
||||
available_formats: LIST [CONTENT_FORMAT]
|
||||
-- Available formats for Current type.
|
||||
|
||||
feature -- Factory
|
||||
|
||||
new_node_with_title (a_title: READABLE_STRING_32; a_partial_node: detachable CMS_NODE): like new_node
|
||||
-- New node with `a_title' and fill from partial `a_partial_node' if set.
|
||||
do
|
||||
create Result.make (a_title)
|
||||
if a_partial_node /= Void then
|
||||
Result.import_node (a_partial_node)
|
||||
Result.set_title (a_title)
|
||||
end
|
||||
end
|
||||
|
||||
new_node (a_partial_node: detachable CMS_NODE): CMS_PAGE
|
||||
-- New node based on partial `a_partial_node', or from none.
|
||||
do
|
||||
create Result.make_empty
|
||||
if a_partial_node /= Void then
|
||||
Result.import_node (a_partial_node)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
17
modules/node/content_type/cms_partial_page.e
Normal file
17
modules/node/content_type/cms_partial_page.e
Normal file
@@ -0,0 +1,17 @@
|
||||
note
|
||||
description: "Summary description for {CMS_PARTIAL_PAGE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_PARTIAL_PAGE
|
||||
|
||||
inherit
|
||||
CMS_PAGE
|
||||
|
||||
create
|
||||
make_empty,
|
||||
make
|
||||
|
||||
end
|
||||
33
modules/node/handler/cms_content_type_webform_manager.e
Normal file
33
modules/node/handler/cms_content_type_webform_manager.e
Normal file
@@ -0,0 +1,33 @@
|
||||
note
|
||||
description: "[
|
||||
Html builder for content type `content_type'.
|
||||
This is used to build webform and html output for a specific node, or node content type.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_CONTENT_TYPE_WEBFORM_MANAGER
|
||||
|
||||
inherit
|
||||
CMS_API_ACCESS
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_type: like content_type)
|
||||
do
|
||||
content_type := a_type
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: CMS_CONTENT_TYPE
|
||||
-- Associated content type.
|
||||
|
||||
name: READABLE_STRING_8
|
||||
-- Associated content type name.
|
||||
do
|
||||
Result := content_type.name
|
||||
end
|
||||
|
||||
end
|
||||
16
modules/node/handler/cms_node_handler.e
Normal file
16
modules/node/handler/cms_node_handler.e
Normal file
@@ -0,0 +1,16 @@
|
||||
note
|
||||
description: "Summary description for {CMS_NODE_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
deferred class
|
||||
CMS_NODE_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_MODULE_HANDLER [CMS_NODE_API]
|
||||
rename
|
||||
module_api as node_api
|
||||
end
|
||||
|
||||
end
|
||||
199
modules/node/handler/cms_node_type_webform_manager.e
Normal file
199
modules/node/handler/cms_node_type_webform_manager.e
Normal file
@@ -0,0 +1,199 @@
|
||||
note
|
||||
description: "Summary description for {CMS_NODE_TYPE_WEBFORM_MANAGER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_NODE_TYPE_WEBFORM_MANAGER [G -> CMS_NODE]
|
||||
|
||||
inherit
|
||||
CMS_NODE_TYPE_WEBFORM_MANAGER_I [G]
|
||||
|
||||
feature -- Forms ...
|
||||
|
||||
populate_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
fset: WSF_FORM_FIELD_SET
|
||||
ta: WSF_FORM_TEXTAREA
|
||||
tselect: WSF_FORM_SELECT
|
||||
opt: WSF_FORM_SELECT_OPTION
|
||||
do
|
||||
create ti.make ("title")
|
||||
ti.set_label ("Title")
|
||||
ti.set_size (70)
|
||||
if a_node /= Void then
|
||||
ti.set_text_value (a_node.title)
|
||||
end
|
||||
ti.set_is_required (True)
|
||||
f.extend (ti)
|
||||
|
||||
f.extend_html_text ("<br/>")
|
||||
|
||||
create ta.make ("body")
|
||||
ta.set_rows (10)
|
||||
ta.set_cols (70)
|
||||
if a_node /= Void then
|
||||
ta.set_text_value (a_node.content)
|
||||
end
|
||||
-- ta.set_label ("Body")
|
||||
ta.set_description ("This is the main content")
|
||||
ta.set_is_required (False)
|
||||
|
||||
create fset.make
|
||||
fset.set_legend ("Body")
|
||||
fset.extend (ta)
|
||||
|
||||
fset.extend_html_text ("<br/>")
|
||||
|
||||
create tselect.make ("format")
|
||||
tselect.set_label ("Body's format")
|
||||
tselect.set_is_required (True)
|
||||
across
|
||||
content_type.available_formats as c
|
||||
loop
|
||||
create opt.make (c.item.name, c.item.title)
|
||||
if attached c.item.html_help as f_help then
|
||||
opt.set_description ("<ul>" + f_help + "</ul>")
|
||||
end
|
||||
tselect.add_option (opt)
|
||||
end
|
||||
if a_node /= Void and then attached a_node.format as l_format then
|
||||
tselect.set_text_by_value (l_format)
|
||||
end
|
||||
|
||||
fset.extend (tselect)
|
||||
|
||||
f.extend (fset)
|
||||
end
|
||||
|
||||
update_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: CMS_NODE)
|
||||
local
|
||||
b: detachable READABLE_STRING_8
|
||||
f: detachable CONTENT_FORMAT
|
||||
do
|
||||
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
check a_node.id = l_id end
|
||||
end
|
||||
if attached fd.string_item ("title") as l_title then
|
||||
a_node.set_title (l_title)
|
||||
end
|
||||
|
||||
if attached fd.string_item ("body") as l_body then
|
||||
b := l_body
|
||||
end
|
||||
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
else
|
||||
f := response.api.formats.default_format
|
||||
end
|
||||
if b /= Void then
|
||||
a_node.set_content (b, Void, f.name) -- FIXME: summary
|
||||
end
|
||||
end
|
||||
|
||||
new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable CMS_NODE): G
|
||||
-- <Precursor>
|
||||
local
|
||||
b: detachable READABLE_STRING_8
|
||||
f: detachable CONTENT_FORMAT
|
||||
l_node: detachable like new_node
|
||||
do
|
||||
if attached {like new_node} a_node as l_arg_node then
|
||||
l_node := l_arg_node
|
||||
else
|
||||
l_node := content_type.new_node (a_node)
|
||||
end
|
||||
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
if l_node /= Void then
|
||||
check l_node.id = l_id end
|
||||
else
|
||||
if attached {like new_node} response.node_api.node (l_id) as n then
|
||||
l_node := n
|
||||
else
|
||||
-- FIXME: Error
|
||||
end
|
||||
end
|
||||
end
|
||||
if attached fd.string_item ("title") as l_title then
|
||||
if l_node = Void then
|
||||
l_node := content_type.new_node (Void)
|
||||
l_node.set_title (l_title)
|
||||
else
|
||||
l_node.set_title (l_title)
|
||||
end
|
||||
else
|
||||
if l_node = Void then
|
||||
l_node := content_type.new_node_with_title ("...", Void)
|
||||
end
|
||||
end
|
||||
l_node.set_author (response.user)
|
||||
|
||||
if attached fd.string_item ("body") as l_body then
|
||||
b := l_body
|
||||
end
|
||||
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
else
|
||||
f := response.api.formats.default_format
|
||||
end
|
||||
if b /= Void then
|
||||
l_node.set_content (b, Void, f.name)
|
||||
end
|
||||
Result := l_node
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
append_html_output_to (a_node: CMS_NODE; a_response: NODE_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
hdate: HTTP_DATE
|
||||
s: STRING
|
||||
node_api: CMS_NODE_API
|
||||
do
|
||||
node_api := a_response.node_api
|
||||
|
||||
a_response.add_variable (a_node, "node")
|
||||
create lnk.make ("View", node_api.node_path (a_node))
|
||||
lnk.set_weight (1)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
create lnk.make ("Edit", node_api.node_path (a_node) + "/edit")
|
||||
lnk.set_weight (2)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
|
||||
create s.make_empty
|
||||
s.append ("<div class=%"info%"> ")
|
||||
if attached a_node.author as l_author then
|
||||
s.append (" by ")
|
||||
s.append (l_author.name)
|
||||
end
|
||||
if attached a_node.modification_date as l_modified then
|
||||
s.append (" (modified: ")
|
||||
create hdate.make_from_date_time (l_modified)
|
||||
s.append (hdate.yyyy_mmm_dd_string)
|
||||
s.append (")")
|
||||
end
|
||||
s.append ("</div>")
|
||||
if attached a_node.content as l_content then
|
||||
s.append ("<p class=%"content%">")
|
||||
if attached node_api.cms_api.format (a_node.format) as f then
|
||||
s.append (f.formatted_output (l_content))
|
||||
else
|
||||
s.append (node_api.cms_api.formats.default_format.formatted_output (l_content))
|
||||
end
|
||||
|
||||
s.append ("</p>")
|
||||
end
|
||||
|
||||
a_response.set_title (a_node.title)
|
||||
a_response.set_main_content (s)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
67
modules/node/handler/cms_node_type_webform_manager_i.e
Normal file
67
modules/node/handler/cms_node_type_webform_manager_i.e
Normal file
@@ -0,0 +1,67 @@
|
||||
note
|
||||
description: "[
|
||||
Html builder for content type `content_type'.
|
||||
This is used to build webform and html output for a specific node, or node content type.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_NODE_TYPE_WEBFORM_MANAGER_I [G -> CMS_NODE]
|
||||
|
||||
inherit
|
||||
CMS_CONTENT_TYPE_WEBFORM_MANAGER
|
||||
redefine
|
||||
content_type
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: CMS_NODE_TYPE [G]
|
||||
-- Associated content type.
|
||||
|
||||
feature -- Query
|
||||
|
||||
has_valid_node_type (a_node: CMS_NODE): BOOLEAN
|
||||
-- Accept `a_node' for Current operations.
|
||||
do
|
||||
Result := attached {like new_node} a_node
|
||||
end
|
||||
|
||||
feature -- Forms ...
|
||||
|
||||
populate_form (response: NODE_RESPONSE; a_form: WSF_FORM; a_node: detachable CMS_NODE)
|
||||
-- Fill the web form `a_form' with data from `a_node' if set.
|
||||
require
|
||||
a_node = Void or else has_valid_node_type (a_node)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Node ...
|
||||
|
||||
new_node (response: NODE_RESPONSE; a_form_data: WSF_FORM_DATA; a_node: detachable CMS_NODE): G
|
||||
-- New typed node with data from `a_form_data', and eventually data from `a_node' if set.
|
||||
require
|
||||
a_node = Void or else has_valid_node_type (a_node)
|
||||
deferred
|
||||
--| Possible implementation:
|
||||
--| Result := content_type.new_node (a_node)
|
||||
end
|
||||
|
||||
update_node (response: NODE_RESPONSE; a_form_data: WSF_FORM_DATA; a_node: CMS_NODE)
|
||||
-- Update node `a_node' with data from `a_form_data'.
|
||||
require
|
||||
has_valid_node_type (a_node)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
append_html_output_to (a_node: CMS_NODE; a_response: NODE_RESPONSE)
|
||||
-- Append an html representation of `a_node' to response `a_response'.
|
||||
require
|
||||
has_valid_node_type (a_node)
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
185
modules/node/handler/cms_page_node_type_webform_manager.e
Normal file
185
modules/node/handler/cms_page_node_type_webform_manager.e
Normal file
@@ -0,0 +1,185 @@
|
||||
note
|
||||
description: "Summary description for {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER
|
||||
|
||||
inherit
|
||||
CMS_NODE_TYPE_WEBFORM_MANAGER [CMS_PAGE]
|
||||
redefine
|
||||
content_type,
|
||||
append_html_output_to
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: CMS_PAGE_NODE_TYPE
|
||||
-- Associated content type.
|
||||
|
||||
feature -- Forms ...
|
||||
|
||||
-- fill_edit_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
|
||||
-- local
|
||||
-- ti: WSF_FORM_TEXT_INPUT
|
||||
-- fset: WSF_FORM_FIELD_SET
|
||||
-- ta: WSF_FORM_TEXTAREA
|
||||
-- tselect: WSF_FORM_SELECT
|
||||
-- opt: WSF_FORM_SELECT_OPTION
|
||||
-- do
|
||||
-- create ti.make ("title")
|
||||
-- ti.set_label ("Title")
|
||||
-- ti.set_size (70)
|
||||
-- if a_node /= Void then
|
||||
-- ti.set_text_value (a_node.title)
|
||||
-- end
|
||||
-- ti.set_is_required (True)
|
||||
-- f.extend (ti)
|
||||
|
||||
-- f.extend_html_text ("<br/>")
|
||||
|
||||
-- create ta.make ("body")
|
||||
-- ta.set_rows (10)
|
||||
-- ta.set_cols (70)
|
||||
-- if a_node /= Void then
|
||||
-- ta.set_text_value (a_node.content)
|
||||
-- end
|
||||
---- ta.set_label ("Body")
|
||||
-- ta.set_description ("This is the main content")
|
||||
-- ta.set_is_required (False)
|
||||
|
||||
-- create fset.make
|
||||
-- fset.set_legend ("Body")
|
||||
-- fset.extend (ta)
|
||||
|
||||
-- fset.extend_html_text ("<br/>")
|
||||
|
||||
-- create tselect.make ("format")
|
||||
-- tselect.set_label ("Body's format")
|
||||
-- tselect.set_is_required (True)
|
||||
-- across
|
||||
-- content_type.available_formats as c
|
||||
-- loop
|
||||
-- create opt.make (c.item.name, c.item.title)
|
||||
-- if attached c.item.html_help as f_help then
|
||||
-- opt.set_description ("<ul>" + f_help + "</ul>")
|
||||
-- end
|
||||
-- tselect.add_option (opt)
|
||||
-- end
|
||||
-- if a_node /= Void and then attached a_node.format as l_format then
|
||||
-- tselect.set_text_by_value (l_format)
|
||||
-- end
|
||||
|
||||
-- fset.extend (tselect)
|
||||
|
||||
-- f.extend (fset)
|
||||
|
||||
-- end
|
||||
|
||||
-- change_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: like new_node)
|
||||
-- local
|
||||
-- b: detachable READABLE_STRING_8
|
||||
-- f: detachable CONTENT_FORMAT
|
||||
-- do
|
||||
-- if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
-- check a_node.id = l_id end
|
||||
-- end
|
||||
-- if attached fd.string_item ("title") as l_title then
|
||||
-- a_node.set_title (l_title)
|
||||
-- end
|
||||
|
||||
-- if attached fd.string_item ("body") as l_body then
|
||||
-- b := l_body
|
||||
-- end
|
||||
-- if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- else
|
||||
-- f := response.api.formats.default_format
|
||||
-- end
|
||||
-- if b /= Void then
|
||||
-- a_node.set_content (b, Void, f.name) -- FIXME: summary
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable like new_node): CMS_PAGE
|
||||
-- -- <Precursor>
|
||||
-- local
|
||||
-- b: detachable READABLE_STRING_8
|
||||
-- f: detachable CONTENT_FORMAT
|
||||
-- l_node: detachable like new_node
|
||||
-- do
|
||||
-- l_node := a_node
|
||||
-- if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
-- if l_node /= Void then
|
||||
-- check l_node.id = l_id end
|
||||
-- else
|
||||
-- if attached {like new_node} response.node_api.node (l_id) as n then
|
||||
-- l_node := n
|
||||
-- else
|
||||
-- -- FIXME: Error
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- if attached fd.string_item ("title") as l_title then
|
||||
-- if l_node = Void then
|
||||
-- l_node := content_type.new_node (Void)
|
||||
-- l_node.set_title (l_title)
|
||||
-- else
|
||||
-- l_node.set_title (l_title)
|
||||
-- end
|
||||
-- else
|
||||
-- if l_node = Void then
|
||||
-- l_node := content_type.new_node_with_title ("...", Void)
|
||||
-- end
|
||||
-- end
|
||||
-- l_node.set_author (response.user)
|
||||
|
||||
-- if attached fd.string_item ("body") as l_body then
|
||||
-- b := l_body
|
||||
-- end
|
||||
-- if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- else
|
||||
-- f := response.api.formats.default_format
|
||||
-- end
|
||||
-- if b /= Void then
|
||||
-- l_node.set_content (b, Void, f.name)
|
||||
-- end
|
||||
-- Result := l_node
|
||||
-- end
|
||||
|
||||
feature -- Output
|
||||
|
||||
append_html_output_to (a_node: CMS_NODE; a_response: NODE_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
Precursor (a_node, a_response)
|
||||
if attached a_response.main_content as l_main_content then
|
||||
s := l_main_content
|
||||
else
|
||||
create s.make_empty
|
||||
end
|
||||
|
||||
if attached {CMS_PAGE} a_node as l_node_page then
|
||||
if attached l_node_page.parent as l_parent_node then
|
||||
s.append ("<div>Parent page is ")
|
||||
s.append (a_response.link (l_parent_node.title + " (#" + l_parent_node.id.out + ")", a_response.node_api.node_path (l_parent_node), Void))
|
||||
s.append ("</div>")
|
||||
end
|
||||
end
|
||||
|
||||
a_response.set_main_content (s)
|
||||
end
|
||||
|
||||
end
|
||||
167
modules/node/handler/experimental/node_content_handler.e
Normal file
167
modules/node/handler/experimental/node_content_handler.e
Normal file
@@ -0,0 +1,167 @@
|
||||
note
|
||||
description: "Summary description for {NEW_CONTENT_HANDLER}."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
NODE_CONTENT_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
|
||||
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 -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
if attached current_user_name (req) then
|
||||
-- Existing node
|
||||
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
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (l_node.content, "node_content")
|
||||
l_page.add_variable (l_id.value, "id")
|
||||
l_page.execute
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user_name (req) 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 attached {WSF_STRING} req.form_parameter ("method") as l_method then
|
||||
if l_method.is_case_insensitive_equal ("PUT") then
|
||||
do_put (req, res)
|
||||
else
|
||||
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
do
|
||||
to_implement ("Check if user has permissions")
|
||||
if attached current_user (req) 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
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_id (l_id.value.to_integer_64)
|
||||
node_api.update_node_content (l_user.id, u_node.id, u_node.content)
|
||||
redirect_to (req.absolute_script_url (""), res)
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
|
||||
if a_id.is_integer then
|
||||
-- resource not found
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
|
||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
do
|
||||
create Result.make ("", "", "")
|
||||
if attached {WSF_STRING}req.form_parameter ("content") as l_content then
|
||||
Result.set_content (l_content.value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
240
modules/node/handler/experimental/node_resource_handler.e
Normal file
240
modules/node/handler/experimental/node_resource_handler.e
Normal file
@@ -0,0 +1,240 @@
|
||||
note
|
||||
description: "Node handler for the API."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
NODE_RESOURCE_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 -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
-- Existing node
|
||||
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.value.to_integer_64) as l_node
|
||||
then
|
||||
-- FIXME: there is a mix between CMS interface and API interface here.
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (l_node, "node")
|
||||
l_page.execute
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
-- Factory
|
||||
new_node (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
do
|
||||
to_implement ("Check user permissions!!!")
|
||||
if attached current_user (req) 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.value.to_integer_64) as l_node
|
||||
then
|
||||
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
|
||||
if l_method.is_case_insensitive_equal ("DELETE") then
|
||||
do_delete (req, res)
|
||||
elseif l_method.is_case_insensitive_equal ("PUT") then
|
||||
do_put (req, res)
|
||||
else
|
||||
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
end
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
-- New node
|
||||
-- FIXME !!!
|
||||
if attached {WSF_STRING} req.form_parameter ("type") as p_type then
|
||||
if attached node_api.content_type (p_type.value) as ct then
|
||||
end
|
||||
create {CMS_PARTIAL_NODE} u_node.make_empty (p_type.url_encoded_value)
|
||||
else
|
||||
create {CMS_PARTIAL_NODE} u_node.make_empty ("")
|
||||
end
|
||||
|
||||
update_node_from_data_form (req, u_node)
|
||||
u_node.set_author (l_user)
|
||||
node_api.new_node (u_node)
|
||||
redirect_to (req.absolute_script_url (""), res)
|
||||
end
|
||||
else
|
||||
send_access_denied (res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
|
||||
if attached current_user (req) 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.value.to_integer_64) as l_node
|
||||
then
|
||||
update_node_from_data_form (req, l_node)
|
||||
l_node.set_author (l_user)
|
||||
node_api.update_node (l_node)
|
||||
redirect_to (req.absolute_script_url (""), res)
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user_name (req) 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
|
||||
node_api.delete_node (l_node)
|
||||
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
|
||||
if a_id.is_integer then
|
||||
-- resource not found
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
feature {NONE} -- Node
|
||||
|
||||
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
if api.user_has_permission (current_user (req), "create node") then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.execute
|
||||
else
|
||||
send_access_denied (res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
update_node_from_data_form (req: WSF_REQUEST; a_node: CMS_NODE)
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
local
|
||||
l_title: detachable READABLE_STRING_32
|
||||
l_summary, l_content, l_format: detachable READABLE_STRING_8
|
||||
do
|
||||
if attached {WSF_STRING} req.form_parameter ("title") as p_title then
|
||||
l_title := p_title.value
|
||||
a_node.set_title (l_title)
|
||||
end
|
||||
if attached {WSF_STRING} req.form_parameter ("summary") as p_summary then
|
||||
l_summary := html_encoded (p_summary.value)
|
||||
end
|
||||
if attached {WSF_STRING} req.form_parameter ("content") as p_content then
|
||||
l_content := html_encoded (p_content.value)
|
||||
end
|
||||
if attached {WSF_STRING} req.form_parameter ("format") as p_format then
|
||||
l_format := p_format.url_encoded_value
|
||||
end
|
||||
if l_format = Void then
|
||||
l_format := a_node.format
|
||||
end
|
||||
a_node.set_content (l_content, l_summary, l_format)
|
||||
end
|
||||
|
||||
end
|
||||
75
modules/node/handler/experimental/node_resources_handler.e
Normal file
75
modules/node/handler/experimental/node_resources_handler.e
Normal file
@@ -0,0 +1,75 @@
|
||||
note
|
||||
description: "Request handler related to /nodes."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
NODE_RESOURCES_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_NODE_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
s: STRING
|
||||
do
|
||||
-- At the moment the template is hardcoded, but we can
|
||||
-- get them from the configuration file and load them into
|
||||
-- the setup class.
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (node_api.nodes, "nodes")
|
||||
|
||||
|
||||
-- NOTE: for development purposes we have the following hardcode output.
|
||||
create s.make_from_string ("<p>Nodes:</p>")
|
||||
if attached node_api.nodes as lst then
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
s.append ("<li>")
|
||||
s.append ("<a href=%"")
|
||||
s.append (req.script_url ("/node/" + ic.item.id.out))
|
||||
s.append ("%">")
|
||||
s.append (api.html_encoded (ic.item.title))
|
||||
s.append (" (")
|
||||
s.append (ic.item.id.out)
|
||||
s.append (")")
|
||||
s.append ("</a>")
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
end
|
||||
|
||||
l_page.set_main_content (s)
|
||||
l_page.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet fully implemented<br/>", Void), "highlighted")
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
end
|
||||
168
modules/node/handler/experimental/node_summary_handler.e
Normal file
168
modules/node/handler/experimental/node_summary_handler.e
Normal file
@@ -0,0 +1,168 @@
|
||||
note
|
||||
description: "Summary description for {NODE_SUMMARY_HANDLER}."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
NODE_SUMMARY_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
|
||||
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 -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
if attached current_user_name (req) then
|
||||
-- Existing node
|
||||
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
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (l_id.value, "id")
|
||||
l_page.add_variable (l_node.summary, "node_summary")
|
||||
l_page.execute
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user_name (req) 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 attached {WSF_STRING} req.form_parameter ("method") as l_method then
|
||||
if l_method.is_case_insensitive_equal ("PUT") then
|
||||
do_put (req, res)
|
||||
else
|
||||
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
do
|
||||
if attached current_user (req) 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
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_id (l_id.value.to_integer_64)
|
||||
node_api.update_node_summary (l_user.id,u_node.id, u_node.summary)
|
||||
redirect_to (req.absolute_script_url (""), res)
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
|
||||
if a_id.is_integer then
|
||||
-- resource not found
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
|
||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
do
|
||||
create Result.make ("", "", "")
|
||||
if attached {WSF_STRING}req.form_parameter ("summary") as l_summary then
|
||||
Result.set_summary (l_summary.value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
166
modules/node/handler/experimental/node_title_handler.e
Normal file
166
modules/node/handler/experimental/node_title_handler.e
Normal file
@@ -0,0 +1,166 @@
|
||||
note
|
||||
description: "Summary description for {NODE_TITLE_HANDLER}."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
NODE_TITLE_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
|
||||
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 -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
if attached current_user_name (req) as l_user then
|
||||
-- Existing node
|
||||
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
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (l_node.title, "node_title")
|
||||
l_page.add_variable (l_id.value, "id")
|
||||
l_page.execute
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user_name (req) 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 attached {WSF_STRING} req.form_parameter ("method") as l_method then
|
||||
if l_method.is_case_insensitive_equal ("PUT") then
|
||||
do_put (req, res)
|
||||
else
|
||||
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
do
|
||||
to_implement ("Check if user has permissions")
|
||||
if attached current_user (req) 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
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_id (l_id.value.to_integer_64)
|
||||
node_api.update_node_title (l_user.id, u_node.id, u_node.title)
|
||||
redirect_to (req.absolute_script_url (""), res)
|
||||
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 (res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
|
||||
if a_id.is_integer then
|
||||
-- resource not found
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
do
|
||||
create Result.make ("", "", "")
|
||||
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
|
||||
Result.set_title (l_title.value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
259
modules/node/handler/node_form_response.e
Normal file
259
modules/node/handler/node_form_response.e
Normal file
@@ -0,0 +1,259 @@
|
||||
note
|
||||
description: "CMS Response handling node editing workflow using Web forms."
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_FORM_RESPONSE
|
||||
|
||||
inherit
|
||||
NODE_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api; a_node_api: like node_api)
|
||||
do
|
||||
create {WSF_NULL_THEME} wsf_theme.make
|
||||
Precursor (req, res, a_api, a_node_api)
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {WSF_CMS_THEME} wsf_theme.make (Current, theme)
|
||||
end
|
||||
|
||||
wsf_theme: WSF_THEME
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
local
|
||||
b: STRING_8
|
||||
f: like edit_form
|
||||
fd: detachable WSF_FORM_DATA
|
||||
nid: INTEGER_64
|
||||
do
|
||||
create b.make_empty
|
||||
nid := node_id_path_parameter (request)
|
||||
if
|
||||
nid > 0 and then
|
||||
attached node_api.node (nid) as l_node
|
||||
then
|
||||
if attached node_api.node_type_for (l_node) as l_type then
|
||||
if has_permission ("edit " + l_type.name) then
|
||||
f := edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent edit_form_validate (?, b))
|
||||
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
set_title (l_node.title)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("View", node_url (l_node)), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("Edit", "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
||||
|
||||
b.append (html_encoded (l_type.title) + " saved")
|
||||
else
|
||||
set_title ("Edit " + html_encoded (l_type.title) + " #" + l_node.id.out)
|
||||
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("View", node_url (l_node)), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("Edit", "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
||||
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
else
|
||||
b.append ("<h1>Access denied</h1>")
|
||||
end
|
||||
else
|
||||
set_title ("Unknown node")
|
||||
end
|
||||
elseif
|
||||
attached {WSF_STRING} request.path_parameter ("type") as p_type and then
|
||||
attached node_api.node_type (p_type.value) as l_type
|
||||
then
|
||||
if has_permission ("create " + l_type.name) then
|
||||
if attached l_type.new_node (Void) as l_node then
|
||||
f := edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent edit_form_validate (?, b))
|
||||
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
|
||||
set_title ("Edit " + html_encoded (l_type.title) + " #" + l_node.id.out)
|
||||
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("View", node_url (l_node)), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("Edit", "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
||||
|
||||
f.append_to_html (wsf_theme, b)
|
||||
else
|
||||
b.append ("<h1>Server error</h1>")
|
||||
end
|
||||
else
|
||||
b.append ("<h1>Access denied</h1>")
|
||||
end
|
||||
else
|
||||
set_title ("Create new content ...")
|
||||
b.append ("<ul id=%"content-types%">")
|
||||
across
|
||||
node_api.node_types as ic
|
||||
loop
|
||||
if
|
||||
attached ic.item as l_node_type and then
|
||||
(has_permission ("create any") or has_permission ("create " + l_node_type.name))
|
||||
then
|
||||
b.append ("<li>" + link (l_node_type.name, "/node/add/" + l_node_type.name, Void))
|
||||
if attached l_node_type.description as d then
|
||||
b.append ("<div class=%"description%">" + d + "</div>")
|
||||
end
|
||||
b.append ("</li>")
|
||||
end
|
||||
end
|
||||
b.append ("</ul>")
|
||||
end
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
feature -- Form
|
||||
|
||||
edit_form_validate (fd: WSF_FORM_DATA; b: STRING)
|
||||
local
|
||||
l_preview: BOOLEAN
|
||||
l_format: detachable CONTENT_FORMAT
|
||||
do
|
||||
l_preview := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Preview")
|
||||
if l_preview then
|
||||
b.append ("<strong>Preview</strong><div class=%"preview%">")
|
||||
if attached fd.string_item ("format") as s_format and then attached api.format (s_format) as f_format then
|
||||
l_format := f_format
|
||||
end
|
||||
if attached fd.string_item ("title") as l_title then
|
||||
b.append ("<strong>Title:</strong><div class=%"title%">" + html_encoded (l_title) + "</div>")
|
||||
end
|
||||
if attached fd.string_item ("body") as l_body then
|
||||
b.append ("<strong>Body:</strong><div class=%"body%">")
|
||||
if l_format /= Void then
|
||||
b.append (l_format.formatted_output (l_body))
|
||||
else
|
||||
b.append (html_encoded (l_body))
|
||||
end
|
||||
b.append ("</div>")
|
||||
end
|
||||
b.append ("</div>")
|
||||
end
|
||||
end
|
||||
|
||||
edit_form_submit (fd: WSF_FORM_DATA; a_node: detachable CMS_NODE; a_type: CMS_NODE_TYPE [CMS_NODE]; b: STRING)
|
||||
local
|
||||
l_preview: BOOLEAN
|
||||
l_node: detachable CMS_NODE
|
||||
s: STRING
|
||||
do
|
||||
l_preview := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Preview")
|
||||
if not l_preview then
|
||||
debug ("cms")
|
||||
across
|
||||
fd as c
|
||||
loop
|
||||
b.append ("<li>" + html_encoded (c.key) + "=")
|
||||
if attached c.item as v then
|
||||
b.append (html_encoded (v.string_representation))
|
||||
end
|
||||
b.append ("</li>")
|
||||
end
|
||||
end
|
||||
if a_node /= Void then
|
||||
l_node := a_node
|
||||
if l_node.has_id then
|
||||
change_node (a_type, fd, a_node)
|
||||
s := "modified"
|
||||
else
|
||||
change_node (a_type, fd, a_node)
|
||||
l_node.set_author (user)
|
||||
s := "created"
|
||||
end
|
||||
else
|
||||
l_node := new_node (a_type, fd, Void)
|
||||
l_node.set_author (user)
|
||||
s := "created"
|
||||
end
|
||||
node_api.save_node (l_node)
|
||||
if attached current_user (request) as u then
|
||||
api.log ("node", "User %"" + user_link (u) + "%" " + s + " node " + link (a_type.name +" #" + l_node.id.out, "/node/" + l_node.id.out , Void), 0, node_local_link (l_node))
|
||||
else
|
||||
api.log ("node", "Anonymous " + s + " node " + a_type.name +" #" + l_node.id.out, 0, node_local_link (l_node))
|
||||
end
|
||||
add_success_message ("Node #" + l_node.id.out + " saved.")
|
||||
set_redirection (node_url (l_node))
|
||||
end
|
||||
end
|
||||
|
||||
edit_form (a_node: detachable CMS_NODE; a_url: READABLE_STRING_8; a_name: STRING; a_type: CMS_NODE_TYPE [CMS_NODE]): CMS_FORM
|
||||
local
|
||||
f: CMS_FORM
|
||||
ts: WSF_FORM_SUBMIT_INPUT
|
||||
th: WSF_FORM_HIDDEN_INPUT
|
||||
do
|
||||
create f.make (a_url, a_name)
|
||||
|
||||
create th.make ("node-id")
|
||||
if a_node /= Void then
|
||||
th.set_text_value (a_node.id.out)
|
||||
else
|
||||
th.set_text_value ("0")
|
||||
end
|
||||
f.extend (th)
|
||||
|
||||
fill_edit_form (a_type, f, a_node)
|
||||
|
||||
f.extend_html_text ("<br/>")
|
||||
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Save")
|
||||
f.extend (ts)
|
||||
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Preview")
|
||||
f.extend (ts)
|
||||
|
||||
Result := f
|
||||
end
|
||||
|
||||
new_node (a_content_type: CMS_NODE_TYPE [CMS_NODE]; a_form_data: WSF_FORM_DATA; a_node: detachable CMS_NODE): CMS_NODE
|
||||
--
|
||||
do
|
||||
if attached node_api.node_type_webform_manager (a_content_type) as wf then
|
||||
Result := wf.new_node (Current, a_form_data, a_node)
|
||||
else
|
||||
Result := a_content_type.new_node (a_node)
|
||||
end
|
||||
end
|
||||
|
||||
change_node (a_content_type: CMS_NODE_TYPE [CMS_NODE]; a_form_data: WSF_FORM_DATA; a_node: CMS_NODE)
|
||||
-- Update node `a_node' with form_data `a_form_data' for the given content type `a_content_type'.
|
||||
do
|
||||
if attached node_api.node_type_webform_manager (a_content_type) as wf then
|
||||
wf.update_node (Current, a_form_data, a_node)
|
||||
end
|
||||
end
|
||||
|
||||
fill_edit_form (a_content_type: CMS_NODE_TYPE [CMS_NODE]; a_form: WSF_FORM; a_node: detachable CMS_NODE)
|
||||
do
|
||||
if attached node_api.node_type_webform_manager (a_content_type) as wf then
|
||||
wf.populate_form (Current, a_form, a_node)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
205
modules/node/handler/node_handler.e
Normal file
205
modules/node/handler/node_handler.e
Normal file
@@ -0,0 +1,205 @@
|
||||
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: INTEGER_64
|
||||
edit_response: NODE_FORM_RESPONSE
|
||||
view_response: NODE_VIEW_RESPONSE
|
||||
do
|
||||
if req.path_info.ends_with_general ("/edit") then
|
||||
check valid_url: req.path_info.starts_with_general ("/node/") end
|
||||
create edit_response.make (req, res, api, node_api)
|
||||
edit_response.execute
|
||||
else
|
||||
-- Display existing node
|
||||
l_nid := node_id_path_parameter (req)
|
||||
if l_nid > 0 then
|
||||
l_node := node_api.node (l_nid)
|
||||
if l_node /= Void then
|
||||
create view_response.make (req, res, api, node_api)
|
||||
view_response.set_node (l_node)
|
||||
view_response.execute
|
||||
else
|
||||
send_not_found (req, res)
|
||||
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
|
||||
if req.path_info.ends_with_general ("/edit") then
|
||||
create edit_response.make (req, res, api, node_api)
|
||||
edit_response.execute
|
||||
-- elseif req.path_info.same_string_general ("/node/") 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_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user (req) 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 api.user_has_permission (l_user, "delete " + l_node.content_type) then
|
||||
node_api.delete_node (l_node)
|
||||
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
|
||||
else
|
||||
send_access_denied (req, res)
|
||||
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 -- 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.add_variable (req.absolute_script_url (req.path_info), "request")
|
||||
if a_id /= Void and then a_id.is_integer then
|
||||
-- resource not found
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("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.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
|
||||
86
modules/node/handler/node_response.e
Normal file
86
modules/node/handler/node_response.e
Normal file
@@ -0,0 +1,86 @@
|
||||
note
|
||||
description: "Generic CMS Response for a CMS NODE."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
NODE_RESPONSE
|
||||
|
||||
inherit
|
||||
CMS_RESPONSE
|
||||
rename
|
||||
make as make_response
|
||||
redefine
|
||||
custom_prepare
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api; a_node_api: like node_api)
|
||||
do
|
||||
node_api := a_node_api
|
||||
make_response (req, res, a_api)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
node_api: CMS_NODE_API
|
||||
-- Associated node API.
|
||||
|
||||
feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
if attached variables as l_variables then
|
||||
across l_variables as c loop page.register_variable (c.item, c.key) end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
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 -- Helpers
|
||||
|
||||
user_local_link (u: CMS_USER): CMS_LINK
|
||||
do
|
||||
create {CMS_LOCAL_LINK} Result.make (u.name, user_url (u))
|
||||
end
|
||||
|
||||
node_local_link (n: CMS_NODE): CMS_LINK
|
||||
do
|
||||
create {CMS_LOCAL_LINK} Result.make (n.title, node_url (n))
|
||||
end
|
||||
|
||||
user_link (u: CMS_USER): like link
|
||||
do
|
||||
Result := link (u.name, "/user/" + u.id.out, Void)
|
||||
end
|
||||
|
||||
node_link (n: CMS_NODE): like link
|
||||
do
|
||||
Result := link (n.title, "/node/" + n.id.out, Void)
|
||||
end
|
||||
|
||||
user_url (u: CMS_USER): like url
|
||||
do
|
||||
Result := url ("/user/" + u.id.out, Void)
|
||||
end
|
||||
|
||||
node_url (n: CMS_NODE): like url
|
||||
do
|
||||
Result := url ("/node/" + n.id.out, Void)
|
||||
end
|
||||
|
||||
end
|
||||
75
modules/node/handler/node_view_response.e
Normal file
75
modules/node/handler/node_view_response.e
Normal file
@@ -0,0 +1,75 @@
|
||||
note
|
||||
description: "Summary description for {NODE_VIEW_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_VIEW_RESPONSE
|
||||
|
||||
inherit
|
||||
NODE_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api; a_node_api: like node_api)
|
||||
do
|
||||
create {WSF_NULL_THEME} wsf_theme.make
|
||||
Precursor (req, res, a_api, a_node_api)
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {WSF_CMS_THEME} wsf_theme.make (Current, theme)
|
||||
end
|
||||
|
||||
wsf_theme: WSF_THEME
|
||||
|
||||
feature -- Access
|
||||
|
||||
node: detachable CMS_NODE
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_node (a_node: like node)
|
||||
do
|
||||
node := a_node
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
local
|
||||
b: STRING_8
|
||||
nid: INTEGER_64
|
||||
l_node: like node
|
||||
do
|
||||
l_node := node
|
||||
if l_node = Void then
|
||||
create b.make_empty
|
||||
nid := node_id_path_parameter (request)
|
||||
if nid > 0 then
|
||||
l_node := node_api.node (nid)
|
||||
end
|
||||
end
|
||||
if l_node /= Void then
|
||||
if
|
||||
attached node_api.node_type_for (l_node) as l_content_type and then
|
||||
attached node_api.node_type_webform_manager (l_content_type) as l_manager
|
||||
then
|
||||
l_manager.append_html_output_to (l_node, Current)
|
||||
end
|
||||
else
|
||||
set_main_content ("Missing node")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
72
modules/node/handler/nodes_handler.e
Normal file
72
modules/node/handler/nodes_handler.e
Normal file
@@ -0,0 +1,72 @@
|
||||
note
|
||||
description: "Request handler related to /nodes."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
NODES_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_NODE_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
s: STRING
|
||||
n: CMS_NODE
|
||||
do
|
||||
-- At the moment the template is hardcoded, but we can
|
||||
-- get them from the configuration file and load them into
|
||||
-- the setup class.
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.add_variable (node_api.nodes, "nodes")
|
||||
|
||||
|
||||
-- NOTE: for development purposes we have the following hardcode output.
|
||||
create s.make_from_string ("<p>Nodes:</p>")
|
||||
if attached node_api.nodes as lst then
|
||||
s.append ("<ul class=%"cms-nodes%">%N")
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
n := ic.item
|
||||
s.append ("<li class=%"cms_type_"+ n.content_type +"%">")
|
||||
s.append (l_page.link (n.title + " (#" + n.id.out + ")", node_api.node_path (n), Void))
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
end
|
||||
|
||||
l_page.set_main_content (s)
|
||||
l_page.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet fully implemented<br/>", Void), "highlighted")
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
end
|
||||
58
modules/node/handler/wsf_cms_theme.e
Normal file
58
modules/node/handler/wsf_cms_theme.e
Normal file
@@ -0,0 +1,58 @@
|
||||
note
|
||||
description: "Summary description for {WSF_CMS_THEME}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_CMS_THEME
|
||||
|
||||
inherit
|
||||
WSF_THEME
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (res: CMS_RESPONSE; a_cms_theme: CMS_THEME)
|
||||
do
|
||||
request := res.request
|
||||
cms_theme := a_cms_theme
|
||||
set_response (res)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
request: WSF_REQUEST
|
||||
|
||||
response: detachable CMS_RESPONSE
|
||||
|
||||
cms_theme: CMS_THEME
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_response (a_response: CMS_RESPONSE)
|
||||
do
|
||||
response := a_response
|
||||
end
|
||||
|
||||
feature -- Core
|
||||
|
||||
site_url: READABLE_STRING_8
|
||||
do
|
||||
if attached response as r then
|
||||
Result := r.site_url
|
||||
else
|
||||
Result := request.absolute_script_url ("")
|
||||
end
|
||||
end
|
||||
|
||||
base_url: detachable READABLE_STRING_8
|
||||
-- Base url if any.
|
||||
do
|
||||
if attached response as r then
|
||||
Result := r.base_url
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
30
modules/node/handler/wsf_null_theme.e
Normal file
30
modules/node/handler/wsf_null_theme.e
Normal file
@@ -0,0 +1,30 @@
|
||||
note
|
||||
description: " Null theme for void-safety purpose."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_NULL_THEME
|
||||
|
||||
inherit
|
||||
WSF_THEME
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Core
|
||||
|
||||
site_url: STRING = ""
|
||||
|
||||
base_url: detachable READABLE_STRING_8
|
||||
-- Base url if any.
|
||||
do
|
||||
end
|
||||
|
||||
end
|
||||
184
modules/node/node_module.e
Normal file
184
modules/node/node_module.e
Normal file
@@ -0,0 +1,184 @@
|
||||
note
|
||||
description: "CMS module that bring support for NODE management."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
NODE_MODULE
|
||||
|
||||
inherit
|
||||
|
||||
CMS_MODULE
|
||||
rename
|
||||
module_api as node_api
|
||||
redefine
|
||||
register_hooks,
|
||||
initialize,
|
||||
is_installed,
|
||||
install,
|
||||
node_api
|
||||
end
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_setup: CMS_SETUP)
|
||||
-- Create Current module, disabled by default.
|
||||
do
|
||||
name := "node"
|
||||
version := "1.0"
|
||||
description := "Service to manage content based on 'node'"
|
||||
package := "core"
|
||||
config := a_setup
|
||||
end
|
||||
|
||||
config: CMS_SETUP
|
||||
-- Node configuration.
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (api: CMS_API)
|
||||
-- <Precursor>
|
||||
local
|
||||
p1,p2: CMS_PAGE
|
||||
ct: CMS_PAGE_NODE_TYPE
|
||||
l_node_api: like node_api
|
||||
do
|
||||
Precursor (api)
|
||||
create l_node_api.make (api)
|
||||
node_api := l_node_api
|
||||
|
||||
-- Add support for CMS_PAGE, which requires a storage extension to store the optional "parent" id.
|
||||
-- For now, we only have extension based on SQL statement.
|
||||
if attached {CMS_NODE_STORAGE_SQL} l_node_api.node_storage as l_sql_node_storage then
|
||||
l_sql_node_storage.register_node_storage_extension (create {CMS_NODE_STORAGE_SQL_PAGE_EXTENSION}.make (l_sql_node_storage))
|
||||
|
||||
-- FIXME: the following code is mostly for test purpose/initialization, remove later
|
||||
if l_sql_node_storage.sql_table_items_count ("page_nodes") = 0 then
|
||||
if attached api.user_api.user_by_id (1) as u then
|
||||
create ct
|
||||
p1 := ct.new_node (Void)
|
||||
p1.set_title ("Welcome")
|
||||
p1.set_content ("Welcome, you are using the ROC Eiffel CMS", Void, Void) -- Use default format
|
||||
p1.set_author (u)
|
||||
l_sql_node_storage.save_node (p1)
|
||||
|
||||
p2 := ct.new_node (Void)
|
||||
p2.set_title ("A new page example")
|
||||
p2.set_content ("This is the content of a page", Void, Void) -- Use default format
|
||||
p2.set_author (u)
|
||||
p2.set_parent (p1)
|
||||
l_sql_node_storage.save_node (p2)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- FIXME: maybe provide a default solution based on file system, when no SQL storage is available.
|
||||
-- IDEA: we could also have generic extension to node system, that handle generic addition field.
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
is_installed (api: CMS_API): BOOLEAN
|
||||
-- Is Current module installed?
|
||||
do
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
Result := l_sql_storage.sql_table_exists ("nodes") and
|
||||
l_sql_storage.sql_table_exists ("page_nodes")
|
||||
end
|
||||
end
|
||||
|
||||
install (api: CMS_API)
|
||||
do
|
||||
-- Schema
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
l_sql_storage.sql_execute_file_script (api.setup.environment.path.extended ("scripts").extended (name).appended_with_extension ("sql"))
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Access: API
|
||||
|
||||
node_api: detachable CMS_NODE_API
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
router (a_api: CMS_API): WSF_ROUTER
|
||||
-- Node router.
|
||||
local
|
||||
l_node_api: like node_api
|
||||
do
|
||||
l_node_api := node_api
|
||||
if l_node_api = Void then
|
||||
create l_node_api.make (a_api)
|
||||
node_api := l_node_api
|
||||
end
|
||||
create Result.make (2)
|
||||
configure_web (a_api, l_node_api, Result)
|
||||
end
|
||||
|
||||
configure_web (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
l_node_handler: NODE_HANDLER
|
||||
l_nodes_handler: NODES_HANDLER
|
||||
l_uri_mapping: WSF_URI_MAPPING
|
||||
do
|
||||
-- TODO: for now, focused only on web interface, add REST api later. [2015-April-29]
|
||||
create l_node_handler.make (a_api, a_node_api)
|
||||
create l_uri_mapping.make_trailing_slash_ignored ("/node", l_node_handler)
|
||||
a_router.map_with_request_methods (l_uri_mapping, a_router.methods_get_post)
|
||||
|
||||
a_router.handle_with_request_methods ("/node/add/{type}", l_node_handler, a_router.methods_get_post)
|
||||
a_router.handle_with_request_methods ("/node/{id}/edit", l_node_handler, a_router.methods_get_post)
|
||||
|
||||
a_router.handle_with_request_methods ("/node/{id}", l_node_handler, a_router.methods_get)
|
||||
-- For now: no REST API handling... a_router.methods_get_put_delete + a_router.methods_get_post)
|
||||
|
||||
-- Nodes
|
||||
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_with_request_methods (l_uri_mapping, a_router.methods_get)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
a_response.subscribe_to_menu_system_alter_hook (Current)
|
||||
a_response.subscribe_to_block_hook (Current)
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := <<"node-info">>
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
local
|
||||
-- b: CMS_CONTENT_BLOCK
|
||||
do
|
||||
-- create b.make (a_block_id, "Block::node", "This is a block test", Void)
|
||||
-- a_response.add_block (b, "sidebar_second")
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
-- perms: detachable ARRAYED_LIST [READABLE_STRING_8]
|
||||
do
|
||||
create lnk.make ("List of nodes", a_response.url ("/nodes", Void))
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
|
||||
create lnk.make ("Create ..", a_response.url ("/node/", Void))
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
end
|
||||
|
||||
end
|
||||
53
modules/node/persistence/cms_node_storage_extension.e
Normal file
53
modules/node/persistence/cms_node_storage_extension.e
Normal file
@@ -0,0 +1,53 @@
|
||||
note
|
||||
description: "Node storage extension for specific node descendant."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_NODE_STORAGE_EXTENSION [G -> CMS_NODE]
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: READABLE_STRING_8
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_accepted (a_node: CMS_NODE): BOOLEAN
|
||||
-- Is `a_node' accepted by current storage extension?
|
||||
do
|
||||
Result := attached {G} a_node
|
||||
end
|
||||
|
||||
feature -- Persistence
|
||||
|
||||
store_node (a_node: CMS_NODE)
|
||||
require
|
||||
a_node_accepted: is_accepted (a_node)
|
||||
do
|
||||
if attached {G} a_node as obj then
|
||||
store (obj)
|
||||
end
|
||||
end
|
||||
|
||||
load_node (a_node: CMS_NODE)
|
||||
require
|
||||
a_node_accepted: is_accepted (a_node)
|
||||
do
|
||||
if attached {G} a_node as obj then
|
||||
load (obj)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Persistence implementation
|
||||
|
||||
store (a_node: G)
|
||||
deferred
|
||||
end
|
||||
|
||||
load (a_node: G)
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
173
modules/node/persistence/cms_node_storage_i.e
Normal file
173
modules/node/persistence/cms_node_storage_i.e
Normal file
@@ -0,0 +1,173 @@
|
||||
note
|
||||
description: "Summary description for {CMS_NODE_STORAGE_I}."
|
||||
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||
revision: "$Revision: 96542 $"
|
||||
|
||||
deferred class
|
||||
CMS_NODE_STORAGE_I
|
||||
|
||||
feature -- Error Handling
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Storage extension
|
||||
|
||||
register_node_storage_extension (a_extension: CMS_NODE_STORAGE_EXTENSION [CMS_NODE])
|
||||
-- Register `a_extension' as extension to the node storage system.
|
||||
local
|
||||
tb: like node_storage_extensions
|
||||
do
|
||||
tb := node_storage_extensions
|
||||
if tb = Void then
|
||||
create tb.make_caseless (1)
|
||||
node_storage_extensions := tb
|
||||
end
|
||||
tb.force (a_extension, a_extension.content_type)
|
||||
end
|
||||
|
||||
node_storage_extension (a_node: CMS_NODE): detachable CMS_NODE_STORAGE_EXTENSION [CMS_NODE]
|
||||
-- Extension to the node storage system for node `a_node'.
|
||||
do
|
||||
if attached node_storage_extensions as tb then
|
||||
Result := tb.item (a_node.content_type)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
node_storage_extensions: detachable STRING_TABLE [CMS_NODE_STORAGE_EXTENSION [CMS_NODE]]
|
||||
-- Table of node storage extensions.
|
||||
|
||||
extended_store (a_node: CMS_NODE)
|
||||
-- Store extended data from `a_node'.
|
||||
do
|
||||
if attached node_storage_extension (a_node) as ext then
|
||||
ext.store_node (a_node)
|
||||
end
|
||||
end
|
||||
|
||||
extended_load (a_node: CMS_NODE)
|
||||
-- Load extended data into `a_node'.
|
||||
do
|
||||
if attached node_storage_extension (a_node) as ext then
|
||||
ext.load_node (a_node)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Access
|
||||
|
||||
nodes_count: INTEGER_64
|
||||
-- Count of nodes.
|
||||
deferred
|
||||
end
|
||||
|
||||
nodes: LIST [CMS_NODE]
|
||||
-- List of nodes.
|
||||
deferred
|
||||
end
|
||||
|
||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||
deferred
|
||||
end
|
||||
|
||||
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
|
||||
-- Retrieve node by id `a_id', if any.
|
||||
require
|
||||
a_id > 0
|
||||
deferred
|
||||
end
|
||||
|
||||
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
||||
-- Node's author. if any.
|
||||
require
|
||||
valid_node: a_id > 0
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change: Node
|
||||
|
||||
save_node (a_node: CMS_NODE)
|
||||
-- Create or update `a_node'.
|
||||
do
|
||||
if a_node.has_id then
|
||||
update_node (a_node)
|
||||
else
|
||||
new_node (a_node)
|
||||
end
|
||||
end
|
||||
|
||||
new_node (a_node: CMS_NODE)
|
||||
-- Save node `a_node'.
|
||||
require
|
||||
no_id: not a_node.has_id
|
||||
valid_user: attached a_node.author as l_author and then l_author.id > 0
|
||||
deferred
|
||||
end
|
||||
|
||||
update_node (a_node: CMS_NODE)
|
||||
-- Update node content `a_node'.
|
||||
-- The user `a_id' is an existing or new collaborator.
|
||||
require
|
||||
has_id: a_node.has_id
|
||||
has_author: attached a_node.author as l_author and then l_author.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
delete_node (a_node: CMS_NODE)
|
||||
-- Delete `a_node'.
|
||||
do
|
||||
if a_node.has_id then
|
||||
delete_node_by_id (a_node.id)
|
||||
end
|
||||
end
|
||||
|
||||
delete_node_by_id (a_id: INTEGER_64)
|
||||
-- Remove node by id `a_id'.
|
||||
require
|
||||
valid_node_id: a_id > 0
|
||||
deferred
|
||||
end
|
||||
|
||||
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||
-- -- Update node title to `a_title', node identified by id `a_node_id'.
|
||||
-- -- The user `a_user_id' is an existing or new collaborator.
|
||||
-- require
|
||||
-- valid_node_id: a_node_id > 0
|
||||
-- valid_user_id: a_user_id > 0
|
||||
-- deferred
|
||||
-- end
|
||||
|
||||
-- update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||
-- -- Update node summary to `a_summary', node identified by id `a_node_id'.
|
||||
-- -- The user `a_user_id' is an existing or new collaborator.
|
||||
-- require
|
||||
-- valid_id: a_node_id > 0
|
||||
-- valid_user_id: a_user_id > 0
|
||||
-- deferred
|
||||
-- end
|
||||
|
||||
-- update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||
-- -- Update node content to `a_content', node identified by id `a_node_id'.
|
||||
-- -- The user `a_user_id' is an existing or new collaborator.
|
||||
-- require
|
||||
-- valid_id: a_node_id > 0
|
||||
-- valid_user_id: a_user_id > 0
|
||||
-- deferred
|
||||
-- end
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
fill_node (a_node: CMS_NODE)
|
||||
-- Fill `a_node' with extra information from database.
|
||||
-- i.e: specific to each content type data.
|
||||
require
|
||||
has_id: a_node.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
106
modules/node/persistence/cms_node_storage_null.e
Normal file
106
modules/node/persistence/cms_node_storage_null.e
Normal file
@@ -0,0 +1,106 @@
|
||||
note
|
||||
description: "[
|
||||
Objects that ...
|
||||
]"
|
||||
author: "$Author$"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_NODE_STORAGE_NULL
|
||||
|
||||
inherit
|
||||
CMS_NODE_STORAGE_I
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
create error_handler.make
|
||||
end
|
||||
|
||||
feature -- Error Handling
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler.
|
||||
|
||||
feature -- Access: node
|
||||
|
||||
nodes_count: INTEGER_64
|
||||
-- Count of nodes.
|
||||
do
|
||||
end
|
||||
|
||||
nodes: LIST[CMS_NODE]
|
||||
-- List of nodes.
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||
end
|
||||
|
||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||
-- List of the `a_count' most recent nodes, starting from `a_lower'.
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||
end
|
||||
|
||||
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
|
||||
-- <Precursor>
|
||||
do
|
||||
end
|
||||
|
||||
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
||||
-- Node's author. if any.
|
||||
do
|
||||
end
|
||||
|
||||
node_collaborators (a_id: like {CMS_NODE}.id): LIST [CMS_USER]
|
||||
-- Possible list of node's collaborator.
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_USER]} Result.make (0)
|
||||
end
|
||||
|
||||
feature -- Node
|
||||
|
||||
new_node (a_node: CMS_NODE)
|
||||
-- Add a new node
|
||||
do
|
||||
end
|
||||
|
||||
delete_node_by_id (a_id: INTEGER_64)
|
||||
-- <Precursor>
|
||||
do
|
||||
end
|
||||
|
||||
update_node (a_node: CMS_NODE)
|
||||
-- <Precursor>
|
||||
do
|
||||
end
|
||||
|
||||
-- update_node_title (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||
-- -- <Precursor>
|
||||
-- do
|
||||
-- end
|
||||
|
||||
-- update_node_summary (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||
-- -- <Precursor>
|
||||
-- do
|
||||
-- end
|
||||
|
||||
-- update_node_content (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||
-- -- <Precursor>
|
||||
-- do
|
||||
-- end
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
fill_node (a_node: CMS_NODE)
|
||||
-- Fill `a_node' with extra information from database.
|
||||
-- i.e: specific to each content type data.
|
||||
do
|
||||
end
|
||||
|
||||
end
|
||||
360
modules/node/persistence/cms_node_storage_sql.e
Normal file
360
modules/node/persistence/cms_node_storage_sql.e
Normal file
@@ -0,0 +1,360 @@
|
||||
note
|
||||
description: "[
|
||||
CMS NODE Storage based on SQL statements.
|
||||
]"
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
CMS_NODE_STORAGE_SQL
|
||||
|
||||
inherit
|
||||
CMS_PROXY_STORAGE_SQL
|
||||
|
||||
CMS_NODE_STORAGE_I
|
||||
|
||||
CMS_STORAGE_SQL_I
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Access
|
||||
|
||||
nodes_count: INTEGER_64
|
||||
-- Number of items nodes.
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".nodes_count")
|
||||
sql_query (sql_select_nodes_count, Void)
|
||||
if sql_rows_count = 1 then
|
||||
Result := sql_read_integer_64 (1)
|
||||
end
|
||||
end
|
||||
|
||||
nodes: LIST [CMS_NODE]
|
||||
-- List of nodes.
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".nodes")
|
||||
|
||||
from
|
||||
sql_query (sql_select_nodes, Void)
|
||||
sql_start
|
||||
until
|
||||
sql_after
|
||||
loop
|
||||
if attached fetch_node as l_node then
|
||||
Result.force (l_node)
|
||||
end
|
||||
sql_forth
|
||||
end
|
||||
-- across
|
||||
-- Result as ic
|
||||
-- loop
|
||||
-- fill_node (ic.item)
|
||||
-- end
|
||||
end
|
||||
|
||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".nodes")
|
||||
|
||||
from
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_count, "rows")
|
||||
l_parameters.put (a_lower, "offset")
|
||||
sql_query (sql_select_recent_nodes, l_parameters)
|
||||
sql_start
|
||||
until
|
||||
sql_after
|
||||
loop
|
||||
if attached fetch_node as l_node then
|
||||
Result.force (l_node)
|
||||
end
|
||||
sql_forth
|
||||
end
|
||||
end
|
||||
|
||||
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
|
||||
-- Retrieve node by id `a_id', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".node")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_id, "nid")
|
||||
sql_query (sql_select_node_by_id, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_node
|
||||
end
|
||||
end
|
||||
|
||||
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
||||
-- Node's author for the given node id.
|
||||
local
|
||||
l_parameters: STRING_TABLE [ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".node_author")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_id, "node_id")
|
||||
sql_query (select_node_author, l_parameters)
|
||||
if sql_rows_count >= 1 then
|
||||
Result := fetch_author
|
||||
end
|
||||
end
|
||||
|
||||
last_inserted_node_id: INTEGER_64
|
||||
-- Last insert node id.
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".last_inserted_node_id")
|
||||
sql_query (Sql_last_insert_node_id, Void)
|
||||
if sql_rows_count = 1 then
|
||||
Result := sql_read_integer_64 (1)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change: Node
|
||||
|
||||
new_node (a_node: CMS_NODE)
|
||||
-- Save node `a_node'.
|
||||
do
|
||||
store_node (a_node)
|
||||
end
|
||||
|
||||
update_node (a_node: CMS_NODE)
|
||||
-- Update node content `a_node'.
|
||||
do
|
||||
store_node (a_node)
|
||||
end
|
||||
|
||||
delete_node_by_id (a_id: INTEGER_64)
|
||||
-- Remove node by id `a_id'.
|
||||
local
|
||||
l_parameters: STRING_TABLE [ANY]
|
||||
do
|
||||
write_information_log (generator + ".delete_node")
|
||||
|
||||
error_handler.reset
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_id, "nid")
|
||||
sql_change (sql_delete_node, l_parameters)
|
||||
end
|
||||
|
||||
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||
-- -- <Precursor>
|
||||
-- local
|
||||
-- l_parameters: STRING_TABLE [detachable ANY]
|
||||
-- do
|
||||
-- -- FIXME: unused a_user_id !
|
||||
-- error_handler.reset
|
||||
-- write_information_log (generator + ".update_node_title")
|
||||
-- create l_parameters.make (3)
|
||||
-- l_parameters.put (a_title, "title")
|
||||
-- l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||
-- l_parameters.put (a_node_id, "nid")
|
||||
-- sql_change (sql_update_node_title, l_parameters)
|
||||
-- end
|
||||
|
||||
-- update_node_summary (a_user_id: Like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||
-- -- <Precursor>
|
||||
-- local
|
||||
-- l_parameters: STRING_TABLE [detachable ANY]
|
||||
-- do
|
||||
-- -- FIXME: unused a_user_id !
|
||||
-- error_handler.reset
|
||||
-- write_information_log (generator + ".update_node_summary")
|
||||
-- create l_parameters.make (3)
|
||||
-- l_parameters.put (a_summary, "summary")
|
||||
-- l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||
-- l_parameters.put (a_node_id, "nid")
|
||||
-- sql_change (sql_update_node_summary, l_parameters)
|
||||
-- end
|
||||
|
||||
-- update_node_content (a_user_id: Like {CMS_USER}.id;a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||
-- -- <Precursor>
|
||||
-- local
|
||||
-- l_parameters: STRING_TABLE [detachable ANY]
|
||||
-- do
|
||||
-- -- FIXME: unused a_user_id !
|
||||
-- error_handler.reset
|
||||
-- write_information_log (generator + ".update_node_content")
|
||||
-- create l_parameters.make (3)
|
||||
-- l_parameters.put (a_content, "content")
|
||||
-- l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||
-- l_parameters.put (a_node_id, "nid")
|
||||
-- sql_change (sql_update_node_content, l_parameters)
|
||||
-- end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
store_node (a_node: CMS_NODE)
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
now: DATE_TIME
|
||||
do
|
||||
create now.make_now_utc
|
||||
error_handler.reset
|
||||
|
||||
write_information_log (generator + ".store_node")
|
||||
create l_parameters.make (8)
|
||||
l_parameters.put (a_node.content_type, "type")
|
||||
l_parameters.put (a_node.title, "title")
|
||||
l_parameters.put (a_node.summary, "summary")
|
||||
l_parameters.put (a_node.content, "content")
|
||||
l_parameters.put (a_node.format, "format")
|
||||
l_parameters.put (a_node.publication_date, "publish")
|
||||
l_parameters.put (now, "changed")
|
||||
if attached a_node.author as l_author then
|
||||
check valid_author: l_author.has_id end
|
||||
l_parameters.put (l_author.id, "author")
|
||||
else
|
||||
l_parameters.put (0, "author")
|
||||
end
|
||||
sql_begin_transaction
|
||||
if a_node.has_id then
|
||||
-- Update
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
sql_change (sql_update_node, l_parameters)
|
||||
if not error_handler.has_error then
|
||||
-- FIXED: FOR NOW no revision
|
||||
-- a_node.set_revision (a_node.revision + 1) -- FIXME: Should be incremented by one, in same transaction...but check!
|
||||
a_node.set_modification_date (now)
|
||||
end
|
||||
else
|
||||
-- Store new node
|
||||
l_parameters.put (a_node.creation_date, "created")
|
||||
sql_change (sql_insert_node, l_parameters)
|
||||
if not error_handler.has_error then
|
||||
a_node.set_modification_date (now)
|
||||
a_node.set_id (last_inserted_node_id)
|
||||
a_node.set_revision (1) -- New object.
|
||||
end
|
||||
end
|
||||
extended_store (a_node)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
fill_node (a_node: CMS_NODE)
|
||||
-- Fill `a_node' with extra information from database.
|
||||
-- i.e: specific to each content type data.
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".fill_node")
|
||||
extended_load (a_node)
|
||||
end
|
||||
|
||||
feature {NONE} -- Queries
|
||||
|
||||
sql_select_nodes_count: STRING = "SELECT count(*) from Nodes;"
|
||||
|
||||
sql_select_nodes: STRING = "SELECT * from Nodes;"
|
||||
-- SQL Query to retrieve all nodes.
|
||||
|
||||
sql_select_node_by_id: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed FROM Nodes WHERE nid =:nid ORDER BY revision desc, publish desc LIMIT 1;"
|
||||
|
||||
sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed FROM Nodes ORDER BY nid desc, publish desc LIMIT :rows OFFSET :offset ;"
|
||||
|
||||
sql_insert_node: STRING = "INSERT INTO nodes (revision, type, title, summary, content, format, publish, created, changed, author) VALUES (1, :type, :title, :summary, :content, :format, :publish, :created, :changed, :author);"
|
||||
-- SQL Insert to add a new node.
|
||||
|
||||
sql_update_node : STRING = "UPDATE nodes SET revision = revision, type=:type, title=:title, summary=:summary, content=:content, format=:format, publish=:publish, changed=:changed, author=:author WHERE nid=:nid;"
|
||||
-- FIXME: for now no revision inc.!
|
||||
-- sql_update_node : STRING = "UPDATE nodes SET revision = revision + 1, type=:type, title=:title, summary=:summary, content=:content, format=:format, publish=:publish, changed=:changed, revision = revision + 1, author=:author WHERE nid=:nid;"
|
||||
-- SQL node.
|
||||
|
||||
sql_delete_node: STRING = "DELETE FROM nodes WHERE nid=:nid;"
|
||||
|
||||
-- sql_update_node_author: STRING = "UPDATE nodes SET author=:author WHERE nid=:nid;"
|
||||
|
||||
-- sql_update_node_title: STRING ="UPDATE nodes SET title=:title, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
|
||||
-- -- SQL update node title.
|
||||
|
||||
-- sql_update_node_summary: STRING ="UPDATE nodes SET summary=:summary, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
|
||||
-- -- SQL update node summary.
|
||||
|
||||
-- sql_update_node_content: STRING ="UPDATE nodes SET content=:content, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
|
||||
-- -- SQL node content.
|
||||
|
||||
sql_last_insert_node_id: STRING = "SELECT MAX(nid) FROM nodes;"
|
||||
|
||||
feature {NONE} -- Sql Queries: USER_ROLES collaborators, author
|
||||
|
||||
Select_user_author: STRING = "SELECT uid, name, password, salt, email, status, created, signed FROM Nodes INNER JOIN users ON nodes.author=users.uid AND users.uid = :uid;"
|
||||
|
||||
Select_node_author: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed FROM users INNER JOIN nodes ON nodes.author=users.uid AND nodes.nid =:nid;"
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
fetch_node: detachable CMS_PARTIAL_NODE
|
||||
do
|
||||
if attached sql_read_string (3) as l_type then
|
||||
create Result.make_empty (l_type)
|
||||
|
||||
if attached sql_read_integer_64 (1) as l_id then
|
||||
Result.set_id (l_id)
|
||||
end
|
||||
if attached sql_read_integer_64 (2) as l_revision then
|
||||
Result.set_revision (l_revision)
|
||||
end
|
||||
if attached sql_read_string_32 (4) as l_title then
|
||||
Result.set_title (l_title)
|
||||
end
|
||||
if attached sql_read_string_32 (5) as l_summary then
|
||||
Result.set_summary (l_summary)
|
||||
end
|
||||
if attached sql_read_string (6) as l_content then
|
||||
Result.set_content (l_content)
|
||||
end
|
||||
if attached sql_read_string (7) as l_format then
|
||||
Result.set_format (l_format)
|
||||
end
|
||||
if attached sql_read_integer_64 (8) as l_author_id then
|
||||
Result.set_author (create {CMS_PARTIAL_USER}.make_with_id (l_author_id))
|
||||
end
|
||||
if attached sql_read_date_time (9) as l_publication_date then
|
||||
Result.set_publication_date (l_publication_date)
|
||||
end
|
||||
if attached sql_read_date_time (10) as l_creation_date then
|
||||
Result.set_creation_date (l_creation_date)
|
||||
end
|
||||
if attached sql_read_date_time (11) as l_modif_date then
|
||||
Result.set_modification_date (l_modif_date)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
fetch_author: detachable CMS_USER
|
||||
do
|
||||
if attached sql_read_string_32 (2) as l_name and then not l_name.is_whitespace then
|
||||
create Result.make (l_name)
|
||||
if attached sql_read_integer_32 (1) as l_id then
|
||||
Result.set_id (l_id)
|
||||
end
|
||||
if attached sql_read_string (3) as l_password then
|
||||
-- FIXME: should we return the password here ???
|
||||
Result.set_hashed_password (l_password)
|
||||
end
|
||||
if attached sql_read_string (5) as l_email then
|
||||
Result.set_email (l_email)
|
||||
end
|
||||
else
|
||||
check expected_valid_user: False end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
110
modules/node/persistence/cms_node_storage_sql_page_extension.e
Normal file
110
modules/node/persistence/cms_node_storage_sql_page_extension.e
Normal file
@@ -0,0 +1,110 @@
|
||||
note
|
||||
description: "Storage extension for Page nodes."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_NODE_STORAGE_SQL_PAGE_EXTENSION
|
||||
|
||||
inherit
|
||||
CMS_NODE_STORAGE_EXTENSION [CMS_PAGE]
|
||||
|
||||
CMS_PROXY_STORAGE_SQL
|
||||
rename
|
||||
sql_storage as node_storage
|
||||
redefine
|
||||
node_storage
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
node_storage: CMS_NODE_STORAGE_SQL
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: STRING
|
||||
once
|
||||
Result := {CMS_PAGE_NODE_TYPE}.name
|
||||
end
|
||||
|
||||
feature -- Persistence
|
||||
|
||||
store (a_node: CMS_PAGE)
|
||||
local
|
||||
l_parameters: STRING_TABLE [ANY]
|
||||
l_new_parent_id, l_previous_parent_id: INTEGER_64
|
||||
l_update: BOOLEAN
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".store_page_data")
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
l_parameters.put (a_node.revision, "revision")
|
||||
|
||||
sql_query (sql_select_page_data, l_parameters)
|
||||
if not has_error then
|
||||
if sql_rows_count = 1 then
|
||||
l_previous_parent_id := sql_read_integer_64 (3)
|
||||
l_update := True
|
||||
end
|
||||
if attached a_node.parent as l_parent then
|
||||
l_new_parent_id := l_parent.id
|
||||
else
|
||||
l_new_parent_id := 0
|
||||
end
|
||||
l_parameters.put (l_new_parent_id, "parent")
|
||||
if l_update and l_new_parent_id /= l_previous_parent_id then
|
||||
sql_change (sql_update_page_data, l_parameters)
|
||||
elseif l_new_parent_id > 0 then
|
||||
sql_change (sql_insert_page_data, l_parameters)
|
||||
else
|
||||
-- no page data, means everything is empty.
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
load (a_node: CMS_PAGE)
|
||||
local
|
||||
l_parameters: STRING_TABLE [ANY]
|
||||
n: INTEGER
|
||||
ct: CMS_PAGE_NODE_TYPE
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".fill_page")
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
l_parameters.put (a_node.revision, "revision")
|
||||
sql_query (sql_select_page_data, l_parameters)
|
||||
if not has_error then
|
||||
n := sql_rows_count
|
||||
if n = 1 then
|
||||
-- nid, revision, parent
|
||||
if
|
||||
attached sql_read_integer_64 (3) as l_parent_id and then
|
||||
l_parent_id /= a_node.id and then
|
||||
attached node_storage.node_by_id (l_parent_id) as l_parent
|
||||
then
|
||||
-- FIXME: find a simple way to access the declared content types.
|
||||
create ct
|
||||
a_node.set_parent (ct.new_node (l_parent))
|
||||
else
|
||||
write_debug_log ("Invalid parent node id!")
|
||||
end
|
||||
else
|
||||
check unique_data: n = 0 end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- SQL
|
||||
|
||||
sql_select_page_data: STRING = "SELECT nid, revision, parent FROM page_nodes WHERE nid =:nid AND revision=:revision;"
|
||||
sql_insert_page_data: STRING = "INSERT INTO page_nodes (nid, revision, parent) VALUES (:nid, :revision, :parent);"
|
||||
sql_update_page_data: STRING = "UPDATE page_nodes SET nid=:nid, revision=:revision, parent=:parent WHERE nid=:nid AND revision=:revision;"
|
||||
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user