001/* 002 * Copyright 2024 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 */ 016package org.ametys.plugins.workspaces.comments; 017 018import java.io.IOException; 019import java.util.List; 020import java.util.Map; 021 022import org.apache.avalon.framework.context.Context; 023import org.apache.avalon.framework.context.ContextException; 024import org.apache.avalon.framework.context.Contextualizable; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.cocoon.components.ContextHelper; 028import org.apache.cocoon.environment.Request; 029 030import org.ametys.cms.repository.mentions.AbstractNotifyMentionsObserver; 031import org.ametys.core.observation.Event; 032import org.ametys.core.right.RightManager; 033import org.ametys.core.user.User; 034import org.ametys.core.user.UserIdentity; 035import org.ametys.core.util.StringUtils; 036import org.ametys.plugins.workspaces.ObservationConstants; 037import org.ametys.plugins.workspaces.WorkspacesHelper; 038import org.ametys.plugins.workspaces.forum.ForumWorkspaceModule; 039import org.ametys.plugins.workspaces.forum.Thread; 040import org.ametys.plugins.workspaces.forum.json.ThreadJSONHelper; 041import org.ametys.plugins.workspaces.project.ProjectManager; 042import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint; 043import org.ametys.plugins.workspaces.project.objects.Project; 044import org.ametys.plugins.workspaces.project.rights.ProjectRightHelper; 045import org.ametys.runtime.i18n.I18nizableText; 046import org.ametys.web.WebConstants; 047import org.ametys.web.renderingcontext.RenderingContext; 048import org.ametys.web.renderingcontext.RenderingContextHandler; 049 050/** 051 * Observer to send mails to mentioned users in content of {@link Thread} 052 */ 053public class NotifyThreadMentionsObserver extends AbstractNotifyMentionsObserver<Thread> implements Contextualizable 054{ 055 056 /** The right manager */ 057 protected RightManager _rightManager; 058 059 /** The forum module */ 060 protected ForumWorkspaceModule _forumModule; 061 062 /** The project manager */ 063 protected ProjectManager _projectManager; 064 065 /** The project tags DAO */ 066 protected ThreadJSONHelper _threadJSONHelper; 067 068 /** The Avalon context */ 069 protected Context _context; 070 071 /** The Workspaces helper */ 072 protected WorkspacesHelper _workspaceHelper; 073 074 /** The project rights helper */ 075 protected ProjectRightHelper _projectRightsHelper; 076 077 /** The rendering context handler */ 078 protected RenderingContextHandler _renderingContextHandler; 079 080 @Override 081 public void service(ServiceManager manager) throws ServiceException 082 { 083 super.service(manager); 084 _rightManager = (RightManager) manager.lookup(RightManager.ROLE); 085 WorkspaceModuleExtensionPoint moduleManagerEP = (WorkspaceModuleExtensionPoint) manager.lookup(WorkspaceModuleExtensionPoint.ROLE); 086 _forumModule = moduleManagerEP.getModule(ForumWorkspaceModule.FORUM_MODULE_ID); 087 _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE); 088 _threadJSONHelper = (ThreadJSONHelper) manager.lookup(ThreadJSONHelper.ROLE); 089 _workspaceHelper = (WorkspacesHelper) manager.lookup(WorkspacesHelper.ROLE); 090 _projectRightsHelper = (ProjectRightHelper) manager.lookup(ProjectRightHelper.ROLE); 091 _renderingContextHandler = (RenderingContextHandler) manager.lookup(RenderingContextHandler.ROLE); 092 } 093 094 public void contextualize(Context context) throws ContextException 095 { 096 _context = context; 097 } 098 099 @Override 100 public void observe(Event event, Map<String, Object> transientVars) throws Exception 101 { 102 Map<String, Object> arguments = event.getArguments(); 103 104 Thread thread = (Thread) arguments.get(ObservationConstants.ARGS_THREAD); 105 Project project = _projectManager.getParentProject(thread); 106 Request request = ContextHelper.getRequest(_context); 107 request.setAttribute(WebConstants.REQUEST_ATTR_SITE_NAME, project.getName()); 108 super.observe(event, transientVars); 109 } 110 111 public boolean supports(Event event) 112 { 113 return event.getId().equals(ObservationConstants.EVENT_THREAD_CREATED); 114 } 115 116 @Override 117 protected I18nizableText _getMailTitle(MentionableObject mentionableObject) 118 { 119 Thread thread = (Thread) mentionableObject.ametysObject(); 120 Project project = _projectManager.getParentProject(thread); 121 122 List<String> i18nParams = List.of(project.getTitle()); 123 124 return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_WORKSPACES_MENTION_MAIL_SUBJECT", i18nParams); 125 } 126 127 @Override 128 protected I18nizableText _getMailSubject(MentionableObject mentionableObject) 129 { 130 Project project = _projectManager.getParentProject(mentionableObject.ametysObject()); 131 List<String> i18nParams = List.of(project.getTitle()); 132 return new I18nizableText("plugin.cms", "PLUGINS_CMS_AMETYS_OBJECT_THREAD_MENTION_MAIL_SUBJECT", i18nParams); 133 } 134 135 @Override 136 protected MentionableObject _getMentionableObjectFromArguments(Map<String, Object> arguments) throws Exception 137 { 138 Thread thread = (Thread) arguments.get(ObservationConstants.ARGS_THREAD); 139 thread = _resolver.resolveById(thread.getId()); 140 Project project = _projectManager.getParentProject(thread); 141 String content = _getContentFromThread(thread); 142 String url = _getUrl(thread, project); 143 144 return new MentionableObject( 145 _userManager.getUser(thread.getAuthor()), 146 content, 147 _mentionUtils.extractMentionedUsersFromRichText(content), 148 thread.getCreationDate(), 149 thread, 150 new LinkToAmetysObject(url, new I18nizableText("plugin.workspaces", "PROJECT_MAIL_NOTIFICATION_BODY_FORUMTHREAD_BUTTON_TEXT")), 151 _workspaceHelper.getLang(project) 152 ); 153 } 154 155 private String _getContentFromThread(Thread thread) throws IOException 156 { 157 Request request = ContextHelper.getRequest(_context); 158 String siteName = (String) request.getAttribute("site"); 159 Project project = _projectManager.getParentProject(thread); 160 if (siteName == null) 161 { 162 request.setAttribute("site", project.getSite().getName()); 163 } 164 return _threadJSONHelper.richTextToRendering(thread.getContent()); 165 } 166 167 private String _getAmetysObjectTitle(Thread thread) 168 { 169 return thread.getTitle(); 170 } 171 172 @Override 173 protected String _transformSyntaxTextToReadableTextWithColors(String content, UserIdentity recipient) 174 { 175 return _mentionUtils.transformRichTextToReadableText(content, recipient); 176 } 177 178 @Override 179 protected I18nizableText _getMailMessageType() 180 { 181 return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_THREAD_MENTION_MAIL_DESCRIPTION_TITLE"); 182 } 183 184 @Override 185 protected I18nizableText _getMailMessage(MentionableObject mentionableObject) 186 { 187 Thread thread = (Thread) mentionableObject.ametysObject(); 188 Project project = _projectManager.getParentProject(thread); 189 User author = mentionableObject.author(); 190 List<String> i18nParams = List.of(StringUtils.escapeHTML(author.getFullName()), StringUtils.escapeHTML(_getAmetysObjectTitle(thread)), StringUtils.escapeHTML(project.getTitle())); 191 return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_THREAD_MENTION_MAIL_MESSAGE", i18nParams); 192 } 193 194 @Override 195 protected boolean _canSendMailToMentionedUser(Thread thread, User authorIdentity, UserIdentity mentionedUserIdentity) 196 { 197 Project project = _projectManager.getParentProject(thread); 198 199 return super._canSendMailToMentionedUser(thread, authorIdentity, mentionedUserIdentity) 200 && _projectRightsHelper.hasReadAccessOnModule(project, ForumWorkspaceModule.FORUM_MODULE_ID, mentionedUserIdentity); 201 } 202 203 private String _getUrl(Thread thread, Project project) 204 { 205 Request request = ContextHelper.getRequest(_context); 206 request.setAttribute("forceAbsoluteUrl", true); 207 208 RenderingContext currentContext = _renderingContextHandler.getRenderingContext(); 209 _renderingContextHandler.setRenderingContext(RenderingContext.FRONT); 210 211 try 212 { 213 return _forumModule.getThreadUri(project, thread.getId()); 214 } 215 finally 216 { 217 _renderingContextHandler.setRenderingContext(currentContext); 218 } 219 } 220}