<?php
/**
 * Parses FormData (key value pairs) to put them in arrays.
 *
 * @package Ealab\Deployer
 * @author Quang-Minh DANG <quang-minh@emerya.fr>
 */

namespace EaLab\WP_Deployer\vendor\Ealab\Deployer\Utility;

/**
 * Parses FormData (key value pairs) to put them in arrays.
 *
 * @deprecated Use PostFormDataAsJsonParser for better support of fields with the same name.
 */
class PostFormDataParser {
	/**
	 * Converts a complete array of FormData key value pairs to an array with the keys converted to array keys.
	 *
	 * @param array $input_to_process The array to process.
	 *
	 * @return array The processed array.
	 */
	public static function convertAllFormDataKeyValueToArray( array $input_to_process ): array {
		$result = array();

		foreach ( $input_to_process as $key => $value ) {
			static::convertSingleFormDataKeyValueToArray( $key, $value, $result );
		}

		return $result;
	}

	/**
	 * Converts a single key value pair to an array.
	 *
	 * @param string     $key The key.
	 * @param mixed      $value The value.
	 * @param array|null $result Result array passed by reference.
	 */
	public static function convertSingleFormDataKeyValueToArray( string $key, $value, ?array &$result = array() ): void {
		$result = $result ?? array();

		if ( preg_match( '/^(.+?)(\[.*])/', $key, $matches ) ) {
			// There is a sub key.
			// Here, the parent_key variable may have brackets around
			// if we are in a recursive call.
			$parent_key = $matches[1];
			$sub_key    = $matches[2];

			if ( $sub_key ) {
				// Continue digging through the tree.
				// Parse again to get the complete remaining key part.
				preg_match( '/^(.+?)(\[.*].*)/', $key, $sub_matches );

				$trimmed_parent_key = trim( $parent_key, '[]' );

				if ( isset( $result[ $trimmed_parent_key ] ) && ! is_array( $result[ $trimmed_parent_key ] ) ) {
					// The form sent two input names referring to the same parent key,
					// but one is a scalar, and the other is an array.
					// This should never happen, but let's make this work be enforcing
					// the array over the scalar value.
					$result[ $trimmed_parent_key ] = array();
				}

				// Remove the brackets of parent_key in case of a recursive call.
				$handle = &static::getHandleOnNewOrExistingItem( $trimmed_parent_key, $result );
				static::convertSingleFormDataKeyValueToArray( $sub_matches[2], $value, $handle );

				return;
			}
		}

		// No sub key found. This is the final value. Assign the value to the appropriate tree keys.
		$handle = &static::getHandleOnNewOrExistingItem( trim( $key, '[]' ), $result );
		$handle = $value;
	}

	/**
	 * This method allows for [] syntax to add values instead of replacing the value.
	 *
	 * This is because [] is interpreted as an empty string. Without this method,
	 * we would overwrite the "" index instead of appending items.
	 *
	 * @param string $key The key.
	 * @param array  $arr The array to get the handle from.
	 *
	 * @return array|null The array, or may return null of not yet set.
	 */
	private static function &getHandleOnNewOrExistingItem( string $key, array &$arr ): ?array {
		if ( empty( $key ) ) {
			// Append an item and return its handle.
			$new_item = &$arr[];

			return $new_item;
		}

		$existing_item = &$arr[ $key ];

		return $existing_item;
	}
}