Added support for log stored in CMS_STORAGE.

Added support for custom value stored in CMS_STORAGE.
Added optional css classes addition to CMS_BLOCK output.
Refactored storage, to manage node from node module code only (or mostly).

TODO: improved view for a cms node, for now hardcoded.
This commit is contained in:
2015-04-15 16:39:03 +02:00
parent 2b25c23977
commit f2bb061488
59 changed files with 1693 additions and 414 deletions

View File

@@ -88,7 +88,7 @@ feature -- Handler
local
sql: STRING
do
if attached {CMS_STORAGE_SQL} a_api.storage as sql_db then
if attached {CMS_STORAGE_SQL_I} a_api.storage as sql_db then
sql_db.sql_query ("select count(*) from tb_demo;", Void)
if sql_db.has_error then
-- Initialize db for demo module

View File

@@ -1,4 +1,5 @@
BEGIN;
CREATE TABLE "users"(
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
"name" VARCHAR(100) NOT NULL,
@@ -30,4 +31,21 @@ CREATE TABLE "role_permissions"(
"module" VARCHAR(255)
);
CREATE TABLE "logs"(
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
"category" VARCHAR(255) NOT NULL,
"level" INTEGER NOT NULL CHECK("level">=1),
"uid" INTEGER,
"message" TEXT NOT NULL,
"info" TEXT,
"link" TEXT,
"date" DATETIME NOT NULL
);
CREATE TABLE "custom_values"(
"type" VARCHAR(255) NOT NULL,
"name" VARCHAR(255) NOT NULL,
"value" VARCHAR(255) NOT NULL
);
COMMIT;

View File

@@ -5,8 +5,9 @@ CREATE TABLE "nodes"(
"revision" INTEGER,
"type" TEXT NOT NULL,
"title" VARCHAR(255) NOT NULL,
"summary" TEXT NOT NULL,
"summary" TEXT,
"content" MEDIUMTEXT NOT NULL,
"format" VARCHAR(255),
"author" INTEGER,
"publish" DATETIME,
"created" DATETIME NOT NULL,

View File

@@ -37,6 +37,16 @@ ul.horizontal li {
#content {
margin-left: 20px;
}
#content #highlighted {
position: relative;
border: solid 1px #ddd;
background-color: #ffc;
width: 70%;
left: 15%;
right: 15%;
padding: 5px;
font-style: italic;
}
.sidebar {
padding: 5px;
@@ -51,3 +61,18 @@ ul.horizontal li {
width: 250px;
float: right;
}
#primary-tabs ul.horizontal {
list-style-type: none;
}
#primary-tabs ul.horizontal li {
display: inline;
padding: 2px 5px;
border: solid 1px #ccf;
}
#primary-tabs ul.horizontal li.active {
border-color: #99f #99f #ddd;
border-style: solid solid none;
border-width: 2px 1px 0;
padding: 2px 7px 1px;
}

View File

@@ -65,3 +65,19 @@ ul.horizontal {
float: right;
}
}
#primary-tabs {
ul.horizontal {
list-style-type: none;
li {
display: inline;
padding: 2px 5px;
border: solid 1px #ccf;
}
li.active {
border-color: #99f #99f #ddd;
border-style: solid solid none;
border-width: 2px 1px 0;
padding: 2px 7px 1px;
}
}
}

View File

@@ -0,0 +1,127 @@
note
description: "Summary description for {CMS_LOG}."
date: "$Date$"
revision: "$Revision$"
class
CMS_LOG
create
make
feature {NONE} -- Initialization
make (a_category: like category; a_message: like message; a_level: like level; a_date: detachable like date)
do
category := a_category
message := a_message
set_level (a_level)
if a_date = Void then
create date.make_now_utc
else
date := a_date
end
end
make_with_id (a_id: like id; a_category: like category; a_message: like message; a_level: like level; a_date: detachable like date)
do
id := a_id
make (a_category, a_message, a_level, a_date)
end
feature -- Access
id: INTEGER
-- Unique identifier of Current.
category: READABLE_STRING_8
-- Associated title (optional).
message: READABLE_STRING_8
-- Log message
level: INTEGER
-- Severity level
level_name: STRING
do
Result := level_to_string (level)
end
info: detachable READABLE_STRING_8
link: detachable CMS_LINK
date: DATE_TIME
feature -- status report
has_id: BOOLEAN
do
Result := id > 0
end
feature -- Change
set_id (a_id: like id)
require
not has_id
do
id := a_id
end
set_level (a_level: like level)
do
if a_level = 0 then
level := level_notice
else
level := a_level
end
end
set_link (lnk: like link)
do
link := lnk
end
set_info (inf: like info)
do
info := inf
end
feature -- Constants
level_to_string (a_level: INTEGER): STRING
do
inspect a_level
when level_emergency then
Result := "emergency"
when level_alert then
Result := "alert"
when level_critical then
Result := "critical"
when level_error then
Result := "error"
when level_warning then
Result := "warning"
when level_notice then
Result := "notice"
when level_info then
Result := "info"
when level_debug then
Result := "debug"
else
Result := "level-" + a_level.out
end
end
level_emergency: INTEGER = 1
level_alert: INTEGER = 2
level_critical: INTEGER = 3
level_error: INTEGER = 4
level_warning: INTEGER = 5
level_notice: INTEGER = 6
level_info: INTEGER = 7
level_debug: INTEGER = 8
end

View File

@@ -10,7 +10,7 @@ deferred class
inherit
CMS_STORAGE
CMS_STORAGE_SQL
CMS_STORAGE_SQL_I
feature {NONE} -- Initialization

View File

