Compare commits

..

2 Commits

Author SHA1 Message Date
7c1d1325eb Adapt to EWF concurrent version. 2015-04-02 18:38:12 +02:00
8382edf9d7 Adapted ROC cms library and example to upcoming concurrency compliant EWF.
(SCOOP support)
2015-03-25 22:32:10 +01:00
188 changed files with 2591 additions and 9071 deletions

4
.gitignore vendored
View File

@@ -2,6 +2,4 @@ EIFGENs
*.swp *.swp
*.log* *.log*
*.rc *.rc
*.bak *.bak
*.sqlite
Thumbs.db

View File

@@ -2,31 +2,31 @@
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<target name="cms"> <target name="cms">
<root all_classes="true"/> <root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional"> <option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<mapping old_name="CMS_LAYOUT" new_name="CMS_ENVIRONMENT"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms_app_env" location=".\library\app_env\app_env-safe.ecf"/>
<library name="cms_model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="config" location=".\library\configuration\config-safe.ecf"/> <library name="config" location=".\library\configuration\config-safe.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/> <library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/> <library name="error" location="$EWF_LIBRARY\library\utility\general\error\error-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <library name="http" location="$EWF_LIBRARY\library\network\protocol\http\http-safe.ecf"/>
<library name="i18n" location="$ISE_LIBRARY\library\i18n\i18n-safe.ecf"/> <library name="http_authorization" location="$EWF_LIBRARY\library\server\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location=".\library\layout\layout-safe.ecf"/>
<library name="cms_model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/> <library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/> <library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/> <library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/> <library name="wsf_extension" location="$EWF_LIBRARY\library\server\wsf\wsf_extension-safe.ecf" readonly="false"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/> <library name="wsf_html" location="$EWF_LIBRARY\library\server\wsf_html\wsf_html-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target> </target>
</system> </system>

30
cms.ecf
View File

@@ -2,31 +2,31 @@
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<target name="cms"> <target name="cms">
<root all_classes="true"/> <root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" void_safety="none" syntax="transitional"> <option warning="true" full_class_checking="false" void_safety="none" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<mapping old_name="CMS_LAYOUT" new_name="CMS_ENVIRONMENT"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="config" location=".\library\configuration\config.ecf"/> <library name="config" location=".\library\configuration\config.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf" readonly="false"/> <library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder.ecf" readonly="false"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/> <library name="error" location="$EWF_LIBRARY\library\utility\general\error\error.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/> <library name="http" location="$EWF_LIBRARY\library\network\protocol\http\http.ecf"/>
<library name="i18n" location="$ISE_LIBRARY\library\i18n\i18n.ecf"/> <library name="http_authorization" location="$EWF_LIBRARY\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="cms_app_env" location=".\library\app_env\app_env.ecf"/> <library name="layout" location=".\library\layout\layout.ecf"/>
<library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/> <library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/> <library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/> <library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/> <library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf.ecf"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html.ecf" readonly="false"/> <library name="wsf_extension" location="$EWF_LIBRARY\library\server\wsf\wsf_extension.ecf" readonly="false"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/> <library name="wsf_html" location="$EWF_LIBRARY\library\server\wsf_html\wsf_html.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target> </target>
</system> </system>

View File

@@ -1,55 +1,58 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo">
<description>Example/demo for Eiffel ROC CMS library</description>
<target name="common" abstract="true"> <target name="common" abstract="true">
<file_rule> <file_rule>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude> <exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional"> <option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="none"/> <setting name="console_application" value="true"/>
<setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/> <library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_app_env" location="..\..\library\app_env\app_env-safe.ecf" readonly="false"/>
<library name="cms_basic_auth_module" location="..\..\modules\basic_auth\basic_auth-safe.ecf" readonly="false"/>
<library name="cms_blog_module" location="modules\blog\cms_blog_module-safe.ecf" readonly="false"/>
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/> <library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/> <library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/> <library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
<!--
<library name="persistence_mysql" location="..\..\library\persistence\mysql\persistence_mysql-safe.ecf" readonly="false"/>
-->
<library name="persistence_sqlite" location="..\..\library\persistence\sqlite\persistence_sqlite-safe.ecf" readonly="false"/> <library name="persistence_sqlite" location="..\..\library\persistence\sqlite\persistence_sqlite-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/> <library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/> <library name="wsf_extension" location="$EWF_LIBRARY\library\server\wsf\wsf_extension-safe.ecf" readonly="false"/>
</target> </target>
<target name="demo_any" extends="common"> <target name="demo_any" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/> <root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/> <setting name="concurrency" value="scoop"/>
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/> <library name="cgi" location="$EWF_LIBRARY\library\server\wsf\connector\cgi-safe.ecf"/>
<library name="nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\nino-safe.ecf"/> <library name="libfcgi" location="$EWF_LIBRARY\library\server\wsf\connector\libfcgi-safe.ecf"/>
<library name="nino" location="$EWF_LIBRARY\library\server\wsf\connector\nino-safe.ecf"/>
<library name="standalone" location="$EWF_LIBRARY\library\server\wsf\connector\standalone-safe.ecf"/>
<cluster name="launcher" location=".\launcher\any\" recursive="true"/> <cluster name="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
<target name="demo_standalone" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<setting name="concurrency" value="scoop"/>
<library name="default_standalone" location="$EWF_LIBRARY\library\server\wsf\default\standalone-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_nino" extends="common"> <target name="demo_nino" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/> <root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<setting name="concurrency" value="none"/> <setting name="concurrency" value="none"/>
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/> <library name="default_nino" location="$EWF_LIBRARY\library\server\wsf\default\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/> <cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
<target name="demo_cgi" extends="common"> <target name="demo_cgi" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/> <root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\cgi-safe.ecf"/> <library name="default_cgi" location="$EWF_LIBRARY\library\server\wsf\default\cgi-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/> <cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
<target name="demo_libfcgi" extends="common"> <target name="demo_libfcgi" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/> <root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/> <library name="default_libfcgi" location="$EWF_LIBRARY\library\server\wsf\default\libfcgi-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/> <cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>

View File

@@ -8,10 +8,10 @@ note
revision: "$Revision: 36 $" revision: "$Revision: 36 $"
class class
APPLICATION_LAUNCHER APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end]
inherit inherit
APPLICATION_LAUNCHER_I APPLICATION_LAUNCHER_I [G]
feature -- Custom feature -- Custom

View File

@@ -10,24 +10,28 @@ note
revision: "$Revision: 36 $" revision: "$Revision: 36 $"
deferred class deferred class
APPLICATION_LAUNCHER_I APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end]
inherit inherit
SHARED_EXECUTION_ENVIRONMENT SHARED_EXECUTION_ENVIRONMENT
feature -- Execution feature -- Execution
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local local
nature: like launcher_nature nature: like launcher_nature
do do
nature := launcher_nature nature := launcher_nature
if nature = Void or else nature = nature_nino then if nature = Void then
launch_nino (a_service, opts) launch_standalone (opts)
elseif nature = nature_standalone then
launch_standalone (opts)
elseif nature = nature_nino then
launch_nino (opts)
elseif nature = nature_cgi then elseif nature = nature_cgi then
launch_cgi (a_service, opts) launch_cgi (opts)
elseif nature = nature_libfcgi then elseif nature = nature_libfcgi then
launch_libfcgi (a_service, opts) launch_libfcgi (opts)
else else
-- bye bye -- bye bye
(create {EXCEPTIONS}).die (-1) (create {EXCEPTIONS}).die (-1)
@@ -43,14 +47,16 @@ feature {NONE} -- Access
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time. --| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
local local
p: PATH p: PATH
l_entry_name: READABLE_STRING_32
ext: detachable READABLE_STRING_32 ext: detachable READABLE_STRING_32
do do
create p.make_from_string (execution_environment.arguments.command_name) create p.make_from_string (execution_environment.arguments.command_name)
if attached p.entry as l_entry then if attached p.entry as l_entry then
ext := l_entry.extension ext := l_entry.extension
end end
if ext /= Void then if ext /= Void then
if ext.same_string (nature_standalone) then
Result := nature_standalone
end
if ext.same_string (nature_nino) then if ext.same_string (nature_nino) then
Result := nature_nino Result := nature_nino
end end
@@ -61,39 +67,58 @@ feature {NONE} -- Access
Result := nature_libfcgi Result := nature_libfcgi
end end
end end
Result := default_nature
end
feature {NONE} -- standalone
nature_standalone: STRING = "standalone"
launch_standalone (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_STANDALONE_SERVICE_LAUNCHER [G]
do
create launcher.make_and_launch (opts)
end end
feature {NONE} -- nino feature {NONE} -- nino
nature_nino: STRING = "nino" nature_nino: STRING = "nino"
launch_nino (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) launch_nino (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local local
launcher: WSF_NINO_SERVICE_LAUNCHER launcher: WSF_NINO_SERVICE_LAUNCHER [G]
do do
create launcher.make_and_launch (a_service, opts) create launcher.make_and_launch (opts)
end end
feature {NONE} -- cgi feature {NONE} -- cgi
nature_cgi: STRING = "cgi" nature_cgi: STRING = "cgi"
launch_cgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) launch_cgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local local
launcher: WSF_CGI_SERVICE_LAUNCHER launcher: WSF_CGI_SERVICE_LAUNCHER [G]
do do
create launcher.make_and_launch (a_service, opts) create launcher.make_and_launch (opts)
end end
feature {NONE} -- libfcgi feature {NONE} -- libfcgi
nature_libfcgi: STRING = "libfcgi" nature_libfcgi: STRING = "libfcgi"
launch_libfcgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) launch_libfcgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local local
launcher: WSF_LIBFCGI_SERVICE_LAUNCHER launcher: WSF_LIBFCGI_SERVICE_LAUNCHER [G]
do do
create launcher.make_and_launch (a_service, opts) create launcher.make_and_launch (opts)
end
feature -- Default
default_nature: STRING
do
Result := nature_standalone
end end

View File

@@ -8,10 +8,10 @@ note
revision: "$Revision: 36 $" revision: "$Revision: 36 $"
class class
APPLICATION_LAUNCHER APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end]
inherit inherit
APPLICATION_LAUNCHER_I APPLICATION_LAUNCHER_I [G]
feature -- Custom feature -- Custom

View File

@@ -10,15 +10,15 @@ note
revision: "$Revision: 96596 $" revision: "$Revision: 96596 $"
deferred class deferred class
APPLICATION_LAUNCHER_I APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end]
feature -- Execution feature -- Execution
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local local
launcher: WSF_DEFAULT_SERVICE_LAUNCHER launcher: WSF_DEFAULT_SERVICE_LAUNCHER [G]
do do
create {WSF_DEFAULT_SERVICE_LAUNCHER} launcher.make_and_launch (a_service, opts) create launcher.make_and_launch (opts)
end end
end end

View File

@@ -1,112 +0,0 @@
note
description: "Summary description for {CMS_BLOG}."
date: "$Date$"
revision: "$Revision$"
class
CMS_BLOG
inherit
CMS_NODE
redefine
make_empty,
import_node
end
create
make_empty,
make
feature {NONE} -- Initialization
make_empty
do
Precursor
end
feature -- Conversion
import_node (a_node: CMS_NODE)
-- <Precursor>
do
Precursor (a_node)
if attached {CMS_BLOG} a_node as l_blog then
if attached l_blog.tags as l_tags then
across
l_tags as ic
loop
add_tag (ic.item)
end
end
end
end
feature -- Access
content_type: READABLE_STRING_8
once
Result := {CMS_BLOG_NODE_TYPE}.name
end
feature -- Access: node
summary: detachable READABLE_STRING_8
-- A short summary of the node.
content: detachable READABLE_STRING_8
-- Content of the node.
format: detachable READABLE_STRING_8
-- Format associated with `content' and `summary'.
-- For example: text, mediawiki, html, etc
feature -- Access: blog
tags: detachable ARRAYED_LIST [READABLE_STRING_32]
-- Optional tags
feature -- Element change: node
set_content (a_content: like content; a_summary: like summary; a_format: like format)
do
content := a_content
summary := a_summary
format := a_format
end
feature -- Element change: blog
add_tag (a_tag: READABLE_STRING_32)
-- Set `parent' to `a_page'
require
not a_tag.is_whitespace
local
l_tags: like tags
do
l_tags := tags
if l_tags = Void then
create l_tags.make (1)
tags := l_tags
end
l_tags.force (a_tag)
end
set_tags_from_string (a_tags: READABLE_STRING_32)
local
t: STRING_32
do
tags := Void
across
a_tags.split (',') as ic
loop
t := ic.item
t.left_adjust
t.right_adjust
if not t.is_whitespace then
add_tag (t)
end
end
end
end

View File

