Implemented CMS storage for user and nodes.
Implemented role and permission storage.
Introduced the CMS_PARTIAL_NODE and CMS_PARTIAL_USER.
Added support for node storage extension
- storage of data specific to each node content type,
- in addition to the core CMS_NODE)
- For now, only implemented for SQL storage.
Note: in current version, CMS_PAGE support is hard coded in the core,
(as opposed to be only supported by the node module.)
Commented/removed for now, the Web API code to update node summary, title, via REST request.
This commit is contained in:
@@ -12,23 +12,22 @@ CREATE TABLE "users"(
|
|||||||
UNIQUE("name")
|
UNIQUE("name")
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE "users_roles"(
|
CREATE TABLE "roles"(
|
||||||
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
|
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
|
||||||
"role" VARCHAR(100) NOT NULL,
|
"name" VARCHAR(100) NOT NULL,
|
||||||
CONSTRAINT "role"
|
CONSTRAINT "name"
|
||||||
UNIQUE("role")
|
UNIQUE("name")
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE "nodes"(
|
CREATE TABLE "users_roles"(
|
||||||
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
|
"uid" INTEGER NOT NULL CHECK("uid">=0),
|
||||||
"version" INTEGER,
|
"rid" INTEGER NOT NULL CHECK("rid">=0)
|
||||||
"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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "role_permissions"(
|
||||||
|
"rid" INTEGER NOT NULL CHECK("rid">=0),
|
||||||
|
"permission" VARCHAR(255) NOT NULL,
|
||||||
|
"module" VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
22
examples/demo/site/scripts/node.sql
Normal file
22
examples/demo/site/scripts/node.sql
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
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 NOT NULL,
|
||||||
|
"content" MEDIUMTEXT NOT NULL,
|
||||||
|
"author" INTEGER,
|
||||||
|
"publish" DATETIME,
|
||||||
|
"created" DATETIME NOT NULL,
|
||||||
|
"changed" DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE page_nodes(
|
||||||
|
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
|
||||||
|
"revision" INTEGER,
|
||||||
|
"parent" INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
15
examples/demo/site/themes/bootstrap/assets/css/node.css
Normal file
15
examples/demo/site/themes/bootstrap/assets/css/node.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
ul.cms-nodes {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 3px 3px 3px 3px;
|
||||||
|
border: solid 1px #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.cms_type_page {
|
||||||
|
border-top: dotted 1px #ccc;
|
||||||
|
}
|
||||||
|
li.cms_type_page a::before {
|
||||||
|
content: "[page] ";
|
||||||
|
}
|
||||||
|
li.cms_type_page:first-child {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
14
examples/demo/site/themes/bootstrap/assets/scss/node.scss
Normal file
14
examples/demo/site/themes/bootstrap/assets/scss/node.scss
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
ul.cms-nodes {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 3px 3px 3px 3px;
|
||||||
|
border: solid 1px #ccc;
|
||||||
|
}
|
||||||
|
li.cms_type_page {
|
||||||
|
a::before {
|
||||||
|
content: "[page] ";
|
||||||
|
}
|
||||||
|
border-top: dotted 1px #ccc;
|
||||||
|
&:first-child {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,38 @@
|
|||||||
{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="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="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}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<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">
|
||||||
<!-- 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">
|
||||||
@@ -70,8 +71,6 @@
|
|||||||
<!-- 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>
|
||||||
|
|||||||
@@ -6,10 +6,29 @@ note
|
|||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
deferred class
|
||||||
CMS_CONTENT_TYPE
|
CMS_CONTENT_TYPE
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: READABLE_STRING_8
|
||||||
|
-- Internal name.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
title: READABLE_STRING_32
|
||||||
|
-- Human readable name.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Factory
|
||||||
|
|
||||||
|
new_node (a_partial_node: detachable CMS_NODE): CMS_NODE
|
||||||
|
-- New node based on partial `a_partial_node', or from none.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2015, 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
|
||||||
|
|||||||
@@ -6,33 +6,31 @@ note
|
|||||||
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) $"
|
||||||
revision: "$Revision: 96542 $"
|
revision: "$Revision: 96542 $"
|
||||||
|
|
||||||
class
|
deferred class
|
||||||
CMS_NODE
|
CMS_NODE
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
create
|
--create
|
||||||
make,
|
-- make,
|
||||||
make_empty
|
-- make_empty
|
||||||
|
|
||||||
feature{NONE} -- Initialization
|
feature{NONE} -- Initialization
|
||||||
|
|
||||||
make_empty
|
make_empty
|
||||||
-- Create empty node.
|
-- Create empty node.
|
||||||
do
|
do
|
||||||
make ({STRING_32} "", {STRING_32} "", {STRING_32} "")
|
make ({STRING_32} "")
|
||||||
end
|
end
|
||||||
|
|
||||||
make (a_content: READABLE_STRING_32; a_summary: READABLE_STRING_32; a_title: READABLE_STRING_32)
|
make (a_title: READABLE_STRING_32)
|
||||||
-- Create current node with `a_content', `a_summary' and `a_title'.
|
-- Create current node with `a_title'.
|
||||||
local
|
local
|
||||||
l_time: DATE_TIME
|
l_time: DATE_TIME
|
||||||
do
|
do
|
||||||
create l_time.make_now_utc
|
create l_time.make_now_utc
|
||||||
set_content (a_content)
|
|
||||||
set_summary (a_summary)
|
|
||||||
set_title (a_title)
|
set_title (a_title)
|
||||||
set_creation_date (l_time)
|
set_creation_date (l_time)
|
||||||
set_modification_date (l_time)
|
set_modification_date (l_time)
|
||||||
@@ -41,32 +39,68 @@ feature{NONE} -- Initialization
|
|||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Remove default harcoded format")
|
fixme ("Remove default harcoded format")
|
||||||
end
|
end
|
||||||
set_format ("HTML")
|
|
||||||
|
|
||||||
debug ("refactor_fixme")
|
|
||||||
fixme ("Remove default harcoded content type")
|
|
||||||
end
|
|
||||||
set_content_type ("Page")
|
|
||||||
ensure
|
ensure
|
||||||
content_set: content = a_content
|
|
||||||
summary_set: summary = a_summary
|
|
||||||
title_set: title = a_title
|
title_set: title = a_title
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature {CMS_CONTENT_TYPE} -- 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
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
id: INTEGER_64 assign set_id
|
id: INTEGER_64 assign set_id
|
||||||
-- Unique id.
|
-- Unique id.
|
||||||
--| Should we use NATURAL_64 instead?
|
--| Should we use NATURAL_64 instead?
|
||||||
|
|
||||||
content: READABLE_STRING_32
|
revision: INTEGER_64 assign set_revision
|
||||||
-- Content of the node.
|
-- Revision value.
|
||||||
|
--| Note: for now version is not supported.
|
||||||
|
|
||||||
summary: READABLE_STRING_32
|
content_type: READABLE_STRING_8
|
||||||
-- A short summary of the node.
|
-- Associated content type name.
|
||||||
|
-- Page, Article, Blog, News, etc.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
title: READABLE_STRING_32
|
title: READABLE_STRING_32
|
||||||
-- Full title of the node.
|
-- 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
|
modification_date: DATE_TIME
|
||||||
-- When the node was updated.
|
-- When the node was updated.
|
||||||
@@ -80,13 +114,7 @@ feature -- Access
|
|||||||
publication_date_output: READABLE_STRING_32
|
publication_date_output: READABLE_STRING_32
|
||||||
-- Formatted output.
|
-- Formatted output.
|
||||||
|
|
||||||
format: READABLE_STRING_32
|
feature -- Access: author
|
||||||
-- 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: detachable CMS_USER
|
||||||
-- Author of current node.
|
-- Author of current node.
|
||||||
@@ -99,22 +127,31 @@ feature -- status report
|
|||||||
Result := id > 0
|
Result := id > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Element change
|
same_node (a_node: CMS_NODE): BOOLEAN
|
||||||
|
-- Is `a_node' same node as Current?
|
||||||
set_content (a_content: like content)
|
|
||||||
-- Assign `content' with `a_content'.
|
|
||||||
do
|
do
|
||||||
content := a_content
|
-- FIXME: if we introduce notion of revision, update this part!
|
||||||
|
Result := Current = a_node or id = a_node.id
|
||||||
ensure
|
ensure
|
||||||
content_assigned: content = a_content
|
valid_result: Result implies a_node.id = id
|
||||||
end
|
end
|
||||||
|
|
||||||
set_summary (a_summary: like summary)
|
is_typed_as (a_content_type: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
-- Assign `summary' with `a_summary'.
|
-- Is current node of type `a_content_type' ?
|
||||||
do
|
do
|
||||||
summary := a_summary
|
Result := a_content_type.is_case_insensitive_equal (content_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
ensure
|
||||||
|
content_assigned: content = a_content
|
||||||
summary_assigned: summary = a_summary
|
summary_assigned: summary = a_summary
|
||||||
|
format_assigned: format = a_format
|
||||||
end
|
end
|
||||||
|
|
||||||
set_title (a_title: like title)
|
set_title (a_title: like title)
|
||||||
@@ -150,28 +187,20 @@ feature -- Element change
|
|||||||
publication_date_assigned: publication_date = a_publication_date
|
publication_date_assigned: publication_date = a_publication_date
|
||||||
end
|
end
|
||||||
|
|
||||||
set_content_type (a_content_type: like content_type)
|
set_id (a_id: like id)
|
||||||
-- Assign `content_type' with `a_content_type'.
|
-- Assign `id' with `a_id'.
|
||||||
do
|
do
|
||||||
content_type := a_content_type
|
id := a_id
|
||||||
ensure
|
ensure
|
||||||
content_type_assigned: content_type = a_content_type
|
id_assigned: id = a_id
|
||||||
end
|
end
|
||||||
|
|
||||||
set_format (a_format: like format)
|
set_revision (a_revision: like revision)
|
||||||
-- Assign `format' with `a_format'.
|
-- Assign `revision' with `a_revision'.
|
||||||
do
|
do
|
||||||
format := a_format
|
revision := a_revision
|
||||||
ensure
|
ensure
|
||||||
format_assigned: format = a_format
|
revision_assigned: revision = a_revision
|
||||||
end
|
|
||||||
|
|
||||||
set_id (an_id: like id)
|
|
||||||
-- Assign `id' with `an_id'.
|
|
||||||
do
|
|
||||||
id := an_id
|
|
||||||
ensure
|
|
||||||
id_assigned: id = an_id
|
|
||||||
end
|
end
|
||||||
|
|
||||||
set_author (u: like author)
|
set_author (u: like author)
|
||||||
|
|||||||
84
library/model/src/content/cms_partial_node.e
Normal file
84
library/model/src/content/cms_partial_node.e
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
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)
|
||||||
|
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
|
||||||
19
library/model/src/user/cms_partial_user.e
Normal file
19
library/model/src/user/cms_partial_user.e
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
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
|
||||||
@@ -71,6 +71,11 @@ 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]
|
||||||
@@ -189,6 +194,14 @@ 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)
|
||||||
@@ -217,6 +230,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-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2015, 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
|
||||||
|
|||||||
@@ -22,15 +22,25 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make_with_id (a_id: like id; a_name: like name)
|
make_with_id (a_id: like id)
|
||||||
|
-- Create current role with role id `a_id'.
|
||||||
do
|
do
|
||||||
id := a_id
|
id := a_id
|
||||||
make (a_name)
|
name := {STRING_32} ""
|
||||||
|
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
|
||||||
|
|
||||||
@@ -42,10 +52,10 @@ feature -- Status report
|
|||||||
Result := id > 0
|
Result := id > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
has_permission (p: READABLE_STRING_8): BOOLEAN
|
has_permission (p: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
-- Has permission `p'?
|
-- Has permission `p'?
|
||||||
do
|
do
|
||||||
Result := across permissions as c some c.item.is_case_insensitive_equal (p) end
|
Result := across permissions as c some p.is_case_insensitive_equal (c.item) end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
@@ -53,7 +63,7 @@ feature -- Access
|
|||||||
id: INTEGER
|
id: INTEGER
|
||||||
-- Unique id associated with Current role.
|
-- Unique id associated with Current role.
|
||||||
|
|
||||||
name: READABLE_STRING_8
|
name: READABLE_STRING_32
|
||||||
-- Name of Current role.
|
-- Name of Current role.
|
||||||
|
|
||||||
permissions: LIST [READABLE_STRING_8]
|
permissions: LIST [READABLE_STRING_8]
|
||||||
@@ -115,6 +125,6 @@ feature -- Permission change
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2015, 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
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ 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
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ feature -- Access
|
|||||||
do
|
do
|
||||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||||
across nodes_iterator as ic loop
|
across nodes_iterator as ic loop
|
||||||
Result.force (ic.item)
|
if attached ic.item as l_node then
|
||||||
|
Result.force (l_node)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -34,27 +36,29 @@ feature -- Access
|
|||||||
-- List of recent `a_count' nodes with an offset of `lower'.
|
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||||
do
|
do
|
||||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
|
||||||
across recent_nodes_iterator (a_lower, a_count) as c loop
|
across recent_nodes_iterator (a_lower, a_count) as ic loop
|
||||||
Result.force (c.item)
|
if attached ic.item as l_node then
|
||||||
|
Result.force (l_node)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access: iterator
|
feature -- Access: iterator
|
||||||
|
|
||||||
nodes_iterator: DATABASE_ITERATION_CURSOR [CMS_NODE]
|
nodes_iterator: DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
|
||||||
-- List of nodes.
|
-- List of nodes.
|
||||||
local
|
local
|
||||||
l_parameters: STRING_TABLE [ANY]
|
l_parameters: STRING_TABLE [ANY]
|
||||||
do
|
do
|
||||||
error_handler.reset
|
error_handler.reset
|
||||||
log.write_information (generator + ".nodes_iterator")
|
write_information_log (generator + ".nodes_iterator")
|
||||||
create l_parameters.make (0)
|
create l_parameters.make (0)
|
||||||
sql_query (select_nodes, l_parameters)
|
sql_query (sql_select_nodes, l_parameters)
|
||||||
create Result.make (db_handler, agent fetch_node)
|
create Result.make (db_handler, agent fetch_node)
|
||||||
sql_post_execution
|
sql_post_execution
|
||||||
end
|
end
|
||||||
|
|
||||||
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
|
||||||
-- The most recent `a_rows'.
|
-- The most recent `a_rows'.
|
||||||
local
|
local
|
||||||
l_parameters: STRING_TABLE [ANY]
|
l_parameters: STRING_TABLE [ANY]
|
||||||
@@ -62,11 +66,11 @@ feature -- Access: iterator
|
|||||||
do
|
do
|
||||||
-- FIXME: check implementation...
|
-- FIXME: check implementation...
|
||||||
error_handler.reset
|
error_handler.reset
|
||||||
log.write_information (generator + ".recent_nodes_iterator")
|
write_information_log (generator + ".recent_nodes_iterator")
|
||||||
create l_parameters.make (2)
|
create l_parameters.make (2)
|
||||||
l_parameters.put (a_rows, "rows")
|
l_parameters.put (a_rows, "rows")
|
||||||
l_parameters.put (a_lower, "offset")
|
l_parameters.put (a_lower, "offset")
|
||||||
create l_query.make_from_string (select_recent_nodes)
|
create l_query.make_from_string (sql_select_recent_nodes)
|
||||||
sql_query (l_query, l_parameters)
|
sql_query (l_query, l_parameters)
|
||||||
create Result.make (db_handler, agent fetch_node)
|
create Result.make (db_handler, agent fetch_node)
|
||||||
sql_post_execution
|
sql_post_execution
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ feature -- Access
|
|||||||
do
|
do
|
||||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||||
across nodes_iterator as ic loop
|
across nodes_iterator as ic loop
|
||||||
Result.force (ic.item)
|
if attached ic.item as l_node then
|
||||||
|
Result.force (l_node)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -34,14 +36,16 @@ feature -- Access
|
|||||||
-- List of recent `a_count' nodes with an offset of `lower'.
|
-- List of recent `a_count' nodes with an offset of `lower'.
|
||||||
do
|
do
|
||||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
|
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
|
||||||
across recent_nodes_iterator (a_lower, a_count) as c loop
|
across recent_nodes_iterator (a_lower, a_count) as ic loop
|
||||||
Result.force (c.item)
|
if attached ic.item as l_node then
|
||||||
|
Result.force (l_node)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access: iterator
|
feature -- Access: iterator
|
||||||
|
|
||||||
nodes_iterator: DATABASE_ITERATION_CURSOR [CMS_NODE]
|
nodes_iterator: DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
|
||||||
-- List of nodes.
|
-- List of nodes.
|
||||||
local
|
local
|
||||||
l_parameters: STRING_TABLE [ANY]
|
l_parameters: STRING_TABLE [ANY]
|
||||||
@@ -49,11 +53,11 @@ feature -- Access: iterator
|
|||||||
error_handler.reset
|
error_handler.reset
|
||||||
write_information_log (generator + ".nodes_iterator")
|
write_information_log (generator + ".nodes_iterator")
|
||||||
create l_parameters.make (0)
|
create l_parameters.make (0)
|
||||||
sql_query (select_nodes, l_parameters)
|
sql_query (sql_select_nodes, l_parameters)
|
||||||
create Result.make (db_handler, agent fetch_node)
|
create Result.make (db_handler, agent fetch_node)
|
||||||
end
|
end
|
||||||
|
|
||||||
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [CMS_NODE]
|
recent_nodes_iterator (a_lower, a_rows: INTEGER): DATABASE_ITERATION_CURSOR [detachable CMS_NODE]
|
||||||
-- The most recent `a_rows'.
|
-- The most recent `a_rows'.
|
||||||
local
|
local
|
||||||
l_parameters: STRING_TABLE [ANY]
|
l_parameters: STRING_TABLE [ANY]
|
||||||
@@ -65,7 +69,7 @@ feature -- Access: iterator
|
|||||||
create l_parameters.make (2)
|
create l_parameters.make (2)
|
||||||
l_parameters.put (a_rows, "rows")
|
l_parameters.put (a_rows, "rows")
|
||||||
l_parameters.put (a_lower, "offset")
|
l_parameters.put (a_lower, "offset")
|
||||||
create l_query.make_from_string (select_recent_nodes)
|
create l_query.make_from_string (sql_select_recent_nodes)
|
||||||
sql_query (l_query, l_parameters)
|
sql_query (l_query, l_parameters)
|
||||||
create Result.make (db_handler, agent fetch_node)
|
create Result.make (db_handler, agent fetch_node)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -45,47 +45,27 @@ feature -- Factory
|
|||||||
end
|
end
|
||||||
|
|
||||||
initialize (a_setup: CMS_SETUP; a_storage: CMS_STORAGE_STORE_SQL)
|
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
|
local
|
||||||
u: CMS_USER
|
u: CMS_USER
|
||||||
|
r: CMS_USER_ROLE
|
||||||
do
|
do
|
||||||
|
-- Schema
|
||||||
|
a_storage.sql_execute_file_script (a_setup.layout.path.extended ("scripts").extended ("core.sql"))
|
||||||
|
|
||||||
|
-- Data
|
||||||
|
-- Users
|
||||||
create u.make ("admin")
|
create u.make ("admin")
|
||||||
u.set_password ("#admin#")
|
u.set_password ("istrator#")
|
||||||
u.set_email (a_setup.site_email)
|
u.set_email (a_setup.site_email)
|
||||||
a_storage.new_user (u)
|
a_storage.new_user (u)
|
||||||
|
|
||||||
|
-- Roles
|
||||||
|
create r.make ("anonymous")
|
||||||
|
a_storage.save_user_role (r)
|
||||||
|
create r.make ("authenticated")
|
||||||
|
r.add_permission ("create page")
|
||||||
|
r.add_permission ("edit page")
|
||||||
|
a_storage.save_user_role (r)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,18 +9,21 @@ class
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
format (a_name: like {CONTENT_FORMAT}.name): detachable CONTENT_FORMAT
|
item (a_name: detachable READABLE_STRING_GENERAL): CONTENT_FORMAT
|
||||||
do
|
do
|
||||||
|
Result := default_format
|
||||||
|
if a_name /= Void then
|
||||||
across
|
across
|
||||||
all_formats as c
|
all_formats as c
|
||||||
until
|
until
|
||||||
Result /= Void
|
Result /= Void
|
||||||
loop
|
loop
|
||||||
if c.item.name.same_string (a_name) then
|
if a_name.same_string (c.item.name) then
|
||||||
Result := c.item
|
Result := c.item
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
all_formats: LIST [CONTENT_FORMAT]
|
all_formats: LIST [CONTENT_FORMAT]
|
||||||
once
|
once
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ feature -- Basic operations
|
|||||||
local
|
local
|
||||||
l_auth: HTTP_AUTHORIZATION
|
l_auth: HTTP_AUTHORIZATION
|
||||||
do
|
do
|
||||||
-- We can inherit from SHARED_LOGGER and write
|
|
||||||
-- write_debug_log ...
|
|
||||||
api.logger.put_debug (generator + ".execute ", Void)
|
api.logger.put_debug (generator + ".execute ", Void)
|
||||||
create l_auth.make (req.http_authorization)
|
create l_auth.make (req.http_authorization)
|
||||||
if attached req.raw_header_data as l_raw_data then
|
if attached req.raw_header_data as l_raw_data then
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ deferred class
|
|||||||
CMS_MODULE
|
CMS_MODULE
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
@@ -27,6 +26,39 @@ feature -- Access
|
|||||||
version: STRING
|
version: STRING
|
||||||
-- Version od the module?
|
-- Version od the module?
|
||||||
|
|
||||||
|
feature {CMS_API} -- Module Initialization
|
||||||
|
|
||||||
|
initialize (api: CMS_API)
|
||||||
|
-- Initialize Current module with `api'.
|
||||||
|
require
|
||||||
|
is_enabled: is_enabled
|
||||||
|
do
|
||||||
|
-- Redefine to process specific module initialization.
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {CMS_API} -- Module management
|
||||||
|
|
||||||
|
is_installed (api: CMS_API): BOOLEAN
|
||||||
|
-- Is Current module installed?
|
||||||
|
do
|
||||||
|
Result := is_enabled
|
||||||
|
-- FIXME: implement proper installation status.
|
||||||
|
end
|
||||||
|
|
||||||
|
install (api: CMS_API)
|
||||||
|
require
|
||||||
|
is_not_installed: not is_installed (api)
|
||||||
|
do
|
||||||
|
-- Not Yet Supported
|
||||||
|
end
|
||||||
|
|
||||||
|
uninstall (api: CMS_API)
|
||||||
|
require
|
||||||
|
is_installed: is_installed (api)
|
||||||
|
do
|
||||||
|
-- Not Yet Supported
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Router
|
feature -- Router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
router (a_api: CMS_API): WSF_ROUTER
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_NODE_API}."
|
description: "[
|
||||||
author: ""
|
API to manage CMS Nodes
|
||||||
|
]"
|
||||||
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 $"
|
||||||
|
|
||||||
@@ -9,12 +10,55 @@ class
|
|||||||
|
|
||||||
inherit
|
inherit
|
||||||
CMS_MODULE_API
|
CMS_MODULE_API
|
||||||
|
redefine
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
initialize
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
Precursor
|
||||||
|
initialize_content_types
|
||||||
|
end
|
||||||
|
|
||||||
|
initialize_content_types
|
||||||
|
-- Initialize content type system.
|
||||||
|
do
|
||||||
|
create content_types.make (1)
|
||||||
|
add_content_type (create {CMS_PAGE_CONTENT_TYPE})
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Content type
|
||||||
|
|
||||||
|
content_types: ARRAYED_LIST [CMS_CONTENT_TYPE]
|
||||||
|
-- Available content types
|
||||||
|
|
||||||
|
add_content_type (a_type: CMS_CONTENT_TYPE)
|
||||||
|
do
|
||||||
|
content_types.force (a_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
content_type (a_name: READABLE_STRING_GENERAL): detachable CMS_CONTENT_TYPE
|
||||||
|
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
|
||||||
|
|
||||||
feature -- Access: Node
|
feature -- Access: Node
|
||||||
|
|
||||||
nodes_count: INTEGER_64
|
nodes_count: INTEGER_64
|
||||||
@@ -40,7 +84,37 @@ feature -- Access: Node
|
|||||||
debug ("refactor_fixme")
|
debug ("refactor_fixme")
|
||||||
fixme ("Check preconditions")
|
fixme ("Check preconditions")
|
||||||
end
|
end
|
||||||
Result := storage.node_by_id (a_id)
|
Result := full_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 content_type (l_partial_node.content_type) as ct then
|
||||||
|
Result := ct.new_node (l_partial_node)
|
||||||
|
storage.fill_node (Result)
|
||||||
|
else
|
||||||
|
Result := l_partial_node
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := 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
|
end
|
||||||
|
|
||||||
feature -- Change: Node
|
feature -- Change: Node
|
||||||
@@ -67,32 +141,32 @@ feature -- Change: Node
|
|||||||
storage.update_node (a_node)
|
storage.update_node (a_node)
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||||
-- Update node title, with user identified by `a_id', with node id `a_node_id' and a new title `a_title'.
|
-- -- Update node title, with user identified by `a_id', with node id `a_node_id' and a new title `a_title'.
|
||||||
do
|
-- do
|
||||||
debug ("refactor_fixme")
|
-- debug ("refactor_fixme")
|
||||||
fixme ("Check preconditions")
|
-- fixme ("Check preconditions")
|
||||||
end
|
-- end
|
||||||
storage.update_node_title (a_user_id, a_node_id, a_title)
|
-- storage.update_node_title (a_user_id, a_node_id, a_title)
|
||||||
end
|
-- end
|
||||||
|
|
||||||
update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
-- update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||||
-- Update node summary, with user identified by `a_user_id', with node id `a_node_id' and a new summary `a_summary'.
|
-- -- Update node summary, with user identified by `a_user_id', with node id `a_node_id' and a new summary `a_summary'.
|
||||||
do
|
-- do
|
||||||
debug ("refactor_fixme")
|
-- debug ("refactor_fixme")
|
||||||
fixme ("Check preconditions")
|
-- fixme ("Check preconditions")
|
||||||
end
|
-- end
|
||||||
storage.update_node_summary (a_user_id, a_node_id, a_summary)
|
-- storage.update_node_summary (a_user_id, a_node_id, a_summary)
|
||||||
end
|
-- end
|
||||||
|
|
||||||
update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
-- update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||||
-- Update node content, with user identified by `a_user_id', with node id `a_node_id' and a new content `a_content'.
|
-- -- Update node content, with user identified by `a_user_id', with node id `a_node_id' and a new content `a_content'.
|
||||||
do
|
-- do
|
||||||
debug ("refactor_fixme")
|
-- debug ("refactor_fixme")
|
||||||
fixme ("Check preconditions")
|
-- fixme ("Check preconditions")
|
||||||
end
|
-- end
|
||||||
storage.update_node_content (a_user_id, a_node_id, a_content)
|
-- storage.update_node_content (a_user_id, a_node_id, a_content)
|
||||||
end
|
-- end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
95
src/modules/node/content_type/cms_page.e
Normal file
95
src/modules/node/content_type/cms_page.e
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
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 {CMS_CONTENT_TYPE} -- 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)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
content_type: READABLE_STRING_8
|
||||||
|
once
|
||||||
|
Result := {CMS_PAGE_CONTENT_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
|
||||||
32
src/modules/node/content_type/cms_page_content_type.e
Normal file
32
src/modules/node/content_type/cms_page_content_type.e
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_PAGE_CONTENT_TYPE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_PAGE_CONTENT_TYPE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_CONTENT_TYPE
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: STRING = "page"
|
||||||
|
-- Internal name.
|
||||||
|
|
||||||
|
title: STRING_32 = "Page"
|
||||||
|
-- Human readable name.
|
||||||
|
|
||||||
|
feature -- Factory
|
||||||
|
|
||||||
|
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
|
||||||
17
src/modules/node/content_type/cms_partial_page.e
Normal file
17
src/modules/node/content_type/cms_partial_page.e
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
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
|
||||||
240
src/modules/node/handler/experimental/node_resource_handler.e
Normal file
240
src/modules/node/handler/experimental/node_resource_handler.e
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
note
|
||||||
|
description: "Node handler for the API."
|
||||||
|
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||||
|
revision: "$Revision: 96616 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
NODE_RESOURCE_HANDLER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_NODE_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,
|
||||||
|
do_post,
|
||||||
|
do_put,
|
||||||
|
do_delete
|
||||||
|
end
|
||||||
|
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature -- execute
|
||||||
|
|
||||||
|
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Execute request handler
|
||||||
|
do
|
||||||
|
execute_methods (req, res)
|
||||||
|
end
|
||||||
|
|
||||||
|
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Execute request handler
|
||||||
|
do
|
||||||
|
execute (req, res)
|
||||||
|
end
|
||||||
|
|
||||||
|
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Execute request handler
|
||||||
|
do
|
||||||
|
execute (req, res)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- HTTP Methods
|
||||||
|
|
||||||
|
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_page: CMS_RESPONSE
|
||||||
|
do
|
||||||
|
-- Existing node
|
||||||
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
|
if
|
||||||
|
l_id.is_integer and then
|
||||||
|
attached node_api.node (l_id.value.to_integer_64) as l_node
|
||||||
|
then
|
||||||
|
-- FIXME: there is a mix between CMS interface and API interface here.
|
||||||
|
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||||
|
l_page.add_variable (l_node, "node")
|
||||||
|
l_page.execute
|
||||||
|
else
|
||||||
|
do_error (req, res, l_id)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Factory
|
||||||
|
new_node (req, res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
u_node: CMS_NODE
|
||||||
|
do
|
||||||
|
to_implement ("Check user permissions!!!")
|
||||||
|
if attached current_user (req) as l_user then
|
||||||
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
|
if
|
||||||
|
l_id.is_integer and then
|
||||||
|
attached node_api.node (l_id.value.to_integer_64) as l_node
|
||||||
|
then
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("method") as l_method then
|
||||||
|
if l_method.is_case_insensitive_equal ("DELETE") then
|
||||||
|
do_delete (req, res)
|
||||||
|
elseif l_method.is_case_insensitive_equal ("PUT") then
|
||||||
|
do_put (req, res)
|
||||||
|
else
|
||||||
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
do_error (req, res, l_id)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- New node
|
||||||
|
-- FIXME !!!
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("type") as p_type then
|
||||||
|
if attached node_api.content_type (p_type.value) as ct then
|
||||||
|
end
|
||||||
|
create {CMS_PARTIAL_NODE} u_node.make_empty (p_type.url_encoded_value)
|
||||||
|
else
|
||||||
|
create {CMS_PARTIAL_NODE} u_node.make_empty ("")
|
||||||
|
end
|
||||||
|
|
||||||
|
update_node_from_data_form (req, u_node)
|
||||||
|
u_node.set_author (l_user)
|
||||||
|
node_api.new_node (u_node)
|
||||||
|
redirect_to (req.absolute_script_url (""), res)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
send_access_denied (res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
|
||||||
|
if attached current_user (req) as l_user then
|
||||||
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
|
if
|
||||||
|
l_id.is_integer and then
|
||||||
|
attached node_api.node (l_id.value.to_integer_64) as l_node
|
||||||
|
then
|
||||||
|
update_node_from_data_form (req, l_node)
|
||||||
|
l_node.set_author (l_user)
|
||||||
|
node_api.update_node (l_node)
|
||||||
|
redirect_to (req.absolute_script_url (""), res)
|
||||||
|
else
|
||||||
|
do_error (req, res, l_id)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
|
end
|
||||||
|
else
|
||||||
|
send_access_denied (res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
if attached current_user_name (req) then
|
||||||
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
|
if
|
||||||
|
l_id.is_integer and then
|
||||||
|
attached node_api.node (l_id.integer_value) as l_node
|
||||||
|
then
|
||||||
|
node_api.delete_node (l_node)
|
||||||
|
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
|
||||||
|
else
|
||||||
|
do_error (req, res, l_id)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||||
|
end
|
||||||
|
else
|
||||||
|
send_access_denied (res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Error
|
||||||
|
|
||||||
|
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||||
|
-- Handling error.
|
||||||
|
local
|
||||||
|
l_page: CMS_RESPONSE
|
||||||
|
do
|
||||||
|
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||||
|
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
|
||||||
|
if a_id.is_integer then
|
||||||
|
-- resource not found
|
||||||
|
l_page.add_variable ("404", "code")
|
||||||
|
l_page.set_status_code (404)
|
||||||
|
else
|
||||||
|
-- bad request
|
||||||
|
l_page.add_variable ("400", "code")
|
||||||
|
l_page.set_status_code (400)
|
||||||
|
end
|
||||||
|
l_page.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Node
|
||||||
|
|
||||||
|
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
local
|
||||||
|
l_page: CMS_RESPONSE
|
||||||
|
do
|
||||||
|
if api.user_has_permission (current_user (req), "create node") then
|
||||||
|
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||||
|
l_page.execute
|
||||||
|
else
|
||||||
|
send_access_denied (res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- {NONE} Form data
|
||||||
|
|
||||||
|
update_node_from_data_form (req: WSF_REQUEST; a_node: CMS_NODE)
|
||||||
|
-- Extract request form data and build a object
|
||||||
|
-- Node
|
||||||
|
local
|
||||||
|
l_title: detachable READABLE_STRING_32
|
||||||
|
l_summary, l_content, l_format: detachable READABLE_STRING_8
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("title") as p_title then
|
||||||
|
l_title := p_title.value
|
||||||
|
a_node.set_title (l_title)
|
||||||
|
end
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("summary") as p_summary then
|
||||||
|
l_summary := html_encoded (p_summary.value)
|
||||||
|
end
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("content") as p_content then
|
||||||
|
l_content := html_encoded (p_content.value)
|
||||||
|
end
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("format") as p_format then
|
||||||
|
l_format := p_format.url_encoded_value
|
||||||
|
end
|
||||||
|
if l_format = Void then
|
||||||
|
l_format := a_node.format
|
||||||
|
end
|
||||||
|
a_node.set_content (l_content, l_summary, l_format)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
note
|
||||||
|
description: "Request handler related to /nodes."
|
||||||
|
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||||
|
revision: "$Revision: 96616 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
NODE_RESOURCES_HANDLER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_NODE_HANDLER
|
||||||
|
|
||||||
|
WSF_URI_HANDLER
|
||||||
|
rename
|
||||||
|
new_mapping as new_uri_mapping
|
||||||
|
end
|
||||||
|
|
||||||
|
WSF_RESOURCE_HANDLER_HELPER
|
||||||
|
redefine
|
||||||
|
do_get
|
||||||
|
end
|
||||||
|
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature -- execute
|
||||||
|
|
||||||
|
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Execute request handler
|
||||||
|
do
|
||||||
|
execute_methods (req, res)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- HTTP Methods
|
||||||
|
|
||||||
|
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_page: CMS_RESPONSE
|
||||||
|
s: STRING
|
||||||
|
do
|
||||||
|
-- At the moment the template is hardcoded, but we can
|
||||||
|
-- get them from the configuration file and load them into
|
||||||
|
-- the setup class.
|
||||||
|
|
||||||
|
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||||
|
l_page.add_variable (node_api.nodes, "nodes")
|
||||||
|
|
||||||
|
|
||||||
|
-- NOTE: for development purposes we have the following hardcode output.
|
||||||
|
create s.make_from_string ("<p>Nodes:</p>")
|
||||||
|
if attached node_api.nodes as lst then
|
||||||
|
across
|
||||||
|
lst as ic
|
||||||
|
loop
|
||||||
|
s.append ("<li>")
|
||||||
|
s.append ("<a href=%"")
|
||||||
|
s.append (req.script_url ("/node/" + ic.item.id.out))
|
||||||
|
s.append ("%">")
|
||||||
|
s.append (api.html_encoded (ic.item.title))
|
||||||
|
s.append (" (")
|
||||||
|
s.append (ic.item.id.out)
|
||||||
|
s.append (")")
|
||||||
|
s.append ("</a>")
|
||||||
|
s.append ("</li>%N")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
l_page.set_main_content (s)
|
||||||
|
l_page.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet fully implemented<br/>", Void), "highlighted")
|
||||||
|
l_page.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -62,15 +62,51 @@ feature -- HTTP Methods
|
|||||||
-- <Precursor>
|
-- <Precursor>
|
||||||
local
|
local
|
||||||
l_page: CMS_RESPONSE
|
l_page: CMS_RESPONSE
|
||||||
|
s: STRING
|
||||||
|
hdate: HTTP_DATE
|
||||||
do
|
do
|
||||||
-- Existing node
|
-- Existing node
|
||||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||||
if
|
if
|
||||||
l_id.is_integer and then
|
l_id.is_integer and then
|
||||||
attached node_api.node (l_id.value.to_integer_64) as l_node
|
attached {CMS_NODE} node_api.node (l_id.value.to_integer_64) as l_node
|
||||||
then
|
then
|
||||||
|
-- FIXME: there is a mix between CMS interface and API interface here.
|
||||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||||
l_page.add_variable (l_node, "node")
|
l_page.add_variable (l_node, "node")
|
||||||
|
|
||||||
|
create s.make_empty
|
||||||
|
s.append ("<h1 class=%"title%">")
|
||||||
|
s.append (html_encoded (l_node.title))
|
||||||
|
s.append ("</h1>")
|
||||||
|
s.append ("<div class=%"info%"> ")
|
||||||
|
if attached l_node.author as l_author then
|
||||||
|
s.append (" by ")
|
||||||
|
s.append (l_author.name)
|
||||||
|
end
|
||||||
|
if attached l_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>")
|
||||||
|
if attached l_node.content as l_content then
|
||||||
|
s.append ("<p class=%"content%">")
|
||||||
|
s.append (api.formats.item (l_node.format).formatted_output (l_content))
|
||||||
|
s.append ("</p>")
|
||||||
|
end
|
||||||
|
if attached {CMS_PAGE} l_node as l_node_page then
|
||||||
|
if attached l_node_page.parent as l_parent_node then
|
||||||
|
s.append ("<div>Parent page is ")
|
||||||
|
s.append ("<a href=%"/node/" + l_parent_node.id.out + "%">")
|
||||||
|
s.append (l_parent_node.title)
|
||||||
|
s.append (" (#")
|
||||||
|
s.append (l_parent_node.id.out)
|
||||||
|
s.append (")</a></div>")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
l_page.set_main_content (s)
|
||||||
l_page.execute
|
l_page.execute
|
||||||
else
|
else
|
||||||
do_error (req, res, l_id)
|
do_error (req, res, l_id)
|
||||||
@@ -107,7 +143,15 @@ feature -- HTTP Methods
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- New node
|
-- New node
|
||||||
create u_node.make ("", "", "")
|
-- FIXME !!!
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("type") as p_type then
|
||||||
|
if attached node_api.content_type (p_type.value) as ct then
|
||||||
|
end
|
||||||
|
create {CMS_PARTIAL_NODE} u_node.make_empty (p_type.url_encoded_value)
|
||||||
|
else
|
||||||
|
create {CMS_PARTIAL_NODE} u_node.make_empty ("")
|
||||||
|
end
|
||||||
|
|
||||||
update_node_from_data_form (req, u_node)
|
update_node_from_data_form (req, u_node)
|
||||||
u_node.set_author (l_user)
|
u_node.set_author (l_user)
|
||||||
node_api.new_node (u_node)
|
node_api.new_node (u_node)
|
||||||
@@ -192,7 +236,7 @@ feature {NONE} -- Node
|
|||||||
local
|
local
|
||||||
l_page: CMS_RESPONSE
|
l_page: CMS_RESPONSE
|
||||||
do
|
do
|
||||||
if attached current_user_name (req) then
|
if api.user_has_permission (current_user (req), "create node") then
|
||||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||||
l_page.execute
|
l_page.execute
|
||||||
else
|
else
|
||||||
@@ -205,16 +249,27 @@ feature -- {NONE} Form data
|
|||||||
update_node_from_data_form (req: WSF_REQUEST; a_node: CMS_NODE)
|
update_node_from_data_form (req: WSF_REQUEST; a_node: CMS_NODE)
|
||||||
-- Extract request form data and build a object
|
-- Extract request form data and build a object
|
||||||
-- Node
|
-- Node
|
||||||
|
local
|
||||||
|
l_title: detachable READABLE_STRING_32
|
||||||
|
l_summary, l_content, l_format: detachable READABLE_STRING_8
|
||||||
do
|
do
|
||||||
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
|
if attached {WSF_STRING} req.form_parameter ("title") as p_title then
|
||||||
a_node.set_title (l_title.value)
|
l_title := p_title.value
|
||||||
|
a_node.set_title (l_title)
|
||||||
end
|
end
|
||||||
if attached {WSF_STRING} req.form_parameter ("summary") as l_summary then
|
if attached {WSF_STRING} req.form_parameter ("summary") as p_summary then
|
||||||
a_node.set_summary (l_summary.value)
|
l_summary := html_encoded (p_summary.value)
|
||||||
end
|
end
|
||||||
if attached {WSF_STRING} req.form_parameter ("content") as l_content then
|
if attached {WSF_STRING} req.form_parameter ("content") as p_content then
|
||||||
a_node.set_content (l_content.value)
|
l_content := html_encoded (p_content.value)
|
||||||
end
|
end
|
||||||
|
if attached {WSF_STRING} req.form_parameter ("format") as p_format then
|
||||||
|
l_format := p_format.url_encoded_value
|
||||||
|
end
|
||||||
|
if l_format = Void then
|
||||||
|
l_format := a_node.format
|
||||||
|
end
|
||||||
|
a_node.set_content (l_content, l_summary, l_format)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ feature -- HTTP Methods
|
|||||||
local
|
local
|
||||||
l_page: CMS_RESPONSE
|
l_page: CMS_RESPONSE
|
||||||
s: STRING
|
s: STRING
|
||||||
l_user: CMS_USER
|
n: CMS_NODE
|
||||||
l_node: CMS_NODE
|
|
||||||
do
|
do
|
||||||
-- At the moment the template is hardcoded, but we can
|
-- At the moment the template is hardcoded, but we can
|
||||||
-- get them from the configuration file and load them into
|
-- get them from the configuration file and load them into
|
||||||
@@ -53,20 +52,23 @@ feature -- HTTP Methods
|
|||||||
-- NOTE: for development purposes we have the following hardcode output.
|
-- NOTE: for development purposes we have the following hardcode output.
|
||||||
create s.make_from_string ("<p>Nodes:</p>")
|
create s.make_from_string ("<p>Nodes:</p>")
|
||||||
if attached node_api.nodes as lst then
|
if attached node_api.nodes as lst then
|
||||||
|
s.append ("<ul class=%"cms-nodes%">%N")
|
||||||
across
|
across
|
||||||
lst as ic
|
lst as ic
|
||||||
loop
|
loop
|
||||||
s.append ("<li>")
|
n := ic.item
|
||||||
|
s.append ("<li class=%"cms_type_"+ n.content_type +"%">")
|
||||||
s.append ("<a href=%"")
|
s.append ("<a href=%"")
|
||||||
s.append (req.script_url ("/node/" + ic.item.id.out))
|
s.append (req.script_url ("/node/" + n.id.out))
|
||||||
s.append ("%">")
|
s.append ("%">")
|
||||||
s.append (api.html_encoded (ic.item.title))
|
s.append (api.html_encoded (n.title))
|
||||||
s.append (" (")
|
s.append (" (")
|
||||||
s.append (ic.item.id.out)
|
s.append (n.id.out)
|
||||||
s.append (")")
|
s.append (")")
|
||||||
s.append ("</a>")
|
s.append ("</a>")
|
||||||
s.append ("</li>%N")
|
s.append ("</li>%N")
|
||||||
end
|
end
|
||||||
|
s.append ("</ul>%N")
|
||||||
end
|
end
|
||||||
|
|
||||||
l_page.set_main_content (s)
|
l_page.set_main_content (s)
|
||||||
|
|||||||
@@ -10,14 +10,16 @@ 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
|
||||||
|
|
||||||
CMS_HOOK_BLOCK
|
CMS_HOOK_BLOCK
|
||||||
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -36,6 +38,59 @@ feature {NONE} -- Initialization
|
|||||||
config: CMS_SETUP
|
config: CMS_SETUP
|
||||||
-- Node configuration.
|
-- Node configuration.
|
||||||
|
|
||||||
|
feature {CMS_API} -- Module Initialization
|
||||||
|
|
||||||
|
initialize (api: CMS_API)
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
Precursor (api)
|
||||||
|
if attached {CMS_NODE_STORAGE_SQL} api.storage as l_sql_storage then
|
||||||
|
l_sql_storage.register_node_storage_extension (create {CMS_NODE_STORAGE_SQL_PAGE_EXTENSION}.make (l_sql_storage))
|
||||||
|
else
|
||||||
|
-- FIXME: maybe provide a default solution based on file system, when no SQL storage is available.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {CMS_API} -- Module management
|
||||||
|
|
||||||
|
is_installed (api: CMS_API): BOOLEAN
|
||||||
|
-- Is Current module installed?
|
||||||
|
do
|
||||||
|
if attached {CMS_STORAGE_SQL} api.storage as l_sql_storage then
|
||||||
|
Result := l_sql_storage.sql_table_exists ("nodes") and
|
||||||
|
l_sql_storage.sql_table_exists ("page_nodes")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
install (api: CMS_API)
|
||||||
|
local
|
||||||
|
p1,p2: CMS_PAGE
|
||||||
|
ct: CMS_PAGE_CONTENT_TYPE
|
||||||
|
do
|
||||||
|
-- Schema
|
||||||
|
if attached {CMS_STORAGE_SQL} api.storage as l_sql_storage then
|
||||||
|
l_sql_storage.sql_execute_file_script (api.setup.layout.path.extended ("scripts").extended (name).appended_with_extension ("sql"))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Data
|
||||||
|
-- FIXME: for test purpose, remove later
|
||||||
|
if attached api.user_api.user_by_id (1) as u then
|
||||||
|
create ct
|
||||||
|
p1 := ct.new_node (Void)
|
||||||
|
p1.set_title ("Welcome")
|
||||||
|
p1.set_content ("Welcome, you are using the ROC Eiffel CMS", "Welcome Eiffel ROC user", Void) -- Use default format
|
||||||
|
p1.set_author (u)
|
||||||
|
api.storage.save_node (p1)
|
||||||
|
|
||||||
|
p2 := ct.new_node (Void)
|
||||||
|
p2.set_title ("A new page example")
|
||||||
|
p2.set_content ("This is the content of a page", "This is a new page", Void) -- Use default format
|
||||||
|
p2.set_author (u)
|
||||||
|
p2.set_parent (p1)
|
||||||
|
api.storage.save_node (p2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access: router
|
feature -- Access: router
|
||||||
|
|
||||||
router (a_api: CMS_API): WSF_ROUTER
|
router (a_api: CMS_API): WSF_ROUTER
|
||||||
@@ -44,87 +99,119 @@ feature -- Access: router
|
|||||||
l_node_api: CMS_NODE_API
|
l_node_api: CMS_NODE_API
|
||||||
do
|
do
|
||||||
create l_node_api.make (a_api)
|
create l_node_api.make (a_api)
|
||||||
create Result.make (5)
|
create Result.make (2)
|
||||||
configure_api_node (a_api, l_node_api, Result)
|
configure_cms (a_api, l_node_api, Result)
|
||||||
configure_api_nodes (a_api, l_node_api, Result)
|
-- configure_api (a_api, l_node_api, Result)
|
||||||
configure_api_node_title (a_api, l_node_api, Result)
|
|
||||||
configure_api_node_summary (a_api, l_node_api, Result)
|
|
||||||
configure_api_node_content (a_api, l_node_api, Result)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation: routes
|
configure_cms (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
|
|
||||||
configure_api_node (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
|
||||||
local
|
local
|
||||||
l_node_handler: NODE_HANDLER
|
l_node_handler: NODE_HANDLER
|
||||||
l_methods: WSF_REQUEST_METHODS
|
l_edit_node_handler: NODE_HANDLER
|
||||||
do
|
l_new_node_handler: NODE_HANDLER
|
||||||
create l_node_handler.make (a_api, a_node_api)
|
|
||||||
create l_methods
|
|
||||||
l_methods.enable_get
|
|
||||||
l_methods.enable_post
|
|
||||||
l_methods.enable_put
|
|
||||||
a_router.handle_with_request_methods ("/node", l_node_handler, l_methods)
|
|
||||||
|
|
||||||
create l_node_handler.make (a_api, a_node_api)
|
|
||||||
create l_methods
|
|
||||||
l_methods.enable_get
|
|
||||||
l_methods.enable_post
|
|
||||||
l_methods.enable_put
|
|
||||||
l_methods.enable_delete
|
|
||||||
a_router.handle_with_request_methods ("/node/{id}", l_node_handler, l_methods)
|
|
||||||
-- a_router.handle_with_request_methods ("/nodes/", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_nodes (?,?, a_api, a_node_api)), a_router.methods_get)
|
|
||||||
end
|
|
||||||
|
|
||||||
configure_api_nodes (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
|
||||||
local
|
|
||||||
l_nodes_handler: NODES_HANDLER
|
l_nodes_handler: NODES_HANDLER
|
||||||
l_methods: WSF_REQUEST_METHODS
|
l_methods: WSF_REQUEST_METHODS
|
||||||
do
|
do
|
||||||
|
create l_node_handler.make (a_api, a_node_api)
|
||||||
|
create l_methods
|
||||||
|
l_methods.enable_get
|
||||||
|
l_methods.enable_post
|
||||||
|
l_methods.lock
|
||||||
|
a_router.handle_with_request_methods ("/node", l_node_handler, l_methods)
|
||||||
|
|
||||||
|
create l_new_node_handler.make (a_api, a_node_api)
|
||||||
|
a_router.handle_with_request_methods ("/node/new/{type}", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_node_creation_by_type (?,?, "type", a_node_api)), a_router.methods_get)
|
||||||
|
a_router.handle_with_request_methods ("/node/new", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_node_creation_selection (?,?, a_api)), a_router.methods_get)
|
||||||
|
|
||||||
|
create l_edit_node_handler.make (a_api, a_node_api)
|
||||||
|
a_router.handle_with_request_methods ("/node/{id}/edit", l_edit_node_handler, a_router.methods_get_post)
|
||||||
|
|
||||||
|
create l_node_handler.make (a_api, a_node_api)
|
||||||
|
a_router.handle_with_request_methods ("/node/{id}", l_node_handler, a_router.methods_get_put_delete + a_router.methods_get_post)
|
||||||
|
|
||||||
|
-- Nodes
|
||||||
create l_nodes_handler.make (a_api, a_node_api)
|
create l_nodes_handler.make (a_api, a_node_api)
|
||||||
create l_methods
|
create l_methods
|
||||||
l_methods.enable_get
|
l_methods.enable_get
|
||||||
a_router.handle_with_request_methods ("/nodes", l_nodes_handler, l_methods)
|
a_router.handle_with_request_methods ("/nodes", l_nodes_handler, l_methods)
|
||||||
end
|
end
|
||||||
|
|
||||||
configure_api_node_summary (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
-- configure_api (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
local
|
-- do
|
||||||
l_report_handler: NODE_SUMMARY_HANDLER
|
-- configure_api_node (a_api, a_node_api, a_router)
|
||||||
l_methods: WSF_REQUEST_METHODS
|
-- configure_api_nodes (a_api, a_node_api, a_router)
|
||||||
do
|
-- configure_api_node_title (a_api, a_node_api, a_router)
|
||||||
create l_report_handler.make (a_api, a_node_api)
|
-- configure_api_node_summary (a_api, a_node_api, a_router)
|
||||||
create l_methods
|
-- configure_api_node_content (a_api, a_node_api, a_router)
|
||||||
l_methods.enable_get
|
-- end
|
||||||
l_methods.enable_post
|
|
||||||
l_methods.enable_put
|
|
||||||
a_router.handle_with_request_methods ("/node/{id}/field/summary", l_report_handler, l_methods)
|
|
||||||
end
|
|
||||||
|
|
||||||
configure_api_node_title (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
feature {NONE} -- Implementation: routes
|
||||||
local
|
|
||||||
l_report_handler: NODE_TITLE_HANDLER
|
|
||||||
l_methods: WSF_REQUEST_METHODS
|
|
||||||
do
|
|
||||||
create l_report_handler.make (a_api, a_node_api)
|
|
||||||
create l_methods
|
|
||||||
l_methods.enable_get
|
|
||||||
l_methods.enable_post
|
|
||||||
l_methods.enable_put
|
|
||||||
a_router.handle_with_request_methods ("/node/{id}/field/title", l_report_handler, l_methods)
|
|
||||||
end
|
|
||||||
|
|
||||||
configure_api_node_content (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
-- configure_api_node (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
local
|
-- local
|
||||||
l_report_handler: NODE_CONTENT_HANDLER
|
-- l_node_handler: NODE_RESOURCE_HANDLER
|
||||||
l_methods: WSF_REQUEST_METHODS
|
-- l_methods: WSF_REQUEST_METHODS
|
||||||
do
|
-- do
|
||||||
create l_report_handler.make (a_api, a_node_api)
|
-- create l_node_handler.make (a_api, a_node_api)
|
||||||
create l_methods
|
-- create l_methods
|
||||||
l_methods.enable_get
|
-- l_methods.enable_get
|
||||||
l_methods.enable_post
|
-- l_methods.enable_post
|
||||||
l_methods.enable_put
|
-- l_methods.lock
|
||||||
a_router.handle_with_request_methods ("/node/{id}/field/content", l_report_handler, l_methods)
|
-- a_router.handle_with_request_methods ("/api/node", l_node_handler, l_methods)
|
||||||
end
|
|
||||||
|
-- create l_node_handler.make (a_api, a_node_api)
|
||||||
|
-- a_router.handle_with_request_methods ("/api/node/{id}", l_node_handler, a_router.methods_get_put_delete + a_router.methods_get_post)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- configure_api_nodes (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
|
-- local
|
||||||
|
-- l_nodes_handler: NODE_RESOURCES_HANDLER
|
||||||
|
-- l_methods: WSF_REQUEST_METHODS
|
||||||
|
-- do
|
||||||
|
-- create l_nodes_handler.make (a_api, a_node_api)
|
||||||
|
-- create l_methods
|
||||||
|
-- l_methods.enable_get
|
||||||
|
-- a_router.handle_with_request_methods ("/api/nodes", l_nodes_handler, l_methods)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- configure_api_node_summary (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
|
-- local
|
||||||
|
-- l_report_handler: NODE_SUMMARY_HANDLER
|
||||||
|
-- l_methods: WSF_REQUEST_METHODS
|
||||||
|
-- do
|
||||||
|
-- create l_report_handler.make (a_api, a_node_api)
|
||||||
|
-- create l_methods
|
||||||
|
-- l_methods.enable_get
|
||||||
|
-- l_methods.enable_post
|
||||||
|
-- l_methods.enable_put
|
||||||
|
-- a_router.handle_with_request_methods ("/node/{id}/field/summary", l_report_handler, l_methods)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- configure_api_node_title (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
|
-- local
|
||||||
|
-- l_report_handler: NODE_TITLE_HANDLER
|
||||||
|
-- l_methods: WSF_REQUEST_METHODS
|
||||||
|
-- do
|
||||||
|
-- create l_report_handler.make (a_api, a_node_api)
|
||||||
|
-- create l_methods
|
||||||
|
-- l_methods.enable_get
|
||||||
|
-- l_methods.enable_post
|
||||||
|
-- l_methods.enable_put
|
||||||
|
-- a_router.handle_with_request_methods ("/node/{id}/field/title", l_report_handler, l_methods)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- configure_api_node_content (a_api: CMS_API; a_node_api: CMS_NODE_API; a_router: WSF_ROUTER)
|
||||||
|
-- local
|
||||||
|
-- l_report_handler: NODE_CONTENT_HANDLER
|
||||||
|
-- l_methods: WSF_REQUEST_METHODS
|
||||||
|
-- do
|
||||||
|
-- create l_report_handler.make (a_api, a_node_api)
|
||||||
|
-- create l_methods
|
||||||
|
-- l_methods.enable_get
|
||||||
|
-- l_methods.enable_post
|
||||||
|
-- l_methods.enable_put
|
||||||
|
-- a_router.handle_with_request_methods ("/node/{id}/field/content", l_report_handler, l_methods)
|
||||||
|
-- end
|
||||||
|
|
||||||
feature -- Hooks
|
feature -- Hooks
|
||||||
|
|
||||||
@@ -156,4 +243,30 @@ feature -- Hooks
|
|||||||
a_menu_system.primary_menu.extend (lnk)
|
a_menu_system.primary_menu.extend (lnk)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Handler
|
||||||
|
|
||||||
|
do_get_node_creation_selection (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
|
||||||
|
local
|
||||||
|
l_page: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||||
|
do
|
||||||
|
create l_page.make (req, res, a_api)
|
||||||
|
l_page.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
do_get_node_creation_by_type (req: WSF_REQUEST; res: WSF_RESPONSE; a_type_varname: READABLE_STRING_8; a_node_api: CMS_NODE_API)
|
||||||
|
local
|
||||||
|
l_page: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||||
|
l_node: detachable CMS_NODE
|
||||||
|
do
|
||||||
|
create l_page.make (req, res, a_node_api.cms_api)
|
||||||
|
if
|
||||||
|
attached {WSF_STRING} req.path_parameter (a_type_varname) as p_type and then
|
||||||
|
attached a_node_api.content_type (p_type.value) as ct
|
||||||
|
then
|
||||||
|
l_node := ct.new_node (Void)
|
||||||
|
l_page.set_main_content (l_node.out)
|
||||||
|
end
|
||||||
|
l_page.execute
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
112
src/persistence/cms_proxy_storage_sql.e
Normal file
112
src/persistence/cms_proxy_storage_sql.e
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
note
|
||||||
|
description: "Proxy on a {CMS_STORAGE_SQL} interface."
|
||||||
|
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||||
|
revision: "$Revision: 96616 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_PROXY_STORAGE_SQL
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_STORAGE_SQL
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_sql_storage: like sql_storage)
|
||||||
|
do
|
||||||
|
sql_storage := a_sql_storage
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_storage: CMS_STORAGE_SQL
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
api: detachable CMS_API
|
||||||
|
-- Associated CMS api.
|
||||||
|
do
|
||||||
|
Result := sql_storage.api
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Error handler
|
||||||
|
|
||||||
|
error_handler: ERROR_HANDLER
|
||||||
|
-- Error handler.
|
||||||
|
do
|
||||||
|
Result := sql_storage.error_handler
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
|
sql_begin_transaction
|
||||||
|
do
|
||||||
|
sql_storage.sql_begin_transaction
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_rollback_transaction
|
||||||
|
do
|
||||||
|
sql_storage.sql_rollback_transaction
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_commit_transaction
|
||||||
|
do
|
||||||
|
sql_storage.sql_commit_transaction
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_post_execution
|
||||||
|
-- Post database execution.
|
||||||
|
-- note: execute after each `sql_query' and `sql_change'.
|
||||||
|
do
|
||||||
|
sql_storage.sql_post_execution
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Operation
|
||||||
|
|
||||||
|
sql_query (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
do
|
||||||
|
sql_storage.sql_query (a_sql_statement, a_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_change (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||||
|
do
|
||||||
|
sql_storage.sql_change (a_sql_statement, a_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
sql_rows_count: INTEGER
|
||||||
|
-- Number of rows for last sql execution.
|
||||||
|
do
|
||||||
|
Result := sql_storage.sql_rows_count
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_start
|
||||||
|
-- Set the cursor on first element.
|
||||||
|
do
|
||||||
|
sql_storage.sql_start
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_after: BOOLEAN
|
||||||
|
-- Are there no more items to iterate over?
|
||||||
|
do
|
||||||
|
Result := sql_storage.sql_after
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_forth
|
||||||
|
-- Fetch next row from last sql execution, if any.
|
||||||
|
do
|
||||||
|
sql_storage.sql_forth
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_valid_item_index (a_index: INTEGER): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := sql_storage.sql_valid_item_index (a_index)
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_item (a_index: INTEGER): detachable ANY
|
||||||
|
do
|
||||||
|
Result:= sql_storage.sql_item (a_index)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -22,6 +22,11 @@ feature {NONE} -- Initialization
|
|||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
api: detachable CMS_API assign set_api
|
||||||
|
-- Associated CMS API.
|
||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
is_available: BOOLEAN
|
is_available: BOOLEAN
|
||||||
@@ -39,6 +44,14 @@ feature -- Error Handling
|
|||||||
error_handler: ERROR_HANDLER
|
error_handler: ERROR_HANDLER
|
||||||
-- Error handler.
|
-- Error handler.
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
set_api (a_api: like api)
|
||||||
|
-- Set `api' to `a_api'.
|
||||||
|
do
|
||||||
|
api := a_api
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Misc
|
feature -- Misc
|
||||||
|
|
||||||
-- set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: READABLE_STRING_8)
|
-- set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: READABLE_STRING_8)
|
||||||
|
|||||||
@@ -95,12 +95,20 @@ feature -- Change: user
|
|||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature -- Access: roles and permissions
|
feature -- Access: roles and permissions
|
||||||
|
|
||||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
user_roles_for (a_user: CMS_USER): LIST [CMS_USER_ROLE]
|
||||||
|
-- User roles for user `a_user'.
|
||||||
|
-- Note: anonymous and authenticated roles are not included.
|
||||||
|
do
|
||||||
|
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
||||||
|
end
|
||||||
|
|
||||||
user_roles: LIST [CMS_USER_ROLE]
|
user_roles: LIST [CMS_USER_ROLE]
|
||||||
do
|
do
|
||||||
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
||||||
@@ -179,4 +187,13 @@ feature -- Node
|
|||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
feature -- Helpers
|
||||||
|
|
||||||
|
fill_node (a_node: CMS_NODE)
|
||||||
|
-- Fill `a_node' with extra information from database.
|
||||||
|
-- i.e: specific to each content type data.
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ note
|
|||||||
deferred class
|
deferred class
|
||||||
CMS_STORAGE_SQL
|
CMS_STORAGE_SQL
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
api: detachable CMS_API
|
||||||
|
-- Associated CMS api.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Error handler
|
feature -- Error handler
|
||||||
|
|
||||||
error_handler: ERROR_HANDLER
|
error_handler: ERROR_HANDLER
|
||||||
@@ -108,6 +115,54 @@ feature -- Operation
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Helper
|
||||||
|
|
||||||
|
sql_execute_file_script (a_path: PATH)
|
||||||
|
-- Execute SQL script from `a_path'.
|
||||||
|
local
|
||||||
|
f: PLAIN_TEXT_FILE
|
||||||
|
sql: STRING
|
||||||
|
do
|
||||||
|
create f.make_with_path (a_path)
|
||||||
|
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
|
||||||
|
sql_execute_script (sql)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_execute_script (a_sql_script: STRING)
|
||||||
|
-- Execute SQL script.
|
||||||
|
-- i.e: multiple SQL statements.
|
||||||
|
do
|
||||||
|
reset_error
|
||||||
|
-- sql_begin_transaction
|
||||||
|
sql_change (a_sql_script, Void)
|
||||||
|
-- sql_commit_transaction
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_table_exists (a_table_name: READABLE_STRING_8): BOOLEAN
|
||||||
|
-- Does table `a_table_name' exists?
|
||||||
|
local
|
||||||
|
l_params: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
reset_error
|
||||||
|
create l_params.make (1)
|
||||||
|
l_params.force (a_table_name, "tbname")
|
||||||
|
sql_query ("SELECT count(*) FROM :tbname ;", l_params)
|
||||||
|
Result := not has_error
|
||||||
|
-- FIXME: find better solution
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
sql_rows_count: INTEGER
|
sql_rows_count: INTEGER
|
||||||
@@ -130,7 +185,13 @@ feature -- Access
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sql_valid_item_index (a_index: INTEGER): BOOLEAN
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
sql_item (a_index: INTEGER): detachable ANY
|
sql_item (a_index: INTEGER): detachable ANY
|
||||||
|
require
|
||||||
|
valid_index: sql_valid_item_index (a_index)
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -160,7 +221,7 @@ feature -- Access
|
|||||||
elseif attached {INTEGER_32_REF} l_item as l_value then
|
elseif attached {INTEGER_32_REF} l_item as l_value then
|
||||||
Result := l_value.item
|
Result := l_value.item
|
||||||
else
|
else
|
||||||
-- check is_integer_32: False end
|
check is_integer_32: False end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -177,7 +238,7 @@ feature -- Access
|
|||||||
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then
|
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then
|
||||||
Result := l_boolean_ref.item.out
|
Result := l_boolean_ref.item.out
|
||||||
else
|
else
|
||||||
-- check is_string: False end
|
check is_string: False end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -192,7 +253,9 @@ feature -- Access
|
|||||||
Result := l_string
|
Result := l_string
|
||||||
else
|
else
|
||||||
if attached sql_read_string (a_index) as s8 then
|
if attached sql_read_string (a_index) as s8 then
|
||||||
Result := s8.to_string_32 -- FIXME
|
Result := s8.to_string_32 -- FIXME: any escape?
|
||||||
|
else
|
||||||
|
check is_string_32: False end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,6 +17,51 @@ feature -- Error Handling
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Storage extension
|
||||||
|
|
||||||
|
register_node_storage_extension (a_extension: CMS_NODE_STORAGE_EXTENSION [CMS_NODE])
|
||||||
|
-- Register `a_extension' as extension to the node storage system.
|
||||||
|
local
|
||||||
|
tb: like node_storage_extensions
|
||||||
|
do
|
||||||
|
tb := node_storage_extensions
|
||||||
|
if tb = Void then
|
||||||
|
create tb.make_caseless (1)
|
||||||
|
node_storage_extensions := tb
|
||||||
|
end
|
||||||
|
tb.force (a_extension, a_extension.content_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
node_storage_extension (a_node: CMS_NODE): detachable CMS_NODE_STORAGE_EXTENSION [CMS_NODE]
|
||||||
|
-- Extension to the node storage system for node `a_node'.
|
||||||
|
do
|
||||||
|
if attached node_storage_extensions as tb then
|
||||||
|
Result := tb.item (a_node.content_type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
node_storage_extensions: detachable STRING_TABLE [CMS_NODE_STORAGE_EXTENSION [CMS_NODE]]
|
||||||
|
-- Table of node storage extensions.
|
||||||
|
|
||||||
|
extended_store (a_node: CMS_NODE)
|
||||||
|
-- Store extended data from `a_node'.
|
||||||
|
do
|
||||||
|
if attached node_storage_extension (a_node) as ext then
|
||||||
|
ext.store_node (a_node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
extended_load (a_node: CMS_NODE)
|
||||||
|
-- Load extended data into `a_node'.
|
||||||
|
do
|
||||||
|
if attached node_storage_extension (a_node) as ext then
|
||||||
|
ext.load_node (a_node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
nodes_count: INTEGER_64
|
nodes_count: INTEGER_64
|
||||||
@@ -44,7 +89,7 @@ feature -- Access
|
|||||||
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
node_author (a_id: like {CMS_NODE}.id): detachable CMS_USER
|
||||||
-- Node's author. if any.
|
-- Node's author. if any.
|
||||||
require
|
require
|
||||||
valid_node: a_id >0
|
valid_node: a_id > 0
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -68,6 +113,15 @@ feature -- Change: Node
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
update_node (a_node: CMS_NODE)
|
||||||
|
-- Update node content `a_node'.
|
||||||
|
-- The user `a_id' is an existing or new collaborator.
|
||||||
|
require
|
||||||
|
has_id: a_node.has_id
|
||||||
|
has_author: attached a_node.author as l_author and then l_author.has_id
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
delete_node (a_node: CMS_NODE)
|
delete_node (a_node: CMS_NODE)
|
||||||
-- Delete `a_node'.
|
-- Delete `a_node'.
|
||||||
do
|
do
|
||||||
@@ -83,39 +137,40 @@ feature -- Change: Node
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node (a_node: CMS_NODE)
|
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||||
-- Update node content `a_node'.
|
-- -- Update node title to `a_title', node identified by id `a_node_id'.
|
||||||
-- The user `a_id' is an existing or new collaborator.
|
-- -- The user `a_user_id' is an existing or new collaborator.
|
||||||
|
-- require
|
||||||
|
-- valid_node_id: a_node_id > 0
|
||||||
|
-- valid_user_id: a_user_id > 0
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||||
|
-- -- Update node summary to `a_summary', node identified by id `a_node_id'.
|
||||||
|
-- -- The user `a_user_id' is an existing or new collaborator.
|
||||||
|
-- require
|
||||||
|
-- valid_id: a_node_id > 0
|
||||||
|
-- valid_user_id: a_user_id > 0
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||||
|
-- -- Update node content to `a_content', node identified by id `a_node_id'.
|
||||||
|
-- -- The user `a_user_id' is an existing or new collaborator.
|
||||||
|
-- require
|
||||||
|
-- valid_id: a_node_id > 0
|
||||||
|
-- valid_user_id: a_user_id > 0
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
feature -- Helpers
|
||||||
|
|
||||||
|
fill_node (a_node: CMS_NODE)
|
||||||
|
-- Fill `a_node' with extra information from database.
|
||||||
|
-- i.e: specific to each content type data.
|
||||||
require
|
require
|
||||||
has_id: a_node.has_id
|
has_id: a_node.has_id
|
||||||
has_author: attached a_node.author as l_author and then l_author.has_id
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
|
||||||
-- Update node title to `a_title', node identified by id `a_node_id'.
|
|
||||||
-- The user `a_user_id' is an existing or new collaborator.
|
|
||||||
require
|
|
||||||
valid_node_id: a_node_id > 0
|
|
||||||
valid_user_id: a_user_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_summary (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
|
||||||
-- Update node summary to `a_summary', node identified by id `a_node_id'.
|
|
||||||
-- The user `a_user_id' is an existing or new collaborator.
|
|
||||||
require
|
|
||||||
valid_id: a_node_id > 0
|
|
||||||
valid_user_id: a_user_id > 0
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_content (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
|
||||||
-- Update node content to `a_content', node identified by id `a_node_id'.
|
|
||||||
-- The user `a_user_id' is an existing or new collaborator.
|
|
||||||
require
|
|
||||||
valid_id: a_node_id > 0
|
|
||||||
valid_user_id: a_user_id > 0
|
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
53
src/persistence/node/cms_node_storage_extension.e
Normal file
53
src/persistence/node/cms_node_storage_extension.e
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
note
|
||||||
|
description: "Node storage extension for specific node descendant."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
CMS_NODE_STORAGE_EXTENSION [G -> CMS_NODE]
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
content_type: READABLE_STRING_8
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_accepted (a_node: CMS_NODE): BOOLEAN
|
||||||
|
-- Is `a_node' accepted by current storage extension?
|
||||||
|
do
|
||||||
|
Result := attached {G} a_node
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Persistence
|
||||||
|
|
||||||
|
store_node (a_node: CMS_NODE)
|
||||||
|
require
|
||||||
|
a_node_accepted: is_accepted (a_node)
|
||||||
|
do
|
||||||
|
if attached {G} a_node as obj then
|
||||||
|
store (obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
load_node (a_node: CMS_NODE)
|
||||||
|
require
|
||||||
|
a_node_accepted: is_accepted (a_node)
|
||||||
|
do
|
||||||
|
if attached {G} a_node as obj then
|
||||||
|
load (obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Persistence implementation
|
||||||
|
|
||||||
|
store (a_node: G)
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
load (a_node: G)
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_NODE_STORAGE_SQL}."
|
description: "[
|
||||||
author: ""
|
CMS NODE Storage based on SQL statements.
|
||||||
|
]"
|
||||||
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 $"
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ feature -- Access
|
|||||||
do
|
do
|
||||||
error_handler.reset
|
error_handler.reset
|
||||||
write_information_log (generator + ".nodes_count")
|
write_information_log (generator + ".nodes_count")
|
||||||
sql_query (select_nodes_count, Void)
|
sql_query (sql_select_nodes_count, Void)
|
||||||
if sql_rows_count = 1 then
|
if sql_rows_count = 1 then
|
||||||
Result := sql_read_integer_64 (1)
|
Result := sql_read_integer_64 (1)
|
||||||
end
|
end
|
||||||
@@ -38,7 +39,7 @@ feature -- Access
|
|||||||
write_information_log (generator + ".nodes")
|
write_information_log (generator + ".nodes")
|
||||||
|
|
||||||
from
|
from
|
||||||
sql_query (select_nodes, Void)
|
sql_query (sql_select_nodes, Void)
|
||||||
sql_start
|
sql_start
|
||||||
until
|
until
|
||||||
sql_after
|
sql_after
|
||||||
@@ -48,6 +49,11 @@ feature -- Access
|
|||||||
end
|
end
|
||||||
sql_forth
|
sql_forth
|
||||||
end
|
end
|
||||||
|
-- across
|
||||||
|
-- Result as ic
|
||||||
|
-- loop
|
||||||
|
-- fill_node (ic.item)
|
||||||
|
-- end
|
||||||
end
|
end
|
||||||
|
|
||||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||||
@@ -64,7 +70,7 @@ feature -- Access
|
|||||||
create l_parameters.make (2)
|
create l_parameters.make (2)
|
||||||
l_parameters.put (a_count, "rows")
|
l_parameters.put (a_count, "rows")
|
||||||
l_parameters.put (a_lower, "offset")
|
l_parameters.put (a_lower, "offset")
|
||||||
sql_query (select_recent_nodes, l_parameters)
|
sql_query (sql_select_recent_nodes, l_parameters)
|
||||||
sql_start
|
sql_start
|
||||||
until
|
until
|
||||||
sql_after
|
sql_after
|
||||||
@@ -84,8 +90,8 @@ feature -- Access
|
|||||||
error_handler.reset
|
error_handler.reset
|
||||||
write_information_log (generator + ".node")
|
write_information_log (generator + ".node")
|
||||||
create l_parameters.make (1)
|
create l_parameters.make (1)
|
||||||
l_parameters.put (a_id,"id")
|
l_parameters.put (a_id, "nid")
|
||||||
sql_query (select_node_by_id, l_parameters)
|
sql_query (sql_select_node_by_id, l_parameters)
|
||||||
if sql_rows_count = 1 then
|
if sql_rows_count = 1 then
|
||||||
Result := fetch_node
|
Result := fetch_node
|
||||||
end
|
end
|
||||||
@@ -121,31 +127,14 @@ feature -- Change: Node
|
|||||||
|
|
||||||
new_node (a_node: CMS_NODE)
|
new_node (a_node: CMS_NODE)
|
||||||
-- Save node `a_node'.
|
-- Save node `a_node'.
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
do
|
||||||
-- New node
|
store_node (a_node)
|
||||||
error_handler.reset
|
|
||||||
write_information_log (generator + ".new_node")
|
|
||||||
create l_parameters.make (7)
|
|
||||||
l_parameters.put (a_node.title, "title")
|
|
||||||
l_parameters.put (a_node.summary, "summary")
|
|
||||||
l_parameters.put (a_node.content, "content")
|
|
||||||
l_parameters.put (a_node.publication_date, "publish")
|
|
||||||
l_parameters.put (a_node.creation_date, "created")
|
|
||||||
l_parameters.put (a_node.modification_date, "changed")
|
|
||||||
if
|
|
||||||
attached a_node.author as l_author and then
|
|
||||||
l_author.id > 0
|
|
||||||
then
|
|
||||||
l_parameters.put (l_author.id, "author")
|
|
||||||
else
|
|
||||||
l_parameters.put (0, "author")
|
|
||||||
end
|
|
||||||
sql_change (sql_insert_node, l_parameters)
|
|
||||||
if not error_handler.has_error then
|
|
||||||
a_node.set_id (last_inserted_node_id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
update_node (a_node: CMS_NODE)
|
||||||
|
-- Update node content `a_node'.
|
||||||
|
do
|
||||||
|
store_node (a_node)
|
||||||
end
|
end
|
||||||
|
|
||||||
delete_node_by_id (a_id: INTEGER_64)
|
delete_node_by_id (a_id: INTEGER_64)
|
||||||
@@ -161,124 +150,163 @@ feature -- Change: Node
|
|||||||
sql_change (sql_delete_node, l_parameters)
|
sql_change (sql_delete_node, l_parameters)
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node (a_node: CMS_NODE)
|
-- update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||||
-- Update node content `a_node'.
|
-- -- <Precursor>
|
||||||
|
-- local
|
||||||
|
-- l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
-- do
|
||||||
|
-- -- FIXME: unused a_user_id !
|
||||||
|
-- error_handler.reset
|
||||||
|
-- write_information_log (generator + ".update_node_title")
|
||||||
|
-- create l_parameters.make (3)
|
||||||
|
-- l_parameters.put (a_title, "title")
|
||||||
|
-- l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||||
|
-- l_parameters.put (a_node_id, "nid")
|
||||||
|
-- sql_change (sql_update_node_title, l_parameters)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- update_node_summary (a_user_id: Like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||||
|
-- -- <Precursor>
|
||||||
|
-- local
|
||||||
|
-- l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
-- do
|
||||||
|
-- -- FIXME: unused a_user_id !
|
||||||
|
-- error_handler.reset
|
||||||
|
-- write_information_log (generator + ".update_node_summary")
|
||||||
|
-- create l_parameters.make (3)
|
||||||
|
-- l_parameters.put (a_summary, "summary")
|
||||||
|
-- l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||||
|
-- l_parameters.put (a_node_id, "nid")
|
||||||
|
-- sql_change (sql_update_node_summary, l_parameters)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- update_node_content (a_user_id: Like {CMS_USER}.id;a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||||
|
-- -- <Precursor>
|
||||||
|
-- local
|
||||||
|
-- l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
-- do
|
||||||
|
-- -- FIXME: unused a_user_id !
|
||||||
|
-- error_handler.reset
|
||||||
|
-- write_information_log (generator + ".update_node_content")
|
||||||
|
-- create l_parameters.make (3)
|
||||||
|
-- l_parameters.put (a_content, "content")
|
||||||
|
-- l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||||
|
-- l_parameters.put (a_node_id, "nid")
|
||||||
|
-- sql_change (sql_update_node_content, l_parameters)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
store_node (a_node: CMS_NODE)
|
||||||
local
|
local
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
now: DATE_TIME
|
now: DATE_TIME
|
||||||
|
is_new: BOOLEAN
|
||||||
do
|
do
|
||||||
create now.make_now_utc
|
create now.make_now_utc
|
||||||
error_handler.reset
|
error_handler.reset
|
||||||
write_information_log (generator + ".update_node")
|
|
||||||
create l_parameters.make (7)
|
write_information_log (generator + ".store_node")
|
||||||
|
create l_parameters.make (8)
|
||||||
|
l_parameters.put (a_node.content_type, "type")
|
||||||
l_parameters.put (a_node.title, "title")
|
l_parameters.put (a_node.title, "title")
|
||||||
l_parameters.put (a_node.summary, "summary")
|
l_parameters.put (a_node.summary, "summary")
|
||||||
l_parameters.put (a_node.content, "content")
|
l_parameters.put (a_node.content, "content")
|
||||||
l_parameters.put (a_node.publication_date, "publish")
|
l_parameters.put (a_node.publication_date, "publish")
|
||||||
l_parameters.put (now, "changed")
|
l_parameters.put (now, "changed")
|
||||||
l_parameters.put (a_node.id, "id")
|
|
||||||
if attached a_node.author as l_author then
|
if attached a_node.author as l_author then
|
||||||
|
check valid_author: l_author.has_id end
|
||||||
l_parameters.put (l_author.id, "author")
|
l_parameters.put (l_author.id, "author")
|
||||||
else
|
else
|
||||||
l_parameters.put (0, "author")
|
l_parameters.put (0, "author")
|
||||||
end
|
end
|
||||||
|
sql_begin_transaction
|
||||||
|
if a_node.has_id then
|
||||||
|
is_new := True
|
||||||
|
-- Update
|
||||||
|
l_parameters.put (a_node.id, "id")
|
||||||
sql_change (sql_update_node, l_parameters)
|
sql_change (sql_update_node, l_parameters)
|
||||||
if not error_handler.has_error then
|
if not error_handler.has_error then
|
||||||
|
a_node.set_revision (a_node.revision + 1) -- FIXME: Should be incremented by one, in same transaction...but check!
|
||||||
a_node.set_modification_date (now)
|
a_node.set_modification_date (now)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
is_new := False
|
||||||
|
-- Store new node
|
||||||
|
l_parameters.put (a_node.creation_date, "created")
|
||||||
|
sql_change (sql_insert_node, l_parameters)
|
||||||
|
if not error_handler.has_error then
|
||||||
|
a_node.set_modification_date (now)
|
||||||
|
a_node.set_id (last_inserted_node_id)
|
||||||
|
a_node.set_revision (1) -- New object.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
extended_store (a_node)
|
||||||
|
sql_commit_transaction
|
||||||
end
|
end
|
||||||
|
|
||||||
update_node_title (a_user_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
feature -- Helpers
|
||||||
-- <Precursor>
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
-- FIXME: unused a_user_id !
|
|
||||||
error_handler.reset
|
|
||||||
write_information_log (generator + ".update_node_title")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_title, "title")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
|
||||||
l_parameters.put (a_node_id, "nid")
|
|
||||||
sql_change (sql_update_node_title, l_parameters)
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_summary (a_user_id: Like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
fill_node (a_node: CMS_NODE)
|
||||||
-- <Precursor>
|
-- Fill `a_node' with extra information from database.
|
||||||
local
|
-- i.e: specific to each content type data.
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
do
|
||||||
-- FIXME: unused a_user_id !
|
|
||||||
error_handler.reset
|
error_handler.reset
|
||||||
write_information_log (generator + ".update_node_summary")
|
write_information_log (generator + ".fill_node")
|
||||||
create l_parameters.make (3)
|
extended_load (a_node)
|
||||||
l_parameters.put (a_summary, "summary")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
|
||||||
l_parameters.put (a_node_id, "nid")
|
|
||||||
sql_change (sql_update_node_summary, l_parameters)
|
|
||||||
end
|
|
||||||
|
|
||||||
update_node_content (a_user_id: Like {CMS_USER}.id;a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
|
||||||
-- <Precursor>
|
|
||||||
local
|
|
||||||
l_parameters: STRING_TABLE [detachable ANY]
|
|
||||||
do
|
|
||||||
-- FIXME: unused a_user_id !
|
|
||||||
error_handler.reset
|
|
||||||
write_information_log (generator + ".update_node_content")
|
|
||||||
create l_parameters.make (3)
|
|
||||||
l_parameters.put (a_content, "content")
|
|
||||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
|
||||||
l_parameters.put (a_node_id, "nid")
|
|
||||||
sql_change (sql_update_node_content, l_parameters)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Queries
|
feature {NONE} -- Queries
|
||||||
|
|
||||||
Select_nodes_count: STRING = "select count(*) from Nodes;"
|
sql_select_nodes_count: STRING = "SELECT count(*) from Nodes;"
|
||||||
|
|
||||||
Select_nodes: STRING = "select * from Nodes;"
|
sql_select_nodes: STRING = "SELECT * from Nodes;"
|
||||||
-- SQL Query to retrieve all nodes.
|
-- SQL Query to retrieve all nodes.
|
||||||
|
|
||||||
Select_node_by_id: STRING = "select * from Nodes where nid =:nid order by nid desc, publish desc;"
|
sql_select_node_by_id: STRING = "SELECT nid, revision, type, title, summary, content, author, publish, created, changed FROM Nodes WHERE nid =:nid ORDER BY revision desc, publish desc LIMIT 1;"
|
||||||
|
|
||||||
Select_recent_nodes: STRING = "select * from Nodes order by nid desc, publish desc LIMIT :rows OFFSET :offset ;"
|
sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, author, publish, created, changed FROM Nodes ORDER BY nid desc, publish desc LIMIT :rows OFFSET :offset ;"
|
||||||
|
|
||||||
SQL_Insert_node: STRING = "insert into nodes (title, summary, content, publish, created, changed, author) values (:title, :summary, :content, :publish, :created, :changed, :author);"
|
sql_insert_node: STRING = "INSERT INTO nodes (revision, type, title, summary, content, publish, created, changed, author) VALUES (1, :type, :title, :summary, :content, :publish, :created, :changed, :author);"
|
||||||
-- SQL Insert to add a new node.
|
-- SQL Insert to add a new node.
|
||||||
|
|
||||||
SQL_Update_node : STRING = "update nodes SET title=:title, summary=:summary, content=:content, publish=:publish, changed=:changed, version = version + 1, author=:author where nid=:nid;"
|
sql_update_node : STRING = "UPDATE nodes SET revision = revision + 1, type=:type, title=:title, summary=:summary, content=:content, publish=:publish, changed=:changed, revision = revision + 1, author=:author WHERE nid=:nid;"
|
||||||
-- SQL node.
|
-- SQL node.
|
||||||
|
|
||||||
SQL_Delete_node: STRING = "delete from nodes where nid=:nid;"
|
sql_delete_node: STRING = "DELETE FROM nodes WHERE nid=:nid;"
|
||||||
|
|
||||||
Sql_update_node_author: STRING = "update nodes SET author=:author where nid=:nid;"
|
-- sql_update_node_author: STRING = "UPDATE nodes SET author=:author WHERE nid=:nid;"
|
||||||
|
|
||||||
SQL_Update_node_title: STRING ="update nodes SET title=:title, changed=:changed, version = version + 1 where nid=:nid;"
|
-- sql_update_node_title: STRING ="UPDATE nodes SET title=:title, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
|
||||||
-- SQL update node title.
|
-- -- SQL update node title.
|
||||||
|
|
||||||
SQL_Update_node_summary: STRING ="update nodes SET summary=:summary, changed=:changed, version = version + 1 where nid=:nid;"
|
-- sql_update_node_summary: STRING ="UPDATE nodes SET summary=:summary, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
|
||||||
-- SQL update node summary.
|
-- -- SQL update node summary.
|
||||||
|
|
||||||
SQL_Update_node_content: STRING ="update nodes SET content=:content, changed=:changed, version = version + 1 where nid=:nid;"
|
-- sql_update_node_content: STRING ="UPDATE nodes SET content=:content, changed=:changed, revision = revision + 1 WHERE nid=:nid;"
|
||||||
-- SQL node content.
|
-- -- SQL node content.
|
||||||
|
|
||||||
Sql_last_insert_node_id: STRING = "SELECT MAX(nid) from nodes;"
|
sql_last_insert_node_id: STRING = "SELECT MAX(nid) FROM nodes;"
|
||||||
|
|
||||||
feature {NONE} -- Sql Queries: USER_ROLES collaborators, author
|
feature {NONE} -- Sql Queries: USER_ROLES collaborators, author
|
||||||
|
|
||||||
Select_user_author: STRING = "SELECT * FROM Nodes INNER JOIN users ON nodes.author=users.uid and users.uid = :uid;"
|
Select_user_author: STRING = "SELECT uid, name, password, salt, email, status, created, signed FROM Nodes INNER JOIN users ON nodes.author=users.uid AND users.uid = :uid;"
|
||||||
|
|
||||||
Select_node_author: STRING = "SELECT * FROM Users INNER JOIN nodes ON nodes.author=users.uid and nodes.nid =:nid;"
|
Select_node_author: STRING = "SELECT nid, revision, type, title, summary, content, author, publish, created, changed FROM users INNER JOIN nodes ON nodes.author=users.uid AND nodes.nid =:nid;"
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
fetch_node: CMS_NODE
|
fetch_node: detachable CMS_PARTIAL_NODE
|
||||||
do
|
do
|
||||||
create Result.make ("", "", "")
|
if attached sql_read_string (3) as l_type then
|
||||||
|
create Result.make_empty (l_type)
|
||||||
|
|
||||||
if attached sql_read_integer_64 (1) as l_id then
|
if attached sql_read_integer_64 (1) as l_id then
|
||||||
Result.set_id (l_id)
|
Result.set_id (l_id)
|
||||||
end
|
end
|
||||||
|
if attached sql_read_integer_64 (2) as l_revision then
|
||||||
|
Result.set_revision (l_revision)
|
||||||
|
end
|
||||||
if attached sql_read_string_32 (4) as l_title then
|
if attached sql_read_string_32 (4) as l_title then
|
||||||
Result.set_title (l_title)
|
Result.set_title (l_title)
|
||||||
end
|
end
|
||||||
@@ -298,7 +326,8 @@ feature {NONE} -- Implementation
|
|||||||
Result.set_modification_date (l_modif_date)
|
Result.set_modification_date (l_modif_date)
|
||||||
end
|
end
|
||||||
if attached sql_read_integer_64 (7) as l_author_id then
|
if attached sql_read_integer_64 (7) as l_author_id then
|
||||||
-- access to API ...
|
Result.set_author (create {CMS_PARTIAL_USER}.make_with_id (l_author_id))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
111
src/persistence/node/cms_node_storage_sql_page_extension.e
Normal file
111
src/persistence/node/cms_node_storage_sql_page_extension.e
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
note
|
||||||
|
description: "Storage extension for Page nodes."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_NODE_STORAGE_SQL_PAGE_EXTENSION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
CMS_NODE_STORAGE_EXTENSION [CMS_PAGE]
|
||||||
|
|
||||||
|
CMS_PROXY_STORAGE_SQL
|
||||||
|
rename
|
||||||
|
sql_storage as node_storage
|
||||||
|
redefine
|
||||||
|
node_storage
|
||||||
|
end
|
||||||
|
|
||||||
|
SHARED_LOGGER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
node_storage: CMS_NODE_STORAGE_SQL
|
||||||
|
-- <Precursor>
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
content_type: STRING
|
||||||
|
once
|
||||||
|
Result := {CMS_PAGE_CONTENT_TYPE}.name
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Persistence
|
||||||
|
|
||||||
|
store (a_node: CMS_PAGE)
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
l_new_parent_id, l_previous_parent_id: INTEGER_64
|
||||||
|
l_update: BOOLEAN
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
write_information_log (generator + ".store_page_data")
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_node.id, "nid")
|
||||||
|
l_parameters.put (a_node.revision, "revision")
|
||||||
|
|
||||||
|
sql_query (sql_select_page_data, l_parameters)
|
||||||
|
if has_error then
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
l_previous_parent_id := sql_read_integer_64 (3)
|
||||||
|
l_update := True
|
||||||
|
end
|
||||||
|
if attached a_node.parent as l_parent then
|
||||||
|
l_new_parent_id := l_parent.id
|
||||||
|
else
|
||||||
|
l_new_parent_id := 0
|
||||||
|
end
|
||||||
|
l_parameters.put (l_new_parent_id, "parent")
|
||||||
|
if l_update and l_new_parent_id /= l_previous_parent_id then
|
||||||
|
sql_change (sql_update_page_data, l_parameters)
|
||||||
|
elseif l_new_parent_id > 0 then
|
||||||
|
sql_change (sql_insert_page_data, l_parameters)
|
||||||
|
else
|
||||||
|
-- no page data, means everything is empty.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
load (a_node: CMS_PAGE)
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
n: INTEGER
|
||||||
|
ct: CMS_PAGE_CONTENT_TYPE
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
write_information_log (generator + ".fill_page")
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_node.id, "nid")
|
||||||
|
l_parameters.put (a_node.revision, "revision")
|
||||||
|
sql_query (sql_select_page_data, l_parameters)
|
||||||
|
if not has_error then
|
||||||
|
n := sql_rows_count
|
||||||
|
if n = 1 then
|
||||||
|
-- nid, revision, parent
|
||||||
|
if
|
||||||
|
attached sql_read_integer_64 (3) as l_parent_id and then
|
||||||
|
l_parent_id /= a_node.id and then
|
||||||
|
attached node_storage.node_by_id (l_parent_id) as l_parent
|
||||||
|
then
|
||||||
|
create ct
|
||||||
|
a_node.set_parent (ct.new_node (l_parent))
|
||||||
|
else
|
||||||
|
write_debug_log ("Invalid parent node id!")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
check unique_data: n = 0 end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- SQL
|
||||||
|
|
||||||
|
sql_select_page_data: STRING = "SELECT nid, revision, parent FROM page_nodes WHERE nid =:nid AND revision=:revision;"
|
||||||
|
sql_insert_page_data: STRING = "INSERT INTO page_nodes (nid, revision, parent) VALUES (:nid, :revision, :parent);"
|
||||||
|
sql_update_page_data: STRING = "UPDATE page_nodes SET nid=:nid, revision=:revision, parent=:parent WHERE nid=:nid AND revision=:revision;"
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -90,29 +90,29 @@ feature -- Change: user
|
|||||||
|
|
||||||
feature -- Access: roles and permissions
|
feature -- Access: roles and permissions
|
||||||
|
|
||||||
user_has_permission (u: detachable CMS_USER; s: detachable READABLE_STRING_8): BOOLEAN
|
-- user_has_permission (u: detachable CMS_USER; s: detachable READABLE_STRING_8): BOOLEAN
|
||||||
-- Anonymous or user `u' has permission for `s' ?
|
-- -- Anonymous or user `u' has permission for `s' ?
|
||||||
--| `s' could be "create page",
|
-- --| `s' could be "create page",
|
||||||
do
|
-- do
|
||||||
-- if s = Void then
|
---- if s = Void then
|
||||||
-- Result := True
|
---- Result := True
|
||||||
-- elseif u = Void then
|
---- elseif u = Void then
|
||||||
---- Result := user_role_has_permission (anonymous_user_role, s)
|
------ Result := user_role_has_permission (anonymous_user_role, s)
|
||||||
-- else
|
---- else
|
||||||
-- Result := user_role_has_permission (authenticated_user_role, s)
|
---- Result := user_role_has_permission (authenticated_user_role, s)
|
||||||
-- if not Result and attached u.roles as l_roles then
|
---- if not Result and attached u.roles as l_roles then
|
||||||
-- across
|
---- across
|
||||||
-- l_roles as r
|
---- l_roles as r
|
||||||
-- until
|
---- until
|
||||||
-- Result
|
---- Result
|
||||||
-- loop
|
---- loop
|
||||||
-- if attached user_role_by_id (r.item) as ur then
|
---- if attached user_role_by_id (r.item) as ur then
|
||||||
-- Result := user_role_has_permission (ur, s)
|
---- Result := user_role_has_permission (ur, s)
|
||||||
|
---- end
|
||||||
|
---- end
|
||||||
|
---- end
|
||||||
|
---- end
|
||||||
-- end
|
-- end
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
|
|
||||||
user_role_has_permission (a_role: CMS_USER_ROLE; s: READABLE_STRING_8): BOOLEAN
|
user_role_has_permission (a_role: CMS_USER_ROLE; s: READABLE_STRING_8): BOOLEAN
|
||||||
do
|
do
|
||||||
@@ -124,6 +124,12 @@ feature -- Access: roles and permissions
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
user_roles_for (a_user: CMS_USER): LIST [CMS_USER_ROLE]
|
||||||
|
-- User roles for user `a_user'.
|
||||||
|
-- Note: anonymous and authenticated roles are not included.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
user_roles: LIST [CMS_USER_ROLE]
|
user_roles: LIST [CMS_USER_ROLE]
|
||||||
-- Possible list of user roles.
|
-- Possible list of user roles.
|
||||||
deferred
|
deferred
|
||||||
|
|||||||
@@ -208,24 +208,240 @@ feature -- Change: user
|
|||||||
feature -- Access: roles and permissions
|
feature -- Access: roles and permissions
|
||||||
|
|
||||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
do
|
do
|
||||||
to_implement (generator + ".user_role_by_id")
|
error_handler.reset
|
||||||
|
write_information_log (generator + ".user_role_by_id")
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_id, "rid")
|
||||||
|
sql_query (select_user_role_by_id, l_parameters)
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := fetch_user_role
|
||||||
|
if Result /= Void and not has_error then
|
||||||
|
fill_user_role (Result)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
check no_more_than_one: sql_rows_count = 0 end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
user_roles_for (a_user: CMS_USER): LIST [CMS_USER_ROLE]
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
write_information_log (generator + ".user_roles_for")
|
||||||
|
|
||||||
|
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
||||||
|
from
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_user.id, "uid")
|
||||||
|
sql_query (select_user_roles_by_user_id, l_parameters)
|
||||||
|
sql_start
|
||||||
|
until
|
||||||
|
sql_after
|
||||||
|
loop
|
||||||
|
if attached fetch_user_role as l_role then
|
||||||
|
Result.force (l_role)
|
||||||
|
end
|
||||||
|
sql_forth
|
||||||
|
end
|
||||||
|
if not has_error then
|
||||||
|
across Result as ic loop
|
||||||
|
fill_user_role (ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
user_roles: LIST [CMS_USER_ROLE]
|
user_roles: LIST [CMS_USER_ROLE]
|
||||||
|
local
|
||||||
|
l_role: detachable CMS_USER_ROLE
|
||||||
do
|
do
|
||||||
to_implement (generator + ".user_roles")
|
error_handler.reset
|
||||||
create {ARRAYED_LIST[CMS_USER_ROLE]} Result.make (0)
|
write_information_log (generator + ".user_roles")
|
||||||
|
|
||||||
|
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
||||||
|
from
|
||||||
|
sql_query (select_user_roles, Void)
|
||||||
|
sql_start
|
||||||
|
until
|
||||||
|
sql_after
|
||||||
|
loop
|
||||||
|
l_role := fetch_user_role
|
||||||
|
if l_role /= Void then
|
||||||
|
Result.force (l_role)
|
||||||
|
end
|
||||||
|
sql_forth
|
||||||
|
end
|
||||||
|
if not has_error then
|
||||||
|
across Result as ic loop
|
||||||
|
fill_user_role (ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fill_user_role (a_role: CMS_USER_ROLE)
|
||||||
|
require
|
||||||
|
a_role_has_id: a_role.has_id
|
||||||
|
do
|
||||||
|
if attached role_permissions_by_id (a_role.id) as l_permissions then
|
||||||
|
across
|
||||||
|
l_permissions as p_ic
|
||||||
|
loop
|
||||||
|
a_role.add_permission (p_ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
role_permissions_by_id (a_role_id: INTEGER_32): LIST [READABLE_STRING_8]
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [ANY]
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
write_information_log (generator + ".role_permissions_by_id")
|
||||||
|
|
||||||
|
create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (0)
|
||||||
|
from
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_role_id, "rid")
|
||||||
|
sql_query (select_role_permissions_by_role_id, l_parameters)
|
||||||
|
sql_start
|
||||||
|
until
|
||||||
|
sql_after
|
||||||
|
loop
|
||||||
|
if attached sql_read_string (1) as l_permission then
|
||||||
|
Result.force (l_permission)
|
||||||
|
end
|
||||||
|
-- if attached sql_read_string_32 (2) as l_module then
|
||||||
|
-- end
|
||||||
|
sql_forth
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Change: roles and permissions
|
feature -- Change: roles and permissions
|
||||||
|
|
||||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
l_existing_role: detachable CMS_USER_ROLE
|
||||||
|
l_permissions: detachable LIST [READABLE_STRING_8]
|
||||||
|
p: READABLE_STRING_8
|
||||||
|
l_found: BOOLEAN
|
||||||
do
|
do
|
||||||
to_implement (generator + ".save_user_role")
|
error_handler.reset
|
||||||
|
write_information_log (generator + ".save_user_role")
|
||||||
|
|
||||||
|
|
||||||
|
if a_user_role.has_id then
|
||||||
|
l_existing_role := user_role_by_id (a_user_role.id)
|
||||||
|
check l_existing_role /= Void and then l_existing_role.id = a_user_role.id end
|
||||||
|
if
|
||||||
|
l_existing_role /= Void and then
|
||||||
|
l_existing_role.name.same_string (a_user_role.name)
|
||||||
|
then
|
||||||
|
-- No update needed
|
||||||
|
else
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_user_role.id, "rid")
|
||||||
|
l_parameters.put (a_user_role.name, "name")
|
||||||
|
sql_change (sql_update_user_role, l_parameters)
|
||||||
|
end
|
||||||
|
if not a_user_role.permissions.is_empty then
|
||||||
|
-- FIXME: check if this is non set permissions,or none ...
|
||||||
|
if l_existing_role /= Void then
|
||||||
|
l_permissions := l_existing_role.permissions
|
||||||
|
fill_user_role (l_existing_role)
|
||||||
|
end
|
||||||
|
if l_permissions = Void or else l_permissions.is_empty then
|
||||||
|
l_permissions := role_permissions_by_id (a_user_role.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
across
|
||||||
|
a_user_role.permissions as ic
|
||||||
|
loop
|
||||||
|
p := ic.item
|
||||||
|
from
|
||||||
|
l_found := False
|
||||||
|
l_permissions.start
|
||||||
|
until
|
||||||
|
l_found or l_permissions.after
|
||||||
|
loop
|
||||||
|
if p.is_case_insensitive_equal (l_permissions.item) then
|
||||||
|
l_found := True
|
||||||
|
else
|
||||||
|
l_permissions.forth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if l_found then
|
||||||
|
-- Already there, skip
|
||||||
|
else
|
||||||
|
-- Add permission
|
||||||
|
set_permission_for_role_id (p, a_user_role.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Remove other
|
||||||
|
across
|
||||||
|
l_permissions as ic
|
||||||
|
loop
|
||||||
|
unset_permission_for_role_id (ic.item, a_user_role.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
create l_parameters.make (1)
|
||||||
|
l_parameters.put (a_user_role.name, "name")
|
||||||
|
sql_change (sql_insert_user_role, l_parameters)
|
||||||
|
if not error_handler.has_error then
|
||||||
|
a_user_role.set_id (last_inserted_user_role_id)
|
||||||
|
across
|
||||||
|
a_user_role.permissions as ic
|
||||||
|
loop
|
||||||
|
set_permission_for_role_id (ic.item, a_user_role.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set_permission_for_role_id (a_permission: READABLE_STRING_8; a_role_id: INTEGER)
|
||||||
|
require
|
||||||
|
a_role_id > 0
|
||||||
|
not a_permission.is_whitespace
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
create l_parameters.make (3)
|
||||||
|
l_parameters.put (a_role_id, "rid")
|
||||||
|
l_parameters.put (a_permission, "permission")
|
||||||
|
l_parameters.put (Void, "module") -- FIXME: unsupported for now!
|
||||||
|
sql_change (sql_insert_user_role_permission, l_parameters)
|
||||||
|
end
|
||||||
|
|
||||||
|
unset_permission_for_role_id (a_permission: READABLE_STRING_8; a_role_id: INTEGER)
|
||||||
|
require
|
||||||
|
a_role_id > 0
|
||||||
|
not a_permission.is_whitespace
|
||||||
|
|
||||||
|
local
|
||||||
|
l_parameters: STRING_TABLE [detachable ANY]
|
||||||
|
do
|
||||||
|
create l_parameters.make (2)
|
||||||
|
l_parameters.put (a_role_id, "rid")
|
||||||
|
l_parameters.put (a_permission, "permission")
|
||||||
|
sql_change (sql_delete_user_role_permission, l_parameters)
|
||||||
|
end
|
||||||
|
|
||||||
|
last_inserted_user_role_id: INTEGER_32
|
||||||
|
-- Last inserted user role id.
|
||||||
|
do
|
||||||
|
error_handler.reset
|
||||||
|
write_information_log (generator + ".last_inserted_user_role_id")
|
||||||
|
sql_query (Sql_last_insert_user_role_id, Void)
|
||||||
|
if sql_rows_count = 1 then
|
||||||
|
Result := sql_read_integer_32 (1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation: User
|
||||||
|
|
||||||
user_salt (a_username: READABLE_STRING_32): detachable READABLE_STRING_8
|
user_salt (a_username: READABLE_STRING_32): detachable READABLE_STRING_8
|
||||||
-- User salt for the given user `a_username', if any.
|
-- User salt for the given user `a_username', if any.
|
||||||
@@ -289,32 +505,83 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation: User role
|
||||||
|
|
||||||
|
fetch_user_role: detachable CMS_USER_ROLE
|
||||||
|
local
|
||||||
|
l_id: INTEGER_32
|
||||||
|
l_name: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
if attached sql_read_integer_32 (1) as rid then
|
||||||
|
l_id := rid
|
||||||
|
end
|
||||||
|
if attached sql_read_string_32 (2) as s and then not s.is_whitespace then
|
||||||
|
l_name := s
|
||||||
|
end
|
||||||
|
|
||||||
|
if l_name /= Void then
|
||||||
|
create Result.make (l_name)
|
||||||
|
if l_id > 0 then
|
||||||
|
Result.set_id (l_id)
|
||||||
|
end
|
||||||
|
elseif l_id > 0 then
|
||||||
|
create Result.make_with_id (l_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- Sql Queries: USER
|
feature {NONE} -- Sql Queries: USER
|
||||||
|
|
||||||
Select_users_count: STRING = "select count(*) from Users;"
|
Select_users_count: STRING = "SELECT count(*) FROM Users;"
|
||||||
-- Number of users.
|
-- Number of users.
|
||||||
|
|
||||||
Sql_last_insert_user_id: STRING = "SELECT MAX(uid) from Users;"
|
Sql_last_insert_user_id: STRING = "SELECT MAX(uid) FROM Users;"
|
||||||
|
|
||||||
Select_users: STRING = "select * from Users;"
|
Select_users: STRING = "SELECT * FROM Users;"
|
||||||
-- List of users.
|
-- List of users.
|
||||||
|
|
||||||
Select_user_by_id: STRING = "select * from Users where uid =:uid;"
|
Select_user_by_id: STRING = "SELECT * FROM Users WHERE uid =:uid;"
|
||||||
-- Retrieve user by id if exists.
|
-- Retrieve user by id if exists.
|
||||||
|
|
||||||
Select_user_by_name: STRING = "select * from Users where name =:name;"
|
Select_user_by_name: STRING = "SELECT * FROM Users WHERE name =:name;"
|
||||||
-- Retrieve user by name if exists.
|
-- Retrieve user by name if exists.
|
||||||
|
|
||||||
Select_user_by_email: STRING = "select * from Users where email =:email;"
|
Select_user_by_email: STRING = "SELECT * FROM Users WHERE email =:email;"
|
||||||
-- Retrieve user by email if exists.
|
-- Retrieve user by email if exists.
|
||||||
|
|
||||||
Select_salt_by_username: STRING = "select salt from Users where name =:name;"
|
Select_salt_by_username: STRING = "SELECT salt FROM Users WHERE name =:name;"
|
||||||
-- Retrieve salt by username if exists.
|
-- Retrieve salt by username if exists.
|
||||||
|
|
||||||
Sql_Insert_user: STRING = "insert into users (name, password, salt, email, created) values (:name, :password, :salt, :email, :created);"
|
sql_insert_user: STRING = "INSERT INTO users (name, password, salt, email, created) VALUES (:name, :password, :salt, :email, :created);"
|
||||||
-- SQL Insert to add a new node.
|
-- SQL Insert to add a new node.
|
||||||
|
|
||||||
sql_update_user: STRING = "update users SET name=:name, password=:password, salt=:salt, email=:email WHERE uid=:uid;"
|
sql_update_user: STRING = "UPDATE users SET name=:name, password=:password, salt=:salt, email=:email WHERE uid=:uid;"
|
||||||
|
|
||||||
|
feature {NONE} -- Sql Queries: USER ROLE
|
||||||
|
|
||||||
|
sql_last_insert_user_role_id: STRING = "SELECT MAX(rid) FROM roles;"
|
||||||
|
|
||||||
|
select_user_roles: STRING = "SELECT rid, name FROM roles;"
|
||||||
|
-- List of user roles.
|
||||||
|
|
||||||
|
sql_insert_user_role: STRING = "INSERT INTO roles (name) VALUES (:name);"
|
||||||
|
-- SQL Insert to add a new user role with name :name.
|
||||||
|
|
||||||
|
sql_update_user_role : STRING = "UPDATE roles SET name=:name WHERE rid=:rid;"
|
||||||
|
-- Update user role with id :rid.
|
||||||
|
|
||||||
|
select_user_roles_by_user_id: STRING = "SELECT rid, name FROM roles INNER JOIN users_roles ON users_roles.rid=roles.rid WHERE users_roles.uid=:uid;"
|
||||||
|
-- List of user roles for user id :uid.
|
||||||
|
|
||||||
|
select_user_role_by_id: STRING = "SELECT rid, name FROM roles WHERE rid=:rid;"
|
||||||
|
-- User role for role id :rid;
|
||||||
|
|
||||||
|
sql_insert_user_role_permission: STRING = "INSERT INTO role_permissions (rid, permission, module) VALUES (:rid, :permission, :module);"
|
||||||
|
-- SQL Insert a new permission :permission for user role :rid.
|
||||||
|
|
||||||
|
sql_delete_user_role_permission: STRING = "DELETE FROM role_permissions WHERE rid=:rid AND permission=:permission;"
|
||||||
|
-- SQL Delete permission :permission from user role :rid.
|
||||||
|
|
||||||
|
select_role_permissions_by_role_id: STRING = "SELECT permission, module FROM role_permissions WHERE rid=:rid;"
|
||||||
|
-- User role permissions for role id :rid;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ feature {NONE} -- Initialize
|
|||||||
|
|
||||||
initialize
|
initialize
|
||||||
-- Initialize the persitent layer.
|
-- Initialize the persitent layer.
|
||||||
|
local
|
||||||
|
l_module: CMS_MODULE
|
||||||
do
|
do
|
||||||
to_implement ("Refactor database setup")
|
to_implement ("Refactor database setup")
|
||||||
if attached setup.storage (error_handler) as l_storage then
|
if attached setup.storage (error_handler) as l_storage then
|
||||||
@@ -39,6 +41,17 @@ feature {NONE} -- Initialize
|
|||||||
else
|
else
|
||||||
create {CMS_STORAGE_NULL} storage
|
create {CMS_STORAGE_NULL} storage
|
||||||
end
|
end
|
||||||
|
storage.set_api (Current)
|
||||||
|
|
||||||
|
across
|
||||||
|
setup.enabled_modules as ic
|
||||||
|
loop
|
||||||
|
l_module := ic.item
|
||||||
|
if not l_module.is_installed (Current) then
|
||||||
|
l_module.install (Current)
|
||||||
|
end
|
||||||
|
l_module.initialize (Current)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
@@ -52,6 +65,13 @@ feature -- Access
|
|||||||
storage: CMS_STORAGE
|
storage: CMS_STORAGE
|
||||||
-- Default persistence storage.
|
-- Default persistence storage.
|
||||||
|
|
||||||
|
feature -- Formats
|
||||||
|
|
||||||
|
formats: CMS_FORMATS
|
||||||
|
once
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Status Report
|
feature -- Status Report
|
||||||
|
|
||||||
has_error: BOOLEAN
|
has_error: BOOLEAN
|
||||||
@@ -66,6 +86,15 @@ feature -- Status Report
|
|||||||
Result := error_handler.as_string_representation
|
Result := error_handler.as_string_representation
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Permissions system
|
||||||
|
|
||||||
|
user_has_permission (a_user: detachable CMS_USER; a_permission: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- Anonymous or user `a_user' has permission for `a_permission'?
|
||||||
|
--| `a_permission' could be for instance "create page".
|
||||||
|
do
|
||||||
|
Result := user_api.user_has_permission (a_user, a_permission)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Query: module
|
feature -- Query: module
|
||||||
|
|
||||||
module (a_type: TYPE [CMS_MODULE]): detachable CMS_MODULE
|
module (a_type: TYPE [CMS_MODULE]): detachable CMS_MODULE
|
||||||
|
|||||||
@@ -11,16 +11,22 @@ feature {NONE} -- Implementation
|
|||||||
|
|
||||||
make (a_api: CMS_API)
|
make (a_api: CMS_API)
|
||||||
do
|
do
|
||||||
api := a_api
|
cms_api := a_api
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
|
||||||
|
initialize
|
||||||
|
-- Initialize Current api.
|
||||||
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {CMS_MODULE, CMS_API} -- Restricted access
|
feature {CMS_MODULE, CMS_API} -- Restricted access
|
||||||
|
|
||||||
api: CMS_API
|
cms_api: CMS_API
|
||||||
|
|
||||||
storage: CMS_STORAGE
|
storage: CMS_STORAGE
|
||||||
do
|
do
|
||||||
Result := api.storage
|
Result := cms_api.storage
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {CMS_MODULE_HANDLER}."
|
description: "CMS handler specific for a module api"
|
||||||
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 $"
|
||||||
|
|
||||||
|
|||||||
@@ -268,13 +268,6 @@ feature -- Logging
|
|||||||
-- service.storage.save_log (l_log)
|
-- service.storage.save_log (l_log)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Formats
|
|
||||||
|
|
||||||
formats: CMS_FORMATS
|
|
||||||
once
|
|
||||||
create Result
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Menu
|
feature -- Menu
|
||||||
|
|
||||||
menu_system: CMS_MENU_SYSTEM
|
menu_system: CMS_MENU_SYSTEM
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ create
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
|
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
||||||
|
-- User by id `a_id', if any.
|
||||||
|
do
|
||||||
|
Result := storage.user_by_id (a_id)
|
||||||
|
end
|
||||||
|
|
||||||
user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER
|
user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER
|
||||||
-- User by name `a_user_name', if any.
|
-- User by name `a_user_name', if any.
|
||||||
do
|
do
|
||||||
@@ -31,6 +37,65 @@ feature -- Status report
|
|||||||
Result := storage.is_valid_credential (a_auth_login, a_auth_password)
|
Result := storage.is_valid_credential (a_auth_login, a_auth_password)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
user_has_permission (a_user: detachable CMS_USER; a_permission: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- Anonymous or user `a_user' has permission for `a_permission'?
|
||||||
|
--| `a_permission' could be for instance "create page".
|
||||||
|
do
|
||||||
|
if a_permission = Void then
|
||||||
|
Result := True
|
||||||
|
elseif a_user = Void then
|
||||||
|
Result := user_role_has_permission (anonymous_user_role, a_permission)
|
||||||
|
else
|
||||||
|
Result := user_role_has_permission (authenticated_user_role, a_permission)
|
||||||
|
if not Result then
|
||||||
|
Result := across user_roles (a_user) as ic some user_role_has_permission (ic.item, a_permission) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
user_roles (a_user: CMS_USER): LIST [CMS_USER_ROLE]
|
||||||
|
local
|
||||||
|
l_roles: detachable LIST [CMS_USER_ROLE]
|
||||||
|
do
|
||||||
|
l_roles := a_user.roles
|
||||||
|
if l_roles = Void then
|
||||||
|
-- Fill user with its roles.
|
||||||
|
create {ARRAYED_LIST [CMS_USER_ROLE]} l_roles.make (0)
|
||||||
|
l_roles := storage.user_roles_for (a_user)
|
||||||
|
end
|
||||||
|
Result := l_roles
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- User roles.
|
||||||
|
|
||||||
|
anonymous_user_role: CMS_USER_ROLE
|
||||||
|
do
|
||||||
|
if attached user_role_by_id (1) as l_anonymous then
|
||||||
|
Result := l_anonymous
|
||||||
|
else
|
||||||
|
create Result.make ("anonymous")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
authenticated_user_role: CMS_USER_ROLE
|
||||||
|
do
|
||||||
|
if attached user_role_by_id (2) as l_authenticated then
|
||||||
|
Result := l_authenticated
|
||||||
|
else
|
||||||
|
create Result.make ("authenticated")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
user_role_has_permission (a_role: CMS_USER_ROLE; a_permission: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := a_role.has_permission (a_permission)
|
||||||
|
end
|
||||||
|
|
||||||
|
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||||
|
do
|
||||||
|
Result := storage.user_role_by_id (a_id)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Change User
|
feature -- Change User
|
||||||
|
|
||||||
new_user (a_user: CMS_USER)
|
new_user (a_user: CMS_USER)
|
||||||
|
|||||||
Reference in New Issue
Block a user