Moved library/src to src

This commit is contained in:
2015-01-27 19:58:13 +01:00
parent d97c4b1a4a
commit 5ddc2006e2
83 changed files with 255 additions and 92 deletions

View File

@@ -1,187 +0,0 @@
note
description: "[
Default CMS_SETUP that can be reused easily, and/or redefined to match specific setup.
]"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
CMS_DEFAULT_SETUP
inherit
CMS_SETUP
REFACTORING_HELPER
create
make
feature {NONE} -- Initialization
make (a_layout: CMS_LAYOUT)
-- Create a default setup with `a_layout'.
do
layout := a_layout
create {INI_CONFIG} configuration.make_from_file (layout.cms_config_ini_path)
initialize
end
initialize
-- Initialize various cms components.
do
configure
create modules.make (3)
create storage_drivers.make (2)
build_mailer
initialize_storages
initialize_modules
end
configure
do
--| Site id, used to identified a site, this could be set to a uuid, or else
site_id := text_item_or_default ("site.id", "_EWF_CMS_NO_ID_")
-- Site url: optional, but ending with a slash
site_url := string_8_item ("site_url")
if attached site_url as l_url and then not l_url.is_empty then
if l_url[l_url.count] /= '/' then
site_url := l_url + "/"
end
end
-- Site name
site_name := text_item_or_default ("site.name", "EWF::CMS")
-- Site email for any internal notification
-- Can be also used to precise the "From:" value for email.
site_email := text_item_or_default ("site.email", "webmaster")
-- Location for theme folders.
if attached text_item ("themes-dir") as s then
create themes_location.make_from_string (s)
else
themes_location := layout.www_path.extended ("themes")
end
-- Selected theme's name
theme_name := text_item_or_default ("theme", "default")
debug ("refactor_fixme")
fixme ("Review export clause for configuration and layout")
end
compute_theme_location
compute_theme_assets_location
end
initialize_storages
-- Initialize storages
do
storage_drivers.force (create {CMS_STORAGE_NULL_BUILDER}, "null")
end
initialize_modules
-- Intialize core modules.
local
m: CMS_MODULE
do
-- -- Core
-- create {USER_MODULE} m.make (Current)
-- m.enable
-- register_module (m)
-- create {ADMIN_MODULE} m.make (Current)
-- m.enable
-- register_module (m)
create {NODE_MODULE} m.make (Current)
m.enable
register_module (m)
end
feature {NONE} -- Configuration
configuration: CONFIG_READER
-- Association configuration file.
feature -- Access
modules: CMS_MODULE_COLLECTION
-- <Precursor>
text_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Configuration value associated with `a_name', if any.
do
Result := configuration.resolved_text_item (a_name)
end
string_8_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_8
-- String 8 configuration value associated with `a_name', if any.
local
utf: UTF_CONVERTER
do
if attached text_item (a_name) as s then
if s.is_valid_as_string_8 then
Result := s.as_string_8
else
Result := utf.escaped_utf_32_string_to_utf_8_string_8 (s)
end
end
end
is_html: BOOLEAN
-- <Precursor>
do
-- Enable change the mode
Result := (create {CMS_JSON_CONFIGURATION}).is_html_mode (layout.application_config_path)
end
is_web: BOOLEAN
-- <Precursor>
do
Result := (create {CMS_JSON_CONFIGURATION}).is_web_mode (layout.application_config_path)
end
build_auth_engine
do
to_implement ("Not implemented authentication")
end
build_mailer
do
to_implement ("Not implemented mailer")
end
feature -- Access: storage
storage_drivers: STRING_TABLE [CMS_STORAGE_BUILDER]
-- Precursor
feature -- Element change
register_module (m: CMS_MODULE)
-- <Precursor>
do
modules.extend (m)
end
feature -- Compute location
compute_theme_location
do
theme_location := themes_location.extended (theme_name)
end
compute_theme_assets_location
-- assets (js, css, images, etc)
-- Not used at the moment.
do
debug ("refactor_fixme")
fixme ("Check if we really need it")
end
-- Check how to get this path from the CMS_THEME information.
theme_assets_location := theme_location.extended ("assets")
end
end

View File

@@ -1,53 +0,0 @@
note
description: "Summary description for {CMS_JSON_CONFIGURATION}."
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
revision: "$Revision: 96454 $"
class
CMS_JSON_CONFIGURATION
inherit
APPLICATION_JSON_CONFIGURATION_HELPER
feature -- Access
is_html_mode (a_path: PATH): BOOLEAN
-- Is the server running on web mode?
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached l_parser.parsed_json_object as jo and then l_parser.is_parsed and then
attached {JSON_OBJECT} jo.item ("server") as l_server and then
attached {JSON_STRING} l_server.item ("mode") as l_mode
then
Result := l_mode.item.is_case_insensitive_equal_general ("html")
end
end
end
is_web_mode (a_path: PATH): BOOLEAN
-- Is the server running on web mode?
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached l_parser.parsed_json_object as jo and then l_parser.is_parsed and then
attached {JSON_OBJECT} jo.item ("server") as l_server and then
attached {JSON_STRING} l_server.item ("mode") as l_mode
then
Result := l_mode.item.is_case_insensitive_equal_general ("web")
end
end
end
end

View File

@@ -1,59 +0,0 @@
note
description: "[
CMS Layout providing file system locations for
- config
- application
- logs
- documentation
- themes
]"
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
revision: "$Revision: 96383 $"
class
CMS_LAYOUT
inherit
APPLICATION_LAYOUT
create
make_default,
make_with_path
feature -- Access
theme_path: PATH
-- Directory for templates (HTML, etc).
local
p: detachable PATH
do
p := internal_theme_path
if p = Void then
p := www_path.extended ("theme")
internal_theme_path := p
end
Result := p
end
cms_config_ini_path: PATH
-- CMS Configuration file path.
local
p: detachable PATH
do
p := internal_cms_config_ini_path
if p = Void then
p := config_path.extended ("cms.ini")
internal_cms_config_ini_path := p
end
Result := p
end
feature {NONE} -- Implementation
internal_theme_path: detachable like theme_path
internal_cms_config_ini_path: detachable like cms_config_ini_path
end

View File

@@ -1,171 +0,0 @@
note
description: "Class that enable to set basic configuration, application layout, core modules and themes."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_SETUP
inherit
REFACTORING_HELPER
feature -- Access
layout: CMS_LAYOUT
-- CMS layout.
is_html: BOOLEAN
-- api with progressive enhancements css and js, server side rendering.
deferred
end
is_web: BOOLEAN
-- web: Web Site with progressive enhancements css and js and Ajax calls.
deferred
end
enabled_modules: CMS_MODULE_COLLECTION
-- List of enabled modules.
local
l_module: CMS_MODULE
do
create Result.make (modules.count)
across
modules as ic
loop
l_module := ic.item
if l_module.is_enabled then
Result.extend (l_module)
end
end
ensure
only_enabled_modules: across Result as ic all ic.item.is_enabled end
end
feature {CMS_MODULE} -- Restricted access
modules: CMS_MODULE_COLLECTION
-- List of available modules.
deferred
end
feature -- Access: Site
site_id: READABLE_STRING_8
-- String identifying current CMS.
-- This could be used in webform, for cookie name, ...
site_name: READABLE_STRING_32
-- Name of the site.
site_email: READABLE_STRING_8
-- Admin email address for the site.
-- Mainly used for internal notification.
site_url: detachable READABLE_STRING_8
-- Optional base url of the site.
front_page_path: detachable READABLE_STRING_8
-- Optional path defining the front page.
-- By default "" or "/".
feature -- Query
text_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Configuration value associated with `a_name', if any.
deferred
end
text_item_or_default (a_name: READABLE_STRING_GENERAL; a_default_value: READABLE_STRING_GENERAL): READABLE_STRING_32
-- `text_item' associated with `a_name' or if none, `a_default_value'.
do
if attached text_item (a_name) as v then
Result := v
else
Result := a_default_value.as_string_32
end
end
string_8_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_8
-- Configuration value associated with `a_name', if any.
deferred
end
feature -- Access: Theme
themes_location: PATH
-- Path to themes.
theme_location: PATH
-- Path to a active theme.
theme_assets_location: PATH
-- Path to a active theme assets folder.
theme_information_location: PATH
-- Active theme informations.
do
Result := theme_location.extended ("theme.info")
end
theme_name: READABLE_STRING_32
-- theme name.
feature -- Access: storage
storage_drivers: STRING_TABLE [CMS_STORAGE_BUILDER]
deferred
end
storage (a_error_handler: ERROR_HANDLER): detachable CMS_STORAGE
local
retried: BOOLEAN
l_message: STRING
do
if not retried then
to_implement ("Refactor database setup")
if
attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (layout.application_config_path) as l_database_config and then
attached storage_drivers.item (l_database_config.driver) as l_builder
then
Result := l_builder.storage (Current)
else
create {CMS_STORAGE_NULL} Result
end
else
to_implement ("Workaround code, persistence layer does not implement yet this kind of error handling.")
-- error hanling.
create {CMS_STORAGE_NULL} Result
create l_message.make (1024)
if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then
if attached l_exception.description as l_description then
l_message.append (l_description.as_string_32)
l_message.append ("%N%N")
elseif attached l_exception.trace as l_trace then
l_message.append (l_trace)
l_message.append ("%N%N")
else
l_message.append (l_exception.out)
l_message.append ("%N%N")
end
else
l_message.append ("The application crash without available information")
l_message.append ("%N%N")
end
a_error_handler.add_custom_error (0, " Database Connection ", l_message)
end
rescue
retried := True
retry
end
feature -- Element change
register_module (m: CMS_MODULE)
-- Add module `m' to `modules'
deferred
ensure
module_added: modules.has (m)
end
end

View File

@@ -1,11 +0,0 @@
note
description: "[
Marker interface for CMS Hook
]"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_HOOK
end

View File

@@ -1,38 +0,0 @@
note
description: "[
Summary description for {CMS_HOOK_AUTO_REGISTER}.
When inheriting from this class, the declared hooks are automatically
registered, otherwise, each descendant has to add it to the cms service
itself.
]"
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
deferred class
CMS_HOOK_AUTO_REGISTER
inherit
CMS_HOOK
feature -- Hook
auto_subscribe_to_hooks (a_response: CMS_RESPONSE)
do
if attached {CMS_HOOK_MENU_SYSTEM_ALTER} Current as h_menu_system_alter then
a_response.subscribe_to_menu_system_alter_hook (h_menu_system_alter)
end
if attached {CMS_HOOK_MENU_ALTER} Current as h_menu_alter then
a_response.subscribe_to_menu_alter_hook (h_menu_alter)
end
if attached {CMS_HOOK_BLOCK} Current as h_block then
a_response.subscribe_to_block_hook (h_block)
end
if attached {CMS_HOOK_FORM_ALTER} Current as h_form then
a_response.subscribe_to_form_alter_hook (h_form)
end
if attached {CMS_HOOK_VALUE_TABLE_ALTER} Current as h_value then
a_response.subscribe_to_value_table_alter_hook (h_value)
end
end
end

View File

@@ -1,26 +0,0 @@
note
description: "[
Hook providing a way to alter a block.
]"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_HOOK_BLOCK
inherit
CMS_HOOK
feature -- Hook
block_list: ITERABLE [like {CMS_BLOCK}.name]
-- List of block names, managed by current object.
deferred
end
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
-- Get block object identified by `a_block_id' and associate with `a_response'.
deferred
end
end

View File

@@ -1,29 +0,0 @@
note
description: "Summary description for {CMS_HOOK_BLOCK_HELPER}."
author: ""
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
revision: "$Revision: 96454 $"
deferred class
CMS_HOOK_BLOCK_HELPER
feature -- Factory
template_block (a_module: CMS_MODULE; a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE): detachable CMS_SMARTY_TEMPLATE_BLOCK
-- Smarty content block for `a_block_id' in the context of `a_module' and `a_response'.
local
p: detachable PATH
do
create p.make_from_string ("templates")
p := p.extended ("block_").appended (a_block_id).appended_with_extension ("tpl")
p := a_response.module_resource_path (a_module, p)
if p /= Void then
if attached p.entry as e then
create Result.make (a_block_id, Void, p.parent, e)
else
create Result.make (a_block_id, Void, p.parent, p)
end
end
end
end

View File

@@ -1,21 +0,0 @@
note
description: "[
Hook providing a way to alter a form.
]"
date: "$Date$"
deferred class
CMS_HOOK_FORM_ALTER
inherit
CMS_HOOK
feature -- Hook
form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; a_response: CMS_RESPONSE)
-- Hook execution on form `a_form' and its associated data `a_form_data',
-- for related response `a_response'.
deferred
end
end

View File

@@ -1,21 +0,0 @@
note
description: "[
Hook providing a way to alter a menu
]"
date: "$Date$"
deferred class
CMS_HOOK_MENU_ALTER
inherit
CMS_HOOK
feature -- Hook
menu_alter (a_menu: CMS_MENU; a_response: CMS_RESPONSE)
-- Hook execution on menu `a_menu'
-- for related response `a_response'.
deferred
end
end

View File

@@ -1,21 +0,0 @@
note
description: "[
Hook providing a way to alter the CMS menu system.
]"
date: "$Date$"
deferred class
CMS_HOOK_MENU_SYSTEM_ALTER
inherit
CMS_HOOK
feature -- Hook
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
-- Hook execution on collection of menu contained by `a_menu_system'
-- for related response `a_response'.
deferred
end
end

View File

@@ -1,30 +0,0 @@
note
description: "[
Hook providing a way to alter the value table for a response.
]"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_HOOK_VALUE_TABLE_ALTER
inherit
CMS_HOOK
feature -- Hook
value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE)
deferred
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,97 +0,0 @@
note
description: "Summary description for {WSF_CMS_COMMON_API}."
author: ""
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
deferred class
CMS_COMMON_API
inherit
WSF_API_UTILITIES
feature {NONE} -- Access
site_url: READABLE_STRING_8
do
Result := ""
end
base_url: detachable READABLE_STRING_8
-- Base url if any.
do
end
feature -- Access
user_link (u: CMS_USER): like link
do
Result := link (u.name, "/user/" + u.id.out, Void)
end
node_link (n: CMS_NODE): like link
do
Result := link (n.title, "/node/" + n.id.out, Void)
end
user_url (u: CMS_USER): like url
do
Result := url ("/user/" + u.id.out, Void)
end
node_url (n: CMS_NODE): like url
do
Result := url ("/node/" + n.id.out, Void)
end
feature -- Helper
is_empty (s: detachable READABLE_STRING_GENERAL): BOOLEAN
-- Is `s' is Void or empty ?
do
Result := s = Void or else s.is_empty
end
unix_timestamp (dt: DATE_TIME): INTEGER_64
do
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp (dt)
end
unix_timestamp_to_date_time (t: INTEGER_64): DATE_TIME
do
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (t)
end
string_unix_timestamp_to_date_time (s: READABLE_STRING_8): DATE_TIME
do
if s.is_integer_64 then
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (s.to_integer_64)
else
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (0)
end
end
feature {NONE} -- Implementation
options_boolean (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING; dft: BOOLEAN): BOOLEAN
do
if attached {BOOLEAN} opts.item (k) as h then
Result := h
else
Result := dft
end
end
options_string (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING): detachable STRING
do
if attached {STRING} opts.item (k) as s then
Result := s
end
end
-- html_encoder: HTML_ENCODER
-- once ("thread")
-- create Result
-- end
end