@@ -1,118 +0,0 @@
note
description: "API to handle nodes of type blog. Extends the node API."
author: "Dario Bösch <daboesch@student.ethz.ch"
date: "$Date: 2015-05-21 14:46:00 +0100$"
revision: "$Revision: 96616 $"
class
CMS_BLOG_API
inherit
CMS_MODULE_API
rename
make as make_with_cms_api
redefine
initialize
end
REFACTORING_HELPER
create
make
feature {NONE} -- Initialization
make (a_api: CMS_API; a_node_api: CMS_NODE_API)
-- (from CMS_MODULE_API)
-- (export status {NONE})
do
node_api := a_node_api
make_with_cms_api (a_api)
end
initialize
-- <Precursor>
do
Precursor
-- Create the node storage for type blog
if attached {CMS_STORAGE_SQL_I} storage as l_storage_sql then
create {CMS_BLOG_STORAGE_SQL} blog_storage.make (l_storage_sql)
else
create {CMS_BLOG_STORAGE_NULL} blog_storage.make
end
-- initialize_node_types
end
feature {CMS_API_ACCESS, CMS_MODULE, CMS_API} -- Restricted access
node_api: CMS_NODE_API
feature {CMS_MODULE} -- Access nodes storage.
blog_storage: CMS_BLOG_STORAGE_I
feature -- Configuration of blog handlers
entries_per_page : NATURAL_32 = 2
-- The numbers of posts that are shown on one page. If there are more post a pagination is generated
--| For test reasons this is 2, so we don't have to create a lot of blog entries.
--| TODO: Set to bigger constant.
feature -- Access node
blogs_count: INTEGER_64
-- Number of nodes of type blog.
do
Result := blog_storage.blogs_count
end
blogs_count_from_user (a_user: CMS_USER): INTEGER_64
-- Number of nodes of type blog from user with `a_user_id'.
require
has_id: a_user.has_id
do
Result := blog_storage.blogs_count_from_user (a_user)
end
blogs_order_created_desc: LIST [CMS_BLOG]
-- List of nodes ordered by creation date (descending)
do
Result := nodes_to_blogs (blog_storage.blogs)
end
blogs_order_created_desc_limited (a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_BLOG]
-- List of nodes ordered by creation date and limited by limit and offset
do
-- load all posts and add the authors to each post
Result := nodes_to_blogs (blog_storage.blogs_limited (a_limit, a_offset))
end
blogs_from_user_order_created_desc_limited (a_user: CMS_USER; a_limit: NATURAL_32; a_offset: NATURAL_32) : LIST [CMS_BLOG]
-- List of nodes ordered by creation date and limited by limit and offset
require
has_id: a_user.has_id
do
-- load all posts and add the authors to each post
Result := nodes_to_blogs (blog_storage.blogs_from_user_limited (a_user, a_limit, a_offset))
end
feature {NONE} -- Helpers
nodes_to_blogs (a_nodes: LIST [CMS_NODE]): ARRAYED_LIST [CMS_BLOG]
-- Convert list of nodes into a list of blog when possible.
do
create {ARRAYED_LIST [CMS_BLOG]} Result.make (a_nodes.count)
if attached node_api as l_node_api then
across
a_nodes as ic
loop
if attached {CMS_BLOG} l_node_api.full_node (ic.item) as l_blog then
Result.force (l_blog)
end
end
end
end
end

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_blog_module" uuid="C92F6E1E-2222-4414-9B6E-AA680E324D42" library_target="cms_blog_module">
<target name="cms_blog_module">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="cms_node_module" location="..\..\..\..\modules\node\node-safe.ecf" readonly="false"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<cluster name="src" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -1,157 +0,0 @@
note
description: "Displays all posts (pages with type blog). It's possible to list posts by user."
author: "Dario Bösch <daboesch@student.ethz.ch>"
date: "$Date: 2015-05-22 15:13:00 +0100 (lun., 18 mai 2015) $"
revision: "$Revision 96616$"
class
CMS_BLOG_MODULE
inherit
CMS_MODULE
rename
module_api as blog_api
redefine
register_hooks,
initialize,
is_installed,
install,
blog_api
end
CMS_HOOK_MENU_SYSTEM_ALTER
create
make
feature {NONE} -- Initialization
make
do
name := "Blog demo module"
version := "1.0"
description := "Service to demonstrate new node for blog"
package := "demo"
end
feature {CMS_API} -- Module Initialization
initialize (api: CMS_API)
-- <Precursor>
local
ct: CMS_BLOG_NODE_TYPE
do
Precursor (api)
if attached {CMS_NODE_API} api.module_api ({NODE_MODULE}) as l_node_api then
create blog_api.make (api, l_node_api)
node_api := l_node_api
-- Depends on {NODE_MODULE}
create ct
l_node_api.add_content_type (ct)
l_node_api.add_content_type_webform_manager (create {CMS_BLOG_NODE_TYPE_WEBFORM_MANAGER}.make (ct))
-- Add support for CMS_BLOG, which requires a storage extension to store the optional "tags" value
-- For now, we only have extension based on SQL statement.
if attached {CMS_NODE_STORAGE_SQL} l_node_api.node_storage as l_sql_node_storage then
l_sql_node_storage.register_node_storage_extension (create {CMS_NODE_STORAGE_SQL_BLOG_EXTENSION}.make (l_sql_node_storage))
end
end
end
feature {CMS_API} -- Module management
is_installed (api: CMS_API): BOOLEAN
-- Is Current module installed?
do
Result := attached api.storage.custom_value ("is_initialized", "module-" + name) as v and then v.is_case_insensitive_equal_general ("yes")
end
install (api: CMS_API)
local
sql: STRING
do
-- Schema
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
if not l_sql_storage.sql_table_exists ("blog_post_nodes") then
sql := "[
CREATE TABLE "blog_post_nodes"(
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
"revision" INTEGER,
"tags" VARCHAR(255)
);
]"
l_sql_storage.sql_execute_script (sql)
if l_sql_storage.has_error then
api.logger.put_error ("Could not initialize database for blog module", generating_type)
end
end
api.storage.set_custom_value ("is_initialized", "module-" + name, "yes")
end
end
feature {CMS_API} -- Access: API
blog_api: detachable CMS_BLOG_API
-- <Precursor>
node_api: detachable CMS_NODE_API
feature -- Access: router
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
-- <Precursor>
do
if attached blog_api as l_blog_api then
configure_web (a_api, l_blog_api, a_router)
else
-- Issue with api/dependencies,
-- thus Current module should not be used!
-- thus no url mapping
end
end
configure_web (a_api: CMS_API; a_blog_api: CMS_BLOG_API; a_router: WSF_ROUTER)
-- Configure router mapping for web interface.
local
l_blog_handler: BLOG_HANDLER
l_blog_user_handler: BLOG_USER_HANDLER
l_uri_mapping: WSF_URI_MAPPING
do
-- TODO: for now, focused only on web interface, add REST api later. [2015-May-18]
create l_blog_handler.make (a_api, a_blog_api)
create l_blog_user_handler.make (a_api, a_blog_api)
-- Let the class BLOG_HANDLER handle the requests on "/blogs"
create l_uri_mapping.make_trailing_slash_ignored ("/blogs", l_blog_handler)
a_router.map_with_request_methods (l_uri_mapping, a_router.methods_get)
-- We can add a page number after /blogs/ to get older posts
a_router.handle_with_request_methods ("/blogs/page/{page}", l_blog_handler, a_router.methods_get)
-- If a user id is given route with blog user handler
--| FIXME: maybe /user/{user}/blogs/ would be better.
a_router.handle_with_request_methods ("/blogs/user/{user}", l_blog_user_handler, a_router.methods_get)
-- If a user id is given we also want to allow different pages
--| FIXME: what about /user/{user}/blogs/?page={page} ?
a_router.handle_with_request_methods ("/blogs/user/{user}/page/{page}", l_blog_user_handler, a_router.methods_get)
end
feature -- Hooks
register_hooks (a_response: CMS_RESPONSE)
do
a_response.subscribe_to_menu_system_alter_hook (Current)
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
do
-- Add the link to the blog to the main menu
create lnk.make ("Blogs", "/blogs/")
a_menu_system.primary_menu.extend (lnk)
end
end

View File

@@ -1,64 +0,0 @@
note
description: "Summary description for {CMS_BLOG_NODE_TYPE}."
date: "$Date$"
revision: "$Revision$"
class
CMS_BLOG_NODE_TYPE
inherit
CMS_NODE_TYPE [CMS_BLOG]
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
create {ARRAYED_LIST [like available_formats.item]} available_formats.make (4)
available_formats.extend (create {PLAIN_TEXT_CONTENT_FORMAT})
available_formats.extend (create {FILTERED_HTML_CONTENT_FORMAT})
available_formats.extend (create {FULL_HTML_CONTENT_FORMAT})
available_formats.extend (create {CMS_EDITOR_CONTENT_FORMAT})
end
feature -- Access
name: STRING = "blog"
-- Internal name.
title: STRING_32 = "Blog"
-- Human readable name.
description: STRING_32 = "Content published as a blog post."
-- Optional description
feature -- Access
available_formats: LIST [CONTENT_FORMAT]
-- Available formats for Current type.
feature -- Factory
new_node_with_title (a_title: READABLE_STRING_32; a_partial_node: detachable CMS_NODE): like new_node
-- New node with `a_title' and fill from partial `a_partial_node' if set.
do
create Result.make (a_title)
if a_partial_node /= Void then
Result.import_node (a_partial_node)
Result.set_title (a_title)
end
end
new_node (a_partial_node: detachable CMS_NODE): CMS_BLOG
-- New node based on partial `a_partial_node', or from none.
do
create Result.make_empty
if a_partial_node /= Void then
Result.import_node (a_partial_node)
end
end
end

View File

@@ -1,109 +0,0 @@
note
description: "Summary description for {CMS_BLOG_NODE_TYPE_WEBFORM_MANAGER}."
date: "$Date$"
revision: "$Revision$"
class
CMS_BLOG_NODE_TYPE_WEBFORM_MANAGER
inherit
CMS_NODE_TYPE_WEBFORM_MANAGER [CMS_BLOG]
redefine
content_type,
populate_form,
update_node,
new_node,
append_html_output_to
end
create
make
feature -- Access
content_type: CMS_BLOG_NODE_TYPE
-- Associated content type.
feature -- form
populate_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
local
ti: WSF_FORM_TEXT_INPUT
s: STRING_32
do
Precursor (response, f, a_node)
create ti.make ("tags")
ti.set_label ("Tags")
ti.set_size (70)
if
a_node /= Void and then
attached {CMS_BLOG} a_node as a_blog and then
attached a_blog.tags as l_tags
then
create s.make_empty
across
l_tags as ic
loop
if not s.is_empty then
s.append_character (',')
end
s.append (ic.item)
end
ti.set_text_value (s)
end
ti.set_is_required (False)
f.extend (ti)
end
update_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: CMS_NODE)
do
Precursor (response, fd, a_node)
if attached fd.string_item ("tags") as l_tags then
if attached {CMS_BLOG} a_node as l_blog then
l_blog.set_tags_from_string (l_tags)
end
end
end
new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable like new_node): like content_type.new_node
-- <Precursor>
do
Result := Precursor (response, fd, a_node)
if attached fd.string_item ("tags") as l_tags then
Result.set_tags_from_string (l_tags)
end
end
feature -- Output
append_html_output_to (a_node: CMS_NODE; a_response: NODE_RESPONSE)
-- <Precursor>
local
s: STRING
do
Precursor (a_node, a_response)
if attached a_response.main_content as l_main_content then
s := l_main_content
else
create s.make_empty
end
if attached {CMS_BLOG} a_node as l_blog_post then
if attached l_blog_post.tags as l_tags then
s.append ("<div><strong>Tags:</strong> ")
across
l_tags as ic
loop
s.append ("<span class=%"tag%">")
s.append (a_response.html_encoded (ic.item))
s.append ("</span> ")
end
s.append ("</div>")
end
end
a_response.set_main_content (s)
end
end

View File

@@ -1,115 +0,0 @@
note
description: "Storage extension for Blog nodes."
date: "$Date$"
revision: "$Revision$"
class
CMS_NODE_STORAGE_SQL_BLOG_EXTENSION
inherit
CMS_NODE_STORAGE_EXTENSION [CMS_BLOG]
CMS_PROXY_STORAGE_SQL
rename
sql_storage as node_storage
redefine
node_storage
end
create
make
feature {NONE} -- Initialization
node_storage: CMS_NODE_STORAGE_SQL
-- <Precursor>
feature -- Access
content_type: STRING
once
Result := {CMS_BLOG_NODE_TYPE}.name
end
feature -- Persistence
store (a_node: CMS_BLOG)
local
l_parameters: STRING_TABLE [detachable ANY]
l_new_tags: detachable STRING_32
l_previous_tags: detachable STRING_32
l_update: BOOLEAN
do
error_handler.reset
if attached api as l_api then
l_api.logger.put_information (generator + ".store", Void)
end
create l_parameters.make (2)
l_parameters.put (a_node.id, "nid")
l_parameters.put (a_node.revision, "revision")
sql_query (sql_select_blog_data, l_parameters)
if not has_error then
if sql_rows_count = 1 then
l_previous_tags := sql_read_string_32 (3)
l_update := True
end
if attached a_node.tags as l_tags and then not l_tags.is_empty then
create l_new_tags.make (0)
across
l_tags as ic
loop
if not l_new_tags.is_empty then
l_new_tags.append_character (',')
end
l_new_tags.append (ic.item)
end
else
l_new_tags := Void
end
l_parameters.put (l_new_tags, "tags")
if l_update and l_new_tags /~ l_previous_tags then
sql_change (sql_update_blog_data, l_parameters)
elseif l_new_tags /= Void then
sql_change (sql_insert_blog_data, l_parameters)
else
-- no blog data, means everything is empty.
end
end
end
load (a_node: CMS_BLOG)
local
l_parameters: STRING_TABLE [ANY]
n: INTEGER
do
error_handler.reset
create l_parameters.make (2)
l_parameters.put (a_node.id, "nid")
l_parameters.put (a_node.revision, "revision")
sql_query (sql_select_blog_data, l_parameters)
if not has_error then
n := sql_rows_count
if n = 1 then
-- nid, revision, parent
if
attached sql_read_string_32 (3) as l_tags and then
not l_tags.is_whitespace
then
-- FIXME: find a simple way to access the declared content types.
a_node.set_tags_from_string (l_tags)
end
else
check unique_data: n = 0 end
end
end
end
feature -- SQL
sql_select_blog_data: STRING = "SELECT nid, revision, tags FROM blog_post_nodes WHERE nid =:nid AND revision=:revision;"
sql_insert_blog_data: STRING = "INSERT INTO blog_post_nodes (nid, revision, tags) VALUES (:nid, :revision, :tags);"
sql_update_blog_data: STRING = "UPDATE blog_post_nodes SET nid=:nid, revision=:revision, tags=:tags WHERE nid=:nid AND revision=:revision;"
end

View File

@@ -1,279 +0,0 @@
note
description: "Request handler related to /blogs and /blogs/{page}. Displays all posts in the blog."
author: "Dario Bösch <daboesch@student.ethz.ch>"
date: "$Date: 2015-05-18 13:49:00 +0100 (lun., 18 mai 2015) $"
revision: "$9661667$"
class
BLOG_HANDLER
inherit
CMS_BLOG_HANDLER
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
end
REFACTORING_HELPER
CMS_API_ACCESS
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for any kind of mapping.
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI mapping.
do
execute (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI-template mapping.
do
execute (req, res)
end
feature -- Global Variables
page_number: NATURAL_32
-- Current page number.
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
-- Read page number from path parameter.
page_number := page_number_path_parameter (req)
-- Responding with `main_content_html (l_page)'.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.set_main_content (main_content_html (l_page))
l_page.execute
end
feature -- Query
posts: LIST [CMS_NODE]
-- Blog posts to display on given page ordered by date (descending).
do
Result := blog_api.blogs_order_created_desc_limited (
entries_per_page,
entries_per_page * (page_number - 1)
)
end
multiple_pages_needed : BOOLEAN
-- Return if more that one page is needed to display posts.
do
Result := entries_per_page < total_entries
end
pages_count: NATURAL_32
-- Number of pages needed to display all posts.
require
entries_per_page > 0
local
tmp: REAL_32
do
tmp := total_entries.to_real_32 / entries_per_page.to_real_32;
Result := tmp.ceiling.to_natural_32
end
page_number_path_parameter (req: WSF_REQUEST): NATURAL_32
-- Page number from path /blogs/{page}.
-- Unsigned integer since negative pages are not allowed.
local
s: STRING
do
Result := 1 -- default if not get variable is set
if attached {WSF_STRING} req.path_parameter ("page") as p_page then
s := p_page.value
if s.is_natural_32 then
if s.to_natural_32 > 1 then
Result := s.to_natural_32
end
end
end
end
total_entries: NATURAL_32
-- Total number of entries/posts.
do
Result := blog_api.blogs_count.to_natural_32
end
feature -- HTML Output
frozen main_content_html (page: CMS_RESPONSE): STRING
-- Content of the page as a html string.
do
create Result.make_empty
append_main_content_html_to (page, Result)
end
append_main_content_html_to (page: CMS_RESPONSE; a_output: STRING)
-- Append to `a_output, the content of the page as a html string.
local
n: CMS_NODE
lnk: CMS_LOCAL_LINK
do
-- Output the title. If more than one page, also output the current page number
append_page_title_html_to (a_output)
-- Get the posts from the current page (given by page number and entries per page)
-- Start list of posts
a_output.append ("<ul class=%"cms_blog_nodes%">%N")
across
posts as ic
loop
n := ic.item
lnk := blog_api.node_api.node_link (n)
a_output.append ("<li class=%"cms_type_"+ n.content_type +"%">")
-- Output the creation date
append_creation_date_html_to (n, a_output)
-- Output the author of the post
append_author_html_to (n, a_output)
-- Output the title of the post as a link (to the detail page)
append_title_html_to (n, page, a_output)
-- Output the summary of the post and a more link to the detail page
append_summary_html_to (n, page, a_output)
a_output.append ("</li>%N")
end
-- End of post list
a_output.append ("</ul>%N")
-- Pagination (older and newer links)
append_pagination_html_to (a_output)
end
append_page_title_html_to (a_output: STRING)
-- Append the title of the page as a html string to `a_output'.
-- It shows the current page number.
do
a_output.append ("<h2>Blog")
if multiple_pages_needed then
a_output.append (" (Page " + page_number.out + " of " + pages_count.out + ")")
end
a_output.append ("</h2>")
end
append_creation_date_html_to (n: CMS_NODE; a_output: STRING)
-- Append the creation date as a html string to `a_output'.
local
hdate: HTTP_DATE
do
if attached n.creation_date as l_modified then
create hdate.make_from_date_time (l_modified)
hdate.append_to_yyyy_mmm_dd_string (a_output)
a_output.append (" ")
end
end
append_author_html_to (n: CMS_NODE; a_output: STRING)
-- Append to `a_output', the author of node `n' as html link to author's posts.
do
if attached n.author as l_author then
a_output.append ("by ")
a_output.append ("<a class=%"blog_user_link%" href=%"/blogs/user/" + l_author.id.out + "%">" + l_author.name + "</a>")
end
end
append_title_html_to (n: CMS_NODE; page: CMS_RESPONSE; a_output: STRING)
-- Append to `a_output', the title of node `n' as html link to detail page.
local
lnk: CMS_LOCAL_LINK
do
lnk := blog_api.node_api.node_link (n)
a_output.append ("<span class=%"blog_title%">")
a_output.append (page.link (lnk.title, lnk.location, Void))
a_output.append ("</span>")
end
append_summary_html_to (n: CMS_NODE; page: CMS_RESPONSE; a_output: STRING)
-- returns a html string with the summary of the node and a link to the detail page
local
lnk: CMS_LOCAL_LINK
do
if attached n.summary as l_summary then
lnk := blog_api.node_api.node_link (n)
a_output.append ("<p class=%"blog_list_summary%">")
if attached api.format (n.format) as f then
a_output.append (f.formatted_output (l_summary))
else
a_output.append (page.formats.default_format.formatted_output (l_summary))
end
a_output.append ("<br />")
a_output.append (page.link ("See more...", lnk.location, Void))
a_output.append ("</p>")
end
end
append_pagination_html_to (a_output: STRING)
-- Append to `a_output' with the pagination links (if necessary).
local
tmp: NATURAL_32
do
if multiple_pages_needed then
a_output.append ("<div class=%"pagination%">")
-- If exist older posts show link to next page
if page_number < pages_count then
tmp := page_number + 1
a_output.append (" <a class=%"blog_older_posts%" href=%"" + base_path + "/page/" + tmp.out + "%"><< Older Posts</a> ")
end
-- Delimiter
if page_number < pages_count AND page_number > 1 then
a_output.append (" | ")
end
-- If exist newer posts show link to previous page
if page_number > 1 then
tmp := page_number -1
a_output.append (" <a class=%"blog_newer_posts%" href=%"" + base_path + "/page/" + tmp.out + "%">Newer Posts >></a> ")
end
a_output.append ("</div>")
end
end
base_path : STRING
-- the path to the page that lists all blogs
do
Result := "/blogs"
end
end

View File

@@ -1,150 +0,0 @@
note
description: "[
Request handler related to
/blogs/user/{id}/
or /blogs/user/{id}/page/{page}.
Displays all posts of the given user
]"
author: "Dario Bösch <daboesch@student.ethz.ch>"
date: "$Date: 2015-05-22 15:13:00 +0100 (lun., 18 mai 2015) $"
revision: "$Revision 96616$"
class
BLOG_USER_HANDLER
inherit
BLOG_HANDLER
redefine
do_get,
posts,
total_entries,
append_page_title_html_to,
base_path
end
create
make
feature -- Global Variables
user : detachable CMS_USER
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_error: NOT_FOUND_ERROR_CMS_RESPONSE
do
user := Void
if attached user_from_request (req) as l_user then
user := l_user
-- Output the results, similar as in the blog hanlder (but with other queries)
Precursor (req, res)
else
-- Throw a bad request error because the user is not valid
create l_error.make (req, res, api)
l_error.set_main_content ("<h1>Error</h1>User with id " + user_id_path_parameter (req).out + " doesn't exist!")
l_error.execute
end
end
feature -- Query
user_valid (req: WSF_REQUEST) : BOOLEAN
-- Returns true if a valid user id is given and a user with this id exists,
-- otherwise returns false.
local
user_id: INTEGER_32
do
user_id := user_id_path_parameter (req)
if user_id <= 0 then
-- Given user id is not valid
Result := False
else
--Check if user with user_id exists
Result := api.user_api.user_by_id (user_id) /= Void
end
end
user_from_request (req: WSF_REQUEST): detachable CMS_USER
-- Eventual user with given id in the path of request `req'.
local
uid: like user_id_path_parameter
do
uid := user_id_path_parameter (req)
if uid > 0 then
Result := api.user_api.user_by_id (uid)
else
-- Missing or invalid user id.
end
end
user_id_path_parameter (req: WSF_REQUEST): INTEGER_32
-- User id from path /blogs/{user}.
-- Unsigned integer since negative ids are not allowed.
-- If no valid id can be read it returns -1
local
s: STRING
do
Result := -1
if attached {WSF_STRING} req.path_parameter ("user") as l_user_id then
if l_user_id.is_integer then
Result := l_user_id.integer_value
end
end
end
posts: LIST [CMS_BLOG]
-- Blog posts to display on given page.
-- Filters out the posts of the current user.
do
if attached user as l_user then
Result := blog_api.blogs_from_user_order_created_desc_limited (l_user, entries_per_page, entries_per_page * (page_number - 1))
else
create {ARRAYED_LIST [CMS_BLOG]} Result.make (0)
end
end
total_entries : NATURAL_32
-- Returns the number of total entries/posts of the current user
do
if attached user as l_user then
Result := blog_api.blogs_count_from_user (l_user).to_natural_32
else
Result := Precursor
end
end
feature -- HTML Output
append_page_title_html_to (a_output: STRING)
-- Returns the title of the page as a html string. It shows the current page number and the name of the current user
do
a_output.append ("<h2>Posts from ")
if attached user as l_user then
a_output.append (l_user.name)
else
a_output.append ("unknown user")
end
if multiple_pages_needed then
a_output.append (" (Page " + page_number.out + " of " + pages_count.out + ")")
-- Get the posts from the current page (limited by entries per page)
end
a_output.append ("</h2>")
end
base_path : STRING
-- Path to page listing all blogs.
-- If user is logged in, include user id
do
if attached user as l_user then
Result := "/blogs/user/" + l_user.id.out
else
Result := precursor
end
end
end

