diff --git a/includes/abstract-integration.php b/includes/abstract-integration.php index 9c84d778a30e7ebefdbbf2a37325399ae290c460..5f1cb5e3b66f219233e77038870cef7a1b64e4b5 100644 --- a/includes/abstract-integration.php +++ b/includes/abstract-integration.php @@ -7,8 +7,6 @@ use WP_Error; use Exception; use TypeError; -use function WPCT_HTTP\wpct_http_post; - /** * Integration abstract class. * @@ -196,9 +194,9 @@ abstract class Integration extends Singleton ); $this->apply_pipes($hook['pipes'], $payload); $headers = $backend->get_headers(); - if (isset($hook['endpoint'])) { + if (isset($hook['method'], $hook['endpoint'])) { $url = $backend->get_endpoint_url($hook['endpoint']); - $res = wpct_http_post($url, [ + $res = $this->submit_rest($hook['method'], $url, [ 'data' => $payload, 'files' => $attachments, 'headers' => $headers, @@ -350,6 +348,36 @@ abstract class Integration extends Singleton ); } + /** + * Submit REST requests over HTTP methods. + * + * @since 3.0.4 + * + * @param string $method HTTP method (GET, POST, PUT, DELETE). + * @param string $url Target URL. + * @param array $args Request arguments. + * @return array|WP_Error Request response. + */ + private function submit_rest($method, $url, $args) + { + $m = strtolower($method); + $func = "\WPCT_HTTP\wpct_http_{$m}"; + if (!is_callable($func)) { + return new WP_Error( + 'http_method_not_allowed', + __("Unkown HTTP method: {$method}", 'wpct-erp-forms'), + ['status' => 405] + ); + } + + if (in_array($method, ['GET', 'DELETE'])) { + unset($args['headers']['Content-Type']); + $args['params'] = $args['data']; + } + + return $func($url, $args); + } + /** * JSON RPC login request. * diff --git a/includes/class-settings.php b/includes/class-settings.php index 0be9dc11299eca2263d2094abab4978ed1212ed3..6d5596c0165ad0d54cc82a863128b370264cab29 100644 --- a/includes/class-settings.php +++ b/includes/class-settings.php @@ -128,6 +128,10 @@ class Settings extends BaseSettings 'backend' => ['type' => 'string'], 'form_id' => ['type' => 'string'], 'endpoint' => ['type' => 'string'], + 'method' => [ + 'type' => 'string', + 'enum' => ['GET', 'POST', 'PUT', 'DELETE'], + ], 'pipes' => [ 'type' => 'array', 'items' => [ diff --git a/languages/wpct-erp-forms-ca.json b/languages/wpct-erp-forms-ca.json index bc75ec686cf58698f6fd4afe2fe3d4c06f27c7f1..b0c2fed9fff1a82f3bafafda65865567a3ee1f74 100644 --- a/languages/wpct-erp-forms-ca.json +++ b/languages/wpct-erp-forms-ca.json @@ -47,6 +47,7 @@ "Edit pipes": ["Editar tubs"], "Remove form": ["Eliminar formulari"], "Add Form": ["Afegir Formulari"], + "Add form": ["Afegir formulari"], "Form Hooks": ["Ganxos de Formulari"], "REST API": [""], "Model": [""], diff --git a/languages/wpct-erp-forms-en_US.json b/languages/wpct-erp-forms-en_US.json index 2ee75067d53593b7c7ceaa2114cb8a3bbfd7daa4..d6113fa74c8c74c5881caf79bac65786e40d765d 100644 --- a/languages/wpct-erp-forms-en_US.json +++ b/languages/wpct-erp-forms-en_US.json @@ -45,6 +45,7 @@ "Edit pipes": [""], "Remove form": [""], "Add Form": [""], + "Add form": [""], "Form Hooks": [""], "REST API": [""], "Model": [""], diff --git a/languages/wpct-erp-forms-es_ES.json b/languages/wpct-erp-forms-es_ES.json index e6236da8e96c46679e64018c0c506c0fb37ca535..19e10cdecc124a7b1d393fa46d3af9e6eede0768 100644 --- a/languages/wpct-erp-forms-es_ES.json +++ b/languages/wpct-erp-forms-es_ES.json @@ -45,6 +45,7 @@ "Edit pipes": ["Editar tubos"], "Remove form": ["Eliminar formulario"], "Add Form": ["A\u00f1adir Formulario"], + "Add form": ["A\u00f1adir formulario"], "Form Hooks": ["Ganchos de Formulario"], "REST API": [""], "Model": ["Modelo"], diff --git a/src/RestApiSettings/FormHooks/FormHook.jsx b/src/RestApiSettings/FormHooks/FormHook.jsx index 70003fe8e747ec0a50a0d0039b6e538743ea66e0..69a77d5715853607b8f4a9b925ef4c8fe3ce5468 100644 --- a/src/RestApiSettings/FormHooks/FormHook.jsx +++ b/src/RestApiSettings/FormHooks/FormHook.jsx @@ -1,6 +1,11 @@ // vendor import React from "react"; -import { TextControl, SelectControl, Button } from "@wordpress/components"; +import { + TextControl, + SelectControl, + Button, + __experimentalSpacer as Spacer, +} from "@wordpress/components"; import { useState, useRef, useEffect } from "@wordpress/element"; // source @@ -10,6 +15,25 @@ import useHookNames from "../../hooks/useHookNames"; import FormPipes from "../../FormPipes"; import { useI18n } from "../../providers/I18n"; +const methodOptions = [ + { + label: "GET", + value: "GET", + }, + { + label: "POST", + value: "POST", + }, + { + label: "PUT", + value: "PUT", + }, + { + label: "DELETE", + value: "DELETE", + }, +]; + function NewFormHook({ add }) { const __ = useI18n(); const [{ backends }] = useGeneral(); @@ -27,6 +51,7 @@ function NewFormHook({ add }) { const [name, setName] = useState(""); const [backend, setBackend] = useState(backendOptions?.[0].value || ""); + const [method, setMethod] = useState("POST"); const [endpoint, setEndpoint] = useState(""); const [formId, setFormId] = useState(formOptions?.[0].value || ""); const [nameConflict, setNameConflict] = useState(false); @@ -36,9 +61,17 @@ function NewFormHook({ add }) { setName(name.trim()); }; - const onClick = () => add({ name, backend, endpoint, form_id: formId }); + const onClick = () => + add({ name, backend, method, endpoint, form_id: formId }); - const disabled = !(name && backend && endpoint && formId && !nameConflict); + const disabled = !( + name && + backend && + method && + endpoint && + formId && + !nameConflict + ); return ( <div @@ -52,47 +85,89 @@ function NewFormHook({ add }) { style={{ display: "flex", gap: "1em", + flexWrap: "wrap", }} > - <TextControl - label={__("Name", "wpct-erp-forms")} - help={ - nameConflict - ? __("This name is already in use", "wpct-erp-forms") - : "" - } - value={name} - onChange={handleSetName} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Backend", "wpct-erp-forms")} - value={backend} - onChange={setBackend} - options={backendOptions} - __nextHasNoMarginBottom - /> - <TextControl - label={__("Endpoint", "wpct-erp-forms")} - value={endpoint} - onChange={setEndpoint} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Form", "wpct-erp-forms")} - value={formId} - onChange={setFormId} - options={formOptions} - __nextHasNoMarginBottom - /> - <Button - variant="primary" - onClick={() => onClick()} - style={{ marginTop: "auto", height: "32px" }} - disabled={disabled} - > - {__("Add", "wpct-erp-forms")} - </Button> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + label={__("Name", "wpct-erp-forms")} + help={ + nameConflict + ? __("This name is already in use", "wpct-erp-forms") + : "" + } + value={name} + onChange={handleSetName} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Backend", "wpct-erp-forms")} + value={backend} + onChange={setBackend} + options={backendOptions} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Method", "wpct-erp-forms")} + value={method || "POST"} + onChange={setMethod} + options={methodOptions} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + label={__("Endpoint", "wpct-erp-forms")} + value={endpoint} + onChange={setEndpoint} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Form", "wpct-erp-forms")} + value={formId} + onChange={setFormId} + options={formOptions} + __nextHasNoMarginBottom + /> + </div> + </div> + <Spacer paddingY="calc(8px)" /> + <div + style={{ + display: "flex", + gap: "1em", + flexWrap: "wrap", + }} + > + <div> + <label + style={{ + display: "block", + fontWeight: 500, + textTransform: "uppercase", + fontSize: "11px", + margin: 0, + marginBottom: "calc(4px)", + maxWidth: "100%", + }} + > + {__("Add form", "wpct-erp-forms")} + </label> + <Button + variant="primary" + onClick={() => onClick()} + style={{ width: "130px", justifyContent: "center", height: "32px" }} + disabled={disabled} + > + {__("Add", "wpct-erp-forms")} + </Button> + </div> </div> </div> ); @@ -151,42 +226,69 @@ export default function FormHook({ update, remove, ...data }) { style={{ display: "flex", gap: "1em", + flexWrap: "wrap", + }} + > + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + ref={nameInput} + label={__("Name", "wpct-erp-forms")} + help={ + nameConflict + ? __("This name is already in use", "wpct-erp-forms") + : "" + } + value={name} + onChange={handleSetName} + onFocus={() => (focus = true)} + onBlur={() => (focus = false)} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Backend", "wpct-erp-forms")} + value={data.backend} + onChange={(backend) => update({ ...data, backend })} + options={backendOptions} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Method", "wpct-erp-forms")} + value={data.method} + onChange={(method) => update({ ...data, method })} + options={methodOptions} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + label={__("Endpoint", "wpct-erp-forms")} + value={data.endpoint} + onChange={(endpoint) => update({ ...data, endpoint })} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Form", "wpct-erp-forms")} + value={data.form_id} + onChange={(form_id) => update({ ...data, form_id })} + options={formOptions} + __nextHasNoMarginBottom + /> + </div> + </div> + <Spacer paddingY="calc(8px)" /> + <div + style={{ + display: "flex", + gap: "1em", + flexWrap: "wrap", }} > - <TextControl - ref={nameInput} - label={__("Name", "wpct-erp-forms")} - help={ - nameConflict - ? __("This name is already in use", "wpct-erp-forms") - : "" - } - value={name} - onChange={handleSetName} - onFocus={() => (focus = true)} - onBlur={() => (focus = false)} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Backend", "wpct-erp-forms")} - value={data.backend} - onChange={(backend) => update({ ...data, backend })} - options={backendOptions} - __nextHasNoMarginBottom - /> - <TextControl - label={__("Endpoint", "wpct-erp-forms")} - value={data.endpoint} - onChange={(endpoint) => update({ ...data, endpoint })} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Form", "wpct-erp-forms")} - value={data.form_id} - onChange={(form_id) => update({ ...data, form_id })} - options={formOptions} - __nextHasNoMarginBottom - /> <div> <label style={{ diff --git a/src/RestApiSettings/FormHooks/index.jsx b/src/RestApiSettings/FormHooks/index.jsx index a61448d093857cb24eab23896db8af18ba922332..a8f659527d7d0930e30c2514027c411fc4044c46 100644 --- a/src/RestApiSettings/FormHooks/index.jsx +++ b/src/RestApiSettings/FormHooks/index.jsx @@ -9,12 +9,13 @@ import { useI18n } from "../../providers/I18n"; export default function FormHooks({ hooks, setHooks }) { const __ = useI18n(); const tabs = hooks - .map(({ backend, endpoint, form_id, name, pipes }) => ({ + .map(({ backend, method, endpoint, form_id, name, pipes }) => ({ name, title: name, - form_id, - endpoint, backend, + method, + endpoint, + form_id, pipes, })) .concat([ diff --git a/src/RpcApiSettings/FormHooks/FormHook.jsx b/src/RpcApiSettings/FormHooks/FormHook.jsx index e6f0de8a914dc940f408bf8bdab452d875f1554e..dc01898a8f2ea16ae9d53c9f8bc4681b89868412 100644 --- a/src/RpcApiSettings/FormHooks/FormHook.jsx +++ b/src/RpcApiSettings/FormHooks/FormHook.jsx @@ -1,6 +1,11 @@ // vendor import React from "react"; -import { TextControl, SelectControl, Button } from "@wordpress/components"; +import { + TextControl, + SelectControl, + Button, + __experimentalSpacer as Spacer, +} from "@wordpress/components"; import { useState, useRef, useEffect } from "@wordpress/element"; // source @@ -52,47 +57,80 @@ function NewFormHook({ add }) { style={{ display: "flex", gap: "1em", + flexWrap: "wrap", }} > - <TextControl - label={__("Name", "wpct-erp-forms")} - help={ - nameConflict - ? __("This name is already in use", "wpct-erp-forms") - : "" - } - value={name} - onChange={handleSetName} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Backend", "wpct-erp-forms")} - value={backend} - onChange={setBackend} - options={backendOptions} - __nextHasNoMarginBottom - /> - <TextControl - label={__("Model", "wpct-erp-forms")} - value={model} - onChange={setModel} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Form", "wpct-erp-forms")} - value={formId} - onChange={setFormId} - options={formOptions} - __nextHasNoMarginBottom - /> - <Button - variant="primary" - onClick={() => onClick()} - style={{ marginTop: "auto", height: "32px" }} - disabled={disabled} - > - {__("Add", "wpct-erp-forms")} - </Button> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + label={__("Name", "wpct-erp-forms")} + help={ + nameConflict + ? __("This name is already in use", "wpct-erp-forms") + : "" + } + value={name} + onChange={handleSetName} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Backend", "wpct-erp-forms")} + value={backend} + onChange={setBackend} + options={backendOptions} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + label={__("Model", "wpct-erp-forms")} + value={model} + onChange={setModel} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Form", "wpct-erp-forms")} + value={formId} + onChange={setFormId} + options={formOptions} + __nextHasNoMarginBottom + /> + </div> + </div> + <Spacer paddingY="calc(8px)" /> + <div + style={{ + display: "flex", + gap: "1em", + flexWrap: "wrap", + }} + > + <div> + <label + style={{ + display: "block", + fontWeight: 500, + textTransform: "uppercase", + fontSize: "11px", + margin: 0, + marginBottom: "calc(4px)", + maxWidth: "100%", + }} + > + {__("Add form", "wpct-erp-forms")} + </label> + <Button + variant="primary" + onClick={() => onClick()} + style={{ width: "130px", justifyContent: "center", height: "32px" }} + disabled={disabled} + > + {__("Add", "wpct-erp-forms")} + </Button> + </div> </div> </div> ); @@ -152,42 +190,60 @@ export default function FormHook({ update, remove, ...data }) { style={{ display: "flex", gap: "1em", + flexWrap: "wrap", + }} + > + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + ref={nameInput} + label={__("Name", "wpct-erp-forms")} + help={ + nameConflict + ? __("This name is already in use", "wpct-erp-forms") + : "" + } + value={name} + onChange={handleSetName} + onFocus={() => (focus = true)} + onBlur={() => (focus = false)} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Backend", "wpct-erp-forms")} + value={data.backend} + onChange={(backend) => update({ ...data, backend })} + options={backendOptions} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <TextControl + label={__("Model", "wpct-erp-forms")} + value={data.model} + onChange={(model) => update({ ...data, model })} + __nextHasNoMarginBottom + /> + </div> + <div style={{ flex: 1, minWidth: "150px", maxWidth: "250px" }}> + <SelectControl + label={__("Form", "wpct-erp-forms")} + value={data.form_id} + onChange={(form_id) => update({ ...data, form_id })} + options={formOptions} + __nextHasNoMarginBottom + /> + </div> + </div> + <Spacer paddingY="calc(8px)" /> + <div + style={{ + display: "flex", + gap: "1em", + flexWrap: "wrap", }} > - <TextControl - ref={nameInput} - label={__("Name", "wpct-erp-forms")} - help={ - nameConflict - ? __("This name is already in use", "wpct-erp-forms") - : "" - } - value={name} - onChange={handleSetName} - onFocus={() => (focus = true)} - onBlur={() => (focus = false)} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Backend", "wpct-erp-forms")} - value={data.backend} - onChange={(backend) => update({ ...data, backend })} - options={backendOptions} - __nextHasNoMarginBottom - /> - <TextControl - label={__("Model", "wpct-erp-forms")} - value={data.model} - onChange={(model) => update({ ...data, model })} - __nextHasNoMarginBottom - /> - <SelectControl - label={__("Form", "wpct-erp-forms")} - value={data.form_id} - onChange={(form_id) => update({ ...data, form_id })} - options={formOptions} - __nextHasNoMarginBottom - /> <div> <label style={{