I'm trying to post the following html form using GuzzleHttp
but I'm unable to do so because of the error while setting the form_params
in the header. InvalidArgumentException: Header value must be scalar or null but array provided.
<form action="https://example.com/process" method="post">
<input type="hidden" name="data" value="<?php echo $base64_encrypted_json; ?>”>
<?php foreach($items_encoded as $item) { ?>
<input type="hidden" name="item_data[]" value="<?php echo $item; ?>”>
<?php } ?>
<input type="hidden" name="rid" value="example">
<input type="submit">
</form>
Here's my code in the constructor.
$this->setRequest(
new Request(
"POST",
$this->getConfig()->get(Module::MODULE_ENDPOINT_URL)["submit"]
)
);
/** @var array $submitDataArray */
$submitDataArray = $this->getConfig()->get(Module::MODULE_SUBMIT_REQUEST_DATA_CONFIG)->toArray();
$submitDataArray["data"] = json_encode($submitDataArray["data"]);
/** @var array $splitItemsData */
$splitItemsData = str_split(json_encode($submitDataArray["itemData"], true), 800);
/** @var array $itemDataEncoded */
$itemDataEncoded = [];
foreach ($splitItemsData as $itemDataString) {
$itemDataEncoded[] = json_encode($itemDataString);
}
$submitDataArray["itemData"] = $itemDataEncoded;
$submitDataModel = (new SubmitDataModel())->exchangeArray($submitDataArray);
$this->setSubmitDataModel($submitDataModel);
And here's my init()
method.
public function init(): void
{
/** @var array $submitDataModel */
$submitDataModel = $this->getSubmitDataModel()->exchangeArray();
/** @var array $formParams */
$formParams = array();
$formParams["rid"] = $submitDataModel["rid"];
$formParams["data"] = $submitDataModel["data"];
$formParams["item_data"] = $submitDataModel["itemData"];
$this->getRequest()->withHeader("Content-Type", "application/x-www-form-urlencoded");
$this->getRequest()->withHeader("form_params", $formParams);
}
The $submitDataArray
is as below
rid = "sandbox"
data = "{"username":"sandbox","request_data":{"return_urls":{"abort":"https:\/\/example.com\/checkout\/abort","fail":"https:\/\/example.com\/checkout\/rejected","success":"https:\/\/example.com\/checkout\/success","return_data":"https:\/\/example.com\/c832jdafs94kb"},"request_type":"standard_finance_request","test_mode":1,"order_details":{"order_id":"","currency":"GBP"},"customer_details":{"firstnames":"","surname":"","email":"","phone":"","address":"","city":"","country":"","postcode":"","dob":"","delivery_address":"","delivery_city":"","delivery_postcode":"","delivery_country":"UK"}}}"
itemData = {array} [1]
0 = ""[{\"description\":\"\",\"quantity\":0,\"price\":0}]""
I've skipped some unnecessary details for the sake of staying concise.
Update:
I've also tried multipart
to handle the array but still no help.
$this->getRequest()->withHeader("Content-Type", "multipart/form-data");
$this->getRequest()->withHeader("multipart", $formParams);
Thanks to @ITgoldman for the lead. I've refactored part of my code as below and it has worked for me.
$this->getRequest()->withHeader("Content-Type", "application/x-www-form-urlencoded");
$this->getRequest()->withBody(\GuzzleHttp\Psr7\Utils::Streamfor(http_build_query($formParams)));
Here's how it works. http_build_query()
function converts an array into a query string which can then be converted into a \Psr\Http\Message\StreamInterface
using \GuzzleHttp\Psr7\Utils::Streamfor()
method to be used with withBody()
method.