From 279b61f698708b651c0cae348a1f5b496c553f49 Mon Sep 17 00:00:00 2001 From: Michael Nowina-Krowicki Date: Wed, 28 Aug 2019 15:07:20 +0930 Subject: [PATCH 1/2] SilverStripe 4 upgrade --- README.md | 31 +-- _config.php | 1 - _config/config.yml | 6 + _config/extensions.yml | 3 - _config/legacy.yml | 9 + code/controllers/TypeformSubmissionAdmin.php | 20 -- code/extensions/TypeformExtension.php | 42 --- .../TypeformSiteConfigExtension.php | 22 -- code/model/TypeformQuestion.php | 33 --- code/model/TypeformSubmission.php | 108 -------- code/tasks/SyncTypeformSubmissions.php | 262 ------------------ composer.json | 12 +- src/Admin/TypeformSubmissionAdmin.php | 26 ++ src/Extensions/TypeformExtension.php | 46 +++ .../TypeformSiteConfigExtension.php | 26 ++ src/Model/TypeformQuestion.php | 42 +++ src/Model/TypeformSubmission.php | 80 ++++++ src/Model/TypeformSubmissionAnswer.php | 23 ++ src/Model/TypeformSubmissionDeleted.php | 32 +++ src/Tasks/SyncTypeformSubmissions.php | 103 +++++++ src/Tasks/SyncTypeformSubmissionsSingle.php | 180 ++++++++++++ 21 files changed, 595 insertions(+), 512 deletions(-) create mode 100644 _config/config.yml delete mode 100644 _config/extensions.yml create mode 100644 _config/legacy.yml delete mode 100644 code/controllers/TypeformSubmissionAdmin.php delete mode 100644 code/extensions/TypeformExtension.php delete mode 100644 code/extensions/TypeformSiteConfigExtension.php delete mode 100644 code/model/TypeformQuestion.php delete mode 100644 code/model/TypeformSubmission.php delete mode 100644 code/tasks/SyncTypeformSubmissions.php create mode 100644 src/Admin/TypeformSubmissionAdmin.php create mode 100644 src/Extensions/TypeformExtension.php create mode 100644 src/Extensions/TypeformSiteConfigExtension.php create mode 100644 src/Model/TypeformQuestion.php create mode 100644 src/Model/TypeformSubmission.php create mode 100644 src/Model/TypeformSubmissionAnswer.php create mode 100644 src/Model/TypeformSubmissionDeleted.php create mode 100644 src/Tasks/SyncTypeformSubmissions.php create mode 100644 src/Tasks/SyncTypeformSubmissionsSingle.php diff --git a/README.md b/README.md index fe1015f..f83ecdb 100644 --- a/README.md +++ b/README.md @@ -7,42 +7,39 @@ ## Requirements -* SilverStripe 3.1 +* SilverStripe 4.4 ## Documentation -This module provides integration with Typeform.com and SilverStripe in a way +This module provides integration with Typeform.com and SilverStripe in a way that SilverStripe `Page` objects can have a linked Typeform Form and submissions made through Typeform are brought into SilverStripe to be managed through a `ModelAdmin` interface. ## Installation - composer require "dnadesign/silverstripe-typeform" + composer require "dnadesign/silverstripe-typeform" ## Usage -Add the `TypeformExtension` extension to your formable page type. For -example, in mysite/_config/extensions.yml +Add the `TypeformExtension` extension to your formable page type. For +example, in `app/_config/extensions.yml` - Page: - extensions: - - TypeformExtension + Page: + extensions: + - DNADesign\Typeform\Extensions\TypeformExtension Rebuild the database and complete the new Typeform tab in the CMS. To sync submissions call `dev/tasks/SyncTypeformSubmissions`. You can also sync individual forms (say on submission callback) by creating an action and manually -invoking the `SyncTypeformSubmissions_Single` class +invoking the `SyncTypeformSubmissionsSingle` class - $sync = new SyncTypeformSubmissions_Single($this->TypeformKey); - $results = $sync->syncComments($this); + $sync = new SyncTypeformSubmissionsSingle($this->TypeformKey); + $results = $sync->syncComments($this); ## Features - * Imports questions, forms and submissions into SilverStripe Data Models - * Attach Typeform pages to any SilverStripe Object - * CMS Admin interface for viewing and managing Typeform data - - - + * Imports questions, forms and submissions into SilverStripe Data Models + * Attach Typeform pages to any SilverStripe Object + * CMS Admin interface for viewing and managing Typeform data diff --git a/_config.php b/_config.php index a4abe2d..b3d9bbc 100644 --- a/_config.php +++ b/_config.php @@ -1,2 +1 @@ 'Varchar', - 'TypeformURL' => 'Varchar', - 'TypeformImported' => 'SS_Datetime' - ); - - public function updateCMSFields(FieldList $fields) - { - $fields->addFieldsToTab('Root.Typeform', array( - new TextField('TypeformURL', 'Typeform URL'), - $key = new TextField('TypeformKey', 'Typeform UID') - )); - - $key->setDescription('The UID of a typeform is found at the end of its URL'); - } - - - public function getTypeformUid() - { - return $this->owner->dbObject('TypeformKey')->getValue(); - } - - public function getLastTypeformImportedTimestamp() - { - return $this->owner->dbObject('TypeformImported')->Format('U'); - } - - public function updateLastTypeformImportedTimestamp() - { - $this->owner->TypeformImported = SS_Datetime::now(); - $this->owner->write(); - } -} \ No newline at end of file diff --git a/code/extensions/TypeformSiteConfigExtension.php b/code/extensions/TypeformSiteConfigExtension.php deleted file mode 100644 index ec74664..0000000 --- a/code/extensions/TypeformSiteConfigExtension.php +++ /dev/null @@ -1,22 +0,0 @@ - 'Varchar' - ); - - public function updateCMSFields(FieldList $fields) - { - $fields->addFieldsToTab('Root.Typeform', array( - $key = new TextField('TypeformApiKey') - )); - - $key->setDescription('Typeform API key'); - } -} \ No newline at end of file diff --git a/code/model/TypeformQuestion.php b/code/model/TypeformQuestion.php deleted file mode 100644 index 29311b8..0000000 --- a/code/model/TypeformQuestion.php +++ /dev/null @@ -1,33 +0,0 @@ - 'Varchar(255)', - 'Title' => 'Varchar(255)', - 'CustomTitle' => 'Varchar(255)', - 'FieldID' => 'Varchar', - 'ParentID' => 'Int' - ); - - private static $has_one = array( - 'GroupField' => 'TypeformQuestion' - ); - - private static $has_many = array( - 'GroupedChildren' => 'TypeformQuestion', - 'Answers' => 'TypeformSubmission_Answer' - ); - - private static $summary_fields = array( - 'ID', - 'Title', - 'FieldID', - 'CustomTitle', - 'GroupField.Title' - ); -} diff --git a/code/model/TypeformSubmission.php b/code/model/TypeformSubmission.php deleted file mode 100644 index 61c558b..0000000 --- a/code/model/TypeformSubmission.php +++ /dev/null @@ -1,108 +0,0 @@ - 'Int', - 'DateStarted' => 'SS_Datetime', - 'DateSubmitted' => 'SS_Datetime' - ); - - private static $has_one = array( - 'Parent' => 'Page' - ); - - private static $has_many = array( - 'Answers' => 'TypeformSubmission_Answer' - ); - - private static $default_sort = "ID DESC"; - - private static $searchable_fields = array( - 'ParentID' - ); - - private static $summary_fields = array( - 'CMSTitle' => 'Title' - ); - - private static $casting = array( - 'Title' => 'Varchar' - ); - - - public function onAfterDelete() - { - parent::onAfterDelete(); - - foreach ($this->Answers() as $answer) { - $answer->delete(); - } - } - - public function getCMSTitle() - { - return sprintf("%s - %s (%s)", $this->ID, $this->DateSubmitted, $this->Parent()->Title); - } - - public function Title() - { - return $this->TypeformID; - } - - public function canView($member = null) - { - return true; - } - - public function onBeforeDelete() - { - parent::onBeforeDelete(); - - $deleted = new TypeformSubmission_Deleted(); - $deleted->TypeformID = $this->TypeformID; - $deleted->ParentID = $this->ParentID; - $deleted->write(); - } -} - -/** - * @package typeform - */ -class TypeformSubmission_Deleted extends DataObject -{ - - private static $db = array( - 'TypeformID' => 'Varchar(255)' - ); - - private static $has_one = array( - 'Parent' => 'Page' - ); - - private static $summary_fields = array( - 'TypeformID', - 'Parent.Title' - ); -} - -/** - * @package typeform - */ -class TypeformSubmission_Answer extends DataObject -{ - - private static $db = array( - 'Value' => 'Text', - 'Label' => 'Varchar(255)' - ); - - private static $has_one = array( - 'Submission' => 'TypeformSubmission', - 'Question' => 'TypeformQuestion' - ); -} diff --git a/code/tasks/SyncTypeformSubmissions.php b/code/tasks/SyncTypeformSubmissions.php deleted file mode 100644 index 1ab9013..0000000 --- a/code/tasks/SyncTypeformSubmissions.php +++ /dev/null @@ -1,262 +0,0 @@ -getVar('form'); - $force = $request->getVar('force') || false; - - if ($request->getVar('delete') && Director::isDev()) { - $submissions = TypeformSubmission::get(); - - if ($formId) { - $submissions = $submissions->filter('ParentID', $formId); - } - - foreach ($submissions as $submission) { - $submission->delete(); - } - } - - foreach ($this->config()->typeform_classes as $class) { - $forms = DataObject::get($class); - - if (Director::is_cli()) { - echo "Syncing " . $class . " forms\n"; - } else { - echo "

