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}