<?php

/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

class PlateAuthorizationApiController extends CController
{

/**
     * Plate Authorization User Widget
     *
     * Receive an XMLHttpRequest POST object, check if it is valid and authorized, call $this->newBlackWhiteList to store authorization's plate
     *
     * newBlackWhiteList($plateListId, $isBlacklist, $idIsCode = false, $plate = null, $refTimestamp = null, $nationality = null, $remoteService = false)
     * Notebook: Integrazione UserWidget Comune di Amalfi
     */
    private $errorStack;
    private $startDateTime;
    private $endDateTime;
    private $nowDateTime;
    
    //Info per admin
    private $num_of_request;
    private $total_requests;
    
    
 public function accessRules()
  {
    return array (
        array (
            'allow' 
        ) 
    );
  }

  protected function beforeAction($action)
  {
    set_time_limit ( 0 );
    return parent::beforeAction ( $action );
  }
    
    public function actionNewBlackWhiteListUserWidget()
    {
        
        
        if (isset(Yii::app()->params['allowUserWidgetAddPlate']) && Yii::app()->params['allowUserWidgetAddPlate']['enable']) {

            $plateAuthorizationUserWidget = array();
            
            if (isset($_POST['NewBlacklistForm']) && !isset($_POST['init'])) {
                $_POST['NewBlacklistForm']['localization'] = substr($_POST['NewBlacklistForm']['localization'], 0, 2);
                $lang = $_POST['NewBlacklistForm']['localization'];
                Yii::app()->language = $lang;
                
                $plateListId = Yii::app()->params['allowUserWidgetAddPlate']['plateListId'];
                              
                
                if($this->checkCaptcha() && $this->checkRules()){
                
                try {
                    $_ENV['token'] = $_POST['NewBlacklistForm']['token'];
           
                    Yii::import('application.controllers.PlateAuthorizationController');
                    
                    $obj = new PlateAuthorizationController("ZTL_Widget");
                    $obj->NewWhitelistAjax($plateListId, false, null, null, null, true);
                   
                    if($this->sendMail(Yii::app()->params['allowUserWidgetAddPlate']['mailUserTemplate'], 'user'))
                        {
                            if(Yii::app()->params['allowUserWidgetAddPlate']['sendEmailToAdmin']){
                                $this->sendMail("adminZtlWidget", 'admin');
                            }
                         $return = array(
                        'status' => 200,
                        'message' => "Success",
                        );
                    http_response_code(200);
                    }else{
                         $this->addError(Yii::t('ztlWidget', 'Unable to send Mail'));
                         $return = $this->errorRequest(401);
                         Yii::log("Error List: ". print_r($return,true), "info", "ZTLWidget.MailSendError");
                    }
                   

                } catch (Exception $e) {
                    $this->addError(Yii::t('ztlWidget', 'Forbidden'));
                    $return = $this->errorRequest(401);
                    Yii::log("Error List: ". print_r($return,true), "info", "ZTLWidget.HttpError");
                   /* $return = array(
                        'status' => 403,
                        'message' => "Error",
                    );
                    http_response_code(200);*/
                    
                }
                }else{
                    $this->addError(Yii::t('ztlWidget', 'Invalid Request'));
                    $return = $this->errorRequest(401);
                     Yii::log("Error List: ". print_r($return,true), "info", "ZTLWidget.HttpError");
                }
            }else{ 
            
            if (!isset($_POST['NewBlacklistForm']) && isset($_POST['init'])) {
                  
                /*
                 * Change Language
                 */
                $lang = substr($_POST['init']['localization'], 0, 2);
               
                Yii::app()->language = $lang;
                
                $params = array(
                    'ip' => $_SERVER['REMOTE_ADDR'],
                    'nameSite' => Yii::app()->params['allowUserWidgetAddPlate']['nameSite'],
                    'logoUrl' => Yii::app()->params['allowUserWidgetAddPlate']['logoUrl'],
                    'timestamp' => '',
                    'startEndDeltaTime' => Yii::app()->params['allowUserWidgetAddPlate']['startEndDeltaTime'],
                    'linkNote' => array(
                        'privacy'=>Yii::app()->params['allowUserWidgetAddPlate']['linkNote']['privacy'],
                        'ordinanze' =>Yii::app()->params['allowUserWidgetAddPlate']['linkNote']['ordinanze'],
                        'sitoComune' => Yii::app()->params['allowUserWidgetAddPlate']['linkNote']['sitoComune'],   
                        ),
                   );
                   foreach (Yii::app()->params['allowUserWidgetAddPlate']['request_type'] as $request){
                       $params['request_type'][] = $request;
                   }
                   $params['localization'] = array(
                        'name' => Yii::t('ztlWidget', 'First Name'),
                        'surname' => Yii::t('ztlWidget', 'Last Name'),
                        'phone' => Yii::t('ztlWidget', 'Phone'),
                        'email' => Yii::t('ztlWidget', 'Email'),
                        'request_type' => Yii::t('ztlWidget', 'Requested reason'),
                        'vehicle_nationality' => Yii::t('ztlWidget', 'Vehicle Nationality'),
                        'license_plate' => Yii::t('ztlWidget', 'Vehicle License Plate'),
                        'start_date' => Yii::t('ztlWidget', 'Start date and time of validity period'),
                        'end_date' => Yii::t('ztlWidget', 'End date and time of validity period'),
                        'privacy' => Yii::t('ztlWidget', 'I authorize the processing of personal personal data'),
                        'help' => Yii::t('ztlWidget', 'This service allows you to make a quickly requests for temporary access to the Limited Traffic Zone of {town}. To proceed, fill all fields with your data, the reasons for access and the date and time when the access will be made. At the end of the procedure you will receive an email with confirmation of the transit permit. The permit has a fixed duration of {max_time} hours, at the end of which the vehicle detected within the ZTL will be considered in violation. A maximum of {max_access} access requests per month is allowed. For more details contact the municipality at {emailOwner}',
                              array('{town}'=> Yii::app()->params['allowUserWidgetAddPlate']['nameOwner'],
                                    '{max_time}'=> Yii::app()->params['allowUserWidgetAddPlate']['startEndDeltaTime'],
                                    '{max_access}'=> Yii::app()->params['allowUserWidgetAddPlate']['numero_richieste_30_days'],
                                    '{emailOwner}'=>Yii::app()->params['allowUserWidgetAddPlate']['emailOwner'])),
                        'alert_messages' => Yii::t('ztlWidget', 'WARNING! The access permit will only be valid upon receipt of any confirmation email!') ,
                        'alert_messages2' => Yii::t('ztlWidget', 'WARNING! Always check on the municipality\'s website for any traffic restrictions!') ,
                        'request_button' => Yii::t('ztlWidget', 'Send'),
                        'validationName' => Yii::t('ztlWidget', 'Name required'),//Nome obbligatorio
                        'validationSurname' => Yii::t('ztlWidget', 'Surname required'),//Cognome obbligatorio
                        'validationPhone' => Yii::t('ztlWidget', 'Please! enter a valid mobile number'),//Prego inserire un numero di cellulare valido
                        'validationEmail' => Yii::t('ztlWidget', 'Please! enter a valid email address'),//Prego inserire un indirizzo email valido
                        'validationRequest' => Yii::t('ztlWidget', 'Invalid request reason'),//Motivo richiesta non valido
                        'validationCountry' => Yii::t('ztlWidget', 'Invalid country'),//Nazione non valida
                        'validationPlate' => Yii::t('ztlWidget', 'Please! enter the vehicle license number'),//Inserire la targa del veicolo
                        'validationStartDate' => Yii::t('ztlWidget', 'Select a valid date and time'),//Seleziona una data valida
                        'validationEndDate' => Yii::t('ztlWidget', 'Select a valid date and time'),//Seleziona una data valida
                        'validationPrivacy' => Yii::t('ztlWidget', 'You must authorize the processing of data to proceed')//Devi autorizzare il trattamento dei dati per proseguire



                       
                       );
                   
                   $return = array(
                        'status' => 200,
                        'message' => $params
                          );
                        http_response_code(200);
                 
            }else{ 
            $this->addError(Yii::t('ztlWidget', 'Forbidden')); 
            $return = $this->errorRequest(403);
            Yii::log("Error List: ". print_r($return,true), "info", "ZTLWidget.HttpError");
            
            
            }
            
            }
            
       
        } else {
            
            $this->addError(Yii::t('ztlWidget', 'Service is not active'));
            $return = $this->errorRequest(401);
            Yii::log("Error List: ". print_r($return,true), "info", "ZTLWidget.HttpError");

        }

        print_r(json_encode($return));
    
    }
    