View File

@@ -1,23 +0,0 @@
note
description: "Deferred request handler related to /blogs/... Has an own blog api."
author: "Dario Bösch <daboesch@student.ethz.ch>"
date: "$Date: 2015-05-18 13:49:00 +0100 (lun., 18 mai 2015) $"
revision: "$9661667$"
deferred class
CMS_BLOG_HANDLER
inherit
CMS_MODULE_HANDLER [CMS_BLOG_API]
rename
module_api as blog_api
end
feature -- Access
entries_per_page: NATURAL_32
do
Result := blog_api.entries_per_page
end
end

View File

@@ -1,43 +0,0 @@
note
description: "Interface for accessing blog contents from the database."
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_BLOG_STORAGE_I
inherit
CMS_NODE_STORAGE_I
feature -- Access
blogs_count: INTEGER_64
-- Count of blog nodes
deferred
end
blogs_count_from_user (a_user: CMS_USER) : INTEGER_64
-- Number of nodes of type blog from `a_user'.
require
has_id: a_user.has_id
deferred
end
blogs: LIST [CMS_NODE]
-- List of nodes ordered by creation date (descending).
deferred
end
blogs_limited (limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_NODE]
-- List of posts ordered by creation date from offset to offset + limit.
deferred
end
blogs_from_user_limited (a_user: CMS_USER; limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_NODE]
-- List of posts from `a_user' ordered by creation date from offset to offset + limit.
require
has_id: a_user.has_id
deferred
end
end

View File

@@ -1,47 +0,0 @@
note
description: "Summary description for {CMS_BLOG_STORAGE_NULL}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_BLOG_STORAGE_NULL
inherit
CMS_NODE_STORAGE_NULL
CMS_BLOG_STORAGE_I
create
make
feature -- Access
blogs_count: INTEGER_64
-- Count of nodes.
do
end
blogs_count_from_user (a_user: CMS_USER) : INTEGER_64
-- <Precursor>
do
end
blogs: LIST [CMS_NODE]
-- <Precursor>
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
blogs_limited (limit: NATURAL_32; offset: NATURAL_32) : LIST [CMS_NODE]
-- <Precursor>
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
blogs_from_user_limited (a_user: CMS_USER; limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_NODE]
-- <Precursor>
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
end

View File

@@ -1,140 +0,0 @@
note
description: "Access to the sql database for the blog module"
author: "Dario Bösch <daboesch@student.ethz.ch>"
date: "$Date: 2015-05-21 14:46:00 +0100$"
revision: "$Revision: 96616 $"
class
CMS_BLOG_STORAGE_SQL
inherit
CMS_NODE_STORAGE_SQL
CMS_BLOG_STORAGE_I
create
make
feature -- Access
blogs_count: INTEGER_64
-- <Precursor>
do
error_handler.reset
write_information_log (generator + ".blogs_count")
sql_query (sql_select_blog_count, Void)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
end
blogs_count_from_user (a_user: CMS_USER) : INTEGER_64
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
write_information_log (generator + ".blogs_count_from_user")
create l_parameters.make (2)
l_parameters.put (a_user.id, "user")
sql_query (sql_select_blog_count_from_user, l_parameters)
if sql_rows_count = 1 then
Result := sql_read_integer_64 (1)
end
end
blogs: LIST [CMS_NODE]
-- <Precursor>
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
write_information_log (generator + ".blogs")
from
sql_query (sql_select_blogs_order_created_desc, Void)
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
end
blogs_limited (a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_NODE]
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
write_information_log (generator + ".blogs_limited")
from
create l_parameters.make (2)
l_parameters.put (a_limit, "limit")
l_parameters.put (a_offset, "offset")
sql_query (sql_blogs_limited, l_parameters)
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
end
blogs_from_user_limited (a_user: CMS_USER; a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_NODE]
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
write_information_log (generator + ".blogs_from_user_limited")
from
create l_parameters.make (2)
l_parameters.put (a_limit, "limit")
l_parameters.put (a_offset, "offset")
l_parameters.put (a_user.id, "user")
sql_query (sql_blogs_from_user_limited, l_parameters)
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
end
feature {NONE} -- Queries
sql_select_blog_count: STRING = "SELECT count(*) FROM Nodes WHERE status != -1 AND type = %"blog%";"
-- Nodes count (Published and not Published)
--| note: {CMS_NODE_API}.trashed = -1
sql_select_blog_count_from_user: STRING = "SELECT count(*) FROM Nodes WHERE status != -1 AND type = %"blog%" AND author = :user ;"
-- Nodes count (Published and not Published)
--| note: {CMS_NODE_API}.trashed = -1
sql_select_blogs_order_created_desc: STRING = "SELECT * FROM Nodes WHERE status != -1 AND type = %"blog%" ORDER BY created DESC;"
-- SQL Query to retrieve all nodes that are from the type "blog" ordered by descending creation date.
sql_blogs_limited: STRING = "SELECT * FROM Nodes WHERE status != -1 AND type = %"blog%" ORDER BY created DESC LIMIT :limit OFFSET :offset ;"
--- SQL Query to retrieve all node of type "blog" limited by limit and starting at offset
sql_blogs_from_user_limited: STRING = "SELECT * FROM Nodes WHERE status != -1 AND type = %"blog%" AND author = :user ORDER BY created DESC LIMIT :limit OFFSET :offset ;"
--- SQL Query to retrieve all node of type "blog" from author with id limited by limit + offset
end

View File

@@ -7,17 +7,17 @@
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard"> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="standard">
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/> <library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/> <library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\..\..\library\model\cms_model-safe.ecf" readonly="false"/> <library name="cms_model" location="..\..\..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <library name="http" location="$EWF_LIBRARY\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/> <library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/> <library name="wsf_encoder" location="$EWF_LIBRARY\library\text\encoder\encoder-safe.ecf"/>
<cluster name="src" location=".\" recursive="true"/> <cluster name="src" location=".\" recursive="true"/>
</target> </target>
</system> </system>

View File

@@ -10,10 +10,7 @@ class
inherit inherit
CMS_MODULE CMS_MODULE
redefine redefine
register_hooks, register_hooks
initialize,
is_installed,
install
end end
CMS_HOOK_MENU_SYSTEM_ALTER CMS_HOOK_MENU_SYSTEM_ALTER
@@ -33,58 +30,14 @@ feature {NONE} -- Initialization
package := "demo" package := "demo"
end end
feature {CMS_API} -- Module Initialization
initialize (api: CMS_API)
-- <Precursor>
do
Precursor (api)
-- Add support for CMS_PAGE, which requires a storage extension to store the optional "parent" id.
-- For now, we only have extension based on SQL statement.
-- if attached {CMS_NODE_STORAGE_SQL} l_node_api.node_storage as l_sql_node_storage then
-- l_sql_node_storage.register_node_storage_extension (create {CMS_NODE_STORAGE_SQL_PAGE_EXTENSION}.make (l_sql_node_storage))
-- end
end
feature {CMS_API} -- Module management
is_installed (api: CMS_API): BOOLEAN
-- Is Current module installed?
do
Result := attached api.storage.custom_value ("is_initialized", "module-" + name) as v and then v.is_case_insensitive_equal_general ("yes")
end
install (api: CMS_API)
local
sql: STRING
do
-- Schema
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
if not l_sql_storage.sql_table_exists ("tb_demo") then
sql := "[
CREATE TABLE "tb_demo"(
"demo_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("demo_id">=0),
"name" VARCHAR(100) NOT NULL,
"value" TEXT
);
]"
l_sql_storage.sql_execute_script (sql)
if l_sql_storage.has_error then
api.logger.put_error ("Could not initialize database for demo module", generating_type)
end
end
api.storage.set_custom_value ("is_initialized", "module-" + name, "yes")
end
end
feature -- Access: router feature -- Access: router
setup_router (a_router: WSF_ROUTER; a_api: CMS_API) router (a_api: CMS_API): WSF_ROUTER
-- <Precursor> -- Node router.
do do
map_uri_template_agent (a_router, "/demo/", agent handle_demo (?,?,a_api)) create Result.make (2)
map_uri_template_agent (a_router, "/demo/{id}", agent handle_demo_entry (?,?,a_api)) map_uri_template_agent (Result, "/demo/", agent handle_demo (?,?,a_api))
map_uri_template_agent (Result, "/demo/{id}", agent handle_demo_entry (?,?,a_api))
end end
feature -- Hooks feature -- Hooks
@@ -131,11 +84,37 @@ feature -- Hooks
feature -- Handler feature -- Handler
initialize_module (a_api: CMS_API)
local
sql: STRING
do
if attached {CMS_STORAGE_SQL} a_api.storage as sql_db then
sql_db.sql_query ("select count(*) from tb_demo;", Void)
if sql_db.has_error then
-- Initialize db for demo module
sql := "[
CREATE TABLE "tb_demo"(
"did" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("did">=0),
"name" VARCHAR(100) NOT NULL,
"value" TEXT
);
]"
sql_db.reset_error
sql_db.sql_change (sql, Void)
if sql_db.has_error then
a_api.logger.put_error ("Could not initialize database for demo module", generating_type)
end
end
end
end
handle_demo, handle_demo,
handle_demo_entry (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API) handle_demo_entry (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
local local
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
do do
initialize_module (a_api)
create r.make (req, res, a_api) create r.make (req, res, a_api)
r.set_main_content ("NODE module does not yet implement %"" + req.path_info + "%" ...") r.set_main_content ("NODE module does not yet implement %"" + req.path_info + "%" ...")
r.add_error_message ("NODE Module: not yet implemented") r.add_error_message ("NODE Module: not yet implemented")

View File

@@ -1,13 +1,10 @@
{ {
"database": { "database": {
"datasource": { "datasource": {
"driver": "sqlite", "driver": "MySQL",
"environment": "sqlite" "environment": "development"
}, },
"environments": { "environments": {
"sqlite": {
"connection_string":"Driver=SQLite3 ODBC Driver;Database=./site/database.sqlite;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;"
},
"test": { "test": {
"connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;" "connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;"
}, },
@@ -32,4 +29,4 @@
} }

View File

@@ -1,28 +0,0 @@
BEGIN;
CREATE TABLE "logs"(
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
"category" VARCHAR(255) NOT NULL,
"level" INTEGER NOT NULL CHECK("level">=1),
"uid" INTEGER,
"message" TEXT NOT NULL,
"info" TEXT,
"link" TEXT,
"date" DATETIME NOT NULL
);
CREATE TABLE "custom_values"(
"type" VARCHAR(255) NOT NULL,
"name" VARCHAR(255) NOT NULL,
"value" VARCHAR(255) NOT NULL
);
CREATE TABLE "path_aliases"(
"pid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("pid">=0),
"source" VARCHAR(255) NOT NULL,
"alias" VARCHAR(255) NOT NULL,
"lang" VARCHAR(12)
);
COMMIT;

View File

@@ -1,24 +0,0 @@
BEGIN;
CREATE TABLE "nodes"(
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
"revision" INTEGER,
"type" TEXT NOT NULL,
"title" VARCHAR(255) NOT NULL,
"summary" TEXT,
"content" MEDIUMTEXT NOT NULL,
"format" VARCHAR(255),
"author" INTEGER,
"publish" DATETIME,
"created" DATETIME NOT NULL,
"changed" DATETIME NOT NULL,
"status" INTEGER
);
CREATE TABLE page_nodes(
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
"revision" INTEGER,
"parent" INTEGER
);
COMMIT;

View File

@@ -1,5 +1,4 @@
BEGIN; BEGIN;
CREATE TABLE "users"( CREATE TABLE "users"(
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0), "uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
"name" VARCHAR(100) NOT NULL, "name" VARCHAR(100) NOT NULL,
@@ -13,22 +12,23 @@ CREATE TABLE "users"(
UNIQUE("name") UNIQUE("name")
); );
CREATE TABLE "roles"(
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
"name" VARCHAR(100) NOT NULL,
CONSTRAINT "name"
UNIQUE("name")
);
CREATE TABLE "users_roles"( CREATE TABLE "users_roles"(
"uid" INTEGER NOT NULL CHECK("uid">=0), "rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
"rid" INTEGER NOT NULL CHECK("rid">=0) "role" VARCHAR(100) NOT NULL,
CONSTRAINT "role"
UNIQUE("role")
); );
CREATE TABLE "role_permissions"( CREATE TABLE "nodes"(
"rid" INTEGER NOT NULL CHECK("rid">=0), "nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
"permission" VARCHAR(255) NOT NULL, "version" INTEGER,
"module" VARCHAR(255) "type" INTEGER,
"title" VARCHAR(255) NOT NULL,
"summary" TEXT NOT NULL,
"content" MEDIUMTEXT NOT NULL,
"author" INTEGER,
"publish" DATETIME,
"created" DATETIME NOT NULL,
"changed" DATETIME NOT NULL
); );
COMMIT; COMMIT;

View File

@@ -1,25 +0,0 @@
ul.cms_blog_nodes {
padding: 0;
margin: 0;
}
ul.cms_blog_nodes li.cms_type_blog {
list-style: none;
display: block;
margin-top: 20px;
padding-bottom: 20px;
border-bottom: 1px dotted black;
}
ul.cms_blog_nodes li.cms_type_blog .blog_title a {
color: black;
font-size: 18px;
text-decoration: none;
display: block;
margin: 6px 0;
}
ul.cms_blog_nodes li.cms_type_blog .blog_title a:hover {
color: #999;
}
ul.cms_blog_nodes li.cms_type_blog .blog_list_summary a {
margin-top: 20px;
display: block;
}

View File

@@ -1,17 +0,0 @@
ul.cms-nodes {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc;
}
ul.cms-nodes li {
border-top: dotted 1px #ccc;
}
ul.cms-nodes li:first-child {
border-top: none;
}
ul.cms-nodes li.cms_type_page a::before {
content: "[page] ";
}
ul.cms-nodes li.cms_type_blog a::before {
content: "[blog] ";
}

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,307 +0,0 @@
var ROC_AUTH = ROC_AUTH || { };
var loginURL = "/login";
var logoutURL = "/logoff";
var userAgent = navigator.userAgent.toLowerCase();
var firstLogIn = true;
ROC_AUTH.login = function() {
var form = document.forms[0];
var username = form.username.value;
var password = form.password.value;
//var host = form.host.value;
var origin = window.location.origin.concat(window.location.pathname);
var _login = function(){
if (document.getElementById('myModalFormId') !== null ) {
ROC_AUTH.remove ('myModalFormId');
}
if (username === "" || password === "") {
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$("body").append(newdiv);
}
}else{
//Instantiate HTTP Request
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", loginURL, true, username, password);
request.send(null);
//Process Response
request.onreadystatechange = function(){
if (request.readyState == 4) {
if (request.status==200) {
delete form;
window.location=origin;
}
else{
if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
}
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$("body").append(newdiv);
}
}
}
}
}
}
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
if (firstLogIn) _login();
else logoff(_login);
}
else{
_login();
}
if (firstLogIn) firstLogIn = false;
};
ROC_AUTH.login_with_redirect = function() {
var form = document.forms[2];
var username = form.username.value;
var password = form.password.value;
var host = form.host.value;
var _login = function(){
var redirectURL = form.redirect && form.redirect.value || "";
$("#imgProgressRedirect").show();
if (document.getElementById('myModalFormId') !== null ) {
ROC_AUTH.remove ('myModalFormId');
}
if (username === "" || password === "") {
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$("body").append(newdiv);
$("#imgProgressRedirect").hide();
}
}else{
//Instantiate HTTP Request
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", host.concat(loginURL), true, username, password);
request.send(null);
//Process Response
request.onreadystatechange = function(){
if (request.readyState == 4) {
if (request.status==200) {
if (redirectURL === "") {
window.location=host.concat("/");
} else {
window.location=host.concat(redirectURL);
}
}
else{
if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
}
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$("body").append(newdiv);
$("#imgProgressRedirect").hide();
}
}
}
}
}
}
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
if (firstLogIn) _login();
else logoff(_login);
}
else{
_login();
}
if (firstLogIn) firstLogIn = false;
};
ROC_AUTH.getQueryParameterByName = function (name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? " " : decodeURIComponent(results[1].replace(/\+/g, " "));
}
ROC_AUTH.logoff = function(callback){
var form = document.forms[0];
var host = form.host.value;
if (userAgent.indexOf("msie") != -1) {
document.execCommand("ClearAuthenticationCache");
}
else if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
var request1 = new XMLHttpRequest();
var request2 = new XMLHttpRequest();
//Logout. Tell the server not to return the "WWW-Authenticate" header
request1.open("GET", host.concat(logoutURL) + "?prompt=false", true);
request1.send("");
request1.onreadystatechange = function(){
if (request1.readyState == 4) {
//Sign in with dummy credentials to clear the auth cache
request2.open("GET", host.concat(logoutURL), true, "logout", "logout");
request2.send("");
request2.onreadystatechange = function(){
if (request2.readyState == 4) {
if (callback!=null) { callback.call(); } else { window.location=host.concat(logoutURL);}
}
}
}
}
}
else {
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", host.concat(logoutURL), true, "logout", "logout");
request.send("");
request.onreadystatechange = function(){
if (request.status==401 || request.status==403 ) { window.location=host.concat(logoutURL);
}
}
}
};
ROC_AUTH.remove = function (id)
{
var element = document.getElementById(id);
element.outerHTML = "";
delete element;
return;
};
$(document).ready(function() {
if (typeof String.prototype.contains != 'function') {
String.prototype.contains = function (str){
return this.indexOf(str) != -1;
};
}
ROC_AUTH.progressive_loging();
});
ROC_AUTH.progressive_loging = function () {
ROC_AUTH.login_href();
};
$(document).keypress(function(e) {
if ((e.which === 13) && (e.target.localName === 'input' && e.target.id === 'password')) {
ROC_AUTH.login();
}
});
ROC_AUTH.OnOneClick = function(event) {
event.preventDefault();
if ( document.forms[0] === undefined ) {
ROC_AUTH.create_form();
}
return false;
};
ROC_AUTH.login_href = function() {
var els = document.getElementsByTagName("a");
for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
if (el.href.contains("/basic_auth_login?destination")) {
loginURL = el.href;
var OneClick = el;
OneClick.addEventListener('click', ROC_AUTH.OnOneClick, false);
}
}
};
ROC_AUTH.create_form = function() {
// Fetching HTML Elements in Variables by ID.
var createform = document.createElement('form'); // Create New Element Form
createform.setAttribute("action", ""); // Setting Action Attribute on Form
createform.setAttribute("method", "post"); // Setting Method Attribute on Form
$("body").append(createform);
var heading = document.createElement('h2'); // Heading of Form
heading.innerHTML = "Login Form ";
createform.appendChild(heading);
var line = document.createElement('hr'); // Giving Horizontal Row After Heading
createform.appendChild(line);
var linebreak = document.createElement('br');
createform.appendChild(linebreak);
var namelabel = document.createElement('label'); // Create Label for Name Field
namelabel.innerHTML = "Username : "; // Set Field Labels
createform.appendChild(namelabel);
var inputelement = document.createElement('input'); // Create Input Field for UserName
inputelement.setAttribute("type", "text");
inputelement.setAttribute("name", "username");
inputelement.setAttribute("required","required");
createform.appendChild(inputelement);
var linebreak = document.createElement('br');
createform.appendChild(linebreak);
var passwordlabel = document.createElement('label'); // Create Label for Password Field
passwordlabel.innerHTML = "Password : ";
createform.appendChild(passwordlabel);
var passwordelement = document.createElement('input'); // Create Input Field for Password.
passwordelement.setAttribute("type", "password");
passwordelement.setAttribute("name", "password");
passwordelement.setAttribute("id", "password");
passwordelement.setAttribute("required","required");
createform.appendChild(passwordelement);
var passwordbreak = document.createElement('br');
createform.appendChild(passwordbreak);
var submitelement = document.createElement('button'); // Append Submit Button
submitelement.setAttribute("type", "button");
submitelement.setAttribute("onclick", "ROC_AUTH.login();");
submitelement.innerHTML = "Sign In ";
createform.appendChild(submitelement);
};

