001/*
002 *  Copyright 2015 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.web.clientsideelement;
017
018import java.io.IOException;
019import java.util.ArrayList;
020import java.util.HashMap;
021import java.util.HashSet;
022import java.util.List;
023import java.util.Map;
024import java.util.Set;
025
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.commons.lang.StringUtils;
029
030import org.ametys.core.group.Group;
031import org.ametys.core.group.GroupIdentity;
032import org.ametys.core.group.GroupManager;
033import org.ametys.core.ui.Callable;
034import org.ametys.core.ui.ClientSideElement;
035import org.ametys.core.user.User;
036import org.ametys.core.user.UserIdentity;
037import org.ametys.core.user.UserManager;
038import org.ametys.core.util.I18nUtils;
039import org.ametys.core.util.mail.SendMailHelper;
040import org.ametys.plugins.core.user.UserHelper;
041import org.ametys.runtime.config.Config;
042import org.ametys.runtime.i18n.I18nizableText;
043import org.ametys.runtime.i18n.I18nizableTextParameter;
044import org.ametys.web.repository.page.Page;
045import org.ametys.web.repository.site.Site;
046
047import jakarta.mail.MessagingException;
048
049/**
050 * This {@link ClientSideElement} creates a button that will be enabled if page and its hierarchy is valid.
051 *
052 */
053public class LivePageClientSideElement extends AbstractPageClientSideElement
054{
055    /** The {@link UserManager} */
056    private UserManager _userManager;
057    
058    /** The {@link UserManager} for front-end users */
059    private UserManager _foUsersManager;
060    
061    /** The {@link GroupManager} for front-end groups */
062    private GroupManager _foGroupsManager;
063    
064    /** The {@link I18nUtils} */
065    private I18nUtils _i18nUtils;
066    
067    private UserHelper _userHelper;
068    
069    @Override
070    public void service(ServiceManager smanager) throws ServiceException
071    {
072        super.service(smanager);
073        _userManager = (UserManager) smanager.lookup(UserManager.ROLE);
074        _foUsersManager = (UserManager) smanager.lookup(UserManager.ROLE);
075        _foGroupsManager = (GroupManager) smanager.lookup(GroupManager.ROLE);
076        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
077        _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE);
078    }
079    
080    /**
081     * Send a notification for online pages.
082     * @param pageIds the ids of the pages
083     * @param users the users that will be notified
084     * @param groups the groups that will be notified
085     * @param comment the comment of the notifier 
086     * @return true 
087     */
088    @Callable
089    public boolean sendOnlineNotification(List<String> pageIds, List<Map<String, String>> users, List<Map<String, String>> groups, String comment)
090    { 
091        UserIdentity userIdentity = _currentUserProvider.getUser();
092        User notifier = _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin());
093        
094        List<UserIdentity> userIdentities = new ArrayList<>();
095        for (Map<String, String> user : users)
096        {
097            UserIdentity ui = _userHelper.json2userIdentity(user);
098            if (ui != null)
099            {
100                userIdentities.add(ui);
101            }
102        }
103        List<GroupIdentity> groupIdentities = new ArrayList<>();
104        for (Map<String, String> group : groups)
105        {
106            String id = group.get("groupId");
107            String groupDirectory = group.get("groupDirectory");
108            groupIdentities.add(new GroupIdentity(id, groupDirectory));
109        }
110        Set<User> distinctUsers = _getDistinctUsers (userIdentities, groupIdentities);
111        
112        for (String pageId : pageIds)
113        {
114            Page page = _resolver.resolveById(pageId);
115            
116            String from = _getSender(notifier, page);
117            String subject = _getSubject (notifier, page);
118            
119            for (User user : distinctUsers)
120            {
121                if (StringUtils.isNotEmpty(user.getEmail()))
122                {
123                    try
124                    {
125                        String body = _getBody(notifier, user, page, comment);
126                        
127                        SendMailHelper.newMail()
128                                      .withSubject(subject)
129                                      .withTextBody(body)
130                                      .withSender(from)
131                                      .withRecipient(user.getEmail())
132                                      .sendMail();
133                    }
134                    catch (MessagingException | IOException e) 
135                    {
136                        getLogger().error("Unable to send mail to user " + user.getEmail(), e);
137                    }
138                }
139            }
140        }
141        
142        return true;
143    }
144
145    /**
146     * Get the email sender
147     * @param sender The user responsible for the action
148     * @param page The published page
149     * @return The sender
150     */
151    private String _getSender (User sender, Page page)
152    {
153        if (sender != null && sender.getEmail() != null)
154        {
155            return sender.getFullName() + " <" + sender.getEmail() + ">";
156        }
157        
158        Site site = page.getSite();
159        String defaultFromValue = Config.getInstance().getValue("smtp.mail.from");
160        return site.getValue("site-mail-from", false, defaultFromValue);
161    }
162    
163    /**
164     * Get the email subject
165     * @param sender The user responsible for the notification
166     * @param page The published page
167     * @return The email subject
168     */
169    private String _getSubject (User sender, Page page)
170    {
171        Site site = page.getSite();
172        
173        Map<String, I18nizableTextParameter> subjectI18nParameters = new HashMap<>();
174        subjectI18nParameters.put("user", new I18nizableText(sender.getFullName()));
175        subjectI18nParameters.put("siteTitle", new I18nizableText(site.getTitle()));
176        subjectI18nParameters.put("pageTitle", new I18nizableText(page.getTitle()));
177        
178        I18nizableText msg = new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_SUBJECT", subjectI18nParameters);
179        
180        return _i18nUtils.translate(msg, page.getSitemapName());
181    }
182    
183    /**
184     * Get the email body
185     * @param sender The user responsible for the notification
186     * @param user The recipient of the notification
187     * @param page The published page
188     * @param comment The user's comment. Can be empty or null.
189     * @return The email body
190     */
191    private String _getBody (User sender, User user, Page page, String comment)
192    {
193        Site site = page.getSite();
194        
195        Map<String, I18nizableTextParameter> bodyI18nParameters = new HashMap<>();
196        bodyI18nParameters.put("sender", new I18nizableText(sender.getFullName()));
197        bodyI18nParameters.put("user", new I18nizableText(user.getFullName()));
198        bodyI18nParameters.put("siteTitle", new I18nizableText(site.getTitle()));
199        bodyI18nParameters.put("siteUrl", new I18nizableText(site.getUrl()));
200        bodyI18nParameters.put("pageTitle", new I18nizableText(page.getTitle()));
201        bodyI18nParameters.put("pageUrl", new I18nizableText(site.getUrl() + "/" + page.getSitemap().getName() + "/" + page.getPathInSitemap() + ".html"));
202
203        I18nizableText msg = null;
204        if (StringUtils.isNotEmpty(comment))
205        {
206            bodyI18nParameters.put("comment", new I18nizableText(comment));
207            msg = new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY_WITH_COMMENT", bodyI18nParameters);
208        }
209        else
210        {
211            msg = new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY", bodyI18nParameters);
212        }
213        
214        return _i18nUtils.translate(msg, page.getSitemapName());
215    }
216    
217    private Set<User> _getDistinctUsers (List<UserIdentity> userIdentities, List<GroupIdentity> groupIdentities)
218    {
219        Set<User> users = new HashSet<>();
220        
221        for (UserIdentity userIdentity : userIdentities)
222        {
223            if (userIdentity != null && StringUtils.isNotEmpty(userIdentity.getLogin()) && StringUtils.isNotEmpty(userIdentity.getPopulationId()))
224            {
225                User user = _foUsersManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin());
226                if (user != null)
227                {
228                    users.add(user);
229                }
230            }
231        }
232        
233        for (GroupIdentity groupIdentity : groupIdentities)
234        {
235            if (groupIdentity != null && StringUtils.isNotEmpty(groupIdentity.getId()) && StringUtils.isNotEmpty(groupIdentity.getDirectoryId()))
236            {
237                Group group = _foGroupsManager.getGroup(groupIdentity.getDirectoryId(), groupIdentity.getId());
238                if (group != null)
239                {
240                    Set<UserIdentity> groupUsers = group.getUsers();
241                    for (UserIdentity userIdentity : groupUsers)
242                    {
243                        User user = _foUsersManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin());
244                        if (user != null)
245                        {
246                            users.add(user);
247                        }
248                    }
249                }
250            }
251        }
252        
253        return users;
254    }
255}