unclecheese / silverstripe-graphql-forms
A POC for SilverStripe forms in graphql.
Installs: 230
Dependents: 2
Suggesters: 0
Security: 0
Stars: 0
Watchers: 3
Forks: 1
Open Issues: 2
Type:silverstripe-vendormodule
Requires
- silverstripe/admin: ^1.0
- silverstripe/framework: ^4.0
- silverstripe/graphql: 4.x-dev
Requires (Dev)
- phpunit/phpunit: ^5.7
- squizlabs/php_codesniffer: ^3.0
This package is auto-updated.
Last update: 2024-12-10 09:54:30 UTC
README
Really simple implementation of FormSchema
in graphql.
Installation
$ composer require unclecheese/silverstripe-graphql-forms:dev-master
Usage
Register your forms in your schema config
*app/_graphql/config.yml
registeredForms:
- 'MyProject\Pages\ContactPageController.ContactForm'
In this example, the key ContactForm
is the name of the form you will pass as an argument
to the Form
query in graphql (it's an enum).
The value can take on a number of different implementations. Here,
'MyProject\Pages\ContactPageController.ContactForm'
refers to:
ContactPageController.php
namespace MyProject\Pages; class ContactPageController extends Controller { public function ContactForm() { // return Form instance } }
You can also use a fully-qualified Form
subclass:
ContactForm: 'MyProject\Forms\ContactForm'
You can also map it to a method on a FormFactoryInterface
that is registered with the query creator
(see below).
ContactForm: 'myMethod'
Usage with Userforms
If you're using silverstripe/userforms
to generate forms in the CMS, there is a specialised
form factory bundled with this module to allow you to register these. Because they all share
the same controller class, you can instead refer to these forms by their link or ID.
MyCMSForm: 'who-we-are/contact-us'
Or, you can use an ID
MyCMSForm: 45
Form factories
By default, the forms are generated using the naming conventions above due to the DefaultFormFactory
being registered in the FormQueryCreator
. Its getFormByName
function resolves the mapping to an
actual Form
object.
If you have custom ways of generating forms, simply register a new factory.
class MyFormFactory implements FormFactoryInterface { public function getFormByName(string $name): ?Form { // Get a Form based on $name } }
Additionally, to map methods directly to forms, you can subclass DefaultFormFactory
.
class MyDefaultFormFactory extends DefaultFormFactory { public function MyForm() { // return instance of MyForm. The parent getFormByName() function checks if // this method is defined before advancing through any other logic. } }
Don't forget to register your form factories!
SilverStripe\Core\Injector\Injector:
UncleCheese\GraphQLForms\FormFactoryRegistry:
properties:
factories:
myFactory: '%$MyProject\MyFormFactory'
Querying
query {
form(name: MyForm) {
schema {
fields {
id
name
type
title
# Recursive, for composite fields
children {
name
type
title
}
}
actions {
name
title
}
}
}
}
Caveats
- Methods that generate forms must be deterministic! No hiding and showing fields based on state (at least not yet).
- If you're using an explicit instance of a
Form
subclass, it needs to be instantiable throughsingleton()
. Ensure that any required constructor params are auto-injected. - Doesn't do anything fancy like composite fields
- TODO: mutations, form submissions
- File uploads? Stop.