Splitted administration and normal web site interfaces.
This optimises a bit the routing map, and make cleaner separation. Make the base url for admin pages customizable via `administration.base_path` variable in cms.ini note: could be /admin, /roc-admin, or .. It is possible to have a specific theme for administration via the variable "administration.admin"
This commit is contained in:
@@ -36,7 +36,7 @@ feature {NONE} -- Initialization
|
||||
site_url := l_url
|
||||
|
||||
-- Site name
|
||||
site_name := text_item_or_default ("site.name", "Another Eiffel ROC Website")
|
||||
site_name := text_item_or_default ("site.name", "Your ROC CMS")
|
||||
|
||||
-- Website email used to send email.
|
||||
-- used as real "From:" email.
|
||||
@@ -77,6 +77,13 @@ feature {NONE} -- Initialization
|
||||
temp_location := site_location.extended ("temp")
|
||||
end
|
||||
|
||||
-- Location for cache folder
|
||||
if attached text_item ("cache-dir") as l_cache_dir then
|
||||
create cache_location.make_from_string (l_cache_dir)
|
||||
else
|
||||
cache_location := temp_location.extended ("cache")
|
||||
end
|
||||
|
||||
-- Location for modules folders.
|
||||
if attached text_item ("modules-dir") as l_modules_dir then
|
||||
create modules_location.make_from_string (l_modules_dir)
|
||||
@@ -92,13 +99,23 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
|
||||
-- Selected theme's name
|
||||
theme_name := text_item_or_default ("theme", "default")
|
||||
site_theme_name := text_item_or_default ("theme", "default")
|
||||
set_theme (site_theme_name)
|
||||
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Review export clause for configuration and environment")
|
||||
-- Administration
|
||||
l_url := string_8_item ("administration.base_path")
|
||||
if l_url /= Void and then not l_url.is_empty then
|
||||
if l_url [l_url.count] = '/' then
|
||||
l_url := l_url.substring (1, l_url.count - 1)
|
||||
end
|
||||
if l_url [1] /= '/' then
|
||||
l_url := "/" + l_url
|
||||
end
|
||||
create administration_base_path.make_from_string (l_url)
|
||||
else
|
||||
create administration_base_path.make_from_string (default_administration_base_path)
|
||||
end
|
||||
|
||||
theme_location := themes_location.extended (theme_name)
|
||||
administration_theme_name := text_item_or_default ("administration.theme", theme_name) -- TODO: Default to builtin theme?
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
@@ -296,11 +313,37 @@ feature -- Access: Site
|
||||
-- Optional path defining the front page.
|
||||
-- By default "" or "/".
|
||||
|
||||
administration_base_path: IMMUTABLE_STRING_8
|
||||
-- Administration base url, default=`default_administration_base_path`.
|
||||
|
||||
feature {NONE} -- Constants
|
||||
|
||||
default_administration_base_path: STRING = "/admin"
|
||||
|
||||
feature -- Settings
|
||||
|
||||
is_debug: BOOLEAN
|
||||
-- Is debug mode enabled?
|
||||
|
||||
set_administration_mode
|
||||
-- Switch to administration mode.
|
||||
--| - Change theme
|
||||
--| - ..
|
||||
do
|
||||
if is_theme_valid (administration_theme_name) then
|
||||
set_theme (administration_theme_name)
|
||||
else
|
||||
-- Keep previous theme!
|
||||
end
|
||||
end
|
||||
|
||||
set_theme (a_name: READABLE_STRING_GENERAL)
|
||||
-- Set theme to `a_name`.
|
||||
do
|
||||
theme_name := a_name.as_string_32
|
||||
theme_location := themes_location.extended (theme_name)
|
||||
end
|
||||
|
||||
feature -- Query
|
||||
|
||||
text_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||
@@ -343,7 +386,7 @@ feature -- Query
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: Theme
|
||||
feature -- Access: directory
|
||||
|
||||
site_location: PATH
|
||||
-- Path to CMS site root dir.
|
||||
@@ -353,7 +396,10 @@ feature -- Access: Theme
|
||||
-- (Mainly for uploaded file).
|
||||
|
||||
files_location: PATH
|
||||
-- Path to public "files" dir.
|
||||
-- Path to public "files" dir.
|
||||
|
||||
cache_location: PATH
|
||||
-- Path to internal cache dir.
|
||||
|
||||
modules_location: PATH
|
||||
-- Path to modules.
|
||||
@@ -361,9 +407,19 @@ feature -- Access: Theme
|
||||
themes_location: PATH
|
||||
-- Path to themes.
|
||||
|
||||
feature -- Access: theme
|
||||
|
||||
theme_location: PATH
|
||||
-- Path to a active theme.
|
||||
|
||||
is_theme_valid (a_theme_name: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Does `a_theme_name` exists?
|
||||
local
|
||||
fu: FILE_UTILITIES
|
||||
do
|
||||
Result := fu.directory_path_exists (themes_location.extended (a_theme_name))
|
||||
end
|
||||
|
||||
theme_information_location: PATH
|
||||
-- Active theme informations.
|
||||
do
|
||||
@@ -373,6 +429,14 @@ feature -- Access: Theme
|
||||
theme_name: READABLE_STRING_32
|
||||
-- theme name.
|
||||
|
||||
site_theme_name: READABLE_STRING_32
|
||||
-- Site theme name.
|
||||
|
||||
administration_theme_name: READABLE_STRING_32
|
||||
-- Administration theme name.
|
||||
-- Default: same as site theme.
|
||||
-- TODO: change to builtin "admin" theme?
|
||||
|
||||
feature -- Access
|
||||
|
||||
mailer: NOTIFICATION_MAILER
|
||||
|
||||
@@ -212,18 +212,46 @@ feature -- Hook: cache
|
||||
|
||||
invoke_clear_cache (a_cache_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]; a_response: CMS_RESPONSE)
|
||||
-- Invoke cache hook for identifiers `a_cache_id_list'.
|
||||
local
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if attached subscribers ({CMS_HOOK_CACHE}) as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
if attached {CMS_HOOK_CACHE} c.item as h then
|
||||
h.clear_cache (a_cache_id_list, a_response)
|
||||
if not retried then
|
||||
if attached subscribers ({CMS_HOOK_CACHE}) as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
if attached {CMS_HOOK_CACHE} c.item as h then
|
||||
safe_call_clear_cache_on_hook (h, a_cache_id_list, a_response)
|
||||
end
|
||||
end
|
||||
a_response.clear_cache (a_cache_id_list)
|
||||
end
|
||||
|
||||
a_response.clear_cache (a_cache_id_list)
|
||||
else
|
||||
a_response.add_error_message ("Error occurred while clearing cache.")
|
||||
end
|
||||
rescue
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
feature {NONE} -- Hook: cache
|
||||
|
||||
safe_call_clear_cache_on_hook (a_hook: CMS_HOOK_CACHE; a_cache_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]; a_response: CMS_RESPONSE)
|
||||
local
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if not retried then
|
||||
a_hook.clear_cache (a_cache_id_list, a_response)
|
||||
else
|
||||
if attached {CMS_MODULE} a_hook as mod then
|
||||
a_response.add_error_message ("Exception occurred for `clear_cache` [" + mod.name + "]")
|
||||
else
|
||||
a_response.add_error_message ("Exception occurred for `clear_cache`")
|
||||
end
|
||||
end
|
||||
rescue
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- Hook: export
|
||||
|
||||
@@ -107,7 +107,7 @@ feature -- Handler
|
||||
append_info_to ("Assets dir", api.setup.environment.assets_path.utf_8_name, r, s)
|
||||
append_info_to ("Config dir", api.setup.environment.config_path.utf_8_name, r, s)
|
||||
s.append ("<hr/>")
|
||||
append_info_to ("Theme", api.setup.theme_name, r, s)
|
||||
append_info_to ("Theme", api.theme_name, r, s)
|
||||
append_info_to ("Theme location", api.theme_location.utf_8_name, r, s)
|
||||
s.append ("<hr/>")
|
||||
append_info_to ("Files location", api.files_location.utf_8_name, r, s)
|
||||
@@ -139,7 +139,7 @@ feature -- Handler
|
||||
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)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
36
src/service/cms_administrable.e
Normal file
36
src/service/cms_administrable.e
Normal file
@@ -0,0 +1,36 @@
|
||||
note
|
||||
description: "Interface providing administration module."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_ADMINISTRABLE
|
||||
|
||||
feature -- Administration
|
||||
|
||||
module_administration: like administration
|
||||
-- Associated administration module.
|
||||
do
|
||||
Result := internal_module_administration
|
||||
if Result = Void then
|
||||
Result := administration
|
||||
internal_module_administration := Result
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
internal_module_administration: detachable like module_administration
|
||||
-- Cached version of `module_administration`.
|
||||
|
||||
feature {NONE} -- Administration
|
||||
|
||||
administration: CMS_MODULE_ADMINISTRATION [CMS_MODULE]
|
||||
-- Administration module.
|
||||
deferred
|
||||
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
|
||||
@@ -15,6 +15,8 @@ inherit
|
||||
|
||||
CMS_ENCODERS
|
||||
|
||||
CMS_URL_UTILITIES
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
@@ -43,10 +45,15 @@ feature {NONE} -- Initialize
|
||||
l_module: CMS_MODULE
|
||||
l_enabled_modules: CMS_MODULE_COLLECTION
|
||||
l_uninstalled_mods: detachable ARRAYED_LIST [CMS_MODULE]
|
||||
s: IMMUTABLE_STRING_8
|
||||
do
|
||||
-- Initialize site_url
|
||||
initialize_site_url
|
||||
|
||||
-- Administration backend
|
||||
s := setup.administration_base_path
|
||||
administration_base_path_location := s.shared_substring (2, s.count)
|
||||
|
||||
-- Initialize formats.
|
||||
initialize_formats
|
||||
-- Initialize contents.
|
||||
@@ -100,8 +107,8 @@ feature {NONE} -- Initialize
|
||||
l_enabled_modules.remove (ic.item)
|
||||
end
|
||||
end
|
||||
-- Initialize hooks system
|
||||
setup_hooks
|
||||
|
||||
-- hooks initialization, is done after site/admin switch.
|
||||
end
|
||||
|
||||
initialize_site_url
|
||||
@@ -233,16 +240,121 @@ feature -- Access
|
||||
|
||||
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/
|
||||
|
||||
site_url: IMMUTABLE_STRING_8
|
||||
-- Site url
|
||||
|
||||
is_administration_request (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
Result := req.percent_encoded_path_info.starts_with_general (setup.administration_base_path)
|
||||
end
|
||||
|
||||
administration_path (a_relative_path: detachable READABLE_STRING_8): STRING_8
|
||||
do
|
||||
create Result.make_from_string (setup.administration_base_path)
|
||||
if a_relative_path /= Void and then not a_relative_path.is_empty then
|
||||
if a_relative_path[1] /= '/' then
|
||||
Result.append_character ('/')
|
||||
end
|
||||
Result.append (a_relative_path)
|
||||
end
|
||||
end
|
||||
|
||||
administration_path_location (a_relative_location: detachable READABLE_STRING_8): STRING_8
|
||||
require
|
||||
no_first_slash: a_relative_location = Void or else not a_relative_location.starts_with_general ("/")
|
||||
do
|
||||
create Result.make_from_string (administration_base_path_location)
|
||||
if a_relative_location /= Void then
|
||||
Result.append_character ('/')
|
||||
Result.append (a_relative_location)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Url implementation.
|
||||
|
||||
administration_base_path_location: IMMUTABLE_STRING_8
|
||||
-- Administration path without first slash!
|
||||
|
||||
feature -- CMS links
|
||||
|
||||
administration_link (a_title: READABLE_STRING_GENERAL; a_location: READABLE_STRING_8): CMS_LOCAL_LINK
|
||||
do
|
||||
Result := local_link (a_title, administration_path_location (a_location))
|
||||
end
|
||||
|
||||
local_link (a_title: READABLE_STRING_GENERAL; a_location: READABLE_STRING_8): CMS_LOCAL_LINK
|
||||
do
|
||||
create Result.make (a_title, a_location)
|
||||
end
|
||||
|
||||
user_local_link (u: CMS_USER; a_opt_title: detachable READABLE_STRING_GENERAL): CMS_LOCAL_LINK
|
||||
do
|
||||
if a_opt_title /= Void then
|
||||
create Result.make (a_opt_title, user_url (u))
|
||||
else
|
||||
create Result.make (user_display_name (u), user_url (u))
|
||||
end
|
||||
end
|
||||
|
||||
user_html_link (u: CMS_USER): STRING
|
||||
require
|
||||
u_with_name: not u.name.is_whitespace
|
||||
do
|
||||
Result := link (user_display_name (u), "user/" + u.id.out, Void)
|
||||
end
|
||||
|
||||
feature -- Helpers: URLs
|
||||
|
||||
location_absolute_url (a_location: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING
|
||||
-- Absolute URL for `a_location'.
|
||||
--| Options `opts' could be
|
||||
--| - absolute: True|False => return absolute url
|
||||
--| - query: string => append "?query"
|
||||
--| - fragment: string => append "#fragment"
|
||||
do
|
||||
Result := absolute_url (a_location, opts)
|
||||
end
|
||||
|
||||
location_url (a_location: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING
|
||||
-- URL for `a_location'.
|
||||
--| Options `opts' could be
|
||||
--| - absolute: True|False => return absolute url
|
||||
--| - query: string => append "?query"
|
||||
--| - fragment: string => append "#fragment"
|
||||
do
|
||||
Result := url (a_location, opts)
|
||||
end
|
||||
|
||||
user_url (u: CMS_USER): like url
|
||||
require
|
||||
u_with_id: u.has_id
|
||||
do
|
||||
Result := location_url ("user/" + u.id.out, Void)
|
||||
end
|
||||
|
||||
feature -- Helpers: html links
|
||||
|
||||
user_display_name (u: CMS_USER): READABLE_STRING_32
|
||||
do
|
||||
Result := user_api.user_display_name (u)
|
||||
end
|
||||
|
||||
feature -- Settings
|
||||
|
||||
switch_to_administration_mode
|
||||
do
|
||||
setup.set_administration_mode
|
||||
is_administration_mode := True
|
||||
end
|
||||
|
||||
is_administration_mode: BOOLEAN
|
||||
-- Is administration mode?
|
||||
|
||||
is_debug: BOOLEAN
|
||||
-- Is debug mode enabled?
|
||||
do
|
||||
@@ -646,13 +758,13 @@ feature -- Hooks
|
||||
hooks: CMS_HOOK_CORE_MANAGER
|
||||
-- Manager handling hook subscriptions.
|
||||
|
||||
feature {NONE} -- Hooks
|
||||
feature {CMS_EXECUTION} -- Hooks
|
||||
|
||||
setup_hooks
|
||||
-- Set up CMS hooks.
|
||||
--| Each module has to opportunity to subscribe to various hooks.
|
||||
local
|
||||
l_module: CMS_MODULE
|
||||
l_module: detachable CMS_MODULE
|
||||
l_hooks: like hooks
|
||||
do
|
||||
l_hooks := hooks
|
||||
@@ -661,10 +773,19 @@ feature {NONE} -- Hooks
|
||||
enabled_modules as ic
|
||||
loop
|
||||
l_module := ic.item
|
||||
if attached {CMS_HOOK_AUTO_REGISTER} l_module as l_auto then
|
||||
l_auto.auto_subscribe_to_hooks (l_hooks)
|
||||
if is_administration_mode then
|
||||
if attached {CMS_ADMINISTRABLE} l_module as adm then
|
||||
l_module := adm.module_administration
|
||||
else
|
||||
l_module := Void
|
||||
end
|
||||
end
|
||||
if l_module /= Void then
|
||||
if attached {CMS_HOOK_AUTO_REGISTER} l_module as l_auto then
|
||||
l_auto.auto_subscribe_to_hooks (l_hooks)
|
||||
end
|
||||
l_module.setup_hooks (l_hooks)
|
||||
end
|
||||
l_module.setup_hooks (l_hooks)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -695,8 +816,10 @@ feature -- Hooks
|
||||
setup_core_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
|
||||
-- Register hooks associated with the cms core.
|
||||
do
|
||||
a_hooks.subscribe_to_export_hook (Current)
|
||||
a_hooks.subscribe_to_import_hook (Current)
|
||||
if is_administration_mode then
|
||||
a_hooks.subscribe_to_export_hook (Current)
|
||||
a_hooks.subscribe_to_import_hook (Current)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Path aliases
|
||||
@@ -813,12 +936,23 @@ feature -- Environment/ theme
|
||||
Result := setup.files_location
|
||||
end
|
||||
|
||||
cache_location: PATH
|
||||
-- CMS internal cache location.
|
||||
do
|
||||
Result := setup.cache_location
|
||||
end
|
||||
|
||||
theme_location: PATH
|
||||
-- Active theme location.
|
||||
do
|
||||
Result := setup.theme_location
|
||||
end
|
||||
|
||||
theme_name: READABLE_STRING_32
|
||||
do
|
||||
Result := setup.theme_name
|
||||
end
|
||||
|
||||
theme_assets_location: PATH
|
||||
-- assets (js, css, images, etc).
|
||||
do
|
||||
@@ -831,6 +965,11 @@ feature -- Environment/ theme
|
||||
|
||||
feature -- Environment/ module
|
||||
|
||||
module_configuration (a_module: CMS_MODULE; a_name: detachable READABLE_STRING_GENERAL): detachable CONFIG_READER
|
||||
do
|
||||
Result := module_configuration_by_name (a_module.name, a_name)
|
||||
end
|
||||
|
||||
module_configuration_by_name (a_module_name: READABLE_STRING_GENERAL; a_name: detachable READABLE_STRING_GENERAL): detachable CONFIG_READER
|
||||
-- Configuration reader for `a_module', and if `a_name' is set, using name `a_name'.
|
||||
local
|
||||
@@ -970,11 +1109,6 @@ feature -- Environment/ modules and theme
|
||||
Result := theme_location.extended ("modules").extended (a_module_name)
|
||||
end
|
||||
|
||||
module_configuration (a_module: CMS_MODULE; a_name: detachable READABLE_STRING_GENERAL): detachable CONFIG_READER
|
||||
do
|
||||
Result := module_configuration_by_name (a_module.name, a_name)
|
||||
end
|
||||
|
||||
feature -- Access: active user
|
||||
|
||||
user_is_authenticated: BOOLEAN
|
||||
|
||||
@@ -19,8 +19,7 @@ inherit
|
||||
execute_default,
|
||||
filter_execute,
|
||||
initialize,
|
||||
initialize_router,
|
||||
initialize_filter
|
||||
initialize_router
|
||||
end
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
@@ -57,10 +56,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
initialize_cms
|
||||
do
|
||||
write_debug_log (generator + ".initialize_cms")
|
||||
|
||||
-- CMS Initialization
|
||||
|
||||
-- for void-safety concern.
|
||||
create {WSF_MAINTENANCE_FILTER} filter
|
||||
end
|
||||
@@ -69,16 +65,7 @@ feature {NONE} -- Initialization
|
||||
-- Initialize `router`.
|
||||
do
|
||||
create_router
|
||||
-- router setup is delayed toi `initialize_execution`.
|
||||
-- setup_router
|
||||
end
|
||||
|
||||
initialize_filter
|
||||
-- Initialize `filter`.
|
||||
do
|
||||
create_filter
|
||||
-- filter setup is delayed toi `initialize_execution`.
|
||||
-- setup_filter
|
||||
-- setup_router: delayed to `initialize_execution`.
|
||||
end
|
||||
|
||||
initialize_modules
|
||||
@@ -108,7 +95,7 @@ feature -- Access
|
||||
end
|
||||
|
||||
modules: CMS_MODULE_COLLECTION
|
||||
-- Configurator of possible modules.
|
||||
-- Declared modules.
|
||||
|
||||
feature -- CMS setup
|
||||
|
||||
@@ -139,14 +126,15 @@ feature -- Settings: router
|
||||
l_router: like router
|
||||
l_module: CMS_MODULE
|
||||
do
|
||||
api.logger.put_debug (generator + ".setup_router", Void)
|
||||
-- Configure root of api handler.
|
||||
l_api := api
|
||||
l_api.logger.put_debug (generator + ".setup_router", Void)
|
||||
|
||||
l_router := router
|
||||
|
||||
-- Configure root of api handler.
|
||||
configure_api_root (l_router)
|
||||
|
||||
-- Include routes from modules.
|
||||
l_api := api
|
||||
across
|
||||
modules as ic
|
||||
loop
|
||||
@@ -159,6 +147,37 @@ feature -- Settings: router
|
||||
configure_api_file_handler (l_router)
|
||||
end
|
||||
|
||||
setup_router_for_administration
|
||||
-- <Precursor>
|
||||
local
|
||||
l_api: like api
|
||||
l_router: like router
|
||||
l_module: CMS_MODULE
|
||||
do
|
||||
l_api := api
|
||||
l_router := router
|
||||
|
||||
l_api.logger.put_debug (generator + ".setup_router_for_administration", Void)
|
||||
|
||||
-- Configure root of api handler.
|
||||
l_router.set_base_url (l_api.administration_path (""))
|
||||
|
||||
-- Include routes from modules.
|
||||
across
|
||||
modules as ic
|
||||
loop
|
||||
l_module := ic.item
|
||||
if
|
||||
l_module.is_initialized and then
|
||||
attached {CMS_ADMINISTRABLE} l_module as l_administration and then
|
||||
attached l_administration.module_administration as adm
|
||||
then
|
||||
adm.setup_router (l_router, l_api)
|
||||
end
|
||||
end
|
||||
map_uri ("/install", create {CMS_ADMIN_INSTALL_HANDLER}.make (api), l_router.methods_head_get)
|
||||
end
|
||||
|
||||
configure_api_root (a_router: WSF_ROUTER)
|
||||
local
|
||||
l_root_handler: CMS_ROOT_HANDLER
|
||||
@@ -171,8 +190,6 @@ feature -- Settings: router
|
||||
a_router.handle ("/", l_root_handler, l_methods)
|
||||
a_router.handle ("", l_root_handler, l_methods)
|
||||
map_uri_agent ("/favicon.ico", agent handle_favicon, a_router.methods_head_get)
|
||||
|
||||
map_uri ("/admin/install", create {CMS_ADMIN_INSTALL_HANDLER}.make (api), a_router.methods_head_get)
|
||||
end
|
||||
|
||||
configure_api_file_handler (a_router: WSF_ROUTER)
|
||||
@@ -217,10 +234,28 @@ feature -- Request execution
|
||||
-- Initialize CMS execution.
|
||||
do
|
||||
request.set_uploaded_file_path (api.temp_location)
|
||||
setup_filter
|
||||
if api.is_administration_request (request) then
|
||||
initialize_administration_execution
|
||||
else
|
||||
initialize_site_execution
|
||||
end
|
||||
end
|
||||
|
||||
initialize_site_execution
|
||||
-- Initialize for site execution.
|
||||
do
|
||||
api.setup_hooks
|
||||
setup_router
|
||||
end
|
||||
|
||||
initialize_administration_execution
|
||||
-- Initialize for administration execution.
|
||||
do
|
||||
api.switch_to_administration_mode
|
||||
api.setup_hooks
|
||||
setup_router_for_administration
|
||||
end
|
||||
|
||||
execute
|
||||
-- <Precursor>.
|
||||
do
|
||||
@@ -233,6 +268,7 @@ feature -- Request execution
|
||||
do
|
||||
res.put_header_line ("Date: " + (create {HTTP_DATE}.make_now_utc).string)
|
||||
res.put_header_line ("X-EWF-Server: CMS_v1.0")
|
||||
|
||||
Precursor (req, res)
|
||||
end
|
||||
|
||||
@@ -282,8 +318,6 @@ feature -- Filters
|
||||
setup_filter
|
||||
-- Setup `filter'.
|
||||
do
|
||||
api.logger.put_debug (generator + ".setup_filter", Void)
|
||||
append_filter (Current)
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
@@ -7,10 +7,10 @@ deferred class
|
||||
CMS_MODULE
|
||||
|
||||
inherit
|
||||
REFACTORING_HELPER
|
||||
|
||||
CMS_ENCODERS
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
feature -- Access
|
||||
|
||||
is_enabled: BOOLEAN
|
||||
@@ -80,7 +80,7 @@ feature -- Status
|
||||
is_initialized: BOOLEAN
|
||||
-- Is Current module initialized?
|
||||
|
||||
feature {CMS_API} -- Access: API
|
||||
feature {CMS_API, CMS_MODULE_ADMINISTRATION} -- Access: API
|
||||
|
||||
module_api: detachable CMS_MODULE_API
|
||||
-- Eventual module api.
|
||||
@@ -180,33 +180,6 @@ feature {CMS_API} -- Module management
|
||||
api.storage.set_custom_value ("is_installed", "no", "module-" + name)
|
||||
end
|
||||
|
||||
feature -- Router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- Setup url dispatching for Current module.
|
||||
require
|
||||
is_initialized: is_initialized
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
|
||||
setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
|
||||
-- Module hooks configuration.
|
||||
require
|
||||
is_enabled: is_enabled
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Filter
|
||||
|
||||
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
|
||||
-- Optional list of filter for Current module.
|
||||
require
|
||||
is_enabled: is_enabled
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Settings
|
||||
|
||||
enable
|
||||
@@ -225,12 +198,39 @@ feature -- Settings
|
||||
module_disbaled: not is_enabled
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
feature -- Filter
|
||||
|
||||
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
|
||||
-- Optional list of filter for Current module.
|
||||
require
|
||||
is_enabled: is_enabled
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- Setup url dispatching for Current module.
|
||||
require
|
||||
is_initialized: is_initialized
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
|
||||
setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
|
||||
-- Module hooks configuration.
|
||||
require
|
||||
is_enabled: is_enabled
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Help
|
||||
|
||||
help_text (a_path: STRING): STRING
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
to_implement ("Add the corresponing implementation.")
|
||||
to_implement ("Add the corresponding implementation.")
|
||||
end
|
||||
create Result.make_empty
|
||||
end
|
||||
|
||||
80
src/service/cms_module_administration.e
Normal file
80
src/service/cms_module_administration.e
Normal file
@@ -0,0 +1,80 @@
|
||||
note
|
||||
description: "[
|
||||
Objects that ...
|
||||
]"
|
||||
author: "$Author$"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_MODULE_ADMINISTRATION [G -> CMS_MODULE]
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
rename
|
||||
is_initialized as module_is_initialized,
|
||||
is_enabled as module_is_enabled
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_module: G)
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
module := a_module
|
||||
version := a_module.version
|
||||
description := a_module.description
|
||||
package := a_module.package
|
||||
|
||||
module_is_initialized := a_module.is_initialized
|
||||
module_is_enabled := a_module.is_enabled
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
module: G
|
||||
|
||||
name: STRING
|
||||
do
|
||||
Result := module.name
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
|
||||
is_initialized: BOOLEAN
|
||||
-- Is Current module initialized?
|
||||
do
|
||||
Result := module.is_initialized
|
||||
end
|
||||
|
||||
is_enabled: BOOLEAN
|
||||
-- Is Current module enabled?
|
||||
do
|
||||
Result := module.is_enabled
|
||||
end
|
||||
|
||||
feature -- Router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
if a_router.base_url /= Void then
|
||||
setup_administration_router (a_router, a_api)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Router/administration
|
||||
|
||||
setup_administration_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- Setup url dispatching for Current module administration.
|
||||
-- (note: `a_router` is already based with admin path prefix).
|
||||
require
|
||||
is_initialized: is_initialized
|
||||
router_has_base_url: a_router.base_url /= Void
|
||||
deferred
|
||||
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
|
||||
@@ -43,11 +43,16 @@ feature -- HTTP Methods
|
||||
l_module: CMS_MODULE
|
||||
s: STRING
|
||||
lst: ARRAYED_LIST [CMS_MODULE]
|
||||
l_access: detachable READABLE_STRING_8
|
||||
l_denied: BOOLEAN
|
||||
do
|
||||
--| FIXME: improve the installer.
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if attached api.setup.string_8_item ("admin.installation_access") as l_access then
|
||||
l_access := api.setup.string_8_item ("admin.installation_access")
|
||||
if l_access = Void then
|
||||
l_access := api.setup.string_8_item ("administration.installation_access")
|
||||
end
|
||||
if l_access /= Void then
|
||||
if l_access.is_case_insensitive_equal ("none") then
|
||||
l_denied := True
|
||||
elseif l_access.is_case_insensitive_equal ("permission") then
|
||||
@@ -100,6 +105,7 @@ feature -- HTTP Methods
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
s.append ("<div>Back to the " + r.link ("Administration", api.administration_path (""), Void) + " ...</div>")
|
||||
r.set_main_content (s)
|
||||
end
|
||||
r.set_title (r.translation ("CMS Installation ...", Void))
|
||||
|
||||
@@ -193,6 +193,6 @@ feature -- Url
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, 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
|
||||
|
||||
@@ -30,10 +30,19 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
|
||||
initialize
|
||||
local
|
||||
s: READABLE_STRING_8
|
||||
do
|
||||
get_theme
|
||||
create menu_system.make
|
||||
initialize_block_region_settings
|
||||
|
||||
s := request.percent_encoded_path_info
|
||||
if not s.is_empty and then s[1] = '/' then
|
||||
create location.make_from_string (s.substring (2, s.count))
|
||||
else
|
||||
create location.make_from_string (s)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
@@ -48,6 +57,14 @@ feature -- Access
|
||||
|
||||
main_content: detachable STRING_8
|
||||
|
||||
feature -- Settings
|
||||
|
||||
is_administration_mode: BOOLEAN
|
||||
-- Is administration mode?
|
||||
do
|
||||
Result := api.is_administration_mode
|
||||
end
|
||||
|
||||
feature -- Access: metadata
|
||||
|
||||
title: detachable READABLE_STRING_32
|
||||
@@ -76,15 +93,8 @@ feature -- Access: metadata
|
||||
|
||||
feature -- Access: query
|
||||
|
||||
location: STRING_8
|
||||
location: IMMUTABLE_STRING_8
|
||||
-- Associated cms local location.
|
||||
do
|
||||
create Result.make_from_string (request.percent_encoded_path_info)
|
||||
if not Result.is_empty and then Result[1] = '/' then
|
||||
Result.remove_head (1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- API
|
||||
|
||||
@@ -496,7 +506,7 @@ feature -- Block management
|
||||
nb_secs.is_integer
|
||||
then
|
||||
if attached block_region_preference (a_block_id, "none") as l_region and then not l_region.same_string_general ("none") then
|
||||
create l_cache.make (api.files_location.extended (".cache").extended ("blocks").extended (a_block_id).appended_with_extension ("html"))
|
||||
create l_cache.make (api.cache_location.extended ("_blocks").extended (a_block_id).appended_with_extension ("html"))
|
||||
if
|
||||
l_cache.exists and then
|
||||
not l_cache.expired (Void, nb_secs.to_integer)
|
||||
@@ -517,7 +527,7 @@ feature -- Block management
|
||||
dir: DIRECTORY
|
||||
l_cache: CMS_FILE_STRING_8_CACHE
|
||||
do
|
||||
p := api.files_location.extended (".cache").extended ("blocks")
|
||||
p := api.cache_location.extended ("_blocks")
|
||||
if a_block_id_list /= Void then
|
||||
across
|
||||
a_block_id_list as ic
|
||||
@@ -535,6 +545,7 @@ feature -- Block management
|
||||
create dir.make_with_path (p)
|
||||
dir.recursive_delete
|
||||
end
|
||||
add_notice_message ("Blocks cache cleared.")
|
||||
end
|
||||
|
||||
feature {CMS_HOOK_CORE_MANAGER} -- Block management: internal
|
||||
@@ -1002,9 +1013,9 @@ feature -- Theme
|
||||
create l_info.make_default
|
||||
end
|
||||
if l_info.engine.is_case_insensitive_equal_general ("smarty") then
|
||||
create {SMARTY_CMS_THEME} theme.make (setup, l_info, site_url)
|
||||
create {SMARTY_CMS_THEME} theme.make (api, l_info, site_url)
|
||||
else
|
||||
create {MISSING_CMS_THEME} theme.make (setup, l_info, site_url)
|
||||
create {MISSING_CMS_THEME} theme.make (api, l_info, site_url)
|
||||
status_code := {HTTP_STATUS_CODE}.service_unavailable
|
||||
to_implement ("Check how to add the Retry-after, http://tools.ietf.org/html/rfc7231#section-6.6.4 and http://tools.ietf.org/html/rfc7231#section-7.1.3")
|
||||
end
|
||||
@@ -1083,7 +1094,7 @@ feature -- Generation
|
||||
|
||||
if api.enabled_modules.count = 1 then
|
||||
-- It is the required CMS_CORE_MODULE!
|
||||
add_to_primary_menu (create {CMS_LOCAL_LINK}.make ("Install", "admin/install"))
|
||||
add_to_primary_menu (api.administration_link ("Install", "install"))
|
||||
end
|
||||
|
||||
-- Blocks
|
||||
@@ -1322,32 +1333,33 @@ feature -- Generation
|
||||
|
||||
feature -- Helpers: cms link
|
||||
|
||||
administration_link (a_title: READABLE_STRING_GENERAL; a_location: READABLE_STRING_8): CMS_LOCAL_LINK
|
||||
do
|
||||
Result := api.administration_link (a_title, a_location)
|
||||
end
|
||||
|
||||
local_link (a_title: READABLE_STRING_GENERAL; a_location: READABLE_STRING_8): CMS_LOCAL_LINK
|
||||
do
|
||||
create Result.make (a_title, a_location)
|
||||
Result := api.local_link (a_title, a_location)
|
||||
end
|
||||
|
||||
user_local_link (u: CMS_USER; a_opt_title: detachable READABLE_STRING_GENERAL): CMS_LOCAL_LINK
|
||||
do
|
||||
if a_opt_title /= Void then
|
||||
create Result.make (a_opt_title, user_url (u))
|
||||
else
|
||||
create Result.make (user_profile_name (u), user_url (u))
|
||||
end
|
||||
Result := api.user_local_link (u, a_opt_title)
|
||||
end
|
||||
|
||||
feature -- Helpers: html links
|
||||
|
||||
user_profile_name, user_display_name (u: CMS_USER): READABLE_STRING_32
|
||||
do
|
||||
Result := api.user_api.user_display_name (u)
|
||||
Result := api.user_display_name (u)
|
||||
end
|
||||
|
||||
user_html_link (u: CMS_USER): STRING
|
||||
require
|
||||
u_with_name: not u.name.is_whitespace
|
||||
do
|
||||
Result := link (user_profile_name (u), "user/" + u.id.out, Void)
|
||||
Result := api.user_html_link (u)
|
||||
end
|
||||
|
||||
feature -- Helpers: URLs
|
||||
@@ -1359,7 +1371,7 @@ feature -- Helpers: URLs
|
||||
--| - query: string => append "?query"
|
||||
--| - fragment: string => append "#fragment"
|
||||
do
|
||||
Result := absolute_url (a_location, opts)
|
||||
Result := api.location_absolute_url (a_location, opts)
|
||||
end
|
||||
|
||||
location_url (a_location: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING
|
||||
@@ -1369,14 +1381,14 @@ feature -- Helpers: URLs
|
||||
--| - query: string => append "?query"
|
||||
--| - fragment: string => append "#fragment"
|
||||
do
|
||||
Result := url (a_location, opts)
|
||||
Result := api.location_url (a_location, opts)
|
||||
end
|
||||
|
||||
user_url (u: CMS_USER): like url
|
||||
require
|
||||
u_with_id: u.has_id
|
||||
do
|
||||
Result := location_url ("user/" + u.id.out, Void)
|
||||
Result := api.user_url (u)
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
@@ -263,7 +263,7 @@ feature -- User roles.
|
||||
role_permissions: HASH_TABLE [LIST [READABLE_STRING_8], STRING_8]
|
||||
-- Possible known permissions indexed by modules.
|
||||
local
|
||||
lst, l_used_permissions: LIST [READABLE_STRING_8]
|
||||
lst, l_full_lst, l_used_permissions: LIST [READABLE_STRING_8]
|
||||
do
|
||||
create Result.make (cms_api.enabled_modules.count + 1)
|
||||
|
||||
@@ -272,6 +272,28 @@ feature -- User roles.
|
||||
cms_api.enabled_modules as ic
|
||||
loop
|
||||
lst := ic.item.permissions
|
||||
if attached {CMS_ADMINISTRABLE} ic.item as adm then
|
||||
create {ARRAYED_LIST [READABLE_STRING_8]} l_full_lst.make (lst.count)
|
||||
l_full_lst.compare_objects
|
||||
-- l_full_lst.append (lst)
|
||||
across
|
||||
lst as lst_ic
|
||||
loop
|
||||
if not l_full_lst.has (lst_ic.item) then
|
||||
l_full_lst.extend (lst_ic.item)
|
||||
end
|
||||
end
|
||||
-- l_full_lst.append (adm.module_administration.permissions)
|
||||
lst := adm.module_administration.permissions
|
||||
across
|
||||
lst as lst_ic
|
||||
loop
|
||||
if not l_full_lst.has (lst_ic.item) then
|
||||
l_full_lst.extend (lst_ic.item)
|
||||
end
|
||||
end
|
||||
lst := l_full_lst
|
||||
end
|
||||
Result.force (lst, ic.item.name)
|
||||
across
|
||||
lst as p_ic
|
||||
|
||||
@@ -16,7 +16,7 @@ inherit
|
||||
|
||||
feature {NONE} -- Access
|
||||
|
||||
setup: CMS_SETUP
|
||||
api: CMS_API
|
||||
|
||||
site_url: IMMUTABLE_STRING_8
|
||||
-- Absolute URL for Current CMS site.
|
||||
@@ -186,7 +186,7 @@ feature {NONE} -- Implementation
|
||||
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)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -18,13 +18,13 @@ create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_setup: like setup; a_info: like information; abs_site_url: READABLE_STRING_8)
|
||||
make (a_api: like api; a_info: like information; abs_site_url: READABLE_STRING_8)
|
||||
do
|
||||
setup := a_setup
|
||||
api := a_api
|
||||
information := a_info
|
||||
set_site_url (abs_site_url)
|
||||
ensure
|
||||
setup_set: setup = a_setup
|
||||
api_set: api = a_api
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
@@ -49,4 +49,7 @@ feature -- Access
|
||||
to_implement ("Add a better response message, maybe using smarty template")
|
||||
Result := "Service Unavailable"
|
||||
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
|
||||
|
||||
@@ -14,18 +14,18 @@ create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_setup: like setup; a_info: like information; abs_site_url: READABLE_STRING_8)
|
||||
make (a_api: like api; a_info: like information; abs_site_url: READABLE_STRING_8)
|
||||
do
|
||||
setup := a_setup
|
||||
api := a_api
|
||||
information := a_info
|
||||
if attached a_info.item ("template_dir") as s then
|
||||
templates_directory := a_setup.theme_location.extended (s)
|
||||
templates_directory := a_api.theme_location.extended (s)
|
||||
else
|
||||
templates_directory := a_setup.theme_location
|
||||
templates_directory := a_api.theme_location
|
||||
end
|
||||
set_site_url (abs_site_url)
|
||||
ensure
|
||||
setup_set: setup = a_setup
|
||||
api_set: api = a_api
|
||||
information_set: information = a_info
|
||||
end
|
||||
|
||||
@@ -129,7 +129,7 @@ feature {NONE} -- Internal
|
||||
invariant
|
||||
attached internal_page_template as inv_p implies inv_p.theme = Current
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, 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)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
Reference in New Issue
Block a user