@@ -1,79 +0,0 @@
note
description: "Summary description for {CMS_NODE_STORAGE_MYSQL}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_NODE_STORAGE_MYSQL
inherit
CMS_NODE_STORAGE_SQL
redefine
nodes, recent_nodes
end
feature {NONE} -- Implementation
db_handler: DATABASE_HANDLER
deferred
end
feature -- Access
nodes: LIST [CMS_NODE]
-- List of nodes.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
across nodes_iterator as ic loop
if attached ic.item as l_node then
Result.force (l_node)
end
end
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of recent `a_count' nodes with an offset of `lower'.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
across recent_nodes_iterator (a_lower, a_count) as ic loop
if attached ic.item as l_node then
Result.force (l_node)
end
end
end
feature -- Access: iterator
nodes_iterator: DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
-- List of nodes.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
write_information_log (generator + ".nodes_iterator")
create l_parameters.make (0)
sql_query (sql_select_nodes, l_parameters)
create Result.make (db_handler, agent fetch_node)
sql_post_execution
end
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
-- The most recent `a_rows'.
local
l_parameters: STRING_TABLE [ANY]
l_query: STRING
do
-- FIXME: check implementation...
error_handler.reset
write_information_log (generator + ".recent_nodes_iterator")
create l_parameters.make (2)
l_parameters.put (a_rows, "rows")
l_parameters.put (a_lower, "offset")
create l_query.make_from_string (sql_select_recent_nodes)
sql_query (l_query, l_parameters)
create Result.make (db_handler, agent fetch_node)
sql_post_execution
end
end

View File

@@ -7,13 +7,11 @@ class
CMS_STORAGE_MYSQL
inherit
CMS_STORAGE
CMS_STORAGE_STORE_SQL
CMS_USER_STORAGE_MYSQL
CMS_CORE_STORAGE_SQL_I
CMS_NODE_STORAGE_MYSQL
CMS_USER_STORAGE_SQL_I
REFACTORING_HELPER

View File

@@ -10,7 +10,7 @@ class
CMS_STORAGE_MYSQL_BUILDER
inherit
CMS_STORAGE_BUILDER
CMS_STORAGE_SQL_BUILDER
create
make

View File

@@ -1,77 +0,0 @@
note
description: "Summary description for {CMS_NODE_STORAGE_SQLITE}."
author: ""
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
deferred class
CMS_NODE_STORAGE_SQLITE
inherit
CMS_NODE_STORAGE_SQL
redefine
nodes, recent_nodes
end
feature {NONE} -- Implementation
db_handler: DATABASE_HANDLER
deferred
end
feature -- Access
nodes: LIST [CMS_NODE]
-- List of nodes.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
across nodes_iterator as ic loop
if attached ic.item as l_node then
Result.force (l_node)
end
end
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of recent `a_count' nodes with an offset of `lower'.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
across recent_nodes_iterator (a_lower, a_count) as ic loop
if attached ic.item as l_node then
Result.force (l_node)
end
end
end
feature -- Access: iterator
nodes_iterator: DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
-- List of nodes.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
write_information_log (generator + ".nodes_iterator")
create l_parameters.make (0)
sql_query (sql_select_nodes, l_parameters)
create Result.make (db_handler, agent fetch_node)
end
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
-- The most recent `a_rows'.
local
l_parameters: STRING_TABLE [ANY]
l_query: STRING
do
-- FIXME: check implementation...
error_handler.reset
write_information_log (generator + ".recent_nodes_iterator")
create l_parameters.make (2)
l_parameters.put (a_rows, "rows")
l_parameters.put (a_lower, "offset")
create l_query.make_from_string (sql_select_recent_nodes)
sql_query (l_query, l_parameters)
create Result.make (db_handler, agent fetch_node)
end
end

View File

@@ -7,13 +7,11 @@ class
CMS_STORAGE_SQLITE
inherit
CMS_STORAGE
CMS_STORAGE_STORE_SQL
CMS_USER_STORAGE_SQLITE
CMS_CORE_STORAGE_SQL_I
CMS_NODE_STORAGE_SQLITE
CMS_USER_STORAGE_SQL_I
REFACTORING_HELPER
@@ -27,5 +25,5 @@ feature -- Status report
do
Result := has_user
end
end

View File

@@ -10,7 +10,7 @@ class
CMS_STORAGE_SQLITE_BUILDER
inherit
CMS_STORAGE_BUILDER
CMS_STORAGE_SQL_BUILDER
create
make
@@ -66,6 +66,11 @@ feature -- Factory
r.add_permission ("create page")
r.add_permission ("edit page")
a_storage.save_user_role (r)
-- Test custom value
a_storage.set_custom_value ("abc", "123", "test")
a_storage.set_custom_value ("abc", "OK", "test")
end
end

View File

@@ -1,14 +0,0 @@
note
description: "Summary description for {CMS_USER_STORAGE_SQLITE}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_USER_STORAGE_SQLITE
inherit
CMS_USER_STORAGE_SQL
end

View File

@@ -20,6 +20,9 @@ feature -- Access
deferred
end
html_options: detachable CMS_HTML_OPTIONS
-- Optional addition html options.
feature -- status report
is_enabled: BOOLEAN
@@ -31,6 +34,34 @@ feature -- status report
deferred
end
feature -- Element change
add_css_class (a_class: READABLE_STRING_8)
-- Add css class `a_class'.
local
opts: like html_options
do
opts := html_options
if opts = Void then
create opts
html_options := opts
end
opts.add_css_class (a_class)
end
remove_css_class (a_class: READABLE_STRING_GENERAL)
-- Remove css class `a_class'.
local
opts: like html_options
do
opts := html_options
if opts = Void then
create opts
html_options := opts
end
opts.remove_css_class (a_class)
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8

View File

@@ -46,7 +46,7 @@ feature -- Access
feature -- Status report
is_raw: BOOLEAN
is_raw: BOOLEAN assign set_is_raw
-- Is raw?
-- If True, do not get wrapped it with block specific div

View File

@@ -31,9 +31,10 @@ feature -- Access
feature -- Status report
is_horizontal: BOOLEAN
is_horizontal: BOOLEAN assign set_is_horizontal
-- Is horizontal layout for the menu?
is_raw: BOOLEAN = False
is_raw: BOOLEAN assign set_is_raw
-- <Precursor>
feature -- Element change
@@ -52,11 +53,23 @@ feature -- Element change
title := a_title
end
set_is_horizontal (b: BOOLEAN)
-- Set `is_horizontal' to `b'.
do
is_horizontal := b
end
set_is_raw (b: BOOLEAN)
-- Set `is_raw' to `b'.
do
is_raw := b
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := a_theme.menu_html (menu, is_horizontal)
Result := a_theme.menu_html (menu, is_horizontal, html_options)
end
end

View File

