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