Added support for path_aliases.
Refactored CMS_MODULE.router (..): WSF_ROUTER design, to create only one router object of type CMS_ROUTER. Added optional CMS_NODE.link: CMS_LOCAL_LINK Reviewed permissions related to node module. Refactor and add CMS_STORAGE_SQL(_BUILDER) abstractions for implementation relying only on SQL statements. Factorized sql builder initialization (to work for sqlite and mysql storage builders). Added CMS_RESPONSE.formatted_string (a_text: READABLE_STRING_GENERAL; args: TUPLE): STRING_32 Added function "translation", but not implemented for now. Updated indexing notes and comments. Code cleaning.
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/>
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||||
|
<library name="i18n" location="$ISE_LIBRARY\library\i18n\i18n-safe.ecf"/>
|
||||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||||
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
|
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
|
||||||
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
|
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
|
||||||
|
|||||||
1
cms.ecf
1
cms.ecf
@@ -17,6 +17,7 @@
|
|||||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf" readonly="false"/>
|
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf" readonly="false"/>
|
||||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||||
|
<library name="i18n" location="$ISE_LIBRARY\library\i18n\i18n.ecf"/>
|
||||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||||
<library name="cms_app_env" location=".\library\app_env\app_env.ecf"/>
|
<library name="cms_app_env" location=".\library\app_env\app_env.ecf"/>
|
||||||
<library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/>
|
<library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/>
|
||||||
|
|||||||
@@ -84,11 +84,10 @@ CREATE TABLE "blog_post_nodes"(
|
|||||||
|
|
||||||
feature -- Access: router
|
feature -- Access: router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||||
-- Node router.
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
create Result.make (1)
|
a_router.handle_with_request_methods ("/blogs/", create {WSF_URI_AGENT_HANDLER}.make (agent handle_blogs (?,?, a_api)), a_router.methods_get)
|
||||||
Result.handle_with_request_methods ("/blogs/", create {WSF_URI_AGENT_HANDLER}.make (agent handle_blogs (?,?, a_api)), Result.methods_get)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Hooks
|
feature -- Hooks
|
||||||
|
|||||||
@@ -80,12 +80,11 @@ CREATE TABLE "tb_demo"(
|
|||||||
|
|
||||||
feature -- Access: router
|
feature -- Access: router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||||
-- Node router.
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
create Result.make (2)
|
map_uri_template_agent (a_router, "/demo/", agent handle_demo (?,?,a_api))
|
||||||
map_uri_template_agent (Result, "/demo/", agent handle_demo (?,?,a_api))
|
map_uri_template_agent (a_router, "/demo/{id}", agent handle_demo_entry (?,?,a_api))
|
||||||
map_uri_template_agent (Result, "/demo/{id}", agent handle_demo_entry (?,?,a_api))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Hooks
|
feature -- Hooks
|
||||||
|
|||||||
@@ -1,35 +1,5 @@
|
|||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
||||||
CREATE TABLE "users"(
|
|
||||||
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
|
|
||||||
"name" VARCHAR(100) NOT NULL,
|
|
||||||
"password" VARCHAR(100) NOT NULL,
|
|
||||||
"salt" VARCHAR(100) NOT NULL,
|
|
||||||
"email" VARCHAR(250) NOT NULL,
|
|
||||||
"status" INTEGER,
|
|
||||||
"created" DATETIME NOT NULL,
|
|
||||||
"signed" DATETIME,
|
|
||||||
CONSTRAINT "name"
|
|
||||||
UNIQUE("name")
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "roles"(
|
|
||||||
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
|
|
||||||
"name" VARCHAR(100) NOT NULL,
|
|
||||||
CONSTRAINT "name"
|
|
||||||
UNIQUE("name")
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "users_roles"(
|
|
||||||
"uid" INTEGER NOT NULL CHECK("uid">=0),
|
|
||||||
"rid" INTEGER NOT NULL CHECK("rid">=0)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "role_permissions"(
|
|
||||||
"rid" INTEGER NOT NULL CHECK("rid">=0),
|
|
||||||
"permission" VARCHAR(255) NOT NULL,
|
|
||||||
"module" VARCHAR(255)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "logs"(
|
CREATE TABLE "logs"(
|
||||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
|
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
|
||||||
@@ -48,4 +18,11 @@ CREATE TABLE "custom_values"(
|
|||||||
"value" VARCHAR(255) NOT NULL
|
"value" VARCHAR(255) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "path_aliases"(
|
||||||
|
"pid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("pid">=0),
|
||||||
|
"source" VARCHAR(255) NOT NULL,
|
||||||
|
"alias" VARCHAR(255) NOT NULL,
|
||||||
|
"lang" VARCHAR(12)
|
||||||
|
);
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|||||||
34
examples/demo/site/scripts/user.sql
Normal file
34
examples/demo/site/scripts/user.sql
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE "users"(
|
||||||
|
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
|
||||||
|
"name" VARCHAR(100) NOT NULL,
|
||||||
|
"password" VARCHAR(100) NOT NULL,
|
||||||
|
"salt" VARCHAR(100) NOT NULL,
|
||||||
|
"email" VARCHAR(250) NOT NULL,
|
||||||
|
"status" INTEGER,
|
||||||
|
"created" DATETIME NOT NULL,
|
||||||
|
"signed" DATETIME,
|
||||||
|
CONSTRAINT "name"
|
||||||
|
UNIQUE("name")
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "roles"(
|
||||||
|
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
|
||||||
|
"name" VARCHAR(100) NOT NULL,
|
||||||
|
CONSTRAINT "name"
|
||||||
|
UNIQUE("name")
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "users_roles"(
|
||||||
|
"uid" INTEGER NOT NULL CHECK("uid">=0),
|
||||||
|
"rid" INTEGER NOT NULL CHECK("rid">=0)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "role_permissions"(
|
||||||
|
"rid" INTEGER NOT NULL CHECK("rid">=0),
|
||||||
|
"permission" VARCHAR(255) NOT NULL,
|
||||||
|
"module" VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -28,12 +28,8 @@ feature {NONE} -- Initialization
|
|||||||
make (a_title: detachable like title; a_location: like location)
|
make (a_title: detachable like title; a_location: like location)
|
||||||
-- Create current local link with optional title `a_title' and location `a_location'.
|
-- Create current local link with optional title `a_title' and location `a_location'.
|
||||||
do
|
do
|
||||||
if a_title /= Void then
|
|
||||||
title := a_title
|
|
||||||
else
|
|
||||||
title := a_location
|
|
||||||
end
|
|
||||||
location := a_location
|
location := a_location
|
||||||
|
set_title (a_title)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
@@ -75,6 +71,16 @@ feature -- Status report
|
|||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
|
set_title (a_title: detachable like title)
|
||||||
|
-- Set `title' to `a_title' or `location'.
|
||||||
|
do
|
||||||
|
if a_title /= Void then
|
||||||
|
title := a_title
|
||||||
|
else
|
||||||
|
title := location
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
add_link (lnk: CMS_LINK)
|
add_link (lnk: CMS_LINK)
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
local
|
local
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_STORAGE_STORE_SQL}."
|
description: "Storage based on Eiffel Store component."
|
||||||
author: ""
|
|
||||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||||
revision: "$Revision: 96616 $"
|
revision: "$Revision: 96616 $"
|
||||||
|
|
||||||
@@ -8,9 +7,7 @@ deferred class
|
|||||||
CMS_STORAGE_STORE_SQL
|
CMS_STORAGE_STORE_SQL
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
CMS_STORAGE
|
CMS_STORAGE_SQL
|
||||||
|
|
||||||
CMS_STORAGE_SQL_I
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
@@ -25,7 +22,6 @@ feature {NONE} -- Initialization
|
|||||||
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
|
||||||
|
|
||||||
create error_handler.make
|
create error_handler.make
|
||||||
-- error_handler.add_synchronization (db_handler.database_error_handler)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Common ancestor for builders responsible to instantiate storage based
|
||||||
|
on Eiffel Store storage.
|
||||||
|
]"
|
||||||
|
author: "$Author: jfiat $"
|
||||||
|
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||||
|
revision: "$Revision: 96616 $"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_STORAGE_STORE_SQL_BUILDER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE_SQL_BUILDER
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
Objects that ...
|
Interface responsible to instantiate CMS_STORAGE_MYSQL object.
|
||||||
]"
|
]"
|
||||||
author: "$Author: jfiat $"
|
author: "$Author: jfiat $"
|
||||||
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||||
@@ -10,7 +10,9 @@ class
|
|||||||
CMS_STORAGE_MYSQL_BUILDER
|
CMS_STORAGE_MYSQL_BUILDER
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
CMS_STORAGE_SQL_BUILDER
|
CMS_STORAGE_STORE_SQL_BUILDER
|
||||||
|
|
||||||
|
GLOBAL_SETTINGS
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -32,6 +34,12 @@ feature -- Factory
|
|||||||
create {DATABASE_CONNECTION_MYSQL} conn.login_with_connection_string (l_database_config.connection_string)
|
create {DATABASE_CONNECTION_MYSQL} conn.login_with_connection_string (l_database_config.connection_string)
|
||||||
if conn.is_connected then
|
if conn.is_connected then
|
||||||
create Result.make (conn)
|
create Result.make (conn)
|
||||||
|
set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default.
|
||||||
|
if Result.is_available then
|
||||||
|
if not Result.is_initialized then
|
||||||
|
initialize (a_setup, Result)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_STORAGE_MYSQL}."
|
description: "Summary description for {CMS_STORAGE_SQLITE}."
|
||||||
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
|
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
|
||||||
revision: "$Revision: 96596 $"
|
revision: "$Revision: 96596 $"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
Objects that ...
|
Interface responsible to instantiate CMS_STORAGE_SQLITE object.
|
||||||
]"
|
]"
|
||||||
author: "$Author: jfiat $"
|
author: "$Author: jfiat $"
|
||||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||||
@@ -10,7 +10,7 @@ class
|
|||||||
CMS_STORAGE_SQLITE_BUILDER
|
CMS_STORAGE_SQLITE_BUILDER
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
CMS_STORAGE_SQL_BUILDER
|
CMS_STORAGE_STORE_SQL_BUILDER
|
||||||
|
|
||||||
GLOBAL_SETTINGS
|
GLOBAL_SETTINGS
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ feature -- Factory
|
|||||||
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_SQLITE
|
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_SQLITE
|
||||||
local
|
local
|
||||||
s: STRING
|
s: STRING
|
||||||
|
conn: DATABASE_CONNECTION
|
||||||
do
|
do
|
||||||
if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config then
|
if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config then
|
||||||
s := "Driver=SQLite3 ODBC Driver;Database="
|
s := "Driver=SQLite3 ODBC Driver;Database="
|
||||||
@@ -36,77 +37,17 @@ feature -- Factory
|
|||||||
s.append (db_name)
|
s.append (db_name)
|
||||||
end
|
end
|
||||||
s.append (";LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
s.append (";LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
||||||
create Result.make (create {DATABASE_CONNECTION_ODBC}.login_with_connection_string (s))
|
create {DATABASE_CONNECTION_ODBC} conn.login_with_connection_string (s)
|
||||||
set_map_zero_null_value (False)
|
if conn.is_connected then
|
||||||
-- This way we map 0 to 0, instead of Null as default.
|
create Result.make (conn)
|
||||||
--create Result.make (create {DATABASE_CONNECTION_ODBC}.login_with_connection_string (l_database_config.connection_string))
|
set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default.
|
||||||
if Result.is_available then
|
if Result.is_available then
|
||||||
if not Result.is_initialized then
|
if not Result.is_initialized then
|
||||||
initialize (a_setup, Result)
|
initialize (a_setup, Result)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initialize (a_setup: CMS_SETUP; a_storage: CMS_STORAGE_STORE_SQL)
|
|
||||||
local
|
|
||||||
u: CMS_USER
|
|
||||||
l_anonymous_role, l_authenticated_role, r: CMS_USER_ROLE
|
|
||||||
l_roles: LIST [CMS_USER_ROLE]
|
|
||||||
do
|
|
||||||
--| Schema
|
|
||||||
a_storage.sql_execute_file_script (a_setup.environment.path.extended ("scripts").extended ("core.sql"))
|
|
||||||
|
|
||||||
--| Roles
|
|
||||||
create l_anonymous_role.make ("anonymous")
|
|
||||||
a_storage.save_user_role (l_anonymous_role)
|
|
||||||
|
|
||||||
create l_authenticated_role.make ("authenticated")
|
|
||||||
a_storage.save_user_role (l_authenticated_role)
|
|
||||||
|
|
||||||
--| Users
|
|
||||||
create u.make ("admin")
|
|
||||||
u.set_password ("istrator#")
|
|
||||||
u.set_email (a_setup.site_email)
|
|
||||||
a_storage.new_user (u)
|
|
||||||
|
|
||||||
--| Node
|
|
||||||
-- FIXME: move that initialization to node module
|
|
||||||
l_anonymous_role.add_permission ("view any page")
|
|
||||||
a_storage.save_user_role (l_anonymous_role)
|
|
||||||
|
|
||||||
l_authenticated_role.add_permission ("create page")
|
|
||||||
l_authenticated_role.add_permission ("view any page")
|
|
||||||
l_authenticated_role.add_permission ("edit own page")
|
|
||||||
l_authenticated_role.add_permission ("delete own page")
|
|
||||||
a_storage.save_user_role (l_authenticated_role)
|
|
||||||
|
|
||||||
|
|
||||||
--| For testing purpose, to be removed later.
|
|
||||||
|
|
||||||
-- Roles, view role for testing.
|
|
||||||
create r.make ("view")
|
|
||||||
r.add_permission ("view page")
|
|
||||||
a_storage.save_user_role (r)
|
|
||||||
|
|
||||||
create {ARRAYED_LIST [CMS_USER_ROLE]} l_roles.make (1)
|
|
||||||
l_roles.force (r)
|
|
||||||
|
|
||||||
create u.make ("auth")
|
|
||||||
u.set_password ("enticated#")
|
|
||||||
u.set_email (a_setup.site_email)
|
|
||||||
a_storage.new_user (u)
|
|
||||||
|
|
||||||
create u.make ("test")
|
|
||||||
u.set_password ("test#")
|
|
||||||
u.set_email (a_setup.site_email)
|
|
||||||
a_storage.new_user (u)
|
|
||||||
|
|
||||||
create u.make ("view")
|
|
||||||
u.set_password ("only#")
|
|
||||||
u.set_email (a_setup.site_email)
|
|
||||||
u.set_roles (l_roles)
|
|
||||||
a_storage.new_user (u)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -37,12 +37,11 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
feature -- Access: router
|
feature -- Access: router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||||
-- Node router.
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
create Result.make (2)
|
configure_api_login (a_api, a_router)
|
||||||
configure_api_login (a_api, Result)
|
configure_api_logoff (a_api, a_router)
|
||||||
configure_api_logoff (a_api, Result)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access: filter
|
feature -- Access: filter
|
||||||
|
|||||||
@@ -176,6 +176,14 @@ feature -- URL
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
node_link (a_node: CMS_NODE): CMS_LOCAL_LINK
|
||||||
|
-- CMS link for node `a_node'.
|
||||||
|
require
|
||||||
|
a_node.has_id
|
||||||
|
do
|
||||||
|
create Result.make (a_node.title, cms_api.path_alias (node_path (a_node)))
|
||||||
|
end
|
||||||
|
|
||||||
node_path (a_node: CMS_NODE): STRING
|
node_path (a_node: CMS_NODE): STRING
|
||||||
-- URI path for node `a_node'.
|
-- URI path for node `a_node'.
|
||||||
-- using the /node/{nid} url.
|
-- using the /node/{nid} url.
|
||||||
@@ -234,6 +242,11 @@ feature -- Access: Node
|
|||||||
Result := a_node
|
Result := a_node
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Update link with aliasing.
|
||||||
|
if a_node /= Void and then a_node.has_id then
|
||||||
|
a_node.set_link (node_link (a_node))
|
||||||
|
end
|
||||||
|
|
||||||
-- Update partial user if needed.
|
-- Update partial user if needed.
|
||||||
if
|
if
|
||||||
Result /= Void and then
|
Result /= Void and then
|
||||||
@@ -259,16 +272,17 @@ feature -- Access: Node
|
|||||||
|
|
||||||
feature -- Permission Scope: Node
|
feature -- Permission Scope: Node
|
||||||
|
|
||||||
permission_scope (u: detachable CMS_USER; a_node: CMS_NODE): STRING
|
has_permission_for_action_on_node (a_action: READABLE_STRING_8; a_node: CMS_NODE; a_user: detachable CMS_USER; ): BOOLEAN
|
||||||
-- Result 'own' if the user `u' is the owner of the node `a_node', in other case
|
-- Has permission to execute action `a_action' on node `a_node', by eventual user `a_user'?
|
||||||
-- `any'.
|
local
|
||||||
|
l_type_name: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
-- FIXME: check if this is ok, since a role may have "any" permission enabled, and "own" disabled,
|
l_type_name := a_node.content_type
|
||||||
-- in this case, we should check both permissions
|
Result := cms_api.user_has_permission (a_user, a_action + " any " + l_type_name)
|
||||||
-- obviously such case should be rare, and look like bad configured permissions, but this may occurs.
|
if not Result and a_user /= Void then
|
||||||
Result := "any"
|
if is_author_of_node (a_user, a_node) then
|
||||||
if u /= Void and then is_author_of_node (u, a_node) then
|
Result := cms_api.user_has_permission (a_user, a_action + " own " + l_type_name)
|
||||||
Result := "own"
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ feature -- Conversion
|
|||||||
a_node.format
|
a_node.format
|
||||||
)
|
)
|
||||||
set_status (a_node.status)
|
set_status (a_node.status)
|
||||||
|
set_link (a_node.link)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
@@ -142,6 +143,11 @@ feature -- status report
|
|||||||
Result := a_content_type.is_case_insensitive_equal (content_type)
|
Result := a_content_type.is_case_insensitive_equal (content_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Access: menu
|
||||||
|
|
||||||
|
link: detachable CMS_LOCAL_LINK
|
||||||
|
-- Associated menu link.
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
set_content (a_content: like content; a_summary: like summary; a_format: like format)
|
set_content (a_content: like content; a_summary: like summary; a_format: like format)
|
||||||
@@ -158,6 +164,9 @@ feature -- Element change
|
|||||||
-- Assign `title' with `a_title'.
|
-- Assign `title' with `a_title'.
|
||||||
do
|
do
|
||||||
title := a_title
|
title := a_title
|
||||||
|
if attached link as lnk then
|
||||||
|
lnk.set_title (a_title)
|
||||||
|
end
|
||||||
ensure
|
ensure
|
||||||
title_assigned: title = a_title
|
title_assigned: title = a_title
|
||||||
end
|
end
|
||||||
@@ -211,6 +220,14 @@ feature -- Element change
|
|||||||
auther_set: author = u
|
auther_set: author = u
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set_link (a_link: like link)
|
||||||
|
-- Set `link' to `a_link'.
|
||||||
|
do
|
||||||
|
link := a_link
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status change
|
||||||
|
|
||||||
mark_not_published
|
mark_not_published
|
||||||
-- Set status to not_published.
|
-- Set status to not_published.
|
||||||
do
|
do
|
||||||
@@ -235,7 +252,6 @@ feature -- Element change
|
|||||||
status_trash: status = {CMS_NODE_API}.trashed
|
status_trash: status = {CMS_NODE_API}.trashed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature {CMS_NODE_STORAGE_I} -- Access: status change.
|
feature {CMS_NODE_STORAGE_I} -- Access: status change.
|
||||||
|
|
||||||
set_status (a_status: like status)
|
set_status (a_status: like status)
|
||||||
|
|||||||
@@ -65,6 +65,26 @@ feature -- Forms ...
|
|||||||
fset.extend (tselect)
|
fset.extend (tselect)
|
||||||
|
|
||||||
f.extend (fset)
|
f.extend (fset)
|
||||||
|
|
||||||
|
-- Path aliase
|
||||||
|
create ti.make ("path_alias")
|
||||||
|
ti.set_label ("Path")
|
||||||
|
ti.set_size (70)
|
||||||
|
if a_node /= Void and then a_node.has_id then
|
||||||
|
if attached a_node.link as lnk then
|
||||||
|
ti.set_text_value (lnk.location)
|
||||||
|
else
|
||||||
|
ti.set_text_value (response.api.path_alias (response.node_api.node_path (a_node)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if
|
||||||
|
attached f.fields_by_name ("title") as l_title_fields and then
|
||||||
|
attached l_title_fields.first as l_title_field
|
||||||
|
then
|
||||||
|
f.insert_after (ti, l_title_field)
|
||||||
|
else
|
||||||
|
f.extend (ti)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: CMS_NODE)
|
update_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: CMS_NODE)
|
||||||
@@ -160,8 +180,9 @@ feature -- Output
|
|||||||
node_api := a_response.node_api
|
node_api := a_response.node_api
|
||||||
|
|
||||||
a_response.add_variable (a_node, "node")
|
a_response.add_variable (a_node, "node")
|
||||||
create lnk.make ("View", node_api.node_path (a_node))
|
create lnk.make (a_response.translation ("View", Void), a_response.node_local_link (a_node).location)
|
||||||
lnk.set_weight (1)
|
lnk.set_weight (1)
|
||||||
|
|
||||||
a_response.add_to_primary_tabs (lnk)
|
a_response.add_to_primary_tabs (lnk)
|
||||||
create lnk.make ("Edit", node_api.node_path (a_node) + "/edit")
|
create lnk.make ("Edit", node_api.node_path (a_node) + "/edit")
|
||||||
lnk.set_weight (2)
|
lnk.set_weight (2)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}."
|
description: "Summary description for {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}."
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ feature -- Execution
|
|||||||
-- Computed response message.
|
-- Computed response message.
|
||||||
local
|
local
|
||||||
b: STRING_8
|
b: STRING_8
|
||||||
f: like edit_form
|
f: like new_edit_form
|
||||||
fd: detachable WSF_FORM_DATA
|
fd: detachable WSF_FORM_DATA
|
||||||
nid: INTEGER_64
|
nid: INTEGER_64
|
||||||
do
|
do
|
||||||
@@ -48,43 +48,44 @@ feature -- Execution
|
|||||||
attached node_api.node (nid) as l_node
|
attached node_api.node (nid) as l_node
|
||||||
then
|
then
|
||||||
if attached node_api.node_type_for (l_node) as l_type then
|
if attached node_api.node_type_for (l_node) as l_type then
|
||||||
if has_permission ("edit " + node_api.permission_scope (current_user (request), l_node) + " " + l_type.name) then
|
if node_api.has_permission_for_action_on_node ("edit", l_node, current_user (request)) then
|
||||||
f := edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type)
|
f := new_edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type)
|
||||||
|
invoke_form_alter (f, fd)
|
||||||
if request.is_post_request_method then
|
if request.is_post_request_method then
|
||||||
f.validation_actions.extend (agent edit_form_validate (?, b))
|
f.validation_actions.extend (agent edit_form_validate (?, b))
|
||||||
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
|
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
|
||||||
f.process (Current)
|
f.process (Current)
|
||||||
fd := f.last_data
|
fd := f.last_data
|
||||||
end
|
end
|
||||||
|
if l_node.has_id then
|
||||||
|
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("View", Void), node_url (l_node)), primary_tabs)
|
||||||
|
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Edit", Void), "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
||||||
|
end
|
||||||
|
|
||||||
if attached redirection as l_location then
|
if attached redirection as l_location then
|
||||||
-- FIXME: Hack for now
|
-- FIXME: Hack for now
|
||||||
set_title (l_node.title)
|
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")
|
b.append (html_encoded (l_type.title) + " saved")
|
||||||
else
|
else
|
||||||
set_title ("Edit " + html_encoded (l_type.title) + " #" + l_node.id.out)
|
set_title (formatted_string (translation ("Edit $1 #$2", Void), [l_type.title, l_node.id]))
|
||||||
|
|
||||||
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)
|
f.append_to_html (wsf_theme, b)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
b.append ("<h1>Access denied</h1>")
|
b.append ("<h1>")
|
||||||
|
b.append (translation ("Access denied", Void))
|
||||||
|
b.append ("</h1>")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
set_title ("Unknown node")
|
set_title (translation ("Unknown node", Void))
|
||||||
end
|
end
|
||||||
elseif
|
elseif
|
||||||
attached {WSF_STRING} request.path_parameter ("type") as p_type and then
|
attached {WSF_STRING} request.path_parameter ("type") as p_type and then
|
||||||
attached node_api.node_type (p_type.value) as l_type
|
attached node_api.node_type (p_type.value) as l_type
|
||||||
then
|
then
|
||||||
if has_permission ("create " + l_type.name) then
|
if has_permissions (<<"create any", "create " + l_type.name>>) then
|
||||||
if attached l_type.new_node (Void) as l_node 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)
|
f := new_edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type)
|
||||||
|
invoke_form_alter (f, fd)
|
||||||
if request.is_post_request_method then
|
if request.is_post_request_method then
|
||||||
f.validation_actions.extend (agent edit_form_validate (?, b))
|
f.validation_actions.extend (agent edit_form_validate (?, b))
|
||||||
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
|
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
|
||||||
@@ -94,25 +95,31 @@ feature -- Execution
|
|||||||
|
|
||||||
set_title ("Edit " + html_encoded (l_type.title) + " #" + l_node.id.out)
|
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)
|
if l_node.has_id then
|
||||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("Edit", "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("View", Void), node_url (l_node)), primary_tabs)
|
||||||
|
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Edit", Void), "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
||||||
|
end
|
||||||
|
|
||||||
f.append_to_html (wsf_theme, b)
|
f.append_to_html (wsf_theme, b)
|
||||||
else
|
else
|
||||||
b.append ("<h1>Server error</h1>")
|
b.append ("<h1>")
|
||||||
|
b.append (translation ("Server error", Void))
|
||||||
|
b.append ("</h1>")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
b.append ("<h1>Access denied</h1>")
|
b.append ("<h1>")
|
||||||
|
b.append (translation ("Access denied", Void))
|
||||||
|
b.append ("</h1>")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
set_title ("Create new content ...")
|
set_title (translation ("Create new content ...", Void))
|
||||||
b.append ("<ul id=%"content-types%">")
|
b.append ("<ul id=%"content-types%">")
|
||||||
across
|
across
|
||||||
node_api.node_types as ic
|
node_api.node_types as ic
|
||||||
loop
|
loop
|
||||||
if
|
if
|
||||||
attached ic.item as l_node_type and then
|
attached ic.item as l_node_type and then
|
||||||
(has_permission ("create any") or has_permission ("create " + l_node_type.name))
|
has_permissions (<<"create any", "create " + l_node_type.name>>)
|
||||||
then
|
then
|
||||||
b.append ("<li>" + link (l_node_type.name, "/node/add/" + l_node_type.name, Void))
|
b.append ("<li>" + link (l_node_type.name, "/node/add/" + l_node_type.name, Void))
|
||||||
if attached l_node_type.description as d then
|
if attached l_node_type.description as d then
|
||||||
@@ -191,16 +198,25 @@ feature -- Form
|
|||||||
end
|
end
|
||||||
node_api.save_node (l_node)
|
node_api.save_node (l_node)
|
||||||
if attached current_user (request) as u then
|
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))
|
api.log ("node", "User %"" + user_html_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
|
else
|
||||||
api.log ("node", "Anonymous " + s + " node " + a_type.name +" #" + l_node.id.out, 0, node_local_link (l_node))
|
api.log ("node", "Anonymous " + s + " node " + a_type.name +" #" + l_node.id.out, 0, node_local_link (l_node))
|
||||||
end
|
end
|
||||||
add_success_message ("Node #" + l_node.id.out + " saved.")
|
add_success_message ("Node #" + l_node.id.out + " saved.")
|
||||||
|
|
||||||
|
if attached fd.string_item ("path_alias") as l_path_alias then
|
||||||
|
api.set_path_alias (node_api.node_path (l_node), l_path_alias, False)
|
||||||
|
l_node.set_link (create {CMS_LOCAL_LINK}.make (l_node.title, l_path_alias))
|
||||||
|
else
|
||||||
|
l_node.set_link (node_api.node_link (l_node))
|
||||||
|
end
|
||||||
|
|
||||||
set_redirection (node_url (l_node))
|
set_redirection (node_url (l_node))
|
||||||
end
|
end
|
||||||
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
|
new_edit_form (a_node: detachable CMS_NODE; a_url: READABLE_STRING_8; a_name: STRING; a_node_type: CMS_NODE_TYPE [CMS_NODE]): CMS_FORM
|
||||||
|
-- Create a web form named `a_name' for node `a_node' (if set), using form action url `a_url', and for type of node `a_node_type'.
|
||||||
local
|
local
|
||||||
f: CMS_FORM
|
f: CMS_FORM
|
||||||
ts: WSF_FORM_SUBMIT_INPUT
|
ts: WSF_FORM_SUBMIT_INPUT
|
||||||
@@ -216,8 +232,7 @@ feature -- Form
|
|||||||
end
|
end
|
||||||
f.extend (th)
|
f.extend (th)
|
||||||
|
|
||||||
fill_edit_form (a_type, f, a_node)
|
populate_form (a_node_type, f, a_node)
|
||||||
|
|
||||||
f.extend_html_text ("<br/>")
|
f.extend_html_text ("<br/>")
|
||||||
|
|
||||||
create ts.make ("op")
|
create ts.make ("op")
|
||||||
@@ -228,11 +243,15 @@ feature -- Form
|
|||||||
ts.set_default_value ("Preview")
|
ts.set_default_value ("Preview")
|
||||||
f.extend (ts)
|
f.extend (ts)
|
||||||
|
|
||||||
if a_node /= Void and then a_node.id > 0 and then has_permission ("delete " + a_name) then
|
if
|
||||||
|
a_node /= Void and then
|
||||||
|
a_node.id > 0 and then
|
||||||
|
has_permission ("delete " + a_name)
|
||||||
|
then
|
||||||
create ts.make ("op")
|
create ts.make ("op")
|
||||||
ts.set_default_value ("Delete")
|
ts.set_default_value ("Delete")
|
||||||
fixme ("[
|
fixme ("[
|
||||||
ts.set_default_value (i18n ("Delete"))i18n or other name such as "translated" or "translation
|
ts.set_default_value (translation ("Delete"))
|
||||||
]")
|
]")
|
||||||
f.extend (ts)
|
f.extend (ts)
|
||||||
end
|
end
|
||||||
@@ -240,8 +259,18 @@ feature -- Form
|
|||||||
Result := f
|
Result := f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
populate_form (a_content_type: CMS_NODE_TYPE [CMS_NODE]; a_form: WSF_FORM; a_node: detachable CMS_NODE)
|
||||||
|
-- Fill the web form `a_form' with data from `a_node' if set,
|
||||||
|
-- and apply this to content type `a_content_type'.
|
||||||
|
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
|
||||||
|
|
||||||
new_node (a_content_type: CMS_NODE_TYPE [CMS_NODE]; a_form_data: WSF_FORM_DATA; a_node: detachable CMS_NODE): CMS_NODE
|
new_node (a_content_type: CMS_NODE_TYPE [CMS_NODE]; a_form_data: WSF_FORM_DATA; a_node: detachable CMS_NODE): CMS_NODE
|
||||||
--
|
-- Node creation with form_data `a_form_data' for the given content type `a_content_type'
|
||||||
|
-- using optional `a_node' to get extra node data.
|
||||||
do
|
do
|
||||||
if attached node_api.node_type_webform_manager (a_content_type) as wf then
|
if attached node_api.node_type_webform_manager (a_content_type) as wf then
|
||||||
Result := wf.new_node (Current, a_form_data, a_node)
|
Result := wf.new_node (Current, a_form_data, a_node)
|
||||||
@@ -258,11 +287,4 @@ feature -- Form
|
|||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ feature -- HTTP Methods
|
|||||||
l_id.is_integer and then
|
l_id.is_integer and then
|
||||||
attached node_api.node (l_id.integer_value) as l_node
|
attached node_api.node (l_id.integer_value) as l_node
|
||||||
then
|
then
|
||||||
if api.user_has_permission (l_user, "delete " + node_api.permission_scope (l_user, l_node) + " " + l_node.content_type) then
|
if node_api.has_permission_for_action_on_node ("delete", l_node, current_user (req)) then
|
||||||
node_api.delete_node (l_node)
|
node_api.delete_node (l_node)
|
||||||
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
|
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -51,36 +51,48 @@ feature -- Helpers
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Helpers
|
feature -- Helpers: cms link
|
||||||
|
|
||||||
user_local_link (u: CMS_USER): CMS_LINK
|
user_local_link (u: CMS_USER): CMS_LOCAL_LINK
|
||||||
do
|
do
|
||||||
create {CMS_LOCAL_LINK} Result.make (u.name, user_url (u))
|
create Result.make (u.name, user_url (u))
|
||||||
end
|
end
|
||||||
|
|
||||||
node_local_link (n: CMS_NODE): CMS_LINK
|
node_local_link (n: CMS_NODE): CMS_LOCAL_LINK
|
||||||
do
|
do
|
||||||
create {CMS_LOCAL_LINK} Result.make (n.title, node_url (n))
|
if attached n.link as lnk then
|
||||||
|
Result := lnk
|
||||||
|
else
|
||||||
|
Result := node_api.node_link (n)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
user_link (u: CMS_USER): like link
|
feature -- Helpers: html link
|
||||||
|
|
||||||
|
user_html_link (u: CMS_USER): like link
|
||||||
do
|
do
|
||||||
Result := link (u.name, "/user/" + u.id.out, Void)
|
Result := link (u.name, "/user/" + u.id.out, Void)
|
||||||
end
|
end
|
||||||
|
|
||||||
node_link (n: CMS_NODE): like link
|
node_html_link (n: CMS_NODE): like link
|
||||||
do
|
do
|
||||||
Result := link (n.title, "/node/" + n.id.out, Void)
|
Result := link (n.title, "/node/" + n.id.out, Void)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Helpers: URL
|
||||||
|
|
||||||
user_url (u: CMS_USER): like url
|
user_url (u: CMS_USER): like url
|
||||||
|
require
|
||||||
|
u_with_id: u.has_id
|
||||||
do
|
do
|
||||||
Result := url ("/user/" + u.id.out, Void)
|
Result := url ("/user/" + u.id.out, Void)
|
||||||
end
|
end
|
||||||
|
|
||||||
node_url (n: CMS_NODE): like url
|
node_url (n: CMS_NODE): like url
|
||||||
|
require
|
||||||
|
n_with_id: n.has_id
|
||||||
do
|
do
|
||||||
Result := url ("/node/" + n.id.out, Void)
|
Result := url (node_api.node_link (n).location, Void)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ feature -- HTTP Methods
|
|||||||
l_page: CMS_RESPONSE
|
l_page: CMS_RESPONSE
|
||||||
s: STRING
|
s: STRING
|
||||||
n: CMS_NODE
|
n: CMS_NODE
|
||||||
|
lnk: CMS_LOCAL_LINK
|
||||||
do
|
do
|
||||||
-- At the moment the template is hardcoded, but we can
|
-- At the moment the template is hardcoded, but we can
|
||||||
-- get them from the configuration file and load them into
|
-- get them from the configuration file and load them into
|
||||||
@@ -57,8 +58,10 @@ feature -- HTTP Methods
|
|||||||
lst as ic
|
lst as ic
|
||||||
loop
|
loop
|
||||||
n := ic.item
|
n := ic.item
|
||||||
|
lnk := node_api.node_link (n)
|
||||||
s.append ("<li class=%"cms_type_"+ n.content_type +"%">")
|
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 (l_page.link (lnk.title, lnk.location, Void))
|
||||||
|
-- s.append (l_page.link (n.title + " (#" + n.id.out + ")", node_api.node_path (n), Void))
|
||||||
s.append ("</li>%N")
|
s.append ("</li>%N")
|
||||||
end
|
end
|
||||||
s.append ("</ul>%N")
|
s.append ("</ul>%N")
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ feature {CMS_API} -- Access: API
|
|||||||
|
|
||||||
feature -- Access: router
|
feature -- Access: router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||||
-- Node router.
|
-- <Precursor>
|
||||||
local
|
local
|
||||||
l_node_api: like node_api
|
l_node_api: like node_api
|
||||||
do
|
do
|
||||||
@@ -119,8 +119,7 @@ feature -- Access: router
|
|||||||
create l_node_api.make (a_api)
|
create l_node_api.make (a_api)
|
||||||
node_api := l_node_api
|
node_api := l_node_api
|
||||||
end
|
end
|
||||||
create Result.make (2)
|
configure_web (a_api, l_node_api, a_router)
|
||||||
configure_web (a_api, l_node_api, Result)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
configure_web (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
configure_web (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ feature -- Change: Node
|
|||||||
no_id: not a_node.has_id
|
no_id: not a_node.has_id
|
||||||
valid_user: attached a_node.author as l_author and then l_author.id > 0
|
valid_user: attached a_node.author as l_author and then l_author.id > 0
|
||||||
deferred
|
deferred
|
||||||
|
ensure
|
||||||
|
has_id: a_node.has_id
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node (a_node: CMS_NODE)
|
update_node (a_node: CMS_NODE)
|
||||||
|
|||||||
@@ -157,51 +157,6 @@ feature -- Change: Node
|
|||||||
sql_change (sql_delete_node, l_parameters)
|
sql_change (sql_delete_node, l_parameters)
|
||||||
end
|
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
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
store_node (a_node: CMS_NODE)
|
store_node (a_node: CMS_NODE)
|
||||||
@@ -273,9 +228,9 @@ feature {NONE} -- Queries
|
|||||||
-- SQL Query to retrieve all nodes.
|
-- SQL Query to retrieve all nodes.
|
||||||
--| note: {CMS_NODE_API}.trashed = -1
|
--| note: {CMS_NODE_API}.trashed = -1
|
||||||
|
|
||||||
sql_select_node_by_id: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status 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, status 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, status 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, status 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, status, author) VALUES (1, :type, :title, :summary, :content, :format, :publish, :created, :changed, :status, :author);"
|
sql_insert_node: STRING = "INSERT INTO nodes (revision, type, title, summary, content, format, publish, created, changed, status, author) VALUES (1, :type, :title, :summary, :content, :format, :publish, :created, :changed, :status, :author);"
|
||||||
-- SQL Insert to add a new node.
|
-- SQL Insert to add a new node.
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ feature {NONE} -- Initialization
|
|||||||
initialize_modules
|
initialize_modules
|
||||||
-- Intialize core modules.
|
-- Intialize core modules.
|
||||||
local
|
local
|
||||||
m: CMS_MODULE
|
-- m: CMS_MODULE
|
||||||
do
|
do
|
||||||
-- Core
|
-- Core
|
||||||
-- create {BASIC_AUTH_MODULE} m.make
|
-- create {BASIC_AUTH_MODULE} m.make
|
||||||
|
|||||||
@@ -36,11 +36,10 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
feature -- Router
|
feature -- Router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||||
-- Router configuration.
|
-- <Precursor>
|
||||||
do
|
do
|
||||||
create Result.make (1)
|
a_router.handle ("/debug/", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_debug (a_api, ?, ?)))
|
||||||
Result.handle ("/debug/", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_debug (a_api, ?, ?)))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Hooks configuration
|
feature -- Hooks configuration
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ inherit
|
|||||||
default_create
|
default_create
|
||||||
end
|
end
|
||||||
|
|
||||||
|
CMS_USER_STORAGE_NULL
|
||||||
|
undefine
|
||||||
|
default_create
|
||||||
|
end
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
rename
|
rename
|
||||||
default_create as default_create_rh
|
default_create as default_create_rh
|
||||||
@@ -40,74 +45,34 @@ feature -- Status report
|
|||||||
Result := True
|
Result := True
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access: user
|
feature -- URL aliases
|
||||||
|
|
||||||
has_user: BOOLEAN
|
set_path_alias (a_source: READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
-- Has any user?
|
-- <Precursor>.
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
users: LIST [CMS_USER]
|
replace_path_alias (a_source: READABLE_STRING_8; a_previous_alias: detachable READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
do
|
-- Replace eventual previous alias `a_previous_alias' with a new alias `a_alias'
|
||||||
create {ARRAYED_LIST [CMS_USER]} Result.make (0)
|
-- on source `a_source'.
|
||||||
end
|
|
||||||
|
|
||||||
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
unset_path_alias (a_source: READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
-- Unalias `a_source' from `a_alias'.
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
path_alias (a_source: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- Return eventual path alias associated with `a_source'.
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
|
source_of_path_alias (a_alias: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- Source path for alias `a_alias'.
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Change: user
|
|
||||||
|
|
||||||
new_user (a_user: CMS_USER)
|
|
||||||
-- Add a new user `a_user'.
|
|
||||||
do
|
|
||||||
a_user.set_id (1)
|
|
||||||
end
|
|
||||||
|
|
||||||
update_user (a_user: CMS_USER)
|
|
||||||
-- Update user `a_user'.
|
|
||||||
do
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Access: roles and permissions
|
|
||||||
|
|
||||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
|
||||||
do
|
|
||||||
end
|
|
||||||
|
|
||||||
user_roles_for (a_user: CMS_USER): LIST [CMS_USER_ROLE]
|
|
||||||
-- User roles for user `a_user'.
|
|
||||||
-- Note: anonymous and authenticated roles are not included.
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
|
||||||
end
|
|
||||||
|
|
||||||
user_roles: LIST [CMS_USER_ROLE]
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Change: roles and permissions
|
|
||||||
|
|
||||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
|
||||||
do
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Logs
|
feature -- Logs
|
||||||
|
|
||||||
save_log (a_log: CMS_LOG)
|
save_log (a_log: CMS_LOG)
|
||||||
@@ -115,6 +80,8 @@ feature -- Logs
|
|||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Custom
|
||||||
|
|
||||||
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: detachable READABLE_STRING_8)
|
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).
|
-- Save data `a_name:a_value' for type `a_type' (or default if none).
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
note
|
|
||||||
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_STORAGE_SQL_BUILDER
|
|
||||||
|
|
||||||
inherit
|
|
||||||
CMS_STORAGE_BUILDER
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -19,6 +19,34 @@ feature -- Error Handling
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- URL aliases
|
||||||
|
|
||||||
|
set_path_alias (a_source: READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
-- Alias `a_source' with `a_alias'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
replace_path_alias (a_source: READABLE_STRING_8; a_previous_alias: detachable READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
-- Replace eventual previous alias `a_previous_alias' with a new alias `a_alias'
|
||||||
|
-- on source `a_source'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
unset_path_alias (a_source: READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
-- Unalias `a_source' from `a_alias'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
path_alias (a_source: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- Return eventual path alias associated with `a_source'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
source_of_path_alias (a_alias: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- Source path for alias `a_alias'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Logs
|
feature -- Logs
|
||||||
|
|
||||||
save_log (a_log: CMS_LOG)
|
save_log (a_log: CMS_LOG)
|
||||||
|
|||||||
@@ -18,6 +18,123 @@ inherit
|
|||||||
|
|
||||||
SHARED_LOGGER
|
SHARED_LOGGER
|
||||||
|
|
||||||
|
feature -- URL aliases
|
||||||
|
|
||||||
|
set_path_alias (a_source: READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_source, "source")
|
||||||
|
l_parameters.put (a_alias, "alias")
|
||||||
|
if attached source_of_path_alias (a_alias) as l_path then
|
||||||
|
if a_source.same_string (l_path) then
|
||||||
|
-- already up to date
|
||||||
|
else
|
||||||
|
error_handler.add_custom_error (0, "alias exists", "Path alias %"" + a_alias + "%" already exists!")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
sql_change (sql_insert_path_alias, l_parameters)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
replace_path_alias (a_source: READABLE_STRING_8; a_previous_alias: detachable READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
l_previous_alias: detachable READABLE_STRING_8
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
|
||||||
|
if a_previous_alias = Void then
|
||||||
|
l_previous_alias := path_alias (a_source)
|
||||||
|
else
|
||||||
|
l_previous_alias := a_previous_alias
|
||||||
|
end
|
||||||
|
if
|
||||||
|
l_previous_alias /= Void and then
|
||||||
|
not a_alias.same_string (l_previous_alias)
|
||||||
|
then
|
||||||
|
create l_parameters.make (3)
|
||||||
|
l_parameters.put (a_source, "source")
|
||||||
|
l_parameters.put (l_previous_alias, "old")
|
||||||
|
l_parameters.put (a_alias, "alias")
|
||||||
|
|
||||||
|
sql_change (sql_update_path_alias, l_parameters)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unset_path_alias (a_source: READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
|
||||||
|
if attached source_of_path_alias (a_alias) as l_path then
|
||||||
|
if a_source.same_string (l_path) then
|
||||||
|
-- Found
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_alias, "alias")
|
||||||
|
sql_change (sql_delete_path_alias, l_parameters)
|
||||||
|
else
|
||||||
|
error_handler.add_custom_error (0, "alias mismatch", "Path alias %"" + a_alias + "%" is not related to source %"" + a_source + "%"!")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- No such alias
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
path_alias (a_source: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_source, "source")
|
||||||
|
sql_query (sql_select_path_source, l_parameters)
|
||||||
|
if not has_error then
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := sql_read_string (1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
source_of_path_alias (a_alias: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_alias, "alias")
|
||||||
|
sql_query (sql_select_path_alias, l_parameters)
|
||||||
|
if not has_error then
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := sql_read_string (1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_select_path_alias: STRING = "SELECT source FROM path_aliases WHERE alias=:alias ;"
|
||||||
|
-- SQL select path aliases.
|
||||||
|
|
||||||
|
sql_select_path_source: STRING = "SELECT alias FROM path_aliases WHERE source=:source ORDER BY pid DESC LIMIT 1;"
|
||||||
|
-- SQL select latest path aliasing :source.
|
||||||
|
|
||||||
|
sql_insert_path_alias: STRING = "INSERT INTO path_aliases (source, alias) VALUES (:source, :alias);"
|
||||||
|
-- SQL insert path alias.
|
||||||
|
|
||||||
|
sql_update_path_alias: STRING = "UPDATE path_aliases SET alias=:alias WHERE source=:source AND alias=:old ;"
|
||||||
|
-- SQL update path alias.
|
||||||
|
|
||||||
|
sql_delete_path_alias: STRING = "DELETE FROM path_aliases WHERE alias=:alias;"
|
||||||
|
-- SQL delete path alias
|
||||||
|
|
||||||
feature -- Logs
|
feature -- Logs
|
||||||
|
|
||||||
save_log (a_log: CMS_LOG)
|
save_log (a_log: CMS_LOG)
|
||||||
|
|||||||
15
src/persistence/sql/cms_storage_sql.e
Normal file
15
src/persistence/sql/cms_storage_sql.e
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
note
|
||||||
|
description: "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
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE
|
||||||
|
|
||||||
|
CMS_STORAGE_SQL_I
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
85
src/persistence/sql/cms_storage_sql_builder.e
Normal file
85
src/persistence/sql/cms_storage_sql_builder.e
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Common ancestor for builders responsible to instantiate storage based
|
||||||
|
on SQL statement storage.
|
||||||
|
]"
|
||||||
|
author: "$Author: jfiat $"
|
||||||
|
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||||
|
revision: "$Revision: 96542 $"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_STORAGE_SQL_BUILDER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE_BUILDER
|
||||||
|
|
||||||
|
feature -- Initialization
|
||||||
|
|
||||||
|
initialize (a_setup: CMS_SETUP; a_storage: CMS_STORAGE_SQL)
|
||||||
|
local
|
||||||
|
u: CMS_USER
|
||||||
|
l_anonymous_role, l_authenticated_role, r: CMS_USER_ROLE
|
||||||
|
l_roles: LIST [CMS_USER_ROLE]
|
||||||
|
do
|
||||||
|
--| Schema
|
||||||
|
a_storage.sql_execute_file_script (a_setup.environment.path.extended ("scripts").extended ("core.sql"))
|
||||||
|
a_storage.sql_execute_file_script (a_setup.environment.path.extended ("scripts").extended ("user.sql"))
|
||||||
|
|
||||||
|
--| Roles
|
||||||
|
create l_anonymous_role.make ("anonymous")
|
||||||
|
a_storage.save_user_role (l_anonymous_role)
|
||||||
|
|
||||||
|
create l_authenticated_role.make ("authenticated")
|
||||||
|
a_storage.save_user_role (l_authenticated_role)
|
||||||
|
|
||||||
|
--| Users
|
||||||
|
create u.make ("admin")
|
||||||
|
u.set_password ("istrator#")
|
||||||
|
u.set_email (a_setup.site_email)
|
||||||
|
a_storage.new_user (u)
|
||||||
|
|
||||||
|
--| Node
|
||||||
|
-- FIXME: move that initialization to node module
|
||||||
|
l_anonymous_role.add_permission ("view any page")
|
||||||
|
a_storage.save_user_role (l_anonymous_role)
|
||||||
|
|
||||||
|
l_authenticated_role.add_permission ("create page")
|
||||||
|
l_authenticated_role.add_permission ("view any page")
|
||||||
|
l_authenticated_role.add_permission ("edit any page")
|
||||||
|
l_authenticated_role.add_permission ("delete page")
|
||||||
|
l_authenticated_role.add_permission ("view own page")
|
||||||
|
l_authenticated_role.add_permission ("edit own page")
|
||||||
|
l_authenticated_role.add_permission ("delete own page")
|
||||||
|
a_storage.save_user_role (l_authenticated_role)
|
||||||
|
|
||||||
|
|
||||||
|
--|-------------------------------------------|--
|
||||||
|
--| For testing purpose, to be removed later. |--
|
||||||
|
--|-------------------------------------------|--
|
||||||
|
|
||||||
|
-- Roles, view role for testing.
|
||||||
|
create r.make ("view")
|
||||||
|
r.add_permission ("view any page")
|
||||||
|
a_storage.save_user_role (r)
|
||||||
|
|
||||||
|
create {ARRAYED_LIST [CMS_USER_ROLE]} l_roles.make (1)
|
||||||
|
l_roles.force (r)
|
||||||
|
|
||||||
|
create u.make ("auth")
|
||||||
|
u.set_password ("enticated#")
|
||||||
|
u.set_email (a_setup.site_email)
|
||||||
|
a_storage.new_user (u)
|
||||||
|
|
||||||
|
create u.make ("test")
|
||||||
|
u.set_password ("test#")
|
||||||
|
u.set_email (a_setup.site_email)
|
||||||
|
a_storage.new_user (u)
|
||||||
|
|
||||||
|
create u.make ("view")
|
||||||
|
u.set_password ("only#")
|
||||||
|
u.set_email (a_setup.site_email)
|
||||||
|
u.set_roles (l_roles)
|
||||||
|
a_storage.new_user (u)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
79
src/persistence/user/cms_user_storage_null.e
Normal file
79
src/persistence/user/cms_user_storage_null.e
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_USER_STORAGE_NULL}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_USER_STORAGE_NULL
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_USER_STORAGE_I
|
||||||
|
|
||||||
|
feature -- Access: user
|
||||||
|
|
||||||
|
has_user: BOOLEAN
|
||||||
|
-- Has any user?
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
users: LIST [CMS_USER]
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_USER]} Result.make (0)
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: user
|
||||||
|
|
||||||
|
new_user (a_user: CMS_USER)
|
||||||
|
-- Add a new user `a_user'.
|
||||||
|
do
|
||||||
|
a_user.set_id (1)
|
||||||
|
end
|
||||||
|
|
||||||
|
update_user (a_user: CMS_USER)
|
||||||
|
-- Update user `a_user'.
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
feature -- Access: roles and permissions
|
||||||
|
|
||||||
|
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
user_roles_for (a_user: CMS_USER): LIST [CMS_USER_ROLE]
|
||||||
|
-- User roles for user `a_user'.
|
||||||
|
-- Note: anonymous and authenticated roles are not included.
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
||||||
|
end
|
||||||
|
|
||||||
|
user_roles: LIST [CMS_USER_ROLE]
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: roles and permissions
|
||||||
|
|
||||||
|
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -232,6 +232,66 @@ feature -- Query: API
|
|||||||
Result := l_api
|
Result := l_api
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Path aliases
|
||||||
|
|
||||||
|
set_path_alias (a_source, a_alias: READABLE_STRING_8; a_keep_previous: BOOLEAN)
|
||||||
|
-- Set `a_alias' as alias of `a_source',
|
||||||
|
-- and eventually unset previous alias if any.
|
||||||
|
local
|
||||||
|
l_continue: BOOLEAN
|
||||||
|
do
|
||||||
|
if attached storage.path_alias (a_source) as l_existing_alias then
|
||||||
|
if a_alias.same_string (l_existing_alias) then
|
||||||
|
-- Already aliased as expected
|
||||||
|
else
|
||||||
|
-- New alias
|
||||||
|
if a_keep_previous then
|
||||||
|
l_continue := True
|
||||||
|
else
|
||||||
|
storage.replace_path_alias (a_source, l_existing_alias, a_alias)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif a_alias.is_whitespace then
|
||||||
|
-- Ignore
|
||||||
|
elseif a_source.same_string (a_alias) then
|
||||||
|
-- No need for alias
|
||||||
|
else
|
||||||
|
l_continue := True
|
||||||
|
end
|
||||||
|
if l_continue then
|
||||||
|
storage.set_path_alias (a_source, a_alias)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unset_path_alias (a_source: READABLE_STRING_8; a_alias: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
storage.unset_path_alias (a_source, a_alias)
|
||||||
|
end
|
||||||
|
|
||||||
|
path_alias (a_source: READABLE_STRING_8): READABLE_STRING_8
|
||||||
|
-- Path alias associated with `a_source' or the source itself.
|
||||||
|
do
|
||||||
|
Result := a_source
|
||||||
|
if attached storage.path_alias (Result) as l_path then
|
||||||
|
Result := l_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
source_of_path_alias (a_alias: READABLE_STRING_8): READABLE_STRING_8
|
||||||
|
-- Resolved path for alias `a_alias'.
|
||||||
|
--| the CMS supports aliases for path, and then this function simply returns
|
||||||
|
--| the effective target path/url for this `a_alias'.
|
||||||
|
--| For instance: /articles/2015/may/this-is-an-article can be an alias to /node/123
|
||||||
|
--| This function will return "/node/123".
|
||||||
|
--| If the alias is bad (i.e does not alias real path), then this function
|
||||||
|
--| returns the alias itself.
|
||||||
|
do
|
||||||
|
Result := a_alias
|
||||||
|
if attached storage.source_of_path_alias (Result) as l_path then
|
||||||
|
Result := l_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Element Change: Error
|
feature -- Element Change: Error
|
||||||
|
|
||||||
reset_error
|
reset_error
|
||||||
|
|||||||
@@ -66,10 +66,8 @@ feature {CMS_API} -- Module management
|
|||||||
|
|
||||||
feature -- Router
|
feature -- Router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||||
-- Router configuration.
|
-- Setup url dispatching for Current module.
|
||||||
require
|
|
||||||
is_enabled: is_enabled
|
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ inherit
|
|||||||
undefine
|
undefine
|
||||||
requires_proxy
|
requires_proxy
|
||||||
redefine
|
redefine
|
||||||
execute_default
|
execute_default,
|
||||||
|
create_router,
|
||||||
|
router
|
||||||
end
|
end
|
||||||
|
|
||||||
WSF_FILTERED_SERVICE
|
WSF_FILTERED_SERVICE
|
||||||
@@ -82,10 +84,17 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
feature -- Settings: router
|
feature -- Settings: router
|
||||||
|
|
||||||
|
router: CMS_ROUTER
|
||||||
|
|
||||||
|
create_router
|
||||||
|
-- Create `router'.
|
||||||
|
do
|
||||||
|
create router.make (api, 30)
|
||||||
|
end
|
||||||
|
|
||||||
setup_router
|
setup_router
|
||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
local
|
local
|
||||||
l_module: CMS_MODULE
|
|
||||||
l_api: like api
|
l_api: like api
|
||||||
l_router: like router
|
l_router: like router
|
||||||
do
|
do
|
||||||
@@ -100,8 +109,7 @@ feature -- Settings: router
|
|||||||
across
|
across
|
||||||
modules as ic
|
modules as ic
|
||||||
loop
|
loop
|
||||||
l_module := ic.item
|
ic.item.setup_router (l_router, l_api)
|
||||||
l_router.import (l_module.router (l_api))
|
|
||||||
end
|
end
|
||||||
-- Configure files handler.
|
-- Configure files handler.
|
||||||
configure_api_file_handler (l_router)
|
configure_api_file_handler (l_router)
|
||||||
|
|||||||
38
src/service/path/cms_router.e
Normal file
38
src/service/path/cms_router.e
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
note
|
||||||
|
description: "Specific version of WSF_ROUTER for CMS component."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_ROUTER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WSF_ROUTER
|
||||||
|
rename
|
||||||
|
make as make_router
|
||||||
|
redefine
|
||||||
|
path_to_dispatch
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_api: CMS_API; a_capacity: INTEGER)
|
||||||
|
do
|
||||||
|
api := a_api
|
||||||
|
make_router (a_capacity)
|
||||||
|
end
|
||||||
|
|
||||||
|
api: CMS_API
|
||||||
|
|
||||||
|
feature {WSF_ROUTER_MAPPING} -- Dispatch helper
|
||||||
|
|
||||||
|
path_to_dispatch (req: WSF_REQUEST): READABLE_STRING_8
|
||||||
|
-- Path used by the router, to apply url dispatching of request `req'.
|
||||||
|
do
|
||||||
|
Result := api.source_of_path_alias (Precursor (req))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -76,6 +76,26 @@ feature -- Access
|
|||||||
redirection: detachable READABLE_STRING_8
|
redirection: detachable READABLE_STRING_8
|
||||||
-- Location for eventual redirection.
|
-- Location for eventual redirection.
|
||||||
|
|
||||||
|
feature -- Internationalization (i18n)
|
||||||
|
|
||||||
|
translation (a_text: READABLE_STRING_GENERAL; opts: detachable CMS_API_OPTIONS): STRING_32
|
||||||
|
-- Translated text `a_text' according to expected context (lang, ...)
|
||||||
|
-- and adapt according to options eventually set by `opts'.
|
||||||
|
do
|
||||||
|
to_implement ("Implement i18n support [2015-may]")
|
||||||
|
Result := a_text.as_string_32
|
||||||
|
end
|
||||||
|
|
||||||
|
formatted_string (a_text: READABLE_STRING_GENERAL; args: TUPLE): STRING_32
|
||||||
|
-- Format `a_text' using arguments `args'.
|
||||||
|
--| ex: formatted_string ("hello $1, see page $title.", ["bob", "contact"] -> "hello bob, see page contact"
|
||||||
|
local
|
||||||
|
l_formatter: CMS_STRING_FORMATTER
|
||||||
|
do
|
||||||
|
create l_formatter
|
||||||
|
Result := l_formatter.formatted_string (a_text, args)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- API
|
feature -- API
|
||||||
|
|
||||||
api: CMS_API
|
api: CMS_API
|
||||||
@@ -185,12 +205,30 @@ feature -- Permission
|
|||||||
Result := user_has_permission (current_user (request), a_permission)
|
Result := user_has_permission (current_user (request), a_permission)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
has_permissions (a_permission_list: ITERABLE [READABLE_STRING_GENERAL]): BOOLEAN
|
||||||
|
-- Does current user has any of the permissions `a_permission_list' ?
|
||||||
|
do
|
||||||
|
Result := user_has_permissions (current_user (request), a_permission_list)
|
||||||
|
end
|
||||||
|
|
||||||
user_has_permission (a_user: detachable CMS_USER; a_permission: READABLE_STRING_GENERAL): BOOLEAN
|
user_has_permission (a_user: detachable CMS_USER; a_permission: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
-- Does `a_user' has permission `a_permission' ?
|
-- Does `a_user' has permission `a_permission' ?
|
||||||
do
|
do
|
||||||
Result := api.user_has_permission (a_user, a_permission)
|
Result := api.user_has_permission (a_user, a_permission)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
user_has_permissions (a_user: detachable CMS_USER; a_permission_list: ITERABLE [READABLE_STRING_GENERAL]): BOOLEAN
|
||||||
|
-- Does `a_user' has any of the permissions `a_permission_list' ?
|
||||||
|
do
|
||||||
|
across
|
||||||
|
a_permission_list as ic
|
||||||
|
until
|
||||||
|
Result
|
||||||
|
loop
|
||||||
|
Result := user_has_permission (a_user, ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Head customization
|
feature -- Head customization
|
||||||
|
|
||||||
add_additional_head_line (s: READABLE_STRING_8; a_allow_duplication: BOOLEAN)
|
add_additional_head_line (s: READABLE_STRING_8; a_allow_duplication: BOOLEAN)
|
||||||
|
|||||||
23
src/support/cms_string_formatter.e
Normal file
23
src/support/cms_string_formatter.e
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
note
|
||||||
|
description: "Format a text using arguments."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_STRING_FORMATTER
|
||||||
|
|
||||||
|
feature -- Conversion
|
||||||
|
|
||||||
|
formatted_string (a_string: READABLE_STRING_GENERAL; args: TUPLE): STRING_32
|
||||||
|
do
|
||||||
|
Result := i18n_formatter.formatted_string (a_string, args)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
i18n_formatter: I18N_STRING_FORMATTER
|
||||||
|
once
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user