@@ -9,9 +9,8 @@ class
feature -- Access
item (a_name: detachable READABLE_STRING_GENERAL): CONTENT_FORMAT
item (a_name: detachable READABLE_STRING_GENERAL): detachable CONTENT_FORMAT
do
Result := default_format
if a_name /= Void then
across
all_formats as c

View File

@@ -51,7 +51,7 @@ feature -- HTTP Methods
api.logger.put_information (generator + ".do_get Processing basic auth logoff", Void)
if attached req.query_parameter ("prompt") as l_prompt then
unset_current_user (req)
send_access_denied (res)
send_access_denied_message (res)
else
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
unset_current_user (req)

View File

@@ -36,6 +36,11 @@ feature {CMS_API} -- Module Initialization
-- Redefine to process specific module initialization.
end
feature {CMS_API} -- Access: API
module_api: detachable CMS_MODULE_API
-- Eventual module api.
feature {CMS_API} -- Module management
is_installed (api: CMS_API): BOOLEAN

View File

@@ -26,10 +26,22 @@ feature -- Access
deferred
end
feature -- Access
available_formats: LIST [CONTENT_FORMAT]
-- Available formats for Current type.
deferred
end
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): CMS_NODE
-- New node based on partial `a_partial_node', or from none.
-- New node based on partial `a_partial_node' if set.
deferred
end

View File

@@ -25,16 +25,30 @@ feature {NONE} -- Implementation
-- <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_content_types
end
initialize_content_types
-- Initialize content type system.
local
ct: CMS_PAGE_CONTENT_TYPE
do
create content_types.make (1)
add_content_type (create {CMS_PAGE_CONTENT_TYPE})
create content_type_webform_managers.make (1)
create ct
add_content_type (ct)
add_content_type_webform_manager (create {CMS_PAGE_CONTENT_TYPE_WEBFORM_MANAGER}.make (ct))
end
feature {NODE_MODULE} -- Access nodes storage.
node_storage: CMS_NODE_STORAGE_I
feature -- Content type
content_types: ARRAYED_LIST [CMS_CONTENT_TYPE]
@@ -59,6 +73,30 @@ feature -- Content type
end
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_type: CMS_CONTENT_TYPE_WEBFORM_MANAGER)
do
content_type_webform_managers.force (a_type)
end
content_type_webform_manager (a_name: READABLE_STRING_GENERAL): detachable CMS_CONTENT_TYPE_WEBFORM_MANAGER
do
across
content_type_webform_managers 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
feature -- URL
new_content_path (ct: detachable CMS_CONTENT_TYPE): STRING
@@ -91,19 +129,19 @@ feature -- Access: Node
nodes_count: INTEGER_64
do
Result := storage.nodes_count
Result := node_storage.nodes_count
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
Result := storage.nodes
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 := storage.recent_nodes (a_offset, a_rows)
Result := node_storage.recent_nodes (a_offset, a_rows)
end
node (a_id: INTEGER_64): detachable CMS_NODE
@@ -112,7 +150,7 @@ feature -- Access: Node
debug ("refactor_fixme")
fixme ("Check preconditions")
end
Result := full_node (storage.node_by_id (a_id))
Result := full_node (node_storage.node_by_id (a_id))
end
full_node (a_node: detachable CMS_NODE): detachable CMS_NODE
@@ -122,7 +160,7 @@ feature -- Access: Node
if attached {CMS_PARTIAL_NODE} a_node as l_partial_node then
if attached content_type (l_partial_node.content_type) as ct then
Result := ct.new_node (l_partial_node)
storage.fill_node (Result)
node_storage.fill_node (Result)
else
Result := l_partial_node
end
@@ -147,26 +185,32 @@ feature -- Access: Node
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
storage.new_node (a_node)
node_storage.new_node (a_node)
end
delete_node (a_node: CMS_NODE)
-- Delete `a_node'.
do
if a_node.has_id then
storage.delete_node (a_node)
node_storage.delete_node (a_node)
end
end
update_node (a_node: CMS_NODE)
-- Update node `a_node' data.
do
storage.update_node (a_node)
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)
@@ -175,7 +219,7 @@ feature -- Change: Node
-- debug ("refactor_fixme")
-- fixme ("Check preconditions")
-- end
-- storage.update_node_title (a_user_id, a_node_id, a_title)
-- 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)
@@ -184,7 +228,7 @@ feature -- Change: Node
-- debug ("refactor_fixme")
-- fixme ("Check preconditions")
-- end
-- storage.update_node_summary (a_user_id, a_node_id, a_summary)
-- 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)
@@ -193,7 +237,7 @@ feature -- Change: Node
-- debug ("refactor_fixme")
-- fixme ("Check preconditions")
-- end
-- storage.update_node_content (a_user_id, a_node_id, a_content)
-- node_storage.update_node_content (a_user_id, a_node_id, a_content)
-- end

View File

@@ -9,6 +9,20 @@ class
inherit
CMS_CONTENT_TYPE
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
@@ -21,8 +35,23 @@ feature -- Access
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

View File

@@ -0,0 +1,44 @@
note
description: "Summary description for {CMS_CONTENT_TYPE_WEBFORM_MANAGER}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_CONTENT_TYPE_WEBFORM_MANAGER
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
do
Result := content_type.name
end
feature -- Forms ...
fill_edit_form (response: NODE_RESPONSE; a_form: WSF_FORM; a_node: detachable CMS_NODE)
deferred
end
new_node (response: NODE_RESPONSE; a_form_data: WSF_FORM_DATA; a_node: detachable CMS_NODE): CMS_NODE
deferred
-- Result := content_type.new_node (a_node)
end
change_node (response: NODE_RESPONSE; a_form_data: WSF_FORM_DATA; a_node: CMS_NODE)
require
a_node.has_id
deferred
end
end

View File

@@ -0,0 +1,160 @@
note
description: "Summary description for {CMS_PAGE_CONTENT_TYPE_WEBFORM_MANAGER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_PAGE_CONTENT_TYPE_WEBFORM_MANAGER
inherit
CMS_CONTENT_TYPE_WEBFORM_MANAGER
redefine
content_type
end
create
make
feature -- Access
content_type: CMS_PAGE_CONTENT_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
end

View File

