View Javadoc
1   /*
2    * Copyright (c) 2002-2025, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.portal.web;
35  
36  import fr.paris.lutece.portal.service.admin.AdminUserService;
37  import fr.paris.lutece.portal.service.content.ContentPostProcessorService;
38  import fr.paris.lutece.portal.service.content.ContentService;
39  import fr.paris.lutece.portal.service.datastore.DatastoreService;
40  import fr.paris.lutece.portal.service.editor.EditorBbcodeService;
41  import fr.paris.lutece.portal.service.i18n.I18nService;
42  import fr.paris.lutece.portal.service.init.AppInfo;
43  import fr.paris.lutece.portal.service.init.AppInit;
44  import fr.paris.lutece.portal.service.mail.MailService;
45  import fr.paris.lutece.portal.service.message.ISiteMessageHandler;
46  import fr.paris.lutece.portal.service.message.SiteMessage;
47  import fr.paris.lutece.portal.service.message.SiteMessageException;
48  import fr.paris.lutece.portal.service.message.SiteMessageService;
49  import fr.paris.lutece.portal.service.portal.PortalService;
50  import fr.paris.lutece.portal.service.portal.ThemesService;
51  import fr.paris.lutece.portal.service.resource.IExtendableResource;
52  import fr.paris.lutece.portal.service.resource.IExtendableResourceService;
53  import fr.paris.lutece.portal.service.security.LuteceUser;
54  import fr.paris.lutece.portal.service.security.SecurityService;
55  import fr.paris.lutece.portal.service.security.UserNotSignedException;
56  import fr.paris.lutece.portal.service.spring.SpringContextService;
57  import fr.paris.lutece.portal.service.template.AppTemplateService;
58  import fr.paris.lutece.portal.service.util.AppException;
59  import fr.paris.lutece.portal.service.util.AppLogService;
60  import fr.paris.lutece.portal.service.util.AppPathService;
61  import fr.paris.lutece.portal.service.util.AppPropertiesService;
62  import fr.paris.lutece.portal.web.constants.Markers;
63  import fr.paris.lutece.portal.web.constants.Parameters;
64  import fr.paris.lutece.util.html.HtmlTemplate;
65  import fr.paris.lutece.util.url.UrlItem;
66  
67  import org.apache.commons.lang3.StringUtils;
68  import org.apache.commons.lang3.BooleanUtils;
69  
70  import java.io.UnsupportedEncodingException;
71  
72  import java.net.URLEncoder;
73  
74  import java.util.Enumeration;
75  import java.util.HashMap;
76  import java.util.List;
77  import java.util.Locale;
78  import java.util.Map;
79  
80  import javax.servlet.http.HttpServletRequest;
81  import javax.servlet.http.HttpSession;
82  
83  /**
84   * This class provides the methods to display the page of the site
85   */
86  public class PortalJspBean
87  {
88      public static final int MODE_HTML = 0;
89      public static final int MODE_ADMIN = 1;
90      private static final String TEMPLATE_PAGE_ERROR404 = "skin/site/page_error404.html";
91      private static final String TEMPLATE_PAGE_ERROR500 = "skin/site/page_error500.html";
92      private static final String TEMPLATE_POPUP_CREDITS = "skin/site/popup_credits.html";
93      private static final String TEMPLATE_POPUP_LEGAL_INFO = "skin/site/popup_legal_info.html";
94      private static final String TEMPLATE_STARTUP_FAILURE = "skin/site/startup_failure.html";
95      private static final String TEMPLATE_SEND_RESOURCE = "skin/site/popup_send_resource.html";
96      private static final String TEMPLATE_EMAIL_SEND_RESOURCE = "skin/site/mail_send_resource.html";
97      private static final String PROPERTY_INFOS_CNIL = "lutece.legal.infos";
98      private static final String ATTRIBUTE_LOGIN_NEXT_URL = "luteceLoginNextUrl";
99      private static final String ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL = "uploadFilterSiteNextUrl";
100     private static final String MARK_PORTAL_DOMAIN = "portal_domain";
101     private static final String MARK_ADDRESS_INFOS_CNIL = "confidentiality_info";
102     private static final String MARK_APP_VERSION = "app_version";
103     private static final String MARK_FAILURE_MESSAGE = "failure_message";
104     private static final String MARK_FAILURE_DETAILS = "failure_details";
105     private static final String MARK_RESOURCE_URL = "resource_url";
106     private static final String MARK_RESOURCE = "resource";
107     private static final String MARK_ERROR = "error";
108     private static final String MARK_SUCCESS = "success";
109     private static final String MARK_ERROR_CAUSE = "error_cause";
110     private static final String MARK_PLUGIN_THEME = "plugin_theme";
111     private static final String MARK_THEME = "theme";
112     private static final String BEAN_SITE_MESSAGE_HANDLER = "siteMessageHandler";
113     private static final String PARAMETER_EXTENDABLE_RESOURCE_TYPE = "extendableResourceType";
114     private static final String PARAMETER_ID_EXTENDABLE_RESOURCE = "idExtendableResource";
115     private static final String PARAMETER_SENDER_NAME = "senderName";
116     private static final String PARAMETER_SENDER_FIRST_NAME = "senderFirstname";
117     private static final String PARAMETER_SENDER_EMAIL = "senderEmail";
118     private static final String PARAMETER_CONTENT = "content";
119     private static final String PARAMETER_SEND = "send";
120     private static final String MESSAGE_ERROR_WRONG_SENDER_EMAIL = "portal.site.error.wrongEmailFormat";
121     private static final String MESSAGE_ERROR_MANDATORY_FIELDS = "portal.util.message.mandatoryFields";
122     private static final String MESSAGE_NO_RESOURCE_FOUND = "portal.site.error.noResourceFound";
123     private static final String PROPERTY_PAGE_TITLE_ERROR404 = "portal.util.error404.title";
124     private static final String PROPERTY_PAGE_TITLE_CREDITS = "portal.site.popup_credits.pageTitle";
125     private static final String PROPERTY_PAGE_TITLE_LEGAL_INFO = "portal.site.popup_legal_info.pageTitle";
126     private static final String PROPERTY_PAGE_TITLE_STARTUP_FAILURE = "portal.util.startup.failure.title";
127     private static final String PROPERTY_PAGE_TITLE_ERROR500 = "portal.util.error500.title";
128     private static final String PROPERTY_DEBUG = "error.page.debug";
129     private static final String PROPERTY_DEBUG_DEFAULT = "true";
130     private static final String CONSTANT_SPACE = " ";
131     private static final String KEY_WEBMASTER_EMAIL = "portal.site.site_property.noreply_email";
132 
133     /**
134      * Returns the content of a page according to the parameters found in the http request. One distinguishes article, page and xpage and the mode.
135      *
136      * @param request
137      *            The http request
138      * @return the html code for the display of a page of a site
139      * @throws UserNotSignedException
140      *             The UserNotSignedException
141      * @throws SiteMessageException
142      *             occurs when a site message need to be displayed
143      */
144     public String getContent( HttpServletRequest request ) throws UserNotSignedException, SiteMessageException
145     {
146         return getContent( request, MODE_HTML );
147     }
148 
149     /**
150      * Returns the content of a page according to the parameters found in the http request. One distinguishes article, page and xpage and the mode.
151      *
152      * @param request
153      *            The http request
154      * @param nMode
155      *            The mode (normal or administration)
156      * @return the html code for the display of a page of a site
157      * @throws UserNotSignedException
158      *             The UserNotSignedException
159      * @throws SiteMessageException
160      *             occurs when a site message need to be displayed
161      */
162     public String getContent( HttpServletRequest request, int nMode ) throws UserNotSignedException, SiteMessageException
163     {
164         if ( !AppInit.isWebappSuccessfullyLoaded( ) )
165         {
166             return getStartUpFailurePage( request );
167         }
168 
169         // Try to register the user in case of external authentication
170         if ( SecurityService.isAuthenticationEnable( ) )
171         {
172             try
173             {
174                 if ( SecurityService.getInstance( ).isExternalAuthentication( ) && !SecurityService.getInstance( ).isMultiAuthenticationSupported( ) )
175                 {
176                     SecurityService.getInstance( ).getRemoteUser( request );
177                 }
178                 else
179                 {
180                     LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
181 
182                     // no checks are needed if the user is already registered
183                     // if multiauthentication is supported, then when have to check remote user
184                     // before other check
185                     if ( user == null && SecurityService.getInstance( ).isMultiAuthenticationSupported( ) )
186                     {
187 
188                         // getRemoteUser needs to be checked before any check so the user is registered
189                         // getRemoteUser throws an exception if no user found, but here we have to
190                         // bypass this exception to display login page.
191                         SecurityService.getInstance( ).getRemoteUser( request );
192                     }
193                 }
194             }
195             catch( UserNotSignedException unse )
196             {
197                 // nothing to do,Leave LuteceAuthenticationFilter testing if the access to the
198                 // content requires authentication
199             }
200         }
201 
202         // Search the content service invoked and call its getPage method
203         ContentService cs = PortalService.getInvokedContentService( request );
204 
205         String strContent = ( cs != null ) ? cs.getPage( request, nMode ) : PortalService.getDefaultPage( request, nMode );
206 
207         if ( ContentPostProcessorService.hasProcessor( ) )
208         {
209             strContent = ContentPostProcessorService.process( request, strContent );
210         }
211 
212         return strContent;
213     }
214 
215     /**
216      * Returns the content of a page according to the parameters found in the http request. One distinguishes article, page and xpage and the mode.
217      *
218      * @param request
219      *            The http request
220      * @return the html code for the display of a page of a site
221      *
222      */
223     public String getSiteMessageContent( HttpServletRequest request )
224     {
225         return getSiteMessageContent( request, MODE_HTML );
226     }
227 
228     /**
229      * Returns the content of a page according to the parameters found in the http request. One distinguishes article, page and xpage and the mode.
230      *
231      * @param request
232      *            The http request
233      * @param nMode
234      *            The mode (normal or administration)
235      * @return the html code for the display of a page of a site
236      *
237      */
238     public String getSiteMessageContent( HttpServletRequest request, int nMode )
239     {
240         String strContent = null;
241 
242         if ( !AppInit.isWebappSuccessfullyLoaded( ) )
243         {
244             return getStartUpFailurePage( request );
245         }
246 
247         ISiteMessageHandler handler = SpringContextService.getBean( BEAN_SITE_MESSAGE_HANDLER );
248 
249         if ( handler.hasMessage( request ) )
250         {
251             strContent = handler.getPage( request, nMode );
252         }
253 
254         return strContent;
255     }
256 
257     /**
258      * Returns the code for the popup of the credits
259      * 
260      * @param request
261      *            The HTTP request
262      * @return the html code for the popup credits
263      */
264     public String getStartUpFailurePage( HttpServletRequest request )
265     {
266         HashMap<String, Object> model = new HashMap<>( );
267         fillPageModel( request, model );
268         model.put( MARK_FAILURE_MESSAGE, AppInit.getLoadingFailureCause( ) );
269         model.put( MARK_FAILURE_DETAILS, AppInit.getLoadingFailureDetails( ) );
270         model.put( Markers.PAGE_TITLE, I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_STARTUP_FAILURE, request.getLocale( ) ) );
271 
272         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_STARTUP_FAILURE, request.getLocale( ), model );
273 
274         return template.getHtml( );
275     }
276 
277     /**
278      * Returns the code for the popup of the credits
279      *
280      * @param request
281      *            The Http Request
282      * @return the html code for the popup credits
283      */
284     public String getCredits( HttpServletRequest request )
285     {
286         HashMap<String, Object> model = new HashMap<>( );
287         fillPageModel( request, model );
288         model.put( MARK_APP_VERSION, AppInfo.getVersion( ) );
289         model.put( MARK_PORTAL_DOMAIN, PortalService.getSiteName( ) );
290         model.put( Markers.PAGE_TITLE, I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_CREDITS, request.getLocale( ) ) );
291 
292         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_POPUP_CREDITS, request.getLocale( ), model );
293 
294         return template.getHtml( );
295     }
296 
297     /**
298      * Returns the code for the popup of the legal infos
299      *
300      * @param request
301      *            The Http Request
302      * @return the html code for the legal infos
303      */
304     public String getLegalInfos( HttpServletRequest request )
305     {
306         HashMap<String, Object> model = new HashMap<>( );
307         fillPageModel( request, model );
308         model.put( MARK_ADDRESS_INFOS_CNIL, AppPropertiesService.getProperty( PROPERTY_INFOS_CNIL ) );
309         model.put( MARK_PORTAL_DOMAIN, PortalService.getSiteName( ) );
310         model.put( Markers.PAGE_TITLE, I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_LEGAL_INFO, request.getLocale( ) ) );
311 
312         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_POPUP_LEGAL_INFO, request.getLocale( ), model );
313 
314         return template.getHtml( );
315     }
316 
317     /**
318      * Returns the 404 Error page
319      * 
320      * @param request
321      *            The HTTP request
322      * @return The page
323      */
324     public String getError404Page( HttpServletRequest request )
325     {
326         HashMap<String, Object> model = new HashMap<>( );
327         fillPageModel( request, model );
328         model.put( Markers.PAGE_TITLE, I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_ERROR404, request.getLocale( ) ) );
329 
330         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_PAGE_ERROR404, request.getLocale( ), model );
331 
332         return template.getHtml( );
333     }
334 
335     /**
336      * Returns the 500 Error page
337      * 
338      * @param request
339      *            The HTTP request
340      * @param exception
341      *            The Exception
342      * @return The page
343      */
344     public String getError500Page( HttpServletRequest request, Throwable exception )
345     {
346         if ( exception == null )
347         {
348             AppLogService.error( "Error 500 : No exception provided" );
349             return getError500Page( request, (String) null );
350         }
351 
352         if ( exception instanceof AppException )
353         {
354             // AppException calls AppLogService.error( message, this ) in the
355             // constructor, so don't call it here again Call toString to have
356             // the Class and the message to be able to indentify the correct
357             // stacktrace in the preceding logs.
358             AppLogService.error( "Error 500 : Caused by previous Critical AppException" );
359         }
360         else
361         {
362             AppLogService.error( "Error 500 : {}", exception.getMessage( ), exception );
363         }
364 
365         String strCause = null;
366 
367         if ( AppPropertiesService.getProperty( PROPERTY_DEBUG, PROPERTY_DEBUG_DEFAULT ).equalsIgnoreCase( "true" ) )
368         {
369             strCause = exception.getMessage( );
370 
371             if ( exception.getCause( ) != null )
372             {
373                 strCause += exception.getCause( ).getMessage( );
374             }
375         }
376 
377         return getError500Page( request, strCause );
378     }
379 
380     /**
381      * Returns the 500 Error page
382      * 
383      * @param request
384      *            The HTTP request
385      * @param strCause
386      *            The message
387      * @return The page
388      */
389     public String getError500Page( HttpServletRequest request, String strCause )
390     {
391         HashMap<String, Object> model = new HashMap<>( );
392         fillPageModel( request, model );
393         model.put( Markers.PAGE_TITLE, I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_ERROR500, request.getLocale( ) ) );
394         model.put( MARK_ERROR_CAUSE, strCause );
395 
396         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_PAGE_ERROR500, request.getLocale( ), model );
397 
398         return template.getHtml( );
399     }
400 
401     /**
402      * Fill the model'map with commons values
403      * 
404      * @param request
405      *            The HTTP request
406      * @param model
407      *            The map containing the model
408      */
409     private static void fillPageModel( HttpServletRequest request, HashMap<String, Object> model )
410     {
411         model.put( Markers.BASE_URL, AppPathService.getBaseUrl( request ) );
412         model.put( MARK_PLUGIN_THEME, null );
413         model.put( MARK_THEME, ThemesService.getGlobalThemeObject( ) );
414     }
415 
416     /**
417      * This method is called by Portal.jsp when it caught an UserNotSignedException. It gives the login url and stores in the session the url asked
418      * 
419      * @param request
420      *            The HTTP request
421      * @return The login page URL
422      * @since v1.1
423      */
424     public static String redirectLogin( HttpServletRequest request )
425     {
426         String strNextUrl = request.getRequestURI( );
427         UrlIteml/UrlItem.html#UrlItem">UrlItem url = new UrlItem( strNextUrl );
428         Enumeration<String> enumParams = request.getParameterNames( );
429 
430         while ( enumParams.hasMoreElements( ) )
431         {
432             String strParamName = enumParams.nextElement( );
433 
434             try
435             {
436                 url.addParameter( strParamName, URLEncoder.encode( request.getParameter( strParamName ), "UTF-8" ) );
437             }
438             catch( UnsupportedEncodingException ex )
439             {
440                 AppLogService.error( "Redirection error while encoding URL : {}", ex.getMessage( ), ex );
441             }
442         }
443 
444         HttpSession session = request.getSession( true );
445         session.setAttribute( ATTRIBUTE_LOGIN_NEXT_URL, url.getUrl( ) );
446 
447         String strRedirect = SecurityService.getInstance( ).getLoginPageUrl( );
448 
449         return AppPathService.getAbsoluteUrl( request, strRedirect );
450     }
451 
452     /**
453      * Returns the url (asked before login) to redirect after login
454      * 
455      * @param request
456      *            The Http request
457      * @return The url asked before login
458      * @since v1.1
459      */
460     public static String getLoginNextUrl( HttpServletRequest request )
461     {
462         HttpSession session = request.getSession( );
463         return (String) session.getAttribute( ATTRIBUTE_LOGIN_NEXT_URL );
464     }
465 
466     /**
467      * Set the upload filter site next url
468      * 
469      * @param request
470      *            the HTTP request
471      */
472     public static void setUploadFilterSiteNextUrl( HttpServletRequest request )
473     {
474         String strNextUrl = request.getRequestURI( );
475         UrlIteml/UrlItem.html#UrlItem">UrlItem url = new UrlItem( strNextUrl );
476         Enumeration<String> enumParams = request.getParameterNames( );
477 
478         while ( enumParams.hasMoreElements( ) )
479         {
480             String strParamName = enumParams.nextElement( );
481             url.addParameter( strParamName, request.getParameter( strParamName ) );
482         }
483 
484         HttpSession session = request.getSession( true );
485         session.setAttribute( ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL, url.getUrl( ) );
486     }
487 
488     /**
489      * Get the upload filter site next url
490      * 
491      * @param request
492      *            the HTTP request
493      * @return the next url
494      */
495     public static String getUploadFilterSiteNextUrl( HttpServletRequest request )
496     {
497         HttpSession session = request.getSession( );
498         return (String) session.getAttribute( ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL );
499     }
500 
501     /**
502      * Remove the upload filter next url from the session
503      * 
504      * @param request
505      *            the HTTP request
506      */
507     public static void removeUploadFilterSiteNextUrl( HttpServletRequest request )
508     {
509         HttpSession session = request.getSession( );
510         session.removeAttribute( ATTRIBUTE_UPLOAD_FILTER_SITE_NEXT_URL );
511     }
512 
513     /**
514      * Do send a resource
515      * 
516      * @param request
517      *            The request
518      * @return The HTML content to display
519      * @throws SiteMessageException
520      *             If the resource or its associated service is not found
521      */
522     public static String sendResource( HttpServletRequest request ) throws SiteMessageException
523     {
524         String strSenderEmail = DatastoreService.getDataValue( KEY_WEBMASTER_EMAIL, "no-reply@mydomain.com" );
525         String strSenderName = request.getParameter( PARAMETER_SENDER_NAME );
526         String strSenderFirstName = request.getParameter( PARAMETER_SENDER_FIRST_NAME );
527         String strReceipientEmail = request.getParameter( Parameters.EMAIL );
528         String strContent = request.getParameter( PARAMETER_CONTENT );
529         String strExtendableResourceType = request.getParameter( PARAMETER_EXTENDABLE_RESOURCE_TYPE );
530         String strIdExtendableResource = request.getParameter( PARAMETER_ID_EXTENDABLE_RESOURCE );
531         String strSend = request.getParameter( PARAMETER_SEND );
532         IExtendableResource resource = null;
533 
534         String strError = checkSendParams( strSend, strSenderEmail, strSenderName, strSenderFirstName, strReceipientEmail, strContent, request.getLocale( ) );
535 
536         // We get the resource from its resource service
537         IExtendableResourceService resourceService = null;
538         List<IExtendableResourceService> listExtendableResourceService = SpringContextService.getBeansOfType( IExtendableResourceService.class );
539 
540         for ( IExtendableResourceService extendableResourceService : listExtendableResourceService )
541         {
542             if ( extendableResourceService.isInvoked( strExtendableResourceType ) )
543             {
544                 resourceService = extendableResourceService;
545                 resource = extendableResourceService.getResource( strIdExtendableResource, strExtendableResourceType );
546             }
547         }
548 
549         if ( ( resourceService == null ) || ( resource == null ) )
550         {
551             SiteMessageService.setMessage( request, MESSAGE_NO_RESOURCE_FOUND, SiteMessage.TYPE_ERROR );
552             throw new SiteMessageException( );
553         }
554 
555         String strResourceUrl = resourceService.getResourceUrl( strIdExtendableResource, strExtendableResourceType );
556         Map<String, Object> model = new HashMap<>( );
557         model.put( MARK_RESOURCE, resource );
558         model.put( MARK_RESOURCE_URL, strResourceUrl );
559         model.put( Markers.BASE_URL, AppPathService.getBaseUrl( request ) );
560 
561         if ( ( strSend != null ) && ( strError == null ) )
562         {
563             Map<String, Object> mailModel = new HashMap<>( );
564             mailModel.put( Markers.BASE_URL, AppPathService.getBaseUrl( request ) );
565             mailModel.put( MARK_RESOURCE, resource );
566             mailModel.put( PARAMETER_SENDER_EMAIL, strSenderEmail );
567             mailModel.put( PARAMETER_SENDER_NAME, strSenderName );
568             mailModel.put( PARAMETER_SENDER_FIRST_NAME, strSenderFirstName );
569             mailModel.put( Parameters.EMAIL, strReceipientEmail );
570             mailModel.put( PARAMETER_CONTENT, EditorBbcodeService.getInstance( ).parse( strContent ) );
571             mailModel.put( MARK_RESOURCE_URL, resourceService.getResourceUrl( strIdExtendableResource, strExtendableResourceType ) );
572 
573             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_EMAIL_SEND_RESOURCE, request.getLocale( ), mailModel );
574             MailService.sendMailHtml( strReceipientEmail, strSenderFirstName + CONSTANT_SPACE + strSenderName, strSenderEmail,
575                     resource.getExtendableResourceName( ), template.getHtml( ) );
576             model.put( MARK_SUCCESS, MARK_SUCCESS );
577         }
578         else
579         {
580             model.put( PARAMETER_SENDER_NAME, strSenderName );
581             model.put( PARAMETER_SENDER_FIRST_NAME, strSenderFirstName );
582             model.put( Parameters.EMAIL, strReceipientEmail );
583             model.put( PARAMETER_CONTENT, strContent );
584             model.put( MARK_ERROR, strError );
585         }
586 
587         model.put( Markers.PAGE_MAIN_MENU, StringUtils.EMPTY );
588 
589         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_SEND_RESOURCE, request.getLocale( ), model );
590 
591         return template.getHtml( );
592     }
593 
594     private static String checkSendParams( String strSend, String strSenderEmail, String strSenderName, String strSenderFirstName, String strReceipientEmail,
595             String strContent, Locale locale )
596     {
597         String strError = null;
598         // If the form was submited, we check data
599         if ( strSend != null )
600         {
601             boolean [ ] conditions = new boolean [ ] {
602                     StringUtils.isBlank( strSenderEmail ), StringUtils.isBlank( strSenderName ), StringUtils.isBlank( strSenderFirstName ),
603                     StringUtils.isBlank( strReceipientEmail ), StringUtils.isBlank( strContent )
604             };
605 
606             if ( BooleanUtils.or( conditions ) )
607             {
608                 strError = I18nService.getLocalizedString( MESSAGE_ERROR_MANDATORY_FIELDS, locale );
609             }
610 
611             if ( ( strError != null ) && ( !AdminUserService.checkEmail( strSenderEmail ) || !AdminUserService.checkEmail( strReceipientEmail ) ) )
612             {
613                 strError = I18nService.getLocalizedString( MESSAGE_ERROR_WRONG_SENDER_EMAIL, locale );
614             }
615         }
616         return strError;
617     }
618 }