ProposalXPage.java
/*
* Copyright (c) 2002-2020, City of Paris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* License 1.0
*/
package fr.paris.lutece.plugins.participatoryideation.web;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import fr.paris.lutece.plugins.avatar.service.AvatarService;
import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistory;
import fr.paris.lutece.plugins.extend.service.extender.history.IResourceExtenderHistoryService;
import fr.paris.lutece.plugins.extend.service.extender.history.ResourceExtenderHistoryService;
import fr.paris.lutece.plugins.participatoryideation.business.proposal.Proposal;
import fr.paris.lutece.plugins.participatoryideation.business.proposal.ProposalHome;
import fr.paris.lutece.plugins.participatoryideation.service.IdeationStaticService;
import fr.paris.lutece.plugins.participatoryideation.service.ProposalService;
import fr.paris.lutece.plugins.participatoryideation.service.campaign.IdeationCampaignDataProvider;
import fr.paris.lutece.plugins.participatoryideation.service.myinfos.MyInfosService;
import fr.paris.lutece.portal.service.datastore.DatastoreService;
import fr.paris.lutece.portal.service.mail.MailService;
import fr.paris.lutece.portal.service.message.SiteMessageException;
import fr.paris.lutece.portal.service.portal.PortalService;
import fr.paris.lutece.portal.service.prefs.UserPreferencesService;
import fr.paris.lutece.portal.service.security.LuteceUser;
import fr.paris.lutece.portal.service.security.SecurityService;
import fr.paris.lutece.portal.service.security.UserNotSignedException;
import fr.paris.lutece.portal.service.spring.SpringContextService;
import fr.paris.lutece.portal.service.template.AppTemplateService;
import fr.paris.lutece.portal.service.util.AppLogService;
import fr.paris.lutece.portal.service.util.AppPathService;
import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
import fr.paris.lutece.portal.web.xpages.XPage;
import fr.paris.lutece.util.html.HtmlTemplate;
/**
* This class provides the user interface to view Proposal xpages
*/
@Controller( xpageName = "proposal", pageTitleI18nKey = "participatoryideation.xpage.proposal.pageTitle", pagePathI18nKey = "participatoryideation.xpage.proposal.pagePathLabel" )
public class ProposalXPage extends MVCApplication
{
/**
*
*/
private static final long serialVersionUID = 2703580251118435168L;
// Templates
private static final String TEMPLATE_VIEW_PROPOSAL = "/skin/plugins/participatoryideation/view_proposal.html";
// Parameters
private static final String PARAM_BP_EMAIL = "participatorybudget.email";
private static final String PARAM_BP_NICKNAME = "portal.nickname";
private static final String PARAMETER_CODE_PROPOSAL = "proposal";
private static final String PARAMETER_CODE_CAMPAIGN = "campaign";
private static final String PARAMETER_SHOW_CONTACT = "showContact";
private static final String PARAMETER_LAST_NAME_USAGER = "last_name_usager";
private static final String PARAMETER_QUESTION_USAGER = "question_usager";
// Markers
private static final String MARK_PROPOSAL = "proposal";
private static final String MARK_NICKNAME = "nickname";
private static final String MARK_NICKNAME_USER = "nicknameUser";
private static final String MARK_IS_OWN_PROPOSAL = "is_own_proposal";
private static final String MARK_HAS_AVATAR = "has_avatar";
private static final String MARK_AVATAR_URL = "avatar_url";
private static final String MARK_IS_EXTEND_INSTALLED = "isExtendInstalled";
private static final String MARK_CODE_PROPOSAL = "proposal";
private static final String MARK_CODE_CAMPAIGN = "campaign";
private static final String MARK_WHOLE_AREA = "whole_area";
private static final String MARK_LASTNAME_USER = "lastNameUser";
private static final String MARK_FIRSTNAME_USER = "firstNameUser";
private static final String MARK_EMAIL_USER = "emailUser";
private static final String MARK_NOM_DEP = "nom_submitter";
private static final String MARK_NOM_CONTACT = "nom_contacteur";
private static final String MARK_MESSAGE = "message";
private static final String MARK_SHOW_CONTACT = "show_contact";
private static final String MARK_MESSAGE_NOT_ACCEPT = "message_not_accept";
// Properties
private static final String PROPERTY_CONTACT_SUBJECT = "participatoryideation.site_property.view_proposal.site_properties.contact_subject";
private static final String PROPERTY_CONTACT_MESSAGE_CONTENT = "participatoryideation.site_property.view_proposal.site_properties.contact_message_content.textblock";
private static final String PROPERTY_CONTACT_MESSAGE_NOT_ACCEPT = "participatoryideation.site_property.view_proposal.site_properties.contact_message_not_accept";
private static final String INFO_MESSAGE_SEND = "participatoryideation.site_property.view_proposal.site_properties.info_message_send";
private static final String ERROR_MESSAGE_SEND = "participatoryideation.site_property.view_proposal.site_properties.error_message_send";
// Views
private static final String VIEW_VIEW_PROPOSAL = "viewProposal";
// Actions
private static final String ACTION_CONTACTER_SUBMITTER = "contacterSubmitter";
// CONSTANTS
private static final String CONSTANT_CONTACT_EXTENDER_TYPE = "contact";
/**
* Returns the form to update info about a proposal
*
* @param request
* The Http request
* @return The HTML form to update info
*/
@View( value = VIEW_VIEW_PROPOSAL, defaultView = true )
public XPage getViewProposal( HttpServletRequest request ) throws UserNotSignedException, SiteMessageException
{
String strCodeCampaign = request.getParameter( PARAMETER_CODE_CAMPAIGN );
Integer nCodeProposal;
try
{
nCodeProposal = Integer.parseInt( request.getParameter( PARAMETER_CODE_PROPOSAL ) );
}
catch( NumberFormatException nfe )
{
nCodeProposal = null;
}
Proposal _proposal;
if ( strCodeCampaign != null && nCodeProposal != null )
{
_proposal = ProposalHome.findByCodes( strCodeCampaign, nCodeProposal );
}
else
{
_proposal = null;
}
String strContactMessageNotAccept = DatastoreService.getDataValue( PROPERTY_CONTACT_MESSAGE_NOT_ACCEPT, "" );
Map<String, Object> model = getModel( );
String strShowContact = request.getParameter( PARAMETER_SHOW_CONTACT );
if ( strShowContact != null && strShowContact.equals( "true" ) )
{
if ( !checkUserAuthorized( request ) )
{
return redirect( request, AppPathService.getProdUrl( request ) + MyInfosService.getInstance( ).getUrlMyInfosFillAction( ) );
}
}
model.put( MARK_SHOW_CONTACT, strShowContact );
model.put( MARK_MESSAGE_NOT_ACCEPT, strContactMessageNotAccept );
model.put( MARK_WHOLE_AREA, IdeationCampaignDataProvider.getInstance( ).getCampaignWholeAreaLabel( strCodeCampaign ) );
if ( _proposal == null || !ProposalService.getInstance( ).isPublished( _proposal ) )
{
return getXPage( TEMPLATE_VIEW_PROPOSAL, request.getLocale( ), model );
}
ProposalHome.loadMissingLinkedProposals( _proposal );
model.put( MARK_PROPOSAL, _proposal );
if ( _proposal.getLuteceUserName( ) != null )
{
if ( _proposal.isFromBackOffice() )
{
model.put( MARK_NICKNAME, _proposal.getLuteceUserName( ) );
model.put( MARK_HAS_AVATAR, false );
}
else
{
model.put( MARK_HAS_AVATAR, true );
model.put( MARK_AVATAR_URL, AvatarService.getAvatarUrl( _proposal.getLuteceUserName( ) ) );
model.put( MARK_NICKNAME, UserPreferencesService.instance( ).getNickname( _proposal.getLuteceUserName( ) ) );
if ( SecurityService.isAuthenticationEnable( ) )
{
LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
if ( user != null && user.getName( ) != null )
{
model.put( MARK_IS_OWN_PROPOSAL, _proposal.getLuteceUserName( ).equals( user.getName( ) ) );
model.put( MARK_NICKNAME_USER, UserPreferencesService.instance( ).getNickname( user.getName( ) ) );
model.put( MARK_LASTNAME_USER, user.getUserInfos( ).get( "user.name.given" ) );
model.put( MARK_FIRSTNAME_USER, user.getUserInfos( ).get( "user.name.family" ) );
model.put( MARK_EMAIL_USER, user.getUserInfos( ).get( "user.business-info.online.email" ) );
String strEmail = UserPreferencesService.instance( ).get( user.getName( ), PARAM_BP_EMAIL, StringUtils.EMPTY );
if ( strEmail != null && !strEmail.isEmpty( ) )
{
model.put( MARK_EMAIL_USER, strEmail );
}
}
}
}
}
model.put( MARK_IS_EXTEND_INSTALLED, PortalService.isExtendActivated( ) );
IdeationStaticService.getInstance( ).fillCampaignStaticContent( model, _proposal.getCodeCampaign( ) );
XPage xpage = getXPage( TEMPLATE_VIEW_PROPOSAL, request.getLocale( ), model );
xpage.setTitle( _proposal.getTitre( ) );
return xpage;
}
@Action( value = ACTION_CONTACTER_SUBMITTER )
public XPage doContacterSubmitter( HttpServletRequest request )
{
String strCodeCampaign = request.getParameter( PARAMETER_CODE_CAMPAIGN );
Integer nCodeProposal;
try
{
nCodeProposal = Integer.parseInt( request.getParameter( PARAMETER_CODE_PROPOSAL ) );
}
catch( NumberFormatException nfe )
{
nCodeProposal = null;
}
Proposal _proposal;
if ( strCodeCampaign != null && nCodeProposal != null )
{
_proposal = ProposalHome.findByCodes( strCodeCampaign, nCodeProposal );
}
else
{
_proposal = null;
}
Map<String, String> viewModel = new HashMap<String, String>( );
viewModel.put( MARK_CODE_CAMPAIGN, strCodeCampaign );
viewModel.put( MARK_CODE_PROPOSAL, "" + nCodeProposal );
String strEmailSubmitter = "";
String strNomSubmitter = "";
if ( _proposal != null )
{
String strEmail = UserPreferencesService.instance( ).get( _proposal.getLuteceUserName( ), PARAM_BP_EMAIL, StringUtils.EMPTY );
String strNickname = UserPreferencesService.instance( ).get( _proposal.getLuteceUserName( ), PARAM_BP_NICKNAME, StringUtils.EMPTY );
strEmailSubmitter = strEmail;
strNomSubmitter = strNickname;
}
String strLastNameUsager = request.getParameter( PARAMETER_LAST_NAME_USAGER );
LuteceUser user = null;
if ( SecurityService.isAuthenticationEnable( ) )
{
user = SecurityService.getInstance( ).getRegisteredUser( request );
}
String strEmailUsager = ( user != null ) ? UserPreferencesService.instance( ).get( user.getName( ), PARAM_BP_EMAIL, StringUtils.EMPTY ) : "";
String strQuestionUsager = request.getParameter( PARAMETER_QUESTION_USAGER );
String strEmailContent = StringUtils.EMPTY;
String strSubject = DatastoreService.getDataValue( PROPERTY_CONTACT_SUBJECT, "" );
String strContactMessage = DatastoreService.getDataValue( PROPERTY_CONTACT_MESSAGE_CONTENT, "" );
Map<String, String> model = new HashMap<String, String>( );
String strLuteceUserName = "";
if ( SecurityService.isAuthenticationEnable( ) )
{
user = SecurityService.getInstance( ).getRegisteredUser( request );
if ( user != null && user.getName( ) != null )
{
strLuteceUserName = user.getName( );
model.put( MARK_LASTNAME_USER, user.getUserInfos( ).get( "user.name.given" ) );
model.put( MARK_FIRSTNAME_USER, user.getUserInfos( ).get( "user.name.family" ) );
model.put( MARK_EMAIL_USER, user.getUserInfos( ).get( "user.business-info.online.email" ) );
}
}
model.put( MARK_NOM_DEP, strNomSubmitter );
model.put( MARK_NOM_CONTACT, strLastNameUsager );
model.put( MARK_MESSAGE, strQuestionUsager );
if ( !strQuestionUsager.isEmpty( ) )
{
try
{
HtmlTemplate t = AppTemplateService.getTemplateFromStringFtl( strContactMessage, request.getLocale( ), model );
strEmailContent = t.getHtml( );
}
catch( Exception e )
{
AppLogService.error( "Erreur template freemarker: " + e + ": " + e.getMessage( ), e );
String strErrorMessageSend = DatastoreService.getDataValue( ERROR_MESSAGE_SEND, "" );
addError( strErrorMessageSend );
return redirect( request, VIEW_VIEW_PROPOSAL, viewModel );
}
}
if ( !strEmailSubmitter.isEmpty( ) && !strEmailUsager.isEmpty( ) && !strEmailContent.isEmpty( ) )
{
String strInfoMessageSend = DatastoreService.getDataValue( INFO_MESSAGE_SEND, "" );
MailService.sendMailHtml( strEmailSubmitter, "", "", "", strEmailUsager, strSubject, strEmailContent );
contactDepHistory( _proposal, strLuteceUserName );
addInfo( strInfoMessageSend );
}
else
{
String strErrorMessageSend = DatastoreService.getDataValue( ERROR_MESSAGE_SEND, "" );
addError( strErrorMessageSend );
}
return redirect( request, VIEW_VIEW_PROPOSAL, viewModel );
}
private boolean checkUserAuthorized( HttpServletRequest request ) throws UserNotSignedException
{
LuteceUser user = null;
if ( SecurityService.isAuthenticationEnable( ) )
{
user = SecurityService.getInstance( ).getRemoteUser( request );
if ( user == null )
{
throw new UserNotSignedException( );
}
return MyInfosService.getInstance( ).isUserValid( user.getName( ) );
}
return false;
}
private void contactDepHistory( Proposal proposal, String strLuteceUserName )
{
IResourceExtenderHistoryService resourceHistoryService = SpringContextService.getBean( ResourceExtenderHistoryService.BEAN_SERVICE );
ResourceExtenderHistory history = new ResourceExtenderHistory( );
history.setExtenderType( CONSTANT_CONTACT_EXTENDER_TYPE );
// history.setIdExtendableResource( proposal.getCodeCampaign() + "-" + String.format("%06d", proposal.getCodeProposal()));
history.setIdExtendableResource( ( proposal != null ) ? ( "" + proposal.getId( ) ) : "proposal is null" );
history.setExtendableResourceType( Proposal.PROPERTY_RESOURCE_TYPE );
history.setIpAddress( StringUtils.EMPTY );
history.setUserGuid( strLuteceUserName );
resourceHistoryService.create( history );
}
}