@@ -0,0 +1,214 @@
note
description: "Summary description for {NODE_FORM_RESPONSE}."
author: ""
date: "$Date$"
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.content_type (l_node.content_type) 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
set_title ("Edit #" + 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>Access denied</h1>")
end
else
set_title ("Unknown node")
end
else
set_title ("Create new content ...")
b.append ("<ul id=%"content-types%">")
across
node_api.content_types as c
loop
if has_permission ("create " + c.item.name) then
b.append ("<li>" + link (c.item.name, "/node/add/" + c.item.name, Void))
if attached c.item.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_CONTENT_TYPE; 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
change_node (a_type, fd, a_node)
s := "modified"
else
l_node := new_node (a_type, fd, Void)
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_CONTENT_TYPE): 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_CONTENT_TYPE; a_form_data: WSF_FORM_DATA; a_node: detachable CMS_NODE): CMS_NODE
do
if attached node_api.content_type_webform_manager (a_content_type.name) 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_CONTENT_TYPE; a_form_data: WSF_FORM_DATA; a_node: CMS_NODE)
do
if attached node_api.content_type_webform_manager (a_content_type.name) as wf then
wf.change_node (Current, a_form_data, a_node)
end
end
fill_edit_form (a_content_type: CMS_CONTENT_TYPE; a_form: WSF_FORM; a_node: detachable CMS_NODE)
do
if attached node_api.content_type_webform_manager (a_content_type.name) as wf then
wf.fill_edit_form (Current, a_form, a_node)
end
end
end

View File