View File

@@ -1,30 +0,0 @@
ul.cms_blog_nodes{
padding:0;
margin:0;
li.cms_type_blog{
list-style: none;
display: block;
margin-top:20px;
padding-bottom:20px;
border-bottom:1px dotted black;
.blog_title a{
color:black;
font-size:18px;
text-decoration: none;
display:block;
margin:6px 0;
&:hover{
color:#999;
}
}
.blog_list_summary a{
margin-top:20px;
display:block;
}
}
}

View File

@@ -1,24 +0,0 @@
ul.cms-nodes {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc;
li{
border-top: dotted 1px #ccc;
&:first-child {
border-top: none;
}
}
li.cms_type_page a::before {
content: "[page] ";
}
li.cms_type_blog a::before {
content: "[blog] ";
}
}

View File

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

View File

@@ -1,38 +1,14 @@
{assign name="debug_enabled" value="True"/} {assign name="debug_enabled" value="True"/}
{if condition="$debug_enabled"} {if condition="$debug_enabled"}
<!-- start debug -->
{literal}
<style>
div.cms-debug>span {
position: absolute;
bottom: 5px;
right: 5px;
color: #ccc;
padding: 5px;
}
div.cms-debug:hover>span {
color: red;
}
div.cms-debug>span+ul {
display: none;
border: solid 2px red;
background-color: #ccc;
white-space: pre-wrap;
}
div.cms-debug:hover>span+ul {
display: block;
position: relative;
bottom: 5px;
left: 1%; right: 1%;
width: 98%;
}
</style>
{/literal}
<div class="cms-debug"><span>Show debug</span>
<ul> <ul>
{assign name="kpage" value="page"/}{assign name="kregions" value="regions"/}{foreach key="k" item="i" from="$page.variables"}{unless condition="$k ~ $kpage"}{unless condition="$k ~ $kregions"}<li><strong>{$k/}</strong>={htmlentities}{$i/}{/htmlentities}</li>{/unless}{/unless} {assign name="kpage" value="page"/}
{assign name="kregions" value="regions"/}
{foreach key="k" item="i" from="$page.variables"}
{unless condition="$k ~ $kpage"}
{unless condition="$k ~ $kregions"}
<li><strong>{$k/}</strong>={$i/}</li>
{/unless}
{/unless}
{/foreach} {/foreach}
</ul> </ul>
</div>
<!-- end debug -->
{/if} {/if}

View File

@@ -1,18 +1,10 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- EWF CMS --> <!-- EWF CMS -->
<link rel="stylesheet" href="{$site_url/}/theme/css/style.css"> <link rel="stylesheet" href="{$site_url/}/theme/css/style.css">
<link rel="stylesheet" href="{$site_url/}/theme/css/node.css">
<!-- CMS Blog Module -->
<link rel="stylesheet" href="{$site_url/}/theme/css/blog.css">
<script src="{$site_url/}/theme/js/jquery-1.10.2.min.js"></script>
<script src="{$site_url/}/theme/js/roc_auth.js"></script>
<!-- bootstrap framework --> <!-- bootstrap framework -->
<!-- Latest compiled and minified CSS --> <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
@@ -78,6 +70,8 @@
<!-- Latest compiled and minified JavaScript --> <!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<!--
{include file="debug.tpl"/} {include file="debug.tpl"/}
-->
</body> </body>
</html> </html>

View File

@@ -16,17 +16,10 @@ inherit
initialize initialize
end end
WSF_SERVICE
redefine
execute
end
REFACTORING_HELPER REFACTORING_HELPER
SHARED_EXECUTION_ENVIRONMENT SHARED_EXECUTION_ENVIRONMENT
SHARED_LOGGER
create create
make_and_launch make_and_launch
@@ -41,36 +34,21 @@ feature {NONE} -- Initialization
initialize initialize
-- Initialize current service. -- Initialize current service.
do do
-- Launcher
Precursor Precursor
create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("demo.ini") create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("demo.ini")
-- CMS
initialize_cms
end
feature -- Service
cms_service: CMS_SERVICE
-- cms service.
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
do
cms_service.execute (req, res)
end end
feature {NONE} -- Launch operation feature {NONE} -- Launch operation
launcher: APPLICATION_LAUNCHER launcher: APPLICATION_LAUNCHER [EWF_ROC_SERVER_EXECUTION]
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local local
l_retry: BOOLEAN l_retry: BOOLEAN
l_message: STRING l_message: STRING
do do
if not l_retry then if not l_retry then
write_debug_log (generator + ".launch") launcher.launch (opts)
launcher.launch (a_service, opts)
else else
-- error hanling. -- error hanling.
create l_message.make (1024) create l_message.make (1024)
@@ -89,77 +67,12 @@ feature {NONE} -- Launch operation
l_message.append ("The application crash without available information") l_message.append ("The application crash without available information")
l_message.append ("%N%N") l_message.append ("%N%N")
end end
-- notify shutdown -- send email shutdown
write_debug_log (generator + ".launch shutdown")
end end
rescue rescue
l_retry := True l_retry := True
retry retry
end end
feature -- CMS Initialization
initialize_cms
local
l_setup: CMS_DEFAULT_SETUP
utf: UTF_CONVERTER
cms_env: CMS_ENVIRONMENT
do
-- Application Environment initialization
if attached execution_environment.arguments.separate_character_option_value ('d') as l_dir then
create cms_env.make_with_directory_name (l_dir)
else
create cms_env.make_default
end
initialize_logger (cms_env)
-- CMS Setup
write_debug_log (generator + ".initialize_cms / SETUP based directory=%"" + utf.escaped_utf_32_string_to_utf_8_string_8 (cms_env.path.name) + "%"")
create l_setup.make (cms_env)
-- CMS
write_debug_log (generator + ".initialize_cms / CMS")
setup_storage (l_setup)
setup_modules (l_setup)
create cms_service.make (l_setup)
end
feature -- CMS setup
setup_modules (a_setup: CMS_SETUP)
-- Setup additional modules.
local
m: CMS_MODULE
do
create {NODE_MODULE} m.make (a_setup)
m.enable
a_setup.register_module (m)
create {BASIC_AUTH_MODULE} m.make
if not a_setup.module_with_same_type_registered (m) then
m.enable
a_setup.register_module (m)
end
create {CMS_DEBUG_MODULE} m.make
m.enable
a_setup.register_module (m)
create {CMS_DEMO_MODULE} m.make
m.enable
a_setup.register_module (m)
create {CMS_BLOG_MODULE} m.make
m.enable
a_setup.register_module (m)
end
setup_storage (a_setup: CMS_SETUP)
-- Setup storage by declaring storage builder.
do
-- a_setup.storage_drivers.force (create {CMS_STORAGE_MYSQL_BUILDER}.make, "mysql")
a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE_BUILDER}.make, "sqlite")
end
end end

View File

@@ -0,0 +1,57 @@
note
description: "Summary description for {EWF_ROC_SERVER_EXECUTION}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
EWF_ROC_SERVER_EXECUTION
inherit
CMS_EXECUTION
redefine
initialize
end
REFACTORING_HELPER
SHARED_LOGGER
create
make
feature {NONE} -- Initialization
initialize
do
Precursor
end
feature -- CMS setup
setup_modules (a_setup: CMS_SETUP)
-- Setup additional modules.
local
m: CMS_MODULE
do
create {BASIC_AUTH_MODULE} m.make
if not a_setup.module_with_same_type_registered (m) then
m.enable
a_setup.register_module (m)
end
create {CMS_DEMO_MODULE} m.make
m.enable
a_setup.register_module (m)
end
setup_storage (a_setup: CMS_SETUP)
do
debug ("refactor_fixme")
to_implement ("To implement custom storage")
end
-- a_setup.storage_drivers.force (create {CMS_STORAGE_MYSQL_BUILDER}.make, "mysql")
a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE_BUILDER}.make, "sqlite")
end
end

View File

@@ -1,13 +0,0 @@
Application Environment Library
===============================
Define a generic application environment to be re-used by different applications.
site/
doc/
logs/
www/
assets
template
theme
config/

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="app_env" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="app_env">
<description>Application Environment (layout, configuration, logger, database, ...)</description>
<target name="app_env">
<root all_classes="true"/>
<option warning="true" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="app_env" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="app_env">
<description>Application Environment (layout, configuration, logger, database, ...)</description>
<target name="app_env">
<root all_classes="true"/>
<option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -1,23 +0,0 @@
note
description: "See {APPLICATION_ENVIRONMENT}."
date: "$Date$"
revision: "$Revision$"
class
APPLICATION_LAYOUT
obsolete
"Use APPLICATION_ENVIRONMENT [April/2015]"
inherit
APPLICATION_ENVIRONMENT
create
make_default,
make_with_path,
make_with_directory_name
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

13
library/layout/Readme.md Normal file
View File

@@ -0,0 +1,13 @@
Layout Library
==============
Define a generic layout to be re-used by different applications.
site/
doc/
logs/
www/
assets
template
theme
config/

View File

