001/* 002 * Copyright 2019 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.ametys.cms.repository.reports.ui; 018 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028 029import org.ametys.cms.ObservationConstants; 030import org.ametys.cms.content.ContentHelper; 031import org.ametys.cms.repository.Content; 032import org.ametys.cms.repository.ModifiableContent; 033import org.ametys.cms.repository.ReportableObject; 034import org.ametys.cms.repository.comment.Comment; 035import org.ametys.cms.repository.comment.CommentableContent; 036import org.ametys.core.observation.Event; 037import org.ametys.core.observation.ObservationManager; 038import org.ametys.core.right.RightManager.RightResult; 039import org.ametys.core.ui.Callable; 040import org.ametys.core.ui.StaticClientSideElement; 041import org.ametys.core.user.CurrentUserProvider; 042import org.ametys.core.user.UserIdentity; 043import org.ametys.plugins.repository.AmetysObjectResolver; 044import org.ametys.plugins.repository.UnknownAmetysObjectException; 045import org.ametys.plugins.repository.metadata.UnknownMetadataException; 046 047/** 048 * This client site elements creates a button representing the validation state of a content's comment 049 */ 050public class ReportsClientSideElement extends StaticClientSideElement 051{ 052 /** The Ametys object resolver */ 053 protected AmetysObjectResolver _resolver; 054 /** The current user provider */ 055 protected CurrentUserProvider _userProvider; 056 /** The observation manager */ 057 protected ObservationManager _observationManager; 058 /** The content helper */ 059 private ContentHelper _contentHelper; 060 061 @Override 062 public void service(ServiceManager smanager) throws ServiceException 063 { 064 super.service(smanager); 065 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 066 _userProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE); 067 _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE); 068 _contentHelper = (ContentHelper) smanager.lookup(ContentHelper.ROLE); 069 } 070 071 /** 072 * Ignore reports on objects (contents or comments) when it is possible. 073 * @param reportedObjects the objects where to ignore reports 074 * @return the JSON result with contents and comments with ignored reports or not 075 */ 076 @Callable 077 public Map<String, Object> ignoreReports(List<Map<String, String>> reportedObjects) 078 { 079 List<Map<String, Object>> contentsWithIgnoredReports = new ArrayList<>(); 080 List<Map<String, Object>> commentsWithIgnoredReports = new ArrayList<>(); 081 List<Map<String, Object>> unknownContents = new ArrayList<>(); 082 List<Map<String, Object>> unknownComments = new ArrayList<>(); 083 List<Map<String, Object>> uncommentableContents = new ArrayList<>(); 084 List<Map<String, Object>> unreportableContents = new ArrayList<>(); 085 List<Map<String, Object>> noRightContents = new ArrayList<>(); 086 087 Map<String, Content> resolvedContentsById = new HashMap<>(); 088 Set<ModifiableContent> modifiedContents = new HashSet<>(); 089 090 UserIdentity currentUser = _userProvider.getUser(); 091 092 for (Map<String, String> reportedObject : reportedObjects) 093 { 094 String contentId = reportedObject.get("contentId"); 095 096 try 097 { 098 Content content = resolvedContentsById.get(contentId); 099 if (content == null) 100 { 101 content = _resolver.resolveById(contentId); 102 resolvedContentsById.put(contentId, content); 103 } 104 105 Map<String, Object> contentParams = _getContentParameters(content); 106 107 if (_rightManager.hasRight(currentUser, "CMS_Rights_CommentModerate", content) == RightResult.RIGHT_ALLOW) 108 { 109 if (reportedObject.containsKey("commentId")) 110 { 111 String commentId = reportedObject.get("commentId"); 112 Map<String, Object> commentParams = _getCommentParameters(commentId, content); 113 114 if (content instanceof CommentableContent) 115 { 116 try 117 { 118 CommentableContent cContent = (CommentableContent) content; 119 boolean ignored = _ignoreReportsOnComment(commentId, cContent, currentUser); 120 if (ignored) 121 { 122 modifiedContents.add(cContent); 123 commentsWithIgnoredReports.add(commentParams); 124 } 125 } 126 catch (UnknownMetadataException e) 127 { 128 getLogger().error("Can not ignore reports on a non existing comment", e); 129 unknownComments.add(commentParams); 130 } 131 } 132 else 133 { 134 getLogger().error("Can not ignore reports on a comment on a non commentable content"); 135 uncommentableContents.add(contentParams); 136 } 137 } 138 else 139 { 140 if (content instanceof ReportableObject && content instanceof ModifiableContent) 141 { 142 boolean ignored = _ignoreReportsOnContent((ReportableObject) content, currentUser); 143 if (ignored) 144 { 145 modifiedContents.add((ModifiableContent) content); 146 contentsWithIgnoredReports.add(contentParams); 147 } 148 } 149 else 150 { 151 getLogger().error("Can not ignore reports on a non reportable content"); 152 unreportableContents.add(contentParams); 153 } 154 } 155 } 156 else 157 { 158 getLogger().error("User '" + currentUser + "' does not have right to ignore reports on content '" + content.getId() + "'"); 159 noRightContents.add(contentParams); 160 } 161 } 162 catch (UnknownAmetysObjectException e) 163 { 164 getLogger().error("Can not ignore reports on a comment on a non existing content", e); 165 unknownContents.add(Map.of("id", contentId)); 166 } 167 } 168 169 for (ModifiableContent modifiedContent : modifiedContents) 170 { 171 modifiedContent.saveChanges(); 172 } 173 174 return Map.of("contents-with-ignored-reports", contentsWithIgnoredReports, 175 "comments-with-ignored-reports", commentsWithIgnoredReports, 176 "unknown-contents", unknownContents, 177 "unknown-comments", unknownComments, 178 "uncommentable-contents", uncommentableContents, 179 "unreportable-contents", unreportableContents, 180 "noright-contents", noRightContents); 181 } 182 183 /** 184 * Retrieves the given content's parameters 185 * @param content the content 186 * @return the content's parameters 187 */ 188 protected Map<String, Object> _getContentParameters(Content content) 189 { 190 Map<String, Object> contentParams = new HashMap<>(); 191 contentParams.put("id", content.getId()); 192 contentParams.put("title", _contentHelper.getTitle(content)); 193 return contentParams; 194 } 195 196 /** 197 * Ignores the reports on the given content 198 * @param content the content 199 * @param currentUser the current user 200 * @return <code>true</code> if there are reports that have been ignored, <code>false</code> otherwise 201 */ 202 protected boolean _ignoreReportsOnContent(ReportableObject content, UserIdentity currentUser) 203 { 204 if (content.getReportsCount() > 0) 205 { 206 content.clearReports(); 207 208 Map<String, Object> eventParams = new HashMap<>(); 209 eventParams.put(ObservationConstants.ARGS_CONTENT, content); 210 _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_IGNORE_REPORTS, currentUser, eventParams)); 211 212 return true; 213 } 214 else 215 { 216 return false; 217 } 218 } 219 220 /** 221 * Retrieves the given comment's parameters 222 * @param commentId the comment identifier 223 * @param content the content of the comment 224 * @return the comment's parameters 225 */ 226 protected Map<String, Object> _getCommentParameters(String commentId, Content content) 227 { 228 Map<String, Object> commentParams = new HashMap<>(); 229 commentParams.put("id", commentId); 230 commentParams.put("contentId", content.getId()); 231 commentParams.put("contentTitle", _contentHelper.getTitle(content)); 232 return commentParams; 233 } 234 235 /** 236 * Ignores the reports on the given comment 237 * @param commentId the identifier of the comment 238 * @param content the content of the comment 239 * @param currentUser the current user 240 * @return <code>true</code> if there are reports that have been ignored, <code>false</code> otherwise 241 */ 242 protected boolean _ignoreReportsOnComment(String commentId, CommentableContent content, UserIdentity currentUser) 243 { 244 Comment comment = content.getComment(commentId); 245 246 if (comment.getReportsCount() > 0) 247 { 248 comment.clearReports(); 249 250 Map<String, Object> eventParams = new HashMap<>(); 251 eventParams.put(ObservationConstants.ARGS_CONTENT, content); 252 eventParams.put(ObservationConstants.ARGS_COMMENT, comment); 253 _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_COMMENT_IGNORE_REPORTS, currentUser, eventParams)); 254 255 return true; 256 } 257 else 258 { 259 return false; 260 } 261 } 262}