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; 045 046/** 047 * This client site elements creates a button representing the validation state of a content's comment 048 */ 049public class ReportsClientSideElement extends StaticClientSideElement 050{ 051 /** The Ametys object resolver */ 052 protected AmetysObjectResolver _resolver; 053 /** The current user provider */ 054 protected CurrentUserProvider _userProvider; 055 /** The observation manager */ 056 protected ObservationManager _observationManager; 057 /** The content helper */ 058 private ContentHelper _contentHelper; 059 060 @Override 061 public void service(ServiceManager smanager) throws ServiceException 062 { 063 super.service(smanager); 064 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 065 _userProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE); 066 _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE); 067 _contentHelper = (ContentHelper) smanager.lookup(ContentHelper.ROLE); 068 } 069 070 /** 071 * Ignore reports on objects (contents or comments) when it is possible. 072 * @param reportedObjects the objects where to ignore reports 073 * @return the JSON result with contents and comments with ignored reports or not 074 */ 075 @Callable 076 public Map<String, Object> ignoreReports(List<Map<String, String>> reportedObjects) 077 { 078 List<Map<String, Object>> contentsWithIgnoredReports = new ArrayList<>(); 079 List<Map<String, Object>> commentsWithIgnoredReports = new ArrayList<>(); 080 List<Map<String, Object>> unknownContents = new ArrayList<>(); 081 List<Map<String, Object>> unknownComments = new ArrayList<>(); 082 List<Map<String, Object>> uncommentableContents = new ArrayList<>(); 083 List<Map<String, Object>> unreportableContents = new ArrayList<>(); 084 List<Map<String, Object>> noRightContents = new ArrayList<>(); 085 086 Map<String, Content> resolvedContentsById = new HashMap<>(); 087 Set<ModifiableContent> modifiedContents = new HashSet<>(); 088 089 UserIdentity currentUser = _userProvider.getUser(); 090 091 for (Map<String, String> reportedObject : reportedObjects) 092 { 093 String contentId = reportedObject.get("contentId"); 094 095 try 096 { 097 Content content = resolvedContentsById.get(contentId); 098 if (content == null) 099 { 100 content = _resolver.resolveById(contentId); 101 resolvedContentsById.put(contentId, content); 102 } 103 104 Map<String, Object> contentParams = _getContentParameters(content); 105 106 if (_rightManager.hasRight(currentUser, "CMS_Rights_CommentModerate", content) == RightResult.RIGHT_ALLOW) 107 { 108 if (reportedObject.containsKey("commentId")) 109 { 110 String commentId = reportedObject.get("commentId"); 111 Map<String, Object> commentParams = _getCommentParameters(commentId, content); 112 113 if (content instanceof CommentableContent) 114 { 115 CommentableContent cContent = (CommentableContent) content; 116 boolean ignored = _ignoreReportsOnComment(commentId, cContent, currentUser); 117 if (ignored) 118 { 119 modifiedContents.add(cContent); 120 commentsWithIgnoredReports.add(commentParams); 121 } 122 } 123 else 124 { 125 getLogger().error("Can not ignore reports on a comment on a non commentable content"); 126 uncommentableContents.add(contentParams); 127 } 128 } 129 else 130 { 131 if (content instanceof ReportableObject && content instanceof ModifiableContent) 132 { 133 boolean ignored = _ignoreReportsOnContent((ReportableObject) content, currentUser); 134 if (ignored) 135 { 136 modifiedContents.add((ModifiableContent) content); 137 contentsWithIgnoredReports.add(contentParams); 138 } 139 } 140 else 141 { 142 getLogger().error("Can not ignore reports on a non reportable content"); 143 unreportableContents.add(contentParams); 144 } 145 } 146 } 147 else 148 { 149 getLogger().error("User '" + currentUser + "' does not have right to ignore reports on content '" + content.getId() + "'"); 150 noRightContents.add(contentParams); 151 } 152 } 153 catch (UnknownAmetysObjectException e) 154 { 155 getLogger().error("Can not ignore reports on a comment on a non existing content", e); 156 unknownContents.add(Map.of("id", contentId)); 157 } 158 } 159 160 for (ModifiableContent modifiedContent : modifiedContents) 161 { 162 modifiedContent.saveChanges(); 163 } 164 165 return Map.of("contents-with-ignored-reports", contentsWithIgnoredReports, 166 "comments-with-ignored-reports", commentsWithIgnoredReports, 167 "unknown-contents", unknownContents, 168 "unknown-comments", unknownComments, 169 "uncommentable-contents", uncommentableContents, 170 "unreportable-contents", unreportableContents, 171 "noright-contents", noRightContents); 172 } 173 174 /** 175 * Retrieves the given content's parameters 176 * @param content the content 177 * @return the content's parameters 178 */ 179 protected Map<String, Object> _getContentParameters(Content content) 180 { 181 Map<String, Object> contentParams = new HashMap<>(); 182 contentParams.put("id", content.getId()); 183 contentParams.put("title", _contentHelper.getTitle(content)); 184 return contentParams; 185 } 186 187 /** 188 * Ignores the reports on the given content 189 * @param content the content 190 * @param currentUser the current user 191 * @return <code>true</code> if there are reports that have been ignored, <code>false</code> otherwise 192 */ 193 protected boolean _ignoreReportsOnContent(ReportableObject content, UserIdentity currentUser) 194 { 195 if (content.getReportsCount() > 0) 196 { 197 content.clearReports(); 198 199 Map<String, Object> eventParams = new HashMap<>(); 200 eventParams.put(ObservationConstants.ARGS_CONTENT, content); 201 _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_IGNORE_REPORTS, currentUser, eventParams)); 202 203 return true; 204 } 205 else 206 { 207 return false; 208 } 209 } 210 211 /** 212 * Retrieves the given comment's parameters 213 * @param commentId the comment identifier 214 * @param content the content of the comment 215 * @return the comment's parameters 216 */ 217 protected Map<String, Object> _getCommentParameters(String commentId, Content content) 218 { 219 Map<String, Object> commentParams = new HashMap<>(); 220 commentParams.put("id", commentId); 221 commentParams.put("contentId", content.getId()); 222 commentParams.put("contentTitle", _contentHelper.getTitle(content)); 223 return commentParams; 224 } 225 226 /** 227 * Ignores the reports on the given comment 228 * @param commentId the identifier of the comment 229 * @param content the content of the comment 230 * @param currentUser the current user 231 * @return <code>true</code> if there are reports that have been ignored, <code>false</code> otherwise 232 */ 233 protected boolean _ignoreReportsOnComment(String commentId, CommentableContent content, UserIdentity currentUser) 234 { 235 Comment comment = content.getComment(commentId); 236 237 if (comment.getReportsCount() > 0) 238 { 239 comment.clearReports(); 240 241 Map<String, Object> eventParams = new HashMap<>(); 242 eventParams.put(ObservationConstants.ARGS_CONTENT, content); 243 eventParams.put(ObservationConstants.ARGS_COMMENT, comment); 244 _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_COMMENT_IGNORE_REPORTS, currentUser, eventParams)); 245 246 return true; 247 } 248 else 249 { 250 return false; 251 } 252 } 253}