@@ -1,3 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<redirection xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" location="..\app_env\app_env-safe.ecf"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="layout" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="layout">
</redirection> <target name="layout">
<root all_classes="true"/>
<option warning="true" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -1,3 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<redirection xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" location="..\app_env\app_env.ecf"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="layout" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="layout">
</redirection> <target name="layout">
<root all_classes="true"/>
<option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -1,6 +1,6 @@
note note
description: "[ description: "[
Application environment (layout, ...) Application layout
Related to file system locations such as Related to file system locations such as
- configuration locations - configuration locations
- application - application
@@ -15,7 +15,7 @@ note
revision: "$Revision: 96584 $" revision: "$Revision: 96584 $"
class class
APPLICATION_ENVIRONMENT APPLICATION_LAYOUT
inherit inherit
SHARED_EXECUTION_ENVIRONMENT SHARED_EXECUTION_ENVIRONMENT

View File

@@ -1,5 +1,6 @@
note note
description: "Object to log messages for a specific application. " description: "Summary description for {LOGGER}."
author: ""
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
@@ -21,35 +22,24 @@ inherit
create create
make, make,
make_with_environment,
make_with_layout make_with_layout
feature {NONE} -- Initialization feature {NONE} -- Initialization
make make
-- Initialize a logger object.
do do
create log.make create log.make
end end
make_with_environment (app: APPLICATION_ENVIRONMENT) make_with_layout (app: APPLICATION_LAYOUT)
-- Initialize a logger object with an application environment `app'.
do do
make make
apply_environment (app) apply_layout (app)
end
make_with_layout (app: APPLICATION_ENVIRONMENT)
-- Initialize a logger object with an application layout `app'.
obsolete
"Use make_with_environment"
do
make_with_environment (app)
end end
feature -- Change feature -- Change
apply_environment (app: APPLICATION_ENVIRONMENT) apply_layout (app: APPLICATION_LAYOUT)
do do
initialize_logger (app, log) initialize_logger (app, log)
end end
@@ -61,44 +51,38 @@ feature {NONE} -- Internal
feature -- Logging feature -- Logging
put_information (a_message: separate READABLE_STRING_8) put_information (a_message: separate READABLE_STRING_8)
-- Put message `a_message' to the log at information level.
do do
log.write_information (create {STRING}.make_from_separate (a_message)) log.write_information (create {STRING}.make_from_separate (a_message))
end end
put_error (a_message: separate READABLE_STRING_8) put_error (a_message: separate READABLE_STRING_8)
-- Put message `a_message' to the log at error level.
do do
log.write_error (create {STRING}.make_from_separate (a_message)) log.write_error (create {STRING}.make_from_separate (a_message))
end end
put_warning (a_message: separate READABLE_STRING_8) put_warning (a_message: separate READABLE_STRING_8)
-- Put message `a_message' to the log at warning level.
do do
log.write_warning (create {STRING}.make_from_separate (a_message)) log.write_warning (create {STRING}.make_from_separate (a_message))
end end
put_critical (a_message: separate READABLE_STRING_8) put_critical (a_message: separate READABLE_STRING_8)
-- Put message `a_message' to the log at critical level.
do do
log.write_critical (create {STRING}.make_from_separate (a_message)) log.write_critical (create {STRING}.make_from_separate (a_message))
end end
put_alert (a_message: separate READABLE_STRING_8) put_alert (a_message: separate READABLE_STRING_8)
-- Put message `a_message' to the log at alert level.
do do
log.write_alert (create {STRING}.make_from_separate (a_message)) log.write_alert (create {STRING}.make_from_separate (a_message))
end end
put_debug (a_message: separate READABLE_STRING_8) put_debug (a_message: separate READABLE_STRING_8)
-- Put message `a_message' to the log at debug level.
do do
log.write_debug (create {STRING}.make_from_separate (a_message)) log.write_debug (create {STRING}.make_from_separate (a_message))
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation
initialize_logger (app: APPLICATION_ENVIRONMENT; a_log: like log) initialize_logger (app: APPLICATION_LAYOUT; a_log: like log)
local local
l_log_writer_file: LOG_ROLLING_WRITER_FILE l_log_writer_file: LOG_ROLLING_WRITER_FILE
l_log_writer: LOG_WRITER l_log_writer: LOG_WRITER

View File

@@ -22,7 +22,7 @@ feature -- Access
register_log_writer (a_log_writer: LOG_WRITER) register_log_writer (a_log_writer: LOG_WRITER)
-- Register the non-default log writer `a_log_writer'. -- -- Register the non-default log writer `a_log_writer'.
do do
logging.register_log_writer (a_log_writer) logging.register_log_writer (a_log_writer)
end end

View File

@@ -98,11 +98,11 @@ feature {NONE} -- Logger: separate implementation
feature {NONE} -- Implementation feature {NONE} -- Implementation
initialize_logger (app: APPLICATION_ENVIRONMENT) initialize_logger (app: APPLICATION_LAYOUT)
local local
l_logger: LOGGER l_logger: LOGGER
do do
create l_logger.make_with_environment (app) create l_logger.make_with_layout (app)
set_logger_to (l_logger, logger_cell) set_logger_to (l_logger, logger_cell)
end end

View File

@@ -0,0 +1,15 @@
note
description: "[
Interface defining a CMS content type.
]"
status: "draft"
date: "$Date$"
revision: "$Revision$"
class
CMS_CONTENT_TYPE
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -0,0 +1,196 @@
note
description: "[
CMS abstraction for CMS content entity, named "node".
]"
status: "draft"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
CMS_NODE
inherit
REFACTORING_HELPER
create
make
feature{NONE} -- Initialization
make (a_content: READABLE_STRING_32; a_summary: READABLE_STRING_32; a_title: READABLE_STRING_32)
-- Create current node with `a_content', `a_summary' and `a_title'.
local
l_time: DATE_TIME
do
create l_time.make_now_utc
set_content (a_content)
set_summary (a_summary)
set_title (a_title)
set_creation_date (l_time)
set_modification_date (l_time)
set_publication_date (l_time)
debug ("refactor_fixme")
fixme ("Remove default harcoded format")
end
set_format ("HTML")
debug ("refactor_fixme")
fixme ("Remove default harcoded content type")
end
set_content_type ("Page")
ensure
content_set: content = a_content
summary_set: summary = a_summary
title_set: title = a_title
end
feature -- Access
id: INTEGER_64 assign set_id
-- Unique id.
content: READABLE_STRING_32
-- Content of the node.
summary: READABLE_STRING_32
-- A short summary of the node.
title: READABLE_STRING_32
-- Full title of the node.
modification_date: DATE_TIME
-- When the node was updated.
creation_date: DATE_TIME
-- When the node was created.
publication_date: DATE_TIME
-- When the node was published.
publication_date_output: READABLE_STRING_32
-- Formatted output.
format: READABLE_STRING_32
-- Format associated with `body'.
-- For example: text, mediawiki, html, etc
content_type: READABLE_STRING_32
-- Associated content type name.
-- Page, Article, Blog, News, etc.
author: detachable CMS_USER
-- Author of current node.
-- collaborators: detachable LIST[CMS_USER]
-- -- Users contributed to current Node.
feature -- status report
has_id: BOOLEAN
-- Has unique identifier?
do
Result := id > 0
end
feature -- Element change
set_content (a_content: like content)
-- Assign `content' with `a_content'.
do
content := a_content
ensure
content_assigned: content = a_content
end
set_summary (a_summary: like summary)
-- Assign `summary' with `a_summary'.
do
summary := a_summary
ensure
summary_assigned: summary = a_summary
end
set_title (a_title: like title)
-- Assign `title' with `a_title'.
do
title := a_title
ensure
title_assigned: title = a_title
end
set_modification_date (a_modification_date: like modification_date)
-- Assign `modification_date' with `a_modification_date'.
do
modification_date := a_modification_date
ensure
modification_date_assigned: modification_date = a_modification_date
end
set_creation_date (a_creation_date: like creation_date)
-- Assign `creation_date' with `a_creation_date'.
do
creation_date := a_creation_date
ensure
creation_date_assigned: creation_date = a_creation_date
end
set_publication_date (a_publication_date: like publication_date)
-- Assign `publication_date' with `a_publication_date'.
do
publication_date := a_publication_date
publication_date_output := publication_date.formatted_out ("yyyy/[0]mm/[0]dd")
ensure
publication_date_assigned: publication_date = a_publication_date
end
set_content_type (a_content_type: like content_type)
-- Assign `content_type' with `a_content_type'.
do
content_type := a_content_type
ensure
content_type_assigned: content_type = a_content_type
end
set_format (a_format: like format)
-- Assign `format' with `a_format'.
do
format := a_format
ensure
format_assigned: format = a_format
end
set_id (an_id: like id)
-- Assign `id' with `an_id'.
do
id := an_id
ensure
id_assigned: id = an_id
end
set_author (u: like author)
-- Assign 'author' with `u'
do
author := u
ensure
auther_set: author = u
end
-- add_collaborator (a_user: CMS_USER)
-- -- Add collaborator `a_user' to the collaborators list.
-- local
-- lst: like collaborators
-- do
-- lst := collaborators
-- if lst = Void then
-- create {ARRAYED_SET [CMS_USER]} lst.make (1)
-- collaborators := lst
-- end
-- lst.force (a_user)
-- end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -28,8 +28,12 @@ feature {NONE} -- Initialization
make (a_title: detachable like title; a_location: like location) make (a_title: detachable like title; a_location: like location)
-- Create current local link with optional title `a_title' and location `a_location'. -- Create current local link with optional title `a_title' and location `a_location'.
do do
if a_title /= Void then
title := a_title
else
title := a_location
end
location := a_location location := a_location
set_title (a_title)
end end
feature -- Access feature -- Access
@@ -71,16 +75,6 @@ feature -- Status report
feature -- Element change feature -- Element change
set_title (a_title: detachable like title)
-- Set `title' to `a_title' or `location'.
do
if a_title /= Void then
title := a_title
else
title := location
end
end
add_link (lnk: CMS_LINK) add_link (lnk: CMS_LINK)
-- <Precursor> -- <Precursor>
local local

View File

@@ -62,7 +62,6 @@ feature -- Status report
end end
has (lnk: CMS_LINK): BOOLEAN has (lnk: CMS_LINK): BOOLEAN
-- Has the current Menu a link `lnk'.
do do
across across
items as ic items as ic
@@ -88,7 +87,6 @@ feature -- Element change
end end
set_title (t: like title) set_title (t: like title)
-- Set `title' with `t'.
do do
title := t title := t
end end

View File

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

View File

@@ -1,19 +0,0 @@
note
description: "Partial CMS USER."
date: "$Date$"
revision: "$Revision$"
class
CMS_PARTIAL_USER
inherit
CMS_USER
create
make,
make_with_id -- MAYBE: export to CMS_STORAGE
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -71,11 +71,6 @@ feature -- Access
last_login_date: detachable DATE_TIME last_login_date: detachable DATE_TIME
-- User last login. -- User last login.
feature -- Roles
roles: detachable LIST [CMS_USER_ROLE]
-- If set, list of roles for current user.
feature -- Access: data feature -- Access: data
data: detachable STRING_TABLE [detachable ANY] data: detachable STRING_TABLE [detachable ANY]
@@ -194,14 +189,6 @@ feature -- Change element
set_last_login_date (create {DATE_TIME}.make_now_utc) set_last_login_date (create {DATE_TIME}.make_now_utc)
end end
feature -- Element change: roles
set_roles (lst: like roles)
-- Set `roles' to `lst'.
do
roles := lst
end
feature -- Change element: data feature -- Change element: data
set_data_item (k: READABLE_STRING_GENERAL; d: like data_item) set_data_item (k: READABLE_STRING_GENERAL; d: like data_item)
@@ -230,6 +217,6 @@ invariant
id_or_name_set: id > 0 or else not name.is_whitespace id_or_name_set: id > 0 or else not name.is_whitespace
note note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others" copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -22,25 +22,15 @@ create
feature {NONE} -- Initialization feature {NONE} -- Initialization
make_with_id (a_id: like id) make_with_id (a_id: like id; a_name: like name)
-- Create current role with role id `a_id'.
do do
id := a_id id := a_id
name := {STRING_32} "" make (a_name)
initialize
end end
make (a_name: like name) make (a_name: like name)
-- Create current role with name `a_name'.
require
a_name_valid: not a_name.is_whitespace
do do
name := a_name name := a_name
initialize
end
initialize
do
create {ARRAYED_LIST [READABLE_STRING_8]} permissions.make (0) create {ARRAYED_LIST [READABLE_STRING_8]} permissions.make (0)
end end
@@ -52,10 +42,10 @@ feature -- Status report
Result := id > 0 Result := id > 0
end end
has_permission (p: READABLE_STRING_GENERAL): BOOLEAN has_permission (p: READABLE_STRING_8): BOOLEAN
-- Has permission `p'? -- Has permission `p'?
do do
Result := across permissions as c some p.is_case_insensitive_equal (c.item) end Result := across permissions as c some c.item.is_case_insensitive_equal (p) end
end end
feature -- Access feature -- Access
@@ -63,7 +53,7 @@ feature -- Access
id: INTEGER id: INTEGER
-- Unique id associated with Current role. -- Unique id associated with Current role.
name: READABLE_STRING_32 name: READABLE_STRING_8
-- Name of Current role. -- Name of Current role.
permissions: LIST [READABLE_STRING_8] permissions: LIST [READABLE_STRING_8]
@@ -125,6 +115,6 @@ feature -- Permission change
end end
note note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others" copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -1,5 +1,6 @@
note note
description: "Storage based on Eiffel Store component." description: "Summary description for {CMS_STORAGE_STORE_SQL}."
author: ""
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $" date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $" revision: "$Revision: 96616 $"
@@ -7,6 +8,8 @@ deferred class
CMS_STORAGE_STORE_SQL CMS_STORAGE_STORE_SQL
inherit inherit
CMS_STORAGE
CMS_STORAGE_SQL CMS_STORAGE_SQL
feature {NONE} -- Initialization feature {NONE} -- Initialization
@@ -22,6 +25,7 @@ feature {NONE} -- Initialization
create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection) create {DATABASE_HANDLER_IMPL} db_handler.make (a_connection)
create error_handler.make create error_handler.make
-- error_handler.add_synchronization (db_handler.database_error_handler)
end end
feature -- Status report feature -- Status report
@@ -51,25 +55,21 @@ feature -- Query
end end
sql_begin_transaction sql_begin_transaction
-- <Precursor>
do do
connection.begin_transaction connection.begin_transaction
end end
sql_rollback_transaction sql_rollback_transaction
-- <Precursor>
do do
connection.rollback connection.rollback
end end
sql_commit_transaction sql_commit_transaction
-- <Precursor>
do do
connection.commit connection.commit
end end
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
-- Execute an sql query `a_sql_statement' with the params `a_params'.
do do
check_sql_query_validity (a_sql_statement, a_params) check_sql_query_validity (a_sql_statement, a_params)
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params)) db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
@@ -78,7 +78,6 @@ feature -- Query
end end
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY]) sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
-- Execute an sql query change `a_sql_statement' with the params `a_params'.
do do
check_sql_query_validity (a_sql_statement, a_params) check_sql_query_validity (a_sql_statement, a_params)
db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params)) db_handler.set_query (create {DATABASE_QUERY}.data_reader (a_sql_statement, a_params))
@@ -110,11 +109,6 @@ feature -- Query
db_handler.forth db_handler.forth
end end
sql_valid_item_index (a_index: INTEGER): BOOLEAN
do
Result := attached {DB_TUPLE} db_handler.item as l_item and then l_item.valid_index (a_index)
end
sql_item (a_index: INTEGER): detachable ANY sql_item (a_index: INTEGER): detachable ANY
do do
if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then if attached {DB_TUPLE} db_handler.item as l_item and then l_item.count >= a_index then

View File

@@ -1,16 +0,0 @@
note
description: "[
Common ancestor for builders responsible to instantiate storage based
on Eiffel Store storage.
]"
author: "$Author: jfiat $"
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
deferred class
CMS_STORAGE_STORE_SQL_BUILDER
inherit
CMS_STORAGE_SQL_BUILDER
end

View File

@@ -8,11 +8,11 @@
<setting name="console_application" value="true"/> <setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\..\cms-safe.ecf" readonly="false"/> <library name="cms" location="..\..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_app_env" location="..\..\app_env\app_env-safe.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/> <library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder-safe.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/> <library name="error" location="$EWF_LIBRARY\library\utility\general\error\error-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\layout\layout-safe.ecf"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/> <library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
<library name="model" location="..\..\model\cms_model-safe.ecf"/> <library name="model" location="..\..\model\cms_model-safe.ecf"/>
<library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql-safe.ecf"/> <library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql-safe.ecf"/>

View File

@@ -9,8 +9,8 @@
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="cms" location="..\..\..\cms.ecf" readonly="false"/> <library name="cms" location="..\..\..\cms.ecf" readonly="false"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/> <library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/> <library name="error" location="$EWF_LIBRARY\library\utility\general\error\error.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="layout" location="..\..\layout\layout.ecf"/> <library name="layout" location="..\..\layout\layout.ecf"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/> <library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
note note
description: "[ description: "[
Interface responsible to instantiate CMS_STORAGE_MYSQL object. Objects that ...
]" ]"
author: "$Author: jfiat $" author: "$Author: jfiat $"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $" date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
@@ -10,9 +10,7 @@ class
CMS_STORAGE_MYSQL_BUILDER CMS_STORAGE_MYSQL_BUILDER
inherit inherit
CMS_STORAGE_STORE_SQL_BUILDER CMS_STORAGE_BUILDER
GLOBAL_SETTINGS
create create
make make
@@ -30,16 +28,10 @@ feature -- Factory
local local
conn: DATABASE_CONNECTION conn: DATABASE_CONNECTION
do do
if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config then if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.layout.application_config_path) as l_database_config then
create {DATABASE_CONNECTION_MYSQL} conn.login_with_connection_string (l_database_config.connection_string) create {DATABASE_CONNECTION_MYSQL} conn.login_with_connection_string (l_database_config.connection_string)
if conn.is_connected then if conn.is_connected then
create Result.make (conn) create Result.make (conn)
set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default.
if Result.is_available then
if not Result.is_initialized then
initialize (a_setup, Result)
end
end
end end
end end
end end