@@ -1,5 +1,5 @@
note
description: "CMS handler for a node."
description: "handler for CMS node in the CMS interface."
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
@@ -64,16 +64,34 @@ feature -- HTTP Methods
l_page: CMS_RESPONSE
s: STRING
hdate: HTTP_DATE
lnk: CMS_LOCAL_LINK
l_node: detachable CMS_NODE
l_nid: INTEGER_64
edit_response: NODE_FORM_RESPONSE
do
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached {CMS_NODE} node_api.node (l_id.value.to_integer_64) as l_node
then
-- FIXME: there is a mix between CMS interface and API interface here.
if req.path_info.ends_with_general ("/edit") then
create edit_response.make (req, res, api, node_api)
edit_response.execute
else
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer then
l_nid := l_id.value.to_integer_64
end
end
if l_nid > 0 then
l_node := node_api.node (l_nid)
end
if l_node /= Void then
-- FIXME: allow a per content type display here!
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (l_node, "node")
create lnk.make ("View", node_api.node_path (l_node))
lnk.set_weight (1)
l_page.add_to_primary_tabs (lnk)
create lnk.make ("Edit", node_api.node_path (l_node) + "/edit")
lnk.set_weight (2)
l_page.add_to_primary_tabs (lnk)
create s.make_empty
s.append ("<div class=%"info%"> ")
@@ -90,7 +108,12 @@ feature -- HTTP Methods
s.append ("</div>")
if attached l_node.content as l_content then
s.append ("<p class=%"content%">")
s.append (api.formats.item (l_node.format).formatted_output (l_content))
if attached api.format (l_node.format) as f then
s.append (f.formatted_output (l_content))
else
s.append (api.formats.default_format.formatted_output (l_content))
end
s.append ("</p>")
end
if attached {CMS_PAGE} l_node as l_node_page then
@@ -103,74 +126,66 @@ feature -- HTTP Methods
l_page.set_title (l_node.title)
l_page.set_main_content (s)
l_page.execute
elseif l_nid > 0 then --| i.e: l_node = Void
send_not_found (req, res)
else
do_error (req, res, l_id)
send_bad_request (req, res)
-- FIXME: should not be accepted
-- Factory
-- create_new_node (req, res)
end
else
-- Factory
new_node (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
edit_response: NODE_FORM_RESPONSE
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
if req.path_info.ends_with_general ("/edit") then
create edit_response.make (req, res, api, node_api)
edit_response.execute
else
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
process_node_update (req, res, l_user, l_node)
-- Accept this, even if this is not proper usage of POST
-- (create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
end
else
do_error (req, res, l_id)
end
else
do_error (req, res, l_id)
process_node_creation (req, res, l_user)
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)
send_access_denied (req, 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)
process_node_update (req, res, l_user, l_node)
else
do_error (req, res, l_id)
end
@@ -178,21 +193,25 @@ feature -- HTTP Methods
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
send_access_denied (res)
send_access_denied (req, res)
end
end
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user_name (req) then
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
node_api.delete_node (l_node)
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
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
@@ -200,20 +219,65 @@ feature -- HTTP Methods
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
send_access_denied (res)
send_access_denied (req, res)
end
end
process_node_creation (req: WSF_REQUEST; res: WSF_RESPONSE; a_user: CMS_USER)
local
u_node: CMS_NODE
do
-- New node
-- FIXME !!!
if
attached {WSF_STRING} req.form_parameter ("type") as p_type and then
attached node_api.content_type (p_type.value) as ct -- should be string 8 value.
then
if api.user_has_permission (a_user, "create " + ct.name) then
u_node := ct.new_node (Void)
-- create {CMS_PARTIAL_NODE} u_node.make_empty (p_type.url_encoded_value)
update_node_from_data_form (req, u_node)
u_node.set_author (a_user)
node_api.new_node (u_node)
if attached {WSF_STRING} req.item ("destination") as p_destination then
redirect_to (req.absolute_script_url (p_destination.url_encoded_value), res)
else
redirect_to (req.absolute_script_url (""), res)
end
else
send_access_denied (req, res)
end
else
do_error (req, res, Void)
end
end
process_node_update (req: WSF_REQUEST; res: WSF_RESPONSE; a_user: CMS_USER; a_node: CMS_NODE)
do
if api.user_has_permission (a_user, "modify " + a_node.content_type) then
update_node_from_data_form (req, a_node)
a_node.set_author (a_user)
node_api.update_node (a_node)
if attached {WSF_STRING} req.item ("destination") as p_destination then
redirect_to (req.absolute_script_url (p_destination.url_encoded_value), res)
else
redirect_to (req.absolute_script_url (""), res)
end
else
send_access_denied (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
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.is_integer then
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)
@@ -227,7 +291,7 @@ feature -- Error
feature {NONE} -- Node
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
create_new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: CMS_RESPONSE
do
@@ -235,7 +299,7 @@ feature {NONE} -- Node
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.execute
else
send_access_denied (res)
send_access_denied (req, res)
end
end
@@ -267,4 +331,5 @@ feature -- {NONE} Form data
a_node.set_content (l_content, l_summary, l_format)
end
end

View File

@@ -0,0 +1,86 @@
note
description: "Summary description for {NODE_RESPONSE}."
author: ""
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
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

View File

@@ -0,0 +1,59 @@
note
description: "Summary description for {WSF_CMS_THEME}."
author: ""
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

View 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

View File

@@ -9,11 +9,14 @@ class
inherit
CMS_MODULE
rename
module_api as node_api
redefine
register_hooks,
initialize,
is_installed,
install
install,
node_api
end
CMS_HOOK_MENU_SYSTEM_ALTER
@@ -45,31 +48,38 @@ feature {CMS_API} -- Module Initialization
local
p1,p2: CMS_PAGE
ct: CMS_PAGE_CONTENT_TYPE
l_node_api: like node_api
do
Precursor (api)
if attached {CMS_NODE_STORAGE_SQL} api.storage as l_sql_storage then
l_sql_storage.register_node_storage_extension (create {CMS_NODE_STORAGE_SQL_PAGE_EXTENSION}.make (l_sql_storage))
if l_sql_storage.sql_table_items_count ("page_nodes") = 0 then
-- Data
-- FIXME: for test purpose, remove later
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", "Welcome Eiffel ROC user", Void) -- Use default format
p1.set_content ("Welcome, you are using the ROC Eiffel CMS", Void, Void) -- Use default format
p1.set_author (u)
api.storage.save_node (p1)
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", "This is a new page", Void) -- Use default format
p2.set_content ("This is the content of a page", Void, Void) -- Use default format
p2.set_author (u)
p2.set_parent (p1)
api.storage.save_node (p2)
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
@@ -78,7 +88,7 @@ feature {CMS_API} -- Module management
is_installed (api: CMS_API): BOOLEAN
-- Is Current module installed?
do
if attached {CMS_STORAGE_SQL} api.storage as l_sql_storage then
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
@@ -87,19 +97,28 @@ feature {CMS_API} -- Module management
install (api: CMS_API)
do
-- Schema
if attached {CMS_STORAGE_SQL} api.storage as l_sql_storage then
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
l_sql_storage.sql_execute_file_script (api.setup.layout.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: CMS_NODE_API
l_node_api: like node_api
do
create l_node_api.make (a_api)
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_cms (a_api, l_node_api, Result)
-- configure_api (a_api, l_node_api, Result)

View File

@@ -1,5 +1,5 @@
note
description: "Proxy on a {CMS_STORAGE_SQL} interface."
description: "Proxy on a {CMS_STORAGE_SQL_I} interface."
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
@@ -7,7 +7,7 @@ class
CMS_PROXY_STORAGE_SQL
inherit
CMS_STORAGE_SQL
CMS_STORAGE_SQL_I
create
make
@@ -19,7 +19,7 @@ feature {NONE} -- Initialization
sql_storage := a_sql_storage
end
sql_storage: CMS_STORAGE_SQL
sql_storage: CMS_STORAGE_SQL_I
feature -- Access

View File

@@ -10,9 +10,9 @@ deferred class
CMS_STORAGE
inherit
CMS_USER_STORAGE
CMS_CORE_STORAGE_I
CMS_NODE_STORAGE
CMS_USER_STORAGE_I
SHARED_LOGGER
@@ -52,21 +52,4 @@ feature -- Element change
api := a_api
end
feature -- Misc
-- set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: READABLE_STRING_8)
-- -- Save data `a_name:a_value' for type `a_type'
-- deferred
-- end
-- custom_value (a_name: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable TABLE_ITERABLE [READABLE_STRING_8, STRING_8]
-- -- Data for name `a_name' and type `a_type'.
-- deferred
-- end
-- custom_value_names_where (a_where_key, a_where_value: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable LIST [READABLE_STRING_8]
-- -- Names where custom value has item `a_where_key' same as `a_where_value' for type `a_type'.
-- deferred
-- end
end

View File

@@ -12,6 +12,7 @@ deferred class
feature -- Factory
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE
-- CMS Storage object based on CMS setup `a_setup'.
deferred
end

View File

@@ -120,80 +120,29 @@ feature -- Change: roles and permissions
do
end
feature -- Access: node
nodes_count: INTEGER_64
-- Count of nodes.
feature -- Logs
save_log (a_log: CMS_LOG)
-- Save `a_log'.
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>
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8)
-- Save data `a_name:a_value' for type `a_type' (or default if none).
do
end
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
-- Node's author. if any.
unset_custom_value (a_name: READABLE_STRING_8; a_type: detachable READABLE_STRING_8)
-- Delete data `a_name' for type `a_type' (or default if none).
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
custom_value (a_name: READABLE_STRING_GENERAL; a_type: detachable READABLE_STRING_8): detachable READABLE_STRING_32
-- Data for name `a_name' and type `a_type' (or default if none).
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

View File

@@ -1,14 +1,15 @@
note
description: "Summary description for {CMS_USER_STORAGE_MYSQL}."
author: ""
description: "[
Objects that ...
]"
author: "$Author: jfiat $"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_USER_STORAGE_MYSQL
CMS_STORAGE_SQL_BUILDER
inherit
CMS_USER_STORAGE_SQL
CMS_STORAGE_BUILDER
end

View File

@@ -1,11 +1,10 @@
note
description: "Summary description for {CMS_STORAGE_SQL}."
author: ""
description: "Interface used to implement CMS Storage based on SQL statement."
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
deferred class
CMS_STORAGE_SQL
CMS_STORAGE_SQL_I
feature -- Access
@@ -161,6 +160,7 @@ feature -- Helper
sql_query ("SELECT count(*) FROM :tbname ;", l_params)
Result := not has_error
-- FIXME: find better solution
reset_error
end
sql_table_items_count (a_table_name: READABLE_STRING_8): INTEGER_64
@@ -252,7 +252,7 @@ feature -- Access
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then
Result := l_boolean_ref.item.out
else
check is_string: False end
check is_string_nor_null: l_item = Void end
end
end
@@ -269,7 +269,7 @@ feature -- Access
if attached sql_read_string (a_index) as s8 then
Result := s8.to_string_32 -- FIXME: any escape?
else
check is_string_32: False end
check is_string_nor_null: l_item = Void end
end
end
end
@@ -283,7 +283,7 @@ feature -- Access
if attached {DATE_TIME} l_item as dt then
Result := dt
else
-- check is_date_time: False end
check is_date_time_nor_null: l_item = Void end
end
end

View File

@@ -0,0 +1,47 @@
note
description: "[
Objects that ...
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_CORE_STORAGE_I
inherit
SHARED_LOGGER
feature -- Error Handling
error_handler: ERROR_HANDLER
-- Error handler.
deferred
end
feature -- Logs
save_log (a_log: CMS_LOG)
-- Save `a_log'.
deferred
end
feature -- Misc
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8)
-- Save data `a_name:a_value' for type `a_type' (or default if none).
deferred
end
unset_custom_value (a_name: READABLE_STRING_8; a_type: detachable READABLE_STRING_8)
-- Delete data `a_name' for type `a_type' (or default if none).
deferred
end
custom_value (a_name: READABLE_STRING_GENERAL; a_type: detachable READABLE_STRING_8): detachable READABLE_STRING_32
-- Data for name `a_name' and type `a_type' (or default if none).
deferred
end
end

View File

@@ -0,0 +1,138 @@
note
description: "[
Objects that ...
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_CORE_STORAGE_SQL_I
inherit
CMS_CORE_STORAGE_I
CMS_STORAGE_SQL_I
REFACTORING_HELPER
SHARED_LOGGER
feature -- Logs
save_log (a_log: CMS_LOG)
-- Save `a_log'.
local
l_parameters: STRING_TABLE [detachable ANY]
now: DATE_TIME
s32: STRING_32
do
create now.make_now_utc
error_handler.reset
create l_parameters.make (8)
l_parameters.put (a_log.category, "category")
l_parameters.put (a_log.level, "level")
l_parameters.put (0, "uid") -- Unsupported for now
l_parameters.put (a_log.message, "message")
l_parameters.put (a_log.info, "info")
if attached a_log.link as lnk then
create s32.make_empty
s32.append_character ('[')
s32.append_string_general (lnk.location)
s32.append_character (']')
s32.append_character ('(')
s32.append (lnk.title)
s32.append_character (')')
l_parameters.put (s32, "link")
else
l_parameters.put (Void, "link")
end
l_parameters.put (now, "date")
sql_change (sql_insert_log, l_parameters)
end
sql_insert_log: STRING = "INSERT INTO logs (category, level, uid, message, info, link, date) VALUES (:category, :level, :uid, :message, :info, :link, :date);"
-- SQL Insert to add a new node.
feature -- Misc
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8)
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
create l_parameters.make (3)
if a_type /= Void then
l_parameters.put (a_type, "type")
else
l_parameters.put (a_type, "default")
end
l_parameters.put (a_name, "name")
l_parameters.put (a_value, "value")
if attached custom_value (a_name, a_type) as l_value then
if a_value.same_string (l_value) then
-- already up to date
else
sql_change (sql_update_custom_value, l_parameters)
end
else
sql_change (sql_insert_custom_value, l_parameters)
end
end
unset_custom_value (a_name: READABLE_STRING_8; a_type: detachable READABLE_STRING_8)
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
create l_parameters.make (3)
if a_type /= Void then
l_parameters.put (a_type, "type")
else
l_parameters.put (a_type, "default")
end
l_parameters.put (a_name, "name")
sql_change (sql_delete_custom_value, l_parameters)
end
custom_value (a_name: READABLE_STRING_GENERAL; a_type: detachable READABLE_STRING_8): detachable READABLE_STRING_32
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
create l_parameters.make (2)
if a_type /= Void then
l_parameters.put (a_type, "type")
else
l_parameters.put (a_type, "default")
end
l_parameters.put (a_name, "name")
sql_query (sql_select_custom_value, l_parameters)
if not has_error then
if sql_rows_count = 1 then
Result := sql_read_string_32 (1)
end
end
end
sql_select_custom_value: STRING = "SELECT value FROM custom_values WHERE type=:type AND name=:name;"
-- SQL Insert to add a new custom value.
sql_insert_custom_value: STRING = "INSERT INTO custom_values (type, name, value) VALUES (:type, :name, :value);"
-- SQL Insert to add a new custom value.
sql_update_custom_value : STRING = "UPDATE custom_values SET value=:value WHERE type=:type AND name=:name;"
-- SQL Update to modify a custom value.
sql_delete_custom_value: STRING = "DELETE FROM custom_values WHERE type=:type AND name=:name;"
-- SQL delete custom value;
end

View File

@@ -1,11 +1,10 @@
note
description: "Summary description for {CMS_NODE_STORAGE}."
author: ""
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
CMS_NODE_STORAGE_I
inherit
SHARED_LOGGER

View 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

View File

@@ -5,18 +5,23 @@ note
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
deferred class
class
CMS_NODE_STORAGE_SQL
inherit
CMS_NODE_STORAGE
CMS_PROXY_STORAGE_SQL
CMS_STORAGE_SQL
CMS_NODE_STORAGE_I
CMS_STORAGE_SQL_I
REFACTORING_HELPER
SHARED_LOGGER
create
make
feature -- Access
nodes_count: INTEGER_64
@@ -146,7 +151,7 @@ feature -- Change: Node
error_handler.reset
create l_parameters.make (1)
l_parameters.put (a_id, "id")
l_parameters.put (a_id, "nid")
sql_change (sql_delete_node, l_parameters)
end
@@ -201,7 +206,6 @@ feature {NONE} -- Implementation
local
l_parameters: STRING_TABLE [detachable ANY]
now: DATE_TIME
is_new: BOOLEAN
do
create now.make_now_utc
error_handler.reset
@@ -212,6 +216,7 @@ feature {NONE} -- Implementation
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
@@ -222,16 +227,14 @@ feature {NONE} -- Implementation
end
sql_begin_transaction
if a_node.has_id then
is_new := True
-- Update
l_parameters.put (a_node.id, "id")
l_parameters.put (a_node.id, "nid")
sql_change (sql_update_node, l_parameters)
if not error_handler.has_error then
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
is_new := False
-- Store new node
l_parameters.put (a_node.creation_date, "created")
sql_change (sql_insert_node, l_parameters)
@@ -263,14 +266,14 @@ feature {NONE} -- Queries
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, author, publish, created, changed FROM Nodes WHERE nid =:nid ORDER BY revision desc, publish desc LIMIT 1;"
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, author, publish, created, changed FROM Nodes ORDER BY nid desc, publish desc LIMIT :rows OFFSET :offset ;"
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, publish, created, changed, author) VALUES (1, :type, :title, :summary, :content, :publish, :created, :changed, :author);"
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 + 1, type=:type, title=:title, summary=:summary, content=:content, publish=:publish, changed=:changed, revision = revision + 1, author=:author WHERE nid=:nid;"
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;"
@@ -292,7 +295,7 @@ 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, author, publish, created, changed FROM users INNER JOIN nodes ON nodes.author=users.uid AND nodes.nid =:nid;"
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
@@ -316,18 +319,21 @@ feature {NONE} -- Implementation
if attached sql_read_string (6) as l_content then
Result.set_content (l_content)
end
if attached sql_read_date_time (8) as l_publication_date then
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 (9) as l_creation_date then
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 (10) as l_modif_date then
if attached sql_read_date_time (11) as l_modif_date then
Result.set_modification_date (l_modif_date)
end
if attached sql_read_integer_64 (7) as l_author_id then
Result.set_author (create {CMS_PARTIAL_USER}.make_with_id (l_author_id))
end
end
end

View File

@@ -90,6 +90,7 @@ feature -- Persistence
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

View File

@@ -1,11 +1,11 @@
note
description: "Summary description for {CMS_USER_STORAGE}."
description: "Summary description for {CMS_USER_STORAGE_I}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_USER_STORAGE
CMS_USER_STORAGE_I
inherit
SHARED_LOGGER

View File

@@ -1,16 +1,15 @@
note
description: "Summary description for {CMS_USER_STORAGE_SQL}."
author: ""
description: "Summary description for {CMS_USER_STORAGE_SQL_I}."
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
deferred class
CMS_USER_STORAGE_SQL
CMS_USER_STORAGE_SQL_I
inherit
CMS_USER_STORAGE
CMS_USER_STORAGE_I
CMS_STORAGE_SQL
CMS_STORAGE_SQL_I
REFACTORING_HELPER
@@ -34,6 +33,7 @@ feature -- Access: user
if sql_rows_count = 1 then
Result := sql_read_integer_32 (1)
end
error_handler.reset
end
users: LIST [CMS_USER]

View File

@@ -47,6 +47,10 @@ feature {NONE} -- Initialize
setup.enabled_modules as ic
loop
l_module := ic.item
-- FIXME: should we initialize first, and then install
-- or the reverse, or merge installation and initialization
-- and leave the responsability to the module to know
-- if this is installed or not...
if not l_module.is_installed (Current) then
l_module.install (Current)
end
@@ -72,6 +76,11 @@ feature -- Formats
create Result
end
format (a_format_name: detachable READABLE_STRING_GENERAL): detachable CONTENT_FORMAT
do
Result := formats.item (a_format_name)
end
feature -- Status Report
has_error: BOOLEAN
@@ -86,6 +95,47 @@ feature -- Status Report
Result := error_handler.as_string_representation
end
feature -- Logging
log (a_category: READABLE_STRING_8; a_message: READABLE_STRING_8; a_level: INTEGER; a_link: detachable CMS_LINK)
local
l_log: CMS_LOG
m: STRING
do
create l_log.make (a_category, a_message, a_level, Void)
if a_link /= Void then
l_log.set_link (a_link)
end
storage.save_log (l_log)
create m.make_from_string ("[" + a_category + "] ")
m.append (a_message)
if a_link /= Void then
m.append (" [" + url_encoded (a_link.title) + "]("+ a_link.location +")")
end
inspect a_level
when {CMS_LOG}.level_emergency then
logger.put_alert (m, Void)
when {CMS_LOG}.level_alert then
logger.put_alert (m, Void)
when {CMS_LOG}.level_critical then
logger.put_critical (m, Void)
when {CMS_LOG}.level_error then
logger.put_error (m, Void)
when {CMS_LOG}.level_warning then
logger.put_warning (m, Void)
when {CMS_LOG}.level_notice then
logger.put_information (m, Void)
when {CMS_LOG}.level_info then
logger.put_information (m, Void)
when {CMS_LOG}.level_debug then
logger.put_debug (m, Void)
else
logger.put_debug (m, Void)
end
end
feature -- Permissions system
user_has_permission (a_user: detachable CMS_USER; a_permission: detachable READABLE_STRING_GENERAL): BOOLEAN
@@ -114,6 +164,16 @@ feature -- Query: module
Result := Void
end
end
ensure
Result /= Void implies (Result.is_enabled and Result.generating_type ~ a_type)
end
module_api (a_type: TYPE [CMS_MODULE]): detachable CMS_MODULE_API
-- Enabled module API associated with module typed `a_type'.
do
if attached module (a_type) as mod then
Result := mod.module_api
end
end
module_by_name (a_name: READABLE_STRING_GENERAL): detachable CMS_MODULE
@@ -133,7 +193,15 @@ feature -- Query: module
end
end
ensure
Result /= Void implies Result.name.is_case_insensitive_equal_general (a_name)
Result /= Void implies (Result.is_enabled and Result.name.is_case_insensitive_equal_general (a_name))
end
module_api_by_name (a_name: READABLE_STRING_GENERAL): detachable CMS_MODULE_API
-- Enabled module API associated with module named `a_name'.
do
if attached module_by_name (a_name) as mod then
Result := mod.module_api
end
end
feature -- Query: API

View File

@@ -36,10 +36,37 @@ feature -- Response helpers
-- res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (a_location))
end
send_access_denied (res: WSF_RESPONSE)
send_access_denied_message (res: WSF_RESPONSE)
-- Send via `res' an access denied response.
do
res.send (create {CMS_FORBIDDEN_RESPONSE_MESSAGE}.make)
end
send_access_denied (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Forbidden response.
local
r: CMS_RESPONSE
do
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.execute
end
send_not_found (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Send via `res' a not found response.
local
r: CMS_RESPONSE
do
create {NOT_FOUND_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.execute
end
send_bad_request (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Send via `res' a bad request response.
local
r: CMS_RESPONSE
do
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.execute
end
end

View File

@@ -9,7 +9,11 @@ deferred class
feature -- Logging
put_information (a_message: READABLE_STRING_8; a_data: detachable ANY)
put_critical (a_message: READABLE_STRING_8; a_data: detachable ANY)
deferred
end
put_alert (a_message: READABLE_STRING_8; a_data: detachable ANY)
deferred
end
@@ -21,11 +25,7 @@ feature -- Logging
deferred
end
put_critical (a_message: READABLE_STRING_8; a_data: detachable ANY)
deferred
end
put_alert (a_message: READABLE_STRING_8; a_data: detachable ANY)
put_information (a_message: READABLE_STRING_8; a_data: detachable ANY)
deferred
end

View File

@@ -162,9 +162,14 @@ feature -- Access: CMS
-- Associated values indexed by string name.
feature -- User access
user: detachable CMS_USER
do
Result := current_user (request)
end
feature -- Permission
-- FIXME: to be implemented has_permissions and has_permission.
has_permission (a_permission: READABLE_STRING_GENERAL): BOOLEAN
-- Does current user has permission `a_permission' ?
@@ -442,6 +447,9 @@ feature -- Blocks
do
if attached primary_tabs as m and then not m.is_empty then
create Result.make (m)
Result.is_horizontal := True
Result.set_is_raw (True)
Result.add_css_class ("tabs")
end
end
@@ -459,7 +467,7 @@ feature -- Blocks
s: STRING
l_hb: STRING
do
create s.make_from_string (theme.menu_html (primary_menu, True))
create s.make_from_string (theme.menu_html (primary_menu, True, Void))
create l_hb.make_empty
create Result.make ("header", Void, l_hb, Void)
Result.set_is_raw (True)
@@ -469,7 +477,15 @@ feature -- Blocks
do
create Result.make_empty
Result.append ("<div id=%"menu-bar%">")
Result.append (theme.menu_html (primary_menu, True))
Result.append (theme.menu_html (primary_menu, True, Void))
Result.append ("</div>")
end
horizontal_primary_tabs_html: STRING
do
create Result.make_empty
Result.append ("<div id=%"tabs-bar%">")
Result.append (theme.menu_html (primary_tabs, True, Void))
Result.append ("</div>")
end
@@ -652,6 +668,11 @@ feature -- Menu: change
add_to_menu (lnk, primary_menu)
end
add_to_primary_tabs (lnk: CMS_LINK)
do
add_to_menu (lnk, primary_tabs)
end
add_to_menu (lnk: CMS_LINK; m: CMS_MENU)
do
-- if attached {CMS_LOCAL_LINK} lnk as l_local then
@@ -872,6 +893,7 @@ feature -- Generation
-- Menu...
page.register_variable (horizontal_primary_menu_html, "primary_nav")
page.register_variable (horizontal_primary_tabs_html, "primary_tabs")
-- Page related
if attached page_title as l_page_title then

View File

@@ -0,0 +1,38 @@
note
description: "Summary description for {FORBIDDEN_ERROR_CMS_RESPONSE}."
date: "$Date: 2014-11-13 19:34:00 +0100 (jeu., 13 nov. 2014) $"
revision: "$Revision: 96086 $"
class
FORBIDDEN_ERROR_CMS_RESPONSE
inherit
CMS_RESPONSE
redefine
custom_prepare
end
create
make
feature -- Generation
custom_prepare (page: CMS_HTML_PAGE)
do
page.register_variable (request.absolute_script_url (request.path_info), "request")
page.set_status_code ({HTTP_STATUS_CODE}.forbidden)
page.register_variable (page.status_code.out, "code")
end
feature -- Execution
process
-- Computed response message.
do
set_title ("Forbidden")
set_page_title ("Forbidden")
set_main_content ("<em>Access denied for resource <strong>" + request.request_uri + "</strong>.</em>")
end
end

View File

@@ -0,0 +1,50 @@
note
description: "Options for any html item during CMS theme output."
date: "$Date$"
revision: "$Revision$"
class
CMS_HTML_OPTIONS
feature -- Access
css_classes: detachable ARRAYED_LIST [READABLE_STRING_8]
-- Optional additional css classes.
feature -- Element change
add_css_class (a_class: READABLE_STRING_8)
-- Add css class `a_class'.
local
l_css_classes: like css_classes
do
l_css_classes := css_classes
if l_css_classes = Void then
create l_css_classes.make (1)
css_classes := l_css_classes
end
l_css_classes.force (a_class)
end
remove_css_class (a_class: READABLE_STRING_GENERAL)
-- Remove css class `a_class'.
local
l_css_classes: like css_classes
do
l_css_classes := css_classes
if l_css_classes /= Void then
from
l_css_classes.start
until
l_css_classes.after
loop
if a_class.is_case_insensitive_equal (l_css_classes.item) then
l_css_classes.remove
l_css_classes.finish
end
l_css_classes.forth
end
end
end
end

View File

@@ -35,12 +35,27 @@ feature -- Access
feature -- Conversion
menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8
menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN; a_options: detachable CMS_HTML_OPTIONS): STRING_8
local
cl: STRING
do
debug ("refactor_fixme")
fixme ("Refactor HTML code to use the new Bootstrap theme template")
end
create Result.make_from_string ("<div id=%""+ a_menu.name +"%" class=%"menu%">")
create cl.make_from_string ("menu")
if a_options /= Void and then attached a_options.css_classes as lst then
across
lst as ic
loop
cl.append_character (' ')
cl.append (ic.item)
end
end
create Result.make_from_string ("<div id=%"")
Result.append (a_menu.name)
Result.append ("%" class=%"")
Result.append (cl)
Result.append ("%">")
if is_horizontal then
Result.append ("<ul class=%"horizontal%" >%N")
else