From 0ea8ba142ab403026c4b954d8959c10959ccddb6 Mon Sep 17 00:00:00 2001 From: TimotheeHrl Date: Tue, 2 Jul 2024 13:42:45 +0200 Subject: [PATCH 1/8] LUT-28232 : Add buttons to archive blog posts --- .../lutece/plugins/blog/business/Blog.java | 20 +++ .../lutece/plugins/blog/business/BlogDAO.java | 96 +++++++++-- .../plugins/blog/business/BlogFilter.java | 19 +++ .../plugins/blog/business/BlogHome.java | 22 +++ .../blog/business/BlogSearchFilter.java | 21 +++ .../plugins/blog/business/IBlogDAO.java | 4 + .../business/portlet/BlogPublicationHome.java | 13 ++ .../blog/resources/blog_messages.properties | 35 ++++ .../resources/blog_messages_fr.properties | 36 ++++- .../plugins/blog/service/BlogIdService.java | 6 + .../service/docsearch/BlogSearchItem.java | 5 + .../service/docsearch/BlogSearchService.java | 38 ++++- .../service/docsearch/DefaultBlogIndexer.java | 20 ++- .../service/docsearch/IBlogSearchIndexer.java | 4 +- .../lutece/plugins/blog/web/BlogJspBean.java | 151 +++++++++++++++++- .../web/portlet/BlogListPortletJspBean.java | 3 +- .../blog/web/portlet/BlogPortletJspBean.java | 2 +- .../plugins/blog/plugin/create_db_blog.sql | 2 + .../upgrade/update_db_blog_3.0.2-3.0.3.sql | 5 + .../admin/plugins/blog/manage_blogs.html | 19 ++- 20 files changed, 483 insertions(+), 38 deletions(-) diff --git a/src/java/fr/paris/lutece/plugins/blog/business/Blog.java b/src/java/fr/paris/lutece/plugins/blog/business/Blog.java index ef29e694..b8f3fd90 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/Blog.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/Blog.java @@ -63,6 +63,7 @@ public class Blog extends ReferenceItem implements Serializable, IExtendableReso public static final String PERMISSION_MODIFY = "MODIFY"; public static final String PERMISSION_DELETE = "DELETE"; public static final String PERMISSION_PUBLISH = "PUBLISH"; + public static final String PERMISSION_ARCHIVE = "ARCHIVE"; // Variables declarations private int _nId; @@ -108,6 +109,7 @@ public class Blog extends ReferenceItem implements Serializable, IExtendableReso private List _tag = new ArrayList<>( ); private List _blogPublication = new ArrayList<>( ); + private boolean _bIsArchived; /** * Returns the Id @@ -638,4 +640,22 @@ public AdminUser getUserCreatorInfos( ) return AdminUserHome.findUserByLogin( _strUserCreator ); } + + /** + *@return the boolean value of the blog is archived + */ + public boolean isArchived( ) + { + + return _bIsArchived; + } + + /** + *set the blog is archived + * @param bIsArchived + */ + public void setArchived( boolean bIsArchived ) + { + _bIsArchived = bIsArchived; + } } diff --git a/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java b/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java index ae941573..b4e660fa 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java @@ -53,33 +53,34 @@ public final class BlogDAO implements IBlogDAO // Constants private static final String SQL_QUERY_NEW_PK = "SELECT max( id_blog ) FROM blog_blog"; private static final String SQL_QUERY_NEW_PK_VERSION = "SELECT max( id_version ) FROM blog_versions"; - private static final String SQL_QUERY_SELECT = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url FROM blog_blog WHERE id_blog = ?"; - private static final String SQL_QUERY_SELECT_LAST_DOCUMENTS = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url FROM blog_blog ORDER BY update_date DESC LIMIT ?"; - private static final String SQL_QUERY_SELECT_BY_NAME = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url FROM blog_blog WHERE content_label = ?"; + private static final String SQL_QUERY_SELECT = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url, is_archived FROM blog_blog WHERE id_blog = ?"; + private static final String SQL_QUERY_SELECT_LAST_DOCUMENTS = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url, is_archived FROM blog_blog ORDER BY update_date DESC LIMIT ?"; + private static final String SQL_QUERY_SELECT_BY_NAME = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url, is_archived FROM blog_blog WHERE content_label = ?"; private static final String SQL_QUERY_SELECT_VERSION = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url FROM blog_versions WHERE id_blog = ? AND version = ? "; - private static final String SQL_QUERY_INSERT = "INSERT INTO blog_blog ( id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) "; + private static final String SQL_QUERY_INSERT = "INSERT INTO blog_blog ( id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url, is_archived ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; private static final String SQL_QUERY_DELETE = "DELETE FROM blog_blog WHERE id_blog = ?"; private static final String SQL_QUERY_DELETE_VERSIONS = "DELETE FROM blog_versions WHERE id_blog = ? "; private static final String SQL_QUERY_DELETE_SPECIFIC_VERSION = "DELETE FROM blog_versions WHERE id_blog = ? AND version = ? "; - private static final String SQL_QUERY_UPDATE = "UPDATE blog_blog SET id_blog = ?, version = ?, content_label = ?, creation_date = ?, update_date = ?, html_content = ?, user_editor = ?, user_creator = ?, attached_portlet_id = ?, edit_comment = ?, description = ?, shareable = ?, url= ? WHERE id_blog = ?"; - private static final String SQL_QUERY_SELECTALL = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url FROM blog_blog order by creation_date DESC"; - private static final String SQL_QUERY_SELECTALL_ID = "SELECT id_blog FROM blog_blog ORDER BY creation_date DESC"; + private static final String SQL_QUERY_UPDATE = "UPDATE blog_blog SET id_blog = ?, version = ?, content_label = ?, creation_date = ?, update_date = ?, html_content = ?, user_editor = ?, user_creator = ?, attached_portlet_id = ?, edit_comment = ?, description = ?, shareable = ?, url= ?, is_archived=? WHERE id_blog = ?"; + private static final String SQL_QUERY_SELECTALL = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url, is_archived FROM blog_blog order by creation_date DESC"; + private static final String SQL_QUERY_SELECTALL_ID = "SELECT id_blog FROM blog_blog WHERE !is_archived ORDER BY creation_date DESC"; private static final String SQL_QUERY_SELECTALL_VERSION = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url FROM blog_versions where id_blog = ?"; private static final String SQL_QUERY_SELECT_LAST_VERSIONS_BY_BLOG_ID = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url FROM blog_versions where id_blog = ? ORDER BY id_version DESC LIMIT ?"; - + private static final String SQL_QUERY_SELECT_BY_ARCHIVE_STATUS = "SELECT id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url, is_archived FROM blog_blog WHERE is_archived = ?"; private static final String SQL_QUERY_SELECTALL_USERS_EDITED_BLOG_VERSION = "SELECT distinct user_editor FROM blog_versions where id_blog = ?"; private static final String SQL_QUERY_INSERT_VERSION = "INSERT INTO blog_versions ( id_version, id_blog, version, content_label, creation_date, update_date, html_content, user_editor, user_creator, attached_portlet_id, edit_comment, description, shareable, url ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) "; private static final String SQL_QUERY_SELECT_BY_FILTER = " SELECT DISTINCT a.id_blog, a.version, a.content_label, " + " a.creation_date, a.update_date, a.html_content, a.user_editor, a.user_creator , a.attached_portlet_id , " - + " a.edit_comment , a.description, a.shareable, a.url, p.document_order FROM blog_blog a " + + " a.edit_comment , a.description, a.shareable, a.url, a.is_archived, p.document_order FROM blog_blog a " + " LEFT OUTER JOIN blog_tag_document f ON a.id_blog = f.id_blog" + " LEFT OUTER JOIN blog_list_portlet_htmldocs p ON a.id_blog = p.id_blog"; - private static final String SQL_QUERY_SELECT_BLOG_BY_ID_TAG = " SELECT b.id_blog, b.version, b.content_label, b.creation_date, b.update_date, b.html_content, b.user_editor, b.user_creator, b.attached_portlet_id, b.edit_comment, b.description, b.shareable, b.url, a.id_tag FROM blog_tag_document a Inner join blog_blog b on (b.id_blog = a.id_blog) WHERE a.id_tag = ? ORDER BY priority"; + private static final String SQL_QUERY_SELECT_BLOG_BY_ID_TAG = " SELECT b.id_blog, b.version, b.content_label, b.creation_date, b.update_date, b.html_content, b.user_editor, b.user_creator, b.attached_portlet_id, b.edit_comment, b.description, b.shareable, b.url, b.is_archived a.id_tag FROM blog_tag_document a Inner join blog_blog b on (b.id_blog = a.id_blog) WHERE a.id_tag = ? ORDER BY priority"; - private static final String SQL_QUERY_SELECT_ALL_BLOG = " SELECT DISTINCT a.id_blog, a.version, a.content_label, a.creation_date, a.update_date, a.html_content, a.user_editor, a.user_creator , a.attached_portlet_id, a.edit_comment , a.description, a.shareable, a.url FROM blog_blog a"; + private static final String SQL_QUERY_SELECT_ALL_BLOG = " SELECT DISTINCT a.id_blog, a.version, a.content_label, a.creation_date, a.update_date, a.html_content, a.user_editor, a.user_creator , a.attached_portlet_id, a.edit_comment , a.description, a.shareable, a.url a.is_archived FROM blog_blog a"; private static final String SQL_QUERY_SELECT_VERSION_NUMBER_BY_BLOG_ID_AND_CREATION_DATE = "SELECT version FROM blog_versions WHERE id_blog = ? ORDER BY ABS( update_date - ? );"; + private static final String SQL_FILTER_WHERE_CLAUSE = " WHERE "; private static final String SQL_FILTER_AND = " AND "; private static final String SQL_FILTER_TAGS_BEGIN = " ("; @@ -93,7 +94,7 @@ public final class BlogDAO implements IBlogDAO private static final String SQL_FILTER_ID_END = ") "; private static final String SQL_ORDER_BY_LAST_MODIFICATION = " ORDER BY a.update_date DESC "; private static final String SQL_ORDER_BY_ORDER_DOCUMENT = " ORDER by p.document_order "; - + private static final String SQL_UPDATE_BLOG_ARCHIVE = "UPDATE blog_blog SET is_archived = ? WHERE id_blog = ? "; /** * Generates a new primary key * @@ -161,6 +162,7 @@ public void insert( Blog blog, Plugin plugin ) daoUtil.setString( nIndex++, blog.getDescription( ) ); daoUtil.setBoolean( nIndex++, blog.getShareable( ) ); daoUtil.setString( nIndex++, blog.getUrl( ) ); + daoUtil.setBoolean( nIndex, false ); daoUtil.executeUpdate( ); } @@ -226,6 +228,7 @@ public Blog load( int nKey, Plugin plugin ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex++ ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); } @@ -263,6 +266,7 @@ public Blog loadByName( String strName, Plugin plugin ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex++ ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); } } @@ -369,6 +373,7 @@ public void store( Blog blog, Plugin plugin ) daoUtil.setString( nIndex++, blog.getDescription( ) ); daoUtil.setBoolean( nIndex++, blog.getShareable( ) ); daoUtil.setString( nIndex++, blog.getUrl( ) ); + daoUtil.setInt( nIndex++, blog.isArchived( )?1:0 ); daoUtil.setInt( nIndex, blog.getId( ) ); @@ -405,6 +410,7 @@ public List selectBlogsList( Plugin plugin ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex++ ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); blogList.add( blog ); } @@ -412,6 +418,43 @@ public List selectBlogsList( Plugin plugin ) } return blogList; } + /** + * {@inheritDoc } + */ + @Override + public List selectBlogsListByArchiveStatus(boolean isArchived, Plugin plugin ) + { + List blogList = new ArrayList<>( ); + try ( DAOUtil daoUtil = new DAOUtil( SQL_QUERY_SELECT_BY_ARCHIVE_STATUS, plugin ) ) + { + daoUtil.setBoolean( 1, isArchived ); + daoUtil.executeQuery( ); + + while ( daoUtil.next( ) ) + { + Blog blog = new Blog( ); + int nIndex = 1; + + blog.setId( daoUtil.getInt( nIndex++ ) ); + blog.setVersion( daoUtil.getInt( nIndex++ ) ); + blog.setContentLabel( daoUtil.getString( nIndex++ ) ); + blog.setCreationDate( daoUtil.getTimestamp( nIndex++ ) ); + blog.setUpdateDate( daoUtil.getTimestamp( nIndex++ ) ); + blog.setHtmlContent( daoUtil.getString( nIndex++ ) ); + blog.setUser( daoUtil.getString( nIndex++ ) ); + blog.setUserCreator( daoUtil.getString( nIndex++ ) ); + blog.setAttachedPortletId( daoUtil.getInt( nIndex++ ) ); + blog.setEditComment( daoUtil.getString( nIndex++ ) ); + blog.setDescription( daoUtil.getString( nIndex++ ) ); + blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); + blog.setUrl( daoUtil.getString( nIndex++ ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); + + blogList.add( blog ); + } + } + return blogList; + } /** * {@inheritDoc } @@ -443,6 +486,7 @@ public List selectlastModifiedBlogsList( Plugin plugin, int nLimit ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex++ ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); blogList.add( blog ); } @@ -481,7 +525,6 @@ public List selectBlogsVersionsList( int nId, Plugin plugin ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex++ ) ); - blogVersionsList.add( blog ); } } @@ -579,6 +622,7 @@ public List selectByFilter( BlogFilter filter ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); if ( filter.getLoadBinaries( ) ) { @@ -661,6 +705,14 @@ private DAOUtil getDaoFromFilter( String strQuerySelect, BlogFilter filter ) sbWhere.append( ( sbWhere.length( ) != 0 ) ? SQL_FILTER_AND : StringUtils.EMPTY ) .append( "a.id_blog NOT IN (SELECT DISTINCT id_blog FROM blogs_tag_document) " ); } + if ( filter.isArchived( ) ) + { + sbWhere.append( ( sbWhere.length( ) != 0 ) ? SQL_FILTER_AND : StringUtils.EMPTY ).append( "a.is_archived = 1 " ); + } + else + { + sbWhere.append( ( sbWhere.length( ) != 0 ) ? SQL_FILTER_AND : StringUtils.EMPTY ).append( "a.is_archived != 1 " ); + } if ( filter.getPortletId( ) != 0 ) { sbWhere.append( ( sbWhere.length( ) != 0 ) ? SQL_FILTER_AND : StringUtils.EMPTY ).append( "p.id_portlet=" ) @@ -766,6 +818,7 @@ public List loadBlogByIdTag( int nIdTag, Plugin plugin ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex++ ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); listBlog.add( blog ); } @@ -804,6 +857,7 @@ public List selectWithoutBinaries( Plugin plugin ) blog.setDescription( daoUtil.getString( nIndex++ ) ); blog.setShareable( daoUtil.getBoolean( nIndex++ ) ); blog.setUrl( daoUtil.getString( nIndex++ ) ); + blog.setArchived( daoUtil.getBoolean( nIndex ) ); listDocuments.add( blog ); } @@ -878,4 +932,20 @@ public int getActualVersionNumber( Timestamp strUpdateDate, int nId, Plugin plug return nVersion; } } + + /** + * Update the blog archive + * @param nIdBlog The blog id + * + **/ + @Override + public void updateBlogArchiveId( int nIdBlog, boolean bArchive, Plugin plugin ) + { + try ( DAOUtil daoUtil = new DAOUtil( SQL_UPDATE_BLOG_ARCHIVE, plugin ) ) + { + daoUtil.setBoolean( 1, bArchive ); + daoUtil.setInt( 2, nIdBlog ); + daoUtil.executeUpdate( ); + } + } } diff --git a/src/java/fr/paris/lutece/plugins/blog/business/BlogFilter.java b/src/java/fr/paris/lutece/plugins/blog/business/BlogFilter.java index 1ae4a87a..0d17f460 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/BlogFilter.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/BlogFilter.java @@ -50,6 +50,7 @@ public class BlogFilter private String _dateMax; private int _nPortletId; private boolean _bOrderInPortlet; + private boolean _bIsArchived; /** * @return the _arrayTagsId @@ -218,4 +219,22 @@ public void setPortletId( int nPortletId ) { _nPortletId = nPortletId; } + + /** + * @return the _bisArchived + */ + public boolean isArchived( ) + { + return _bIsArchived; + } + + /** + * @param bIsArchived + * the _bIsArchived to set + */ + public void setIsArchived( boolean bIsArchived ) + { + this._bIsArchived = bIsArchived; + } + } diff --git a/src/java/fr/paris/lutece/plugins/blog/business/BlogHome.java b/src/java/fr/paris/lutece/plugins/blog/business/BlogHome.java index f7725d2b..5b4256bb 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/BlogHome.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/BlogHome.java @@ -323,4 +323,26 @@ public static int getActualVersionNumber( Timestamp strUpdateDate, int nId ) return _dao.getActualVersionNumber( strUpdateDate, nId, _plugin ); } + /** + * Archive a blog + * + * @param blogId + * The id of the blog to archive + */ + public static void updateBlogArchiveId( boolean isArchived, int blogId ) + { + _dao.updateBlogArchiveId( blogId, isArchived, _plugin ); + } + + /** + * Select the list of blogs by archive status + * + * @param isArchived + * The archive status + * @return The list of blogs + */ + public static List selectByArchiveStatus( boolean isArchived ) + { + return _dao.selectBlogsListByArchiveStatus( isArchived, _plugin ); + } } diff --git a/src/java/fr/paris/lutece/plugins/blog/business/BlogSearchFilter.java b/src/java/fr/paris/lutece/plugins/blog/business/BlogSearchFilter.java index 8dd0748d..a24709fb 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/BlogSearchFilter.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/BlogSearchFilter.java @@ -48,6 +48,7 @@ public class BlogSearchFilter private Date _dateUpdateDateAfter; private Date _dateUpdateDateBefor; private String _strUserEditedBlogVersion; + private Boolean _bIsArchived; /** * Get the id of the filter @@ -214,4 +215,24 @@ public void setUpdateDateBefor( Date dateUpdateDateBefor ) _dateUpdateDateBefor = dateUpdateDateBefor; } + /** + * Returns the isArchived + * + * @return The isArchived + */ + public Boolean getIsArchived( ) + { + return _bIsArchived; + } + + /** + * Sets the isArchived + * + * @param isArchived + * The isArchived + */ + public void setIsArchived( Boolean isArchived ) + { + _bIsArchived = isArchived; + } } diff --git a/src/java/fr/paris/lutece/plugins/blog/business/IBlogDAO.java b/src/java/fr/paris/lutece/plugins/blog/business/IBlogDAO.java index 313d9d42..02968302 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/IBlogDAO.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/IBlogDAO.java @@ -152,6 +152,8 @@ public interface IBlogDAO */ List selectBlogsList( Plugin plugin ); + List selectBlogsListByArchiveStatus( boolean isArchived, Plugin plugin ); + /** * Load the data of nLimit last modified blog objects and returns them as a list * @@ -232,4 +234,6 @@ public interface IBlogDAO List selectWithoutBinaries( Plugin plugin ); int getActualVersionNumber( java.sql.Timestamp strUpdateDate, int nId, fr.paris.lutece.portal.service.plugin.Plugin plugin ); + + void updateBlogArchiveId( int nIdBlog, boolean bArchive, Plugin plugin ); } diff --git a/src/java/fr/paris/lutece/plugins/blog/business/portlet/BlogPublicationHome.java b/src/java/fr/paris/lutece/plugins/blog/business/portlet/BlogPublicationHome.java index 12f8821a..d2a7ff55 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/portlet/BlogPublicationHome.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/portlet/BlogPublicationHome.java @@ -163,6 +163,18 @@ public static void remove( int nIdDoc, int nIdPortlet ) _dao.remove( nIdDoc, nIdPortlet, _plugin ); } + /** + * Delete the BlogPublication by the blog id + * + * @param nIdDoc + * The Blog id + */ + public static void removeByBlogId( int nIdDoc ) + { + _dao.deleteBlogsId( nIdDoc, _plugin ); + + } + /** * Load all BlogPublication @@ -237,4 +249,5 @@ public static int countPublicationByIdBlogAndDate( int nIdBlog, Date date ) { return _dao.countPublicationByIdBlogAndDate( nIdBlog, date, _plugin ); } + } diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties index ce3d9b54..f780755c 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties @@ -70,6 +70,13 @@ manage_blogs.columnCreator=Author manage_blogs.sortByUtilisateurButton=Only my post manage_blogs.labelContributors=Contributors manage_blogs.unknownUser=Unknown user +manage_blogs.labelSelectUnselectAll=Select/Deselect all +manage_blogs.selectActionToApply=Select the action to execute +manage_blogs.applyToSelection=Execute the action on the selected elements +manage_blogs.labelArchived=Archived +manage_blogs.labelArchive=Archive +manage_blogs.labelUnarchive=Unarchive +manage_blogs.delete=Delete create_blog.pageTitle=Post create_blog.title=Create a Post @@ -188,6 +195,11 @@ message.errorTagUpdatePosition=The tag position can not be updated ! message.errorTagDeletion=The tag can not be deleted ! message.errorTagTitleNotEmpty=The tag title can not be empty ! message.errorTagNotSet=Can not set the tag ! +message.confirmArchiveBlog=Are you sure you want to archive this blog post ? Please note that publications of this post will be removed. +message.confirmArchiveMultipleBlogs=Are you sure you want to archive these blog posts ? Please note that publications of these posts will be removed. +message.confirmUnarchiveMultipleBlogs=Are you sure you want to unarchive these blog posts ? +message.confirmUnarchiveBlog=Are you sure you want to unarchive this blog post ? +message.confirmRemoveMultipleBlogs=Are you sure you want to delete these blog posts ? Please note that contents associated with these posts will be removed. publication_blog.pageTitle=Posts Publication @@ -242,7 +254,12 @@ portlet.blog.lableNbPost=Number of posts per page info.blog.created=Post created info.blog.updated=Post updated info.blog.removed=Post removed +info.blog.multipleBlogsRemoved=These posts have been deleted info.history.blog.removed=The version of the post has been deleted +info.blog.multipleBlogsArchived=Blog posts archived +info.blog.blogArchived=Blog post archived +info.blog.multipleBlogsUnarchived=Blog posts unarchived +info.blog.blogUnarchived=Blog post unarchived message.blogLocked=Post Locked message.blogFileTypeNotUpdated=The file type can not be updated ! message.blogFileCannotBeDeleted=The file can not be deleted @@ -334,6 +351,18 @@ publication_blog.labelSelectError=You have to select a post ! publication_blog.labelCreated=created publication_blog.labelUpdated=updated +# Management of archived blog posts +manage_blog_archives.pageTitle=Blog - Manage archived blog posts +manage_blog_archives.title=List of archived blog posts +manage_blog_archives.noArchive=No blog post archived yet +manage_blog_archives.archivedDate=Archiving date +manage_blog_archives.labelActionArchive=Archive +manage_blog_archives.labelActionUnarchive=Unarchive + +# Error Messages +message.error.action.executionFailed=The action couldn't be executed +message.error.action.notFound=Selected action not found + #dashboard dashboard.columnLastModifiedDocument=My last posts dashboard.columnStatus=Status @@ -353,6 +382,7 @@ rbac.blog.permission.create=Create a blog post rbac.blog.permission.modify=Modify a blog post rbac.blog.permission.delete=Delete a blog post rbac.blog.permission.publish=Publish a blog post +rbac.blog.permission.archive=Archive a blog post rbac.tag.resourceType=(blog) Blog tag management rbac.tag.permission.view=View a tag @@ -360,6 +390,11 @@ rbac.tag.permission.create=Create a tag rbac.tag.permission.delete=Delete a tag rbac.tag.permission.modify=Modify a tag +rbac.archive.resourceType=(blog) Archived blog post management +rbac.archive.permission.view=View the list of archived blog posts +rbac.archive.permission.archive=Archive a blog post +rbac.archive.permission.unarchive=Unarchive a blog post + validation.blog.Utilisateur.size=The size of the field User is limited to 255 characters validation.blog.Utilisateur.notEmpty=The field User cannot be empty. validation.blog.Creator.size=The field Author is limited to 255 characters. diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties index d1f0c625..3cf38671 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties @@ -72,6 +72,13 @@ manage_blogs.columnUserCreator=Auteur manage_blogs.columnUser=Dernier auteur manage_blogs.labelContributors=Contributeurs manage_blogs.unknownUser=Utilisateur inconnu +manage_blogs.labelSelectUnselectAll=S\u00e9lectionner/D\u00e9s\u00e9lectionner tout +manage_blogs.selectActionToApply=S\u00e9lectionner l'action \u00e0 ex\u00e9cuter +manage_blogs.applyToSelection=Appliquer \u00e0 la s\u00e9lection +manage_blogs.labelArchived=Archiv\u00e9 +manage_blogs.labelArchive=Archiver +manage_blogs.labelUnarchive=D\u00e9sarchiver +manage_blogs.delete=Supprimer create_blog.pageTitle=Cr\u00e9er un billet create_blog.title=Cr\u00e9er un billet @@ -219,6 +226,18 @@ publication_blog.labelSelectError=Vous devez sélectionner un billet publication_blog.labelCreated=cr\u00e9\u00e9 le publication_blog.labelUpdated=modifi\u00e9 le +# Management of archived blog posts +manage_blog_archives.pageTitle=Blog - Gestion des billets archiv\u00e9s +manage_blog_archives.title=Liste des billets archiv\u00e9s +manage_blog_archives.noArchive=Aucun billet archiv\u00e9 +manage_blog_archives.archivedDate=Date d'archivage +manage_blog_archives.labelActionArchive=Archiver +manage_blog_archives.labelActionUnarchive=D\u00e9sarchiver + +# Error Messages +message.error.action.executionFailed=L'action n'a pas pu \u00eatre ex\u00e9cut\u00e9e +message.error.action.notFound=L'action s\u00e9lectionn\u00e9e n'existe pas + # JSR 303 constraint validator messages validation.blog.ContentLabel.notEmpty=Le champs Titre ne peut \u00eatre vide. Veuillez le compl\u00e9ter. validation.blog.ContentLabel.size=Le champs Titre ne peut accepter plus de 255 caract\u00e8res. @@ -271,6 +290,11 @@ info.blog.created=Billet cr\u00e9\u00e9 info.blog.updated=Billet modifi\u00e9 info.blog.removed=Billet supprim\u00e9 info.history.blog.removed=Version du billet supprim\u00e9e +info.blog.multipleBlogsArchived=Billets archiv\u00e9s +info.blog.blogArchived=Billet archiv\u00e9 +info.blog.multipleBlogsUnarchived=Billets d\u00e9sarchiv\u00e9s +info.blog.blogUnarchived=Billet d\u00e9sarchiv\u00e9 +info.blog.multipleBlogsRemoved=Billets supprim\u00e9s # Blog error messages error.history.blog.cantRemoveOriginal=Vous ne pouvez pas supprimer la version originale du billet @@ -336,7 +360,11 @@ message.errorTagUpdatePosition=Impossible de mettre \u00e0 jour la position de c message.errorTagDeletion=Le tag ne peut \u00e9tre supprim\u00e9 ! message.errorTagTitleNotEmpty=Le titre du tag peut \u00e9tre vide ! message.errorTagNotSet=Impossible d'ajouter ce tag ! - +message.confirmArchiveBlog=Voulez-vous archiver ce billet ? Les publications associ\u00e9es de ce billet seront supprim\u00e9es. +message.confirmArchiveMultipleBlogs=Voulez-vous archiver ces {0} billets ? Les publications associ\u00e9es \u00e0 ces billets seront supprim\u00e9es. +message.confirmUnarchiveMultipleBlogs=Voulez-vous d\u00e9sarchiver ces {0} billets ? +message.confirmUnarchiveBlog=Voulez-vous d\u00e9sarchiver ce billet ? +message.confirmRemoveMultipleBlogs=Voulez-vous supprimer ces {0} billets ? Les contenus associ\u00e9s \u00e0 ces billets seront supprim\u00e9s. #Dashboard dashboard.columnLastModifiedDocument=Mes derniers billets dashboard.columnStatus=Statut @@ -356,6 +384,7 @@ rbac.blog.permission.create=Cr\u00e9er un billet rbac.blog.permission.modify=Modifier un billet rbac.blog.permission.delete=Supprimer un billet rbac.blog.permission.publish=Publier un blog +rbac.blog.permission.archive=Archiver un billet rbac.tag.resourceType=(blog) Gestion des tags des billets rbac.tag.permission.view=Voir un tag @@ -363,6 +392,11 @@ rbac.tag.permission.create=Cr\u00e9er un tag rbac.tag.permission.delete=Supprimer un tag rbac.tag.permission.modify=Modifier un tag +rbac.archive.resourceType=(blog) Gestion des billets archiv\u00e9s +rbac.archive.permission.view=Voir la liste des billets archiv\u00e9s +rbac.archive.permission.archive=Archiver un billet +rbac.archive.permission.unarchive=D\u00e9sarchiver un billet + # Insert Service insertService.blog.name=Insertion d'un lien vers un blog insertService.blog.label=Lien vers l'url d'un blog diff --git a/src/java/fr/paris/lutece/plugins/blog/service/BlogIdService.java b/src/java/fr/paris/lutece/plugins/blog/service/BlogIdService.java index 12556a34..334546e4 100644 --- a/src/java/fr/paris/lutece/plugins/blog/service/BlogIdService.java +++ b/src/java/fr/paris/lutece/plugins/blog/service/BlogIdService.java @@ -53,6 +53,7 @@ public class BlogIdService extends ResourceIdService private static final String PROPERTY_LABEL_MODIFY = "blog.rbac.blog.permission.modify"; private static final String PROPERTY_LABEL_DELETE = "blog.rbac.blog.permission.delete"; private static final String PROPERTY_LABEL_PUBLISH = "blog.rbac.blog.permission.publish"; + private static final String PROPERTY_LABEL_ARCHIVE = "blog.rbac.blog.permission.archive"; @Override public void register( ) @@ -89,6 +90,11 @@ public void register( ) p.setPermissionTitleKey( PROPERTY_LABEL_PUBLISH ); rt.registerPermission( p ); + p = new Permission( ); + p.setPermissionKey( Blog.PERMISSION_ARCHIVE); + p.setPermissionTitleKey( PROPERTY_LABEL_ARCHIVE ); + rt.registerPermission( p ); + // for all permissions ResourceTypeManager.registerResourceType( rt ); diff --git a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchItem.java b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchItem.java index 8d90879d..a462c9a4 100644 --- a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchItem.java +++ b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchItem.java @@ -83,4 +83,9 @@ public BlogSearchItem( Document document ) */ public static final String FIELD_USERS_EDITED_BLOG = "usersEditedBlog"; + /* + * Blog is archived + */ + public static final String FIELD_ARCHIVED = "archived"; + } diff --git a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchService.java b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchService.java index 959744db..c0f20576 100644 --- a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchService.java +++ b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/BlogSearchService.java @@ -46,6 +46,7 @@ import fr.paris.lutece.portal.service.util.AppLogService; import fr.paris.lutece.portal.service.util.AppPathService; import fr.paris.lutece.portal.service.util.AppPropertiesService; +import fr.paris.lutece.plugins.blog.business.Blog; import org.apache.commons.lang3.StringUtils; import org.apache.lucene.analysis.Analyzer; @@ -266,6 +267,22 @@ public String processIndexing( boolean bCreate ) return sbLogs.toString( ); } + public void updateDocument ( Blog blog) { + try ( IndexWriter writer = new IndexWriter( FSDirectory.open( Paths.get( _strIndex ) ), new IndexWriterConfig( _analyzer ) ) ) + { + IndexWriterConfig conf = new IndexWriterConfig( _analyzer ); + LogMergePolicy mergePolicy = new LogDocMergePolicy( ); + mergePolicy.setMergeFactor( _nWriterMergeFactor ); + conf.setMergePolicy( mergePolicy ); + conf.setOpenMode( OpenMode.CREATE_OR_APPEND ); + _indexer.updateDocument( writer, blog ); + } + catch( Exception e ) + { + AppLogService.error( "Indexing error : " + e.getMessage( ), e ); + } + + } /** * Get search results @@ -390,13 +407,22 @@ private Query prepareQueryForFilter( BlogSearchFilter filter ) throws org.apache flags.add( BooleanClause.Occur.MUST ); } - if ( filter.getIsUnpulished( ) > 0 ) - { - Term termIsUnpublished = new Term( BlogSearchItem.FIELD_UNPUBLISHED, String.valueOf( filter.getIsUnpulished( ) == 1 ) ); - Query termQueryIsUnpublished = new TermQuery( termIsUnpublished ); - queries.add( termQueryIsUnpublished.toString( ) ); - sectors.add( BlogSearchItem.FIELD_UNPUBLISHED ); + Term termIsArchived = new Term( BlogSearchItem.FIELD_ARCHIVED, filter.getIsArchived() ? "true" : "false" ); + Query termQueryIsArchived = new TermQuery( termIsArchived ); + queries.add( termQueryIsArchived.toString( ) ); + sectors.add( BlogSearchItem.FIELD_ARCHIVED ); flags.add( BooleanClause.Occur.MUST ); + + if ( !filter.getIsArchived( )) + { + if ( filter.getIsUnpulished( ) > 0 ) + { + Term termIsUnpublished = new Term( BlogSearchItem.FIELD_UNPUBLISHED, String.valueOf( filter.getIsUnpulished( ) == 1 ) ); + Query termQueryIsUnpublished = new TermQuery( termIsUnpublished ); + queries.add( termQueryIsUnpublished.toString( ) ); + sectors.add( BlogSearchItem.FIELD_UNPUBLISHED ); + flags.add( BooleanClause.Occur.MUST ); + } } Term term = new Term( SearchItem.FIELD_TYPE, BlogPlugin.PLUGIN_NAME ); diff --git a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/DefaultBlogIndexer.java b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/DefaultBlogIndexer.java index db5c8414..b13f7023 100644 --- a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/DefaultBlogIndexer.java +++ b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/DefaultBlogIndexer.java @@ -45,6 +45,7 @@ import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; +import org.apache.lucene.document.IntPoint; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; @@ -116,6 +117,22 @@ private void indexListBlog( IndexWriter indexWriter, List listIdBlog ) } } + /** + * Update isArchived field in the index + */ +@Override + public void updateDocument( IndexWriter indexWriter, Blog blog ) throws IOException + { + Term term = new Term( BlogSearchItem.FIELD_ID_HTML_DOC, Integer.toString( blog.getId( ) ) ); + Term [ ] terms = { + term + }; + + indexWriter.deleteDocuments( terms ); + Document doc = getDocument( blog ); + indexWriter.addDocument( doc ); + } + /** * {@inheritDoc} */ @@ -223,7 +240,8 @@ public static org.apache.lucene.document.Document getDocument( Blog blog ) throw boolean isPublished = blog.getBlogPublication( ).stream( ) .anyMatch( publication -> today.after( publication.getDateBeginPublishing( ) ) && today.before( publication.getDateEndPublishing( ) ) ); doc.add( new TextField( BlogSearchItem.FIELD_UNPUBLISHED, ( isPublished ) ? "false" : "true", Field.Store.YES ) ); - + // add isArchived field + doc.add( new TextField( BlogSearchItem.FIELD_ARCHIVED, blog.isArchived( ) ? "true" : "false", Field.Store.YES ) ); // Add the uid as a field, so that index can be incrementally maintained. // This field is not stored with question/answer, it is indexed, but it is not // tokenized prior to indexing. diff --git a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/IBlogSearchIndexer.java b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/IBlogSearchIndexer.java index 8abb03bc..e50d5938 100644 --- a/src/java/fr/paris/lutece/plugins/blog/service/docsearch/IBlogSearchIndexer.java +++ b/src/java/fr/paris/lutece/plugins/blog/service/docsearch/IBlogSearchIndexer.java @@ -34,7 +34,7 @@ package fr.paris.lutece.plugins.blog.service.docsearch; import fr.paris.lutece.portal.service.message.SiteMessageException; - +import fr.paris.lutece.plugins.blog.business.Blog; import org.apache.lucene.index.IndexWriter; import java.io.IOException; @@ -46,6 +46,8 @@ */ public interface IBlogSearchIndexer { + void updateDocument( IndexWriter indexWriter, Blog blog ) throws IOException; + /** * add to the index writer the document associate to the key specified in parameter * diff --git a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java index dc6e1cd4..fe45078e 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java @@ -43,10 +43,13 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.List; +import fr.paris.lutece.util.date.DateUtil; + import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; @@ -72,6 +75,8 @@ import org.outerj.daisy.diff.html.TextNodeComparator; import org.outerj.daisy.diff.html.dom.DomTreeBuilder; import org.xml.sax.InputSource; +import java.text.MessageFormat; + import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.blog.business.Blog; @@ -89,11 +94,13 @@ import fr.paris.lutece.plugins.blog.service.BlogSessionListner; import fr.paris.lutece.plugins.blog.service.docsearch.BlogSearchService; import fr.paris.lutece.plugins.blog.utils.BlogLock; +import fr.paris.lutece.plugins.blog.utils.BlogUtils; import fr.paris.lutece.portal.business.rbac.RBAC; import fr.paris.lutece.portal.business.user.AdminUser; import fr.paris.lutece.portal.service.admin.AccessDeniedException; import fr.paris.lutece.portal.service.admin.AdminUserService; import fr.paris.lutece.portal.service.datastore.DatastoreService; +import fr.paris.lutece.portal.service.i18n.I18nService; import fr.paris.lutece.portal.service.message.AdminMessage; import fr.paris.lutece.portal.service.message.AdminMessageService; import fr.paris.lutece.portal.service.rbac.RBACService; @@ -113,7 +120,6 @@ import fr.paris.lutece.util.json.JsonUtil; import fr.paris.lutece.util.sort.AttributeComparator; import fr.paris.lutece.util.url.UrlItem; - /** * This class provides the user interface to manage Blog features ( manage, create, modify, remove ) */ @@ -161,6 +167,10 @@ public class BlogJspBean extends ManageBlogJspBean protected static final String PARAMETER_TYPE_ID = "idType"; protected static final String PARAMETER_CONTENT_ID = "idContent"; protected static final String PARAMETER_CONTENT_ACTION = "contentAction"; + protected static final String PARAMETER_INFO_MESSAGE = "info_message"; + protected static final String PARAMETER_TO_ARCHIVE = "to_archive"; + + protected static final String PARAMETER_SELECTED_BLOGS = "select_blog_id"; // Properties for page titles private static final String PROPERTY_PAGE_TITLE_MANAGE_BLOG = "blog.manage_blog.pageTitle"; @@ -170,6 +180,7 @@ public class BlogJspBean extends ManageBlogJspBean private static final String PROPERTY_PAGE_TITLE_PREVIEW_BLOG = "blog.preview_blog.pageTitle"; private static final String PROPERTY_PAGE_TITLE_DIFF_BLOG = "blog.diff_blog.pageTitle"; protected static final String PROPERTY_USE_UPLOAD_IMAGE_PLUGIN = "use_upload_image_plugin"; + protected static final String PROPERTY_BLOG_ARCHIVE = "blog.manage_blog_archives.labelActionArchive"; // Properties private static final String PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE = "blog.listItems.itemsPerPage"; @@ -194,6 +205,9 @@ public class BlogJspBean extends ManageBlogJspBean protected static final String MARK_PERMISSION_MODIFY_BLOG = "permission_manage_modify_blog"; protected static final String MARK_PERMISSION_PUBLISH_BLOG = "permission_manage_publish_blog"; protected static final String MARK_PERMISSION_DELETE_BLOG = "permission_manage_delete_blog"; + protected static final String MARK_PERMISSION_ARCHIVE_BLOG = "permission_manage_archive_blog"; + private static final String MARK_NUMBER_MANDATORY_TAGS = "number_mandatory_tags"; + private static final String MARK_STATUS_FILTER = "status_filter"; private static final String JSP_MANAGE_BLOGS = "jsp/admin/plugins/blog/ManageBlogs.jsp"; @@ -201,7 +215,9 @@ public class BlogJspBean extends ManageBlogJspBean private static final String MESSAGE_CONFIRM_REMOVE_BLOG = "blog.message.confirmRemoveBlog"; private static final String MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED = "blog.message.errorDocumentIsPublished"; private static final String MESSAGE_CONFIRM_REMOVE_HISTORY_BLOG = "blog.message.confirmRemoveHistoryBlog"; + private static final String ACCESS_DENIED_MESSAGE = "portal.message.user.accessDenied"; + protected static final String MARK_BLOG_ACTION_LIST = "selection_action_list"; // Validations private static final String VALIDATION_ATTRIBUTES_PREFIX = "blog.model.entity.blog.attribute."; @@ -228,6 +244,7 @@ public class BlogJspBean extends ManageBlogJspBean private static final String ACTION_DUPLICATE_BLOG = "duplicateBlog"; private static final String ACTION_REMOVE_HISTORY_BLOG = "removeHistoryBlog"; private static final String ACTION_CONFIRM_REMOVE_HISTORY_BLOG = "confirmRemoveHistoryBlog"; + private static final String ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS = "updateArchiveMultipleBlogs"; // Infos private static final String INFO_BLOG_CREATED = "blog.info.blog.created"; @@ -276,6 +293,9 @@ public class BlogJspBean extends ManageBlogJspBean protected String _strSortedAttributeName; protected Boolean _bIsAscSort; protected String [ ] _strTag; + private ReferenceList _listBlogActionsList; + private List _listSelectedBlogIds = new ArrayList<>( ); + // Session variable to store working values private final BlogServiceSession _blogServiceSession = BlogServiceSession.getInstance( ); @@ -304,6 +324,8 @@ public String getManageBlogs( HttpServletRequest request ) String strButtonReset = request.getParameter( PARAMETER_BUTTON_RESET ); String strUnpublished = request.getParameter(PARAMETER_UNPUBLISHED); + + if ( strButtonSearch != null ) { // CURRENT USER @@ -333,7 +355,6 @@ public String getManageBlogs( HttpServletRequest request ) _nIsUnpublished = 0; } } - if ( StringUtils.isNotBlank( _strSearchText ) || ( _strTag != null && _strTag.length > 0 ) || _bIsChecked || _nIsUnpublished > 0 || _dateUpdateBlogAfter != null || _dateUpdateBlogBefor != null ) { @@ -350,7 +371,14 @@ public String getManageBlogs( HttpServletRequest request ) { filter.setUser( user.getAccessCode( ) ); } - + if(_nIsUnpublished == 3) + { + filter.setIsArchived(true); + } + else + { + filter.setIsArchived( false ); + } filter.setIsUnpulished(_nIsUnpublished); if ( _dateUpdateBlogAfter != null ) @@ -430,8 +458,12 @@ public String getManageBlogs( HttpServletRequest request ) (User) getUser( ) ); boolean bPermissionPublish = RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_PUBLISH, (User) getUser( ) ); + boolean bPermissionArchive = RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, + (User) getUser( ) ); Map model = new HashMap<>( ); + model.put( MARK_STATUS_FILTER, _nIsUnpublished ); + model.put( MARK_BLOG_ACTION_LIST, _listBlogActionsList ); model.put( MARK_BLOG_LIST, listDocuments ); model.put( MARK_PAGINATOR, paginator ); model.put( MARK_BLOG_FILTER_LIST, getBlogFilterList( ) ); @@ -450,6 +482,8 @@ public String getManageBlogs( HttpServletRequest request ) model.put( MARK_PERMISSION_DELETE_BLOG, bPermissionDelete ); model.put( MARK_PERMISSION_PUBLISH_BLOG, bPermissionPublish ); model.put(BlogParameterService.MARK_DEFAULT_NUMBER_MANDATORY_TAGS, BlogParameterService.getInstance().getNumberMandatoryTags() ); + model.put( MARK_PERMISSION_ARCHIVE_BLOG, bPermissionArchive ); + return getPage( PROPERTY_PAGE_TITLE_MANAGE_BLOG, TEMPLATE_MANAGE_BLOGS, model ); } @@ -652,6 +686,7 @@ public String doCreateBlog( HttpServletRequest request ) _blog.setUserCreator( AdminUserService.getAdminUser( request ).getAccessCode( ) ); _blog.setVersion( 1 ); _blog.setAttachedPortletId( 0 ); + _blog.setArchived( false ); _blog.setDocContent( listDocContent ); populate( _blog, request ); @@ -1628,11 +1663,119 @@ private ReferenceList getTageList( ) * The Id session * @return return true if the blog is locked else false */ - private boolean checkLockBlog( int nIdBlog, String strIdSession ) + private static boolean checkLockBlog( int nIdBlog, String strIdSession ) { return _mapLockBlog.get( nIdBlog ) != null && !_mapLockBlog.get( nIdBlog ).getSessionId( ).equals( strIdSession ); } + + + /** + * Handles the manual archiving of multiple blog posts + * + * @param request + * The Http request + * @return the jsp URL to display the main blog posts' management view + * @throws AccessDeniedException + */ + @Action( ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS ) + public String doArchiveMultipleBlog( HttpServletRequest request ) throws AccessDeniedException + { + User user = AdminUserService.getAdminUser( request ); + if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, user ) ) + { + String strMessage = I18nService.getLocalizedString( ACCESS_DENIED_MESSAGE, request.getLocale( ) ); + throw new AccessDeniedException( strMessage ); + } + // Get a List of the selected posts' IDs, from the current session + _listSelectedBlogIds = getSelectedBlogPostsIds( request ); + + // Check if any of the selected post is being modified by another user + if ( checkLockMultipleBlogs( request.getSession( ).getId( ) ) ) + { + UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) ); + String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP ); + return redirect( request, strMessageUrl ); + } + // Archive the selected blog posts + Boolean bArchive = Boolean.parseBoolean( request.getParameter( PARAMETER_TO_ARCHIVE ) ); + updateArchiveMultipleBlogs( _listSelectedBlogIds, bArchive ); + return redirectView( request, VIEW_MANAGE_BLOGS ); + } + + + + /** + * Get the IDs of the blog posts selected by the user + * + * @param request + * The Http request + * @return a List of the selected IDs, or an empty List if no element was selected + */ + private List getSelectedBlogPostsIds( HttpServletRequest request ) + { + // Retrieve an array containing the selected blog post IDs from the request + String [ ] listSelectedBlogPosts = request.getParameterValues( PARAMETER_SELECTED_BLOGS ); + if ( ArrayUtils.isNotEmpty( listSelectedBlogPosts ) ) + { + // Convert the value of the IDs from strings to integers and put them in a List + return Arrays.stream( listSelectedBlogPosts ).map( Integer::parseInt ).collect( Collectors.toList( ) ); + } + return Collections.emptyList( ); + } + + + /** + * Check if the given blogs are locked + * The IDs of the blogs to check + * @param strIdSession + * The ID of the session + * @return true if one of the blogs is locked + */ + private synchronized boolean checkLockMultipleBlogs( String strIdSession ) + { + if(_listBlogActionsList == null || CollectionUtils.isEmpty( _listSelectedBlogIds )) + { + return false; + } + for ( int blogId : _listSelectedBlogIds ) + { + // If one of the blogs is locked, return true + if ( checkLockBlog( blogId, strIdSession ) ) + { + return true; + } + } + // None of the blogs is locked + return false; + } + + private void updateArchiveMultipleBlogs( List listBlogIds, boolean bArchive ) + { + if( listBlogIds == null ) + { + return; + } + for ( int i = 0; i < listBlogIds.size( ); i++ ) + { + Integer blogId = listBlogIds.get( i ); + BlogHome.updateBlogArchiveId(bArchive, blogId); + Blog blog = BlogHome.findByPrimaryKey( blogId ); + BlogSearchService.getInstance( ).updateDocument( blog ); + BlogSearchService.getInstance( ).updateDocument( blog ); + if( bArchive ) + { + BlogPublicationHome.getDocPublicationByIdDoc( blogId ); + + BlogPublicationHome.getDocPublicationByIdDoc( blogId ); + if ( BlogPublicationHome.getDocPublicationByIdDoc( blogId ) != null && BlogPublicationHome.getDocPublicationByIdDoc( blogId ).size( ) > 0 ) + { + BlogPublicationHome.removeByBlogId( blogId ); + } + } + } + } + /** * Lock blog * diff --git a/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogListPortletJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogListPortletJspBean.java index 3b9e6a89..0617c3cc 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogListPortletJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogListPortletJspBean.java @@ -191,7 +191,7 @@ protected Map getPaginatedListModel( HttpServletRequest request { Blog blog = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( documentId ); - if ( blog != null ) + if ( blog != null && !blog.isArchived()) { listBlog.add( blog ); } @@ -256,6 +256,7 @@ private List filterBlogIds( HttpServletRequest request ) { filter.setUpdateDateBefor( DateUtil.formatDate( _dateUpdateBlogBefor, getLocale( ) ) ); } + filter.setIsArchived( false ); BlogSearchService.getInstance( ).getSearchResults( filter, listBlogsId ); diff --git a/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogPortletJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogPortletJspBean.java index 4fb1c9ab..5ca7b8d3 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogPortletJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/portlet/BlogPortletJspBean.java @@ -92,7 +92,7 @@ public String getCreate( HttpServletRequest request ) { String strPageId = request.getParameter( PARAMETER_PAGE_ID ); String strPortletTypeId = request.getParameter( PARAMETER_PORTLET_TYPE_ID ); - List listBlog = BlogHome.getBlogsList( ); + List listBlog = BlogHome.selectByArchiveStatus(false); HashMap model = new HashMap<>( ); model.put( MARK_WEBAPP_URL, AppPathService.getBaseUrl( request ) ); diff --git a/src/sql/plugins/blog/plugin/create_db_blog.sql b/src/sql/plugins/blog/plugin/create_db_blog.sql index 36a1df27..483d5858 100644 --- a/src/sql/plugins/blog/plugin/create_db_blog.sql +++ b/src/sql/plugins/blog/plugin/create_db_blog.sql @@ -26,6 +26,7 @@ edit_comment varchar(255) default '' NOT NULL, description long varchar, shareable int default 0 NOT NULL, url varchar(255) default '', +is_archived boolean default false, PRIMARY KEY (id_blog) ); @@ -116,6 +117,7 @@ CONSTRAINT fk_id_tag FOREIGN KEY(id_tag) references blog_tag(id_tag), PRIMARY KEY (id_tag, id_blog) ); + /*==============================================================*/ /* Table structure for table blog_indexer_action */ /*==============================================================*/ diff --git a/src/sql/plugins/blog/upgrade/update_db_blog_3.0.2-3.0.3.sql b/src/sql/plugins/blog/upgrade/update_db_blog_3.0.2-3.0.3.sql index 2b449ce3..3dd5a47a 100644 --- a/src/sql/plugins/blog/upgrade/update_db_blog_3.0.2-3.0.3.sql +++ b/src/sql/plugins/blog/upgrade/update_db_blog_3.0.2-3.0.3.sql @@ -8,3 +8,8 @@ INSERT INTO core_admin_dashboard(dashboard_name, dashboard_column, dashboard_ord INSERT INTO core_datastore(entity_key, entity_value) VALUES ('blog.advanced_parameters.number_mandatory_tags', '0'); INSERT INTO core_datastore(entity_key, entity_value) VALUES ('blog.advanced_parameters.default_date_end_publishing', '01/01/2050'); + +-- +-- Add new column blog_archive to blog_blog +-- +ALTER TABLE blog_blog ADD COLUMN is_archived boolean DEFAULT false; diff --git a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html index e5783ff8..bc8e0c13 100644 --- a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html +++ b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html @@ -47,6 +47,7 @@ <@option value="0" selected=(unpublishedString == '') label='#i18n{blog.manage_blogs.labelAllBlogs}'/> <@option value="1" selected=(unpublishedString == '1') label='#i18n{blog.manage_blogs.labelNotPublished}' /> <@option value="2" selected=(unpublishedString == '2') label='#i18n{blog.manage_blogs.labelPublished}' /> + <@option value="3" selected=(unpublishedString == '3') label='#i18n{blog.manage_blogs.labelArchived}' /> @@ -172,6 +173,13 @@ + <#if permission_manage_archive_blog> + <#if blog.isArchived() > + <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=updateArchiveMultipleBlogs&to_archive=true&select_blog_id=${blog.id}' title='#i18n{blog.manage_blog_archives.labelActionUnarchive}' buttonIcon='archive' hideTitle=['all'] color='warning' /> + <#else> + <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=updateArchiveMultipleBlogs&to_archive=false&select_blog_id=${blog.id}' title='#i18n{blog.manage_blog_archives.labelActionArchive}' buttonIcon='archive' hideTitle=['all'] color='info' /> + + <#if permission_manage_delete_blog> <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=confirmRemoveBlog&id=${blog.id}' title='#i18n{portal.util.labelDelete}' buttonIcon='trash' hideTitle=['all'] color='danger' /> @@ -220,6 +228,7 @@ timeoutDelay: 200, }, }); +}); // Check if all inputs are empty or unchecked @@ -230,15 +239,6 @@ const dateUpdateBlogAfter = document.getElementById('dateUpdateBlogAfter').value.trim(); const dateUpdateBlogBefore = document.getElementById('dateUpdateBlogBefore').value.trim(); const blogStatus = document.getElementById('unpublished').value; -// Debug output - console.log({ - isChecked, - searchText, - tagValue, - dateUpdateBlogAfter, - dateUpdateBlogBefore, - blogStatus - }); return !isChecked && (searchText === '' || searchText === null) && !tagValue && @@ -265,5 +265,4 @@ document.getElementById('unpublished').addEventListener('change', function() { btnReset.classList.toggle('d-none', areAllInputsEmptyOrUnchecked()); }); -}); From 7118af8ba3ae6d92491e8ac0e94034da35094d05 Mon Sep 17 00:00:00 2001 From: TimotheeHrl Date: Tue, 2 Jul 2024 13:44:12 +0200 Subject: [PATCH 2/8] LUT-28233 : Add checkbox in front of each blog --- .../admin/plugins/blog/manage_blogs.html | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html index bc8e0c13..a481aca5 100644 --- a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html +++ b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html @@ -63,9 +63,10 @@ <@messages infos=infos /> <@box> <@boxBody> - <#assign idx=0 /> + <#assign idx=0 /> <@table headBody=true > <@tr> + <@th> <@th>#i18n{blog.manage_blogs.columnContentLabel} <@sort jsp_url="jsp/admin/plugins/blog/ManageBlogs.jsp" attribute="contentLabel" /> <@th>#i18n{blog.manage_blogs.columnCreationDate} <@sort jsp_url="jsp/admin/plugins/blog/ManageBlogs.jsp" attribute="creationDate" /> <@th>#i18n{blog.manage_blogs.columnUpdateDate} <@sort jsp_url="jsp/admin/plugins/blog/ManageBlogs.jsp" attribute="updateDate" /> @@ -77,6 +78,9 @@ <@tableHeadBodySeparator /> <#list blog_list as blog> <@tr> + <@td> + <@checkBox id='selected_blog_${blog.id}' name='select_blog_id' value='${blog.id}' /> + <@td> <@div class='d-flex justify-content-between align-items-center mb-0 w-100'> <@div class='mb-1'> @@ -265,4 +269,36 @@ document.getElementById('unpublished').addEventListener('change', function() { btnReset.classList.toggle('d-none', areAllInputsEmptyOrUnchecked()); }); + +// checkbox row +let btnApplyActionOnSelection = document.getElementById('button_apply_selected_action') + +// When the "Check all" / "Uncheck all" element is clicked, check / uncheck all the blog posts' checkboxes +document.getElementById('select_all_blogs_id').addEventListener('click', function () { + let selectionButton = document.getElementById('select_blog_action') + let checkBoxes = document.querySelectorAll('input[name="select_blog_id"]') + + // Check / uncheck the available checkboxes + checkBoxes.forEach(function (checkBox) { + checkBox.checked = this.checked + }, this); +}); + +// Enable / disabled the selection of an action when a blog post's checkbox is checked +document.querySelectorAll('input[name="select_blog_id"]').forEach(function (checkbox) { + checkbox.addEventListener('change', function () { + let selectionButton = document.getElementById('select_blog_action') + let selectedCheckBoxes = document.querySelectorAll('input[name="select_blog_id"]:checked') + if (selectedCheckBoxes.length > 0) { + // Enable the selection and execution of an action + selectionButton.removeAttribute('disabled') + btnApplyActionOnSelection.removeAttribute('disabled') + } + else { + // Disable the selection and execution of an action + selectionButton.setAttribute('disabled', 'disabled') + btnApplyActionOnSelection.setAttribute('disabled', 'disabled') + } + }) +}); From 61f7fc6e669124035a8c3c7afc893e985e09fbd9 Mon Sep 17 00:00:00 2001 From: TimotheeHrl Date: Tue, 2 Jul 2024 13:44:38 +0200 Subject: [PATCH 3/8] LUT-28234 : Add an archiving and a suppressing buttons action --- .../lutece/plugins/blog/business/BlogDAO.java | 2 +- .../lutece/plugins/blog/web/BlogJspBean.java | 139 +++++++++++++++++- .../admin/plugins/blog/manage_blogs.html | 58 ++++++-- 3 files changed, 181 insertions(+), 18 deletions(-) diff --git a/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java b/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java index b4e660fa..622feb78 100644 --- a/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java +++ b/src/java/fr/paris/lutece/plugins/blog/business/BlogDAO.java @@ -78,7 +78,7 @@ public final class BlogDAO implements IBlogDAO private static final String SQL_QUERY_SELECT_BLOG_BY_ID_TAG = " SELECT b.id_blog, b.version, b.content_label, b.creation_date, b.update_date, b.html_content, b.user_editor, b.user_creator, b.attached_portlet_id, b.edit_comment, b.description, b.shareable, b.url, b.is_archived a.id_tag FROM blog_tag_document a Inner join blog_blog b on (b.id_blog = a.id_blog) WHERE a.id_tag = ? ORDER BY priority"; - private static final String SQL_QUERY_SELECT_ALL_BLOG = " SELECT DISTINCT a.id_blog, a.version, a.content_label, a.creation_date, a.update_date, a.html_content, a.user_editor, a.user_creator , a.attached_portlet_id, a.edit_comment , a.description, a.shareable, a.url a.is_archived FROM blog_blog a"; + private static final String SQL_QUERY_SELECT_ALL_BLOG = " SELECT DISTINCT a.id_blog, a.version, a.content_label, a.creation_date, a.update_date, a.html_content, a.user_editor, a.user_creator , a.attached_portlet_id, a.edit_comment , a.description, a.shareable, a.url, a.is_archived FROM blog_blog a"; private static final String SQL_QUERY_SELECT_VERSION_NUMBER_BY_BLOG_ID_AND_CREATION_DATE = "SELECT version FROM blog_versions WHERE id_blog = ? ORDER BY ABS( update_date - ? );"; private static final String SQL_FILTER_WHERE_CLAUSE = " WHERE "; diff --git a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java index fe45078e..e34ee8ee 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java @@ -171,6 +171,9 @@ public class BlogJspBean extends ManageBlogJspBean protected static final String PARAMETER_TO_ARCHIVE = "to_archive"; protected static final String PARAMETER_SELECTED_BLOGS = "select_blog_id"; + protected static final String PARAMETER_SELECTED_BLOG_ACTION = "select_blog_action"; + protected static final String PARAMETER_SELECTED_BLOG_IDS_LIST = "selected_blogs_list"; + // Properties for page titles private static final String PROPERTY_PAGE_TITLE_MANAGE_BLOG = "blog.manage_blog.pageTitle"; @@ -245,7 +248,8 @@ public class BlogJspBean extends ManageBlogJspBean private static final String ACTION_REMOVE_HISTORY_BLOG = "removeHistoryBlog"; private static final String ACTION_CONFIRM_REMOVE_HISTORY_BLOG = "confirmRemoveHistoryBlog"; private static final String ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS = "updateArchiveMultipleBlogs"; - + private static final String ACTION_REMOVE_MULTIPLE_BLOGS = "removeMultipleBlogs"; + private static final String ACTION_EXECUTE_SELECTED_ACTION = "form_checkbox_action"; // Infos private static final String INFO_BLOG_CREATED = "blog.info.blog.created"; private static final String INFO_BLOG_UPDATED = "blog.info.blog.updated"; @@ -258,6 +262,8 @@ public class BlogJspBean extends ManageBlogJspBean private static final String ERROR_HISTORY_BLOG_NOT_REMOVED = "blog.error.history.blog.notRemoved"; private static final String MESSAGE_ERROR_MANDATORY_TAGS = "blog.message.errorMandatoryTags"; + private static final String ERROR_ACTION_EXECUTION_FAILED = "blog.message.error.action.executionFailed"; + private static final String ERROR_ACTION_NOT_FOUND = "blog.message.error.action.notFound"; // Filter Marks protected static final String MARK_BLOG_FILTER_LIST = "blog_filter_list"; protected static final String MARK_BLOG_FILTER_NAME = "Nom"; @@ -1669,7 +1675,55 @@ private static boolean checkLockBlog( int nIdBlog, String strIdSession ) } + /** + * Handles the manual delete of multiple blog posts + * + * @param request + * The Http request + * @return the jsp URL to display the main blog posts' management view + * @throws AccessDeniedException + */ + @Action( ACTION_REMOVE_MULTIPLE_BLOGS ) + public String doRemoveMultipleBlog( HttpServletRequest request ) throws AccessDeniedException + { + User user = AdminUserService.getAdminUser( request ); + AdminUser adminUser = AdminUserService.getAdminUser( request ); + if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_DELETE, user ) && !adminUser.isAdmin( ) ) + { + String strMessage = I18nService.getLocalizedString( ACCESS_DENIED_MESSAGE, getLocale( ) ); + throw new AccessDeniedException( strMessage ); + } + // Get a List of the selected posts' IDs, from the current session + _listSelectedBlogIds = getSelectedBlogPostsIds( request ); + + // Check if any of the selected post is being modified by another user + if ( checkLockMultipleBlogs( request.getSession( ).getId( ) ) ) + { + UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) ); + String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP ); + return redirect( request, strMessageUrl ); + } + removeMultipleBlogs( _listSelectedBlogIds ); + return redirectView( request, VIEW_MANAGE_BLOGS ); + } + private void removeMultipleBlogs( List listBlogIds ) + { + if( listBlogIds == null ) + { + return; + } + for ( int blogId : listBlogIds ) + { + BlogPublicationHome.getDocPublicationByIdDoc( blogId ); + if ( BlogPublicationHome.getDocPublicationByIdDoc( blogId ) != null && BlogPublicationHome.getDocPublicationByIdDoc( blogId ).size( ) > 0 ) + { + BlogPublicationHome.removeByBlogId( blogId ); + } + BlogHome.removeVersions( blogId ); + BlogHome.remove( blogId ); + } + } /** * Handles the manual archiving of multiple blog posts * @@ -1684,9 +1738,10 @@ public String doArchiveMultipleBlog( HttpServletRequest request ) throws AccessD User user = AdminUserService.getAdminUser( request ); if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, user ) ) { - String strMessage = I18nService.getLocalizedString( ACCESS_DENIED_MESSAGE, request.getLocale( ) ); + String strMessage = I18nService.getLocalizedString( ACCESS_DENIED_MESSAGE, getLocale( ) ); throw new AccessDeniedException( strMessage ); } + // Get a List of the selected posts' IDs, from the current session _listSelectedBlogIds = getSelectedBlogPostsIds( request ); @@ -1698,11 +1753,89 @@ public String doArchiveMultipleBlog( HttpServletRequest request ) throws AccessD return redirect( request, strMessageUrl ); } // Archive the selected blog posts - Boolean bArchive = Boolean.parseBoolean( request.getParameter( PARAMETER_TO_ARCHIVE ) ); + if( request.getParameter( PARAMETER_TO_ARCHIVE ) != null) + { + Boolean bArchive = Boolean.parseBoolean( request.getParameter( PARAMETER_TO_ARCHIVE ) ); + updateArchiveMultipleBlogs( _listSelectedBlogIds, bArchive ); + } else + { + Boolean bArchive = Boolean.parseBoolean( request.getAttribute( PARAMETER_TO_ARCHIVE ).toString( ) ); updateArchiveMultipleBlogs( _listSelectedBlogIds, bArchive ); + request.removeAttribute( PARAMETER_TO_ARCHIVE ); + } return redirectView( request, VIEW_MANAGE_BLOGS ); } + /** + * Process a specific action on a selection of multiple blog post elements + * + * @param request + * The Http request + * @return the URL to redirect to once the action is executed + * @throws AccessDeniedException + */ + @Action( ACTION_EXECUTE_SELECTED_ACTION ) + public String doExecuteSelectedAction( HttpServletRequest request ) throws AccessDeniedException + { + Locale locale = getLocale( ); + + // Get the selected action + int selectedActionId = getSelectedAction( request ); + // Get the IDs of the blog posts selected for the action + _listSelectedBlogIds = getSelectedBlogPostsIds( request ); + + // Check if the content retrieved is null. Redirect and display an error if it is the case + if ( selectedActionId == -1 || CollectionUtils.isEmpty( _listSelectedBlogIds ) ) + { + addError( ERROR_ACTION_EXECUTION_FAILED, locale ); + return redirectView( request, VIEW_MANAGE_BLOGS ); + } + + // Save the list of selected blogs in the current session's attributes + request.getSession( ).setAttribute( PARAMETER_SELECTED_BLOG_IDS_LIST, _listSelectedBlogIds ); + + // Execute the action selected by the user + if ( selectedActionId == 0 ) + { + // add parameter to the request to_archive=true + request.setAttribute( PARAMETER_TO_ARCHIVE, Boolean.TRUE.toString( ) ); + return doArchiveMultipleBlog( request ); + } + else if ( selectedActionId == 1 ) + { + // add parameter to the request to_archive=false + request.setAttribute( PARAMETER_TO_ARCHIVE, Boolean.FALSE.toString( ) ); + return doArchiveMultipleBlog( request ); + } + else if ( selectedActionId == 2 ) + { + return doRemoveMultipleBlog( request ); + } + else + { + addError( ERROR_ACTION_NOT_FOUND, locale ); + return redirectView( request, VIEW_MANAGE_BLOGS ); + } + } + + /** + * Get the value of the action selected by the user + * + * @param request + * The Http request + * @return the ID of the selected action, or -1 if the value couldn't be parsed properly + * + */ + private int getSelectedAction( HttpServletRequest request ) + { + // Retrieve the value of the selected action from the request + String strSelectedActionId = request.getParameter( PARAMETER_SELECTED_BLOG_ACTION ); + if ( StringUtils.isNumeric( strSelectedActionId ) ) + { + return Integer.parseInt( strSelectedActionId ); + } + return -1; + } /** diff --git a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html index a481aca5..fd763bd7 100644 --- a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html +++ b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html @@ -63,10 +63,32 @@ <@messages infos=infos /> <@box> <@boxBody> + <@tform id='form_checkbox_action' name='form_checkbox_action' method='post' class='p-0' action='jsp/admin/plugins/blog/ManageBlogs.jsp'> + <@input type='hidden' id='action' name='action' value='form_checkbox_action' /> <#assign idx=0 /> + <#if permission_manage_archive_blog || permission_manage_delete_blog> + <@div class='d-flex flex-row'> + <@inputGroup class='p-2'> + <@select id='select_blog_action' name='select_blog_action' title='#i18n{blog.manage_blogs.selectActionToApply}' class='p-2'> + <#if permission_manage_archive_blog> + + + + <#if permission_manage_delete_blog> + + + + <@inputGroupItem type='btn'> + <@button type='submit' id='button_apply_selected_action' name='button_apply_selected_action' title='#i18n{blog.manage_blogs.applyToSelection}' buttonIcon='check' hideTitle=['all'] disabled=true /> + + + + <@table headBody=true > <@tr> - <@th> + <#if permission_manage_archive_blog || permission_manage_delete_blog> + <@th><@checkBox name='select_all_blogs_id' id='select_all_blogs_id' /> + <@th>#i18n{blog.manage_blogs.columnContentLabel} <@sort jsp_url="jsp/admin/plugins/blog/ManageBlogs.jsp" attribute="contentLabel" /> <@th>#i18n{blog.manage_blogs.columnCreationDate} <@sort jsp_url="jsp/admin/plugins/blog/ManageBlogs.jsp" attribute="creationDate" /> <@th>#i18n{blog.manage_blogs.columnUpdateDate} <@sort jsp_url="jsp/admin/plugins/blog/ManageBlogs.jsp" attribute="updateDate" /> @@ -78,9 +100,11 @@ <@tableHeadBodySeparator /> <#list blog_list as blog> <@tr> - <@td> - <@checkBox id='selected_blog_${blog.id}' name='select_blog_id' value='${blog.id}' /> - + <#if permission_manage_archive_blog || permission_manage_delete_blog> + <@td> + <@checkBox id='selected_blog_${blog.id}' name='select_blog_id' value='${blog.id}' /> + + <@td> <@div class='d-flex justify-content-between align-items-center mb-0 w-100'> <@div class='mb-1'> @@ -202,6 +226,7 @@ <#assign idx=idx + 1/> + <@paginationAdmin paginator=paginator combo=1 /> @@ -275,30 +300,35 @@ // When the "Check all" / "Uncheck all" element is clicked, check / uncheck all the blog posts' checkboxes document.getElementById('select_all_blogs_id').addEventListener('click', function () { - let selectionButton = document.getElementById('select_blog_action') - let checkBoxes = document.querySelectorAll('input[name="select_blog_id"]') + var selectionButton = document.getElementById('select_blog_action') + var checkBoxes = document.querySelectorAll('input[name="select_blog_id"]') // Check / uncheck the available checkboxes checkBoxes.forEach(function (checkBox) { checkBox.checked = this.checked }, this); + manageActionButtonVisibility(); }); // Enable / disabled the selection of an action when a blog post's checkbox is checked document.querySelectorAll('input[name="select_blog_id"]').forEach(function (checkbox) { checkbox.addEventListener('change', function () { - let selectionButton = document.getElementById('select_blog_action') - let selectedCheckBoxes = document.querySelectorAll('input[name="select_blog_id"]:checked') + manageActionButtonVisibility(); + }) +}); + + function manageActionButtonVisibility() { + var selectionButton = document.getElementById('select_blog_action'); + var selectedCheckBoxes = document.querySelectorAll('input[name="select_blog_id"]:checked'); if (selectedCheckBoxes.length > 0) { // Enable the selection and execution of an action - selectionButton.removeAttribute('disabled') - btnApplyActionOnSelection.removeAttribute('disabled') + selectionButton.removeAttribute('disabled'); + btnApplyActionOnSelection.removeAttribute('disabled'); } else { // Disable the selection and execution of an action - selectionButton.setAttribute('disabled', 'disabled') - btnApplyActionOnSelection.setAttribute('disabled', 'disabled') + selectionButton.setAttribute('disabled', 'disabled'); + btnApplyActionOnSelection.setAttribute('disabled', 'disabled'); } - }) -}); + } From 05cbf0a4a259436eb6f31d68ec959e8786cf884c Mon Sep 17 00:00:00 2001 From: TimotheeHrl Date: Tue, 2 Jul 2024 13:45:10 +0200 Subject: [PATCH 4/8] LUT-28235 : Archive action: adding a confirmation popup --- .../lutece/plugins/blog/web/BlogJspBean.java | 171 ++++++++++++++++-- .../admin/plugins/blog/manage_blogs.html | 13 +- 2 files changed, 161 insertions(+), 23 deletions(-) diff --git a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java index e34ee8ee..87f48de9 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java @@ -185,9 +185,6 @@ public class BlogJspBean extends ManageBlogJspBean protected static final String PROPERTY_USE_UPLOAD_IMAGE_PLUGIN = "use_upload_image_plugin"; protected static final String PROPERTY_BLOG_ARCHIVE = "blog.manage_blog_archives.labelActionArchive"; - // Properties - private static final String PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE = "blog.listItems.itemsPerPage"; - // Markers protected static final String MARK_BLOG_LIST = "blog_list"; protected static final String MARK_BLOG_VERSION_LIST = "blog_version_list"; @@ -215,12 +212,22 @@ public class BlogJspBean extends ManageBlogJspBean private static final String JSP_MANAGE_BLOGS = "jsp/admin/plugins/blog/ManageBlogs.jsp"; // Properties + private static final String PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE = "blog.listItems.itemsPerPage"; private static final String MESSAGE_CONFIRM_REMOVE_BLOG = "blog.message.confirmRemoveBlog"; private static final String MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED = "blog.message.errorDocumentIsPublished"; private static final String MESSAGE_CONFIRM_REMOVE_HISTORY_BLOG = "blog.message.confirmRemoveHistoryBlog"; private static final String ACCESS_DENIED_MESSAGE = "portal.message.user.accessDenied"; + private static final String MESSAGE_CONFIRM_ARCHIVE_BLOG = "blog.message.confirmArchiveBlog"; + private static final String MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_BLOGS = "blog.message.confirmArchiveMultipleBlogs"; + private static final String MESSAGE_CONFIRM_UNARCHIVE_MULTIPLE_BLOGS = "blog.message.confirmUnarchiveMultipleBlogs"; + private static final String MESSAGE_CONFIRM_UNARCHIVE_BLOG= "blog.message.confirmUnarchiveBlog"; + private static final String MESSAGE_CONFIRM_REMOVE_MULTIPE_BLOGS = "blog.message.confirmRemoveMultipleBlogs"; protected static final String MARK_BLOG_ACTION_LIST = "selection_action_list"; + private static final String INFO_BLOG_UNARCHIVED = "blog.info.blog.blogUnarchived"; + private static final String INFO_MULTIPLE_BLOGS_UNARCHIVED = "blog.info.blog.multipleBlogsUnarchived"; + private static final String INFO_BLOG_ARCHIVED = "blog.info.blog.blogArchived"; + private static final String INFO_MULTIPLE_BLOGS_ARCHIVED = "blog.info.blog.multipleBlogsArchived"; // Validations private static final String VALIDATION_ATTRIBUTES_PREFIX = "blog.model.entity.blog.attribute."; @@ -250,6 +257,11 @@ public class BlogJspBean extends ManageBlogJspBean private static final String ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS = "updateArchiveMultipleBlogs"; private static final String ACTION_REMOVE_MULTIPLE_BLOGS = "removeMultipleBlogs"; private static final String ACTION_EXECUTE_SELECTED_ACTION = "form_checkbox_action"; + private static final String ACTION_CONFIRM_ARCHIVE_BLOG = "confirmArchiveBlog"; + private static final String ACTION_ARCHIVE_BLOG = "archiveBlog"; + private static final String ACTION_CONFIRM_ARCHIVE_BLOGS = "confirmArchiveBlogs"; + private static final String ACTION_CONFIRM_UNARCHIVE_BLOGS = "confirmUnarchiveBlogs"; + // Infos private static final String INFO_BLOG_CREATED = "blog.info.blog.created"; private static final String INFO_BLOG_UPDATED = "blog.info.blog.updated"; @@ -467,9 +479,20 @@ public String getManageBlogs( HttpServletRequest request ) boolean bPermissionArchive = RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, (User) getUser( ) ); + HttpSession session = request.getSession(); + Map model = new HashMap<>( ); + if( session.getAttribute(PARAMETER_INFO_MESSAGE ) != null ) + { + Locale locale = request.getLocale( ); + String messageKey = request.getSession().getAttribute(PARAMETER_INFO_MESSAGE).toString(); + model.put( PARAMETER_INFO_MESSAGE, I18nService.getLocalizedString( messageKey, locale ) ); + session.removeAttribute(PARAMETER_INFO_MESSAGE); + } else { + model.put( PARAMETER_INFO_MESSAGE, null ); + } + model.put( MARK_STATUS_FILTER, _nIsUnpublished ); - model.put( MARK_BLOG_ACTION_LIST, _listBlogActionsList ); model.put( MARK_BLOG_LIST, listDocuments ); model.put( MARK_PAGINATOR, paginator ); model.put( MARK_BLOG_FILTER_LIST, getBlogFilterList( ) ); @@ -1724,6 +1747,94 @@ private void removeMultipleBlogs( List listBlogIds ) BlogHome.remove( blogId ); } } + /** + * Display the confirmation message before one or multiple selected blog posts are removed + * + * @param request + * The Http request + * @return the html code to confirm the action + * @throws AccessDeniedException + */ + @Action( ACTION_CONFIRM_ARCHIVE_BLOGS ) + public String getconfirmArchiveBlogs( HttpServletRequest request ) throws AccessDeniedException + { + // Check if the user has the permission to archive a blog + if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, + (User) getUser( ) ) ) + { + throw new AccessDeniedException( UNAUTHORIZED ); + } + + // Check if one of the blog selected is currently locked. Display a message and redirect the user if it's the case + if ( checkLockMultipleBlogs( request.getSession( ).getId( ) ) ) + { + UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) ); + String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP ); + return redirect( request, strMessageUrl ); + } + + UrlItem url = new UrlItem( getActionUrl( ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS ) ); + url.addParameter( PARAMETER_SELECTED_BLOGS, _listSelectedBlogIds.stream( ).map( String::valueOf ).collect( Collectors.joining( "," ) ) ); + url.addParameter( PARAMETER_TO_ARCHIVE, String.valueOf( true )); + // Check if there's 1 or multiple posts being archived, to adapt the content of the displayed message + String confirmationMessage = _listSelectedBlogIds.size( ) > 1 ? MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_BLOGS : MESSAGE_CONFIRM_ARCHIVE_BLOG; + if( _listSelectedBlogIds.size( ) > 1 ) + { + Object [ ] messageArgs = { + _listSelectedBlogIds.size( ) + }; + return redirect( request, AdminMessageService.getMessageUrl( request, confirmationMessage, messageArgs, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION )); + } + else + { + return redirect( request, AdminMessageService.getMessageUrl( request, confirmationMessage, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION )); + } + } + /** + * Display the confirmation message before one or multiple selected blog posts are archived + * + * @param request + * The Http request + * @return the html code to confirm the action + * @throws AccessDeniedException + */ + @Action( ACTION_CONFIRM_UNARCHIVE_BLOGS ) + public String getconfirmUnarchiveBlogs( HttpServletRequest request ) throws AccessDeniedException + { + // Check if the user has the permission to archive a blog + if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, + (User) getUser( ) ) ) + { + String strMessage = I18nService.getLocalizedString( ACCESS_DENIED_MESSAGE, request.getLocale( ) ); + throw new AccessDeniedException( strMessage ); + } + + // Check if one of the blog selected is currently locked. Display a message and redirect the user if it's the case + if ( checkLockMultipleBlogs( request.getSession( ).getId( ) ) ) + { + UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) ); + String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP ); + return redirect( request, strMessageUrl ); + } + + UrlItem url = new UrlItem( getActionUrl( ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS ) ); + url.addParameter( PARAMETER_SELECTED_BLOGS, _listSelectedBlogIds.stream( ).map( String::valueOf ).collect( Collectors.joining( "," ) ) ); + url.addParameter( PARAMETER_TO_ARCHIVE, String.valueOf( false )); + // Check if there's 1 or multiple posts being archived, to adapt the content of the displayed message + String confirmationMessage = _listSelectedBlogIds.size( ) > 1 ? MESSAGE_CONFIRM_UNARCHIVE_MULTIPLE_BLOGS : MESSAGE_CONFIRM_UNARCHIVE_BLOG; + if( _listSelectedBlogIds.size( ) > 1 ) + { + Object [ ] messageArgs = { + _listSelectedBlogIds.size( ) + }; + return redirect( request, AdminMessageService.getMessageUrl( request, confirmationMessage, messageArgs, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION )); + } + else + { + return redirect( request, AdminMessageService.getMessageUrl( request, confirmationMessage, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION ) ); + } + } + /** * Handles the manual archiving of multiple blog posts * @@ -1743,7 +1854,7 @@ public String doArchiveMultipleBlog( HttpServletRequest request ) throws AccessD } // Get a List of the selected posts' IDs, from the current session - _listSelectedBlogIds = getSelectedBlogPostsIds( request ); + _listSelectedBlogIds = (List) request.getSession( ).getAttribute( PARAMETER_SELECTED_BLOG_IDS_LIST ); // Check if any of the selected post is being modified by another user if ( checkLockMultipleBlogs( request.getSession( ).getId( ) ) ) @@ -1753,17 +1864,43 @@ public String doArchiveMultipleBlog( HttpServletRequest request ) throws AccessD return redirect( request, strMessageUrl ); } // Archive the selected blog posts - if( request.getParameter( PARAMETER_TO_ARCHIVE ) != null) + Boolean bArchive = Boolean.parseBoolean( request.getParameter( PARAMETER_TO_ARCHIVE ) ); + updateArchiveMultipleBlogs( _listSelectedBlogIds, bArchive ); + HttpSession session = request.getSession(); + session.setAttribute( PARAMETER_INFO_MESSAGE, getArchivedResultMessageKey( bArchive, _listSelectedBlogIds ) ); + return redirectView( request, VIEW_MANAGE_BLOGS ); + } + + /** + * Get the key of the message to display after the archiving of multiple blog posts + * @param toArchived + * @param listBlogIds + * @return the key of the message to display + */ + private String getArchivedResultMessageKey(Boolean toArchived, List listBlogIds) + { + if(toArchived) { - Boolean bArchive = Boolean.parseBoolean( request.getParameter( PARAMETER_TO_ARCHIVE ) ); - updateArchiveMultipleBlogs( _listSelectedBlogIds, bArchive ); - } else + if(listBlogIds.size() == 1) + { + return INFO_BLOG_ARCHIVED; + } + else + { + return INFO_MULTIPLE_BLOGS_ARCHIVED; + } + } + else { - Boolean bArchive = Boolean.parseBoolean( request.getAttribute( PARAMETER_TO_ARCHIVE ).toString( ) ); - updateArchiveMultipleBlogs( _listSelectedBlogIds, bArchive ); - request.removeAttribute( PARAMETER_TO_ARCHIVE ); + if(listBlogIds.size() == 1) + { + return INFO_BLOG_UNARCHIVED; + } + else + { + return INFO_MULTIPLE_BLOGS_UNARCHIVED; + } } - return redirectView( request, VIEW_MANAGE_BLOGS ); } /** @@ -1797,15 +1934,11 @@ public String doExecuteSelectedAction( HttpServletRequest request ) throws Acces // Execute the action selected by the user if ( selectedActionId == 0 ) { - // add parameter to the request to_archive=true - request.setAttribute( PARAMETER_TO_ARCHIVE, Boolean.TRUE.toString( ) ); - return doArchiveMultipleBlog( request ); + return getconfirmArchiveBlogs( request ); } else if ( selectedActionId == 1 ) { - // add parameter to the request to_archive=false - request.setAttribute( PARAMETER_TO_ARCHIVE, Boolean.FALSE.toString( ) ); - return doArchiveMultipleBlog( request ); + return getconfirmUnarchiveBlogs( request ); } else if ( selectedActionId == 2 ) { diff --git a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html index fd763bd7..c3e63a55 100644 --- a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html +++ b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html @@ -66,10 +66,15 @@ <@tform id='form_checkbox_action' name='form_checkbox_action' method='post' class='p-0' action='jsp/admin/plugins/blog/ManageBlogs.jsp'> <@input type='hidden' id='action' name='action' value='form_checkbox_action' /> <#assign idx=0 /> + <#if info_message?? && info_message?trim !=''> + <@initToast> + <@addToast content=info_message class='text-bg-info border-0' /> + + <#if permission_manage_archive_blog || permission_manage_delete_blog> <@div class='d-flex flex-row'> <@inputGroup class='p-2'> - <@select id='select_blog_action' name='select_blog_action' title='#i18n{blog.manage_blogs.selectActionToApply}' class='p-2'> + <@select id='select_blog_action' name='select_blog_action' title='#i18n{blog.manage_blogs.selectActionToApply}' class='p-2' disabled=true> <#if permission_manage_archive_blog> @@ -202,10 +207,10 @@ <#if permission_manage_archive_blog> - <#if blog.isArchived() > - <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=updateArchiveMultipleBlogs&to_archive=true&select_blog_id=${blog.id}' title='#i18n{blog.manage_blog_archives.labelActionUnarchive}' buttonIcon='archive' hideTitle=['all'] color='warning' /> + <#if blog.isArchived() > + <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=form_checkbox_action&select_blog_action=1&select_blog_id=${blog.id}' title='#i18n{blog.manage_blog_archives.labelActionUnarchive}' buttonIcon='archive' hideTitle=['all'] color='info' /> <#else> - <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=updateArchiveMultipleBlogs&to_archive=false&select_blog_id=${blog.id}' title='#i18n{blog.manage_blog_archives.labelActionArchive}' buttonIcon='archive' hideTitle=['all'] color='info' /> + <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=form_checkbox_action&select_blog_action=0&select_blog_id=${blog.id}' title='#i18n{blog.manage_blog_archives.labelActionArchive}' buttonIcon='archive' hideTitle=['all'] color='warning' /> <#if permission_manage_delete_blog> From 02521171c9dea4b41b5fec7d8b8fd0b0ab43a826 Mon Sep 17 00:00:00 2001 From: Thusel Date: Mon, 6 Jan 2025 16:59:26 +0100 Subject: [PATCH 5/8] LUT-28236 : Delete action: adding a confirmation popup --- .../blog/resources/blog_messages.properties | 2 +- .../resources/blog_messages_fr.properties | 2 +- .../lutece/plugins/blog/web/BlogJspBean.java | 103 ++++++++++++++---- 3 files changed, 86 insertions(+), 21 deletions(-) diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties index f780755c..415ef549 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties @@ -188,7 +188,7 @@ diff_blog.latestVersion=Compare the latest versions message.confirmRemoveBlog=Are you sure that you want to delete this post? message.confirmRemoveHistoryBlog=Are you sure that you want to delete this version of the post? -message.errorDocumentIsPublished=This post is still published in the site, please unpublish it before delete it. +message.errorDocumentIsActive=This post is still active in the site, please archive it before deleting it. message.errorTagIsAffected=This Tag is still atached to a post, please detached it before delete it ! message.errorTagExist=This Tag already exist ! message.errorTagUpdatePosition=The tag position can not be updated ! diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties index 3cf38671..876e94fb 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties @@ -353,7 +353,7 @@ message.mandatory.searchField=Le champs de recherche est obligatoire ! message.notNumericField=Le champs doit \u00e9tre au format num\u00e9rique ! message.confirmRemoveBlog=Voulez-vous supprimer ce billet ? message.confirmRemoveHistoryBlog=Voulez-vous supprimer cette version du billet ? -message.errorDocumentIsPublished=Ce billet est encore publi\u00e9 sur le site, pour le supprimer d\u00e9publiez-le ! +message.errorDocumentIsActive=Ce billet est encore actif sur le site, pour supprimer ce billet merci d'archiver le billet au pr\u00e9alable. message.errorTagIsAffected=Ce Tag est est attach\u00e9 \u00e0 un billet, pour le supprimer d\u00e9tachez le ! message.errorTagExist=Ce Tag existe d\u00e9j\a ! message.errorTagUpdatePosition=Impossible de mettre \u00e0 jour la position de ce tag ! diff --git a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java index 87f48de9..16c11885 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java @@ -48,8 +48,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; -import fr.paris.lutece.util.date.DateUtil; - import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; @@ -75,8 +73,6 @@ import org.outerj.daisy.diff.html.TextNodeComparator; import org.outerj.daisy.diff.html.dom.DomTreeBuilder; import org.xml.sax.InputSource; -import java.text.MessageFormat; - import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.blog.business.Blog; @@ -94,7 +90,6 @@ import fr.paris.lutece.plugins.blog.service.BlogSessionListner; import fr.paris.lutece.plugins.blog.service.docsearch.BlogSearchService; import fr.paris.lutece.plugins.blog.utils.BlogLock; -import fr.paris.lutece.plugins.blog.utils.BlogUtils; import fr.paris.lutece.portal.business.rbac.RBAC; import fr.paris.lutece.portal.business.user.AdminUser; import fr.paris.lutece.portal.service.admin.AccessDeniedException; @@ -183,7 +178,6 @@ public class BlogJspBean extends ManageBlogJspBean private static final String PROPERTY_PAGE_TITLE_PREVIEW_BLOG = "blog.preview_blog.pageTitle"; private static final String PROPERTY_PAGE_TITLE_DIFF_BLOG = "blog.diff_blog.pageTitle"; protected static final String PROPERTY_USE_UPLOAD_IMAGE_PLUGIN = "use_upload_image_plugin"; - protected static final String PROPERTY_BLOG_ARCHIVE = "blog.manage_blog_archives.labelActionArchive"; // Markers protected static final String MARK_BLOG_LIST = "blog_list"; @@ -214,7 +208,7 @@ public class BlogJspBean extends ManageBlogJspBean // Properties private static final String PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE = "blog.listItems.itemsPerPage"; private static final String MESSAGE_CONFIRM_REMOVE_BLOG = "blog.message.confirmRemoveBlog"; - private static final String MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED = "blog.message.errorDocumentIsPublished"; + private static final String MESSAGE_ERROR_DOCUMENT_IS_ACTIVE = "blog.message.errorDocumentIsActive"; private static final String MESSAGE_CONFIRM_REMOVE_HISTORY_BLOG = "blog.message.confirmRemoveHistoryBlog"; private static final String ACCESS_DENIED_MESSAGE = "portal.message.user.accessDenied"; private static final String MESSAGE_CONFIRM_ARCHIVE_BLOG = "blog.message.confirmArchiveBlog"; @@ -223,7 +217,6 @@ public class BlogJspBean extends ManageBlogJspBean private static final String MESSAGE_CONFIRM_UNARCHIVE_BLOG= "blog.message.confirmUnarchiveBlog"; private static final String MESSAGE_CONFIRM_REMOVE_MULTIPE_BLOGS = "blog.message.confirmRemoveMultipleBlogs"; - protected static final String MARK_BLOG_ACTION_LIST = "selection_action_list"; private static final String INFO_BLOG_UNARCHIVED = "blog.info.blog.blogUnarchived"; private static final String INFO_MULTIPLE_BLOGS_UNARCHIVED = "blog.info.blog.multipleBlogsUnarchived"; private static final String INFO_BLOG_ARCHIVED = "blog.info.blog.blogArchived"; @@ -257,8 +250,7 @@ public class BlogJspBean extends ManageBlogJspBean private static final String ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS = "updateArchiveMultipleBlogs"; private static final String ACTION_REMOVE_MULTIPLE_BLOGS = "removeMultipleBlogs"; private static final String ACTION_EXECUTE_SELECTED_ACTION = "form_checkbox_action"; - private static final String ACTION_CONFIRM_ARCHIVE_BLOG = "confirmArchiveBlog"; - private static final String ACTION_ARCHIVE_BLOG = "archiveBlog"; + private static final String ACTION_CONFIRM_REMOVE_MULTIPLE_BLOGS = "confirmRemoveMultipleBlogs"; private static final String ACTION_CONFIRM_ARCHIVE_BLOGS = "confirmArchiveBlogs"; private static final String ACTION_CONFIRM_UNARCHIVE_BLOGS = "confirmUnarchiveBlogs"; @@ -268,6 +260,7 @@ public class BlogJspBean extends ManageBlogJspBean private static final String INFO_BLOG_REMOVED = "blog.info.blog.removed"; private static final String BLOG_LOCKED = "blog.message.blogLocked"; private static final String INFO_HISTORY_BLOG_REMOVED = "blog.info.history.blog.removed"; + private static final String INFO_MULTIPLE_BLOGS_REMOVED = "blog.info.blog.multipleBlogsRemoved"; // Errors private static final String ERROR_HISTORY_BLOG_CANT_REMOVE_ORIGINAL = "blog.error.history.blog.cantRemoveOriginal"; @@ -311,7 +304,6 @@ public class BlogJspBean extends ManageBlogJspBean protected String _strSortedAttributeName; protected Boolean _bIsAscSort; protected String [ ] _strTag; - private ReferenceList _listBlogActionsList; private List _listSelectedBlogIds = new ArrayList<>( ); @@ -623,12 +615,12 @@ public String doRemoveHistoryBlog( HttpServletRequest request ) } // Check if this blog is currently published List docPublication = BlogPublicationHome.getDocPublicationByIdDoc( nBlogId ); - if ( CollectionUtils.isNotEmpty( docPublication ) ) + if ( CollectionUtils.isNotEmpty( docPublication ) || BlogHome.findByPrimaryKey( nBlogId ).isArchived() ) { // Inform the user that the blog is currently published and redirect to the blog's history view UrlItem url = new UrlItem( getViewFullUrl( VIEW_HISTORY_BLOG ) ); url.addParameter( PARAMETER_ID_BLOG, nBlogId ); - String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED, url.getUrl( ), + String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_ACTIVE, url.getUrl( ), AdminMessage.TYPE_STOP ); return redirect( request, strMessageUrl ); } @@ -967,9 +959,9 @@ public String doRemoveBlog( HttpServletRequest request ) List docPublication = BlogPublicationHome.getDocPublicationByIdDoc( nId ); - if ( CollectionUtils.isNotEmpty( docPublication ) ) + if ( CollectionUtils.isNotEmpty( docPublication ) || BlogHome.findByPrimaryKey( nId ).isArchived() ) { - String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED, AdminMessage.TYPE_STOP ); + String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_ACTIVE, AdminMessage.TYPE_STOP ); return redirect( request, strMessageUrl ); } @@ -979,7 +971,8 @@ public String doRemoveBlog( HttpServletRequest request ) ExtendableResourceRemovalListenerService.doRemoveResourceExtentions( Blog.PROPERTY_RESOURCE_TYPE, String.valueOf( nId ) ); - addInfo( INFO_BLOG_REMOVED, getLocale( ) ); + HttpSession session = request.getSession(); + session.setAttribute( PARAMETER_INFO_MESSAGE, INFO_BLOG_REMOVED); } return redirectView( request, VIEW_MANAGE_BLOGS ); } @@ -1698,6 +1691,51 @@ private static boolean checkLockBlog( int nIdBlog, String strIdSession ) } + /** + * Display the confirmation message before one or multiple selected blog posts are deleted + * + * @param request + * The Http request + * @return the html code to confirm the action + * @throws AccessDeniedException + */ + @Action( ACTION_CONFIRM_REMOVE_MULTIPLE_BLOGS ) + public String getConfirmRemoveMultipleBlogs( HttpServletRequest request ) throws AccessDeniedException + { + // Check if the user has the permission to archive a blog + AdminUser adminUser = AdminUserService.getAdminUser( request ); + User user = AdminUserService.getAdminUser( request ); + if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_DELETE, user ) ) + { + String strMessage = I18nService.getLocalizedString( ACCESS_DENIED_MESSAGE, request.getLocale( ) ); + throw new AccessDeniedException( strMessage ); + } + + // Check if one of the blog selected is currently locked. Display a message and redirect the user if it's the case + if ( checkLockMultipleBlogs( request.getSession( ).getId( ) ) ) + { + UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) ); + String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP ); + return redirect( request, strMessageUrl ); + } + + UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_MULTIPLE_BLOGS ) ); + url.addParameter( PARAMETER_SELECTED_BLOGS, _listSelectedBlogIds.stream( ).map( String::valueOf ).collect( Collectors.joining( "," ) ) ); + // Check if there's 1 or multiple posts to be removed, to adapt the content of the displayed message + String confirmationMessage = _listSelectedBlogIds.size( ) > 1 ? MESSAGE_CONFIRM_REMOVE_MULTIPE_BLOGS : MESSAGE_CONFIRM_REMOVE_BLOG; + if( _listSelectedBlogIds.size( ) > 1 ) + { + Object [ ] messageArgs = { + _listSelectedBlogIds.size( ) + }; + return redirect( request, AdminMessageService.getMessageUrl( request, confirmationMessage, messageArgs, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION )); + } + else + { + return redirect( request, AdminMessageService.getMessageUrl( request, confirmationMessage, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION )); + } + } + /** * Handles the manual delete of multiple blog posts * @@ -1718,7 +1756,7 @@ public String doRemoveMultipleBlog( HttpServletRequest request ) throws AccessDe throw new AccessDeniedException( strMessage ); } // Get a List of the selected posts' IDs, from the current session - _listSelectedBlogIds = getSelectedBlogPostsIds( request ); + _listSelectedBlogIds = (List) request.getSession( ).getAttribute( PARAMETER_SELECTED_BLOG_IDS_LIST ); // Check if any of the selected post is being modified by another user if ( checkLockMultipleBlogs( request.getSession( ).getId( ) ) ) @@ -1727,7 +1765,18 @@ public String doRemoveMultipleBlog( HttpServletRequest request ) throws AccessDe String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP ); return redirect( request, strMessageUrl ); } + for ( int docPublicationId : _listSelectedBlogIds ) + { + if ( CollectionUtils.isNotEmpty( BlogPublicationHome.getDocPublicationByIdDoc( docPublicationId ) ) ) + { + String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_ACTIVE, AdminMessage.TYPE_STOP ); + + return redirect( request, strMessageUrl ); + } + } removeMultipleBlogs( _listSelectedBlogIds ); + HttpSession session = request.getSession(); + session.setAttribute( PARAMETER_INFO_MESSAGE, getRemovedResultMessageKey( _listSelectedBlogIds )); return redirectView( request, VIEW_MANAGE_BLOGS ); } private void removeMultipleBlogs( List listBlogIds ) @@ -1902,6 +1951,22 @@ private String getArchivedResultMessageKey(Boolean toArchived, List lis } } } + /** + * Get the key of the message to display after the removing of multiple blog posts + * @param listBlogIds + * @return the key of the message to display + */ + private String getRemovedResultMessageKey(List listBlogIds) + { + if(listBlogIds.size() == 1) + { + return INFO_BLOG_REMOVED; + } + else + { + return INFO_MULTIPLE_BLOGS_REMOVED; + } + }; /** * Process a specific action on a selection of multiple blog post elements @@ -1942,7 +2007,7 @@ else if ( selectedActionId == 1 ) } else if ( selectedActionId == 2 ) { - return doRemoveMultipleBlog( request ); + return getConfirmRemoveMultipleBlogs( request ); } else { @@ -2000,7 +2065,7 @@ private List getSelectedBlogPostsIds( HttpServletRequest request ) */ private synchronized boolean checkLockMultipleBlogs( String strIdSession ) { - if(_listBlogActionsList == null || CollectionUtils.isEmpty( _listSelectedBlogIds )) + if( CollectionUtils.isEmpty( _listSelectedBlogIds )) { return false; } From 31058a02c8a543b7e4a6b44bf62e6dbc54761544 Mon Sep 17 00:00:00 2001 From: Thusel Date: Wed, 8 Jan 2025 16:56:23 +0100 Subject: [PATCH 6/8] LUT-28236 : prevent blog deletion without archiving it first --- .../plugins/blog/resources/blog_messages.properties | 1 + .../blog/resources/blog_messages_fr.properties | 1 + .../fr/paris/lutece/plugins/blog/web/BlogJspBean.java | 11 +++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties index 415ef549..f2979e2c 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties @@ -188,6 +188,7 @@ diff_blog.latestVersion=Compare the latest versions message.confirmRemoveBlog=Are you sure that you want to delete this post? message.confirmRemoveHistoryBlog=Are you sure that you want to delete this version of the post? +message.errorDocumentIsPublished=This post is still published in the site, please unpublish it before delete it. message.errorDocumentIsActive=This post is still active in the site, please archive it before deleting it. message.errorTagIsAffected=This Tag is still atached to a post, please detached it before delete it ! message.errorTagExist=This Tag already exist ! diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties index 876e94fb..98e217f8 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties @@ -353,6 +353,7 @@ message.mandatory.searchField=Le champs de recherche est obligatoire ! message.notNumericField=Le champs doit \u00e9tre au format num\u00e9rique ! message.confirmRemoveBlog=Voulez-vous supprimer ce billet ? message.confirmRemoveHistoryBlog=Voulez-vous supprimer cette version du billet ? +message.errorDocumentIsPublished=Ce billet est encore publi\u00e9 sur le site, pour le supprimer d\u00e9publiez-le ! message.errorDocumentIsActive=Ce billet est encore actif sur le site, pour supprimer ce billet merci d'archiver le billet au pr\u00e9alable. message.errorTagIsAffected=Ce Tag est est attach\u00e9 \u00e0 un billet, pour le supprimer d\u00e9tachez le ! message.errorTagExist=Ce Tag existe d\u00e9j\a ! diff --git a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java index 16c11885..40951943 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java @@ -213,6 +213,7 @@ public class BlogJspBean extends ManageBlogJspBean private static final String ACCESS_DENIED_MESSAGE = "portal.message.user.accessDenied"; private static final String MESSAGE_CONFIRM_ARCHIVE_BLOG = "blog.message.confirmArchiveBlog"; private static final String MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_BLOGS = "blog.message.confirmArchiveMultipleBlogs"; + private static final String MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED = "blog.message.errorDocumentIsPublished"; private static final String MESSAGE_CONFIRM_UNARCHIVE_MULTIPLE_BLOGS = "blog.message.confirmUnarchiveMultipleBlogs"; private static final String MESSAGE_CONFIRM_UNARCHIVE_BLOG= "blog.message.confirmUnarchiveBlog"; private static final String MESSAGE_CONFIRM_REMOVE_MULTIPE_BLOGS = "blog.message.confirmRemoveMultipleBlogs"; @@ -620,7 +621,7 @@ public String doRemoveHistoryBlog( HttpServletRequest request ) // Inform the user that the blog is currently published and redirect to the blog's history view UrlItem url = new UrlItem( getViewFullUrl( VIEW_HISTORY_BLOG ) ); url.addParameter( PARAMETER_ID_BLOG, nBlogId ); - String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_ACTIVE, url.getUrl( ), + String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED, url.getUrl( ), AdminMessage.TYPE_STOP ); return redirect( request, strMessageUrl ); } @@ -959,9 +960,10 @@ public String doRemoveBlog( HttpServletRequest request ) List docPublication = BlogPublicationHome.getDocPublicationByIdDoc( nId ); - if ( CollectionUtils.isNotEmpty( docPublication ) || BlogHome.findByPrimaryKey( nId ).isArchived() ) + if ( CollectionUtils.isNotEmpty( docPublication ) || !BlogHome.findByPrimaryKey( nId ).isArchived( ) ) { - String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_ACTIVE, AdminMessage.TYPE_STOP ); + UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) ); + String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_ACTIVE, url.getUrl( ), AdminMessage.TYPE_STOP ); return redirect( request, strMessageUrl ); } @@ -1767,7 +1769,8 @@ public String doRemoveMultipleBlog( HttpServletRequest request ) throws AccessDe } for ( int docPublicationId : _listSelectedBlogIds ) { - if ( CollectionUtils.isNotEmpty( BlogPublicationHome.getDocPublicationByIdDoc( docPublicationId ) ) ) + if ( CollectionUtils.isNotEmpty( BlogPublicationHome.getDocPublicationByIdDoc( docPublicationId ) ) || !BlogHome.findByPrimaryKey( + docPublicationId ).isArchived( ) ) { String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_ACTIVE, AdminMessage.TYPE_STOP ); From 69ac09e740ddb399bbe0a6eab6665894d296f158 Mon Sep 17 00:00:00 2001 From: Thusel Date: Thu, 9 Jan 2025 17:58:11 +0100 Subject: [PATCH 7/8] LUT-27285 : hide delete button for unarchived blogs --- .../WEB-INF/templates/admin/plugins/blog/manage_blogs.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html index c3e63a55..112b9a3f 100644 --- a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html +++ b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html @@ -79,7 +79,7 @@ - <#if permission_manage_delete_blog> + <#if permission_manage_delete_blog && status_filter == 3> @@ -213,7 +213,7 @@ <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=form_checkbox_action&select_blog_action=0&select_blog_id=${blog.id}' title='#i18n{blog.manage_blog_archives.labelActionArchive}' buttonIcon='archive' hideTitle=['all'] color='warning' /> - <#if permission_manage_delete_blog> + <#if permission_manage_delete_blog && status_filter == 3> <@aButton href='jsp/admin/plugins/blog/ManageBlogs.jsp?action=confirmRemoveBlog&id=${blog.id}' title='#i18n{portal.util.labelDelete}' buttonIcon='trash' hideTitle=['all'] color='danger' /> <@aButton href='jsp/site/Portal.jsp?page=blog&id=${blog.id}' title='#i18n{portal.site.admin_page.labelShowPage}' buttonIcon='external-link' hideTitle=['all'] target='_blank' color='default ms-1' size='' class='btn-preview' /> @@ -303,6 +303,8 @@ // checkbox row let btnApplyActionOnSelection = document.getElementById('button_apply_selected_action') +window.addEventListener("load", ( ) => manageActionButtonVisibility( ) ); + // When the "Check all" / "Uncheck all" element is clicked, check / uncheck all the blog posts' checkboxes document.getElementById('select_all_blogs_id').addEventListener('click', function () { var selectionButton = document.getElementById('select_blog_action') From 936b4ece41f3e759e741e87c3061133a78119efd Mon Sep 17 00:00:00 2001 From: Thusel Date: Fri, 10 Jan 2025 17:32:08 +0100 Subject: [PATCH 8/8] LUT-28237 : add archive confirmation for published blogs --- .../blog/resources/blog_messages.properties | 12 ++++--- .../resources/blog_messages_fr.properties | 6 ++-- .../lutece/plugins/blog/web/BlogJspBean.java | 31 ++++++++++++++----- .../admin/plugins/blog/manage_blogs.html | 15 +++++---- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties index f2979e2c..e1dc927a 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages.properties @@ -196,11 +196,13 @@ message.errorTagUpdatePosition=The tag position can not be updated ! message.errorTagDeletion=The tag can not be deleted ! message.errorTagTitleNotEmpty=The tag title can not be empty ! message.errorTagNotSet=Can not set the tag ! -message.confirmArchiveBlog=Are you sure you want to archive this blog post ? Please note that publications of this post will be removed. -message.confirmArchiveMultipleBlogs=Are you sure you want to archive these blog posts ? Please note that publications of these posts will be removed. -message.confirmUnarchiveMultipleBlogs=Are you sure you want to unarchive these blog posts ? -message.confirmUnarchiveBlog=Are you sure you want to unarchive this blog post ? -message.confirmRemoveMultipleBlogs=Are you sure you want to delete these blog posts ? Please note that contents associated with these posts will be removed. +message.confirmArchiveBlog=Do you want to archive this blog ? +message.confirmArchivePublishedBlog=This blog is still assigned to a portlet. Do you want to unpublish and archive this blog ? +message.confirmArchiveMultipleBlogs=Do you want to archive these {0} blogs ? +message.confirmArchiveMultiplePublishedBlogs=At least one of these blogs is assigned to a portlet. Do you want to unpublish and archive these {0} blogs ? +message.confirmUnarchiveMultipleBlogs=Do you want to unarchive these {0} blogs ? +message.confirmUnarchiveBlog=Do you want to unarchive this blog ? +message.confirmRemoveMultipleBlogs=Are you sure you want to delete these {0} blog ? Please note that contents associated with these posts will be removed. publication_blog.pageTitle=Posts Publication diff --git a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties index 98e217f8..ded89723 100644 --- a/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties +++ b/src/java/fr/paris/lutece/plugins/blog/resources/blog_messages_fr.properties @@ -361,8 +361,10 @@ message.errorTagUpdatePosition=Impossible de mettre \u00e0 jour la position de c message.errorTagDeletion=Le tag ne peut \u00e9tre supprim\u00e9 ! message.errorTagTitleNotEmpty=Le titre du tag peut \u00e9tre vide ! message.errorTagNotSet=Impossible d'ajouter ce tag ! -message.confirmArchiveBlog=Voulez-vous archiver ce billet ? Les publications associ\u00e9es de ce billet seront supprim\u00e9es. -message.confirmArchiveMultipleBlogs=Voulez-vous archiver ces {0} billets ? Les publications associ\u00e9es \u00e0 ces billets seront supprim\u00e9es. +message.confirmArchiveBlog=Voulez-vous archiver ce billet ? +message.confirmArchivePublishedBlog=Ce billet est assign\u00e9 \u00e0 une rubrique du site. Souhaitez-vous d\u00e9publier ce billet et l'archiver ? +message.confirmArchiveMultipleBlogs=Voulez-vous archiver ces {0} billets ? +message.confirmArchiveMultiplePublishedBlogs=Au moins un de ces billet est assign\u00e9 \u00e0 une rubrique du site. Souhaitez-vous d\u00e9publier et archiver ces {0} billets ? message.confirmUnarchiveMultipleBlogs=Voulez-vous d\u00e9sarchiver ces {0} billets ? message.confirmUnarchiveBlog=Voulez-vous d\u00e9sarchiver ce billet ? message.confirmRemoveMultipleBlogs=Voulez-vous supprimer ces {0} billets ? Les contenus associ\u00e9s \u00e0 ces billets seront supprim\u00e9s. diff --git a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java index 40951943..0cf5a9ce 100644 --- a/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java +++ b/src/java/fr/paris/lutece/plugins/blog/web/BlogJspBean.java @@ -212,7 +212,9 @@ public class BlogJspBean extends ManageBlogJspBean private static final String MESSAGE_CONFIRM_REMOVE_HISTORY_BLOG = "blog.message.confirmRemoveHistoryBlog"; private static final String ACCESS_DENIED_MESSAGE = "portal.message.user.accessDenied"; private static final String MESSAGE_CONFIRM_ARCHIVE_BLOG = "blog.message.confirmArchiveBlog"; + private static final String MESSAGE_CONFIRM_ARCHIVE_PUBLISHED_BLOG = "blog.message.confirmArchivePublishedBlog"; private static final String MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_BLOGS = "blog.message.confirmArchiveMultipleBlogs"; + private static final String MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_PUBLISHED_BLOGS = "blog.message.confirmArchiveMultiplePublishedBlogs"; private static final String MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED = "blog.message.errorDocumentIsPublished"; private static final String MESSAGE_CONFIRM_UNARCHIVE_MULTIPLE_BLOGS = "blog.message.confirmUnarchiveMultipleBlogs"; private static final String MESSAGE_CONFIRM_UNARCHIVE_BLOG= "blog.message.confirmUnarchiveBlog"; @@ -1790,7 +1792,6 @@ private void removeMultipleBlogs( List listBlogIds ) } for ( int blogId : listBlogIds ) { - BlogPublicationHome.getDocPublicationByIdDoc( blogId ); if ( BlogPublicationHome.getDocPublicationByIdDoc( blogId ) != null && BlogPublicationHome.getDocPublicationByIdDoc( blogId ).size( ) > 0 ) { BlogPublicationHome.removeByBlogId( blogId ); @@ -1808,7 +1809,7 @@ private void removeMultipleBlogs( List listBlogIds ) * @throws AccessDeniedException */ @Action( ACTION_CONFIRM_ARCHIVE_BLOGS ) - public String getconfirmArchiveBlogs( HttpServletRequest request ) throws AccessDeniedException + public String getConfirmArchiveBlogs( HttpServletRequest request ) throws AccessDeniedException { // Check if the user has the permission to archive a blog if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, @@ -1828,10 +1829,23 @@ public String getconfirmArchiveBlogs( HttpServletRequest request ) throws Access UrlItem url = new UrlItem( getActionUrl( ACTION_UPDATE_ARCHIVE_MULTIPLE_BLOGS ) ); url.addParameter( PARAMETER_SELECTED_BLOGS, _listSelectedBlogIds.stream( ).map( String::valueOf ).collect( Collectors.joining( "," ) ) ); url.addParameter( PARAMETER_TO_ARCHIVE, String.valueOf( true )); - // Check if there's 1 or multiple posts being archived, to adapt the content of the displayed message - String confirmationMessage = _listSelectedBlogIds.size( ) > 1 ? MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_BLOGS : MESSAGE_CONFIRM_ARCHIVE_BLOG; - if( _listSelectedBlogIds.size( ) > 1 ) + String confirmationMessage; + Boolean publishedBlog = false; + + // Check if there is published blogs + for ( int blogId : _listSelectedBlogIds ) { + if ( BlogPublicationHome.getDocPublicationByIdDoc( blogId ) != null && !BlogPublicationHome.getDocPublicationByIdDoc( blogId ).isEmpty( ) ) + { + publishedBlog = true; + break; + } + } + + if ( _listSelectedBlogIds.size( ) > 1 ) + { + confirmationMessage = publishedBlog ? MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_PUBLISHED_BLOGS : MESSAGE_CONFIRM_ARCHIVE_MULTIPLE_BLOGS; + Object [ ] messageArgs = { _listSelectedBlogIds.size( ) }; @@ -1839,6 +1853,7 @@ public String getconfirmArchiveBlogs( HttpServletRequest request ) throws Access } else { + confirmationMessage = publishedBlog ? MESSAGE_CONFIRM_ARCHIVE_PUBLISHED_BLOG : MESSAGE_CONFIRM_ARCHIVE_BLOG; return redirect( request, AdminMessageService.getMessageUrl( request, confirmationMessage, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION )); } } @@ -1851,7 +1866,7 @@ public String getconfirmArchiveBlogs( HttpServletRequest request ) throws Access * @throws AccessDeniedException */ @Action( ACTION_CONFIRM_UNARCHIVE_BLOGS ) - public String getconfirmUnarchiveBlogs( HttpServletRequest request ) throws AccessDeniedException + public String getConfirmUnarchiveBlogs( HttpServletRequest request ) throws AccessDeniedException { // Check if the user has the permission to archive a blog if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_ARCHIVE, @@ -2002,11 +2017,11 @@ public String doExecuteSelectedAction( HttpServletRequest request ) throws Acces // Execute the action selected by the user if ( selectedActionId == 0 ) { - return getconfirmArchiveBlogs( request ); + return getConfirmArchiveBlogs( request ); } else if ( selectedActionId == 1 ) { - return getconfirmUnarchiveBlogs( request ); + return getConfirmUnarchiveBlogs( request ); } else if ( selectedActionId == 2 ) { diff --git a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html index 112b9a3f..0c743e63 100644 --- a/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html +++ b/webapp/WEB-INF/templates/admin/plugins/blog/manage_blogs.html @@ -71,13 +71,16 @@ <@addToast content=info_message class='text-bg-info border-0' /> - <#if permission_manage_archive_blog || permission_manage_delete_blog> + <#if permission_manage_archive_blog || permission_manage_delete_blog && status_filter == 3> <@div class='d-flex flex-row'> <@inputGroup class='p-2'> <@select id='select_blog_action' name='select_blog_action' title='#i18n{blog.manage_blogs.selectActionToApply}' class='p-2' disabled=true> <#if permission_manage_archive_blog> - - + <#if status_filter == 3> + + <#else> + + <#if permission_manage_delete_blog && status_filter == 3> @@ -91,7 +94,7 @@ <@table headBody=true > <@tr> - <#if permission_manage_archive_blog || permission_manage_delete_blog> + <#if permission_manage_archive_blog || permission_manage_delete_blog && status_filter == 3> <@th><@checkBox name='select_all_blogs_id' id='select_all_blogs_id' /> <@th>#i18n{blog.manage_blogs.columnContentLabel} <@sort jsp_url="jsp/admin/plugins/blog/ManageBlogs.jsp" attribute="contentLabel" /> @@ -105,7 +108,7 @@ <@tableHeadBodySeparator /> <#list blog_list as blog> <@tr> - <#if permission_manage_archive_blog || permission_manage_delete_blog> + <#if permission_manage_archive_blog || permission_manage_delete_blog && status_filter == 3> <@td> <@checkBox id='selected_blog_${blog.id}' name='select_blog_id' value='${blog.id}' /> @@ -154,7 +157,7 @@ <@td> - <#if permission_manage_publish_blog> + <#if permission_manage_publish_blog && status_filter != 3> <#assign btnColor><#if blog.blogPublication?size = 0>default<#else>primary <#assign btnTitle><#if blog.blogPublication?size==0>#i18n{blog.manage_blogs.labelPublished}<#else>#i18n{blog.manage_blogs.managePublication} <@btnGroup params='aria-label="Manage"'>