Hi all,
I want to send form data from a Uniform form directly into NocoDB (something like Airtaible). I have already managed to send the content against the API of NocoDB via a custom action.
But unfortunately NocoDB needs a multipart/form-data POST request if you want to send content that affects multiple tables. I have already adjusted the header in multipart/form-data and experimented a bit. But unfortunately I can’t find a way to send the content as multipart/form-data. In Postman it works fine.
I like to attach my CustomAction. Is it at all possible to send multipart/form-data from Remote::request()? Or do I have to go another way?
<?php
namespace Uniform\Actions;
use Exception;
use Kirby\Toolkit\A;
use Kirby\Http\Remote;
use Kirby\Toolkit\I18n;
class NocodbAction extends Action
{
/**
* Call a webhook
*/
public function perform()
{
$url = $this->requireOption('url');
$only = $this->option('only');
$except = $this->option('except');
$escape = $this->option('escapeHtml', true);
if (is_array($only)) {
$data = [];
foreach ($only as $key) {
$data[$key] = $this->form->data($key, '', $escape);
}
} else {
$data = $this->form->data('', '', $escape);
}
if (is_array($except)) {
foreach ($except as $key) {
unset($data[$key]);
}
}
$params = $this->option('params', []);
// merge the optional 'static' data from the action array with the form data
$data = array_merge(A::get($params, 'data', []), $data);
$params['data'] = $this->transformData($data);
if ($this->option('json') === true) {
$headers = ['Content-Type: application/json'];
$params['data'] = json_encode($params['data'], JSON_UNESCAPED_SLASHES);
} else {
$headers = ['Content-Type: multipart/form-data'];
#$headers = [];
}
$params['headers'] = array_merge(A::get($params, 'headers', []), $headers);
try {
$test = $this->request($url, $params);
$wurst = $test;
} catch (Exception $e) {
$this->fail(I18n::translate('uniform-webhook-error') . $e->getMessage());
}
}
protected function getElementById($array, $id)
{
foreach ($array as $element) {
if ($element->Id == intval($id)) {
if (property_exists($element, "Title")) {
return ["Id" => $element->Id, "Title" => $element->Title];
} elseif (property_exists($element, "Bereichsname")) {
return ["Id" => $element->Id, "Title" => $element->Bereichsname];
} else {
return $element;
}
}
}
return null; // If element with given ID not found, return null
}
protected function getArrayByIDs($array, $ids)
{
$result = [];
foreach ($ids as $id) {
$result[] = $this->getElementById($array, $id);
}
return $result;
}
protected function transformData(array $data)
{
$nocodb = $this->options["nocodb_options"];
return [
"Email" => $data['email'],
"Vorname" => $data['firstname'],
"Nachname" => $data['lastname'],
"Geburtstag" => $data['birthday'],
"Handynummer" => $data['mobile'],
"Adresse" => $data['adress'],
"Stadt" => $data['city'],
"PLZ" => (int) $data['plz'],
"Aufbau" => $data["availability_pre_event"] == "on" ? true : false,
"Verfügbarkeit_Anmerkung" => $data['availability_message'],
"Bereichswunsch_Anmerkung" => $data["area_preference_message"],
"Food" => $this->getElementById($nocodb["food"], $data["food"]),
"Kleidung" => $this->getElementById($nocodb["clothing"], $data["clothing"]),
"Availability" => $this->getArrayByIDs($nocodb["availability"], $data["availability"]),
"Preverence 1" => $this->getElementById($nocodb["preference"], $data["area_preference"]),
"Preverence 2" => $this->getElementById($nocodb["preference"], $data["area_second_preference"]),
];
}
/**
*
* @param string $url
* @param array $params
* @return RemoteResponse
*/
protected function request($url, $params)
{
return Remote::request($url, $params);
}
}