Syncing " . $class . " forms

"; - } - - if (!$formId) { - if (Director::is_cli()) { - echo $forms->count() . " found\n"; - } else { - echo "

" . $forms->count() . " found

"; - } - } - - foreach ($forms as $form) { - $key = null; - - if ($form->hasMethod('getTypeformUid')) { - $key = $form->getTypeformUid(); - } - - if ($key && $formId && $form->ID !== $formId) { - if (Director::is_cli()) { - echo sprintf("* Skipping %s\n", $form->Title); - } else { - echo sprintf("
  • Skipping %s
  • ", $form->Title); - } - - continue; - } - - if ($key) { - $fetch = new SyncTypeformSubmissions_Single($key); - $results = $fetch->syncComments($form, $force); - - $total = $results['total']; - $synced = $results['synced']; - - if (Director::is_cli()) { - echo sprintf("* %d new synced submissions out of %d total for %s\n", $synced, $total, $form->Title); - } else { - echo sprintf("
  • %d new synced submissions out of %d for %s
  • ", $synced, $total, $form->Title); - } - } else { - if (Director::is_cli()) { - echo sprintf("* No valid key for %s\n", $form->Title); - } else { - echo sprintf("
  • No valid key for %s
  • ", $form->Title); - } - } - } - } - } -} - -/** - * @package typeform - */ -class SyncTypeformSubmissions_Single { - - /** - * @param string $formKey - */ - public function __construct($formKey) { - $this->formKey = $formKey; - } - - /** - * @param ITypeform $target - * @param boolean $force - * - * @return array - */ - public function syncComments(ITypeform $target, $force = false, $offset = 0) { - // either now or 10 minutes. - $results = array( - 'total' => 0, - 'synced' => 0, - ); - - $limit = 500; - - $since = $target->getLastTypeformImportedTimestamp(); - - if (!$force) { - if ($since) { - $since = '&since=' . $since; - } - } else { - $since = ''; - } - - $rest = new RestfulService("https://api.typeform.com/v0/form/", 0); - $url = - sprintf("%s?key=%s&completed=true&offset=0&limit=%s%s", - $this->formKey, - SiteConfig::current_site_config()->TypeformApiKey, - $offset, - $limit, - $since - ); - - $response = $rest->request($url); - - if ($response && !$response->isError()) { - $body = json_decode($response->getBody(), true); - - if (isset($body['stats'])) { - $target->extend('updateTypeformStats', $body['stats']); - } - - if (isset($body['questions'])) { - $this->populateQuestions($body['questions'], $target, $results); - } - - if (isset($body['responses'])) { - $this->populateResponses($body['responses'], $target, $results, $force); - } - - // if the number of responses are 500, then we assume we need to - // sync another page. - $body = json_decode($response->getBody()); - - if ($body->stats->responses->total >= ($offset + $limit)) { - $this->syncComments($target, $force, $offset + $limit); - } - } else { - SS_Log::log($response->getBody(), SS_Log::WARN); - } - - return $results; - } - - public function populateQuestions($questions, $target, $results) { - foreach ($questions as $question) { - $existing = TypeformQuestion::get()->filter(array( - 'ParentID' => $target->ID, - 'Reference' => $question['id'], - ))->first(); - - if (!$existing) { - $existing = TypeformQuestion::create(); - $existing->ParentID = $target->ID; - $existing->Reference = $question['id']; - } - - $existing->FieldID = $question['field_id']; - - if (isset($question['group']) && $question['group']) { - $group = TypeformQuestion::get()->filter('Reference', $question['group'])->first(); - - if ($group) { - $existing->GroupFieldID = $group->ID; - } - } - - $existing->Title = $question['question']; - $existing->write(); - } - } - - public function populateResponses($responses, $target, &$results, $force) { - // assumes comments don't update. - foreach ($responses as $response) { - $results['total']++; - - $deleted = TypeformSubmission_Deleted::get()->filter(array( - 'TypeformID' => $response['id'], - 'ParentID' => $target->ID, - )); - - if ($deleted->count() > 0 && !$force) { - continue; - } - - $existing = TypeformSubmission::get()->filter(array( - 'TypeformID' => $response['id'], - 'ParentID' => $target->ID, - )); - - if ($existing->count() > 0) { - continue; - } else { - $results['synced']++; - - // check to make sure it hasn't been deleted - $submission = TypeformSubmission::create(); - - $submission->TypeformID = $response['id']; - $submission->DateStarted = date("Y-m-d H:i:s", strtotime($response['metadata']['date_land'] . ' UTC')); - $submission->DateSubmitted = date("Y-m-d H:i:s", strtotime($response['metadata']['date_submit'] . ' UTC')); - - $submission->ParentID = $target->ID; - $submission->write(); - - if (isset($response['answers'])) { - foreach ($response['answers'] as $field => $value) { - $question = TypeformQuestion::get()->filter(array( - 'Reference' => $field, - ))->first(); - - if (!$question) { - $question = TypeformQuestion::create(); - $question->ParentID = $target->ID; - $question->Reference = $reference; - $question->write(); - } - - $answer = TypeformSubmission_Answer::create(); - $answer->Label = $question->Title; - $answer->QuestionID = $question->ID; - $answer->SubmissionID = $submission->ID; - $answer->Value = $value; - $answer->write(); - } - } - - $submission->extend('onAfterAnswersSynced'); - } - } - } -} diff --git a/composer.json b/composer.json index 3682f96..f23b75a 100644 --- a/composer.json +++ b/composer.json @@ -1,15 +1,19 @@ { "name": "dnadesign/silverstripe-typeform", "description": "Module to provide integration with Typeform. Downloads submissions and allows them to be managed within SilverStripe.", - "type": "silverstripe-module", - "keywords": ["silverstripe", "typeform"], - "license": "BSD-3-Clause", + "type": "silverstripe-vendormodule", + "keywords": [ + "silverstripe", + "typeform" + ], + "license": "BSD-3-Clause", "authors": [{ "name": "Will Rossiter", "email": "will.rossiter@dna.co.nz" }], "require": { - "silverstripe/framework": "~3.1" + "silverstripe/cms": "^4.4", + "silverstripe/admin": "^1.3" }, "extra": { "installer-name": "typeform" diff --git a/src/Admin/TypeformSubmissionAdmin.php b/src/Admin/TypeformSubmissionAdmin.php new file mode 100644 index 0000000..0b81c0a --- /dev/null +++ b/src/Admin/TypeformSubmissionAdmin.php @@ -0,0 +1,26 @@ + 'Varchar', + 'TypeformURL' => 'Varchar', + 'TypeformImported' => 'Datetime', + ]; + + public function updateCMSFields(FieldList $fields) + { + $fields->addFieldsToTab('Root.Typeform', [ + TextField::create('TypeformURL', 'Typeform URL'), + $key = TextField::create('TypeformKey', 'Typeform UID'), + ]); + + $key->setDescription('The UID of a typeform is found at the end of its URL'); + } + + public function getTypeformUid() + { + return $this->owner->dbObject('TypeformKey')->getValue(); + } + + public function getLastTypeformImportedTimestamp() + { + return $this->owner->dbObject('TypeformImported')->Format('U'); + } + + public function updateLastTypeformImportedTimestamp() + { + $this->owner->TypeformImported = DBDatetime::now(); + $this->owner->write(); + } +} diff --git a/src/Extensions/TypeformSiteConfigExtension.php b/src/Extensions/TypeformSiteConfigExtension.php new file mode 100644 index 0000000..d3bb7e6 --- /dev/null +++ b/src/Extensions/TypeformSiteConfigExtension.php @@ -0,0 +1,26 @@ + 'Varchar', + ]; + + public function updateCMSFields(FieldList $fields) + { + $fields->addFieldsToTab('Root.Typeform', [ + $key = TextField::create('TypeformApiKey'), + ]); + + $key->setDescription('Typeform API key'); + } +} diff --git a/src/Model/TypeformQuestion.php b/src/Model/TypeformQuestion.php new file mode 100644 index 0000000..696223c --- /dev/null +++ b/src/Model/TypeformQuestion.php @@ -0,0 +1,42 @@ + 'Varchar(255)', + 'Title' => 'Varchar(255)', + 'CustomTitle' => 'Varchar(255)', + 'FieldID' => 'Varchar', + 'ParentID' => 'Int', + ]; + + private static $has_one = [ + 'GroupField' => TypeformQuestion::class, + ]; + + private static $has_many = [ + 'GroupedChildren' => TypeformQuestion::class, + 'Answers' => TypeformSubmissionAnswer::class, + ]; + + private static $summary_fields = [ + 'ID', + 'Title', + 'FieldID', + 'CustomTitle', + 'GroupField.Title', + ]; + + private static $field_labels = [ + 'GroupField.Title' => 'Group Field', + ]; + + private static $table_name = 'TypeformQuestion'; +} diff --git a/src/Model/TypeformSubmission.php b/src/Model/TypeformSubmission.php new file mode 100644 index 0000000..17368a8 --- /dev/null +++ b/src/Model/TypeformSubmission.php @@ -0,0 +1,80 @@ + 'Int', + 'DateStarted' => 'Datetime', + 'DateSubmitted' => 'Datetime', + ]; + + private static $has_one = [ + 'Parent' => Page::class, + ]; + + private static $has_many = [ + 'Answers' => TypeformSubmissionAnswer::class, + ]; + + private static $default_sort = 'ID DESC'; + + private static $searchable_fields = [ + 'ParentID', + ]; + + private static $summary_fields = [ + 'CMSTitle', + ]; + + private static $field_labels = [ + 'CMSTitle' => 'Title', + ]; + + private static $casting = [ + 'Title' => 'Varchar', + ]; + + private static $table_name = 'TypeformSubmission'; + + public function onAfterDelete() + { + parent::onAfterDelete(); + + foreach ($this->Answers() as $answer) { + $answer->delete(); + } + } + + public function getCMSTitle() + { + return sprintf('%s - %s (%s)', $this->ID, $this->DateSubmitted, $this->Parent()->Title); + } + + public function Title() + { + return $this->TypeformID; + } + + public function canView($member = null) + { + return true; + } + + public function onBeforeDelete() + { + parent::onBeforeDelete(); + + $deleted = new TypeformSubmissionDeleted(); + $deleted->TypeformID = $this->TypeformID; + $deleted->ParentID = $this->ParentID; + $deleted->write(); + } +} diff --git a/src/Model/TypeformSubmissionAnswer.php b/src/Model/TypeformSubmissionAnswer.php new file mode 100644 index 0000000..0b8debe --- /dev/null +++ b/src/Model/TypeformSubmissionAnswer.php @@ -0,0 +1,23 @@ + 'Text', + 'Label' => 'Varchar(255)', + ]; + + private static $has_one = [ + 'Submission' => TypeformSubmission::class, + 'Question' => TypeformQuestion::class, + ]; + + private static $table_name = 'TypeformSubmissionAnswer'; +} diff --git a/src/Model/TypeformSubmissionDeleted.php b/src/Model/TypeformSubmissionDeleted.php new file mode 100644 index 0000000..6ad658d --- /dev/null +++ b/src/Model/TypeformSubmissionDeleted.php @@ -0,0 +1,32 @@ + 'Varchar(255)', + ]; + + private static $has_one = [ + 'Parent' => Page::class, + ]; + + private static $summary_fields = [ + 'TypeformID', + 'Parent.Title', + ]; + + private static $field_labels = [ + 'TypeformID' => 'Typeform ID', + 'Parent.Title' => 'Parent', + ]; + + private static $table_name = 'TypeformSubmissionDeleted'; +} diff --git a/src/Tasks/SyncTypeformSubmissions.php b/src/Tasks/SyncTypeformSubmissions.php new file mode 100644 index 0000000..b475ec6 --- /dev/null +++ b/src/Tasks/SyncTypeformSubmissions.php @@ -0,0 +1,103 @@ +getVar('form'); + $force = $request->getVar('force') || false; + + if ($request->getVar('delete') && Director::isDev()) { + $submissions = TypeformSubmission::get(); + + if ($formId) { + $submissions = $submissions->filter('ParentID', $formId); + } + + foreach ($submissions as $submission) { + $submission->delete(); + } + } + + foreach ($this->config()->typeform_classes as $class) { + $forms = DataObject::get($class); + + if (Director::is_cli()) { + echo 'Syncing ' . $class . " forms\n"; + } else { + echo '

    Syncing ' . $class . ' forms

    '; + } + + if (!$formId) { + if (Director::is_cli()) { + echo $forms->count() . " found\n"; + } else { + echo '

    ' . $forms->count() . ' found

    '; + } + } + + foreach ($forms as $form) { + $key = null; + + if ($form->hasMethod('getTypeformUid')) { + $key = $form->getTypeformUid(); + } + + if ($key && $formId && $form->ID !== $formId) { + if (Director::is_cli()) { + echo sprintf("* Skipping %s\n", $form->Title); + } else { + echo sprintf('
  • Skipping %s
  • ', $form->Title); + } + + continue; + } + + if ($key) { + $fetch = new SyncTypeformSubmissionsSingle($key); + $results = $fetch->syncComments($form, $force); + + $total = $results['total']; + $synced = $results['synced']; + + if (Director::is_cli()) { + echo sprintf("* %d new synced submissions out of %d total for %s\n", $synced, $total, $form->Title); + } else { + echo sprintf('
  • %d new synced submissions out of %d for %s
  • ', $synced, $total, $form->Title); + } + } else { + if (Director::is_cli()) { + echo sprintf("* No valid key for %s\n", $form->Title); + } else { + echo sprintf('
  • No valid key for %s
  • ', $form->Title); + } + } + } + } + } +} diff --git a/src/Tasks/SyncTypeformSubmissionsSingle.php b/src/Tasks/SyncTypeformSubmissionsSingle.php new file mode 100644 index 0000000..531bdca --- /dev/null +++ b/src/Tasks/SyncTypeformSubmissionsSingle.php @@ -0,0 +1,180 @@ +formKey = $formKey; + } + + /** + * @param ITypeform $target + * @param boolean $force + * + * @return array + */ + public function syncComments(ITypeform $target, $force = false, $offset = 0) + { + // either now or 10 minutes. + $results = [ + 'total' => 0, + 'synced' => 0, + ]; + + $limit = 500; + + $since = $target->getLastTypeformImportedTimestamp(); + + if (!$force) { + if ($since) { + $since = '&since=' . $since; + } + } else { + $since = ''; + } + + $rest = new RestfulService('https://api.typeform.com/v0/form/', 0); + $url = + sprintf('%s?key=%s&completed=true&offset=0&limit=%s%s', + $this->formKey, + SiteConfig::current_site_config()->TypeformApiKey, + $offset, + $limit, + $since + ); + + $response = $rest->request($url); + + if ($response && !$response->isError()) { + $body = json_decode($response->getBody(), true); + + if (isset($body['stats'])) { + $target->extend('updateTypeformStats', $body['stats']); + } + + if (isset($body['questions'])) { + $this->populateQuestions($body['questions'], $target, $results); + } + + if (isset($body['responses'])) { + $this->populateResponses($body['responses'], $target, $results, $force); + } + + // if the number of responses are 500, then we assume we need to + // sync another page. + $body = json_decode($response->getBody()); + + if ($body->stats->responses->total >= ($offset + $limit)) { + $this->syncComments($target, $force, $offset + $limit); + } + } else { + SS_Log::log($response->getBody(), SS_Log::WARN); + } + + return $results; + } + + public function populateQuestions($questions, $target, $results) + { + foreach ($questions as $question) { + $existing = TypeformQuestion::get()->filter([ + 'ParentID' => $target->ID, + 'Reference' => $question['id'], + ])->first(); + + if (!$existing) { + $existing = TypeformQuestion::create(); + $existing->ParentID = $target->ID; + $existing->Reference = $question['id']; + } + + $existing->FieldID = $question['field_id']; + + if (isset($question['group']) && $question['group']) { + $group = TypeformQuestion::get()->filter('Reference', $question['group'])->first(); + + if ($group) { + $existing->GroupFieldID = $group->ID; + } + } + + $existing->Title = $question['question']; + $existing->write(); + } + } + + public function populateResponses($responses, $target, &$results, $force) + { + // assumes comments don't update. + foreach ($responses as $response) { + $results['total']++; + + $deleted = TypeformSubmissionDeleted::get()->filter([ + 'TypeformID' => $response['id'], + 'ParentID' => $target->ID, + ]); + + if ($deleted->count() > 0 && !$force) { + continue; + } + + $existing = TypeformSubmission::get()->filter([ + 'TypeformID' => $response['id'], + 'ParentID' => $target->ID, + ]); + + if ($existing->count() > 0) { + continue; + } + $results['synced']++; + + // check to make sure it hasn't been deleted + $submission = TypeformSubmission::create(); + + $submission->TypeformID = $response['id']; + $submission->DateStarted = date('Y-m-d H:i:s', strtotime($response['metadata']['date_land'] . ' UTC')); + $submission->DateSubmitted = date('Y-m-d H:i:s', strtotime($response['metadata']['date_submit'] . ' UTC')); + + $submission->ParentID = $target->ID; + $submission->write(); + + if (isset($response['answers'])) { + foreach ($response['answers'] as $field => $value) { + $question = TypeformQuestion::get()->filter([ + 'Reference' => $field, + ])->first(); + + if (!$question) { + $question = TypeformQuestion::create(); + $question->ParentID = $target->ID; + $question->Reference = $reference; + $question->write(); + } + + $answer = TypeformSubmissionAnswer::create(); + $answer->Label = $question->Title; + $answer->QuestionID = $question->ID; + $answer->SubmissionID = $submission->ID; + $answer->Value = $value; + $answer->write(); + } + } + + $submission->extend('onAfterAnswersSynced'); + } + } +} From dee760d6e5c4d21d6d0f79d9c8d2dde7cf6d6fb7 Mon Sep 17 00:00:00 2001 From: Michael Nowina-Krowicki Date: Wed, 28 Aug 2019 15:25:14 +0930 Subject: [PATCH 2/2] Typo fix --- src/Extensions/TypeformExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Extensions/TypeformExtension.php b/src/Extensions/TypeformExtension.php index ff14a09..455f4df 100644 --- a/src/Extensions/TypeformExtension.php +++ b/src/Extensions/TypeformExtension.php @@ -1,6 +1,6 @@