<?php
/**
 * MachForm
 * 
 * © 2007–2025 Appnitro Software. All rights reserved.
 * 
 * This source code is proprietary and may not be copied, modified,
 * or distributed in any form without express written permission from Appnitro Software.
 * 
 * License information: https://www.machform.com/license-agreement/
 */
	$is_ajax = true;

	require('config.php');
	require('lib/db-session-handler.php');
	require('includes/init.php');
	require('includes/db-core.php');
	require('includes/helper-functions.php');
	require('includes/check-session.php');
	
	require('includes/filter-functions.php');
	require('lib/htmlpurifier/HTMLPurifier.standalone.php');
	
	$_POST = json_decode(file_get_contents('php://input'), true);

	$dbh = mf_connect_db();
	$mf_settings = mf_get_settings($dbh);

	//check for max_input_vars
	mf_init_max_input_vars();
	
	$element_properties_array = mf_sanitize($_POST['fp']);
	$form_id				  = (int) $_POST['form_id'];
	$csrf_token 	   		  = isset($_POST['csrf_token']) ? trim($_POST['csrf_token']) : false;

	//validate CSRF token
	mf_verify_csrf_token($csrf_token);

	$response_data 	  = new stdClass();
	
	//initialize HTML purifier
	$htmlpurifier_config = HTMLPurifier_Config::createDefault();
	$htmlpurifier_config->set('Attr.AllowedFrameTargets', array('_blank'));
	
	//check for the temporary folder, create it if not exist
	if(!file_exists($mf_settings['upload_dir']."/temp")){
		$old_mask = umask(0);
		mkdir($mf_settings['upload_dir']."/temp",0755);
		umask($old_mask);

		@file_put_contents($mf_settings['upload_dir']."/temp/index.html",' ');
	}

	//if temp folder is writable, set the htmlpurifier cache path there
	//otherwise disable the cache
	if(is_writable($mf_settings['upload_dir']."/temp")){
		$htmlpurifier_config->set('Cache.SerializerPath', $mf_settings['upload_dir']."/temp");
	}else{
		$htmlpurifier_config->set('Cache.DefinitionImpl', null);
	}
	
	$purifier = new HTMLPurifier($htmlpurifier_config);
	
	$updated_element_id = ''; 
	
	//loop through each element properties
	if(!empty($element_properties_array)){
		foreach($element_properties_array as $element_properties){
			
			unset($element_properties['is_db_live']);
			unset($element_properties['last_option_id']); //this property exist for choices field type
			unset($element_properties['page_total']); //this property exist for page break field type
			unset($element_properties['deletion_confirmed']);
			
			$element_options = array();
			$element_options = $element_properties['options'] ?? false;
			unset($element_properties['options']);

			$element_properties['id'] = htmlentities($element_properties['id']);

			/***************************************************************************************************************/	
			/* 1. Synch into ap_elements_options table																   	   */
			/***************************************************************************************************************/
			// This is only necessary for multiple choice, checkboxes, dropdown and matrix field
			if(in_array($element_properties['type'],array('radio','checkbox','select'))){
				
				//delete any previous records of this element
				$query = "DELETE FROM 
									 ".MF_TABLE_PREFIX."element_options
								WHERE
									 form_id = :form_id AND element_id = :element_id and live='2'"; 
				
				$params = array(':form_id' => $form_id,
								':element_id' => $element_properties['id']);	
				
				mf_do_query($query,$params,$dbh);
				
				//insert the new options
				$query = "INSERT INTO 
									`".MF_TABLE_PREFIX."element_options` 
									(`form_id`,`element_id`,`option_id`,`position`,`option`,`option_is_default`,`option_is_hidden`,`live`) 
							  VALUES 
							  		(:form_id,:element_id,:option_id,:position,:option,:is_default,:is_hidden,'2');"; 
				
				foreach ($element_options as $option_id=>$value){
					
					$params = array(':form_id' => $form_id,
									':element_id' => $element_properties['id'],
									':option_id' => $option_id,
									':position' => $value['position'],
									':option' => $value['option'],
									':is_default' => $value['is_default'],
									':is_hidden' => $value['is_hidden']);
					mf_do_query($query,$params,$dbh);
				}
				
				
			}else if($element_properties['type'] == 'matrix'){
				$column_data = array();
				$column_data = $element_options[$element_properties['id']]['column_data'];
				
				foreach ($element_options as $m_element_id=>$value){
					
					//delete any previous records of this element	
					$query = "DELETE FROM 
										 ".MF_TABLE_PREFIX."element_options
									WHERE
										 form_id = :form_id AND element_id = :element_id and live='2'";
					
					
					$params = array(':form_id' => $form_id,
									':element_id' => $m_element_id);	
					mf_do_query($query,$params,$dbh);
									
					
					//insert the new options		
					$query = "INSERT INTO 
										`".MF_TABLE_PREFIX."element_options` 
										(`form_id`,`element_id`,`option_id`,`position`,`option`,`option_is_default`,`option_is_hidden`,`live`) 
								  VALUES 
								   		(:form_id,:element_id,:option_id,:position,:option,'0','0','2');";
					 
					foreach ($column_data as $option_id=>$data){
						$params = array(':form_id' => $form_id,
										':element_id' => $m_element_id,
										':option_id' => $option_id ,
										':position' => $data['position'],
										':option' => $data['column_title']);
						mf_do_query($query,$params,$dbh);
					}
					
				}
			}
			
			/***************************************************************************************************************/	
			/* 2. Synch into ap_form_elements table																	   	   */
			/***************************************************************************************************************/
			$update_values = '';
			$params = array();
			
			//dynamically create the sql update string, based on the input given
			foreach ($element_properties as $key=>$value){
				//purify user inputs, clean xss payload, for any value with the length more than 1
				if(strlen((string) $value) > 1){
					$value = $purifier->purify($value);
				}
				
				$update_values .= "`element_{$key}`= :element_{$key},";
				$params[':element_'.$key] = $value;
			}
			$update_values = rtrim($update_values,',');
			
			$query = "UPDATE `".MF_TABLE_PREFIX."form_elements` set 
										$update_values
								  where 
							  	  		form_id = :form_id and element_id = :w_element_id";
										
			$params[':form_id'] = $form_id;
			$params[':w_element_id'] = $element_properties['id'];
			
			mf_do_query($query,$params,$dbh);
										
			$updated_element_id .= '#li_'.$element_properties['id'].',';
			
			//if this is matrix field, the element title need to be updated again from the options, the position as well
			if($element_properties['type'] == 'matrix'){
				
				$query = "UPDATE 
								`".MF_TABLE_PREFIX."form_elements` 
							 SET 
								`element_title` = :element_title,
								`element_position` = :element_position		
						   WHERE 
								form_id = :form_id and element_id = :element_id";
				
				
				foreach ($element_options as $m_element_id=>$value){
					
					$params = array();
					$params[':element_title'] 		= $value['row_title'];
					$params[':element_position']	= $value['position'];
					$params[':form_id']				= $form_id;
					$params[':element_id']			= $m_element_id;
					
					mf_do_query($query,$params,$dbh);	
				} //end foreach element_options
			}
		}
	}
	
	$updated_element_id = rtrim($updated_element_id,',');
	
	$response_data->status    			= "ok";
	$response_data->updated_element_id 	= $updated_element_id;
	
	$response_json = json_encode($response_data);
	
	echo $response_json;
	
?>