Reputation: 499
I would like to have Silverstripe's userforms add on submit values to a CRM, namely Active Campaign.
I see there is a SubmittedForm class but how would I go about taking the data before it is submitted and submit it via my API as well?
Alternatively, is there a way that once the form data has been submitted to the DB it redirects to a custom page with the ID of the form that has just been submitted? Then I can grab the fields and submit to the API.
Upvotes: 0
Views: 493
Reputation: 24435
You can retrieve submitted form data from a specific UserDefinedForm page like this:
/** @var SubmittedForm[] $submissions */
$submissions = UserDefinedForm::get()->filter(['URLSegment' => 'my-integrated-form'])->Submissions();
Or retrieve all submissions for all user form pages:
$submissions = SubmittedForm::get();
From here to integrate your data to an external system you could write a BuildTask that does what you need to do. You could plug this into the crontask module, or the queuedjobs module to have it run on a schedule daily:
class IntegrateUserFormSubmissionsTask extends BuildTask
{
protected $title = 'Integrate userforms submissions somewhere';
protected $api;
public function run($request)
{
$submissions = SubmittedForm::get();
foreach ($submissions as $submission) {
$formatted = [
'user' => [
'first_name' => $submission->SubmittedBy()->FirstName,
'surname' => $submission->SubmittedBy()->Surname,
],
// ...
];
$this->getYourApi()->submitData($formatted);
}
}
public function getYourApi()
{
if (!$this->api) {
$this->api = new RestfulService(...);
}
return $this->api;
}
}
Of course this is just a quick example, you'd need to map your data structures. Take a look at SubmittedForm
for the actual submission structure, and note that most of the actual form field values will be under $submission->Values()
. You could use the SubmittedFormField::getExportValue
method to return something useful for all "values".
Note that I'd suggest strongly that you don't run this integration inline with extensions to the user defined form, since that will introduce a synchronous dependency which could prevent your forms from working if the other server went down, you experience network latency etc.
If you need a way of monitoring which records have been exported you could use a DataExtension to provide an "ExportedTimestamp" field or something which you could set when you've successfully sent the data to your API:
public function ExternalApiExtension extends DataExtension
{
private static $db = [
'LastExported' => 'SS_Datetime',
];
public function markAsExported()
{
$this->owner->LastExported = SS_Datetime::now();
$this->owner->write();
}
}
Apply the extension to SubmittedForm
with YAML configuration (plenty in the docs about this), then in your export BuildTask you can just add $submission->markAsExported();
when you've validated a successful result from your API. Include ->filter(['LastExported' => null])
or something in the filter for your DataList before you run through all your records.
Good luck!
Upvotes: 4
Reputation: 5875
I think you should be able to add a DataExtension
to SubmittedForm
that implements updateAfterProcess
.
It's an extension hook on SubmittedForm
that will be called once all user-data has been validated and the email (if applicable) has been sent.
Your extension could look like this:
<?php
class UserFormCRMExtension extends DataExtension
{
public function updateAfterProcess()
{
/** @var SubmittedFormField $field */
foreach ($this->owner->Values() as $field) {
/* prepare data for submittal to CRM */
}
/* send data to CRM */
}
}
Apply as usual, via config.yml
:
SubmittedForm:
extensions:
- UserFormCRMExtension
Upvotes: 1
Reputation: 762
You could go with extending the class and have it submitted manually, based on a certain prerequisite.
Same for redirection, you'll need to write an Extension.
Upvotes: 1