Improved node management.

- List node by node types
- fixed the trash/restore/delete workflow
Added messaging module to send message to cms users (by email for now).
Added early protection for cache, export and import functionalities.
This commit is contained in:
2017-02-28 11:24:48 +01:00
parent dc84e79952
commit a341bd98eb
35 changed files with 1055 additions and 212 deletions

View File

@@ -0,0 +1,98 @@
note
description: "[
CMS text with smarty template text content.
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_SMARTY_TEMPLATE_TEXT
inherit
ANY
SHARED_TEMPLATE_CONTEXT
undefine
is_equal
end
create
make
feature {NONE} -- Initialization
make (a_source: like source)
-- Create template text from `a_source`.
do
source := a_source
create values.make (0)
end
feature -- Access
source: READABLE_STRING_8
-- Template source.
values: STRING_TABLE [detachable ANY]
-- Additional value used during template output processing.
value (k: READABLE_STRING_GENERAL): detachable ANY assign set_value
do
Result := values.item (k)
end
feature -- Element change
set_value (v: detachable ANY; k: READABLE_STRING_GENERAL)
-- Associate value `v' with key `k'.
do
values.force (v, k)
end
unset_value (k: READABLE_STRING_GENERAL)
-- Remove value indexed by key `k'.
do
values.remove (k)
end
feature -- Conversion
string: STRING_8
-- <Precursor>
local
tpl: detachable TEMPLATE_TEXT
l_table_inspector: detachable STRING_TABLE_OF_STRING_INSPECTOR
do
template_context.disable_verbose
debug ("cms")
template_context.enable_verbose
end
create tpl.make_from_text (source)
across
values as ic
loop
tpl.add_value (ic.item, ic.key)
end
create l_table_inspector.register (({detachable STRING_TABLE [STRING_8]}).name)
create l_table_inspector.register (({detachable STRING_TABLE [STRING_32]}).name)
create l_table_inspector.register (({detachable STRING_TABLE [READABLE_STRING_8]}).name)
create l_table_inspector.register (({detachable STRING_TABLE [READABLE_STRING_32]}).name)
tpl.get_structure
tpl.get_output
l_table_inspector.unregister
-- l_table32_inspector.unregister
if attached tpl.output as l_output then
Result := l_output
else
Result := source
end
end
note
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -44,6 +44,9 @@ feature {NONE} -- Initialize
l_enabled_modules: CMS_MODULE_COLLECTION
l_uninstalled_mods: detachable ARRAYED_LIST [CMS_MODULE]
do
-- Initialize site_url
initialize_site_url
-- Initialize formats.
initialize_formats
-- Initialize contents.
@@ -101,6 +104,35 @@ feature {NONE} -- Initialize
setup_hooks
end
initialize_site_url
-- Initialize site and base url.
local
l_url: detachable STRING_8
i,j: INTEGER
do
--| WARNING: do not use `absolute_url' and `url', since it relies on site_url and base_url.
if attached setup.site_url as l_site_url and then not l_site_url.is_empty then
create l_url.make_from_string (l_site_url)
else
l_url := request.absolute_script_url ("/")
end
check is_not_empty: not l_url.is_empty end
if l_url [l_url.count] /= '/' then
l_url.append_character ('/')
end
site_url := l_url
i := l_url.substring_index ("://", 1)
if i > 0 then
j := l_url.index_of ('/', i + 3)
if j > 0 then
base_url := l_url.substring (j, l_url.count)
end
end
ensure
site_url_set: site_url /= Void
site_url_ends_with_slash: site_url.ends_with_general ("/")
end
initialize_content_types
-- Initialize content types.
do
@@ -199,6 +231,16 @@ feature -- Access
storage: CMS_STORAGE
-- Default persistence storage.
feature -- Access: url
site_url: IMMUTABLE_STRING_8
-- Site url
base_url: detachable IMMUTABLE_STRING_8
-- Base url if any.
--| Usually it is Void, but it could be
--| /project/demo/
feature -- Settings
is_debug: BOOLEAN
@@ -400,6 +442,8 @@ feature -- Emails
setup.mailer.safe_process_email (e)
if setup.mailer.has_error then
error_handler.add_custom_error (0, "Mailer error", "Error occurred while processing email.")
else
e.set_is_sent (True)
end
end
@@ -442,7 +486,13 @@ feature -- Permissions system
-- Anonymous or user `user' has permission for `a_permission'?
--| `a_permission' could be for instance "create page".
do
Result := user_api.user_has_permission (user, a_permission)
Result := user_has_permission (user, a_permission)
end
has_permissions (a_permission_list: ITERABLE [READABLE_STRING_GENERAL]): BOOLEAN
-- Anonymous or user `user' has any of the permissions `a_permission_list`?
do
Result := user_has_permissions (user, a_permission_list)
end
user_has_permission (a_user: detachable CMS_USER; a_permission: detachable READABLE_STRING_GENERAL): BOOLEAN
@@ -452,6 +502,18 @@ feature -- Permissions system
Result := user_api.user_has_permission (a_user, a_permission)
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 -- Query: module
is_module_installed (a_module: CMS_MODULE): BOOLEAN
@@ -905,6 +967,24 @@ feature -- Access: active user
user_api.update_user (a_user)
end
feature -- Site builtin variables
builtin_variables: STRING_TABLE [detachable ANY]
-- Builtin variables , value indexed by name.
do
create Result.make (7)
Result["site_url"] := site_url
Result["site_email"] := setup.site_email
Result["site_name"] := setup.site_name
if attached user as l_user then
Result["active_user"] := l_user
Result["user"] := l_user.name
Result["user_id"] := l_user.id
Result["user_profile_name"] := user_api.user_display_name (l_user)
end
end
feature -- Request utilities
execution_variable (a_name: READABLE_STRING_GENERAL): detachable ANY

