<?php
defined( 'ABSPATH' ) or exit;   // show a blank page if try to access this file directly

require_once( EWZ_PLUGIN_DIR . "classes/ewz-webform.php");
require_once( EWZ_PLUGIN_DIR . "classes/ewz-layout.php");
require_once( EWZ_PLUGIN_DIR . "classes/validation/ewz-input.php");

/* Validation for the forms on Webforms page */

class Ewz_Webform_Input extends Ewz_Input
{

    /**
     * @param array<mixed> $form_data
     *
     * @return void
     */
     function __construct( $form_data ) {
         parent::__construct( $form_data );

        /* rules('type') specifies the function called to validate, defined either here or in ewz-input.php */
        /* rules('val') defines extra args to pass */
         $this->rules = array(

                '_wp_http_referer' =>  array( 'type' => 'to_string', 'req' => false, 'val' => '' ),
                  'ewzmode'        =>  array( 'type' => 'fixed',      'req' => true,  'val' => 'webform' ),
                  'ewznonce'       =>  array( 'type' => 'anonce',     'req' => true,  'val' => '' ),
                  'layout_id'      =>  array( 'type' => 'to_seq',     'req' => true,  'val' => ['len' => 10] ),
                  'num_items'      =>  array( 'type' => 'to_seq',     'req' => false, 'val' => ['len' => 5] ),
                  'page'           =>  array( 'type' => 'fixed',      'req' => true,  'val' => 'entrywizard' ),
                  'prefix'         =>  array( 'type' => 'v_prefix',   'req' => false, 'val' => ['len' => 75] ),
                  'apply_prefix'   =>  array( 'type' => 'to_bool',    'req' => false, 'val' => '' ),
                  'gen_fname'      =>  array( 'type' => 'to_bool',    'req' => false, 'val' => '' ),
                  'upload_open'    =>  array( 'type' => 'to_bool',    'req' => false, 'val' => '' ),
                  'o_user'         =>  array( 'type' => 'v_users',    'req' => false, 'val' => ['len' => 20] ),
                  'webform_id'     =>  array( 'type' => 'to_seq',     'req' => false, 'val' => ['len' => 10] ),
                  'webform_ident'  =>  array( 'type' => 'ident',      'req' => true,  'val' => ['len' => 15] ),
                  'webform_title'  =>  array( 'type' => 'to_string',  'req' => true,  'val' => ['len' => 100] ),
                  'openwebform'    =>  array( 'type' => 'to_seq',     'req' => false, 'val' => ['len' => 10] ),
                  'auto_close'     =>  array( 'type' => 'to_bool',    'req' => false, 'val' => '' ),
                  'auto_close_date' =>  array( 'type' => 'v_date',     'req' => false, 'val' => '' ),
                  'auto_close_time' =>  array( 'type' => 'v_time',     'req' => false, 'val' => '' ),
                  'auto_open'       =>  array( 'type' => 'to_bool',    'req' => false, 'val' => '' ),
                  'auto_open_date'  =>  array( 'type' => 'v_date',     'req' => false, 'val' => '' ),
                  'auto_open_time'  =>  array( 'type' => 'v_time',     'req' => false, 'val' => '' ),
                  'archive_id'      =>  array( 'type' => 'to_string',     'req' => false, 'val' => ['len' => 16] ),
                  );
        $this->validate();
     }

    /**
     * @return boolean  true on success
     */
     function validate( ){

        // an unchecked checkbox does not create any matching value in $_POST
        if ( !array_key_exists( 'upload_open', $this->input_data ) ) {
            $this->input_data['upload_open'] = false;
        }
        if ( !array_key_exists( 'apply_prefix', $this->input_data ) ) {
            $this->input_data['apply_prefix'] = false;
        }
        if ( !array_key_exists( 'gen_fname', $this->input_data ) ) {
            $this->input_data['gen_fname'] = false;
        }
        if ( !array_key_exists( 'auto_close', $this->input_data ) ) {
            $this->input_data['auto_close'] = false;
        }
        if ( !array_key_exists( 'auto_open', $this->input_data ) ) {
            $this->input_data['auto_open'] = false;
        }
        $closedt = null;
        if( $this->input_data['auto_close']){
            if( !( isset( $this->input_data['auto_close_date'] ) &&  isset( $this->input_data['auto_close_time'] ) ) ){
                throw new EWZ_Exception( 'Invalid input date' );
            }
            $closedt =  Ewz_Base::datetime_to_timestamp( $this->input_data['auto_close_date'] . ' ' . $this->input_data['auto_close_time']  );

            $now = time();  // current Unix timestamp
            if( $closedt < $now + 30 ){
                throw new EWZ_Exception( 'Input date too early' );
            }
        }
        if( $this->input_data['auto_open']){
            if( !( isset( $this->input_data['auto_open_date'] ) &&  isset( $this->input_data['auto_open_time'] ) ) ){
                throw new EWZ_Exception( 'Invalid input date' );
            }
            $dt =  Ewz_Base::datetime_to_timestamp( $this->input_data['auto_open_date'] . ' ' . $this->input_data['auto_open_time']  );

            $now = time();  // current Unix timestamp
            if( $dt < $now + 30 ){
                throw new EWZ_Exception( 'Input date too early' );
            }
        }


        parent::validate();

        return true;
     }

     //****** All v_.... functions must return a boolean or raise an exception **************/

    /**
     * @param mixed $value
     * @param string $arg
     *
     * @return boolean
     */
     function v_date( $value, $arg ){
         $timestamp = strtotime( $value );
         if( !$timestamp ){
             throw new EWZ_Exception( 'Bad input for date' );
         }
         return true;
     }

    /**
     * @param mixed $value
     * @param string $arg
     *
     * @return boolean
     */
     function v_time( $value, $arg ){
         if( !is_string( $value ) ){
             throw new EWZ_Exception( 'Bad input for time' );
         }
         return true;
     }

    /**
     * @param mixed $value
     * @param array<mixed> $arg
     *
     * @return boolean
     */
     function v_prefix( $value, $arg ){
         if( !is_string( $value ) ){
             throw new EWZ_Exception( 'Bad input for prefix' );
         }
         if( isset($arg['len'] ) && ( strlen( $value ) > $arg['len'] )){
              throw new EWZ_Exception( 'Prefix too long' );
         }
         if( !preg_match( '/^[\[\]A-Z0-9~\-_]*$/i', $value ) ){
             throw new EWZ_Exception( 'Invalid character in prefix' );
         }
         return true;
     }

    /**
     * @param mixed $value
     * @param array<mixed> $arg
     *
     * @return boolean
     */
     function v_users( $value, $arg ){
         if( !is_array( $value ) ){
             throw new EWZ_Exception( 'Bad input for user' );
         }
         foreach( $value as $key => $uid ){
             if( !self::to_seq( $value[$key], $arg ) ){   // seq potentially changes first arg
                 throw new EWZ_Exception( "Bad value '$uid' for user" );
             }
         }
         return true;
     }
}