remove project options & add embed data

This commit is contained in:
Marc Michalsky forumZFD 2020-10-29 16:26:00 +01:00
parent 52a3a1e978
commit 6e07d97dba
Signed by untrusted user who does not match committer: marc.koch
GPG key ID: 12406554CFB028B9
5 changed files with 78 additions and 1430 deletions

View file

@ -42,8 +42,6 @@ class TwingleProject {
private $values;
private $options;
/**
* TwingleProject constructor.
@ -63,12 +61,6 @@ class TwingleProject {
// Fetch custom field mapping once
self::init();
// Create TwingleProjectOptions object
$this->options = new TwingleProjectOptions($project['options'], $origin);
// Unset project options in $project array
unset($project['options']);
// If values come from CiviCRM Campaign API
if ($origin == self::CIVICRM) {
@ -172,28 +164,11 @@ class TwingleProject {
self::IN
);
// Prepare project option values for import into database
$options_prepared_for_import = $this->options->getValues();
TwingleProjectOptions::formatValues(
$options_prepared_for_import,
self::IN
);
self::translateCustomFields(
$options_prepared_for_import,
self::IN
);
// Merge project values and project options values
$merged = array_merge(
$values_prepared_for_import,
$options_prepared_for_import
);
// Set id
$merged['id'] = $this->id;
$values_prepared_for_import['id'] = $this->id;
// Create campaign
$result = civicrm_api3('Campaign', 'create', $merged);
$result = civicrm_api3('Campaign', 'create', $values_prepared_for_import);
// Update id
$this->id = $result['id'];
@ -226,12 +201,6 @@ class TwingleProject {
*/
public function update(array $values) {
// Update project options
$this->options->update($values['options']);
// Unset options array in project values
unset($values['options']);
// Update project values
$this->values = array_merge($this->values, $values);
}
@ -250,7 +219,6 @@ class TwingleProject {
$values = $this->values;
self::formatValues($values, self::OUT);
self::translateKeys($values, self::OUT);
// Get template for project
$project = self::$templates['project'];
@ -265,37 +233,6 @@ class TwingleProject {
return $values;
}
/**
* Export options. Ensures that only those values will be exported which the
* Twingle API expects. Missing values will get complemented with default
* values.
*
* @return array
* Array with all options to send to the Twingle API
*
* @throws Exception
*
*/
public function exportOptions() {
$options = $this->values['options'];
self::formatValues($options, self::OUT);
self::translateKeys($options, self::OUT);
// Get Template for project options
$project_options_template = self::$templates['project_options'];
// Replace array items which the Twingle API does not expect
foreach ($options as $key => $value) {
if (!key_exists($key, $project_options_template)) {
unset($options[$key]);
}
}
// Complement missing options with default values
return array_merge($project_options_template, $options);
}
/**
* Check if a TwingleProject campaign already exists and if so set attributes
@ -349,9 +286,6 @@ class TwingleProject {
// Translate keys from CiviCRM format to Twingle format
self::translateKeys($values, self::OUT);
// Separate options from project values
self::separateOptions($values);
// Set attributes to the values of the existing TwingleProject campaign
// to reflect the state of the actual campaign in the database
$this->update($values);
@ -379,9 +313,6 @@ class TwingleProject {
'id' => $id,
]);
// Separate options from project values
self::separateOptions($result['values']);
return new TwingleProject(
$result['values'],
self::CIVICRM
@ -484,14 +415,17 @@ class TwingleProject {
elseif ($direction == self::OUT) {
// Change DateTime string into timestamp
$values['last_modified_date'] =
self::getTimestamp($values['last_modified_date']);
$values['last_update'] =
self::getTimestamp($values['last_update']);
// default project_type to ''
// Default project_type to ''
$values['type'] = $values['type'] == 'default'
? ''
: $values['type'];
// Cast project target to integer
$values['project_target'] = (int) $values['project_target'];
}
else {
@ -568,31 +502,32 @@ class TwingleProject {
}
/**
* A function that picks all option values from the values array and puts them
* into an own array.
* Set embed data fields
*
* @param array $values
* @param array $embedData
* Array with embed data from Twingle API
*/
private static function separateOptions(array &$values) {
public function setEmbedData(array $embedData) {
$options = [];
// Get all embed_data keys from template
$embed_data_keys = self::$templates['project_embed_data'];
// Get array with template for project values and options
$options_template = self::$templates['project_options'];
// Map array items into $values and $options array
foreach ($values as $key => $value) {
if (key_exists($key, $options_template)) {
$options[$key] = $value;
unset($values[$key]);
// Transfer all embed_data values
foreach ($embed_data_keys as $key) {
$this->values[$key] = htmlspecialchars($embedData[$key]);
}
}
// Insert options array into values array
$values['options'] = $options;
/**
* Set counter url
*
* @param String $counterUrl
* URL of the counter
*/
public function setCounterUrl(string $counterUrl) {
$this->values['counter'] = $counterUrl;
}
/**
* Deactivate this TwingleProject campaign
*
@ -657,6 +592,7 @@ class TwingleProject {
'title' => $this->values['name'],
'id' => (int) $this->id,
'project_id' => (int) $this->values['id'],
'project_type' => $this->values['type'],
'status' => $status,
];
}
@ -730,12 +666,8 @@ class TwingleProject {
* @return int|null
*/
public function lastUpdate() {
$lastProjectUpdate = self::getTimestamp($this->values['last_update']);
$lastOptionsUpdate = self::getTimestamp($this->options->lastUpdate());
$lastUpdate = $lastProjectUpdate > $lastOptionsUpdate
? $lastProjectUpdate
: $lastOptionsUpdate;
return self::getTimestamp($lastUpdate);
return self::getTimestamp($this->values['last_update']);
}

View file

@ -1,243 +0,0 @@
<?php
namespace CRM\TwingleCampaign\BAO;
use CRM_TwingleCampaign_ExtensionUtil as E;
use CRM_Utils_Array;
use Exception;
include_once E::path() . '/CRM/TwingleCampaign/BAO/CustomField.php';
class TwingleProjectOptions {
private $values;
/**
* TwingleProjectOptions constructor.
*
* @param array $options
* Result array of Twingle API call to
* https://project.twingle.de/api/by-organisation/$project_id/options
*
* @param string $origin
* Origin of the arrays. It can be one of two constants:
* TwingleProject::TWINGLE|CIVICRM
*
* @throws Exception
*/
public function __construct(array $options, string $origin) {
// If values come from CiviCRM Campaign API
if ($origin == TwingleProject::CIVICRM) {
// Translate custom field names into Twingle field names
TwingleProject::translateCustomFields($options, TwingleProject::OUT);
// Format values
self::formatValues($options, TwingleProject::OUT);
}
// Unset project options id
unset($options['id']);
// Set project values attribute
$this->values = $options;
}
/**
* Update an this object
*
* @param array $options
* Array with values to update
*
* @throws Exception
*/
public function update(array $options) {
// Update values
$this->values = array_merge($this->values, $options);
}
/**
* Export values. Ensures that only those values will be exported which the
* Twingle API expects.
*
* @return array
* Array with all values to send to the Twingle API
*
* @throws Exception
*/
public function export() {
$values = $this->values;
self::formatValues($values, TwingleProject::OUT);
TwingleProject::translateKeys($values, TwingleProject::OUT);
// Get Template for project options
$project_options_template = TwingleProject::$templates['project_options'];
// Replace array items which the Twingle API does not expect
foreach ($values as $key => $value) {
if (!key_exists($key, $project_options_template)) {
unset($values[$key]);
}
}
// Format project target format
if (key_exists('has_projecttarget_as_money', $values)) {
$values['has_projecttarget_as_money'] =
$values['has_projecttarget_as_money'] ? 'in Euro' : 'percentage';
}
return $values;
}
/**
* Translate values between CiviCRM Campaigns and Twingle
*
* @param array $values
* array of which values shall be translated
*
* @param string $direction
* TwingleProject::IN -> translate array values from Twingle to CiviCRM <br>
* TwingleProject::OUT -> translate array values from CiviCRM to Twingle
*
* @throws Exception
*/
public static function formatValues(array &$values, string $direction) {
if ($direction == TwingleProject::IN) {
// Change timestamp into DateTime string
if ($values['last_update']) {
$values['last_update'] =
TwingleProject::getDateTime($values['last_update']);
}
// format donation rhythm
if (is_array($values['donation_rhythm'])) {
$tmp = [];
foreach ($values['donation_rhythm'] as $key => $value) {
if ($value) {
$tmp[$key] = $key;
}
}
$values['donation_rhythm'] = CRM_Utils_Array::implodePadded($tmp);
}
// Format contact fields
if ($values['exclude_contact_fields']) {
$possible_contact_fields =
TwingleProject::$campaigns['custom_fields']
['twingle_project_exclude_contact_fields']['option_values'];
$exclude_contact_fields = explode(
',',
$values['exclude_contact_fields']
);
foreach ($exclude_contact_fields as $exclude_contact_field) {
unset($possible_contact_fields[$exclude_contact_field]);
}
$values['exclude_contact_fields'] =
CRM_Utils_Array::implodePadded($possible_contact_fields);
}
// Format languages
if ($values['languages']) {
$values['languages'] =
CRM_Utils_Array::implodePadded(
explode(
',',
$values['languages']
)
);
}
// Format project target format
if (key_exists('has_projecttarget_as_money', $values)) {
$values['has_projecttarget_as_money'] =
$values['has_projecttarget_as_money'] ? 'in Euro' : 'percentage';
}
}
elseif ($direction == TwingleProject::OUT) {
// Change DateTime string into timestamp
$values['last_update'] =
TwingleProject::getTimestamp($values['last_update']);
// format donation rhythm
if (is_array($values['donation_rhythm'])) {
$tmp = [];
foreach ($values['donation_rhythm'] as $key => $value) {
if ($value) {
$tmp[$key] = $key;
}
}
$values['donation_rhythm'] = CRM_Utils_Array::implodePadded($tmp);
}
// Format contact fields
if ($values['exclude_contact_fields']) {
$possible_contact_fields =
TwingleProject::$campaigns['custom_fields']
['twingle_project_exclude_contact_fields']['option_values'];
$exclude_contact_fields = explode(
',',
$values['exclude_contact_fields']
);
foreach ($exclude_contact_fields as $exclude_contact_field) {
unset($possible_contact_fields[$exclude_contact_field]);
}
$values['exclude_contact_fields'] =
CRM_Utils_Array::implodePadded($possible_contact_fields);
}
// Format languages
if ($values['languages']) {
$values['languages'] =
CRM_Utils_Array::implodePadded(
explode(
',',
$values['languages']
)
);
}
// Cast project_target to integer
$values['project_target'] = (int) $values['project_target'];
}
else {
throw new Exception(
"Invalid Parameter $direction for formatValues()"
);
}
}
/**
* @return array
*/
public function getValues(): array {
return $this->values;
}
public function lastUpdate() {
return $this->values['last_update'];
}
}

File diff suppressed because it is too large Load diff

View file

@ -10,77 +10,14 @@
"type",
"last_update"
],
"event": [
"project_embed_data": [
"widget",
"form",
"form-single",
"widget-single",
"eventall",
"eventlist"
],
"project_options": {
"has_confirmation_mail": false,
"has_confirmation_mail_api": false,
"has_donation_receipt": true,
"has_contact_data": false,
"donation_rhythm": {
"yearly": true,
"halfyearly": false,
"quarterly": false,
"monthly": true,
"one_time": true
},
"has_newsletter_registration": false,
"has_postinfo_registration": false,
"design_background_color": "",
"design_primary_color": "",
"design_font": "",
"design_font_color": "",
"design_button_font_color": "",
"design_button_font_color_light": "",
"image": "",
"bcc_email_address": "",
"donation_value_min": 5,
"donation_value_max": 500,
"donation_value_default": 50,
"exclude_contact_fields": "birthday",
"custom_js": null,
"custom_css": null,
"share_url": null,
"has_contact_mandatory": false,
"has_doi": true,
"doi_redirect": null,
"has_force_donation_target_buttons": false,
"has_show_single_target": false,
"betterpayment_credit_card_theme": null,
"app_js": null,
"slidericon": "heart",
"extra_field": [],
"has_hidden_logo": false,
"has_projecttarget_as_money": false,
"rapidmail_recipient_list": null,
"mailchimp_recipient_list": null,
"has_mailchimp_add_all_user": null,
"has_mail_hide_paymentblock": false,
"has_mail_hide_paymentblock_api": false,
"has_donationtarget_textfield": false,
"has_civi_crm_activated": false,
"has_step_index": false,
"gift_donation": "",
"gift_donation_icon": null,
"gift_donation_image": null,
"languages": "de",
"has_buttons": false,
"has_no_slider": false,
"buttons": {
"button1": {
"amount": ""
},
"button2": {
"amount": ""
},
"button3": {
"amount": ""
}
},
"has_newsletter_namerequest": false,
"has_show_donator_data": false,
"has_donation_letter": false,
"has_donation_letter_api": false,
"amount_images": []
}
"event": [
]
}

View file

@ -74,18 +74,6 @@ class TwingleApiCall {
return $response;
}
public function getProjectOptions(int $projectId) {
$response = [];
foreach ($this->organisationId as $organisationId) {
$url = $this->protocol . 'project' . $this->baseUrl . $projectId .
'/options';
$response = array_merge($this->curlGet($url));
}
return $response;
}
/**
*
* Returns all Events for the given $projectId
@ -138,25 +126,6 @@ class TwingleApiCall {
// If $values is an array
if (is_array($values)) {
// Get project options
try {
$values['options'] = $this->getProjectOptions($values['id']);
} catch (Exception $e) {
// Log Exception
Civi::log()->error(
"Failed to instantiate TwingleProject: $e->getMessage()"
);
// Return result array with error description
return [
"title" => $values['name'],
"project_id" => (int) $values['id'],
"status" =>
"Failed to get project options from Twingle: $e->getMessage()",
];
}
// Instantiate TwingleProject
try {
$project = new TwingleProject(
@ -182,8 +151,9 @@ class TwingleApiCall {
// Check if the TwingleProject campaign already exists
if (!$project->exists()) {
// ... if not, create it
// ... if not, get embed data and create project
try {
$this->getEmbedData($project);
$result = $project->create($is_test);
} catch (Exception $e) {
@ -206,12 +176,10 @@ class TwingleApiCall {
// If Twingle's version of the project is newer than the CiviCRM
// TwingleProject campaign update the campaign
$lastUpdate = $values['last_update'] > $values['options']['last_update']
? $values['last_update']
: $values['options']['last_update'];
if ($lastUpdate > $project->lastUpdate()) {
if ($values['last_update'] > $project->lastUpdate()) {
try {
$project->update($values);
$this->getEmbedData($project);
$result = $project->create();
$result['status'] = $result['status'] == 'TwingleProject created'
? 'TwingleProject updated'
@ -229,7 +197,7 @@ class TwingleApiCall {
}
// If the CiviCRM TwingleProject campaign was changed, update the project
// on Twingle's side
elseif ($lastUpdate < $project->lastUpdate()) {
elseif ($values['last_update'] < $project->lastUpdate()) {
// If this is a test do not make database changes
if ($is_test) {
$result = $project->getResponse(
@ -243,10 +211,8 @@ class TwingleApiCall {
elseif ($result['status'] == 'TwingleProject exists') {
$result = $project->getResponse('TwingleProject up to date');
}
}
// Return a response of the synchronization
return $result;
}
@ -256,6 +222,25 @@ class TwingleApiCall {
}
/**
* @param \CRM\TwingleCampaign\BAO\TwingleProject $project
*/
private function getEmbedData(TwingleProject &$project) {
// Prepare url for curl
$url = $this->protocol . 'project' . $this->baseUrl . $project->getProjectId();
// Send curl
$result = $this->curlGet($url);
// Set embed data
$project->setEmbedData($result['embed']);
// Set counter-url
$project->setCounterUrl($result['counter-url']['url']);
}
/**
* Sends an curl post call to Twingle to update an existing project and then
* updates the TwingleProject campaign.
@ -267,7 +252,7 @@ class TwingleApiCall {
* Returns a response array that contains title, id, project_id and status
*
*/
public function updateProject(TwingleProject &$project) {
private function updateProject(TwingleProject &$project) {
try {
$values = $project->export();
@ -292,7 +277,8 @@ class TwingleApiCall {
if (is_array($result) && !array_key_exists('message', $result)) {
// Try to update the local TwingleProject campaign
try {
$project->update($result, TwingleProject::TWINGLE);
$project->update($result);
$this->getEmbedData($project);
$project->create();
return $project->getResponse('TwingleProject pushed to Twingle');
} catch (Exception $e) {