View File

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

View File

@@ -29,13 +29,13 @@ feature {NONE} -- Initialization
storage.new_user (default_user) storage.new_user (default_user)
storage.new_user (custom_user ("u2", "p2", "e2")) storage.new_user (custom_user ("u2", "p2", "e2"))
l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- storage.update_node_title (2,ll_node.id, "New Title") storage.update_node_title (2,ll_node.id, "New Title")
-- check check
-- attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary
-- end end
-- end end
end end
@@ -64,10 +64,9 @@ feature {NONE} -- Implementation
Result := custom_node ("Default content", "default summary", "Default") Result := custom_node ("Default content", "default summary", "Default")
end end
custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_PAGE custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_NODE
do do
create Result.make (a_title) create Result.make (a_content, a_summary, a_title)
Result.set_content (a_content, a_summary, Void)
end end
end end

View File

@@ -167,192 +167,192 @@ feature -- Test routines
assert ("Valid password", storage.is_valid_credential ("test", "password")) assert ("Valid password", storage.is_valid_credential ("test", "password"))
end end
-- test_recent_nodes_empty test_recent_nodes_empty
-- do do
-- assert ("No recent nodes", storage.recent_nodes (0, 10).is_empty) assert ("No recent nodes", storage.recent_nodes (0, 10).is_empty)
-- end end
-- test_recent_nodes test_recent_nodes
-- local local
-- l_nodes: LIST[CMS_NODE] l_nodes: LIST[CMS_NODE]
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- storage.new_user (default_user) storage.new_user (default_user)
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out) l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- end end
-- l_nodes := storage.recent_nodes (0, 10) l_nodes := storage.recent_nodes (0, 10)
-- assert ("10 recent nodes", l_nodes.count = 10) assert ("10 recent nodes", l_nodes.count = 10)
-- assert ("First node id=10", l_nodes.first.id = 10) assert ("First node id=10", l_nodes.first.id = 10)
-- assert ("Last node id=1", l_nodes.last.id = 1) assert ("Last node id=1", l_nodes.last.id = 1)
-- l_nodes := storage.recent_nodes (5, 10) l_nodes := storage.recent_nodes (5, 10)
-- assert ("5 recent nodes", l_nodes.count = 5) assert ("5 recent nodes", l_nodes.count = 5)
-- assert ("First node id=5", l_nodes.first.id = 5) assert ("First node id=5", l_nodes.first.id = 5)
-- assert ("Last node id=1", l_nodes.last.id = 1) assert ("Last node id=1", l_nodes.last.id = 1)
-- l_nodes := storage.recent_nodes (9, 10) l_nodes := storage.recent_nodes (9, 10)
-- assert ("1 recent nodes", l_nodes.count = 1) assert ("1 recent nodes", l_nodes.count = 1)
-- assert ("First node id=1", l_nodes.first.id = 1) assert ("First node id=1", l_nodes.first.id = 1)
-- assert ("Last node id=1", l_nodes.last.id = 1) assert ("Last node id=1", l_nodes.last.id = 1)
-- l_nodes := storage.recent_nodes (10, 10) l_nodes := storage.recent_nodes (10, 10)
-- assert ("Is empty", l_nodes.is_empty) assert ("Is empty", l_nodes.is_empty)
-- end end
-- test_node_does_not_exist test_node_does_not_exist
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- storage.new_user (default_user) storage.new_user (default_user)
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out) l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- end end
-- assert ("Not exist node id: 12", storage.node_by_id (12) = Void) assert ("Not exist node id: 12", storage.node_by_id (12) = Void)
-- end end
-- test_node test_node
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- storage.new_user (default_user) storage.new_user (default_user)
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out) l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- end end
-- assert ("Node id: 10", attached storage.node_by_id (10) as ll_node and then ll_node.title ~ "Title_10" ) assert ("Node id: 10", attached storage.node_by_id (10) as ll_node and then ll_node.title ~ "Title_10" )
-- end end
-- test_update_node test_update_node
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- l_node := custom_node ("Content", "Summary", "Title") l_node := custom_node ("Content", "Summary", "Title")
-- storage.new_user (default_user) storage.new_user (default_user)
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- l_node := ll_node.twin l_node := ll_node.twin
-- l_node.set_content ("New Content") l_node.set_content ("New Content")
-- l_node.set_summary ("New Summary") l_node.set_summary ("New Summary")
-- l_node.set_title("New Title") l_node.set_title("New Title")
-- if attached storage.user_by_email (default_user.email) as l_user then if attached storage.user_by_email (default_user.email) as l_user then
-- l_node.set_author (l_user) l_node.set_author (l_user)
-- storage.update_node (l_node) storage.update_node (l_node)
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then not (u_node.content ~ ll_node.content) and then not (u_node.summary ~ ll_node.summary)) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then not (u_node.content ~ ll_node.content) and then not (u_node.summary ~ ll_node.summary))
-- end end
-- end end
-- end end
-- test_update_node_title test_update_node_title
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- l_node := custom_node ("Content", "Summary", "Title") l_node := custom_node ("Content", "Summary", "Title")
-- storage.new_user (default_user) storage.new_user (default_user)
-- storage.new_user (custom_user ("u2", "p2", "e2")) storage.new_user (custom_user ("u2", "p2", "e2"))
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- storage.update_node_title (2,ll_node.id, "New Title") storage.update_node_title (2,ll_node.id, "New Title")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary)
-- end end
-- end end
-- test_update_node_summary test_update_node_summary
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- l_node := custom_node ("Content", "Summary", "Title") l_node := custom_node ("Content", "Summary", "Title")
-- storage.new_user (default_user) storage.new_user (default_user)
-- storage.new_user (custom_user ("u2", "p2", "e2")) storage.new_user (custom_user ("u2", "p2", "e2"))
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- storage.update_node_summary (2,ll_node.id, "New Summary") storage.update_node_summary (2,ll_node.id, "New Summary")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then u_node.content ~ ll_node.content and then not (u_node.summary ~ ll_node.summary)) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then u_node.content ~ ll_node.content and then not (u_node.summary ~ ll_node.summary))
-- end end
-- end end
-- test_update_node_content test_update_node_content
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- l_node := custom_node ("Content", "Summary", "Title") l_node := custom_node ("Content", "Summary", "Title")
-- storage.new_user (default_user) storage.new_user (default_user)
-- storage.new_user (custom_user ("u2", "p2", "e2")) storage.new_user (custom_user ("u2", "p2", "e2"))
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- storage.update_node_content (2,ll_node.id, "New Content") storage.update_node_content (2,ll_node.id, "New Content")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then not (u_node.content ~ ll_node.content) and then u_node.summary ~ ll_node.summary) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then not (u_node.content ~ ll_node.content) and then u_node.summary ~ ll_node.summary)
-- end end
-- end end
-- test_update_node_title_by_author test_update_node_title_by_author
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- l_node := custom_node ("Content", "Summary", "Title") l_node := custom_node ("Content", "Summary", "Title")
-- storage.new_user (default_user) storage.new_user (default_user)
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- storage.update_node_title (1,ll_node.id, "New Title") storage.update_node_title (1,ll_node.id, "New Title")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary)
-- end end
-- end end
-- test_update_node_summary_by_author test_update_node_summary_by_author
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- l_node := custom_node ("Content", "Summary", "Title") l_node := custom_node ("Content", "Summary", "Title")
-- storage.new_user (default_user) storage.new_user (default_user)
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- storage.update_node_summary (1,ll_node.id, "New Summary") storage.update_node_summary (1,ll_node.id, "New Summary")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then u_node.content ~ ll_node.content and then not (u_node.summary ~ ll_node.summary)) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then u_node.content ~ ll_node.content and then not (u_node.summary ~ ll_node.summary))
-- end end
-- end end
-- test_update_node_content_by_author test_update_node_content_by_author
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- l_node := custom_node ("Content", "Summary", "Title") l_node := custom_node ("Content", "Summary", "Title")
-- storage.new_user (default_user) storage.new_user (default_user)
-- l_node.set_author (storage.user_by_email (default_user.email)) l_node.set_author (storage.user_by_email (default_user.email))
-- storage.new_node (l_node) storage.new_node (l_node)
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- storage.update_node_content (1,ll_node.id, "New Content") storage.update_node_content (1,ll_node.id, "New Content")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then not (u_node.content ~ ll_node.content) and then u_node.summary ~ ll_node.summary) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then not (u_node.content ~ ll_node.content) and then u_node.summary ~ ll_node.summary)
-- end end
-- end end
-- test_delete_node test_delete_node
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- l_user: like {CMS_NODE}.author l_user: like {CMS_NODE}.author
-- do do
-- storage.new_user (custom_user ("test_delete", "testu", "email")) storage.new_user (custom_user ("test_delete", "testu", "email"))
-- l_user := storage.user_by_name ("test_delete") l_user := storage.user_by_name ("test_delete")
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out) l_node := custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)
-- l_node.set_author (l_user) l_node.set_author (l_user)
-- storage.new_node (l_node) storage.new_node (l_node)
-- end end
-- assert ("Exist node id: 10", attached storage.node_by_id (10) as ll_node and then ll_node.title ~ "Title_10" ) assert ("Exist node id: 10", attached storage.node_by_id (10) as ll_node and then ll_node.title ~ "Title_10" )
-- storage.delete_node_by_id (10) storage.delete_node_by_id (10)
-- assert ("Not exist node id: 10", storage.node_by_id (10) = Void) assert ("Not exist node id: 10", storage.node_by_id (10) = Void)
-- end end
end end

View File

@@ -10,7 +10,6 @@
<library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/> <library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/> <library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
<library name="module_node" location="..\..\..\..\modules\node\node-safe.ecf"/>
<library name="persitence_mysql" location="..\persistence_mysql-safe.ecf" readonly="false"/> <library name="persitence_mysql" location="..\persistence_mysql-safe.ecf" readonly="false"/>
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/> <library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/> <library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
@@ -19,7 +18,6 @@
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude> <exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
<exclude>/nodes$</exclude>
</file_rule> </file_rule>
</cluster> </cluster>
</target> </target>

View File

@@ -75,11 +75,11 @@ feature -- Test routines
connection.begin_transaction connection.begin_transaction
u.set_email ("test@example.com") u.set_email ("test@example.com")
assert ("Has user:", storage.user_by_email ("test@example.com") /= Void) assert ("Has user:", storage.user_by_email ("test@example.com") /= Void)
-- storage.new_node (default_node) storage.new_node (default_node)
-- assert ("Has one node:", storage.nodes_count = 1) assert ("Has one node:", storage.nodes_count = 1)
connection.rollback connection.rollback
assert ("Not has user:", storage.user_by_email ("test@example.com") = Void) assert ("Not has user:", storage.user_by_email ("test@example.com") = Void)
-- assert ("Has no node:", storage.nodes_count = 0) assert ("Has no node:", storage.nodes_count = 0)
end end
end end

View File

@@ -41,9 +41,8 @@ feature {NONE} -- Fixture Factories: Nodes
Result := custom_node ("Default content", "default summary", "Default") Result := custom_node ("Default content", "default summary", "Default")
end end
custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_PAGE custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_NODE
do do
create Result.make (a_title) create Result.make (a_content, a_summary, a_title)
Result.set_content (a_content, a_summary, Void)
end end
end end

View File

@@ -8,11 +8,11 @@
<setting name="console_application" value="true"/> <setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\..\cms-safe.ecf"/> <library name="cms" location="..\..\..\cms-safe.ecf"/>
<library name="cms_app_env" location="..\..\app_env\app_env-safe.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/> <library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder-safe.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/> <library name="error" location="$EWF_LIBRARY\library\utility\general\error\error-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\layout\layout-safe.ecf"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/> <library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging-safe.ecf"/>
<library name="model" location="..\..\model\cms_model-safe.ecf"/> <library name="model" location="..\..\model\cms_model-safe.ecf"/>
<library name="odbc" location="$ISE_LIBRARY\library\store\dbms\rdbms\odbc\odbc-safe.ecf"/> <library name="odbc" location="$ISE_LIBRARY\library\store\dbms\rdbms\odbc\odbc-safe.ecf"/>

View File

@@ -9,8 +9,8 @@
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="cms" location="..\..\..\cms.ecf"/> <library name="cms" location="..\..\..\cms.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/> <library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/> <library name="error" location="$EWF_LIBRARY\library\utility\general\error\error.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="layout" location="..\..\layout\layout.ecf"/> <library name="layout" location="..\..\layout\layout.ecf"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/> <library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>

View File

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

View File

@@ -1,5 +1,5 @@
note note
description: "Summary description for {CMS_STORAGE_SQLITE}." description: "Summary description for {CMS_STORAGE_MYSQL}."
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $" date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $" revision: "$Revision: 96596 $"
@@ -7,11 +7,13 @@ class
CMS_STORAGE_SQLITE CMS_STORAGE_SQLITE
inherit inherit
CMS_STORAGE
CMS_STORAGE_STORE_SQL CMS_STORAGE_STORE_SQL
CMS_CORE_STORAGE_SQL_I CMS_USER_STORAGE_SQLITE
CMS_USER_STORAGE_SQL_I CMS_NODE_STORAGE_SQLITE
REFACTORING_HELPER REFACTORING_HELPER
@@ -25,5 +27,5 @@ feature -- Status report
do do
Result := has_user Result := has_user
end end
end end

View File