View File

@@ -160,7 +160,7 @@ feature -- Import
import_json_user (j_user: JSON_OBJECT; a_import_ctx: CMS_IMPORT_CONTEXT)
local
l_user_by_name, l_user_by_email: detachable CMS_USER
l_user_by_name, l_user_by_email, l_user: detachable CMS_USER
do
if attached json_to_user (j_user) as u then
l_user_by_name := user_api.user_by_name (u.name)
@@ -170,6 +170,28 @@ feature -- Import
if l_user_by_name /= Void or l_user_by_email /= Void then
a_import_ctx.log ("Skip user %"" + u.name + "%": already exists!")
-- Already exists!
if l_user_by_email /= Void then
l_user := l_user_by_email
if
l_user_by_name /= Void and then
l_user_by_name.same_as (l_user)
then
-- Two different accounts exists!
a_import_ctx.log ("Two different accounts already exists for username %"" + u.name + "%" !")
end
else
l_user := l_user_by_name
end
-- Check if new information are now available.
if
l_user /= Void and then
l_user.profile_name = Void and then
attached u.profile_name as l_new_prof_name and then
not l_new_prof_name.is_whitespace
then
l_user.set_profile_name (l_new_prof_name)
user_api.update_user (l_user)
end
else
user_api.new_user (u)
a_import_ctx.log ("New user %"" + u.name + "%" -> " + u.id.out + " .")

View File

@@ -12,7 +12,19 @@ inherit
create
make
feature -- Status report
is_sent: BOOLEAN
-- Current Email is sent.
feature -- Element change
set_is_sent (b: BOOLEAN)
do
is_sent := b
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -24,46 +24,18 @@ feature {NONE} -- Initialization
response := res
create header.make
create values.make (3)
site_url := a_api.site_url
base_url := a_api.base_url
initialize
end
initialize
do
initialize_site_url
get_theme
create menu_system.make
initialize_block_region_settings
end
initialize_site_url
-- Initialize site and base url.
local
l_url: detachable STRING_8
i,j: INTEGER
do
--| WARNING: do not use `absolute_url' and `url', since it relies on site_url and base_url.
if attached setup.site_url as l_site_url and then not l_site_url.is_empty then
create l_url.make_from_string (l_site_url)
else
l_url := request.absolute_script_url ("/")
end
check is_not_empty: not l_url.is_empty end
if l_url [l_url.count] /= '/' then
l_url.append_character ('/')
end
site_url := l_url
i := l_url.substring_index ("://", 1)
if i > 0 then
j := l_url.index_of ('/', i + 3)
if j > 0 then
base_url := l_url.substring (j, l_url.count)
end
end
ensure
site_url_set: site_url /= Void
site_url_ends_with_slash: site_url.ends_with_general ("/")
end
feature -- Access
request: WSF_REQUEST
@@ -236,13 +208,7 @@ feature -- Permission
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
Result := api.user_has_permissions (a_user, a_permission_list)
end
feature -- Head customization
@@ -1088,6 +1054,17 @@ feature -- Cache managment
end
end
feature -- Response builtin variables
builtin_variables: STRING_TABLE [detachable ANY]
-- builtin variables value indexed by name.
do
Result := api.builtin_variables
Result ["site_url"] := site_url
Result ["host"] := site_url -- FIXME: check and remove if unused.
Result ["is_https"] := request.is_https
end
feature -- Generation
prepare (page: CMS_HTML_PAGE)
@@ -1233,14 +1210,17 @@ feature -- Generation
end
end
-- Fill with CMS builtin variables.
across
builtin_variables as ic
loop
page.register_variable (ic.item, ic.key)
end
-- Variables
page.register_variable (absolute_url ("", Void), "site_url")
page.register_variable (absolute_url ("", Void), "host") -- Same as `site_url'.
page.register_variable (request.is_https, "is_https")
if attached user as l_user then
page.register_variable (l_user.name, "user")
page.register_variable (user_profile_name (l_user), "user_profile_name")
end
if attached title as l_title then
page.register_variable (l_title, "site_title")
else
@@ -1358,15 +1338,9 @@ feature -- Helpers: cms link
feature -- Helpers: html links
user_profile_name (u: CMS_USER): READABLE_STRING_32
user_profile_name, user_display_name (u: CMS_USER): READABLE_STRING_32
do
if attached u.profile_name as pn and then not pn.is_whitespace then
Result := pn
elseif not u.name.is_whitespace then
Result := u.name
else
Result := {STRING_32} "user #" + u.id.out
end
Result := api.user_api.user_display_name (u)
end
user_html_link (u: CMS_USER): STRING

View File

@@ -68,6 +68,20 @@ feature -- Validation
end
end
feature -- Query
user_display_name (u: CMS_USER): READABLE_STRING_32
-- Display name for user `u`.
do
if attached u.profile_name as pn and then not pn.is_whitespace then
Result := pn
elseif not u.name.is_whitespace then
Result := u.name
else
Result := {STRING_32} "user #" + u.id.out
end
end
feature -- Access: user
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER