Skip to content
POC for graphql forms
PHP JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
_config
docs/en
src New form reference Oct 19, 2019
tests
.editorconfig
.eslintrc.js
.gitattributes Initial commit Sep 13, 2019
.gitignore
.nvmrc
.scrutinizer.yml
.travis.yml
CONTRIBUTING.md Initial commit Sep 13, 2019
LICENSE.md
README.md
_config.php
code-of-conduct.md
composer.json
phpcs.xml.dist
phpunit.xml.dist

README.md

SilverStripe graphql forms (POC)

Really simple implementation of FormSchema in graphql.

Installation

$ composer require unclecheese/silverstripe-graphql-forms:dev-master

Usage

Register your forms withFormQueryCreator.

UncleCheese\GraphQLForms\FormQueryCreator:
  registered_forms:
    ContactForm: '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\FormQueryCreator:
    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 through singleton(). Ensure that any required constructor params are auto-injected.
  • Doesn't do anything fancy like composite fields
  • TODO: mutations, form submissions
  • File uploads? Stop.
You can’t perform that action at this time.