@@ -1,6 +1,6 @@
note note
description: "[ description: "[
Interface responsible to instantiate CMS_STORAGE_SQLITE object. Objects that ...
]" ]"
author: "$Author: jfiat $" author: "$Author: jfiat $"
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $" date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
@@ -10,9 +10,7 @@ class
CMS_STORAGE_SQLITE_BUILDER CMS_STORAGE_SQLITE_BUILDER
inherit inherit
CMS_STORAGE_STORE_SQL_BUILDER CMS_STORAGE_BUILDER
GLOBAL_SETTINGS
create create
make make
@@ -29,25 +27,65 @@ feature -- Factory
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_SQLITE storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_SQLITE
local local
s: STRING s: STRING
conn: DATABASE_CONNECTION
do do
if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config then if attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.layout.application_config_path) as l_database_config then
s := "Driver=SQLite3 ODBC Driver;Database=" s := "Driver=SQLite3 ODBC Driver;Database="
if attached l_database_config.database_name as db_name then if attached l_database_config.database_name as db_name then
s.append (db_name) s.append (db_name)
end end
s.append (";LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;") s.append (";LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
create {DATABASE_CONNECTION_ODBC} conn.login_with_connection_string (s) create Result.make (create {DATABASE_CONNECTION_ODBC}.login_with_connection_string (s))
if conn.is_connected then --create Result.make (create {DATABASE_CONNECTION_ODBC}.login_with_connection_string (l_database_config.connection_string))
create Result.make (conn) if Result.is_available then
set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default. if not Result.is_initialized then
if Result.is_available then initialize (a_setup, Result)
if not Result.is_initialized then
initialize (a_setup, Result)
end
end end
end end
end end
end end
initialize (a_setup: CMS_SETUP; a_storage: CMS_STORAGE_STORE_SQL)
do
initialize_schema (a_setup, a_storage)
initialize_data (a_setup, a_storage)
end
initialize_schema (a_setup: CMS_SETUP; a_storage: CMS_STORAGE_STORE_SQL)
local
p: PATH
f: PLAIN_TEXT_FILE
sql: STRING
do
p := a_setup.layout.path.extended ("scripts").extended ("sqlite.sql")
create f.make_with_path (p)
if f.exists and then f.is_access_readable then
create sql.make (f.count)
f.open_read
from
f.start
until
f.exhausted or f.end_of_file
loop
f.read_stream_thread_aware (1_024)
sql.append (f.last_string)
end
f.close
a_storage.error_handler.reset
-- a_storage.sql_begin_transaction
a_storage.sql_change (sql, Void)
-- a_storage.sql_commit_transaction
end
end
initialize_data (a_setup: CMS_SETUP; a_storage: CMS_STORAGE_STORE_SQL)
local
u: CMS_USER
do
create u.make ("admin")
u.set_password ("#admin#")
u.set_email (a_setup.site_email)
a_storage.new_user (u)
end
end end

View File

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

View File

@@ -167,107 +167,107 @@ feature -- Test routines
assert ("Valid password", storage.is_valid_credential ("test", "password")) assert ("Valid password", storage.is_valid_credential ("test", "password"))
end end
-- test_recent_nodes_empty test_recent_nodes_empty
-- do do
-- assert ("No recent nodes", storage.recent_nodes (0, 10).is_empty) assert ("No recent nodes", storage.recent_nodes (0, 10).is_empty)
-- end end
-- test_recent_nodes test_recent_nodes
-- local local
-- l_nodes: LIST[CMS_NODE] l_nodes: LIST[CMS_NODE]
-- do do
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out))
-- end end
-- l_nodes := storage.recent_nodes (0, 10) l_nodes := storage.recent_nodes (0, 10)
-- assert ("10 recent nodes", l_nodes.count = 10) assert ("10 recent nodes", l_nodes.count = 10)
-- assert ("First node id=10", l_nodes.first.id = 10) assert ("First node id=10", l_nodes.first.id = 10)
-- assert ("Last node id=1", l_nodes.last.id = 1) assert ("Last node id=1", l_nodes.last.id = 1)
-- l_nodes := storage.recent_nodes (5, 10) l_nodes := storage.recent_nodes (5, 10)
-- assert ("5 recent nodes", l_nodes.count = 5) assert ("5 recent nodes", l_nodes.count = 5)
-- assert ("First node id=5", l_nodes.first.id = 5) assert ("First node id=5", l_nodes.first.id = 5)
-- assert ("Last node id=1", l_nodes.last.id = 1) assert ("Last node id=1", l_nodes.last.id = 1)
-- l_nodes := storage.recent_nodes (9, 10) l_nodes := storage.recent_nodes (9, 10)
-- assert ("1 recent nodes", l_nodes.count = 1) assert ("1 recent nodes", l_nodes.count = 1)
-- assert ("First node id=1", l_nodes.first.id = 1) assert ("First node id=1", l_nodes.first.id = 1)
-- assert ("Last node id=1", l_nodes.last.id = 1) assert ("Last node id=1", l_nodes.last.id = 1)
-- l_nodes := storage.recent_nodes (10, 10) l_nodes := storage.recent_nodes (10, 10)
-- assert ("Is empty", l_nodes.is_empty) assert ("Is empty", l_nodes.is_empty)
-- end end
-- test_node_does_not_exist test_node_does_not_exist
-- do do
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out))
-- end end
-- assert ("Not exist node id: 12", storage.node_by_id (12) = Void) assert ("Not exist node id: 12", storage.node_by_id (12) = Void)
-- end end
-- test_node test_node
-- do do
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out))
-- end end
-- assert ("has nodes", storage.nodes.count > 5) assert ("has nodes", storage.nodes.count > 5)
-- assert ("Node id: 10", attached storage.node_by_id (10) as l_node and then l_node.title ~ "Title_10" ) assert ("Node id: 10", attached storage.node_by_id (10) as l_node and then l_node.title ~ "Title_10" )
-- end end
-- test_update_node test_update_node
-- local local
-- l_node: CMS_NODE l_node: CMS_NODE
-- do do
-- storage.new_node (custom_node ("Content", "Summary", "Title")) storage.new_node (custom_node ("Content", "Summary", "Title"))
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
-- l_node := ll_node.twin l_node := ll_node.twin
-- l_node.set_content ("New Content") l_node.set_content ("New Content")
-- l_node.set_summary ("New Summary") l_node.set_summary ("New Summary")
-- l_node.set_title("New Title") l_node.set_title("New Title")
---- storage.update_node (l_node) -- storage.update_node (l_node)
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then not (u_node.content ~ ll_node.content) and then not (u_node.summary ~ ll_node.summary)) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then not (u_node.content ~ ll_node.content) and then not (u_node.summary ~ ll_node.summary))
-- end end
-- end end
-- test_update_node_title test_update_node_title
-- do do
-- storage.new_node (custom_node ("Content", "Summary", "Title")) storage.new_node (custom_node ("Content", "Summary", "Title"))
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
---- storage.update_node_title (ll_node.id, "New Title") -- storage.update_node_title (ll_node.id, "New Title")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then not (u_node.title ~ ll_node.title) and then u_node.content ~ ll_node.content and then u_node.summary ~ ll_node.summary)
-- end end
-- end end
-- test_update_node_summary test_update_node_summary
-- do do
-- storage.new_node (custom_node ("Content", "Summary", "Title")) storage.new_node (custom_node ("Content", "Summary", "Title"))
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
---- storage.update_node_summary (ll_node.id, "New Summary") -- storage.update_node_summary (ll_node.id, "New Summary")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then u_node.content ~ ll_node.content and then not (u_node.summary ~ ll_node.summary)) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then u_node.content ~ ll_node.content and then not (u_node.summary ~ ll_node.summary))
-- end end
-- end end
-- test_update_node_content test_update_node_content
-- do do
-- storage.new_node (custom_node ("Content", "Summary", "Title")) storage.new_node (custom_node ("Content", "Summary", "Title"))
-- if attached {CMS_NODE} storage.node_by_id (1) as ll_node then if attached {CMS_NODE} storage.node_by_id (1) as ll_node then
---- storage.update_node_content (ll_node.id, "New Content") -- storage.update_node_content (ll_node.id, "New Content")
-- assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then not (u_node.content ~ ll_node.content) and then u_node.summary ~ ll_node.summary) assert ("Updated", attached {CMS_NODE} storage.node_by_id (1) as u_node and then u_node.title ~ ll_node.title and then not (u_node.content ~ ll_node.content) and then u_node.summary ~ ll_node.summary)
-- end end
-- end end
-- test_delete_node test_delete_node
-- do do
-- across 1 |..| 10 as c loop across 1 |..| 10 as c loop
-- storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out)) storage.new_node (custom_node ("Content_" + c.item.out, "Summary_" + c.item.out, "Title_" + c.item.out))
-- end end
-- assert ("Exist node id: 10", attached storage.node_by_id (10) as l_node and then l_node.title ~ "Title_10" ) assert ("Exist node id: 10", attached storage.node_by_id (10) as l_node and then l_node.title ~ "Title_10" )
-- storage.delete_node_by_id (10) storage.delete_node_by_id (10)
-- assert ("Not exist node id: 10", storage.node_by_id (10) = Void) assert ("Not exist node id: 10", storage.node_by_id (10) = Void)
-- end end
end end

View File

@@ -10,7 +10,6 @@
<library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/> <library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/> <library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
<library name="module_node" location="..\..\..\..\modules\node\node-safe.ecf"/>
<library name="persitence_sqlite" location="..\persistence_sqlite-safe.ecf" readonly="false"/> <library name="persitence_sqlite" location="..\persistence_sqlite-safe.ecf" readonly="false"/>
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/> <library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/> <library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
@@ -19,7 +18,6 @@
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude> <exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
<exclude>/nodes$</exclude>
</file_rule> </file_rule>
</cluster> </cluster>
</target> </target>

View File

@@ -38,18 +38,17 @@ feature {NONE} -- Fixture Factory: Users
Result.set_email (a_email) Result.set_email (a_email)
end end
--feature {NONE} -- Fixture Factories: Nodes feature {NONE} -- Fixture Factories: Nodes
-- default_node: CMS_NODE default_node: CMS_NODE
-- do do
-- Result := custom_node ("Default content", "default summary", "Default") Result := custom_node ("Default content", "default summary", "Default")
-- end end
-- custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_PAGE custom_node (a_content, a_summary, a_title: READABLE_STRING_32): CMS_NODE
-- do do
-- create Result.make (a_title) create Result.make (a_content, a_summary, a_title)
-- Result.set_content (a_content, a_summary, Void) end
-- end
end end

View File

@@ -1 +0,0 @@
Location for contributed CMS modules.

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="basic_auth" uuid="05216FE9-20F3-45FB-AB2E-8FCD75A8AD7E" library_target="basic_auth">
<target name="basic_auth">
<root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms-safe.ecf"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
<cluster name="src" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="basic_auth" uuid="05216FE9-20F3-45FB-AB2E-8FCD75A8AD7E" library_target="basic_auth">
<target name="basic_auth">
<root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="cms" location="..\..\cms.ecf"/>
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/>
<cluster name="src" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -1,42 +0,0 @@
note
description: "[
Interface defining a CMS content type.
]"
status: "draft"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_CONTENT_TYPE
inherit
CMS_API_ACCESS
feature -- Access
name: READABLE_STRING_8
-- Internal name.
deferred
end
title: READABLE_STRING_32
-- Human readable name.
deferred
end
description: detachable READABLE_STRING_32
-- Optional description
deferred
end
feature -- Access
available_formats: LIST [CONTENT_FORMAT]
-- Available formats for Current type.
deferred
end
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,331 +0,0 @@
note
description: "[
API to manage CMS Nodes
]"
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
class
CMS_NODE_API
inherit
CMS_MODULE_API
redefine
initialize
end
REFACTORING_HELPER
create
make
feature {NONE} -- Implementation
initialize
-- <Precursor>
do
Precursor
if attached {CMS_STORAGE_SQL_I} storage as l_storage_sql then
create {CMS_NODE_STORAGE_SQL} node_storage.make (l_storage_sql)
else
create {CMS_NODE_STORAGE_NULL} node_storage.make
end
initialize_node_types
end
initialize_node_types
-- Initialize content type system.
local
ct: CMS_PAGE_NODE_TYPE
do
create content_types.make (1)
create content_type_webform_managers.make (1)
create ct
add_content_type (ct)
add_content_type_webform_manager (create {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}.make (ct))
end
feature {CMS_MODULE} -- Access nodes storage.
node_storage: CMS_NODE_STORAGE_I
feature -- Content type
content_types: ARRAYED_LIST [CMS_CONTENT_TYPE]
-- Available content types
node_types: ARRAYED_LIST [attached like node_type]
-- Node content types.
do
create Result.make (content_types.count)
across
content_types as ic
loop
if attached {like node_type} ic.item as l_node_type then
Result.extend (l_node_type)
end
end
end
add_content_type (a_type: CMS_CONTENT_TYPE)
-- Register content type `a_type'.
do
content_types.force (a_type)
end
content_type (a_name: READABLE_STRING_GENERAL): detachable CMS_CONTENT_TYPE
-- Content type named `a_named' if any.
do
across
content_types as ic
until
Result /= Void
loop
Result := ic.item
if not a_name.is_case_insensitive_equal (Result.name) then
Result := Void
end
end
end
node_type (a_name: READABLE_STRING_GENERAL): detachable CMS_NODE_TYPE [CMS_NODE]
-- Content type named `a_named' if any.
do
across
content_types as ic
until
Result /= Void
loop
if
attached {like node_type} ic.item as l_node_type and then
a_name.is_case_insensitive_equal (l_node_type.name)
then
Result := l_node_type
end
end
end
node_type_for (a_node: CMS_NODE): like node_type
-- Content type for node `a_node' if any.
local
l_type_name: READABLE_STRING_8
do
l_type_name := a_node.content_type
Result := node_type (l_type_name)
end
feature -- Content type webform
content_type_webform_managers: ARRAYED_LIST [CMS_CONTENT_TYPE_WEBFORM_MANAGER]
-- Available content types
add_content_type_webform_manager (a_manager: CMS_CONTENT_TYPE_WEBFORM_MANAGER)
-- Register webform manager `a_manager'.
do
content_type_webform_managers.force (a_manager)
end
content_type_webform_manager (a_content_type: CMS_CONTENT_TYPE): detachable CMS_CONTENT_TYPE_WEBFORM_MANAGER
-- Web form manager for content type `a_content_type' if any.
local
l_type_name: READABLE_STRING_GENERAL
do
l_type_name := a_content_type.name
across
content_type_webform_managers as ic
until
Result /= Void
loop
Result := ic.item
if not l_type_name.is_case_insensitive_equal (Result.name) then
Result := Void
end
end
end
node_type_webform_manager (a_node_type: CMS_CONTENT_TYPE): detachable CMS_NODE_TYPE_WEBFORM_MANAGER_I [CMS_NODE]
-- Web form manager for node type `a_node_type' if any.
local
l_type_name: READABLE_STRING_GENERAL
do
l_type_name := a_node_type.name
across
content_type_webform_managers as ic
until
Result /= Void
loop
if
attached {like node_type_webform_manager} ic.item as l_manager and then
l_type_name.is_case_insensitive_equal (l_manager.name)
then
Result := l_manager
end
end
end
feature -- URL
new_content_path (ct: detachable CMS_CONTENT_TYPE): STRING
-- URI path for new content of type `ct'
-- or URI of path for selection of new content possibilities if ct is Void.
do
if ct /= Void then
Result := "/node/add/" + ct.name
else
Result := "/node/"
end
end
node_link (a_node: CMS_NODE): CMS_LOCAL_LINK
-- CMS link for node `a_node'.
require
a_node.has_id
do
create Result.make (a_node.title, cms_api.path_alias (node_path (a_node)))
end
node_path (a_node: CMS_NODE): STRING
-- URI path for node `a_node'.
-- using the /node/{nid} url.
require
a_node.has_id
do
Result := "/node/" + a_node.id.out
end
nodes_path: STRING
-- URI path for list of nodes.
do
Result := "/nodes"
end
feature -- Access: Node
nodes_count: INTEGER_64
do
Result := node_storage.nodes_count
end
nodes: LIST [CMS_NODE]
-- List of nodes.
do
Result := node_storage.nodes
end
recent_nodes (a_offset, a_rows: INTEGER): LIST [CMS_NODE]
-- List of the `a_rows' most recent nodes starting from `a_offset'.
do
Result := node_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 := full_node (node_storage.node_by_id (a_id))
end
full_node (a_node: detachable CMS_NODE): detachable CMS_NODE
-- If `a_node' is partial, return the full node from `a_node',
-- otherwise return directly `a_node'.
do
if attached {CMS_PARTIAL_NODE} a_node as l_partial_node then
if attached node_type_for (l_partial_node) as ct then
Result := ct.new_node (l_partial_node)
node_storage.fill_node (Result)
else
Result := l_partial_node
end
else
Result := a_node
end
-- Update link with aliasing.
if a_node /= Void and then a_node.has_id then
a_node.set_link (node_link (a_node))
end
-- Update partial user if needed.
if
Result /= Void and then
attached {CMS_PARTIAL_USER} Result.author as l_partial_author
then
if attached cms_api.user_api.user_by_id (l_partial_author.id) as l_author then
Result.set_author (l_author)
else
check
valid_author_id: False
end
end
end
end
is_author_of_node (u: CMS_USER; a_node: CMS_NODE): BOOLEAN
-- Is the user `u' owner of the node `n'.
do
if attached node_storage.node_author (a_node.id) as l_author then
Result := u.same_as (l_author)
end
end
feature -- Permission Scope: Node
has_permission_for_action_on_node (a_action: READABLE_STRING_8; a_node: CMS_NODE; a_user: detachable CMS_USER; ): BOOLEAN
-- Has permission to execute action `a_action' on node `a_node', by eventual user `a_user'?
local
l_type_name: READABLE_STRING_8
do
l_type_name := a_node.content_type
Result := cms_api.user_has_permission (a_user, a_action + " any " + l_type_name)
if not Result and a_user /= Void then
if is_author_of_node (a_user, a_node) then
Result := cms_api.user_has_permission (a_user, a_action + " own " + l_type_name)
end
end
end
feature -- Change: Node
save_node (a_node: CMS_NODE)
-- Save `a_node'.
do
node_storage.save_node (a_node)
end
new_node (a_node: CMS_NODE)
-- Add a new node `a_node'
require
no_id: not a_node.has_id
do
node_storage.new_node (a_node)
end
delete_node (a_node: CMS_NODE)
-- Delete `a_node'.
do
if a_node.has_id then
node_storage.delete_node (a_node)
end
end
update_node (a_node: CMS_NODE)
-- Update node `a_node' data.
do
node_storage.update_node (a_node)
end
feature -- Node status
Not_published: INTEGER = 0
-- The node is not published.
Published: INTEGER = 1
-- The node is published.
Trashed: INTEGER = -1
-- The node is trashed (soft delete), ready to be deleted/destroyed from storage.
end

View File

