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