Files
ROC/modules/blog/cms_blog_module.e
Jocelyn Fiat 32a47fbba3 When importing, do not change modification date.
Display /nodes sorted by changed date.
Improved the import form, and report wrong import folder. Only import from folder inside site/import for security reason.
2017-01-27 23:12:02 +01:00

332 lines
10 KiB
Plaintext

note
description: "Displays all posts (pages with type blog). It's possible to list posts by user."
date: "$Date: 2015-05-22 15:13:00 +0100 (lun., 18 mai 2015) $"
revision: "$Revision 96616$"
class
CMS_BLOG_MODULE
inherit
CMS_MODULE
rename
module_api as blog_api
redefine
setup_hooks,
initialize,
install,
blog_api
end
CMS_HOOK_MENU_SYSTEM_ALTER
CMS_HOOK_RESPONSE_ALTER
CMS_HOOK_EXPORT
CMS_HOOK_IMPORT
CMS_EXPORT_NODE_UTILITIES
CMS_IMPORT_NODE_UTILITIES
create
make
feature {NONE} -- Initialization
make
do
version := "1.0"
description := "Blogging service"
package := "content"
add_dependency ({CMS_NODE_MODULE})
end
feature -- Access
name: STRING = "blog"
feature {CMS_API} -- Module Initialization
initialize (api: CMS_API)
-- <Precursor>
local
ct: CMS_BLOG_NODE_TYPE
do
Precursor (api)
if attached {CMS_NODE_API} api.module_api ({CMS_NODE_MODULE}) as l_node_api then
create ct
create blog_api.make (api, l_node_api)
node_api := l_node_api
-- Depends on {CMS_NODE_MODULE}
--| For now, add all available formats to content type `ct'.
across
api.formats as ic
loop
ct.extend_format (ic.item)
end
l_node_api.add_node_type (ct)
l_node_api.add_node_type_webform_manager (create {CMS_BLOG_NODE_TYPE_WEBFORM_MANAGER}.make (ct, l_node_api))
end
end
feature {CMS_API} -- Module management
install (a_api: CMS_API)
do
-- Schema
if attached a_api.storage.as_sql_storage as l_sql_storage then
l_sql_storage.sql_execute_file_script (a_api.module_resource_location (Current, (create {PATH}.make_from_string ("scripts")).extended ("install.sql")), Void)
if l_sql_storage.has_error then
a_api.logger.put_error ("Could not initialize database for module [" + name + "]", generating_type)
else
Precursor {CMS_MODULE} (a_api)
end
end
end
feature {CMS_API} -- Access: API
blog_api: detachable CMS_BLOG_API
-- <Precursor>
node_api: detachable CMS_NODE_API
feature -- Access: router
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
-- <Precursor>
do
if attached blog_api as l_blog_api then
configure_web (a_api, l_blog_api, a_router)
else
-- Issue with api/dependencies,
-- thus Current module should not be used!
-- thus no url mapping
end
end
configure_web (a_api: CMS_API; a_blog_api: CMS_BLOG_API; a_router: WSF_ROUTER)
-- Configure router mapping for web interface.
local
l_blog_handler: BLOG_HANDLER
l_blog_user_handler: BLOG_USER_HANDLER
l_uri_mapping: WSF_URI_MAPPING
do
create l_blog_handler.make (a_api, a_blog_api)
create l_blog_user_handler.make (a_api, a_blog_api)
-- Let the class BLOG_HANDLER handle the requests on "/blogs"
create l_uri_mapping.make_trailing_slash_ignored ("/blogs", l_blog_handler)
a_router.map (l_uri_mapping, a_router.methods_get)
-- We can add a page number after /blogs/ to get older posts
a_router.handle ("/blogs/page/{page}", l_blog_handler, a_router.methods_get)
-- If a user id is given route with blog user handler
a_router.handle ("/blog/{user}", l_blog_user_handler, a_router.methods_get)
-- If a user id is given we also want to allow different pages
a_router.handle ("/blog/{user}", l_blog_user_handler, a_router.methods_get)
end
feature -- Hooks
setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
do
a_hooks.subscribe_to_menu_system_alter_hook (Current)
a_hooks.subscribe_to_response_alter_hook (Current)
a_hooks.subscribe_to_export_hook (Current)
a_hooks.subscribe_to_import_hook (Current)
end
response_alter (a_response: CMS_RESPONSE)
do
a_response.add_style (a_response.url ("/module/" + name + "/files/css/blog.css", Void), Void)
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
do
-- Add the link to the blog to the main menu
create lnk.make ("Blogs", "blogs/")
a_menu_system.primary_menu.extend (lnk)
end
export_to (a_export_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]; a_export_ctx: CMS_EXPORT_CONTEXT; a_response: CMS_RESPONSE)
-- Export data identified by `a_export_id_list',
-- or export all data if `a_export_id_list' is Void.
local
n: CMS_BLOG
p: PATH
d: DIRECTORY
f: PLAIN_TEXT_FILE
lst: LIST [CMS_BLOG]
do
if
attached node_api as l_node_api and then
attached l_node_api.node_type ("blog") as l_node_type and then
( a_export_id_list = Void
or else across a_export_id_list as ic some ic.item.same_string (l_node_type.name) end
)
then
if
a_response.has_permissions (<<"export any node", "export " + l_node_type.name>>) and then
attached blog_api as l_blog_api
then
lst := l_blog_api.blogs_order_created_desc
a_export_ctx.log ("Exporting " + lst.count.out + " [" + l_node_type.name + "] items...")
create d.make_with_path (a_export_ctx.location.extended ("nodes").extended (l_node_type.name))
if d.exists then
d.recursive_delete
end
across
lst as ic
loop
n := l_blog_api.full_blog_node (ic.item)
a_export_ctx.log (n.content_type + " #" + n.id.out)
p := a_export_ctx.location.extended ("nodes").extended (n.content_type).extended (n.id.out).appended_with_extension ("json")
create d.make_with_path (p.parent)
if not d.exists then
d.recursive_create_dir
end
create f.make_with_path (p)
if not f.exists or else f.is_access_writable then
f.open_write
f.put_string (json_to_string (blog_node_to_json (n, l_blog_api)))
f.close
end
-- Revisions.
if
attached l_node_api.node_revisions (n) as l_revisions and then
l_revisions.count > 1
then
a_export_ctx.log (n.content_type + " " + l_revisions.count.out + " revisions.")
p := a_export_ctx.location.extended ("nodes").extended (n.content_type).extended (n.id.out)
create d.make_with_path (p)
if not d.exists then
d.recursive_create_dir
end
across
l_revisions as revs_ic
loop
if attached {CMS_BLOG} revs_ic.item as l_blog then
create f.make_with_path (p.extended ("rev-" + n.revision.out).appended_with_extension ("json"))
if not f.exists or else f.is_access_writable then
f.open_write
f.put_string (json_to_string (blog_node_to_json (l_blog, l_blog_api)))
end
f.close
end
end
end
end
end
end
end
blog_node_to_json (a_blog: CMS_BLOG; a_blog_api: CMS_BLOG_API): JSON_OBJECT
do
Result := node_to_json (a_blog, a_blog_api.node_api)
end
import_from (a_import_id_list: detachable ITERABLE [READABLE_STRING_GENERAL]; a_import_ctx: CMS_IMPORT_CONTEXT; a_response: CMS_RESPONSE)
-- Import data identified by `a_import_id_list',
-- or import all data if `a_import_id_list' is Void.
local
p,fp: PATH
d: DIRECTORY
loc: STRING
l_id: STRING_32
l_entity: detachable CMS_BLOG
do
if
attached node_api as l_node_api and then
attached {CMS_BLOG_NODE_TYPE} l_node_api.node_type ("blog") as l_node_type and then
( a_import_id_list = Void
or else across a_import_id_list as ic some ic.item.same_string ({CMS_BLOG_NODE_TYPE}.name) end
)
then
if
a_response.has_permissions (<<"import any node", "import " + l_node_type.name>>) and then
attached blog_api as l_blog_api
then
p := a_import_ctx.location.extended ("nodes").extended (l_node_type.name)
create d.make_with_path (p)
if d.exists and then d.is_readable then
a_import_ctx.log ("Importing [" + l_node_type.name + "] items ..")
across
d.entries as ic
loop
if attached ic.item.extension as ext and then ext.same_string_general ("json") then
l_id := ic.item.name
l_id.remove_tail (ext.count + 1)
fp := p.extended_path (ic.item)
if attached json_object_from_location (fp) as j then
if
attached json_string_item (j, "type") as l_type and then
l_type.same_string_general (l_node_type.name)
then
l_entity := json_to_node_blog (l_node_type, j, l_node_api)
if l_entity /= Void then
if l_entity.is_published then
if l_entity.author = Void then
-- FIXME!!!
l_entity.set_author (l_blog_api.cms_api.user)
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
if
attached l_blog_api.blogs_by_title (l_author, l_entity.title) as l_blogs and then
not l_blogs.is_empty
then
-- Blog Already exists!
-- FIXME/TODO
l_entity := l_blogs.first
a_import_ctx.log (l_node_type.name + " %"" + fp.utf_8_name + "%" skipped (already exists for user #" + l_author.id.out + ")!")
else
a_import_ctx.log (l_node_type.name + " %"" + fp.utf_8_name + "%" imported for user #" + l_author.id.out + ".")
l_blog_api.import_blog (l_entity)
apply_taxonomy_to_node (j, l_entity, l_blog_api.cms_api)
if attached {CMS_LOCAL_LINK} l_entity.link as l_link then
loc := l_node_api.node_path (l_entity)
if not l_link.location.starts_with_general ("node/") then
l_blog_api.cms_api.set_path_alias (loc, l_link.location, False)
end
end
end
if l_entity /= Void and then l_entity.has_id then
-- Support for comments
import_comments_file_for_entity (p.extended (l_id).extended ("comments.json"), l_entity, l_node_api.cms_api, a_import_ctx)
end
else
a_import_ctx.log (l_node_type.name + " %"" + fp.utf_8_name + "%" skipped (Author is unknown!)")
end
else
a_import_ctx.log (l_node_type.name + " %"" + fp.utf_8_name + "%" skipped (Status is Not Published!)")
end
end
end
end
end
end
end
else
a_import_ctx.log ("Importing [" + l_node_type.name + "] NOT ALLOWED!")
end
end
end
json_to_node_blog (a_node_type: CMS_BLOG_NODE_TYPE; j: JSON_OBJECT; a_node_api: CMS_NODE_API): detachable CMS_BLOG
do
if attached json_to_node (a_node_type, j, a_node_api) as l_node then
Result := a_node_type.new_node (l_node)
end
end
end