✨️ 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ## Update instance values
|
||||
* This method updates the **$values** array of this instance with the values
|
||||
* 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
|
||||
* Array with values to update
|
||||
|
@ -118,47 +117,33 @@ abstract class CRM_TwingleCampaign_BAO_Campaign {
|
|||
// Update campaign values
|
||||
$filter = Cache::getInstance()->getTemplates()[$this->className];
|
||||
foreach ($values as $key => $value) {
|
||||
if ($this->className == "TwingleProject" && $key == 'project_id') {
|
||||
$this->values['id'] = $value;
|
||||
}
|
||||
elseif (in_array($key, $filter)) {
|
||||
if ($this->in_array_r($key, $filter)) {
|
||||
$this->values[$key] = $value;
|
||||
}
|
||||
elseif ($key == 'embed') {
|
||||
self::setEmbedData($value);
|
||||
}
|
||||
elseif ($key == 'counter-url') {
|
||||
self::setCounterUrl($value['url']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ## Set embed data fields
|
||||
* This method sets all embed data fields that are defined in
|
||||
* *CRM/TwingleCampaign/resources/twingle_api_templates.json*
|
||||
*
|
||||
* @param array $embedData
|
||||
* Array with embed data from Twingle API
|
||||
* ## Complement campaign values
|
||||
* Complement existing campaign values with new ones
|
||||
* @param array $arrayToComplement
|
||||
*/
|
||||
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
|
||||
$embed_data_keys = Cache::getInstance()
|
||||
->getTemplates()['project_embed_data'];
|
||||
|
||||
// Transfer all embed_data values
|
||||
foreach ($embed_data_keys as $key) {
|
||||
if (array_key_exists($key, $embedData)) {
|
||||
$this->values[$key] = $embedData[$key];
|
||||
private function complement_r($orig, &$fill) {
|
||||
foreach ($orig as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$this->complement_r($orig[$key], $fill[$key]);
|
||||
} else {
|
||||
$fill[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract function formatValues(array &$values, string $direction);
|
||||
|
||||
public static abstract function formatValues(array &$values, string $direction);
|
||||
|
||||
/**
|
||||
* ## Translate array keys between CiviCRM Campaigns and Twingle
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
use CRM_TwingleCampaign_BAO_TwingleProject as TwingleProject;
|
||||
use CRM_TwingleCampaign_ExtensionUtil as E;
|
||||
|
||||
|
||||
|
@ -79,11 +78,41 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall {
|
|||
*/
|
||||
public function getProject(int $projectId = NULL): ?array {
|
||||
|
||||
$url = empty($projectId)
|
||||
? $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' . $this->organisationId
|
||||
: $this->protocol . 'project' . $this->baseUrl . $projectId;
|
||||
// If no project id is provided, return all projects
|
||||
if (empty($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.
|
||||
*
|
||||
* @param TwingleProject $project
|
||||
* The TwingleProject object that should get pushed to Twingle
|
||||
* @param array $project
|
||||
* The project values array that should get pushed to Twingle
|
||||
*
|
||||
* @return array
|
||||
* @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
|
||||
$values = $project->export();
|
||||
$projectOptions = $project['project_options'];
|
||||
unset($project['project_options']);
|
||||
$paymentMethods = $project['payment_methods'];
|
||||
unset($project['payment_methods']);
|
||||
|
||||
// Prepare url for curl
|
||||
if ($values['id']) {
|
||||
$url = $this->protocol . 'project' . $this->baseUrl . $values['id'];
|
||||
}
|
||||
else {
|
||||
try {
|
||||
if (!isset($project['id'])) {
|
||||
$url = $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' .
|
||||
$this->organisationId;
|
||||
|
||||
// Post project values
|
||||
$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);
|
||||
}
|
||||
|
||||
// Send curl and return result
|
||||
return $this->curlPost($url, $values);
|
||||
// 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()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ## Get event from Twingle
|
||||
* 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
|
||||
|
|
|
@ -189,11 +189,6 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
|
|||
$project = new TwingleProject($project_from_twingle);
|
||||
|
||||
try {
|
||||
// Get embed data
|
||||
$project->setEmbedData(
|
||||
$twingleApi->getProjectEmbedData($project->getProjectId())
|
||||
);
|
||||
|
||||
// If this is a test, do not make db changes
|
||||
if (isset($params['is_test']) && $params['is_test']) {
|
||||
$returnValues[$project->getId()] =
|
||||
|
@ -231,14 +226,18 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
|
|||
$project = new TwingleProject($project_from_civicrm, $id);
|
||||
|
||||
// sync project
|
||||
$result = _projectSync($project, $project_from_twingle, $twingleApi, $params);
|
||||
if ($result['is_error'] != 0) {
|
||||
$errors_occurred++;
|
||||
$result = _projectSync(
|
||||
$project,
|
||||
$project_from_twingle,
|
||||
$twingleApi,
|
||||
$params);
|
||||
if (!$result['is_error'] == 0) {
|
||||
$errors[$result['id']] = $result['error_message'];
|
||||
$returnValues[$project->getId()] =
|
||||
$project->getResponse($result['error_message']);
|
||||
}
|
||||
else {
|
||||
$returnValues[$project->getId()] = $result['values'];
|
||||
$returnValues[$result['id']] = $result['values'][$result['id']];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -284,9 +283,7 @@ function _updateProjectLocally(array $project_from_twingle,
|
|||
|
||||
try {
|
||||
$project->update($project_from_twingle);
|
||||
$project->setEmbedData(
|
||||
$twingleApi->getProjectEmbedData($project->getProjectId())
|
||||
);
|
||||
|
||||
// If this is a test, do not make db changes
|
||||
if (array_key_exists('is_test', $params) && $params['is_test']) {
|
||||
return civicrm_api3_create_success(
|
||||
|
@ -346,7 +343,7 @@ function _pushProjectToTwingle(TwingleProject $project,
|
|||
|
||||
// Push project to Twingle
|
||||
try {
|
||||
$result = $twingleApi->pushProject($project);
|
||||
$result = $twingleApi->pushProject($project->export());
|
||||
} catch (Exception $e) {
|
||||
Civi::log()->error(
|
||||
E::LONG_NAME .
|
||||
|
@ -363,11 +360,7 @@ function _pushProjectToTwingle(TwingleProject $project,
|
|||
// Update local campaign with data returning from Twingle
|
||||
if ($result) {
|
||||
$project->update($result);
|
||||
// Get embed data
|
||||
try {
|
||||
$project->setEmbedData(
|
||||
$twingleApi->getProjectEmbedData($project->getProjectId())
|
||||
);
|
||||
// Create updated campaign
|
||||
$project->create(TRUE);
|
||||
$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
|
||||
// on Twingle's side
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue