001/* 002 * Copyright 2018 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.members; 017 018import java.io.IOException; 019import java.io.UnsupportedEncodingException; 020import java.net.URLEncoder; 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Date; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027import java.util.Set; 028 029import javax.jcr.RepositoryException; 030 031import org.apache.avalon.framework.component.Component; 032import org.apache.avalon.framework.configuration.Configurable; 033import org.apache.avalon.framework.configuration.Configuration; 034import org.apache.avalon.framework.configuration.ConfigurationException; 035import org.apache.avalon.framework.context.Context; 036import org.apache.avalon.framework.context.ContextException; 037import org.apache.avalon.framework.context.Contextualizable; 038import org.apache.avalon.framework.service.ServiceException; 039import org.apache.avalon.framework.service.ServiceManager; 040import org.apache.avalon.framework.service.Serviceable; 041import org.apache.cocoon.components.ContextHelper; 042import org.apache.cocoon.environment.Request; 043import org.apache.commons.lang3.StringUtils; 044 045import org.ametys.cms.languages.Language; 046import org.ametys.cms.languages.LanguagesManager; 047import org.ametys.cms.transformation.xslt.ResolveURIComponent; 048import org.ametys.core.ui.Callable; 049import org.ametys.core.user.CurrentUserProvider; 050import org.ametys.core.user.User; 051import org.ametys.core.user.UserIdentity; 052import org.ametys.core.user.UserManager; 053import org.ametys.core.user.directory.NotUniqueUserException; 054import org.ametys.core.user.population.PopulationContextHelper; 055import org.ametys.core.util.I18nUtils; 056import org.ametys.core.util.mail.SendMailHelper; 057import org.ametys.plugins.core.user.UserHelper; 058import org.ametys.plugins.repository.AmetysObjectIterable; 059import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector; 060import org.ametys.plugins.workspaces.members.MembersWorkspaceModule.Invitation; 061import org.ametys.plugins.workspaces.project.ProjectManager; 062import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint; 063import org.ametys.plugins.workspaces.project.objects.Project; 064import org.ametys.plugins.workspaces.project.rights.ProjectRightHelper; 065import org.ametys.runtime.authentication.AccessDeniedException; 066import org.ametys.runtime.i18n.I18nizableText; 067import org.ametys.runtime.i18n.I18nizableTextParameter; 068import org.ametys.runtime.plugin.component.AbstractLogEnabled; 069import org.ametys.runtime.plugin.component.PluginAware; 070import org.ametys.web.WebConstants; 071import org.ametys.web.WebHelper; 072import org.ametys.web.repository.page.Page; 073import org.ametys.web.repository.page.Zone; 074import org.ametys.web.repository.page.ZoneItem; 075import org.ametys.web.repository.page.ZoneItem.ZoneType; 076import org.ametys.web.repository.site.Site; 077import org.ametys.web.repository.site.SiteManager; 078import org.ametys.web.usermanagement.UserManagementException; 079import org.ametys.web.usermanagement.UserSignUpConfiguration; 080import org.ametys.web.usermanagement.UserSignupManager; 081 082import jakarta.mail.MessagingException; 083 084/** 085 * Helper for invitations by email 086 * 087 */ 088public class ProjectInvitationHelper extends AbstractLogEnabled implements Serviceable, Component, Configurable, PluginAware, Contextualizable 089{ 090 /** The role */ 091 public static final String ROLE = ProjectInvitationHelper.class.getName(); 092 093 private static final String __MAIL_PROJECT_EMAIL_PATTERN = "${email}"; 094 private static final String __MAIL_PROJECT_TOKEN_PATTERN = "${token}"; 095 096 private ProjectManager _projectManager; 097 private UserSignUpConfiguration _signupConfig; 098 private UserSignupManager _signupManager; 099 private SiteManager _siteManager; 100 private WorkspaceModuleExtensionPoint _moduleEP; 101 private CurrentUserProvider _currentUserProvider; 102 private UserManager _userManager; 103 private UserHelper _userHelper; 104 private ProjectRightHelper _projectRightsHelper; 105 private ProjectMemberManager _projectMemberManager; 106 private PopulationContextHelper _populationContextHelper; 107 private LanguagesManager _languagesManager; 108 109 private String _subjectKeyForInvitation; 110 private String _textBodyKeyForInvitation; 111 private String _htmlBodyKeyForInvitation; 112 private String _subjectKeyForInvitationAccepted; 113 private String _textBodyKeyForInvitationAccepted; 114 private String _htmlBodyKeyForInvitationAccepted; 115 116 private I18nUtils _i18nUtils; 117 118 private String _pluginName; 119 120 private Context _context; 121 122 123 public void setPluginInfo(String pluginName, String featureName, String id) 124 { 125 _pluginName = pluginName; 126 } 127 128 public void contextualize(Context context) throws ContextException 129 { 130 _context = context; 131 } 132 133 @Override 134 public void service(ServiceManager serviceManager) throws ServiceException 135 { 136 _projectManager = (ProjectManager) serviceManager.lookup(ProjectManager.ROLE); 137 _projectRightsHelper = (ProjectRightHelper) serviceManager.lookup(ProjectRightHelper.ROLE); 138 _projectMemberManager = (ProjectMemberManager) serviceManager.lookup(ProjectMemberManager.ROLE); 139 _signupConfig = (UserSignUpConfiguration) serviceManager.lookup(UserSignUpConfiguration.ROLE); 140 _signupManager = (UserSignupManager) serviceManager.lookup(UserSignupManager.ROLE); 141 _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE); 142 _moduleEP = (WorkspaceModuleExtensionPoint) serviceManager.lookup(WorkspaceModuleExtensionPoint.ROLE); 143 _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE); 144 _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE); 145 _userHelper = (UserHelper) serviceManager.lookup(UserHelper.ROLE); 146 _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE); 147 _populationContextHelper = (PopulationContextHelper) serviceManager.lookup(PopulationContextHelper.ROLE); 148 _languagesManager = (LanguagesManager) serviceManager.lookup(LanguagesManager.ROLE); 149 } 150 151 @Override 152 public void configure(Configuration configuration) throws ConfigurationException 153 { 154 _subjectKeyForInvitation = configuration.getChild("invitation-email-subject").getValue(null); 155 _textBodyKeyForInvitation = configuration.getChild("invitation-email-text-body").getValue(null); 156 _htmlBodyKeyForInvitation = configuration.getChild("invitation-email-html-body").getValue(null); 157 158 _subjectKeyForInvitationAccepted = configuration.getChild("invitation-accepted-email-subject").getValue(null); 159 _textBodyKeyForInvitationAccepted = configuration.getChild("invitation-accepted-email-text-body").getValue(null); 160 _htmlBodyKeyForInvitationAccepted = configuration.getChild("invitation-accepted-email-html-body").getValue(null); 161 } 162 163 /** 164 * Invite emails to be member of a project 165 * @param projectName The project name 166 * @param emails The emails 167 * @param allowedProfileByModule the allowed profiles by module 168 * @return The result 169 * @throws UserManagementException if failed to invit user 170 * @throws NotUniqueUserException if many users match the given email 171 */ 172 public Map<String, Object> inviteEmails(String projectName, List<String> emails, Map<String, String> allowedProfileByModule) throws UserManagementException, NotUniqueUserException 173 { 174 Request request = ContextHelper.getRequest(_context); 175 String siteName = WebHelper.getSiteName(request); 176 String sitemapLanguage = (String) request.getAttribute(WebConstants.REQUEST_ATTR_SITEMAP_NAME); 177 178 Project project = _projectManager.getProject(projectName); 179 Map<String, String> emailConfiguration = _getInvitationEmailConfiguration(project, sitemapLanguage); 180 String mailSubject = emailConfiguration.get("subject"); 181 String mailBody = emailConfiguration.get("bodyText"); 182 183 return inviteEmails(projectName, siteName, sitemapLanguage, emails, allowedProfileByModule, mailSubject, mailBody); 184 } 185 /** 186 * Invite emails to be member of a project 187 * @param projectName The project name 188 * @param siteName The site name 189 * @param lang the current language 190 * @param emails The emails 191 * @param allowedProfileByModule the allowed profiles by module 192 * @param mailSubject The subject of mail 193 * @param mailBody The body of mail 194 * @return The result 195 * @throws UserManagementException if failed to invit user 196 * @throws NotUniqueUserException if many users match the given email 197 */ 198 @Callable 199 public Map<String, Object> inviteEmails(String projectName, String siteName, String lang, List<String> emails, Map<String, String> allowedProfileByModule, String mailSubject, String mailBody) throws UserManagementException, NotUniqueUserException 200 { 201 Map<String, Object> result = new HashMap<>(); 202 203 result.put("existing-users", new ArrayList<Map<String, Object>>()); 204 result.put("email-success", new ArrayList<String>()); 205 result.put("email-error", new ArrayList<String>()); 206 207 Project project = _projectManager.getProject(projectName); 208 if (project != null) 209 { 210 MembersWorkspaceModule module = _moduleEP.getModule(MembersWorkspaceModule.MEMBERS_MODULE_ID); 211 if (module != null && _projectManager.isModuleActivated(project, module.getId())) 212 { 213 if (!_projectRightsHelper.canAddMember(project)) 214 { 215 throw new AccessDeniedException("User '" + _currentUserProvider.getUser() + "' tried to send invitations without sufficient right."); 216 } 217 218 String catalogSiteName = _projectManager.getCatalogSiteName(); 219 220 String userDirectoryAsStr = _getUserDirectoryForSignup(result, catalogSiteName, lang); 221 if (userDirectoryAsStr != null) 222 { 223 String populationId = StringUtils.substringBeforeLast(userDirectoryAsStr, "#"); 224 String userDirectoryId = StringUtils.substringAfterLast(userDirectoryAsStr, "#"); 225 226 for (String email : emails) 227 { 228 try 229 { 230 if (!_signupManager.userExists(email, catalogSiteName)) 231 { 232 _signupManager.temporarySignup(siteName, lang, email, populationId, userDirectoryId); 233 234 // Whatever or not the mail has already been invited, re-created the invitation 235 if (_addOrUpdateInvitation(project, catalogSiteName, module, email, allowedProfileByModule, populationId, userDirectoryId, mailSubject, mailBody)) 236 { 237 @SuppressWarnings("unchecked") 238 List<String> emailSuccess = (List<String>) result.get("email-success"); 239 emailSuccess.add(email); 240 241 } 242 else 243 { 244 @SuppressWarnings("unchecked") 245 List<String> emailErrors = (List<String>) result.get("email-error"); 246 emailErrors.add(email); 247 } 248 } 249 else 250 { 251 User user = _getUser(catalogSiteName, email); 252 253 Map<String, Object> user2json = _userHelper.user2json(user, true); 254 255 @SuppressWarnings("unchecked") 256 List<Map<String, Object>> existingUsers = (List<Map<String, Object>>) result.get("existing-users"); 257 existingUsers.add(user2json); 258 } 259 } 260 catch (UserManagementException e) 261 { 262 getLogger().error("Cannot invite " + email, e); 263 @SuppressWarnings("unchecked") 264 List<String> emailErrors = (List<String>) result.get("email-error"); 265 emailErrors.add(email); 266 } 267 } 268 269 @SuppressWarnings("unchecked") 270 List<String> emailSuccess = (List<String>) result.get("email-success"); 271 if (emailSuccess.size() == emails.size()) 272 { 273 result.put("success", true); 274 } 275 } 276 } 277 } 278 else 279 { 280 result.put("success", false); 281 result.put("unknown-project", projectName); 282 } 283 284 return result; 285 } 286 287 private User _getUser(String siteName, String email) throws NotUniqueUserException 288 { 289 Set<String> populations = _populationContextHelper.getUserPopulationsOnContexts(Arrays.asList("/sites/" + siteName, "/sites-fo/" + siteName), false); 290 for (String population : populations) 291 { 292 User user = _userManager.getUser(population, email); 293 if (user == null) 294 { 295 user = _userManager.getUserByEmail(population, email); 296 } 297 298 if (user != null) 299 { 300 return user; 301 } 302 } 303 304 return null; 305 } 306 307 /** 308 * Get the configuration to invite users by emails 309 * @param projectName The current project 310 * @param lang the current language 311 * @return the configuration for email invitations 312 */ 313 @Callable 314 public Map<String, Object> getInvitationConfiguration(String projectName, String lang) 315 { 316 Project project = _projectManager.getProject(projectName); 317 318 Map<String, Object> config = new HashMap<>(); 319 320 // Check the configuration is valid for invitations 321 String catalogSiteName = _projectManager.getCatalogSiteName(); 322 if (_getUserDirectoryForSignup(config, catalogSiteName, lang) == null) 323 { 324 config.remove("success"); 325 config.put("allowed", false); 326 return config; 327 } 328 329 // Check the current user has right to invite users 330 if (!_projectRightsHelper.canAddMember(project)) 331 { 332 config.put("allowed", false); 333 config.put("error", "no-right"); 334 return config; 335 } 336 337 config.put("allowed", true); 338 config.put("email", _getInvitationEmailConfiguration(project, lang)); 339 config.put("rights", _projectRightsHelper.getProjectRightsData(projectName)); 340 341 return config; 342 } 343 344 private Map<String, String> _getInvitationEmailConfiguration(Project project, String lang) 345 { 346 Map<String, String> emailConfig = new HashMap<>(); 347 348 Map<String, I18nizableTextParameter> i18nparams = new HashMap<>(); 349 i18nparams.put("projectTitle", new I18nizableText(project.getTitle())); 350 i18nparams.put("projectUrl", new I18nizableText(_projectManager.getProjectUrl(project, StringUtils.EMPTY))); 351 i18nparams.put("nbDays", new I18nizableText(String.valueOf(_signupConfig.getTokenValidity()))); 352 i18nparams.put("nbDays", new I18nizableText(String.valueOf(_signupConfig.getTokenValidity()))); 353 354 String catalogSiteName = _projectManager.getCatalogSiteName(); 355 Site catalogSite = _siteManager.getSite(catalogSiteName); 356 i18nparams.put("catalogSiteTitle", new I18nizableText(catalogSite.getTitle())); 357 i18nparams.put("catalogSiteUrl", new I18nizableText(catalogSite.getUrl())); 358 359 Page signupPage = _getSignupPage(_projectManager.getCatalogSiteName(), lang); 360 if (signupPage != null) 361 { 362 String signupUri = ResolveURIComponent.resolve("page", signupPage.getId(), false, true) + "?email=${email}&token=${token}"; 363 i18nparams.put("signupUri", new I18nizableText(signupUri)); 364 } 365 366 String subject = getSubjectForInvitationEmail(i18nparams, lang); 367 if (subject != null) 368 { 369 emailConfig.put("subject", subject); 370 } 371 String bodyTxt = getTextBodyForInvitationEmail(i18nparams, lang); 372 if (bodyTxt != null) 373 { 374 emailConfig.put("bodyText", bodyTxt); 375 } 376 String bodyHtml = getHtmlBodyForInvitationEmail(i18nparams, lang); 377 if (bodyHtml != null) 378 { 379 emailConfig.put("bodyHtml", bodyHtml); 380 } 381 382 return emailConfig; 383 } 384 385 private Page _getSignupPage(String catalogSiteName, String lang) 386 { 387 388 Page signupPage = _signupManager.getSignupPage(catalogSiteName, lang); 389 390 if (signupPage == null) 391 { 392 signupPage = _signupManager.getSignupPage(catalogSiteName, "en"); 393 } 394 395 if (signupPage == null) 396 { 397 Map<String, Language> availableLanguages = _languagesManager.getAvailableLanguages(); 398 for (Language availableLanguage : availableLanguages.values()) 399 { 400 if (signupPage == null) 401 { 402 signupPage = _signupManager.getSignupPage(catalogSiteName, availableLanguage.getCode()); 403 } 404 } 405 } 406 return signupPage; 407 } 408 409 private void _sendInvitationMail (String catalogSiteName, String email, String populationId, String userDirectoryId, String mailSubject, String mailBodyTpl) throws UserManagementException 410 { 411 String bodyTxt = mailBodyTpl; 412 413 String encodedEmail; 414 try 415 { 416 encodedEmail = URLEncoder.encode(email, "UTF-8"); 417 } 418 catch (UnsupportedEncodingException e) 419 { 420 // Should never happen. 421 throw new UserManagementException("Encoding error while sending a sign-up confirmation e-mail.", e); 422 } 423 424 String token = _signupManager.getToken(catalogSiteName, email, populationId, userDirectoryId); 425 426 bodyTxt = StringUtils.replace(bodyTxt, __MAIL_PROJECT_TOKEN_PATTERN, token); 427 bodyTxt = StringUtils.replace(bodyTxt, __MAIL_PROJECT_EMAIL_PATTERN, encodedEmail); 428 429 getLogger().debug("Sending signup invitation e-mail to {}", email); 430 431 Site site = _siteManager.getSite(catalogSiteName); 432 String from = site.getValue("site-mail-from"); 433 434 try 435 { 436 // Send the e-mail. 437 SendMailHelper.newMail() 438 .withSubject(mailSubject) 439 .withTextBody(bodyTxt) 440 .withSender(from) 441 .withRecipient(email) 442 .sendMail(); 443 } 444 catch (MessagingException | IOException e) 445 { 446 throw new UserManagementException("Error sending the sign-up confirmation mail.", e); 447 } 448 } 449 450 private boolean _addOrUpdateInvitation(Project project, String catalogSiteName, MembersWorkspaceModule module, String email, Map<String, String> allowedProfileByModules, String populationId, String userDirectoryId, String mailSubject, String mailBody) throws UserManagementException 451 { 452 try 453 { 454 // First remove invitation if exists 455 module.removeInvitation(project, email); 456 457 // Add invitations with temporary rights 458 module.addInvitation(project, new Date(), email, _currentUserProvider.getUser(), allowedProfileByModules); 459 460 project.saveChanges(); 461 462 _sendInvitationMail(catalogSiteName, email, populationId, userDirectoryId, mailSubject, mailBody); 463 464 return true; 465 } 466 catch (RepositoryException e) 467 { 468 getLogger().error("Fail to store invitation for email " + email, e); 469 return false; 470 } 471 } 472 473 private String _getUserDirectoryForSignup(Map<String, Object> result, String catalogSiteName, String lang) 474 { 475 if (catalogSiteName == null) 476 { 477 getLogger().error("The catalog's site name is not configured. User invitations can not be activated."); 478 result.put("success", false); 479 result.put("error", "invalid-configuration"); 480 return null; 481 } 482 483 if (!_signupManager.isPublicSignupAllowed(catalogSiteName)) 484 { 485 getLogger().warn("Public signup is disabled for the catalog's site."); 486 result.put("success", false); 487 return null; 488 } 489 490 Page signupPage = _getSignupPage(catalogSiteName, lang); 491 if (signupPage == null) 492 { 493 getLogger().error("The catalog's site does not contain the signup service for language " + lang + ". User invitations can not be activated."); 494 result.put("success", false); 495 result.put("error", "invalid-configuration"); 496 return null; 497 } 498 499 String userDirectoryAsStr = _getUserDirectoryForSignup(signupPage); 500 if (StringUtils.isEmpty(userDirectoryAsStr)) 501 { 502 getLogger().error("There is no user directory configured for users signup. Please check the sign up service of catalog's site."); 503 result.put("success", false); 504 result.put("error", "invalid-configuration"); 505 return null; 506 } 507 508 return userDirectoryAsStr; 509 510 } 511 512 private String _getUserDirectoryForSignup(Page signupPage) 513 { 514 for (Zone zone : signupPage.getZones()) 515 { 516 try (AmetysObjectIterable<? extends ZoneItem> zoneItems = zone.getZoneItems()) 517 { 518 for (ZoneItem zoneItem : zoneItems) 519 { 520 if (zoneItem.getType() == ZoneType.SERVICE && zoneItem.getServiceId().equals("org.ametys.web.service.UserSignup")) 521 { 522 return zoneItem.getServiceParameters().getValue("userdirectory"); 523 } 524 } 525 } 526 } 527 528 return null; 529 530 } 531 532 /** 533 * Add user as member of all project where it has been invited 534 * @param user the new user 535 */ 536 public void createMemberFromInvitations(User user) 537 { 538 Request request = ContextHelper.getRequest(_context); 539 String currentWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request); 540 541 try 542 { 543 // Force default workspace 544 RequestAttributeWorkspaceSelector.setForcedWorkspace(request, "default"); 545 546 MembersWorkspaceModule memberModule = (MembersWorkspaceModule) _moduleEP.getExtension(MembersWorkspaceModule.MEMBERS_MODULE_ID); 547 548 List<Invitation> invitations = memberModule.getInvitations(user.getEmail()); 549 550 for (Invitation invitation : invitations) 551 { 552 Map<String, String> allowedProfileByModules = invitation.getAllowedProfileByModules(); 553 String projectName = invitation.getProjectName(); 554 555 Project project = _projectManager.getProject(projectName); 556 557 558 _projectMemberManager.addOrUpdateProjectMember(project, user.getIdentity(), allowedProfileByModules); 559 560 // Notify author that invitation was accepted 561 UserIdentity author = invitation.getAuthor(); 562 sendInvitationAcceptedMail(project, _userManager.getUser(author), user); 563 564 try 565 { 566 // Remove invitation 567 memberModule.removeInvitation(project, invitation.getEmail()); 568 } 569 catch (RepositoryException e) 570 { 571 getLogger().error("Failed to remove invitation " + invitation, e); 572 } 573 } 574 } 575 finally 576 { 577 // Restore current workspace 578 RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWorkspace); 579 } 580 581 } 582 583 /** 584 * Send email to the user who initiated the invitation 585 * @param project The project 586 * @param invitAuthor The author of invitation 587 * @param newMember The new member 588 */ 589 protected void sendInvitationAcceptedMail(Project project, User invitAuthor, User newMember) 590 { 591 if (invitAuthor != null) 592 { 593 Site site = project.getSite(); 594 String from = site.getValue("site-mail-from"); 595 String email = invitAuthor.getEmail(); 596 597 if (StringUtils.isNotEmpty(email)) 598 { 599 // Prepare mail. 600 Map<String, I18nizableTextParameter> i18nParams = new HashMap<>(); 601 i18nParams.put("projectTitle", new I18nizableText(project.getTitle())); 602 i18nParams.put("projectUrl", new I18nizableText(_projectManager.getProjectUrl(project, StringUtils.EMPTY))); 603 i18nParams.put("newMember", new I18nizableText(newMember.getFullName())); 604 i18nParams.put("newMemberMail", new I18nizableText(newMember.getEmail())); 605 606 Set<Page> memberPages = _projectManager.getModulePages(project, MembersWorkspaceModule.MEMBERS_MODULE_ID); 607 if (!memberPages.isEmpty()) 608 { 609 Page page = memberPages.iterator().next(); 610 i18nParams.put("membersPageUri", new I18nizableText(ResolveURIComponent.resolve("page", page.getId(), false, true))); 611 } 612 613 String subject = getSubjectForInvitationAcceptedEmail(i18nParams, null); 614 String textBody = getTextBodyForInvitationAcceptedEmail(i18nParams, null); 615 String htmlBody = getHtmlBodyForInvitationAcceptedEmail(i18nParams, null); 616 617 try 618 { 619 // Send the e-mail. 620 SendMailHelper.newMail() 621 .withSubject(subject) 622 .withHTMLBody(htmlBody) 623 .withTextBody(textBody) 624 .withSender(from) 625 .withRecipient(email) 626 .sendMail(); 627 } 628 catch (MessagingException | IOException e) 629 { 630 getLogger().error("Error sending the invitation accepted email.", e); 631 } 632 } 633 } 634 } 635 636 /** 637 * The email subject for invitation by email 638 * @param defaultI18nParams The default i18n parameters 639 * @param language the language 640 * @return the email subject for invitation by email 641 */ 642 public String getSubjectForInvitationEmail (Map<String, I18nizableTextParameter> defaultI18nParams , String language) 643 { 644 if (StringUtils.isNotBlank(_subjectKeyForInvitation)) 645 { 646 return _i18nUtils.translate(_getI18nizableText(_subjectKeyForInvitation, defaultI18nParams), language); 647 } 648 649 return null; 650 } 651 652 /** 653 * The email text body for invitation by email 654 * @param defaultI18nParams The default i18n parameters with : 655 * siteName the site name 656 * email the mail 657 * token the token 658 * confirmUri the confirmation uri 659 * siteTitle the site title 660 * siteUrl the site url 661 * @param language the language 662 * @return the email text for invitation by email 663 */ 664 public String getTextBodyForInvitationEmail(Map<String, I18nizableTextParameter> defaultI18nParams, String language) 665 { 666 if (StringUtils.isNotBlank(_textBodyKeyForInvitation)) 667 { 668 return _i18nUtils.translate(_getI18nizableText(_textBodyKeyForInvitation, defaultI18nParams), language); 669 } 670 671 return null; 672 } 673 674 /** 675 * The email html body for invitation by email 676 * @param defaultI18nParams The default i18n parameters with : 677 * siteName the site name 678 * email the mail 679 * token the token 680 * confirmUri the confirmation uri 681 * siteTitle the site title 682 * siteUrl the site url 683 * @param language the language 684 * @return the email html for invitation by email 685 */ 686 public String getHtmlBodyForInvitationEmail(Map<String, I18nizableTextParameter> defaultI18nParams, String language) 687 { 688 if (StringUtils.isNotBlank(_htmlBodyKeyForInvitation)) 689 { 690 return _i18nUtils.translate(_getI18nizableText(_htmlBodyKeyForInvitation, defaultI18nParams), language); 691 } 692 693 return null; 694 } 695 696 /** 697 * The email subject for invitation by email 698 * @param defaultI18nParams The default i18n parameters 699 * @param language the language 700 * @return the email subject for invitation by email 701 */ 702 public String getSubjectForInvitationAcceptedEmail (Map<String, I18nizableTextParameter> defaultI18nParams , String language) 703 { 704 if (StringUtils.isNotBlank(_subjectKeyForInvitationAccepted)) 705 { 706 return _i18nUtils.translate(_getI18nizableText(_subjectKeyForInvitationAccepted, defaultI18nParams), language); 707 } 708 709 return null; 710 } 711 712 /** 713 * The email text body for invitation by email 714 * @param defaultI18nParams The default i18n parameters with : 715 * @param language the language 716 * @return the email text for invitation by email 717 */ 718 public String getTextBodyForInvitationAcceptedEmail(Map<String, I18nizableTextParameter> defaultI18nParams, String language) 719 { 720 if (StringUtils.isNotBlank(_textBodyKeyForInvitationAccepted)) 721 { 722 return _i18nUtils.translate(_getI18nizableText(_textBodyKeyForInvitationAccepted, defaultI18nParams), language); 723 } 724 725 return null; 726 } 727 728 /** 729 * The email html body for invitation by email 730 * @param defaultI18nParams The default i18n parameters with : 731 * @param language the language 732 * @return the email html for invitation by email 733 */ 734 public String getHtmlBodyForInvitationAcceptedEmail(Map<String, I18nizableTextParameter> defaultI18nParams, String language) 735 { 736 if (StringUtils.isNotBlank(_htmlBodyKeyForInvitationAccepted)) 737 { 738 return _i18nUtils.translate(_getI18nizableText(_htmlBodyKeyForInvitationAccepted, defaultI18nParams), language); 739 } 740 741 return null; 742 } 743 744 /** 745 * Get the {@link I18nizableText} from the configured key and i18n parameters 746 * @param fullI18nKey the configured i18n key 747 * @param i18nParams the i18n parameters 748 * @return the i18nizable text 749 */ 750 protected I18nizableText _getI18nizableText(String fullI18nKey, Map<String, I18nizableTextParameter> i18nParams) 751 { 752 String catalogue = StringUtils.contains(fullI18nKey, ":") ? StringUtils.substringBefore(fullI18nKey, ":") : "plugin." + _pluginName; 753 String i18nKey = StringUtils.contains(fullI18nKey, ":") ? StringUtils.substringAfter(fullI18nKey, ":") : fullI18nKey; 754 755 return new I18nizableText(catalogue, i18nKey, i18nParams); 756 } 757 758}