@@ -1,30 +0,0 @@
note
description: "[
Interface defining a CMS content type.
]"
status: "draft"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_NODE_TYPE [G -> CMS_NODE]
inherit
CMS_CONTENT_TYPE
feature -- Factory
new_node_with_title (a_title: READABLE_STRING_32; a_partial_node: detachable CMS_NODE): like new_node
-- New node with `a_title' and fill from partial `a_partial_node' if set.
deferred
end
new_node (a_partial_node: detachable CMS_NODE): G
-- New node based on partial `a_partial_node' if set.
deferred
end
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,268 +0,0 @@
note
description: "[
CMS abstraction for CMS content entity, named "node".
]"
status: "draft"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
deferred class
CMS_NODE
inherit
REFACTORING_HELPER
feature{NONE} -- Initialization
make_empty
-- Create empty node.
do
make ({STRING_32} "")
end
make (a_title: READABLE_STRING_32)
-- Create current node with `a_title'.
local
l_time: DATE_TIME
do
create l_time.make_now_utc
set_title (a_title)
set_creation_date (l_time)
set_modification_date (l_time)
set_publication_date (l_time)
mark_not_published
ensure
title_set: title = a_title
end
feature -- Conversion
import_node (a_node: CMS_NODE)
-- Import `a_node' into current node.
do
set_id (a_node.id)
set_revision (a_node.revision)
set_title (a_node.title)
set_creation_date (a_node.creation_date)
set_modification_date (a_node.modification_date)
set_publication_date (a_node.publication_date)
set_author (a_node.author)
set_content (
a_node.content,
a_node.summary,
a_node.format
)
set_status (a_node.status)
set_link (a_node.link)
end
feature -- Access
id: INTEGER_64 assign set_id
-- Unique id.
--| Should we use NATURAL_64 instead?
revision: INTEGER_64 assign set_revision
-- Revision value.
--| Note: for now version is not supported.
content_type: READABLE_STRING_8
-- Associated content type name.
-- Page, Article, Blog, News, etc.
deferred
end
status: INTEGER
-- Associated status for the current node.
-- default: {CMS_NODE_API}.Not_Published}
-- {CMS_NODE_API}.Published
-- {CMS_NODE_API}.Trashed
feature -- Access
title: READABLE_STRING_32
-- Full title of the node.
-- Required!
summary: detachable READABLE_STRING_8
-- A short summary of the node.
deferred
end
content: detachable READABLE_STRING_8
-- Content of the node.
deferred
end
format: detachable READABLE_STRING_8
-- Format associated with `content' and `summary'.
-- For example: text, mediawiki, html, etc
deferred
end
feature -- Access: date
modification_date: DATE_TIME
-- When the node was updated.
creation_date: DATE_TIME
-- When the node was created.
publication_date: DATE_TIME
-- When the node was published.
publication_date_output: READABLE_STRING_32
-- Formatted output.
feature -- Access: author
author: detachable CMS_USER
-- Author of current node.
feature -- status report
has_id: BOOLEAN
-- Has unique identifier?
do
Result := id > 0
end
same_node (a_node: CMS_NODE): BOOLEAN
-- Is `a_node' same node as Current?
do
-- FIXME: if we introduce notion of revision, update this part!
Result := Current = a_node or id = a_node.id
ensure
valid_result: Result implies a_node.id = id
end
is_typed_as (a_content_type: READABLE_STRING_GENERAL): BOOLEAN
-- Is current node of type `a_content_type' ?
do
Result := a_content_type.is_case_insensitive_equal (content_type)
end
feature -- Access: menu
link: detachable CMS_LOCAL_LINK
-- Associated menu link.
feature -- Element change
set_content (a_content: like content; a_summary: like summary; a_format: like format)
-- Set `content', `summary' and `format' to `a_content', `a_summary' and `a_format'.
-- The `format' is associated with both `content' and `summary'
deferred
ensure
content_assigned: content = a_content
summary_assigned: summary = a_summary
format_assigned: format = a_format
end
set_title (a_title: like title)
-- Assign `title' with `a_title'.
do
title := a_title
if attached link as lnk then
lnk.set_title (a_title)
end
ensure
title_assigned: title = a_title
end
set_modification_date (a_modification_date: like modification_date)
-- Assign `modification_date' with `a_modification_date'.
do
modification_date := a_modification_date
ensure
modification_date_assigned: modification_date = a_modification_date
end
set_creation_date (a_creation_date: like creation_date)
-- Assign `creation_date' with `a_creation_date'.
do
creation_date := a_creation_date
ensure
creation_date_assigned: creation_date = a_creation_date
end
set_publication_date (a_publication_date: like publication_date)
-- Assign `publication_date' with `a_publication_date'.
do
publication_date := a_publication_date
publication_date_output := publication_date.formatted_out ("yyyy/[0]mm/[0]dd")
ensure
publication_date_assigned: publication_date = a_publication_date
end
set_id (a_id: like id)
-- Assign `id' with `a_id'.
do
id := a_id
ensure
id_assigned: id = a_id
end
set_revision (a_revision: like revision)
-- Assign `revision' with `a_revision'.
do
revision := a_revision
ensure
revision_assigned: revision = a_revision
end
set_author (u: like author)
-- Assign 'author' with `u'
do
author := u
ensure
auther_set: author = u
end
set_link (a_link: like link)
-- Set `link' to `a_link'.
do
link := a_link
end
feature -- Status change
mark_not_published
-- Set status to not_published.
do
set_status ({CMS_NODE_API}.not_published)
ensure
status_not_published: status = {CMS_NODE_API}.not_published
end
mark_published
-- Set status to published.
do
set_status ({CMS_NODE_API}.published)
ensure
status_published: status = {CMS_NODE_API}.published
end
mark_trashed
-- Set status to trashed.
do
set_status ({CMS_NODE_API}.trashed)
ensure
status_trash: status = {CMS_NODE_API}.trashed
end
feature {CMS_NODE_STORAGE_I} -- Access: status change.
set_status (a_status: like status)
-- Assign `status' with `a_status'.
do
status := a_status
ensure
status_set: status = a_status
end
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,85 +0,0 @@
note
description: "Node object representing the CMS_NODE data in database."
date: "$Date$"
revision: "$Revision$"
class
CMS_PARTIAL_NODE
inherit
CMS_NODE
rename
make_empty as make_empty_node,
set_content as set_all_content
end
create
make_empty
feature {NONE} -- Initialization
make_empty (a_content_type: READABLE_STRING_8)
require
type_not_blank: not a_content_type.is_whitespace
do
content_type := a_content_type
make_empty_node
end
feature -- Access: code
content_type: READABLE_STRING_8
-- <Precursor>
feature -- Access: content
summary: detachable READABLE_STRING_8
-- A short summary of the node.
content: detachable READABLE_STRING_8
-- Content of the node.
format: detachable READABLE_STRING_8
-- Format associated with `content' and `summary'.
-- For example: text, mediawiki, html, etc
feature -- Element change
set_all_content (a_content: like content; a_summary: like summary; a_format: like format)
-- <Precursor>
do
set_content (a_content)
set_summary (a_summary)
set_format (a_format)
end
set_content (a_content: like content)
-- Assign `content' with `a_content', and set the associated `format'.
do
content := a_content
ensure
content_assigned: content = a_content
end
set_summary (a_summary: like summary)
-- Assign `summary' with `a_summary'.
do
summary := a_summary
ensure
summary_assigned: summary = a_summary
end
set_format (a_format: like format)
-- Assign `format' with `a_format'.
do
format := a_format
ensure
format_assigned: format = a_format
end
invariant
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,95 +0,0 @@
note
description: "A page node."
date: "$Date$"
revision: "$Revision$"
class
CMS_PAGE
inherit
CMS_NODE
redefine
make_empty,
import_node
end
create
make_empty,
make
feature {NONE} -- Initialization
make_empty
do
Precursor
end
feature -- Conversion
import_node (a_node: CMS_NODE)
-- <Precursor>
do
Precursor (a_node)
if attached {CMS_PAGE} a_node as l_page then
set_parent (l_page.parent)
end
end
feature -- Access
content_type: READABLE_STRING_8
once
Result := {CMS_PAGE_NODE_TYPE}.name
end
feature -- Access: content
summary: detachable READABLE_STRING_8
-- A short summary of the node.
content: detachable READABLE_STRING_8
-- Content of the node.
format: detachable READABLE_STRING_8
-- Format associated with `content' and `summary'.
-- For example: text, mediawiki, html, etc
parent: detachable CMS_PAGE
-- Eventual parent page.
--| Used to describe a book structure.
feature -- Element change
set_content (a_content: like content; a_summary: like summary; a_format: like format)
do
content := a_content
summary := a_summary
format := a_format
end
set_parent (a_page: detachable CMS_PAGE)
-- Set `parent' to `a_page'
require
Current_is_not_parent_of_a_page: not is_parent_of (a_page)
do
parent := a_page
end
feature -- Status report
is_parent_of (a_page: detachable CMS_PAGE): BOOLEAN
-- Is Current page, a parent of `a_page' ?
do
if
a_page /= Void and then
attached a_page.parent as l_parent
then
if l_parent.same_node (a_page) then
Result := True
else
Result := is_parent_of (l_parent)
end
end
end
end

View File

@@ -1,64 +0,0 @@
note
description: "Summary description for {CMS_PAGE_NODE_TYPE}."
date: "$Date$"
revision: "$Revision$"
class
CMS_PAGE_NODE_TYPE
inherit
CMS_NODE_TYPE [CMS_PAGE]
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
create {ARRAYED_LIST [like available_formats.item]} available_formats.make (4)
available_formats.extend (create {PLAIN_TEXT_CONTENT_FORMAT})
available_formats.extend (create {FILTERED_HTML_CONTENT_FORMAT})
available_formats.extend (create {FULL_HTML_CONTENT_FORMAT})
available_formats.extend (create {CMS_EDITOR_CONTENT_FORMAT})
end
feature -- Access
name: STRING = "page"
-- Internal name.
title: STRING_32 = "Page"
-- Human readable name.
description: STRING_32 = "Use basic pages for your content, such as an 'About us' page."
-- Optional description
feature -- Access
available_formats: LIST [CONTENT_FORMAT]
-- Available formats for Current type.
feature -- Factory
new_node_with_title (a_title: READABLE_STRING_32; a_partial_node: detachable CMS_NODE): like new_node
-- New node with `a_title' and fill from partial `a_partial_node' if set.
do
create Result.make (a_title)
if a_partial_node /= Void then
Result.import_node (a_partial_node)
Result.set_title (a_title)
end
end
new_node (a_partial_node: detachable CMS_NODE): CMS_PAGE
-- New node based on partial `a_partial_node', or from none.
do
create Result.make_empty
if a_partial_node /= Void then
Result.import_node (a_partial_node)
end
end
end

View File

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

View File

@@ -1,33 +0,0 @@
note
description: "[
Html builder for content type `content_type'.
This is used to build webform and html output for a specific node, or node content type.
]"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_CONTENT_TYPE_WEBFORM_MANAGER
inherit
CMS_API_ACCESS
feature {NONE} -- Initialization
make (a_type: like content_type)
do
content_type := a_type
end
feature -- Access
content_type: CMS_CONTENT_TYPE
-- Associated content type.
name: READABLE_STRING_8
-- Associated content type name.
do
Result := content_type.name
end
end

View File

@@ -1,281 +0,0 @@
note
description: "Summary description for {CMS_NODE_TYPE_WEBFORM_MANAGER}."
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_NODE_TYPE_WEBFORM_MANAGER [G -> CMS_NODE]
inherit
CMS_NODE_TYPE_WEBFORM_MANAGER_I [G]
feature -- Forms ...
populate_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
local
ti: WSF_FORM_TEXT_INPUT
fset: WSF_FORM_FIELD_SET
ta, sum: CMS_FORM_TEXTAREA
tselect: WSF_FORM_SELECT
opt: WSF_FORM_SELECT_OPTION
cms_format: CMS_EDITOR_CONTENT_FORMAT
do
create cms_format
create ti.make ("title")
ti.set_label ("Title")
ti.set_size (70)
if a_node /= Void then
ti.set_text_value (a_node.title)
end
ti.set_is_required (True)
f.extend (ti)
f.extend_html_text ("<br/>")
-- Select field has to be initialized before textareas are replaced, because they depend on the selection of the field
create tselect.make ("format")
tselect.set_label ("Body's format")
tselect.set_is_required (True)
-- Main Content
create ta.make ("body")
ta.set_rows (10)
ta.set_cols (70)
ta.show_as_editor_if_selected (tselect, cms_format.name)
if a_node /= Void then
ta.set_text_value (a_node.content)
end
ta.set_label ("Content")
ta.set_description ("This is the main content")
ta.set_is_required (False)
-- Summary
create sum.make ("summary")
sum.set_rows (3)
sum.set_cols (70)
-- if cms_html is selected
sum.show_as_editor_if_selected (tselect, cms_format.name)
if a_node /= Void then
sum.set_text_value (a_node.summary)
end
sum.set_label ("Summary")
sum.set_description ("This is the summary")
sum.set_is_required (False)
create fset.make
fset.set_legend ("Body")
-- Add summary
fset.extend (sum)
fset.extend_html_text("<br />")
-- Add content (body)
fset.extend (ta)
fset.extend_html_text ("<br/>")
across
content_type.available_formats as c
loop
create opt.make (c.item.name, c.item.title)
if attached c.item.html_help as f_help then
opt.set_description ("<ul>" + f_help + "</ul>")
end
tselect.add_option (opt)
end
if a_node /= Void and then attached a_node.format as l_format then
tselect.set_text_by_value (l_format)
end
fset.extend (tselect)
f.extend (fset)
-- Path alias
create ti.make ("path_alias")
ti.set_label ("Path")
ti.set_size (70)
if a_node /= Void and then a_node.has_id then
if attached a_node.link as lnk then
ti.set_text_value (lnk.location)
else
ti.set_text_value (response.api.path_alias (response.node_api.node_path (a_node)))
end
end
if
attached f.fields_by_name ("title") as l_title_fields and then
attached l_title_fields.first as l_title_field
then
f.insert_after (ti, l_title_field)
else
f.extend (ti)
end
end
update_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: CMS_NODE)
local
b,s: detachable READABLE_STRING_8
f: detachable CONTENT_FORMAT
do
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
check a_node.id = l_id end
end
if attached fd.string_item ("title") as l_title then
a_node.set_title (l_title)
end
if attached fd.string_item ("body") as l_body then
b := l_body
end
-- Read out the summary field from the form data
if attached fd.string_item ("summary") as l_summary then
s := l_summary
end
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
f := f_format
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
f := f_format
else
f := response.formats.default_format
end
-- Update node with summary and body content
if b /= Void then
a_node.set_content (b, s, f.name)
end
end
new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable CMS_NODE): G
-- <Precursor>
local
b,s: detachable READABLE_STRING_8
f: detachable CONTENT_FORMAT
l_node: detachable like new_node
do
if attached {like new_node} a_node as l_arg_node then
l_node := l_arg_node
else
l_node := content_type.new_node (a_node)
end
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
if l_node /= Void then
check l_node.id = l_id end
else
if attached {like new_node} response.node_api.node (l_id) as n then
l_node := n
else
-- FIXME: Error
end
end
end
if attached fd.string_item ("title") as l_title then
if l_node = Void then
l_node := content_type.new_node (Void)
l_node.set_title (l_title)
else
l_node.set_title (l_title)
end
else
if l_node = Void then
l_node := content_type.new_node_with_title ("...", Void)
end
end
l_node.set_author (response.user)
--Summary
if attached fd.string_item ("summary") as l_summary then
s := l_summary
end
--Content
if attached fd.string_item ("body") as l_body then
b := l_body
end
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
f := f_format
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
f := f_format
else
f := response.formats.default_format
end
-- Update node with summary and content
if b /= Void then
l_node.set_content (b, s, f.name)
end
Result := l_node
end
feature -- Output
append_html_output_to (a_node: CMS_NODE; a_response: NODE_RESPONSE)
-- <Precursor>
local
lnk: CMS_LOCAL_LINK
hdate: HTTP_DATE
s: STRING
node_api: CMS_NODE_API
do
node_api := a_response.node_api
a_response.add_variable (a_node, "node")
create lnk.make (a_response.translation ("View", Void), a_response.node_local_link (a_node).location)
lnk.set_weight (1)
a_response.add_to_primary_tabs (lnk)
create lnk.make ("Edit", node_api.node_path (a_node) + "/edit")
lnk.set_weight (2)
a_response.add_to_primary_tabs (lnk)
create s.make_empty
s.append ("<div class=%"info%"> ")
if attached a_node.author as l_author then
s.append (" by ")
s.append (l_author.name)
end
if attached a_node.modification_date as l_modified then
s.append (" (modified: ")
create hdate.make_from_date_time (l_modified)
s.append (hdate.yyyy_mmm_dd_string)
s.append (")")
end
s.append ("</div>")
-- We don't show the summary on the detail page, since its just a short view of the full content. Otherwise we would write the same thing twice.
-- The usage of the summary is to give a short overview in the list of nodes or for the meta tag "description"
-- if attached a_node.summary as l_summary then
-- s.append ("<p class=%"summary%">")
-- if attached node_api.cms_api.format (a_node.format) as f then
-- s.append (f.formatted_output (l_summary))
-- else
-- s.append (a_response.formats.default_format.formatted_output (l_summary))
-- end
-- s.append ("</p>")
-- end
if attached a_node.content as l_content then
s.append ("<p class=%"content%">")
if attached node_api.cms_api.format (a_node.format) as f then
s.append (f.formatted_output (l_content))
else
s.append (a_response.formats.default_format.formatted_output (l_content))
end
s.append ("</p>")
end
a_response.set_title (a_node.title)
a_response.set_main_content (s)
end
end

Some files were not shown because too many files have changed in this diff Show More