001/* 002 * Copyright 2010 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.web.repository.comment; 018 019import java.util.ArrayList; 020import java.util.List; 021import java.util.Map; 022import java.util.Set; 023 024import javax.mail.MessagingException; 025 026import org.apache.avalon.framework.context.Context; 027import org.apache.avalon.framework.context.ContextException; 028import org.apache.avalon.framework.context.Contextualizable; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.avalon.framework.service.Serviceable; 032import org.apache.cocoon.components.ContextHelper; 033import org.apache.cocoon.environment.Request; 034import org.apache.commons.lang.StringUtils; 035 036import org.ametys.cms.ObservationConstants; 037import org.ametys.cms.content.ContentHelper; 038import org.ametys.cms.repository.Content; 039import org.ametys.cms.repository.comment.Comment; 040import org.ametys.core.observation.Event; 041import org.ametys.core.observation.Observer; 042import org.ametys.core.right.RightManager; 043import org.ametys.core.user.User; 044import org.ametys.core.user.UserIdentity; 045import org.ametys.core.user.UserManager; 046import org.ametys.core.user.population.PopulationContextHelper; 047import org.ametys.core.util.I18nUtils; 048import org.ametys.core.util.mail.SendMailHelper; 049import org.ametys.runtime.config.Config; 050import org.ametys.runtime.i18n.I18nizableText; 051import org.ametys.runtime.plugin.component.AbstractLogEnabled; 052import org.ametys.runtime.plugin.component.PluginAware; 053import org.ametys.web.repository.content.WebContent; 054import org.ametys.web.repository.site.Site; 055 056/** 057 * Listener to send mails to moderators or observers 058 */ 059public class SendMailToContributorCommentListener extends AbstractLogEnabled implements Observer, Serviceable, Contextualizable, PluginAware 060{ 061 /** The i18n utils of runtime */ 062 protected I18nUtils _i18nUtils; 063 /** The avalon context */ 064 protected Context _context; 065 /** The ametys rights manager */ 066 protected RightManager _rightManager; 067 /** The users manager. */ 068 protected UserManager _userManager; 069 /** The content helper */ 070 protected ContentHelper _contentHelper; 071 /** The plugin name */ 072 protected String _pluginName; 073 074 @Override 075 public void service(ServiceManager manager) throws ServiceException 076 { 077 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 078 _rightManager = (RightManager) manager.lookup(RightManager.ROLE); 079 _userManager = (UserManager) manager.lookup(UserManager.ROLE); 080 _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE); 081 } 082 083 @Override 084 public void contextualize(Context context) throws ContextException 085 { 086 _context = context; 087 } 088 089 public void setPluginInfo(String pluginName, String featureName, String id) 090 { 091 _pluginName = pluginName; 092 } 093 094 public int getPriority(Event event) 095 { 096 return MAX_PRIORITY; 097 } 098 099 @Override 100 public boolean supports(Event event) 101 { 102 return event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_VALIDATED) 103 || event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_REPORTED) 104 || event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_ADDED); 105 } 106 107 public void observe(Event event, Map<String, Object> transientVars) throws Exception 108 { 109 Map<String, Object> arguments = event.getArguments(); 110 Content content = (Content) arguments.get(ObservationConstants.ARGS_CONTENT); 111 Comment comment = (Comment) arguments.get(ObservationConstants.ARGS_COMMENT); 112 113 _setRequestAttributes (content); 114 115 if (event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_ADDED)) 116 { 117 _sendCommentAddedNotificationMail(content, comment); 118 } 119 else if (event.getId().equals(ObservationConstants.EVENT_CONTENT_COMMENT_REPORTED)) 120 { 121 UserIdentity issuer = event.getIssuer(); 122 _sendCommentReportedNotificationMail(content, comment, issuer); 123 } 124 else 125 { 126 _sendCommentValidatedNotificationMail(content, comment); 127 } 128 } 129 130 private void _setRequestAttributes (Content content) 131 { 132 Request request = ContextHelper.getRequest(_context); 133 134 if (content instanceof WebContent) 135 { 136 String siteName = ((WebContent) content).getSiteName(); 137 138 // Set the site name into the request for the other components to be able to retrieve it. 139 request.setAttribute("siteName", siteName); 140 141 List<String> populationContexts = new ArrayList<>(); 142 143 // Set the population contexts to be able to get allowed users 144 populationContexts.add("/sites/" + siteName); 145 populationContexts.add("/sites-fo/" + siteName); 146 147 request.setAttribute(PopulationContextHelper.POPULATION_CONTEXTS_REQUEST_ATTR, populationContexts); 148 } 149 } 150 151 private List<String> _getRecipients(Set<UserIdentity> users) 152 { 153 List<String> recipients = new ArrayList<>(); 154 155 for (UserIdentity userIdentity : users) 156 { 157 User user = _userManager.getUser(userIdentity); 158 if (user != null && StringUtils.isNotBlank(user.getEmail())) 159 { 160 recipients.add(user.getEmail()); 161 } 162 } 163 return recipients; 164 } 165 166 /** 167 * Send email notification on comment added 168 * @param content the content 169 * @param comment the added comment 170 */ 171 protected void _sendCommentAddedNotificationMail (Content content, Comment comment) 172 { 173 if (comment.isValidated()) 174 { 175 Set<UserIdentity> users = _rightManager.getAllowedUsers("CMS_Rights_CommentNotified", content).resolveAllowedUsers(Config.getInstance().getValue("runtime.mail.massive.sending")); 176 List<String> recipients = _getRecipients(users); 177 178 _sendMail(content, comment, recipients, "PLUGINS_WEB_CONTENT_COMMENTS_NOTIFICATION_SUBJECT", "PLUGINS_WEB_CONTENT_COMMENTS_NOTIFICATION_BODY"); 179 } 180 else 181 { 182 // Determine the list of listeners 183 Set<UserIdentity> users = _rightManager.getAllowedUsers("CMS_Rights_CommentModerate", content).resolveAllowedUsers(Config.getInstance().getValue("runtime.mail.massive.sending")); 184 List<String> recipients = _getRecipients(users); 185 186 _sendMail(content, comment, recipients, "PLUGINS_WEB_CONTENT_COMMENTS_MODERATION_SUBJECT", "PLUGINS_WEB_CONTENT_COMMENTS_MODERATION_BODY"); 187 } 188 } 189 190 /** 191 * Send email notification on comment validated 192 * @param content the content 193 * @param comment the validated comment 194 */ 195 protected void _sendCommentValidatedNotificationMail (Content content, Comment comment) 196 { 197 Set<UserIdentity> users = _rightManager.getAllowedUsers("CMS_Rights_CommentNotified", content).resolveAllowedUsers(Config.getInstance().getValue("runtime.mail.massive.sending")); 198 List<String> recipients = _getRecipients(users); 199 200 _sendMail(content, comment, recipients, "PLUGINS_WEB_CONTENT_COMMENTS_NOTIFICATION_SUBJECT", "PLUGINS_WEB_CONTENT_COMMENTS_NOTIFICATION_BODY"); 201 } 202 203 /** 204 * Send email notification on comment report 205 * @param content the content 206 * @param comment the reported comment 207 * @param issuer the issuer 208 */ 209 protected void _sendCommentReportedNotificationMail (Content content, Comment comment, UserIdentity issuer) 210 { 211 Set<UserIdentity> users = _rightManager.getAllowedUsers("CMS_Rights_CommentNotified", content).resolveAllowedUsers(Config.getInstance().getValue("runtime.mail.massive.sending")); 212 List<String> recipients = _getRecipients(users); 213 214 List<String> i18nParams = _getCommonBodyI18nParams(content, comment); 215 User issuerAsUser = _userManager.getUser(issuer); 216 i18nParams.add(issuerAsUser.getFullName()); // {6} 217 218 _sendMail(content, comment, recipients, "PLUGINS_WEB_CONTENT_COMMENTS_REPORTED_SUBJECT", "PLUGINS_WEB_CONTENT_COMMENTS_REPORTED_BODY"); 219 } 220 221 /** 222 * Send notification on comment to contributor 223 * @param content the content 224 * @param comment the modified comment 225 * @param recipients the list of recipients 226 * @param subjectI18nKey the i18n for email subject 227 * @param bodyI18nKey the i18n for email body 228 */ 229 protected void _sendMail(Content content, Comment comment, List<String> recipients, String subjectI18nKey, String bodyI18nKey) 230 { 231 _sendMail(content, comment, recipients, subjectI18nKey, bodyI18nKey, _getCommonBodyI18nParams(content, comment)); 232 } 233 234 /** 235 * Send notification on comment to contributor 236 * @param content the content 237 * @param comment the modified comment 238 * @param recipients the list of recipients 239 * @param subjectI18nKey the i18n for email subject 240 * @param bodyI18nKey the i18n for email body 241 * @param i18nParams the i18n parameters 242 */ 243 protected void _sendMail(Content content, Comment comment, List<String> recipients, String subjectI18nKey, String bodyI18nKey, List<String> i18nParams) 244 { 245 getLogger().debug("Send email notification to '{}' for his comment '{}' on content '{}'", comment.getAuthorEmail(), comment.getId(), content.getId()); 246 247 I18nizableText i18nSubject = new I18nizableText("plugin." + _pluginName, subjectI18nKey, i18nParams); 248 String subject = _i18nUtils.translate(i18nSubject, content.getLanguage()); 249 250 I18nizableText i18nBody = new I18nizableText("plugin." + _pluginName, bodyI18nKey, i18nParams); 251 String body = _i18nUtils.translate(i18nBody, content.getLanguage()); 252 253 String from = Config.getInstance().getValue("smtp.mail.from"); 254 if (content instanceof WebContent) 255 { 256 Site site = ((WebContent) content).getSite(); 257 from = site.getValue("site-mail-from"); 258 } 259 260 try 261 { 262 SendMailHelper.sendMail(subject, null, body, recipients, from, true); 263 } 264 catch (MessagingException e) 265 { 266 getLogger().warn("Could not send a notification mail to {}", recipients, e); 267 } 268 } 269 270 /** 271 * The comment i18n parameters for email notification 272 * @param content the content 273 * @param comment the comment 274 * @return the i18n parameters 275 */ 276 protected List<String> _getCommonBodyI18nParams(Content content, Comment comment) 277 { 278 List<String> i18nparam = new ArrayList<>(); 279 280 i18nparam.add(_contentHelper.getTitle(content)); // {0} 281 i18nparam.add(_getContentURI(content)); // {1} 282 i18nparam.add(comment.getAuthorName()); // {2} 283 i18nparam.add(comment.getContent()); // {3} 284 285 if (content instanceof WebContent) 286 { 287 Site site = ((WebContent) content).getSite(); 288 i18nparam.add(site.getName()); // {4} 289 i18nparam.add(site.getTitle()); // {5} 290 } 291 292 return i18nparam; 293 } 294 295 /** 296 * Get the content URI in back-office 297 * @param content the content 298 * @return the content uri 299 */ 300 protected String _getContentURI(Content content) 301 { 302 String cmsUrl = StringUtils.stripEnd(StringUtils.removeEndIgnoreCase(Config.getInstance().getValue("cms.url"), "index.html"), "/"); 303 304 StringBuilder url = new StringBuilder(cmsUrl); 305 306 if (content instanceof WebContent) 307 { 308 Site site = ((WebContent) content).getSite(); 309 url.append("/").append(site.getName()); 310 } 311 url.append("/index.html?uitool=uitool-content,id:%27").append(content.getId()).append("%27"); 312 return url.toString(); 313 } 314}