    private function checkCaptcha(){
        
        $response = $_POST['NewBlacklistForm']['token'];//$_POST["g-recaptcha-response"];
	$url = 'https://www.google.com/recaptcha/api/siteverify';
	$data = array(
		'secret' => Yii::app()->params['allowUserWidgetAddPlate']['recaptcha_secret'],
		'response' => $_POST['NewBlacklistForm']['token']
	);
	$options = array(
		'http' => array (
			'method' => 'POST',
			'content' => http_build_query($data)
		)
	);
	$context  = stream_context_create($options);
	$verify = file_get_contents($url, false, $context);
	$captcha_success=json_decode($verify);
	if ($captcha_success->success==false) {
            $this->addError(Yii::t('ztlWidget', 'Invalid Recapcha'));
            
            Yii::log("Invalid Recapcha Error: ". print_r(($captcha_success->error), true), "info", "Captcha.ZTLWidget");
            /*
             * $captcha_success->success
             * missing-input-secret	The secret parameter is missing.
             * invalid-input-secret	The secret parameter is invalid or malformed.
             * missing-input-response	The response parameter is missing.
             * invalid-input-response	The response parameter is invalid or malformed.
             * bad-request              The request is invalid or malformed.
            */    
		return false;
	} else if ($captcha_success->success==true) {
           
            //Yii::log(print_r(($captcha_success), true), "info", "captcha_success");
            
		return true;
	}
           
    }
    