View File

@@ -1,38 +0,0 @@
note
description: "Describe content to be placed inside Regions."
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
deferred class
CMS_BLOCK
feature -- Access
name: READABLE_STRING_8
-- Name identifying Current block.
deferred
end
title: detachable READABLE_STRING_32
-- Optional title.
deferred
end
feature -- status report
is_enabled: BOOLEAN
-- Is current block enabled?
is_raw: BOOLEAN
-- Is raw?
-- If True, do not get wrapped it with block specific div
deferred
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
-- HTML representation of Current block.
deferred
end
end

View File

@@ -1,42 +0,0 @@
note
description: "Summary description for {CMS_BLOCK_REGION}."
date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $"
class
CMS_BLOCK_REGION
create
make
feature {NONE} -- Initialization
make (a_name: like name)
do
name := a_name
create blocks.make (1)
end
feature -- Access
name: READABLE_STRING_8
blocks: ARRAYED_LIST [CMS_BLOCK]
feature -- Element change
extend (b: CMS_BLOCK)
do
blocks.force (b)
end
;note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,96 +0,0 @@
note
description: "CMS_BLOCK implemented with a `content' associated with a specific `format'."
date: "$Date$"
revision: "$Revision$"
class
CMS_CONTENT_BLOCK
inherit
CMS_BLOCK
create
make,
make_raw
feature {NONE} -- Initialization
make (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
require
a_name_not_blank: not a_name.is_whitespace
do
is_enabled := True
name := a_name
title := a_title
content := a_content
format := a_format
end
make_raw (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
require
a_name_not_blank: not a_name.is_whitespace
do
make (a_name, a_title, a_content, a_format)
set_is_raw (True)
end
feature -- Access
name: READABLE_STRING_8
title: detachable READABLE_STRING_32
content: READABLE_STRING_8
format: detachable CONTENT_FORMAT
feature -- Status report
is_raw: BOOLEAN
-- Is raw?
-- If True, do not get wrapped it with block specific div
feature -- Element change
set_is_raw (b: BOOLEAN)
do
is_raw := b
end
set_name (n: like name)
-- Set `name' to `n'.
require
not n.is_whitespace
do
name := n
end
set_title (a_title: like title)
-- Set `title' to `a_title'.
do
title := a_title
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
-- Why in this particular case theme is not used to generate the content?
if attached format as f then
Result := f.formatted_output (content)
else
Result := content
end
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,35 +0,0 @@
note
description: "Summary description for {CMS_ENCODERS}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_ENCODERS
feature -- Encoders
url_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8
local
enc: URL_ENCODER
do
create enc
if s /= Void then
Result := enc.general_encoded_string (s)
else
create Result.make_empty
end
end
html_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8
local
enc: HTML_ENCODER
do
create enc
if s /= Void then
Result := enc.general_encoded_string (s)
else
create Result.make_empty
end
end
end

View File

@@ -1,62 +0,0 @@
note
description: "Summary description for {CMS_MENU_BLOCK}."
date: "$Date: 2014-11-14 20:11:17 +0100 (ven., 14 nov. 2014) $"
class
CMS_MENU_BLOCK
inherit
CMS_BLOCK
create
make
feature {NONE} -- Initialization
make (a_menu: like menu)
do
is_enabled := True
menu := a_menu
name := a_menu.name
title := a_menu.title
end
feature -- Access
menu: CMS_MENU
name: READABLE_STRING_8
title: detachable READABLE_STRING_32
feature -- Status report
is_horizontal: BOOLEAN
is_raw: BOOLEAN = False
-- <Precursor>
feature -- Element change
set_name (n: like name)
-- Set `name' to `n'.
require
not n.is_whitespace
do
name := n
end
set_title (a_title: like title)
-- Set `title' to `a_title'.
do
title := a_title
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := a_theme.menu_html (menu, is_horizontal)
end
end

View File

@@ -1,195 +0,0 @@
note
description: "[
CMS block with smarty template file content.
]"
date: "$Date: 2014-12-05 22:39:27 +0100 (ven., 05 déc. 2014) $"
revision: "$Revision: 96260 $"
class
CMS_SMARTY_TEMPLATE_BLOCK
inherit
CMS_BLOCK
redefine
out
select
out
end
SHARED_TEMPLATE_CONTEXT
rename
out as tpl_out
end
create
make,
make_raw
feature {NONE} -- Initialization
make (a_name: like name; a_title: like title; a_template_root_path: PATH; a_template_location: PATH)
-- Create Current with `a_name', `a_title', `a_template_location'
-- inside root directory `a_template_root_path' for the templates.
require
a_name_not_blank: not a_name.is_whitespace
do
is_enabled := True
name := a_name
title := a_title
location := a_template_location
template_root_path := a_template_root_path
create values.make (0)
end
make_raw (a_name: like name; a_title: like title; a_template_root_path: PATH; a_template_location: PATH)
-- Create Current with `a_name', `a_title', `a_template_location'
-- inside root directory `a_template_root_path' for the templates.
require
a_name_not_blank: not a_name.is_whitespace
do
make (a_name, a_title, a_template_root_path, a_template_location)
set_is_raw (True)
end
feature -- Access
name: READABLE_STRING_8
-- <Precursor>
title: detachable READABLE_STRING_32
-- <Precursor>
location: PATH
-- Location of template file.
template_root_path: PATH
-- Root location for templates universe.
values: STRING_TABLE [detachable ANY]
-- Additional value used during template output processing.
feature -- Status report
is_raw: BOOLEAN
-- Is raw?
-- If True, do not get wrapped it with block specific div
feature -- Element change
set_is_raw (b: BOOLEAN)
do
is_raw := b
end
set_name (n: like name)
-- Set `name' to `n'.
require
not n.is_whitespace
do
name := n
end
set_title (a_title: like title)
-- Set `title' to `a_title'.
do
title := a_title
end
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
to_html (a_theme: CMS_THEME): STRING_8
-- <Precursor>
local
p: detachable PATH
tpl: detachable TEMPLATE_FILE
ut: FILE_UTILITIES
n: STRING_32
l_table_inspector: detachable STRING_TABLE_OF_STRING_INSPECTOR
do
-- Process html generation
p := location
if ut.file_path_exists (template_root_path.extended_path (p)) then
n := p.name
template_context.set_template_folder (template_root_path)
template_context.disable_verbose
debug ("cms")
template_context.enable_verbose
end
create tpl.make_from_file (n)
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.analyze
tpl.get_output
l_table_inspector.unregister
-- l_table32_inspector.unregister
if attached tpl.output as l_output then
Result := l_output
else
Result := ""
debug ("cms")
Result := "Template block #" + name
end
end
else
Result := ""
debug ("cms")
Result := "Template block #" + name
end
end
end
feature -- Debug
out: STRING
do
create Result.make_from_string (generator)
Result.append ("%Nname:")
Result.append (name)
if attached title as l_title then
Result.append ("%N%Ttitle:")
Result.append (l_title)
end
Result.append ("%Nlocation:")
Result.append (location.out)
Result.append ("%Ntemplate_root_path:")
Result.append (template_root_path.out)
Result.append ("%NValues: {")
from
values.start
until
values.after
loop
Result.append ("%NKey:")
Result.append (values.key_for_iteration.as_string_8)
Result.append (" - Value:")
if attached values.item_for_iteration as l_item then
Result.append (l_item.out)
end
values.forth
end
Result.append ("%N}")
end
end

View File

@@ -1,92 +0,0 @@
note
description: "[
Object containing a collection of values.
It is typically used by `{CMS_RESPONSE}.values' .
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_VALUE_TABLE
inherit
TABLE_ITERABLE [detachable ANY, READABLE_STRING_GENERAL]
create
make
feature {NONE} -- Initialization
make (nb: INTEGER)
do
create table.make (nb)
end
feature -- Access
count: INTEGER
-- Number of items.
do
Result := table.count
end
item (key: READABLE_STRING_GENERAL): detachable ANY
-- Item associated with `key', if present
-- otherwise default value of type `G'.
note
option: stable
do
Result := table.item (key)
end
has (key: READABLE_STRING_GENERAL): BOOLEAN
-- Has item associated with key `key'?
do
Result := table.has (key)
end
new_cursor: TABLE_ITERATION_CURSOR [detachable ANY, READABLE_STRING_GENERAL]
-- <Precursor>
do
Result := table.new_cursor
end
feature -- Element change
put (new: detachable ANY; key: READABLE_STRING_GENERAL)
-- Insert `new' with `key' if there is no other item
-- associated with the same key.
do
table.put (new, key)
end
force (new: detachable ANY; key: READABLE_STRING_GENERAL)
-- Update table so that `new' will be the item associated
-- with `key'.
do
table.force (new, key)
end
remove (key: READABLE_STRING_GENERAL)
do
table.remove (key)
end
feature {NONE} -- Duplication
table: STRING_TABLE [detachable ANY]
invariant
table_set: table /= Void
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,64 +0,0 @@
note
description: "Summary description for {CMS_FORMATS}."
author: ""
date: "$Date: 2014-10-16 04:45:23 -0300 (ju. 16 de oct. de 2014) $"
revision: "$Revision: 95932 $"
class
CMS_FORMATS
feature -- Access
format (a_name: like {CONTENT_FORMAT}.name): detachable CONTENT_FORMAT
do
across
all_formats as c
until
Result /= Void
loop
if c.item.name.same_string (a_name) then
Result := c.item
end
end
end
all_formats: LIST [CONTENT_FORMAT]
once
create {ARRAYED_LIST [CONTENT_FORMAT]} Result.make (3)
Result.force (plain_text)
Result.force (full_html)
Result.force (filtered_html)
end
default_format: CONTENT_FORMAT
do
Result := plain_text --FIXME
end
plain_text: PLAIN_TEXT_CONTENT_FORMAT
once
create Result
end
full_html: FULL_HTML_CONTENT_FORMAT
once
create Result
end
filtered_html: FILTERED_HTML_CONTENT_FORMAT
once
create Result
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,42 +0,0 @@
note
description: "Summary description for {CMS_FORM}."
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
class
CMS_FORM
inherit
WSF_FORM
rename
process as process_form
end
create
make
feature -- Basic operation
prepare (a_response: CMS_RESPONSE)
do
a_response.invoke_form_alter (Current, Void)
end
process (a_response: CMS_RESPONSE)
do
process_form (a_response.request, agent on_prepared (a_response, ?), agent on_processed (a_response, ?))
end
on_prepared (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
do
a_response.invoke_form_alter (Current, fd)
end
on_processed (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
do
if not fd.is_valid or fd.has_error then
a_response.report_form_errors (fd)
end
end
end

View File

@@ -1,104 +0,0 @@
note
description: "[
Menu associated with CMS system.
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_MENU_SYSTEM
inherit
ITERABLE [CMS_MENU]
REFACTORING_HELPER
create
make
feature {NONE} -- Initialization
make
-- Create a predefined manu system
do
to_implement ("Refactor, take the info from a Database or Configuration file.")
create items.make (5)
force (create {CMS_MENU}.make ("primary", 3))
force (create {CMS_MENU}.make_with_title ("management", "Management", 3))
force (create {CMS_MENU}.make_with_title ("secondary", "Navigation", 3))
force (create {CMS_MENU}.make_with_title ("user", "User", 3))
end
feature -- Access
item (n: like {CMS_MENU}.name): CMS_MENU
-- Menu associated with name `n',
-- if none, it is created.
local
m: detachable CMS_MENU
do
m := items.item (n)
if m = Void then
create m.make (n, 3)
force (m)
end
Result := m
end
main_menu: CMS_MENU
obsolete
"Use `primary_menu' [Nov/2014]"
do
Result := primary_menu
end
primary_menu: CMS_MENU
do
Result := item ("primary")
end
secondary_menu: CMS_MENU
do
Result := item ("secondary")
end
management_menu: CMS_MENU
do
Result := item ("management")
end
navigation_menu: CMS_MENU
do
Result := item ("navigation")
end
user_menu: CMS_MENU
do
Result := item ("user")
end
primary_tabs: CMS_MENU
do
Result := item ("primary-tabs")
end
feature -- Change
force (m: CMS_MENU)
-- Add menu `m'.
do
items.force (m, m.name)
end
feature -- Access
new_cursor: ITERATION_CURSOR [CMS_MENU]
-- Fresh cursor associated with current structure.
do
Result := items.new_cursor
end
feature {NONE} -- Implementation
items: STRING_TABLE [CMS_MENU]
end

View File

@@ -1,73 +0,0 @@
note
description: "This module allows the use of HTTP Basic Authentication to restrict access by looking up users in the given providers."
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_MODULE
inherit
CMS_MODULE
redefine
filters
end
create
make
feature {NONE} -- Initialization
make
do
name := "basic auth"
version := "1.0"
description := "Service to manage basic authentication"
package := "core"
end
feature -- Access: router
router (a_api: CMS_API): WSF_ROUTER
-- Node router.
do
create Result.make (2)
configure_api_login (a_api, Result)
configure_api_logoff (a_api, Result)
end
feature -- Access: filter
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
-- Possibly list of Filter's module.
do
create {ARRAYED_LIST [WSF_FILTER]} Result.make (2)
Result.extend (create {CORS_FILTER})
Result.extend (create {BASIC_AUTH_FILTER}.make (a_api))
end
feature {NONE} -- Implementation: routes
configure_api_login (api: CMS_API; a_router: WSF_ROUTER)
local
l_bal_handler: BASIC_AUTH_LOGIN_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_bal_handler.make (api)
create l_methods
l_methods.enable_get
a_router.handle_with_request_methods ("/basic_auth_login", l_bal_handler, l_methods)
end
configure_api_logoff (api: CMS_API; a_router: WSF_ROUTER)
local
l_bal_handler: BASIC_AUTH_LOGOFF_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_bal_handler.make (api)
create l_methods
l_methods.enable_get
a_router.handle_with_request_methods ("/basic_auth_logoff", l_bal_handler, l_methods)
end
end

View File

@@ -1,57 +0,0 @@
note
description: "Processes a HTTP request's BASIC authorization headers, putting the result into the execution variable user."
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
CMS_HANDLER
WSF_FILTER
create
make
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
local
l_auth: HTTP_AUTHORIZATION
do
log.write_debug (generator + ".execute " )
create l_auth.make (req.http_authorization)
if attached req.raw_header_data as l_raw_data then
log.write_debug (generator + ".execute " + l_raw_data )
end
-- A valid user
if (attached l_auth.type as l_auth_type and then l_auth_type.is_case_insensitive_equal_general ("basic")) and then
attached l_auth.login as l_auth_login and then attached l_auth.password as l_auth_password then
if api.is_valid_credential (l_auth_login, l_auth_password) then
if attached api.user_by_name (l_auth_login) as l_user then
debug ("refactor_fixme")
fixme ("Maybe we need to store in the credentials in a shared context SECURITY_CONTEXT")
-- req.set_execution_variable ("security_content", create SECURITY_CONTEXT.make (l_user))
-- other authentication filters (OpenID, etc) should implement the same approach.
end
req.set_execution_variable ("user", l_user)
execute_next (req, res)
else
debug ("refactor_fixme")
to_implement ("Internal server error")
end
end
else
log.write_error (generator + ".execute login_valid failed for: " + l_auth_login )
execute_next (req, res)
end
else
log.write_error (generator + ".execute Not valid")
execute_next (req, res)
end
end
end

View File

@@ -1,28 +0,0 @@
note
description: "CORS filter"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
CORS_FILTER
inherit
WSF_FILTER
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
local
l_header: HTTP_HEADER
do
create l_header.make
-- l_header.add_header_key_value ("Access-Control-Allow-Origin", "localhost")
l_header.add_header_key_value ("Access-Control-Allow-Headers", "*")
l_header.add_header_key_value ("Access-Control-Allow-Methods", "*")
l_header.add_header_key_value ("Access-Control-Allow-Credentials", "true")
res.put_header_lines (l_header)
execute_next (req, res)
end
end

View File

@@ -1,60 +0,0 @@
note
description: "Summary description for {BASIC_AUTH_LOGIN_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_LOGIN_HANDLER
inherit
CMS_HANDLER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_FILTER
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
log.write_information(generator + ".do_get Processing basic auth login")
if attached {STRING_32} current_user_name (req) as l_user then
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url("/"))
else
(create {CMS_GENERIC_RESPONSE}).new_response_authenticate (req, res)
end
end
end

View File

@@ -1,59 +0,0 @@
note
description: "Summary description for {BASIC_AUTH_LOGOFF_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_LOGOFF_HANDLER
inherit
CMS_HANDLER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
log.write_information(generator + ".do_get Processing basic auth logoff")
if attached req.query_parameter ("prompt") as l_prompt then
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
else
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
l_page.execute
end
end
end

View File

@@ -1,140 +0,0 @@
note
description: "Summary description for {CMS_DEBUG_MODULE}."
date: "$Date: 2014-12-18 16:47:20 +0100 (jeu., 18 déc. 2014) $"
revision: "$Revision: 96384 $"
class
CMS_DEBUG_MODULE
inherit
CMS_MODULE
redefine
register_hooks
end
-- CMS_HOOK_BLOCK
CMS_HOOK_AUTO_REGISTER
SHARED_EXECUTION_ENVIRONMENT
export
{NONE} all
end
create
make
feature {NONE} -- Initialization
make
do
name := "debug"
version := "1.0"
description := "Debug"
package := "cms"
end
feature -- Router
router (a_api: CMS_API): WSF_ROUTER
-- Router configuration.
do
create Result.make (1)
Result.handle ("/debug/", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_debug (a_api, ?, ?)))
end
feature -- Hooks configuration
register_hooks (a_response: CMS_RESPONSE)
-- Module hooks configuration.
do
auto_subscribe_to_hooks (a_response)
-- a_response.subscribe_to_block_hook (Current)
end
feature -- Hooks
-- block_list: ITERABLE [like {CMS_BLOCK}.name]
-- do
-- Result := <<"debug-info">>
-- end
-- get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
-- local
-- b: CMS_CONTENT_BLOCK
-- do
-- create b.make ("debug-info", "Debug", "... ", a_response.formats.plain_text)
-- a_response.add_block (b, Void)
-- end
feature -- Handler
handle_debug (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
local
r: CMS_RESPONSE
s: STRING
do
if req.is_get_request_method then
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
r.set_title ("DEBUG")
create s.make_empty
append_info_to ("Name", api.setup.site_name, r, s)
append_info_to ("Url", api.setup.site_url, r, s)
if attached api.setup.layout.cms_config_ini_path as l_loc then
s.append ("<hr/>")
append_info_to ("Configuration file", l_loc.name, r, s)
end
s.append ("<hr/>")
append_info_to ("Current dir", execution_environment.current_working_path.utf_8_name, r, s)
-- append_info_to ("Base url", cms.base_url, r, s)
-- append_info_to ("Script url", cms.script_url, r, s)
s.append ("<hr/>")
append_info_to ("Site dir", api.setup.layout.path.utf_8_name, r, s)
append_info_to ("Www dir", api.setup.layout.www_path.utf_8_name, r, s)
append_info_to ("Assets dir", api.setup.layout.assets_path.utf_8_name, r, s)
append_info_to ("Config dir", api.setup.layout.config_path.utf_8_name, r, s)
s.append ("<hr/>")
append_info_to ("Theme", api.setup.theme_name, r, s)
append_info_to ("Theme location", api.setup.themes_location.utf_8_name, r, s)
s.append ("<hr/>")
-- append_info_to ("Files location", api...files_location.utf_8_name, r, s)
-- s.append ("<hr/>")
append_info_to ("Url", r.url ("/", Void), r, s)
-- if attached r.user as u then
-- append_info_to ("User", u.name, r, s)
-- append_info_to ("User url", r.user_url (u), r, s)
-- end
r.set_main_content (s)
else
create {NOT_FOUND_ERROR_CMS_RESPONSE} r.make (req, res, api)
end
r.execute
end
append_info_to (n: READABLE_STRING_8; v: detachable READABLE_STRING_GENERAL; r: CMS_RESPONSE; t: STRING)
do
t.append ("<li>")
t.append ("<strong>" + n + "</strong>: ")
if v /= Void then
t.append (r.html_encoded (v))
end
t.append ("</li>")
end
note
copyright: "Copyright (c) 1984-2013, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,85 +0,0 @@
note
description: "Describe module features that adds one or more features to your web site."
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_MODULE
inherit
REFACTORING_HELPER
feature -- Access
is_enabled: BOOLEAN
-- Is the module enabled?
name: STRING
-- Name of the module.
description: STRING
-- Description of the module.
package: STRING
--
version: STRING
-- Version od the module?
feature -- Router
router (a_api: CMS_API): WSF_ROUTER
-- Router configuration.
require
is_enabled: is_enabled
deferred
end
feature -- Hooks configuration
register_hooks (a_response: CMS_RESPONSE)
-- 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
-- enable the module.
do
is_enabled := True
ensure
module_enabled: is_enabled
end
disable
-- disable the module.
do
is_enabled := False
ensure
module_disbaled: not is_enabled
end
feature -- Hooks
help_text (a_path: STRING): STRING
do
debug ("refactor_fixme")
to_implement ("Add the corresponing implementation.")
end
create Result.make_empty
end
end

View File

@@ -1,64 +0,0 @@
note
description: "Summary description for {CMS_MODULE_COLLECTION}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_MODULE_COLLECTION
inherit
ITERABLE [CMS_MODULE]
create
make
feature {NONE} -- Initialization
make (nb: INTEGER)
do
create modules.make (nb)
end
feature -- Access
new_cursor: INDEXABLE_ITERATION_CURSOR [CMS_MODULE]
-- <Precursor>
do
Result := modules.new_cursor
end
feature -- Status report
has (a_module: CMS_MODULE): BOOLEAN
-- Has `a_module'?
do
Result := modules.has (a_module)
end
count: INTEGER
-- Number of modules.
do
Result := modules.count
end
feature -- Element change
extend (a_module: CMS_MODULE)
-- Add module
do
modules.force (a_module)
end
remove (a_module: CMS_MODULE)
-- Remove module
do
modules.prune_all (a_module)
end
feature {NONE} -- Implementation
modules: ARRAYED_LIST [CMS_MODULE]
-- List of available modules.
end

View File

@@ -1,171 +0,0 @@
note
description: "Summary description for {NEW_CONTENT_HANDLER}."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
NODE_CONTENT_HANDLER
inherit
CMS_HANDLER
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
if attached current_user_name (req) then
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (l_node.content, "node_content")
l_page.add_variable (l_id.value, "id")
l_page.execute
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user_name (req) then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
end
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
do
to_implement ("Check if user has permissions")
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
u_node := extract_data_form (req)
u_node.set_id (l_id.value.to_integer_64)
api.update_node_content (l_user.id, u_node.id, u_node.content)
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found
l_page.add_variable ("404", "code")
l_page.set_status_code (404)
else
-- bad request
l_page.add_variable ("400", "code")
l_page.set_status_code (400)
end
l_page.execute
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_NODE
-- Extract request form data and build a object
-- Node
do
create Result.make ("", "", "")
if attached {WSF_STRING}req.form_parameter ("content") as l_content then
Result.set_content (l_content.value)
end
end
end

View File

@@ -1,226 +0,0 @@
note
description: "Summary description for {NODE_HANDLER}."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
NODE_HANDLER
inherit
CMS_HANDLER
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put,
do_delete
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached api.node (l_id.value.to_integer_64) as l_node
then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (l_node, "node")
l_page.execute
else
do_error (req, res, l_id)
end
else
-- Factory
new_node (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
do
to_implement ("Check user permissions!!!")
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached {CMS_NODE} api.node (l_id.value.to_integer_64) as l_node
then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("DELETE") then
do_delete (req, res)
elseif l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
end
else
do_error (req, res, l_id)
end
else
-- New node
create u_node.make ("", "", "")
update_node_from_data_form (req, u_node)
u_node.set_author (l_user)
api.new_node (u_node)
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached api.node (l_id.value.to_integer_64) as l_node
then
update_node_from_data_form (req, l_node)
l_node.set_author (l_user)
api.update_node (l_node)
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user_name (req) then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then
attached api.node (l_id.integer_value) as l_node
then
api.delete_node (l_node)
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found
l_page.add_variable ("404", "code")
l_page.set_status_code (404)
else
-- bad request
l_page.add_variable ("400", "code")
l_page.set_status_code (400)
end
l_page.execute
end
feature {NONE} -- Node
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: CMS_RESPONSE
do
if attached current_user_name (req) then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (setup.is_html, "html")
l_page.add_variable (setup.is_web, "web")
l_page.execute
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
feature -- {NONE} Form data
update_node_from_data_form (req: WSF_REQUEST; a_node: CMS_NODE)
-- Extract request form data and build a object
-- Node
do
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
a_node.set_title (l_title.value)
end
if attached {WSF_STRING} req.form_parameter ("summary") as l_summary then
a_node.set_summary (l_summary.value)
end
if attached {WSF_STRING} req.form_parameter ("content") as l_content then
a_node.set_content (l_content.value)
end
end
end

View File

@@ -1,171 +0,0 @@
note
description: "Summary description for {NODE_SUMMARY_HANDLER}."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
NODE_SUMMARY_HANDLER
inherit
CMS_HANDLER
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
if attached current_user_name (req) then
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (l_id.value, "id")
l_page.add_variable (l_node.summary, "node_summary")
l_page.execute
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user_name (req) then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
end
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
do
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
u_node := extract_data_form (req)
u_node.set_id (l_id.value.to_integer_64)
api.update_node_summary (l_user.id,u_node.id, u_node.summary)
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found
l_page.add_variable ("404", "code")
l_page.set_status_code (404)
else
-- bad request
l_page.add_variable ("400", "code")
l_page.set_status_code (400)
end
l_page.execute
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_NODE
-- Extract request form data and build a object
-- Node
do
create Result.make ("", "", "")
if attached {WSF_STRING}req.form_parameter ("summary") as l_summary then
Result.set_summary (l_summary.value)
end
end
end

View File

@@ -1,169 +0,0 @@
note
description: "Summary description for {NODE_TITLE_HANDLER}."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
NODE_TITLE_HANDLER
inherit
CMS_HANDLER
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post,
do_put
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
if attached current_user_name (req) as l_user then
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (l_node.title, "node_title")
l_page.add_variable (l_id.value, "id")
l_page.execute
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user_name (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
end
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
u_node: CMS_NODE
do
to_implement ("Check if user has permissions")
if attached current_user (req) as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then
u_node := extract_data_form (req)
u_node.set_id (l_id.value.to_integer_64)
api.update_node_title (l_user.id,u_node.id, u_node.title)
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
else
do_error (req, res, l_id)
end
else
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
end
end
feature -- Error
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
-- Handling error.
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found
l_page.add_variable ("404", "code")
l_page.set_status_code (404)
else
-- bad request
l_page.add_variable ("400", "code")
l_page.set_status_code (400)
end
l_page.execute
end
feature -- {NONE} Form data
extract_data_form (req: WSF_REQUEST): CMS_NODE
-- Extract request form data and build a object
-- Node
do
create Result.make ("", "", "")
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
Result.set_title (l_title.value)
end
end
end

View File

@@ -1,59 +0,0 @@
note
description: "Summary description for {NODES_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
NODES_HANDLER
inherit
CMS_HANDLER
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
-- At the moment the template is hardcoded, but we can
-- get them from the configuration file and load them into
-- the setup class.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.add_variable (api.nodes, "nodes")
l_page.execute
end
end

View File

@@ -1,200 +0,0 @@
note
description: "CMS module that bring support for NODE management."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
NODE_MODULE
inherit
CMS_MODULE
redefine
register_hooks
end
CMS_HOOK_MENU_SYSTEM_ALTER
CMS_HOOK_BLOCK
create
make
feature {NONE} -- Initialization
make (a_setup: CMS_SETUP)
-- Create Current module, disabled by default.
do
name := "node"
version := "1.0"
description := "Service to manage content based on 'node'"
package := "core"
config := a_setup
end
config: CMS_SETUP
-- Node configuration.
feature -- Access: router
router (a_api: CMS_API): WSF_ROUTER
-- Node router.
do
create Result.make (5)
configure_api_node (a_api, Result)
configure_api_nodes (a_api, Result)
configure_api_node_title (a_api, Result)
configure_api_node_summary (a_api, Result)
configure_api_node_content (a_api, Result)
end
feature {NONE} -- Implementation: routes
configure_api_node (api: CMS_API; a_router: WSF_ROUTER)
local
l_node_handler: NODE_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_node_handler.make (api)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
a_router.handle_with_request_methods ("/node", l_node_handler, l_methods)
create l_node_handler.make (api)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
l_methods.enable_delete
a_router.handle_with_request_methods ("/node/{id}", l_node_handler, l_methods)
a_router.handle_with_request_methods ("/nodes/", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_nodes (?,?, api)), a_router.methods_get)
end
configure_api_nodes (api: CMS_API; a_router: WSF_ROUTER)
local
l_nodes_handler: NODES_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_nodes_handler.make (api)
create l_methods
l_methods.enable_get
a_router.handle_with_request_methods ("/nodes", l_nodes_handler, l_methods)
end
configure_api_node_summary (api: CMS_API; a_router: WSF_ROUTER)
local
l_report_handler: NODE_SUMMARY_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (api)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
a_router.handle_with_request_methods ("/node/{id}/summary", l_report_handler, l_methods)
end
configure_api_node_title (api: CMS_API; a_router: WSF_ROUTER)
local
l_report_handler: NODE_TITLE_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (api)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
a_router.handle_with_request_methods ("/node/{id}/title", l_report_handler, l_methods)
end
configure_api_node_content (api: CMS_API; a_router: WSF_ROUTER)
local
l_report_handler: NODE_CONTENT_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_report_handler.make (api)
create l_methods
l_methods.enable_get
l_methods.enable_post
l_methods.enable_put
a_router.handle_with_request_methods ("/node/{id}/content", l_report_handler, l_methods)
end
feature -- Hooks
register_hooks (a_response: CMS_RESPONSE)
do
a_response.subscribe_to_menu_system_alter_hook (Current)
a_response.subscribe_to_block_hook (Current)
end
block_list: ITERABLE [like {CMS_BLOCK}.name]
do
Result := <<"node-info">>
end
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
local
-- b: CMS_CONTENT_BLOCK
do
-- create b.make (a_block_id, "Block::node", "This is a block test", Void)
-- a_response.add_block (b, "sidebar_second")
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
-- perms: detachable ARRAYED_LIST [READABLE_STRING_8]
do
create lnk.make ("List of nodes", a_response.url ("/nodes", Void))
a_menu_system.primary_menu.extend (lnk)
end
feature -- Handler
do_get_nodes (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
local
r: CMS_RESPONSE
s: STRING
l_user: CMS_USER
l_node: CMS_NODE
do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_api)
if attached a_api.user_by_name ("foo") as u then
l_user := u
else
create l_user.make ("foo")
l_user.set_password ("foobar#")
l_user.set_email ("test@example.com")
a_api.new_user (l_user)
end
if a_api.nodes_count = 0 then
create l_node.make ({STRING_32} "This is a content", {STRING_32} "And a summary", {STRING_32} "Nice title")
l_node.set_author (l_user)
a_api.new_node (l_node)
end
create s.make_from_string ("<p>Nodes:</p>")
if attached a_api.nodes as lst then
across
lst as ic
loop
s.append ("<li>")
s.append (a_api.html_encoded (ic.item.title))
s.append (" (")
s.append (ic.item.id.out)
s.append (")")
s.append ("</li>%N")
end
end
r.set_main_content (s)
r.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet fully implemented<br/>", Void), "highlighted")
r.execute
end
end

View File

@@ -1,47 +0,0 @@
note
description : "[
CMS interface to storage
]"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_STORAGE
inherit
CMS_USER_STORAGE
CMS_NODE_STORAGE
SHARED_LOGGER
feature {NONE} -- Initialization
initialize
do
end
feature -- Error Handling
error_handler: ERROR_HANDLER
-- Error handler.
feature -- Misc
-- set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: READABLE_STRING_8)
-- -- Save data `a_name:a_value' for type `a_type'
-- deferred
-- end
-- custom_value (a_name: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable TABLE_ITERABLE [READABLE_STRING_8, STRING_8]
-- -- Data for name `a_name' and type `a_type'.
-- deferred
-- end
-- custom_value_names_where (a_where_key, a_where_value: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable LIST [READABLE_STRING_8]
-- -- Names where custom value has item `a_where_key' same as `a_where_value' for type `a_type'.
-- deferred
-- end
end

View File

@@ -1,18 +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_BUILDER
feature -- Factory
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE
deferred
end
end

View File

@@ -1,168 +0,0 @@
note
description: "Summary description for {CMS_STORAGE_NULL}."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
CMS_STORAGE_NULL
inherit
CMS_STORAGE
redefine
default_create
select
default_create
end
REFACTORING_HELPER
rename
default_create as default_create_rh
end
feature -- Initialization
default_create
do
create error_handler.make
end
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 -- User Nodes
user_collaborator_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
-- Possible list of nodes where the user identified by `a_id', is a collaborator.
do
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
end
user_author_nodes (a_id: like {CMS_USER}.id): LIST[CMS_NODE]
-- Possible list of nodes where the user identified by `a_id', is the author.
do
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
end
feature -- Change: user
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
do
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: 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 -- Access: node
nodes_count: INTEGER_64
-- Count of nodes.
do
end
nodes: LIST[CMS_NODE]
-- List of nodes.
do
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of the `a_count' most recent nodes, starting from `a_lower'.
do
create {ARRAYED_LIST[CMS_NODE]} Result.make (0)
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- <Precursor>
do
end
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
-- Node's author. if any.
do
end
node_collaborators (a_id: like {CMS_NODE}.id): LIST [CMS_USER]
-- Possible list of node's collaborator.
do
create {ARRAYED_LIST[CMS_USER]} Result.make (0)
end
feature -- Node
new_node (a_node: CMS_NODE)
-- Add a new node
do
end
delete_node_by_id (a_id: INTEGER_64)
-- <Precursor>
do
end
update_node (a_node: CMS_NODE)
-- <Precursor>
do
end
update_node_title (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
-- <Precursor>
do
end
update_node_summary (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
-- <Precursor>
do
end
update_node_content (a_user_id: like {CMS_NODE}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
-- <Precursor>
do
end
end

View File

@@ -1,22 +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 $"
class
CMS_STORAGE_NULL_BUILDER
inherit
CMS_STORAGE_BUILDER
feature -- Factory
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_NULL
do
create Result
end
end

View File

@@ -1,214 +0,0 @@
note
description: "Summary description for {CMS_STORAGE_SQL}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_STORAGE_SQL
feature -- Error handler
error_handler: ERROR_HANDLER
deferred
end
feature -- Execution
sql_begin_transaction
deferred
end
sql_rollback_transaction
deferred
end
sql_commit_transaction
deferred
end
sql_post_execution
-- Post database execution.
deferred
end
feature -- Operation
check_sql_query_validity (a_sql_statement: READABLE_STRING_8; a_params: detachable STRING_TABLE [detachable ANY])
local
l_sql_params: STRING_TABLE [READABLE_STRING_8]
i,j,n: INTEGER
s: STRING
do
create l_sql_params.make_caseless (0)
from
i := 1
n := a_sql_statement.count
until
i > n
loop
i := a_sql_statement.index_of (':', i)
if i = 0 then
i := n -- exit
else
from
j := i + 1
until
j > n or not (a_sql_statement[j].is_alpha_numeric or a_sql_statement[j] = '_')
loop
j := j + 1
end
s := a_sql_statement.substring (i + 1, j - 1)
l_sql_params.force (s, s)
end
i := i + 1
end
if a_params = Void then
if not l_sql_params.is_empty then
check False end
error_handler.add_custom_error (-1, "invalid query", "missing value for sql parameters")
end
else
across
a_params as ic
loop
if l_sql_params.has (ic.key) then
l_sql_params.remove (ic.key)
else
error_handler.add_custom_error (-1, "useless value", "value for unexpected parameter [" + ic.key + "]")
end
end
across
l_sql_params as ic
loop
error_handler.add_custom_error (-1, "invalid query", "missing value for sql parameter [" + ic.item + "]")
end
end
end
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
deferred
end
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
deferred
end
feature -- Access
sql_rows_count: INTEGER
-- Number of rows for last sql execution.
deferred
end
sql_start
-- Set the cursor on first element.
deferred
end
sql_after: BOOLEAN
-- Are there no more items to iterate over?
deferred
end
sql_forth
-- Fetch next row from last sql execution, if any.
deferred
end
sql_item (a_index: INTEGER): detachable ANY
deferred
end
sql_read_integer_64 (a_index: INTEGER): INTEGER_64
-- Retrieved value at `a_index' position in `item'.
local
l_item: like sql_item
do
l_item := sql_item (a_index)
if attached {INTEGER_64} l_item as i then
Result := i
elseif attached {INTEGER_64_REF} l_item as l_value then
Result := l_value.item
else
Result := sql_read_integer_32 (a_index).to_integer_64
end
end
sql_read_integer_32 (a_index: INTEGER): INTEGER_32
-- Retrieved value at `a_index' position in `item'.
local
l_item: like sql_item
do
l_item := sql_item (a_index)
if attached {INTEGER_32} l_item as i then
Result := i
elseif attached {INTEGER_32_REF} l_item as l_value then
Result := l_value.item
else
-- check is_integer_32: False end
end
end
sql_read_string (a_index: INTEGER): detachable STRING
-- Retrieved value at `a_index' position in `item'.
local
l_item: like sql_item
do
l_item := sql_item (a_index)
if attached {READABLE_STRING_8} l_item as l_string then
Result := l_string
elseif attached {BOOLEAN} l_item as l_boolean then
Result := l_boolean.out
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then
Result := l_boolean_ref.item.out
else
-- check is_string: False end
end
end
sql_read_string_32 (a_index: INTEGER): detachable STRING_32
-- Retrieved value at `a_index' position in `item'.
local
l_item: like sql_item
do
-- FIXME: handle string_32 !
l_item := sql_item (a_index)
if attached {READABLE_STRING_32} l_item as l_string then
Result := l_string
else
if attached sql_read_string (a_index) as s8 then
Result := s8.to_string_32 -- FIXME
end
end
end
sql_read_date_time (a_index: INTEGER): detachable DATE_TIME
-- Retrieved value at `a_index' position in `item'.
local
l_item: like sql_item
do
l_item := sql_item (a_index)
if attached {DATE_TIME} l_item as dt then
Result := dt
else
-- check is_date_time: False end
end
end
sql_read_boolean (a_index: INTEGER): detachable BOOLEAN
-- Retrieved value at `a_index' position in `item'.
local
l_item: like sql_item
do
l_item := sql_item (a_index)
if attached {BOOLEAN} l_item as l_boolean then
Result := l_boolean
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then
Result := l_boolean_ref.item
else
check is_boolean: False end
end
end
end

View File

@@ -1,122 +0,0 @@
note
description: "Summary description for {CMS_NODE_STORAGE}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_NODE_STORAGE
inherit
SHARED_LOGGER
feature -- Error Handling
error_handler: ERROR_HANDLER
-- Error handler.
deferred
end
feature -- Access
nodes_count: INTEGER_64
-- Count of nodes.
deferred
end
nodes: LIST [CMS_NODE]
-- List of nodes.
deferred
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of recent `a_count' nodes with an offset of `lower'.
deferred
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- Retrieve node by id `a_id', if any.
require
a_id > 0
deferred
end
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
-- Node's author. if any.
require
valid_node: a_id >0
deferred
end
feature -- Change: Node
save_node (a_node: CMS_NODE)
-- Create or update `a_node'.
do
if a_node.has_id then
update_node (a_node)
else
new_node (a_node)
end
end
new_node (a_node: CMS_NODE)
-- Save node `a_node'.
require
no_id: not a_node.has_id
valid_user: attached a_node.author as l_author and then l_author.id > 0
deferred
end
delete_node (a_node: CMS_NODE)
-- Delete `a_node'.
do
if a_node.has_id then
delete_node_by_id (a_node.id)
end
end
delete_node_by_id (a_id: INTEGER_64)
-- Remove node by id `a_id'.
require
valid_node_id: a_id > 0
deferred
end
update_node (a_node: CMS_NODE)
-- Update node content `a_node'.
-- The user `a_id' is an existing or new collaborator.
require
has_id: a_node.has_id
has_author: attached a_node.author as l_author and then l_author.has_id
deferred
end
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
-- Update node title to `a_title', node identified by id `a_node_id'.
-- The user `a_user_id' is an existing or new collaborator.
require
valid_node_id: a_node_id > 0
valid_user_id: a_user_id > 0
deferred
end
update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
-- Update node summary to `a_summary', node identified by id `a_node_id'.
-- The user `a_user_id' is an existing or new collaborator.
require
valid_id: a_node_id > 0
valid_user_id: a_user_id > 0
deferred
end
update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
-- Update node content to `a_content', node identified by id `a_node_id'.
-- The user `a_user_id' is an existing or new collaborator.
require
valid_id: a_node_id > 0
valid_user_id: a_user_id > 0
deferred
end
end

View File

@@ -1,339 +0,0 @@
note
description: "Summary description for {CMS_NODE_STORAGE_SQL}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_NODE_STORAGE_SQL
inherit
CMS_NODE_STORAGE
CMS_STORAGE_SQL
REFACTORING_HELPER
SHARED_LOGGER
feature -- Access
nodes_count: INTEGER_64
-- Number of items nodes.
do
error_handler.reset
log.write_information (generator + ".nodes_count")
sql_query (select_nodes_count, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
sql_post_execution
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
log.write_information (generator + ".nodes")
from
sql_query (select_nodes, Void)
sql_post_execution
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
sql_post_execution
end
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
-- List of recent `a_count' nodes with an offset of `lower'.
local
l_parameters: STRING_TABLE [detachable ANY]
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
log.write_information (generator + ".nodes")
from
create l_parameters.make (2)
l_parameters.put (a_count, "rows")
l_parameters.put (a_lower, "offset")
sql_query (select_recent_nodes, l_parameters)
sql_post_execution
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
sql_post_execution
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- Retrieve node by id `a_id', if any.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
log.write_information (generator + ".node")
create l_parameters.make (1)
l_parameters.put (a_id,"id")
sql_query (select_node_by_id, l_parameters)
if sql_rows_count = 1 then
Result := fetch_node
end
sql_post_execution
end
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
-- Node's author for the given node id.
local
l_parameters: STRING_TABLE [ANY]
do
error_handler.reset
log.write_information (generator + ".node_author")
create l_parameters.make (1)
l_parameters.put (a_id, "node_id")
sql_query (select_node_author, l_parameters)
if sql_rows_count >= 1 then
Result := fetch_author
end
sql_post_execution
end
last_inserted_node_id: INTEGER_64
-- Last insert node id.
do
error_handler.reset
log.write_information (generator + ".last_inserted_node_id")
sql_query (Sql_last_insert_node_id, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
sql_post_execution
end
feature -- Change: Node
new_node (a_node: CMS_NODE)
-- Save node `a_node'.
local
l_parameters: STRING_TABLE [detachable ANY]
do
-- New node
error_handler.reset
log.write_information (generator + ".new_node")
create l_parameters.make (7)
l_parameters.put (a_node.title, "title")
l_parameters.put (a_node.summary, "summary")
l_parameters.put (a_node.content, "content")
l_parameters.put (a_node.publication_date, "publish")
l_parameters.put (a_node.creation_date, "created")
l_parameters.put (a_node.modification_date, "changed")
if
attached a_node.author as l_author and then
l_author.id > 0
then
l_parameters.put (l_author.id, "author")
else
l_parameters.put (0, "author")
end
sql_change (sql_insert_node, l_parameters)
sql_post_execution
if not error_handler.has_error then
a_node.set_id (last_inserted_node_id)
sql_post_execution
end
end
delete_node_by_id (a_id: INTEGER_64)
-- Remove node by id `a_id'.
local
l_parameters: STRING_TABLE [ANY]
do
log.write_information (generator + ".delete_node")
error_handler.reset
create l_parameters.make (1)
l_parameters.put (a_id, "id")
sql_change (sql_delete_node, l_parameters)
sql_post_execution
end
update_node (a_node: CMS_NODE)
-- Update node content `a_node'.
local
l_parameters: STRING_TABLE [detachable ANY]
now: DATE_TIME
do
create now.make_now_utc
error_handler.reset
log.write_information (generator + ".update_node")
create l_parameters.make (7)
l_parameters.put (a_node.title, "title")
l_parameters.put (a_node.summary, "summary")
l_parameters.put (a_node.content, "content")
l_parameters.put (a_node.publication_date, "publish")
l_parameters.put (now, "changed")
l_parameters.put (a_node.id, "id")
if attached a_node.author as l_author then
l_parameters.put (l_author.id, "author")
else
l_parameters.put (0, "author")
end
sql_change (sql_update_node, l_parameters)
sql_post_execution
if not error_handler.has_error then
a_node.set_modification_date (now)
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
log.write_information (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)
sql_post_execution
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
log.write_information (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)
sql_post_execution
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
log.write_information (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)
sql_post_execution
end
feature {NONE} -- Queries
Select_nodes_count: STRING = "select count(*) from Nodes;"
Select_nodes: STRING = "select * from Nodes;"
-- SQL Query to retrieve all nodes.
Select_node_by_id: STRING = "select * from Nodes where nid =:nid order by nid desc, publish desc;"
Select_recent_nodes: STRING = "select * from Nodes order by nid desc, publish desc LIMIT :rows OFFSET :offset ;"
SQL_Insert_node: STRING = "insert into nodes (title, summary, content, publish, created, changed, author) values (:title, :summary, :content, :publish, :created, :changed, :author);"
-- SQL Insert to add a new node.
SQL_Update_node : STRING = "update nodes SET title=:title, summary=:summary, content=:content, publish=:publish, changed=:changed, version = version + 1, author=:author where nid=:nid;"
-- SQL node.
SQL_Delete_node: STRING = "delete from nodes where nid=:nid;"
Sql_update_node_author: STRING = "update nodes SET author=:author where nid=:nid;"
SQL_Update_node_title: STRING ="update nodes SET title=:title, changed=:changed, version = version + 1 where nid=:nid;"
-- SQL update node title.
SQL_Update_node_summary: STRING ="update nodes SET summary=:summary, changed=:changed, version = version + 1 where nid=:nid;"
-- SQL update node summary.
SQL_Update_node_content: STRING ="update nodes SET content=:content, changed=:changed, version = version + 1 where nid=:nid;"
-- SQL node content.
Sql_last_insert_node_id: STRING = "SELECT MAX(nid) from nodes;"
feature {NONE} -- Sql Queries: USER_ROLES collaborators, author
Select_user_author: STRING = "SELECT * FROM Nodes INNER JOIN users ON nodes.author=users.uid and users.uid = :uid;"
Select_node_author: STRING = "SELECT * FROM Users INNER JOIN nodes ON nodes.author=users.uid and nodes.nid =:nid;"
feature {NONE} -- Implementation
fetch_node: CMS_NODE
do
create Result.make ("", "", "")
if attached sql_read_integer_64 (1) as l_id then
Result.set_id (l_id)
end
if attached sql_read_string_32 (4) as l_title then
Result.set_title (l_title)
end
if attached sql_read_string_32 (5) as l_summary then
Result.set_summary (l_summary)
end
if attached sql_read_string (6) as l_content then
Result.set_content (l_content)
end
if attached sql_read_date_time (8) as l_publication_date then
Result.set_publication_date (l_publication_date)
end
if attached sql_read_date_time (9) as l_creation_date then
Result.set_creation_date (l_creation_date)
end
if attached sql_read_date_time (10) as l_modif_date then
Result.set_modification_date (l_modif_date)
end
if attached sql_read_integer_64 (7) as l_author_id then
-- access to API ...
end
end
fetch_author: detachable CMS_USER
do
if attached sql_read_string_32 (2) as l_name and then not l_name.is_whitespace then
create Result.make (l_name)
if attached sql_read_integer_32 (1) as l_id then
Result.set_id (l_id)
end
if attached sql_read_string (3) as l_password then
-- FIXME: should we return the password here ???
Result.set_hashed_password (l_password)
end
if attached sql_read_string (5) as l_email then
Result.set_email (l_email)
end
else
check expected_valid_user: False end
end
end
end

View File

@@ -1,139 +0,0 @@
note
description: "Summary description for {CMS_USER_STORAGE}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_USER_STORAGE
inherit
SHARED_LOGGER
feature -- Error Handling
error_handler: ERROR_HANDLER
-- Error handler.
deferred
end
feature -- Access
has_user: BOOLEAN
-- Has any user?
deferred
end
users: LIST [CMS_USER]
-- List of users.
deferred
end
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
-- User with id `a_id', if any.
require
a_id > 0
deferred
ensure
same_id: Result /= Void implies Result.id = a_id
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
-- User with name `a_name', if any.
require
a_name /= Void and then not a_name.is_empty
deferred
ensure
same_name: Result /= Void implies a_name ~ Result.name
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
-- User with name `a_email', if any.
deferred
ensure
same_email: Result /= Void implies a_email ~ Result.email
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
is_valid_credential (a_u, a_p: READABLE_STRING_32): BOOLEAN
-- Does account with username `a_username' and password `a_password' exist?
deferred
end
feature -- Change: user
save_user (a_user: CMS_USER)
-- Create or update `a_user'.
do
if a_user.has_id then
update_user (a_user)
else
new_user (a_user)
end
end
new_user (a_user: CMS_USER)
-- New user `a_user'.
require
no_id: not a_user.has_id
deferred
end
update_user (a_user: CMS_USER)
-- Save user `a_user'.
require
has_id: a_user.has_id
deferred
end
feature -- Access: roles and permissions
user_has_permission (u: detachable CMS_USER; s: detachable READABLE_STRING_8): BOOLEAN
-- Anonymous or user `u' has permission for `s' ?
--| `s' could be "create page",
do
-- if s = Void then
-- Result := True
-- elseif u = Void then
---- Result := user_role_has_permission (anonymous_user_role, s)
-- else
-- Result := user_role_has_permission (authenticated_user_role, s)
-- if not Result and attached u.roles as l_roles then
-- across
-- l_roles as r
-- until
-- Result
-- loop
-- if attached user_role_by_id (r.item) as ur then
-- Result := user_role_has_permission (ur, s)
-- end
-- end
-- end
-- end
end
user_role_has_permission (a_role: CMS_USER_ROLE; s: READABLE_STRING_8): BOOLEAN
do
Result := a_role.has_permission (s)
end
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
-- User role by id `a_id', if any.
deferred
end
user_roles: LIST [CMS_USER_ROLE]
-- Possible list of user roles.
deferred
end
feature -- Change: roles and permissions
save_user_role (a_user_role: CMS_USER_ROLE)
-- Save user role `a_user_role'
deferred
end
end

View File

@@ -1,331 +0,0 @@
note
description: "Summary description for {CMS_USER_STORAGE_SQL}."
author: ""
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_USER_STORAGE_SQL
inherit
CMS_USER_STORAGE
CMS_STORAGE_SQL
REFACTORING_HELPER
SHARED_LOGGER
feature -- Access: user
has_user: BOOLEAN
-- Has any user?
do
Result := user_count > 0
end
user_count: INTEGER
-- Number of items users.
do
error_handler.reset
log.write_information (generator + ".user_count")
sql_query (select_users_count, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_32 (1)
end
sql_post_execution
end
users: LIST [CMS_USER]
do
create {ARRAYED_LIST [CMS_USER]} Result.make (0)
error_handler.reset
log.write_information (generator + ".all_users")
from
sql_query (select_users, Void)
sql_post_execution
sql_start
until
sql_after
loop
if attached fetch_user as l_user then
Result.force (l_user)
end
sql_forth
end
sql_post_execution
end
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
-- User for the given id `a_id', if any.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
log.write_information (generator + ".user")
create l_parameters.make (1)
l_parameters.put (a_id, "uid")
sql_query (select_user_by_id, l_parameters)
if sql_rows_count = 1 then
Result := fetch_user
else
check no_more_than_one: sql_rows_count = 0 end
end
sql_post_execution
end
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
-- User for the given name `a_name', if any.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
log.write_information (generator + ".user_by_name")
create l_parameters.make (1)
l_parameters.put (a_name, "name")
sql_query (select_user_by_name, l_parameters)
if sql_rows_count = 1 then
Result := fetch_user
else
check no_more_than_one: sql_rows_count = 0 end
end
sql_post_execution
end
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
-- User for the given email `a_email', if any.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
log.write_information (generator + ".user_by_email")
create l_parameters.make (1)
l_parameters.put (a_email, "email")
sql_query (select_user_by_email, l_parameters)
if sql_rows_count = 1 then
Result := fetch_user
else
check no_more_than_one: sql_rows_count = 0 end
end
sql_post_execution
end
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
local
l_security: SECURITY_PROVIDER
do
if attached user_salt (l_auth_login) as l_hash then
if attached user_by_name (l_auth_login) as l_user then
create l_security
if
attached l_user.hashed_password as l_hashed_password and then
l_security.password_hash (l_auth_password, l_hash).is_case_insensitive_equal (l_hashed_password)
then
Result := True
else
log.write_information (generator + ".is_valid_credential User: wrong username or password" )
end
else
log.write_information (generator + ".is_valid_credential User:" + l_auth_login + "does not exist" )
end
end
end
feature -- Change: user
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
local
l_parameters: STRING_TABLE [detachable ANY]
l_password_salt, l_password_hash: STRING
l_security: SECURITY_PROVIDER
do
error_handler.reset
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
sql_begin_transaction
create l_security
l_password_salt := l_security.salt
l_password_hash := l_security.password_hash (l_password, l_password_salt)
log.write_information (generator + ".new_user")
create l_parameters.make (4)
l_parameters.put (a_user.name, "name")
l_parameters.put (l_password_hash, "password")
l_parameters.put (l_password_salt, "salt")
l_parameters.put (l_email, "email")
l_parameters.put (create {DATE_TIME}.make_now_utc, "created")
sql_change (sql_insert_user, l_parameters)
sql_post_execution
if not error_handler.has_error then
a_user.set_id (last_inserted_user_id)
sql_post_execution
end
sql_commit_transaction
else
-- set error
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
end
end
update_user (a_user: CMS_USER)
-- Save user `a_user'.
local
l_parameters: STRING_TABLE [detachable ANY]
l_password_salt, l_password_hash: detachable READABLE_STRING_8
l_security: SECURITY_PROVIDER
do
error_handler.reset
if attached a_user.password as l_password then
-- New password!
create l_security
l_password_salt := l_security.salt
l_password_hash := l_security.password_hash (l_password, l_password_salt)
else
-- Existing hashed password
l_password_hash := a_user.hashed_password
l_password_salt := user_salt (a_user.name)
end
if
l_password_hash /= Void and l_password_salt /= Void and
attached a_user.email as l_email
then
log.write_information (generator + ".update_user")
create l_parameters.make (6)
l_parameters.put (a_user.id, "uid")
l_parameters.put (a_user.name, "name")
l_parameters.put (l_password_hash, "password")
l_parameters.put (l_password_salt, "salt")
l_parameters.put (l_email, "email")
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
sql_change (sql_update_user, l_parameters)
sql_post_execution
else
-- set error
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
end
end
feature -- Access: roles and permissions
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
do
to_implement (generator + ".user_role_by_id")
end
user_roles: LIST [CMS_USER_ROLE]
do
to_implement (generator + ".user_roles")
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
to_implement (generator + ".save_user_role")
end
feature {NONE} -- Implementation
user_salt (a_username: READABLE_STRING_32): detachable READABLE_STRING_8
-- User salt for the given user `a_username', if any.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
log.write_information (generator + ".user_salt")
create l_parameters.make (1)
l_parameters.put (a_username, "name")
sql_query (select_salt_by_username, l_parameters)
if sql_rows_count = 1 then
if attached sql_read_string (1) as l_salt then
Result := l_salt
end
end
sql_post_execution
end
fetch_user: detachable CMS_USER
local
l_id: INTEGER_64
l_name: detachable READABLE_STRING_32
do
if attached sql_read_integer_32 (1) as i then
l_id := i
end
if attached sql_read_string_32 (2) as s and then not s.is_whitespace then
l_name := s
end
if l_name /= Void then
create Result.make (l_name)
if l_id > 0 then
Result.set_id (l_id)
end
elseif l_id > 0 then
create Result.make_with_id (l_id)
end
if Result /= Void then
if attached sql_read_string (3) as l_password then
-- FIXME: should we return the password here ???
Result.set_hashed_password (l_password)
end
if attached sql_read_string (5) as l_email then
Result.set_email (l_email)
end
else
check expected_valid_user: False end
end
end
last_inserted_user_id: INTEGER_64
-- Last insert user id.
do
error_handler.reset
log.write_information (generator + ".last_inserted_user_id")
sql_query (Sql_last_insert_user_id, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
sql_post_execution
end
feature {NONE} -- Sql Queries: USER
Select_users_count: STRING = "select count(*) from Users;"
-- Number of users.
Sql_last_insert_user_id: STRING = "SELECT MAX(uid) from Users;"
Select_users: STRING = "select * from Users;"
-- List of users.
Select_user_by_id: STRING = "select * from Users where uid =:uid;"
-- Retrieve user by id if exists.
Select_user_by_name: STRING = "select * from Users where name =:name;"
-- Retrieve user by name if exists.
Select_user_by_email: STRING = "select * from Users where email =:email;"
-- Retrieve user by email if exists.
Select_salt_by_username: STRING = "select salt from Users where name =:name;"
-- Retrieve salt by username if exists.
Sql_Insert_user: STRING = "insert into users (name, password, salt, email, created) values (:name, :password, :salt, :email, :created);"
-- SQL Insert to add a new node.
sql_update_user: STRING = "update users SET name=:name, password=:password, salt=:salt, email=:email WHERE uid=:uid;"
end

View File

@@ -1,159 +0,0 @@
note
description: "Provides security routine helpers"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
SECURITY_PROVIDER
inherit
REFACTORING_HELPER
feature -- Access
token: STRING
-- Cryptographic random base 64 string.
do
Result := salt_with_size (5)
-- Remove trailing equal sign
Result.keep_head (Result.count - 1)
end
salt: STRING
-- Cryptographic random number of 16 bytes.
do
Result := salt_with_size (16)
end
password: STRING
-- Cryptographic random password of 10 bytes.
do
Result := salt_with_size (10)
-- Remove trailing equal signs
Result.keep_head (Result.count - 2)
end
password_hash (a_password: READABLE_STRING_GENERAL; a_salt: STRING): STRING
-- Password hash based on password `a_password' and salt value `a_salt'.
local
utf: UTF_CONVERTER
s: STRING
do
create s.make (a_password.count + a_salt.count)
utf.utf_32_string_into_utf_8_string_8 (a_password, s)
s.append (a_salt)
Result := sha1_string (s)
end
feature {NONE} -- Implementation
salt_with_size (a_val: INTEGER): STRING
-- Return a salt with size `a_val'.
local
l_salt: SALT_XOR_SHIFT_64_GENERATOR
l_array: ARRAY [INTEGER_8]
i: INTEGER
do
create l_salt.make (a_val)
create l_array.make_empty
i := 1
across
l_salt.new_sequence as c
loop
l_array.force (c.item.as_integer_8, i)
i := i + 1
end
Result := encode_base_64 (l_array)
end
sha1_string (a_str: STRING): STRING
-- SHA1 diggest of `a_str'.
do
sha1.update_from_string (a_str)
Result := sha1.digest_as_string
sha1.reset
end
sha1: SHA1
-- Create a SHA1 object.
once
create Result.make
end
feature -- Encoding
encode_base_64 (bytes: SPECIAL [INTEGER_8]): STRING_8
-- Encodes a byte array into a STRING doing base64 encoding.
local
l_output: SPECIAL [INTEGER_8]
l_remaining: INTEGER
i, ptr: INTEGER
char: CHARACTER
do
to_implement ("Check existing code to do that!!!.")
create l_output.make_filled (0, ((bytes.count + 2) // 3) * 4)
l_remaining := bytes.count
from
i := 0
ptr := 0
until
l_remaining <= 3
loop
l_output [ptr] := encode_value (bytes [i] |>> 2)
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i] & 0x3) |<< 4) | ((bytes [i + 1] |>> 4) & 0xF))
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i + 1] & 0xF) |<< 2) | ((bytes [i + 2] |>> 6) & 0x3))
ptr := ptr + 1
l_output [ptr] := encode_value (bytes [i + 2] & 0x3F)
ptr := ptr + 1
l_remaining := l_remaining - 3
i := i + 3
end
-- encode when exactly 1 element (left) to encode
char := '='
if l_remaining = 1 then
l_output [ptr] := encode_value (bytes [i] |>> 2)
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i]) & 0x3) |<< 4)
ptr := ptr + 1
l_output [ptr] := char.code.as_integer_8
ptr := ptr + 1
l_output [ptr] := char.code.as_integer_8
ptr := ptr + 1
end
-- encode when exactly 2 elements (left) to encode
if l_remaining = 2 then
l_output [ptr] := encode_value (bytes [i] |>> 2)
ptr := ptr + 1
l_output [ptr] := encode_value (((bytes [i] & 0x3) |<< 4) | ((bytes [i + 1] |>> 4) & 0xF));
ptr := ptr + 1
l_output [ptr] := encode_value ((bytes [i + 1] & 0xF) |<< 2);
ptr := ptr + 1
l_output [ptr] := char.code.as_integer_8
ptr := ptr + 1
end
Result := ""
across
l_output as elem
loop
Result.append_character (elem.item.to_character_8)
end
end
base64_map: SPECIAL [CHARACTER_8]
-- Table for Base64 encoding.
once
Result := ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/").area
end
encode_value (i: INTEGER_8): INTEGER_8
-- Encode `i'.
do
Result := base64_map [i & 0x3F].code.as_integer_8
end
end

View File

@@ -1,258 +0,0 @@
note
description: "API for a CMS"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
CMS_API
inherit
ANY
REFACTORING_HELPER
SHARED_HTML_ENCODER
export
{NONE} all
end
SHARED_WSF_PERCENT_ENCODER
export
{NONE} all
end
create
make
feature -- Initialize
make (a_setup: CMS_SETUP)
-- Create the API service with a setup `a_setup'
do
setup := a_setup
create error_handler.make
initialize
ensure
setup_set: setup = a_setup
error_handler_set: not error_handler.has_error
end
setup: CMS_SETUP
-- CMS setup.
initialize
-- Initialize the persitent layer.
do
to_implement ("Refactor database setup")
if attached setup.storage (error_handler) as l_storage then
storage := l_storage
else
create {CMS_STORAGE_NULL} storage
end
end
feature -- Access: Error
has_error: BOOLEAN
-- Has error?
do
Result := error_handler.has_error
end
as_string_representation: STRING_32
-- String representation of all error(s).
do
Result := error_handler.as_string_representation
end
feature -- Element Change: Error
reset
-- Reset error handler.
do
error_handler.reset
end
feature {NONE}-- Error handler implemenations
error_handler: ERROR_HANDLER
-- Error handler.
feature -- Status Report
is_valid_credential (a_auth_login, a_auth_password: READABLE_STRING_32): BOOLEAN
-- Is the credentials `a_auth_login' and `a_auth_password' valid?
do
Result := storage.is_valid_credential (a_auth_login, a_auth_password)
end
feature -- Access: Node
nodes_count: INTEGER_64
do
Result := storage.nodes_count
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
Result := storage.nodes
end
recent_nodes (a_offset, a_rows: INTEGER): LIST [CMS_NODE]
-- List of the `a_rows' most recent nodes starting from `a_offset'.
do
Result := storage.recent_nodes (a_offset, a_rows)
end
node (a_id: INTEGER_64): detachable CMS_NODE
-- Node by ID.
do
debug ("refactor_fixme")
fixme ("Check preconditions")
end
Result := storage.node_by_id (a_id)
end
feature -- Change: Node
new_node (a_node: CMS_NODE)
-- Add a new node `a_node'
require
no_id: not a_node.has_id
do
storage.new_node (a_node)
end
delete_node (a_node: CMS_NODE)
-- Delete `a_node'.
do
if a_node.has_id then
storage.delete_node (a_node)
end
end
update_node (a_node: CMS_NODE)
-- Update node `a_node' data.
do
storage.update_node (a_node)
end
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
-- Update node title, with user identified by `a_id', with node id `a_node_id' and a new title `a_title'.
do
debug ("refactor_fixme")
fixme ("Check preconditions")
end
storage.update_node_title (a_user_id, a_node_id, a_title)
end
update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
-- Update node summary, with user identified by `a_user_id', with node id `a_node_id' and a new summary `a_summary'.
do
debug ("refactor_fixme")
fixme ("Check preconditions")
end
storage.update_node_summary (a_user_id, a_node_id, a_summary)
end
update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
-- Update node content, with user identified by `a_user_id', with node id `a_node_id' and a new content `a_content'.
do
debug ("refactor_fixme")
fixme ("Check preconditions")
end
storage.update_node_content (a_user_id, a_node_id, a_content)
end
feature -- Access: User
user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER
-- User by name `a_user_name', if any.
do
Result := storage.user_by_name (a_username)
end
feature -- Change User
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
no_hashed_password: a_user.hashed_password = Void
do
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
storage.new_user (a_user)
else
debug ("refactor_fixme")
fixme ("Add error")
end
end
end
update_user (a_user: CMS_USER)
-- Update user `a_user'.
require
has_id: a_user.has_id
do
storage.update_user (a_user)
end
feature -- Helpers
html_encoded (a_string: READABLE_STRING_GENERAL): STRING_8
-- `a_string' encoded for html output.
do
Result := html_encoder.general_encoded_string (a_string)
end
percent_encoded (a_string: READABLE_STRING_GENERAL): STRING_8
-- `a_string' encoded with percent encoding, mainly used for url.
do
Result := percent_encoder.percent_encoded_string (a_string)
end
feature -- Layout
module_configuration (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
p, l_path: PATH
ut: FILE_UTILITIES
do
p := setup.layout.config_path.extended ("modules").extended (a_module_name)
if a_name = Void then
p := p.extended (a_module_name)
else
p := p.extended (a_name)
end
l_path := p.appended_with_extension ("json")
if ut.file_path_exists (l_path) then
create {JSON_CONFIG} Result.make_from_file (l_path)
else
l_path := p.appended_with_extension ("ini")
if ut.file_path_exists (l_path) then
create {INI_CONFIG} Result.make_from_file (l_path)
end
end
if Result = Void and a_name /= Void then
-- Use sub config from default?
if attached {CONFIG_READER} module_configuration (a_module_name, Void) as cfg then
Result := cfg.sub_config (a_name)
else
-- Maybe try to use the global cms.ini ?
end
end
end
feature {NONE} -- Implemenataion
storage: CMS_STORAGE
-- Persistence storage.
end

View File

@@ -1,17 +0,0 @@
note
description: "Summary description for {CMS_API_OPTIONS}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_API_OPTIONS
inherit
WSF_API_OPTIONS
create
make,
make_from_manifest
end

View File

@@ -1,58 +0,0 @@
note
description: "Summary description for {CMS_REQUEST_UTIL}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_REQUEST_UTIL
inherit
CMS_ENCODERS
REFACTORING_HELPER
feature -- User
current_user_name (req: WSF_REQUEST): detachable READABLE_STRING_32
-- Current user name or Void in case of Guest users.
note
EIS: "src=eiffel:?class=AUTHENTICATION_FILTER&feature=execute"
do
if attached {CMS_USER} current_user (req) as l_user then
Result := l_user.name
end
end
current_user (req: WSF_REQUEST): detachable CMS_USER
-- Current user or Void in case of Guest user.
note
EIS: "eiffel:?class=AUTHENTICATION_FILTER&feature=execute"
do
if attached {CMS_USER} req.execution_variable ("user") as l_user then
Result := l_user
end
end
feature -- Media Type
current_media_type (req: WSF_REQUEST): detachable READABLE_STRING_32
-- Current media type or Void if it's not acceptable.
do
if attached {STRING} req.execution_variable ("media_type") as l_type then
Result := l_type
end
end
feature -- Absolute Host
absolute_host (req: WSF_REQUEST; a_path:STRING): STRING
do
Result := req.absolute_script_url (a_path)
if Result.last_index_of ('/', Result.count) = Result.count then
Result.remove_tail (1)
end
end
end

View File

@@ -1,261 +0,0 @@
note
description: "[
This class implements the CMS service
It could be used to implement the main EWF service, or
even for a specific handler.
]"
class
CMS_SERVICE
inherit
WSF_ROUTED_SKELETON_SERVICE
rename
execute as execute_service
undefine
requires_proxy
redefine
execute_default
end
WSF_FILTERED_SERVICE
WSF_FILTER
rename
execute as execute_filter
end
WSF_NO_PROXY_POLICY
WSF_URI_HELPER_FOR_ROUTED_SERVICE
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_SERVICE
REFACTORING_HELPER
SHARED_LOGGER
create
make
feature {NONE} -- Initialization
make (a_api: CMS_API)
-- Build a CMS service with `a_api'
do
api := a_api
initialize
ensure
api_set: api = a_api
end
initialize
-- Initialize various parts of the CMS service.
do
initialize_modules
initialize_users
initialize_auth_engine
initialize_mailer
-- initialize_router
-- initialize_filter: expanded here, for void-safety concern.
create_filter
initialize_router
setup_filter
end
initialize_modules
-- Intialize modules and keep only enabled modules.
do
modules := setup.enabled_modules
ensure
only_enabled_modules: across modules as ic all ic.item.is_enabled end
end
initialize_users
-- Initialize users.
do
end
initialize_mailer
-- Initialize mailer engine.
do
to_implement ("To Implement mailer")
end
initialize_auth_engine
do
to_implement ("To Implement authentication engine")
end
feature -- Settings: router
setup_router
-- <Precursor>
local
l_module: CMS_MODULE
l_api: like api
l_router: like router
do
log.write_debug (generator + ".setup_router")
-- Configure root of api handler.
l_router := router
configure_api_root (l_router)
-- Include routes from modules.
l_api := api
across
modules as ic
loop
l_module := ic.item
l_router.import (l_module.router (l_api))
end
-- Configure files handler.
configure_api_file_handler (l_router)
end
configure_api_root (a_router: WSF_ROUTER)
local
l_root_handler: CMS_ROOT_HANDLER
l_methods: WSF_REQUEST_METHODS
do
log.write_debug (generator + ".configure_api_root")
create l_root_handler.make (api)
create l_methods
l_methods.enable_get
a_router.handle_with_request_methods ("/", l_root_handler, l_methods)
a_router.handle_with_request_methods ("", l_root_handler, l_methods)
end
configure_api_file_handler (a_router: WSF_ROUTER)
local
fhdl: WSF_FILE_SYSTEM_HANDLER
do
log.write_debug (generator + ".configure_api_file_handler")
create fhdl.make_hidden_with_path (setup.theme_assets_location)
fhdl.disable_index
fhdl.set_not_found_handler (agent (ia_uri: READABLE_STRING_8; ia_req: WSF_REQUEST; ia_res: WSF_RESPONSE)
do
execute_default (ia_req, ia_res)
end)
a_router.handle_with_request_methods ("/theme/", fhdl, router.methods_GET)
create fhdl.make_hidden_with_path (setup.layout.www_path)
fhdl.disable_index
fhdl.set_not_found_handler (agent (ia_uri: READABLE_STRING_8; ia_req: WSF_REQUEST; ia_res: WSF_RESPONSE)
do
execute_default (ia_req, ia_res)
end)
a_router.handle_with_request_methods ("/", fhdl, router.methods_GET)
end
feature -- Execute Filter
execute_filter (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
do
res.put_header_line ("Date: " + (create {HTTP_DATE}.make_now_utc).string)
res.put_header_line ("X-EWF-Server: CMS_v1.0")
execute_service (req, res)
end
feature -- Filters
create_filter
-- Create `filter'.
local
f, l_filter: detachable WSF_FILTER
l_module: CMS_MODULE
l_api: like api
do
log.write_debug (generator + ".create_filter")
l_filter := Void
-- Maintenance
create {WSF_MAINTENANCE_FILTER} f
f.set_next (l_filter)
l_filter := f
-- Error Filter
create {CMS_ERROR_FILTER} f.make (api)
f.set_next (l_filter)
l_filter := f
-- Include filters from modules
l_api := api
across
modules as ic
loop
l_module := ic.item
if
l_module.is_enabled and then
attached l_module.filters (l_api) as l_m_filters
then
across l_m_filters as f_ic loop
f := f_ic.item
f.set_next (l_filter)
l_filter := f
end
end
end
filter := l_filter
end
setup_filter
-- Setup `filter'.
local
f: WSF_FILTER
do
log.write_debug (generator + ".setup_filter")
from
f := filter
until
not attached f.next as l_next
loop
f := l_next
end
f.set_next (Current)
end
feature -- Access
api: CMS_API
-- API service.
setup: CMS_SETUP
-- CMS setup.
do
Result := api.setup
end
modules: CMS_MODULE_COLLECTION
-- Configurator of possible modules.
feature -- Execution
execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Default request handler if no other are relevant
local
r: NOT_FOUND_ERROR_CMS_RESPONSE
do
to_implement ("Default response for CMS_SERVICE")
create r.make (req, res, api)
r.execute
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,129 +0,0 @@
note
description: "Summary description for {CMS_URL_UTILITIES}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_URL_UTILITIES
inherit
CMS_REQUEST_UTIL
feature -- Core
site_url: READABLE_STRING_8
deferred
end
base_url: detachable READABLE_STRING_8
-- Base url if any.
deferred
end
based_path (p: STRING): STRING
-- Path `p' in the context of the `base_url'
do
if attached base_url as l_base_url then
create Result.make_from_string (l_base_url)
if p.is_empty then
else
if p[1] = '/' then
Result.append (p.substring (2, p.count))
else
Result.append (p)
end
end
else
Result := p
end
end
feature -- Url
absolute_url (a_path: STRING; opts: detachable CMS_API_OPTIONS): STRING
local
l_opts: detachable CMS_API_OPTIONS
do
l_opts := opts
if l_opts = Void then
create l_opts.make (1)
end
l_opts.force (True, "absolute")
Result := url (a_path, l_opts)
end
url (a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING
-- URL for path `a_path' and optional parameters from `opts'.
--| Options `opts' could be
--| - absolute: True|False => return absolute url
--| - query: string => append "?query"
--| - fragment: string => append "#fragment"
local
q,f: detachable STRING_8
l_abs: BOOLEAN
do
l_abs := False
if opts /= Void then
l_abs := opts.boolean_item ("absolute", l_abs)
if attached opts.item ("query") as l_query then
if attached {READABLE_STRING_8} l_query as s_value then
q := s_value
elseif attached {ITERABLE [TUPLE [key, value: READABLE_STRING_GENERAL]]} l_query as lst then
create q.make_empty
across
lst as c
loop
if q.is_empty then
else
q.append_character ('&')
end
q.append (url_encoded (c.item.key))
q.append_character ('=')
q.append (url_encoded (c.item.value))
end
end
end
if attached opts.string_item ("fragment") as s_frag then
f := s_frag
end
end
if l_abs then
if a_path.substring_index ("://", 1) = 0 then
create Result.make_from_string (site_url)
if a_path.is_empty then
elseif Result.ends_with ("/") then
if a_path[1] = '/' then
Result.append_string (a_path.substring (2, a_path.count))
else
Result.append_string (a_path)
end
else
if a_path[1] = '/' then
Result.append_string (a_path)
else
Result.append_character ('/')
Result.append_string (a_path)
end
end
else
Result := a_path
end
else
Result := based_path (a_path)
end
if q /= Void then
Result.append ("?" + q)
end
if f /= Void then
Result.append ("#" + f)
end
end
checked_url (a_url: READABLE_STRING_8): READABLE_STRING_8
do
Result := a_url
end
end

View File

@@ -1,40 +0,0 @@
note
description: "Summary description for {CMS_ERROR_FILTER}."
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
revision: "$Revision: 96402 $"
class
CMS_ERROR_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
CMS_HANDLER
WSF_FILTER
create
make
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter
do
fixme ("Check if it's ok to add new fetures CMS_API.has_error:BOOLEAN and CMS_API.error_description.")
if not api.has_error then
log.write_information (generator + ".execute with req: " + req.debug_output)
if attached req.raw_header_data as l_header_data then
log.write_debug (generator + ".execute with req header: " + l_header_data)
end
if attached req.raw_input_data as l_input_data then
log.write_debug (generator + ".execute with req input: " + l_input_data)
end
execute_next (req, res)
else
log.write_critical (generator + ".execute" + api.as_string_representation )
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
api.reset
end
end
end

View File

@@ -1,38 +0,0 @@
note
description: "Summary description for {CMS_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_HANDLER
inherit
WSF_HANDLER
CMS_REQUEST_UTIL
SHARED_LOGGER
REFACTORING_HELPER
feature {NONE} -- Initialization
make (a_api: CMS_API)
do
api := a_api
end
feature -- Setup
setup: CMS_SETUP
do
Result := api.setup
end
feature -- API Service
api: CMS_API
end

View File

@@ -1,54 +0,0 @@
note
description: "Summary description for {CMS_ROOT_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
CMS_ROOT_HANDLER
inherit
CMS_HANDLER
WSF_FILTER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
(create {HOME_CMS_RESPONSE}.make (req, res, api)).execute
end
end

View File

@@ -1,38 +0,0 @@
note
description: "Summary description for {BAD_REQUEST_ERROR_CMS_RESPONSE}."
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
revision: "$Revision: 96402 $"
class
BAD_REQUEST_ERROR_CMS_RESPONSE
inherit
CMS_RESPONSE
redefine
custom_prepare
end
create
make
feature -- Generation
custom_prepare (page: CMS_HTML_PAGE)
do
page.register_variable (request.absolute_script_url (request.path_info), "request")
page.set_status_code ({HTTP_STATUS_CODE}.bad_request)
page.register_variable (page.status_code.out, "code")
end
feature -- Execution
process
-- Computed response message.
do
set_title ("Bad request")
set_page_title ("Bad request")
set_main_content ("<em>Bad request.</em>")
end
end

View File

@@ -1,61 +0,0 @@
note
description: "Summary description for {CMS_GENERIC_RESPONSE}."
date: "$Date$"
revision: "$Revision$"
class
CMS_GENERIC_RESPONSE
feature -- Responses
new_response_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
-- Redirect to `a_location'
local
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_html
h.put_current_date
h.put_location (a_location)
res.set_status_code ({HTTP_STATUS_CODE}.see_other)
res.put_header_text (h.string)
end
new_response_authenticate (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Handle authenticate.
local
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_html
h.put_current_date
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"CMSRoc-User%"")
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.put_header_text (h.string)
end
new_response_denied (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Handle access denied.
local
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_html
h.put_current_date
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.put_header_text (h.string)
end
new_response_unauthorized (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Handle not authorized.
local
h: HTTP_HEADER
do
create h.make
h.put_content_type_text_html
h.put_current_date
res.set_status_code ({HTTP_STATUS_CODE}.forbidden)
res.put_header_text (h.string)
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +0,0 @@
note
description: "Summary description for {NODE_VIEW_CMS_RESPONSE}."
date: "$Date$"
revision: "$Revision$"
class
GENERIC_VIEW_CMS_RESPONSE
inherit
CMS_RESPONSE
redefine
custom_prepare
end
create
make
feature -- Generation
custom_prepare (page: CMS_HTML_PAGE)
do
if attached variables as l_variables then
across l_variables as c loop page.register_variable (c.item, c.key) end
end
end
feature -- Execution
process
-- Computed response message.
do
-- set_title ("CMS")
-- set_page_title (Void)
end
end

View File

@@ -1,36 +0,0 @@
note
description: "Summary description for {HOME_CMS_RESPONSE}."
date: "$Date: 2014-12-17 13:14:43 +0100 (mer., 17 déc. 2014) $"
revision: "$Revision: 96367 $"
class
HOME_CMS_RESPONSE
inherit
CMS_RESPONSE
redefine
custom_prepare
end
create
make
feature -- Generation
custom_prepare (page: CMS_HTML_PAGE)
do
Precursor (page)
-- page.register_variable (api.recent_nodes (0, 5), "nodes")
end
feature -- Execution
process
-- Computed response message.
do
set_title (Void)
set_page_title (Void)
end
end

View File

@@ -1,38 +0,0 @@
note
description: "Summary description for {INTERNAL_SERVER_ERROR_CMS_RESPONSE}."
date: "$Date: 2014-12-19 14:17:32 +0100 (ven., 19 déc. 2014) $"
revision: "$Revision: 96402 $"
class
INTERNAL_SERVER_ERROR_CMS_RESPONSE
inherit
CMS_RESPONSE
redefine
custom_prepare
end
create
make
feature -- Generation
custom_prepare (page: CMS_HTML_PAGE)
do
page.register_variable (request.absolute_script_url (request.path_info), "request")
page.set_status_code ({HTTP_STATUS_CODE}.internal_server_error)
page.register_variable (page.status_code.out, "code")
end
feature -- Execution
process
-- Computed response message.
do
set_title ("Internal Server Error")
set_page_title (Void)
set_main_content ("<em>Internal Server Error</em>")
end
end

View File

@@ -1,38 +0,0 @@
note
description: "Summary description for {NOT_FOUND_ERROR_CMS_RESPONSE}."
date: "$Date$"
revision: "$Revision$"
class
NOT_FOUND_ERROR_CMS_RESPONSE
inherit
CMS_RESPONSE
redefine
custom_prepare
end
create
make
feature -- Generation
custom_prepare (page: CMS_HTML_PAGE)
do
page.register_variable (request.absolute_script_url (request.path_info), "request")
page.set_status_code ({HTTP_STATUS_CODE}.not_found)
page.register_variable (page.status_code.out, "code")
end
feature -- Execution
process
-- Computed response message.
do
set_title ("Not Found")
set_page_title ("Not Found")
set_main_content ("<em>The requested page could not be found.</em>")
end
end

View File

@@ -1,40 +0,0 @@
note
description: "Summary description for {NOT_IMPLEMENTED_ERROR_CMS_RESPONSE}."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
inherit
CMS_RESPONSE
redefine
custom_prepare
end
create
make
feature -- Generation
custom_prepare (page: CMS_HTML_PAGE)
do
page.register_variable (request.absolute_script_url (request.path_info), "request")
page.set_status_code ({HTTP_STATUS_CODE}.not_implemented)
page.register_variable (page.status_code.out, "code")
end
feature -- Execution
process
-- Computed response message.
do
set_title ("Not Implemented")
set_page_title (Void)
if main_content = Void then
set_main_content (request.percent_encoded_path_info + " is not implemented!")
end
end
end

View File

@@ -1,193 +0,0 @@
note
description: "Summary description for {CMS_HTML_PAGE}."
author: ""
date: "$Date: 2014-11-04 09:57:24 -0300 (ma. 04 de nov. de 2014) $"
revision: "$Revision: 96034 $"
class
CMS_HTML_PAGE
create
make,
make_typed
feature {NONE} -- Initialization
make_typed (a_type: attached like type)
-- Make current page with optional page type `a_type'.
do
make
type := a_type
end
make
do
create regions.make (5)
language := "en"
status_code := {HTTP_STATUS_CODE}.ok
create header.make
create {ARRAYED_LIST [STRING]} head_lines.make (5)
header.put_content_type_text_html
create variables.make (0)
end
feature -- Access
type: detachable READABLE_STRING_8
-- Optional page type.
-- such as "front", "about", ... that could be customized by themes.
is_front: BOOLEAN
title: detachable READABLE_STRING_32
language: STRING
head_lines: LIST [STRING]
head_lines_to_string: STRING
do
create Result.make_empty
across
head_lines as h
loop
Result.append (h.item)
Result.append_character ('%N')
end
end
variables: STRING_TABLE [detachable ANY]
feature -- Status
status_code: INTEGER
feature -- Header
header: HTTP_HEADER
feature -- Region
regions: STRING_TABLE [STRING_8]
-- header
-- content
-- footer
-- could have sidebar first, sidebar second, ...
region (n: STRING_8): STRING_8
do
if attached regions.item (n) as r then
Result := r
else
Result := ""
debug
Result := "{{" + n + "}}"
end
end
end
feature -- Element change
set_is_front (b: BOOLEAN)
-- Set `is_front' to `b'.
do
is_front := b
end
register_variable (a_value: detachable ANY; k: READABLE_STRING_GENERAL)
do
variables.force (a_value, k)
end
add_to_region (s: STRING; k: STRING)
local
r: detachable STRING
do
r := regions.item (k)
if r = Void then
create r.make_from_string (s)
set_region (r, k)
else
r.append (s)
end
end
set_region (s: STRING; k: STRING)
do
regions.force (s, k)
end
feature -- Element change
set_status_code (c: like status_code)
do
status_code := c
end
set_language (s: like language)
do
language := s
end
set_title (s: like title)
do
title := s
end
add_meta_name_content (a_name: STRING; a_content: STRING)
local
s: STRING_8
do
s := "<meta name=%"" + a_name + "%" content=%"" + a_content + "%" />"
head_lines.extend (s)
end
add_meta_http_equiv (a_http_equiv: STRING; a_content: STRING)
local
s: STRING_8
do
s := "<meta http-equiv=%"" + a_http_equiv + "%" content=%"" + a_content + "%" />"
head_lines.extend (s)
end
add_style (a_href: STRING; a_media: detachable STRING)
local
s: STRING_8
do
s := "<link rel=%"stylesheet%" href=%""+ a_href + "%" type=%"text/css%""
if a_media /= Void then
s.append (" media=%""+ a_media + "%"")
end
s.append ("/>")
head_lines.extend (s)
end
add_javascript_url (a_src: STRING)
local
s: STRING_8
do
s := "<script type=%"text/javascript%" src=%"" + a_src + "%"></script>"
head_lines.extend (s)
end
add_javascript_content (a_script: STRING)
local
s: STRING_8
do
s := "<script type=%"text/javascript%">%N" + a_script + "%N</script>"
head_lines.extend (s)
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,77 +0,0 @@
note
description: "Summary description for {CMS_HTML_PAGE_RESPONSE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_HTML_PAGE_RESPONSE
inherit
WSF_RESPONSE_MESSAGE
create
make
feature {NONE} -- Initialization
make (a_html: like html)
do
html := a_html
status_code := {HTTP_STATUS_CODE}.ok
create header.make
header.put_content_type_text_html
end
feature -- Status
status_code: INTEGER
feature -- Header
header: HTTP_HEADER
feature -- Html access
html: STRING
feature -- Element change
set_status_code (c: like status_code)
do
status_code := c
end
feature {WSF_RESPONSE} -- Output
send_to (res: WSF_RESPONSE)
local
h: like header
s: STRING_8
do
h := header
res.set_status_code (status_code)
s := html
if not h.has_content_length then
h.put_content_length (s.count)
end
if not h.has_content_type then
h.put_content_type_text_html
end
res.put_header_text (h.string)
res.put_string (s)
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,13 +0,0 @@
note
description: "Summary description for {WSF_CMS_HTML_TEMPLATE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_HTML_TEMPLATE
inherit
CMS_TEMPLATE
end

View File

@@ -1,12 +0,0 @@
note
description: "Summary description for {CMS_PAGE_TEMPLATE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_PAGE_TEMPLATE
inherit
CMS_TEMPLATE
end

View File

@@ -1,43 +0,0 @@
note
description: "[
Abstract interface for a CMS Template, as part of the theme design.
]"
date: "$Date: 2014-11-20 15:03:29 +0100 (jeu., 20 nov. 2014) $"
revision: "$Revision: 96138 $"
deferred class
CMS_TEMPLATE
feature -- Access
theme: CMS_THEME
-- Associated theme.
deferred
end
variables: STRING_TABLE [detachable ANY]
-- Variables used for Current template rendering.
deferred
end
prepare (page: CMS_HTML_PAGE)
-- Prepare `page' with current template.
deferred
end
to_html (page: CMS_HTML_PAGE): STRING
-- HTML rendering for page `page'.
deferred
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,139 +0,0 @@
note
description: "Abstract class describing a generic theme"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_THEME
inherit
CMS_ENCODERS
REFACTORING_HELPER
feature {NONE} -- Access
setup: CMS_SETUP
feature -- Access
name: STRING
-- theme name.
deferred
end
regions: ARRAY [STRING]
-- theme's regions.
deferred
end
page_template: CMS_TEMPLATE
-- theme template page.
deferred
end
feature -- Conversion
menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8
do
debug ("refactor_fixme")
fixme ("Refactor HTML code to use the new Bootstrap theme template")
end
create Result.make_from_string ("<div id=%""+ a_menu.name +"%" class=%"menu%">")
if is_horizontal then
Result.append ("<ul class=%"horizontal%" >%N")
else
Result.append ("<ul class=%"vertical%" >%N")
end
across
a_menu as c
loop
append_cms_link_to (c.item, Result)
end
Result.append ("</ul>%N")
Result.append ("</div>")
end
block_html (a_block: CMS_BLOCK): STRING_8
local
s: STRING
do
debug ("refactor_fixme")
fixme ("Refactor HTML code to use the new Bootstrap theme template")
end
if attached a_block.is_raw then
create s.make_empty
if attached a_block.title as l_title then
s.append ("<div class=%"title%">" + html_encoded (l_title) + "</div>")
end
s.append (a_block.to_html (Current))
else
create s.make_from_string ("<div class=%"block%" id=%"" + a_block.name + "%">")
if attached a_block.title as l_title then
s.append ("<div class=%"title%">" + html_encoded (l_title) + "</div>")
end
s.append ("<div class=%"inside%">")
s.append (a_block.to_html (Current))
s.append ("</div>")
s.append ("</div>")
end
Result := s
end
page_html (page: CMS_HTML_PAGE): STRING_8
-- Render `page' as html.
deferred
end
feature {NONE} -- Implementation
append_cms_link_to (lnk: CMS_LINK; s: STRING_8)
local
cl: STRING
do
debug ("refactor_fixme")
fixme ("Remove HTML from Eiffel")
end
create cl.make_empty
if lnk.is_active then
cl.append ("active ")
end
if lnk.is_expandable then
cl.append ("expandable ")
end
if lnk.is_expanded then
cl.append ("expanded ")
end
if cl.is_empty then
s.append ("<li>")
else
s.append ("<li class=%""+ cl + "%">")
end
s.append ("<a href=%"" + (lnk.location) + "%">" + html_encoded (lnk.title) + "</a>")
if
(lnk.is_expanded or lnk.is_collapsed) and then
attached lnk.children as l_children
then
s.append ("<ul>%N")
across
l_children as c
loop
append_cms_link_to (c.item, s)
end
s.append ("</ul>")
end
s.append ("</li>")
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,135 +0,0 @@
note
description: "Summary description for {CMS_THEME_INFORMATION}."
date: "$Date$"
revision: "$Revision$"
class
CMS_THEME_INFORMATION
create
make,
make_default
feature {NONE} -- Initialization
make_default
do
engine := {STRING_32} "default"
create items.make_caseless (1)
create regions.make (5)
across
(<<"top","header", "highlighted","help", "content", "footer", "first_sidebar", "second_sidebar", "bottom">>) as ic
loop
regions.force (ic.item, ic.item)
end
end
make (fn: PATH)
local
f: PLAIN_TEXT_FILE
s: STRING_8
h,k: STRING_8
v: STRING_32
i: INTEGER
utf: UTF_CONVERTER
l_engine: detachable READABLE_STRING_32
done: BOOLEAN
do
make_default
create f.make_with_path (fn)
if f.exists and then f.is_access_readable then
f.open_read
from
until
done or f.exhausted or f.end_of_file
loop
f.read_line_thread_aware
s := f.last_string
s.left_adjust
if
s.is_empty
or else s.starts_with_general (";")
or else s.starts_with_general ("#")
or else s.starts_with_general ("--")
then
-- Ignore
else
i := s.index_of ('=', 1)
if i > 0 then
h := s.substring (1, i - 1)
h.left_adjust
h.right_adjust
if h.is_case_insensitive_equal_general ("engine") then
s.remove_head (i)
s.right_adjust
v := utf.utf_8_string_8_to_string_32 (s)
l_engine := v
elseif h.starts_with_general ("regions[") and h[h.count] = ']' then
s.remove_head (i)
s.right_adjust
v := utf.utf_8_string_8_to_string_32 (s)
i := h.index_of ('[', 1)
k := h.substring (i + 1, h.count - 1)
k.left_adjust
k.right_adjust
if k.starts_with_general ("-") then
--| If name is prefixed by "-"
--| remove the related region
--| If name is "-*", clear all regions.
if k.is_case_insensitive_equal_general ("-*") then
regions.wipe_out
else
k.remove_head (1)
regions.remove (k)
end
else
regions.force (v, k)
end
else
s.remove_head (i)
s.right_adjust
v := utf.utf_8_string_8_to_string_32 (s)
end
items.force (v, h)
end
end
end
f.close
end
if l_engine /= Void and then not l_engine.is_empty then
engine := l_engine
end
end
feature -- Access
engine: STRING_32
-- Template engine.
--| Could be: default, smarty, ...
regions: STRING_TABLE [READABLE_STRING_GENERAL]
-- Regions available in this theme
item (k: READABLE_STRING_GENERAL): detachable STRING_32
-- Item associated with name `k' if any.
do
Result := items[k]
end
items: STRING_TABLE [STRING_32]
-- Items indexed by key name.
invariant
engine_set: not engine.is_empty
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,75 +0,0 @@
note
description: "Summary description for {DEFAULT_CMS_TEMPLATE}."
date: "$Date$"
revision: "$Revision$"
deferred class
DEFAULT_CMS_TEMPLATE
inherit
CMS_TEMPLATE
feature {NONE} -- Implementation
apply_template_engine (s: STRING_8)
local
p,n: INTEGER
k: STRING
sv: detachable STRING
do
from
n := s.count
p := 1
until
p = 0
loop
p := s.index_of ('$', p)
if p > 0 then
k := next_identifier (s, p + 1)
s.remove_substring (p, p + k.count)
sv := Void
if attached variables.item (k) as l_value then
if attached {STRING_8} l_value as s8 then
sv := s8
elseif attached {STRING_32} l_value as s32 then
sv := s32.as_string_8 -- FIXME: use html encoder
else
sv := l_value.out
end
s.insert_string (sv, p)
p := p + sv.count
else
debug
s.insert_string ("$" + k, p)
end
end
end
end
end
next_identifier (s: STRING; a_index: INTEGER): STRING
local
i: INTEGER
do
from
i := a_index
until
not (s[i].is_alpha_numeric or s[i] = '_' or s[i] = '.')
loop
i := i + 1
end
Result := s.substring (a_index, i - 1)
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,48 +0,0 @@
note
description: "[
Template to be used with missing theme.
]"
date: "$Date$"
revision: "$Revision$"
class
MISSING_CMS_TEMPLATE
inherit
CMS_TEMPLATE
create
make
feature {NONE} -- Implementation
make (a_theme: MISSING_CMS_THEME)
-- Instantiate Current template based on theme `a_theme'.
do
theme := a_theme
end
feature -- Access
theme: MISSING_CMS_THEME
-- <Precursor>
variables: STRING_TABLE [detachable ANY]
-- <Precursor>
do
create Result.make (0)
end
prepare (page: CMS_HTML_PAGE)
-- <Precursor>
do
end
to_html (page: CMS_HTML_PAGE): STRING
-- <Precursor>
do
Result := " "
end
end

View File

@@ -1,48 +0,0 @@
note
description: "[
Theme used when expected theme is missing.
It is mainly used to report missing theme error.
]"
date: "$Date$"
revision: "$Revision$"
class
MISSING_CMS_THEME
inherit
CMS_THEME
create
make
feature {NONE} -- Initialization
make (a_setup: like setup)
do
setup := a_setup
ensure
setup_set: setup = a_setup
end
feature -- Access
name: STRING = "missing theme"
regions: ARRAY [STRING]
do
create Result.make_empty
end
page_template: CMS_TEMPLATE
-- theme template page.
do
create {MISSING_CMS_TEMPLATE} Result.make (Current)
end
page_html (page: CMS_HTML_PAGE): STRING_8
do
to_implement ("Add a better response message, maybe using smarty template")
Result := "Service Unavailable"
end
end

View File

@@ -1,60 +0,0 @@
note
description: "Summary description for {SMARTY_CMS_HTML_PAGE_INSPECTOR}."
author: ""
date: "$Date: 2014-11-07 04:58:41 -0300 (vi. 07 de nov. de 2014) $"
revision: "$Revision: 96042 $"
class
SMARTY_CMS_HTML_PAGE_INSPECTOR
inherit
TEMPLATE_INSPECTOR
redefine
internal_data
end
CMS_ENCODERS
create
register
feature {TEMPLATE_ROUTINES}
internal_data (field_name: STRING; obj: detachable ANY): detachable CELL [detachable ANY]
-- Return object in a cell
-- If not handled by this inspector, return Void
local
l_fn: STRING
do
if attached {CMS_HTML_PAGE} obj as l_page then
l_fn := field_name.as_lower
if attached l_page.variables.item (l_fn) as v then
Result := cell_of (v)
elseif l_fn.is_case_insensitive_equal ("title") then
if attached l_page.title as l_title then
Result := cell_of (html_encoded (l_title))
else
Result := cell_of (Void)
end
elseif l_fn.is_case_insensitive_equal ("is_front") then
Result := cell_of (l_page.is_front)
elseif l_fn.starts_with_general ("region_") then
l_fn.remove_head (7) -- remove "region_"
Result := cell_of (l_page.region (l_fn))
elseif l_fn.is_case_insensitive_equal ("regions") then
Result := cell_of (l_page.regions)
end
end
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,140 +0,0 @@
note
description: "Summary description for {CMS_PAGE_TEMPLATE}."
date: "$Date: 2015-01-14 16:13:47 +0100 (mer., 14 janv. 2015) $"
revision: "$Revision: 96454 $"
class
SMARTY_CMS_PAGE_TEMPLATE
inherit
CMS_PAGE_TEMPLATE
CMS_ENCODERS
SHARED_TEMPLATE_CONTEXT
create
make
feature {NONE} -- Initialization
make (tpl: READABLE_STRING_GENERAL; t: SMARTY_CMS_THEME)
do
theme := t
create variables.make (0)
template_name := tpl
end
variables: STRING_TABLE [detachable ANY]
feature -- Access
template_name: READABLE_STRING_GENERAL
theme: SMARTY_CMS_THEME
prepare (page: CMS_HTML_PAGE)
do
variables.make (10)
across
page.variables as ic
loop
variables.force (ic.item, ic.key)
end
-- FIXME: review variables !
if attached page.title as l_title then
variables.force (html_encoded (l_title), "head_title")
variables.force (html_encoded (l_title), "page_title")
else
variables.force ("CMS", "head_title")
variables.force ("", "page_title")
end
variables.force (page.language, "language")
variables.force (page.head_lines_to_string, "head_lines")
across
theme.regions as r
loop
variables.force (page.region (r.item), "region_" + r.item)
end
end
to_html (page: CMS_HTML_PAGE): STRING
local
tpl: detachable TEMPLATE_FILE
ut: FILE_UTILITIES
p: detachable PATH
n: STRING_32
do
-- Process html generation
template_context.set_template_folder (theme.templates_directory)
template_context.disable_verbose
debug ("smarty")
template_context.enable_verbose
end
if attached page.type as l_page_type then
create n.make_from_string_general (l_page_type)
n.append_character ('-')
n.append_string_general (template_name)
n.append_string_general (".tpl")
p := template_context.template_file (n)
if ut.file_path_exists (p) then
create tpl.make_from_file (n)
end
end
if tpl = Void then
create n.make_from_string_general (template_name)
n.append_string_general (".tpl")
p := template_context.template_file (n)
if ut.file_path_exists (p) then
create tpl.make_from_file (n)
end
end
if tpl /= Void then
across
variables as ic
loop
tpl.add_value (ic.item, ic.key)
end
debug ("cms")
template_context.enable_verbose
end
tpl.analyze
tpl.get_output
if attached tpl.output as l_output then
Result := l_output
else
create Result.make_from_string ("ERROR: template issue.")
end
else
create Result.make_from_string ("ERROR: template issue.")
end
end
feature -- Registration
register (v: STRING_8; k: STRING_8)
do
variables.force (v, k)
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,47 +0,0 @@
note
description: "Summary description for {SMARTY_CMS_REGIONS_INSPECTOR}."
author: ""
date: "$Date: 2014-11-06 17:59:12 -0300 (ju. 06 de nov. de 2014) $"
revision: "$Revision: 96040 $"
class
SMARTY_CMS_REGIONS_INSPECTOR
inherit
TEMPLATE_INSPECTOR
redefine
internal_data
end
create
register
feature {TEMPLATE_ROUTINES}
internal_data (field_name: STRING; obj: detachable ANY): detachable CELL [detachable ANY]
-- Return object in a cell
-- If not handled by this inspector, return Void
local
l_fn: STRING
do
if attached {like {CMS_RESPONSE}.regions} obj as l_regions then
l_fn := field_name.as_lower
if l_fn.is_case_insensitive_equal ("count") then
Result := cell_of (l_regions.count)
elseif l_regions.has (l_fn) then
Result := cell_of (l_regions.item (l_fn))
end
end
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,140 +0,0 @@
note
description: "Smarty template CMS theme."
date: "$Date: 2014-12-05 22:39:27 +0100 (ven., 05 déc. 2014) $"
revision: "$Revision: 96260 $"
class
SMARTY_CMS_THEME
inherit
CMS_THEME
create
make
feature {NONE} -- Initialization
make (a_setup: like setup; a_info: like information;)
do
setup := a_setup
information := a_info
if attached a_info.item ("template_dir") as s then
templates_directory := a_setup.theme_location.extended (s)
else
templates_directory := a_setup.theme_location
end
ensure
setup_set: setup = a_setup
information_set: information = a_info
end
feature -- Access
name: STRING = "smarty-CMS"
templates_directory: PATH
information: CMS_THEME_INFORMATION
regions: ARRAY [STRING]
local
i: INTEGER
utf: UTF_CONVERTER
l_regions: like internal_regions
do
l_regions := internal_regions
if l_regions = Void then
if attached information.regions as tb and then not tb.is_empty then
i := 1
create l_regions.make_filled ("", i, i + tb.count - 1)
across
tb as ic
loop
l_regions.force (utf.utf_32_string_to_utf_8_string_8 (ic.key), i) -- NOTE: UTF-8 encoded !
i := i + 1
end
else
l_regions := <<"top","header", "highlighted","help", "content", "footer", "first_sidebar", "second_sidebar", "bottom">>
end
internaL_regions := l_regions
end
Result := l_regions
end
page_template: SMARTY_CMS_PAGE_TEMPLATE
local
tpl: like internal_page_template
do
tpl := internal_page_template
if tpl = Void then
create tpl.make ("page", Current)
internal_page_template := tpl
end
Result := tpl
end
feature -- Conversion
prepare (page: CMS_HTML_PAGE)
do
page.register_variable (page, "page")
page.register_variable (page.regions, "regions")
across
page.regions as ic
loop
page.register_variable (ic.item, "region_" + ic.key)
end
end
page_html (page: CMS_HTML_PAGE): STRING_8
local
l_page_inspector: detachable SMARTY_CMS_HTML_PAGE_INSPECTOR
l_regions_inspector: detachable SMARTY_CMS_REGIONS_INSPECTOR
l_table_inspector: detachable STRING_TABLE_OF_STRING_INSPECTOR
do
prepare (page)
create l_page_inspector.register (page.generating_type)
if attached {CMS_RESPONSE} page.variables.item ("cms") as l_cms then
if attached l_cms.regions as l_regions then
create l_regions_inspector.register (l_regions.generating_type)
end
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)
page_template.prepare (page)
Result := page_template.to_html (page)
-- Clean template inspector.
if l_regions_inspector /= Void then
l_regions_inspector.unregister
end
if l_page_inspector /= Void then
l_page_inspector.unregister
end
l_table_inspector.unregister
end
feature {NONE} -- Internal
internal_regions: detachable like regions
internal_page_template: detachable like page_template
invariant
attached internal_page_template as inv_p implies inv_p.theme = Current
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,56 +0,0 @@
note
description: "Summary description for {STRING_TABLE_OF_STRING_INSPECTOR}."
author: ""
date: "$Date: 2014-12-05 22:39:27 +0100 (ven., 05 déc. 2014) $"
revision: "$Revision: 96260 $"
class
STRING_TABLE_OF_STRING_INSPECTOR
inherit
TEMPLATE_INSPECTOR
redefine
internal_data
end
create
register
feature {TEMPLATE_ROUTINES}
internal_data (field_name: STRING; obj: detachable ANY): detachable CELL [detachable ANY]
-- Return object in a cell
-- If not handled by this inspector, return Void
local
l_fn: STRING
utf: UTF_CONVERTER
do
if attached {STRING_TABLE [detachable READABLE_STRING_GENERAL]} obj as l_regions then
l_fn := field_name.as_lower
if l_fn.is_case_insensitive_equal ("count") then
Result := cell_of (l_regions.count)
elseif attached l_regions.item (l_fn) as v then
if attached {READABLE_STRING_32} v as v32 then
if attached v32.is_valid_as_string_8 then
Result := cell_of (v.to_string_8)
else
Result := cell_of (utf.escaped_utf_32_string_to_utf_8_string_8 (v32))
end
else
Result := cell_of (v.to_string_8)
end
end
end
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end