Skip to content

Commit aa62538

Browse files
committed
feat: grist add-on first commit
1 parent a337958 commit aa62538

5 files changed

Lines changed: 474 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Grist Addon for Forms Bridge
2+
3+
This addon integrates Forms Bridge with Grist using its REST API.
4+
5+
## Features
6+
7+
- Connect WordPress forms to Grist databases
8+
- Map form fields to Grist table columns
9+
- Support for all Grist column types (Text, Numeric, Bool, Date, DateTime, Choice, Ref, RefList)
10+
- Automatic type mapping between WordPress and Grist
11+
12+
## Requirements
13+
14+
- Forms Bridge plugin installed and activated
15+
- Grist account with API access
16+
- Grist API token
17+
18+
## Setup
19+
20+
1. **Install the addon**: Place the `grist` folder in `forms-bridge/addons/`
21+
2. **Enable the addon**: Go to Forms Bridge settings and enable the Grist addon
22+
3. **Configure backend**:
23+
- Go to Forms Bridge → Backends
24+
- Add a new backend with your Grist API URL (e.g., `https://docs.getgrist.com`)
25+
- Add your Grist API token as the access token
26+
4. **Create a bridge**:
27+
- Go to Forms Bridge → Bridges
28+
- Add a new bridge with the Grist addon
29+
- Select your form and the Grist backend
30+
- Set the endpoint to your Grist table API (e.g., `/api/tables/{tableId}/records`)
31+
- Map your form fields to Grist columns
32+
33+
## API Endpoints
34+
35+
Common Grist API endpoints:
36+
- `/api/docs` - API documentation
37+
- `/api/tables` - List tables
38+
- `/api/tables/{tableId}` - Get table info
39+
- `/api/tables/{tableId}/records` - Get/add records
40+
- `/api/tables/{tableId}/schema` - Get table schema
41+
42+
## Field Mapping
43+
44+
Grist column types are automatically mapped to appropriate form field types:
45+
46+
| Grist Type | Form Type |
47+
|------------|-----------|
48+
| Text | text |
49+
| Numeric | number |
50+
| Bool | boolean |
51+
| Date | string |
52+
| DateTime | string |
53+
| Choice | string |
54+
| Ref | string |
55+
| RefList | array |
56+
57+
## Troubleshooting
58+
59+
- **Connection issues**: Verify your Grist API URL and token are correct
60+
- **Field mapping errors**: Check that your form fields match the Grist column types
61+
- **Permission errors**: Ensure your API token has write access to the target table
62+
63+
## Support
64+
65+
For support, please open an issue on the Forms Bridge GitHub repository.
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
<?php
2+
3+
namespace FORMS_BRIDGE;
4+
5+
if ( ! defined( 'ABSPATH' ) ) {
6+
exit();
7+
}
8+
9+
require_once 'class-grist-form-bridge.php';
10+
11+
/**
12+
* Grist addon class.
13+
*/
14+
class Grist_Addon extends Addon {
15+
16+
/**
17+
* Handles the addon's title.
18+
*
19+
* @var string
20+
*/
21+
const TITLE = 'Grist';
22+
23+
/**
24+
* Handles the addon's name.
25+
*
26+
* @var string
27+
*/
28+
const NAME = 'grist';
29+
30+
/**
31+
* Handles the addon's custom bridge class.
32+
*
33+
* @var string
34+
*/
35+
const BRIDGE = '\FORMS_BRIDGE\Grist_Form_Bridge';
36+
37+
/**
38+
* Performs a request against the backend to check the connection status.
39+
*
40+
* @param string $backend Backend name.
41+
*
42+
* @return boolean
43+
*/
44+
public function ping( $backend ) {
45+
$bridge = new Grist_Form_Bridge(
46+
array(
47+
'name' => '__grist-' . time(),
48+
'backend' => $backend,
49+
'endpoint' => '/api/docs',
50+
'method' => 'GET',
51+
)
52+
);
53+
54+
$backend = $bridge->backend;
55+
if ( ! $backend ) {
56+
Logger::log( 'Grist backend ping error: Bridge has no valid backend', Logger::ERROR );
57+
return false;
58+
}
59+
60+
$credential = $backend->credential;
61+
if ( ! $credential ) {
62+
Logger::log( 'Grist backend ping error: Backend has no valid credential', Logger::ERROR );
63+
return false;
64+
}
65+
66+
$access_token = $credential->get_access_token();
67+
68+
if ( ! $access_token ) {
69+
Logger::log( 'Grist backend ping error: Unable to recover the credential access token', Logger::ERROR );
70+
return false;
71+
}
72+
73+
return true;
74+
}
75+
76+
/**
77+
* Performs a GET request against the backend endpoint and retrive the response data.
78+
*
79+
* @param string $endpoint Grist endpoint.
80+
* @param string $backend Backend name.
81+
*
82+
* @return array|WP_Error
83+
*/
84+
public function fetch( $endpoint, $backend ) {
85+
$backend = FBAPI::get_backend( $backend );
86+
if ( ! $backend ) {
87+
return new WP_Error( 'invalid_backend' );
88+
}
89+
90+
$credential = $backend->credential;
91+
if ( ! $credential ) {
92+
return new WP_Error( 'invalid_credential' );
93+
}
94+
95+
$access_token = $credential->get_access_token();
96+
if ( ! $access_token ) {
97+
return new WP_Error( 'invalid_credential' );
98+
}
99+
100+
$response = http_bridge_get(
101+
$backend->base_url . $endpoint,
102+
array(),
103+
array(
104+
'Authorization' => "Bearer {$access_token}",
105+
'Accept' => 'application/json',
106+
)
107+
);
108+
109+
if ( is_wp_error( $response ) ) {
110+
return $response;
111+
}
112+
113+
return $response;
114+
}
115+
116+
/**
117+
* Performs an introspection of the backend API and returns a list of available endpoints.
118+
*
119+
* @param string $backend Target backend name.
120+
* @param string|null $method HTTP method.
121+
*
122+
* @return array|WP_Error
123+
*/
124+
public function get_endpoints( $backend, $method = null ) {
125+
// Grist doesn't have a standard endpoint discovery API
126+
// Return common Grist API endpoints
127+
return array(
128+
'/api/docs',
129+
'/api/tables',
130+
'/api/records',
131+
);
132+
}
133+
134+
/**
135+
* Performs an introspection of the backend endpoint and returns API fields
136+
* and accepted content type.
137+
*
138+
* @param string $endpoint Grist endpoint.
139+
* @param string $backend Backend name.
140+
* @param string|null $method HTTP method.
141+
*
142+
* @return array List of fields and content type of the endpoint.
143+
*/
144+
public function get_endpoint_schema( $endpoint, $backend, $method = null ) {
145+
if ( 'POST' !== $method ) {
146+
return array();
147+
}
148+
149+
$bridge = null;
150+
$bridges = FBAPI::get_addon_bridges( self::NAME );
151+
foreach ( $bridges as $candidate ) {
152+
$data = $candidate->data();
153+
if ( ! $data ) {
154+
continue;
155+
}
156+
157+
if (
158+
$data['endpoint'] === $endpoint &&
159+
$data['backend'] === $backend
160+
) {
161+
/**
162+
* Current bridge.
163+
*
164+
* @var Grist_Form_Bridge
165+
*/
166+
$bridge = $candidate;
167+
}
168+
}
169+
170+
if ( ! isset( $bridge ) ) {
171+
return array();
172+
}
173+
174+
$fields = $bridge->get_fields();
175+
176+
if ( is_wp_error( $fields ) ) {
177+
return array();
178+
}
179+
180+
$schema = array();
181+
foreach ( $fields as $field ) {
182+
$schema[] = array(
183+
'name' => $field['name'],
184+
'schema' => array( 'type' => $field['type'] ),
185+
);
186+
}
187+
188+
return $schema;
189+
}
190+
}
191+
192+
Grist_Addon::setup();

0 commit comments

Comments
 (0)