    private function checkRules(){
       
        //check if start date is before end date
        $UnixTimestamp = DateTime::createFromFormat( 'Y/m/d H:i', $_POST['NewBlacklistForm']['startDateTime'] );
        $start_dateTime = clone $UnixTimestamp;
        $_POST['NewBlacklistForm']['startDate'] = $start_dateTime->format(getFormat_Date());
        $_POST['NewBlacklistForm']['startTime'] = $start_dateTime->format(getFormat_Time());
        $end_dateTime = clone $UnixTimestamp;
        $end_dateTime->add(DateInterval::createFromDateString(Yii::app()->params['allowUserWidgetAddPlate']['startEndDeltaTime'].' hours'));
        $end_dateTime->modify("-1 second");
        $_POST['NewBlacklistForm']['endDate'] = $end_dateTime->format(getFormat_Date());
        $_POST['NewBlacklistForm']['endTime'] = $end_dateTime->format(getFormat_Time());
        $nowDateTime = new DateTime();
        $this->nowDateTime = $nowDateTime->format('d/m/Y H:i:s');
        $this->startDateTime = $start_dateTime->format('d/m/Y H:i:s');
        $this->endDateTime = $end_dateTime->format('d/m/Y H:i:s');
        if($start_dateTime <= $this->nowDateTime){
            $this->addError(Yii::t('ztlWidget', 'Start date and time cannot be before today'));
            Yii::log("Invalid StartTime: ".$start_dateTime->format('d/m/Y H:i:s')."  <= Now Time: ". $nowDateTime->format('d/m/Y H:i:s'), "info", "Injection.ZTLWidget");
            return false;
        }
           
        $sql = "SELECT code FROM plate_list WHERE id = ".Yii::app()->params['allowUserWidgetAddPlate']['plateListId'];
        $plateListId = Yii::app()->db->createCommand($sql)->queryRow();
        
        if(isEmpty($plateListId)){
            Yii::log("La lista ".Yii::app()->params['allowUserWidgetAddPlate']['plateListId'].". Controllare che il file local.php sia compilato correttamente", "info", "ZTLWidget.ListIdError");
            $this->addError(Yii::t('ztlWidget', 'Service is not active'));
            return false;
        }
       /*TODO    RegExpr Plate*/ 
        
        $plate = $_POST['NewBlacklistForm']['plate'];
        
       
        $sql = "SELECT COUNT(b.id) FROM vehicletable AS a LEFT JOIN whitelisttable AS b ON a.ID = b.VehicleID "
                . "WHERE a.targa = '".$plate."' AND b.epoch >= (NOW() - INTERVAL 30 DAY) AND b.list_code = ".$plateListId['code'];
                
        $num_of_request = Yii::app()->db->createCommand($sql)->queryScalar();
        $this->num_of_request = $num_of_request;
        $param_num_of_request = Yii::app()->params['allowUserWidgetAddPlate']['numero_richieste_30_days'];
        
        if ($num_of_request > $param_num_of_request) {
             Yii::log("Il numero di richieste supera il limite di ".$param_num_of_request." richieste ogni 30 giorni", "info", "ZTLWidget.NumOfRequest");
             $this->addError(Yii::t('ztlWidget', 'The number of requests exceeds the limit of {param_num_of_request} requests every 30 days', array ('{param_num_of_request}'=>$param_num_of_request)));
            return false;
        }               
        
        //Limite di accessi automatici al varco per finestre orarie : parametrizzato max 3 join tra whitelist ed abbonamento table
        //Cambiare GateID da -1 al numero del gate nel caso in cui nel widget fosse presente anche la scelta del gate.
        
        $sql = "SELECT count(*) FROM whitelisttable AS a LEFT JOIN abbonamentotable AS b ON a.AbbonamentoID = b.ID"
            ." WHERE (('".$start_dateTime->format('Y/m/d H:i:s')."' > b.DataInizio AND '".$start_dateTime->format('Y/m/d H:i:s')."' <= b.DataFine)" 
            ." OR ('".$end_dateTime->format('Y/m/d H:i:s')."' > b.DataInizio AND '".$end_dateTime->format('Y/m/d H:i:s')."' <= b.DataFine))" 
            ." AND b.list_code = ".$plateListId['code']." AND GateID = -1";
        
        $num_of_entry = Yii::app()->db->createCommand($sql)->queryScalar();
        $param_num_of_entry = Yii::app()->params['allowUserWidgetAddPlate']['disponibilita_varco'];
        if ($num_of_entry > $param_num_of_entry) {
             Yii::log("Il numero di richieste supera il limite di ".$param_num_of_entry." nella fascia oraria selezionata", "info", "ZTLWidget.NumOfEntry");
             $this->addError(Yii::t('ztlWidget', 'The number of requests exceeds the limit of {param_num_of_entry} in the selected time slot', array ('{param_num_of_entry}'=>$param_num_of_entry)));
            return false;
        }  
       
        //Per dati Admin
        $sql = "SELECT COUNT(b.id) FROM vehicletable AS a LEFT JOIN whitelisttable AS b ON a.ID = b.VehicleID "
                . "WHERE a.targa = '".$plate."' AND b.list_code = ".$plateListId['code'];
                
        $this->total_requests = Yii::app()->db->createCommand($sql)->queryScalar();
        
        ////Limiti nel calendario da Pasqua, area - zona pedonale, al 3 novembre 11.10 alle 11.50 chiusa, 12.10 aperta alle 12.50.
       
        return true; 
        
    }
    
