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.util.List;
019import java.util.Map;
020
021import org.apache.avalon.framework.context.Context;
022import org.apache.avalon.framework.context.ContextException;
023import org.apache.avalon.framework.context.Contextualizable;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.components.ContextHelper;
027import org.apache.cocoon.environment.Request;
028
029import org.ametys.cms.repository.CommentableAmetysObject;
030import org.ametys.cms.repository.comment.contributor.AbstractCommentNotifyMentionsObserver;
031import org.ametys.core.observation.Event;
032import org.ametys.core.right.RightManager;
033import org.ametys.core.ui.mail.StandardMailBodyHelper.MailBodyBuilder;
034import org.ametys.core.user.User;
035import org.ametys.core.user.UserIdentity;
036import org.ametys.plugins.repository.AmetysObject;
037import org.ametys.plugins.workspaces.WorkspacesHelper;
038import org.ametys.plugins.workspaces.documents.DocumentWorkspaceModule;
039import org.ametys.plugins.workspaces.project.ProjectManager;
040import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint;
041import org.ametys.plugins.workspaces.project.objects.Project;
042import org.ametys.plugins.workspaces.project.rights.ProjectRightHelper;
043import org.ametys.plugins.workspaces.tasks.TasksWorkspaceModule;
044import org.ametys.runtime.i18n.I18nizableText;
045import org.ametys.web.WebConstants;
046import org.ametys.web.mail.StandardWebMailBodyHelper;
047import org.ametys.web.renderingcontext.RenderingContext;
048import org.ametys.web.renderingcontext.RenderingContextHandler;
049
050/**
051 * Observer to send mails to mentioned users in contributor comments of workspaces objects
052 * @param <T> type of the {@link CommentableAmetysObject}
053 */
054public abstract class AbstractNotifyWorkspacesCommentMentionsObserver<T extends CommentableAmetysObject> extends AbstractCommentNotifyMentionsObserver<T> implements Contextualizable
055{
056    /** The right manager */
057    protected RightManager _rightManager;
058
059    /** The project manager */
060    protected ProjectManager _projectManager;
061
062    /** The task module */
063    protected TasksWorkspaceModule _taskModule;
064    
065    /** The document module */
066    protected DocumentWorkspaceModule _documentModule;
067
068    /** The Workspaces helper */
069    protected WorkspacesHelper _workspaceHelper;
070    
071    /** The context */
072    protected Context _context;
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        _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE);
086        WorkspaceModuleExtensionPoint moduleManagerEP = (WorkspaceModuleExtensionPoint) manager.lookup(WorkspaceModuleExtensionPoint.ROLE);
087        _taskModule = moduleManagerEP.getModule(TasksWorkspaceModule.TASK_MODULE_ID);
088        _documentModule = moduleManagerEP.getModule(DocumentWorkspaceModule.DOCUMENT_MODULE_ID);
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        AmetysObject ametysObject = _getAmetysObjectFromArguments(arguments);
105        Project project = _projectManager.getParentProject(ametysObject);
106        Request request = ContextHelper.getRequest(_context);
107        request.setAttribute(WebConstants.REQUEST_ATTR_SITE_NAME, project.getName());
108        super.observe(event, transientVars);
109    }
110    
111    /**
112     * Get the language of the project containing the given object
113     * @param project the project
114     * @return the language code
115     */
116    protected String _getLanguage(Project project)
117    {
118        return _workspaceHelper.getLang(project);
119    }
120    
121    /**
122     * Get the Ametys object from the event arguments
123     * @param arguments the event arguments
124     * @return the Ametys object
125     */
126    protected T _getAmetysObjectFromArguments(Map<String, Object> arguments)
127    {
128        String ametysObjectId = (String) arguments.get(org.ametys.plugins.explorer.ObservationConstants.ARGS_ID);
129        T ametysObject = _resolver.resolveById(ametysObjectId);
130        return ametysObject;
131    }
132
133    @Override
134    protected MailBodyBuilder getStandardMailBodyHelper()
135    {
136        return StandardWebMailBodyHelper.newHTMLBody();
137    }
138
139    @Override
140    protected I18nizableText _getMailSubject(MentionableObject mentionableObject)
141    {
142        Project project = _projectManager.getParentProject(mentionableObject.ametysObject());
143        List<String> i18nParams = List.of(project.getTitle());
144        return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_WORKSPACES_MENTION_MAIL_TITLE", i18nParams);
145    }
146    
147    @Override
148    protected I18nizableText _getMailTitle(MentionableObject mentionableObject)
149    {
150        AmetysObject ametysObject = mentionableObject.ametysObject();
151        Project project = _projectManager.getParentProject(ametysObject);
152
153        List<String> i18nParams = List.of(project.getTitle());
154        return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_WORKSPACES_MENTION_MAIL_SUBJECT", i18nParams);
155    }
156    
157    @Override
158    protected boolean _canSendMailToMentionedUser(T ametysObject, User authorIdentity, UserIdentity mentionedUserIdentity)
159    {
160        Project project = _projectManager.getParentProject(ametysObject);
161        
162        return super._canSendMailToMentionedUser(ametysObject, authorIdentity, mentionedUserIdentity)
163            && _projectRightsHelper.hasReadAccessOnModule(project, _getModuleId(), mentionedUserIdentity);
164    }
165
166    /**
167     * Get the module id to check read access
168     * @return the module id
169     */
170    protected abstract String _getModuleId();
171
172    
173    /**
174     * Get the absolute URL of the given Ametys object in the context of the given project
175     * @param ametysObject the Ametys object
176     * @param project the project containing the Ametys object
177     * @return the absolute URL
178     */
179    protected String _getAbsoluteUrl(T ametysObject, Project project)
180    {
181        Request request = ContextHelper.getRequest(_context);
182        request.setAttribute("forceAbsoluteUrl", true);
183        
184        RenderingContext currentContext = _renderingContextHandler.getRenderingContext();
185        _renderingContextHandler.setRenderingContext(RenderingContext.FRONT);
186        
187        try
188        {
189            return getUrl(ametysObject, project);
190        }
191        finally
192        {
193            _renderingContextHandler.setRenderingContext(currentContext);
194        }
195    }
196
197    /**
198     * Get the URL of the given Ametys object in the context of the given project
199     * @param ametysObject the Ametys object
200     * @param project the project containing the Ametys object
201     * @return the URL (may be relative or absolute depending on the implementation)
202     */
203    protected abstract String getUrl(T ametysObject, Project project);
204    
205}