001/*
002 *  Copyright 2015 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.sms.service;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.parameters.Parameters;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.acting.ServiceableAction;
027import org.apache.cocoon.environment.ObjectModelHelper;
028import org.apache.cocoon.environment.Redirector;
029import org.apache.cocoon.environment.Request;
030import org.apache.cocoon.environment.SourceResolver;
031
032import org.ametys.core.captcha.CaptchaHelper;
033import org.ametys.core.cocoon.ActionResultGenerator;
034import org.ametys.plugins.repository.AmetysObjectResolver;
035import org.ametys.plugins.sms.SMSHelper;
036import org.ametys.plugins.sms.dao.SubscriberDAO;
037import org.ametys.runtime.i18n.I18nizableText;
038import org.ametys.web.cache.PageHelper;
039import org.ametys.web.repository.page.ZoneItem;
040import org.ametys.web.site.SiteConfigurationExtensionPoint;
041
042/**
043 * Add or remove the phone number into a list
044 */
045public class SubscribeAction extends ServiceableAction
046{  
047    /** Ametys object resolver. */
048    protected AmetysObjectResolver _resolver;
049    
050    /** Subscriber DAO. */
051    protected SubscriberDAO _subscriberDAO;
052    
053    /** The site configuration */
054    protected SiteConfigurationExtensionPoint _siteConfiguration;
055    /** Page helper */
056    protected PageHelper _pageHelper;
057    
058    @Override
059    public void service(ServiceManager serviceManager) throws ServiceException
060    {
061        super.service(serviceManager);
062        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
063        _subscriberDAO = (SubscriberDAO) serviceManager.lookup(SubscriberDAO.ROLE);
064        _siteConfiguration = (SiteConfigurationExtensionPoint) serviceManager.lookup(SiteConfigurationExtensionPoint.ROLE);
065        _pageHelper = (PageHelper) serviceManager.lookup(PageHelper.ROLE);
066    }
067    
068    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
069    {
070        Map<String, Object> result = new HashMap<>();
071        List<I18nizableText> errors = new ArrayList<>();
072
073        Request request = ObjectModelHelper.getRequest(objectModel);
074        
075        String phoneNumber = request.getParameter("phone");
076        
077        String zoneId = request.getParameter("zone-id");
078        ZoneItem zoneItem = _resolver.resolveById(zoneId);
079        
080        // Get the register type
081        String register = zoneItem.getServiceParameters().getValue("register-type", false, "user-choice");
082        // We check if the admin choose it
083        if (register.equals("user-choice"))
084        {
085            // If not we get the register type chosen by the user
086            register = request.getParameter("register");
087            if (register == null)
088            {
089                errors.add(new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_ERROR_REGISTER"));
090            }
091        }
092        
093        // Get the subscribers list
094        String list = zoneItem.getServiceParameters().getValue("subscribers-list", false, "-");
095        // We check if the admin choose it
096        if (list.equals("-"))
097        {
098            // If not we get the list chosen by the user
099            list = request.getParameter("list");
100            if (list == null)
101            {
102                errors.add(new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_ERROR_DIRECTORY"));
103            }
104        }
105
106        if (_pageHelper.isCaptchaRequired(zoneItem.getZone().getPage()))
107        {
108            String captchaKey = request.getParameter("captcha-key");
109            String captchaValue = request.getParameter("captcha-value");
110        
111            // We check if the captcha is correct
112            if (!CaptchaHelper.checkAndInvalidate(captchaKey, captchaValue)) 
113            {
114                errors.add(new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_ERROR_CAPTCHA"));
115            }
116        }
117        
118        // We check if the phone number is correct
119        if (phoneNumber == null)
120        {
121            errors.add(new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_ERROR_PHONE"));
122        }
123        else
124        {
125            phoneNumber = phoneNumber.trim();           
126            phoneNumber = SMSHelper.transformPhoneNumber(phoneNumber);
127
128            if (!SMSHelper.checkPhoneNumber(phoneNumber))
129            {   
130                errors.add(new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_ERROR_PHONE"));
131            }
132            else if (!SMSHelper.PHONE_NUMBER_INTERNATIONAL_VALIDATOR.matcher(phoneNumber).matches())
133            {
134                errors.add(new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_ERROR_PHONE2"));                
135                getLogger().error("The phone number entered by the user: " + request.getParameter("phone") + ", we tried to insert this number: " + phoneNumber + ". This is not match the internationnal format. Look the global configuration.");
136            }
137        }
138        
139        // If there are no errors
140        if (errors.isEmpty())
141        {            
142            _process(result, phoneNumber, register, list);
143        }
144        else
145        {
146            result.put("error", errors);
147        }
148        
149        request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result);
150        
151        return EMPTY_MAP;
152    }
153
154    private void _process(Map<String, Object> result, String phoneNumber, String register, String list)
155    {
156        if (_subscriberDAO.numberAlreadyExists(phoneNumber, list))
157        {
158            if (register.equals("subscribe"))
159            {
160                result.put("messageError", new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_MESSAGE_ALREADY_RECORD"));
161            }
162            else
163            {
164                _subscriberDAO.deleteNumber(phoneNumber, list);
165                result.put("messageDelete", new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_MESSAGE_DELETE"));
166            }
167        }
168        else
169        {
170            if (register.equals("subscribe"))
171            {
172                _subscriberDAO.insertNumber(phoneNumber, list);
173                result.put("messageRecord", new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_MESSAGE_ADD"));
174            }
175            else
176            {
177                result.put("messageError", new I18nizableText("plugin.sms", "PLUGINS_SMS_SUBSCRIPTION_SERVICE_FORM_MESSAGE_NOT_RECORD"));                    
178            }
179        }
180    }
181}