    private function addError($error){
        $this->errorStack[] = $error;
    }
    
     private function errorRequest($status){
         $return = array(
                'status' => $status,
                'message' => $this->errorStack,
            );
            http_response_code($status);
            return $return;
    }
    
    private function sendMail($template,$type = null){
        
        $mail = new YiiMailer();
        $mail->setView($template.'_'.strtoupper($_POST['NewBlacklistForm']['localization']));
        
        switch ($type) {
            case "user":
                $mail->setData($this->getEmailUserData());
                $mail->setTo($_POST['NewBlacklistForm']['email']);
                break;
            case "admin":
                $mail->setData($this->getEmailAdminData());
                $mail->setTo(Yii::app()->params['allowUserWidgetAddPlate']['adminEmail']);
                break;
            default:
                
                break;
        }
              
	$mail->setFrom(Yii::app()->params['allowUserWidgetAddPlate']['emailOwner'], Yii::app()->params['allowUserWidgetAddPlate']['nameOwner']);
        $mail->setSubject("Conferma " . Yii::app()->params['allowUserWidgetAddPlate']['nameSite']);
	
	if ($mail->send()) {
            return true;
        } else {
            $this->addError(Yii::t('ztlWidget', 'Unable to send email to the user. Error: ') . $mail->getError());
            return false;
	}
        
        
    }
    
