✨️ implement synchronisation of TwingleProject settings
This commit is contained in:
parent
0b1128fce5
commit
4dc3644bb3
3 changed files with 149 additions and 67 deletions
|
@ -104,12 +104,11 @@ abstract class CRM_TwingleCampaign_BAO_Campaign {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ## Update instance values
|
* ## Update instance values
|
||||||
* This method updates the **$values** array of this instance with the values
|
* This method updates the **$values** array of this instance with the values
|
||||||
* from the provided array if they are defined in
|
* from the provided array if they are defined in
|
||||||
* *CRM/TwingleCampaign/resources/twingle_api_templates.json*
|
* *CRM/TwingleCampaign/resources/twingle_api_templates.php*
|
||||||
*
|
*
|
||||||
* @param array $values
|
* @param array $values
|
||||||
* Array with values to update
|
* Array with values to update
|
||||||
|
@ -118,47 +117,33 @@ abstract class CRM_TwingleCampaign_BAO_Campaign {
|
||||||
// Update campaign values
|
// Update campaign values
|
||||||
$filter = Cache::getInstance()->getTemplates()[$this->className];
|
$filter = Cache::getInstance()->getTemplates()[$this->className];
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
if ($this->className == "TwingleProject" && $key == 'project_id') {
|
if ($this->in_array_r($key, $filter)) {
|
||||||
$this->values['id'] = $value;
|
|
||||||
}
|
|
||||||
elseif (in_array($key, $filter)) {
|
|
||||||
$this->values[$key] = $value;
|
$this->values[$key] = $value;
|
||||||
}
|
}
|
||||||
elseif ($key == 'embed') {
|
|
||||||
self::setEmbedData($value);
|
|
||||||
}
|
|
||||||
elseif ($key == 'counter-url') {
|
|
||||||
self::setCounterUrl($value['url']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ## Set embed data fields
|
* ## Complement campaign values
|
||||||
* This method sets all embed data fields that are defined in
|
* Complement existing campaign values with new ones
|
||||||
* *CRM/TwingleCampaign/resources/twingle_api_templates.json*
|
* @param array $arrayToComplement
|
||||||
*
|
|
||||||
* @param array $embedData
|
|
||||||
* Array with embed data from Twingle API
|
|
||||||
*/
|
*/
|
||||||
public function setEmbedData(array $embedData) {
|
public function complement(array $arrayToComplement) {
|
||||||
|
$this->complement_r($this->values, $arrayToComplement);
|
||||||
|
$this->values = $arrayToComplement;
|
||||||
|
}
|
||||||
|
|
||||||
// Get all embed_data keys from template
|
private function complement_r($orig, &$fill) {
|
||||||
$embed_data_keys = Cache::getInstance()
|
foreach ($orig as $key => $value) {
|
||||||
->getTemplates()['project_embed_data'];
|
if (is_array($value)) {
|
||||||
|
$this->complement_r($orig[$key], $fill[$key]);
|
||||||
// Transfer all embed_data values
|
} else {
|
||||||
foreach ($embed_data_keys as $key) {
|
$fill[$key] = $value;
|
||||||
if (array_key_exists($key, $embedData)) {
|
|
||||||
$this->values[$key] = $embedData[$key];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static abstract function formatValues(array &$values, string $direction);
|
||||||
public abstract function formatValues(array &$values, string $direction);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ## Translate array keys between CiviCRM Campaigns and Twingle
|
* ## Translate array keys between CiviCRM Campaigns and Twingle
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use CRM_TwingleCampaign_BAO_TwingleProject as TwingleProject;
|
|
||||||
use CRM_TwingleCampaign_ExtensionUtil as E;
|
use CRM_TwingleCampaign_ExtensionUtil as E;
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,11 +78,41 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall {
|
||||||
*/
|
*/
|
||||||
public function getProject(int $projectId = NULL): ?array {
|
public function getProject(int $projectId = NULL): ?array {
|
||||||
|
|
||||||
$url = empty($projectId)
|
// If no project id is provided, return all projects
|
||||||
? $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' . $this->organisationId
|
if (empty($projectId)) {
|
||||||
: $this->protocol . 'project' . $this->baseUrl . $projectId;
|
$response = [];
|
||||||
|
$projects = $this->curlGet($this->protocol . 'project' .
|
||||||
|
$this->baseUrl . 'by-organisation/' . $this->organisationId);
|
||||||
|
foreach ($projects as $project) {
|
||||||
|
$response[] = $this->getProject($project['id']);
|
||||||
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
// If a project id is provided, return only one project
|
||||||
|
else {
|
||||||
|
|
||||||
return $this->curlGet($url);
|
// Get all general project information
|
||||||
|
$project = $this->curlGet($this->protocol . 'project' .
|
||||||
|
$this->baseUrl . $projectId);
|
||||||
|
|
||||||
|
// Get project options
|
||||||
|
$project['project_options'] = $this->getProjectOptions($projectId);
|
||||||
|
|
||||||
|
// Get project payment methods
|
||||||
|
$project['payment_methods'] =
|
||||||
|
$this->getProjectPaymentMethods($projectId);
|
||||||
|
|
||||||
|
// Set last update time
|
||||||
|
$project['last_update'] = max(
|
||||||
|
$project['last_update'],
|
||||||
|
$project['project_options']['last_update'],
|
||||||
|
$project['payment_methods']['updated_at']
|
||||||
|
);
|
||||||
|
unset($project['project_options']['last_update']);
|
||||||
|
unset($project['payment_methods']['updated_at']);
|
||||||
|
|
||||||
|
return $project;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,30 +121,67 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall {
|
||||||
*
|
*
|
||||||
* Returns an array with all project values.
|
* Returns an array with all project values.
|
||||||
*
|
*
|
||||||
* @param TwingleProject $project
|
* @param array $project
|
||||||
* The TwingleProject object that should get pushed to Twingle
|
* The project values array that should get pushed to Twingle
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function pushProject(TwingleProject &$project): array {
|
public function pushProject(array $project): array {
|
||||||
|
|
||||||
// Get only those values from the TwingleProject object which Twingle expects
|
$projectOptions = $project['project_options'];
|
||||||
$values = $project->export();
|
unset($project['project_options']);
|
||||||
|
$paymentMethods = $project['payment_methods'];
|
||||||
|
unset($project['payment_methods']);
|
||||||
|
|
||||||
// Prepare url for curl
|
try {
|
||||||
if ($values['id']) {
|
if (!isset($project['id'])) {
|
||||||
$url = $this->protocol . 'project' . $this->baseUrl . $values['id'];
|
$url = $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' .
|
||||||
}
|
$this->organisationId;
|
||||||
else {
|
|
||||||
$url = $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' .
|
// Post project values
|
||||||
$this->organisationId;
|
$updatedProject = $this->curlPost($url, $project);
|
||||||
|
|
||||||
|
$url = $this->protocol . 'project' . $this->baseUrl .
|
||||||
|
$updatedProject['id'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$url = $this->protocol . 'project' . $this->baseUrl . $project['id'];
|
||||||
|
|
||||||
|
// Post project values
|
||||||
|
$updatedProject = $this->curlPost($url, $project);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post project_options
|
||||||
|
$updatedProject['project_options'] =
|
||||||
|
$this->curlPost($url . '/options', $projectOptions);
|
||||||
|
|
||||||
|
// Post payment_methods
|
||||||
|
$this->curlPost($url . '/payment-methods', $paymentMethods);
|
||||||
|
$updatedProject['payment_methods'] =
|
||||||
|
$this->getProjectPaymentMethods($updatedProject['id']);
|
||||||
|
|
||||||
|
// Set last update time
|
||||||
|
$updatedProject['last_update'] = max(
|
||||||
|
$updatedProject['last_update'],
|
||||||
|
$updatedProject['project_options']['last_update'],
|
||||||
|
$updatedProject['payment_methods']['updated_at']
|
||||||
|
);
|
||||||
|
unset($updatedProject['project_options']['last_update']);
|
||||||
|
unset($updatedProject['payment_methods']['updated_at']);
|
||||||
|
|
||||||
|
return $updatedProject;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new Exception(
|
||||||
|
E::SHORT_NAME . 'Call to Twingle API failed: ' .
|
||||||
|
$e->getMessage()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send curl and return result
|
|
||||||
return $this->curlPost($url, $values);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ## Get event from Twingle
|
* ## Get event from Twingle
|
||||||
* Returns all events for the provided **$projectId** or a single event if an
|
* Returns all events for the provided **$projectId** or a single event if an
|
||||||
|
@ -197,6 +263,33 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ## Get project options
|
||||||
|
* Gets all project options from the Twingle API
|
||||||
|
* @param $projectId
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function getProjectOptions($projectId): array {
|
||||||
|
$url = $this->protocol . 'project' . $this->baseUrl . $projectId . '/options';
|
||||||
|
return $this->curlGet($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ## Get project payment methods
|
||||||
|
* Gets all project payment methods from the Twingle API
|
||||||
|
* @param $projectId
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function getProjectPaymentMethods($projectId): array {
|
||||||
|
$url = $this->protocol . 'project' . $this->baseUrl . $projectId
|
||||||
|
. '/payment-methods';
|
||||||
|
return $this->curlGet($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ## Delete Project
|
* ## Delete Project
|
||||||
|
|
|
@ -189,11 +189,6 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
|
||||||
$project = new TwingleProject($project_from_twingle);
|
$project = new TwingleProject($project_from_twingle);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Get embed data
|
|
||||||
$project->setEmbedData(
|
|
||||||
$twingleApi->getProjectEmbedData($project->getProjectId())
|
|
||||||
);
|
|
||||||
|
|
||||||
// If this is a test, do not make db changes
|
// If this is a test, do not make db changes
|
||||||
if (isset($params['is_test']) && $params['is_test']) {
|
if (isset($params['is_test']) && $params['is_test']) {
|
||||||
$returnValues[$project->getId()] =
|
$returnValues[$project->getId()] =
|
||||||
|
@ -231,14 +226,18 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
|
||||||
$project = new TwingleProject($project_from_civicrm, $id);
|
$project = new TwingleProject($project_from_civicrm, $id);
|
||||||
|
|
||||||
// sync project
|
// sync project
|
||||||
$result = _projectSync($project, $project_from_twingle, $twingleApi, $params);
|
$result = _projectSync(
|
||||||
if ($result['is_error'] != 0) {
|
$project,
|
||||||
$errors_occurred++;
|
$project_from_twingle,
|
||||||
|
$twingleApi,
|
||||||
|
$params);
|
||||||
|
if (!$result['is_error'] == 0) {
|
||||||
|
$errors[$result['id']] = $result['error_message'];
|
||||||
$returnValues[$project->getId()] =
|
$returnValues[$project->getId()] =
|
||||||
$project->getResponse($result['error_message']);
|
$project->getResponse($result['error_message']);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$returnValues[$project->getId()] = $result['values'];
|
$returnValues[$result['id']] = $result['values'][$result['id']];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -284,9 +283,7 @@ function _updateProjectLocally(array $project_from_twingle,
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$project->update($project_from_twingle);
|
$project->update($project_from_twingle);
|
||||||
$project->setEmbedData(
|
|
||||||
$twingleApi->getProjectEmbedData($project->getProjectId())
|
|
||||||
);
|
|
||||||
// If this is a test, do not make db changes
|
// If this is a test, do not make db changes
|
||||||
if (array_key_exists('is_test', $params) && $params['is_test']) {
|
if (array_key_exists('is_test', $params) && $params['is_test']) {
|
||||||
return civicrm_api3_create_success(
|
return civicrm_api3_create_success(
|
||||||
|
@ -346,7 +343,7 @@ function _pushProjectToTwingle(TwingleProject $project,
|
||||||
|
|
||||||
// Push project to Twingle
|
// Push project to Twingle
|
||||||
try {
|
try {
|
||||||
$result = $twingleApi->pushProject($project);
|
$result = $twingleApi->pushProject($project->export());
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Civi::log()->error(
|
Civi::log()->error(
|
||||||
E::LONG_NAME .
|
E::LONG_NAME .
|
||||||
|
@ -363,11 +360,7 @@ function _pushProjectToTwingle(TwingleProject $project,
|
||||||
// Update local campaign with data returning from Twingle
|
// Update local campaign with data returning from Twingle
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$project->update($result);
|
$project->update($result);
|
||||||
// Get embed data
|
|
||||||
try {
|
try {
|
||||||
$project->setEmbedData(
|
|
||||||
$twingleApi->getProjectEmbedData($project->getProjectId())
|
|
||||||
);
|
|
||||||
// Create updated campaign
|
// Create updated campaign
|
||||||
$project->create(TRUE);
|
$project->create(TRUE);
|
||||||
$response = $project->getResponse('TwingleProject pushed to Twingle');
|
$response = $project->getResponse('TwingleProject pushed to Twingle');
|
||||||
|
@ -432,6 +425,17 @@ function _projectSync(TwingleProject $project,
|
||||||
// If the CiviCRM TwingleProject campaign was changed, update the project
|
// If the CiviCRM TwingleProject campaign was changed, update the project
|
||||||
// on Twingle's side
|
// on Twingle's side
|
||||||
elseif ($project_from_twingle['last_update'] < $project->lastUpdate()) {
|
elseif ($project_from_twingle['last_update'] < $project->lastUpdate()) {
|
||||||
|
// Make sure that the project hast a correct project_id. This is important
|
||||||
|
// to avoid an accidental cloning of project.
|
||||||
|
if (empty($project->getProjectId())) {
|
||||||
|
throw new \CiviCRM_API3_Exception(
|
||||||
|
'Missing project_id for project that is meant to get updated on Twingle side.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// By merging the project values with the values coming from Twingle, we
|
||||||
|
// make sure that the project contains all values needed to get pushed
|
||||||
|
$project->complement($project_from_twingle);
|
||||||
|
|
||||||
return _pushProjectToTwingle($project, $twingleApi, $params);
|
return _pushProjectToTwingle($project, $twingleApi, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue