001/*
002 *  Copyright 2019 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.ugc.observation;
017
018import java.io.IOException;
019import java.text.DateFormat;
020import java.util.Collection;
021import java.util.Date;
022import java.util.HashMap;
023import java.util.Locale;
024import java.util.Map;
025
026import org.apache.avalon.framework.configuration.Configurable;
027import org.apache.avalon.framework.configuration.Configuration;
028import org.apache.avalon.framework.configuration.ConfigurationException;
029import org.apache.avalon.framework.logger.AbstractLogEnabled;
030import org.apache.avalon.framework.service.ServiceException;
031import org.apache.avalon.framework.service.ServiceManager;
032import org.apache.avalon.framework.service.Serviceable;
033import org.apache.commons.lang.StringUtils;
034
035import org.ametys.cms.contenttype.ContentTypesHelper;
036import org.ametys.cms.repository.Content;
037import org.ametys.core.observation.Event;
038import org.ametys.core.observation.Observer;
039import org.ametys.core.util.I18nUtils;
040import org.ametys.core.util.mail.SendMailHelper;
041import org.ametys.plugins.ugc.UGCConstants;
042import org.ametys.runtime.config.Config;
043import org.ametys.runtime.i18n.I18nizableText;
044import org.ametys.runtime.i18n.I18nizableTextParameter;
045import org.ametys.web.repository.content.WebContent;
046import org.ametys.web.repository.page.Page;
047import org.ametys.web.repository.site.Site;
048
049import jakarta.mail.MessagingException;
050
051/** 
052 * Abstract observer to send mail to UGC author on UGC content event
053 *
054 */
055public abstract class AbstractUGCContentObserver extends AbstractLogEnabled implements Observer, Serviceable, Configurable
056{
057    /** The content type helper */
058    protected ContentTypesHelper _cTypeHelper;
059    /** The i18n utils */
060    protected I18nUtils _i18nUtils;
061    
062    /** The i18n key for mail subject */
063    protected String _subjectI18nKey;
064    /** The i18n key for mail body */
065    protected String _bodyI18nKey;
066    
067    @Override
068    public void service(ServiceManager smanager) throws ServiceException
069    {
070        _cTypeHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE);
071        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
072    }
073    
074    public void configure(Configuration configuration) throws ConfigurationException
075    {
076        _subjectI18nKey = configuration.getChild("mailSubjectKey").getValue(null);
077        _bodyI18nKey = configuration.getChild("mailBodyKey").getValue(null);
078    }
079    
080    @Override
081    public int getPriority(Event event)
082    {
083        return MIN_PRIORITY;
084    }
085    
086    /**
087     * Send mail to the UGC author
088     * @param ugcContent The UGC content
089     * @param comment The comment. Can be null.
090     */
091    protected void sendMailToUGCAuthor(Content ugcContent, String comment)
092    {
093        String recipient = ugcContent.getValue(UGCConstants.ATTRIBUTE_PATH_UGC_MAIL, false, null);
094        
095        if (StringUtils.isNotBlank(recipient))
096        {
097            String sender = Config.getInstance().getValue("smtp.mail.from");
098            if (ugcContent instanceof WebContent)
099            {
100                Site site = ((WebContent) ugcContent).getSite();
101                sender = site.getValue("site-mail-from", false, Config.getInstance().getValue("smtp.mail.from"));
102            }
103            
104            String subject = getMailSubject(ugcContent);
105            String body = getMailBody(ugcContent, comment);
106            
107            try
108            {
109                SendMailHelper.newMail()
110                              .withSubject(subject)
111                              .withTextBody(body)
112                              .withSender(sender)
113                              .withRecipient(recipient)
114                              .withAsync(true)
115                              .sendMail();
116            }
117            catch (MessagingException | IOException e)
118            {
119                getLogger().warn("Fail to send UGC content notification mail to " + recipient, e);
120            }
121        }
122    }
123    
124    /**
125     * Get the mail subject
126     * @param ugcContent The UGC content
127     * @return the mail text subject
128     */
129    protected String getMailSubject (Content ugcContent)
130    {
131        I18nizableText subjectKey = new I18nizableText(null, _subjectI18nKey, getSubjectI18nParams(ugcContent));
132        return _i18nUtils.translate(subjectKey, null);
133    }
134    
135    /**
136     * Get the mail body
137     * @param ugcContent The UGC content
138     * @param comment The comment. Can be null.
139     * @return the mail text body
140     */
141    protected String getMailBody (Content ugcContent, String comment)
142    {
143        I18nizableText bodyKey = new I18nizableText(null, _bodyI18nKey, getBodyI18nParams(ugcContent, comment));
144        return _i18nUtils.translate(bodyKey, null);
145    }
146    
147    /**
148     * Get the i18n parameters for mail subject
149     * @param ugcContent The UGC content
150     * @return the i18n parameters for mail subject
151     */
152    protected Map<String, I18nizableTextParameter> getSubjectI18nParams(Content ugcContent)
153    {
154        Map<String, I18nizableTextParameter> params = new HashMap<>();
155        
156        params.put("contentTitle", new I18nizableText(ugcContent.getTitle()));
157        if (ugcContent instanceof WebContent)
158        {
159            Site site = ((WebContent) ugcContent).getSite();
160            params.put("siteTitle", new I18nizableText(site.getTitle()));
161        }
162        
163        return params;
164    }
165    
166    /**
167     * Get the i18n parameters for mail body
168     * @param ugcContent The UGC content
169     * @param comment The comment. Can be null.
170     * @return the i18n parameters for mail body
171     */
172    protected Map<String, I18nizableTextParameter> getBodyI18nParams(Content ugcContent, String comment)
173    {
174        Map<String, I18nizableTextParameter> params = new HashMap<>();
175        
176        String authorFullName = ugcContent.getValue(UGCConstants.ATTRIBUTE_PATH_UGC_AUTHOR, false, null);
177        params.put("authorFullName", new I18nizableText(authorFullName));
178        
179        params.put("contentTitle", new I18nizableText(ugcContent.getTitle()));
180        
181        if (ugcContent instanceof WebContent)
182        {
183            Site site = ((WebContent) ugcContent).getSite();
184            params.put("siteTitle", new I18nizableText(site.getTitle()));
185            params.put("siteUrl", new I18nizableText(site.getUrl()));
186            
187            Collection<Page> pages = ((WebContent) ugcContent).getReferencingPages();
188            if (!pages.isEmpty())
189            {
190                Page page = pages.iterator().next();
191                String uri = site.getUrl() + "/" + page.getSitemapName() + "/" + page.getPathInSitemap() + ".html";
192                params.put("uri", new I18nizableText(uri));
193            }
194        }
195        
196        Date creationDate = ugcContent.getCreationDate();
197        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, new Locale(ugcContent.getLanguage()));
198        params.put("creationDate", new I18nizableText(df.format(creationDate)));
199        
200        if (StringUtils.isNotBlank(comment))
201        {
202            params.put("comment", new I18nizableText(comment));
203        }
204        
205        return params;
206    }
207}