    private function getEmailUserData(){
        
        return array(           'plate' => $_POST['NewBlacklistForm']['plate'],
                                'code' => $_POST['NewBlacklistForm']['authorization_code'],
                                'vehicleNationality' => $_POST['NewBlacklistForm']['vehicleNationality'],
                                'nameUser' => $_POST['NewBlacklistForm']['name'],
                                'surnameUser' => $_POST['NewBlacklistForm']['surname'],
                                'emailUser' => $_POST['NewBlacklistForm']['email'],
                                'phoneUser' => $_POST['NewBlacklistForm']['phone'],
                                'startDateTime' => $this->startDateTime,
                                'endDateTime' => $this->endDateTime,
                                'nowTime' => $this->nowDateTime,
                                'note' => $_POST['NewBlacklistForm']['note'],
                                'nameOwner' => Yii::app()->params['allowUserWidgetAddPlate']['nameOwner'],
                                'emailOwner' => Yii::app()->params['allowUserWidgetAddPlate']['emailOwner'],
                                'siteName' => Yii::app()->params['allowUserWidgetAddPlate']['nameSite']);
      
    }
     private function getEmailAdminData(){
        
                
        return array(           'plate' => $_POST['NewBlacklistForm']['plate'],
                                'vehicleNationality' => $_POST['NewBlacklistForm']['vehicleNationality'],
                                'code' => $_POST['NewBlacklistForm']['authorization_code'],
                                'nameUser' => $_POST['NewBlacklistForm']['name'],
                                'surnameUser' => $_POST['NewBlacklistForm']['surname'],
                                'emailUser' => $_POST['NewBlacklistForm']['email'],
                                'phoneUser' => $_POST['NewBlacklistForm']['phone'],
                                'startDateTime' => $this->startDateTime,
                                'endDateTime' => $this->endDateTime,
                                'nowTime' => $this->nowDateTime,
                                'note' => $_POST['NewBlacklistForm']['note'],
                                'nameOwner' => Yii::app()->params['allowUserWidgetAddPlate']['nameOwner'],
                                'emailOwner' => Yii::app()->params['allowUserWidgetAddPlate']['emailOwner'],
                                'siteName' => Yii::app()->params['allowUserWidgetAddPlate']['nameSite'],
                                'num_of_request' => $this->num_of_request,
                                'total_requests' => $this->total_requests,
                                );
                        }
                        
    public function actionCheckValid($authorizationCode){
         
        if (isset($authorizationCode) && preg_match('/^[a-z0-9]{20}$/', $authorizationCode)){
           
            $sql = "SELECT a.GateID,a.TimeID,a.enabled,a.to_be_confirmed,b.DataInizio, b.DataFine 
                FROM whitelisttable AS a LEFT JOIN abbonamentotable AS b ON a.AbbonamentoID = b.ID 
                WHERE a.authorization_Code = '".$authorizationCode."'";
                
            $request = Yii::app()->db->createCommand($sql)->queryRow();
            $nowDateTime = new DateTime();
            if($request){
                $date = DateTime::createFromFormat( 'Y-m-d H:i:s', $request['DataFine'] );
                if($date <=  $nowDateTime){
                    
                    $params = array(
                            'DataInizio'=>$request['DataInizio'],
                            'DataFine'=>$request['DataFine'],
                            'authorized' => (bool) $request['enabled'],
                            'confirmed' => !$request['to_be_confirmed'],
                            'expired' => true
                                     );   
                
                    
                     }else{
                    
                    $params = array(
                            'DataInizio'=>$request['DataInizio'],
                            'DataFine'=>$request['DataFine'],
                            'authorized' => (bool) $request['enabled'],
                            'confirmed' => !$request['to_be_confirmed'],
                            'expired' => false
                                     );    
                            }
            }
            
            
            
            $return = array(
                        'status' => 200,
                        'message' => $params
                          );
                        http_response_code(200); 
        }else{
            $this->addError(Yii::t('ztlWidget', 'Forbidden')); 
            $return = $this->errorRequest(401);
            Yii::log("Sql-Injection authorizationCode: " . $authorizationCode, "info", "CheckValid.ZTLWidget");
            
        }
         
                        
         print_r(json_encode($return));                
        
    }
    
}
    