From 6cb6dd160931a2aca52e0d351842dd87d296989a Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 3 Mar 2017 11:12:51 +0100 Subject: [PATCH] Added notion of author (owner) and editor to allow the editing of node by non owner users. --- .../demo/site/modules/node/scripts/node.sql | 2 + .../node/scripts/updates/node-1.0.0.1.sql | 7 ++ modules/blog/cms_blog_module.e | 6 +- .../blog/persistence/cms_blog_storage_sql.e | 20 +++- modules/node/cms_node_api.e | 26 +++-- modules/node/cms_node_module.e | 4 +- modules/node/content/cms_node.e | 42 ++++--- .../node/export/cms_export_node_utilities.e | 3 + .../handler/cms_node_type_webform_manager.e | 16 ++- modules/node/handler/node_form_response.e | 1 + modules/node/handler/node_handler.e | 15 ++- .../node/import/cms_import_node_utilities.e | 4 + .../node/persistence/cms_node_storage_sql.e | 104 +++++++++++++----- modules/node/site/scripts/node.sql | 2 + .../site/scripts/updates/node-1.0.0.1.sql | 7 ++ .../node/submodules/page/cms_page_module.e | 6 +- .../submodules/page/cms_page_storage_sql.e | 4 +- src/service/cms_api.e | 49 +++++++++ 18 files changed, 248 insertions(+), 70 deletions(-) create mode 100644 examples/demo/site/modules/node/scripts/updates/node-1.0.0.1.sql create mode 100644 modules/node/site/scripts/updates/node-1.0.0.1.sql diff --git a/examples/demo/site/modules/node/scripts/node.sql b/examples/demo/site/modules/node/scripts/node.sql index c71ea60..5feda91 100644 --- a/examples/demo/site/modules/node/scripts/node.sql +++ b/examples/demo/site/modules/node/scripts/node.sql @@ -8,6 +8,7 @@ CREATE TABLE nodes ( `content` TEXT, `format` VARCHAR(128), `author` INTEGER, + `editor` INTEGER, `publish` DATETIME, `created` DATETIME NOT NULL, `changed` DATETIME NOT NULL, @@ -23,6 +24,7 @@ CREATE TABLE node_revisions ( `content` TEXT, `format` VARCHAR(128), `author` INTEGER, + `editor` INTEGER, `changed` DATETIME NOT NULL, `status` INTEGER, CONSTRAINT Unique_nid_revision PRIMARY KEY (nid,revision) diff --git a/examples/demo/site/modules/node/scripts/updates/node-1.0.0.1.sql b/examples/demo/site/modules/node/scripts/updates/node-1.0.0.1.sql new file mode 100644 index 0000000..5bc6a92 --- /dev/null +++ b/examples/demo/site/modules/node/scripts/updates/node-1.0.0.1.sql @@ -0,0 +1,7 @@ +ALTER TABLE nodes ADD editor INTEGER ; +UPDATE nodes SET editor = author; + +ALTER TABLE node_revisions ADD editor INTEGER ; +UPDATE node_revisions SET editor = author; + + diff --git a/modules/blog/cms_blog_module.e b/modules/blog/cms_blog_module.e index a706de1..68e99da 100644 --- a/modules/blog/cms_blog_module.e +++ b/modules/blog/cms_blog_module.e @@ -276,7 +276,11 @@ feature -- Hooks if l_entity.is_published then if l_entity.author = Void then -- FIXME!!! - l_entity.set_author (l_blog_api.cms_api.user) + if attached l_entity.editor as l_last_editor then + l_entity.set_author (l_last_editor) + else + l_entity.set_author (l_blog_api.cms_api.user) + end a_import_ctx.log (l_node_type.name + " %"" + fp.utf_8_name + "%" WARNING (Author is unknown!)") end if attached l_entity.author as l_author then diff --git a/modules/blog/persistence/cms_blog_storage_sql.e b/modules/blog/persistence/cms_blog_storage_sql.e index 9334474..59f535d 100644 --- a/modules/blog/persistence/cms_blog_storage_sql.e +++ b/modules/blog/persistence/cms_blog_storage_sql.e @@ -159,16 +159,28 @@ feature {NONE} -- Queries -- Nodes count (Published and not Published) --| note: {CMS_NODE_API}.trashed = -1 - sql_select_blogs_order_created_desc: STRING = "SELECT * FROM nodes WHERE status != -1 AND type = %"blog%" ORDER BY created DESC;" + sql_select_blogs_order_created_desc: STRING -- SQL Query to retrieve all nodes that are from the type "blog" ordered by descending creation date. + once + Result := sql_select_all_from_nodes + " WHERE status != -1 AND type = %"blog%" ORDER BY created DESC;" + end - sql_blogs_limited: STRING = "SELECT * FROM nodes WHERE status != -1 AND type = %"blog%" ORDER BY created DESC LIMIT :limit OFFSET :offset ;" + sql_blogs_limited: STRING --- SQL Query to retrieve all nodes of type "blog" limited by limit and starting at offset + once + Result := sql_select_all_from_nodes + " WHERE status != -1 AND type = %"blog%" ORDER BY created DESC LIMIT :limit OFFSET :offset ;" + end - sql_blogs_from_user_limited: STRING = "SELECT * FROM nodes WHERE status != -1 AND type = %"blog%" AND author = :user ORDER BY created DESC LIMIT :limit OFFSET :offset ;" + sql_blogs_from_user_limited: STRING --- SQL Query to retrieve all nodes of type "blog" from author with id limited by limit + offset + once + Result := sql_select_all_from_nodes + " WHERE status != -1 AND type = %"blog%" AND author = :user ORDER BY created DESC LIMIT :limit OFFSET :offset ;" + end - sql_blogs_from_user_with_title: STRING = "SELECT * FROM nodes WHERE status != -1 AND type = %"blog%" AND author = :user AND title = :title ORDER BY created DESC;" + sql_blogs_from_user_with_title: STRING --- SQL Query to retrieve all nodes of type "blog" from author with title . + once + Result := sql_select_all_from_nodes + " WHERE status != -1 AND type = %"blog%" AND author = :user AND title = :title ORDER BY created DESC;" + end end diff --git a/modules/node/cms_node_api.e b/modules/node/cms_node_api.e index 8e580fc..47517d8 100644 --- a/modules/node/cms_node_api.e +++ b/modules/node/cms_node_api.e @@ -243,15 +243,23 @@ feature -- Access: Node check has_link: Result.has_id implies attached Result.link as lnk and then lnk.location.same_string (node_link (Result).location) 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 + if Result /= Void then + if 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 + if attached {CMS_PARTIAL_USER} Result.editor as l_partial_editor then + if attached cms_api.user_api.user_by_id (l_partial_editor.id) as l_editor then + Result.set_editor (l_editor) + else + check + valid_author_id: False + end end end end diff --git a/modules/node/cms_node_module.e b/modules/node/cms_node_module.e index 17a3f46..d541063 100644 --- a/modules/node/cms_node_module.e +++ b/modules/node/cms_node_module.e @@ -37,7 +37,7 @@ feature {NONE} -- Initialization make -- Create Current module, disabled by default. do - version := "1.0" + version := "1.0.0.1" description := "Service to manage content based on 'node'" package := "core" -- Optional dependencies, mainly for information. @@ -327,7 +327,7 @@ feature -- Hooks end end ch.set_information (l_info) - ch.set_author (n.author) + ch.set_author (n.editor) ch.set_summary (n.summary) if attached {CMS_TAXONOMY_API} l_node_api.cms_api.module_api ({CMS_TAXONOMY_MODULE}) as l_taxonomy_api then if attached l_taxonomy_api.terms_of_content (n, Void) as l_terms then diff --git a/modules/node/content/cms_node.e b/modules/node/content/cms_node.e index 4f6754c..c9d695a 100644 --- a/modules/node/content/cms_node.e +++ b/modules/node/content/cms_node.e @@ -28,7 +28,7 @@ feature{NONE} -- Initialization end make (a_title: READABLE_STRING_32) - -- Create current node with `a_title'. + -- Create current node with `a_title`. local now: DATE_TIME do @@ -45,7 +45,7 @@ feature{NONE} -- Initialization feature -- Conversion import_node (a_node: CMS_NODE) - -- Import `a_node' into current node. + -- Import `a_node` into current node. do set_id (a_node.id) set_revision (a_node.revision) @@ -54,6 +54,7 @@ feature -- Conversion set_modification_date (a_node.modification_date) set_publication_date (a_node.publication_date) set_author (a_node.author) + set_editor (a_node.editor) set_content ( a_node.content, a_node.summary, @@ -144,7 +145,10 @@ feature -- Access: date feature -- Access: author author: detachable CMS_USER - -- Author of current node. + -- Author of current node (i.e creator). + + editor: detachable CMS_USER + -- Last user that modified Current node. feature -- status report @@ -155,7 +159,7 @@ feature -- status report end same_node (a_node: CMS_NODE): BOOLEAN - -- Is `a_node' same node as Current? + -- Is `a_node` same node as Current? do -- FIXME: if we introduce notion of revision, update this part! Result := Current = a_node or id = a_node.id @@ -182,8 +186,8 @@ feature -- Status report 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' + -- Set `content`, `summary` and `format` to `a_content`, `a_summary` and `a_format`. + -- The `format` is associated with both `content` and `summary` deferred ensure content_assigned: content = a_content @@ -192,7 +196,7 @@ feature -- Element change end set_title (a_title: like title) - -- Assign `title' with `a_title'. + -- Assign `title` with `a_title`. do title := a_title if attached link as lnk then @@ -203,7 +207,7 @@ feature -- Element change end set_modification_date (a_modification_date: like modification_date) - -- Assign `modification_date' with `a_modification_date'. + -- Assign `modification_date` with `a_modification_date`. do modification_date := a_modification_date ensure @@ -211,7 +215,7 @@ feature -- Element change end set_creation_date (a_creation_date: like creation_date) - -- Assign `creation_date' with `a_creation_date'. + -- Assign `creation_date` with `a_creation_date`. do creation_date := a_creation_date ensure @@ -219,7 +223,7 @@ feature -- Element change end set_publication_date (a_publication_date: like publication_date) - -- Assign `publication_date' with `a_publication_date'. + -- Assign `publication_date` with `a_publication_date`. do publication_date := a_publication_date publication_date_output := publication_date.formatted_out ("yyyy/[0]mm/[0]dd") @@ -228,7 +232,7 @@ feature -- Element change end set_id (a_id: like id) - -- Assign `id' with `a_id'. + -- Assign `id` with `a_id`. do id := a_id ensure @@ -236,7 +240,7 @@ feature -- Element change end set_revision (a_revision: like revision) - -- Assign `revision' with `a_revision'. + -- Assign `revision` with `a_revision`. do revision := a_revision ensure @@ -244,15 +248,23 @@ feature -- Element change end set_author (u: like author) - -- Assign 'author' with `u' + -- Assign `author` with `u` do author := u ensure auther_set: author = u end + set_editor (u: like editor) + -- Assign `last_editor` with `u` + do + editor := u + ensure + last_editor_set: editor = u + end + set_link (a_link: like link) - -- Set `link' to `a_link'. + -- Set `link` to `a_link`. do link := a_link end @@ -286,7 +298,7 @@ feature -- Status change feature {CMS_NODE_STORAGE_I} -- Access: status change. set_status (a_status: like status) - -- Assign `status' with `a_status'. + -- Assign `status` with `a_status`. do status := a_status ensure diff --git a/modules/node/export/cms_export_node_utilities.e b/modules/node/export/cms_export_node_utilities.e index c50ab18..c3cc451 100644 --- a/modules/node/export/cms_export_node_utilities.e +++ b/modules/node/export/cms_export_node_utilities.e @@ -33,6 +33,9 @@ feature -- Access if attached n.author as u then Result.put (user_to_json (u), "author") end + if attached n.editor as u then + Result.put (user_to_json (u), "editor") + end create jo.make_empty if attached n.format as l_format then jo.put_string (l_format, "format") diff --git a/modules/node/handler/cms_node_type_webform_manager.e b/modules/node/handler/cms_node_type_webform_manager.e index 2ff79f4..2e840ed 100644 --- a/modules/node/handler/cms_node_type_webform_manager.e +++ b/modules/node/handler/cms_node_type_webform_manager.e @@ -201,9 +201,9 @@ feature -- Forms ... s := l_summary end - if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then + if attached fd.string_item ("format") as s_format and then attached cms_api.format (s_format) as f_format then f := f_format - elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then + elseif a_node /= Void and then attached a_node.format as s_format and then attached cms_api.format (s_format) as f_format then f := f_format else f := cms_api.formats.default_format @@ -214,8 +214,13 @@ feature -- Forms ... a_node.set_content (b, s, f.name) end - -- Update author - a_node.set_author (response.user) + -- Update editor, author + a_node.set_editor (cms_api.user) + if a_node.author = Void then + a_node.set_author (cms_api.user) + else + -- Keep existing author as creator! + end end new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable CMS_NODE): G @@ -253,7 +258,8 @@ feature -- Forms ... l_node := content_type.new_node_with_title ("...", Void) end end - l_node.set_author (response.user) + l_node.set_author (cms_api.user) + l_node.set_editor (cms_api.user) --Summary if attached fd.string_item ("summary") as l_summary then diff --git a/modules/node/handler/node_form_response.e b/modules/node/handler/node_form_response.e index 9cedeca..f687130 100644 --- a/modules/node/handler/node_form_response.e +++ b/modules/node/handler/node_form_response.e @@ -471,6 +471,7 @@ feature -- Form Result := a_content_type.new_node (a_node) end Result.set_author (user) + Result.set_editor (user) end apply_form_data_to_node (a_content_type: CMS_NODE_TYPE [CMS_NODE]; a_form_data: WSF_FORM_DATA; a_node: CMS_NODE) diff --git a/modules/node/handler/node_handler.e b/modules/node/handler/node_handler.e index 1518e80..19c3c98 100644 --- a/modules/node/handler/node_handler.e +++ b/modules/node/handler/node_handler.e @@ -333,11 +333,20 @@ feature {NONE} -- Trash:Restore b.append (" #") b.append (n.revision.out) b.append (" : ") - b.append (n.modification_date.out) + b.append (api.formatted_date_time_yyyy_mm_dd__hh_min_ss (n.modification_date)) b.append ("") - if attached n.author as l_author then - b.append (" by ") + if attached n.editor as l_editor then + if n.revision = 1 then + b.append (" created by ") + else + b.append (" edited by ") + end + b.append (r.link (r.user_profile_name (l_editor), "user/" + l_editor.id.out, Void)) + end + if attached n.author as l_author and then not l_author.same_as (n.editor) then + b.append (" (owner: ") b.append (r.link (r.user_profile_name (l_author), "user/" + l_author.id.out, Void)) + b.append (")") end if node_api.has_permission_for_action_on_node ("edit revisions", l_node, api.user) then b.append (" (