Compare commits

..

No commits in common. "main" and "IHK-Projekt" have entirely different histories.

33 changed files with 516 additions and 1066 deletions

View file

@ -125,9 +125,7 @@ abstract class CRM_TwingleCampaign_BAO_Campaign {
/**
* ## Complement campaign values
* Complement existing campaign values with new ones.
* Existing values will not get overwritten.
*
* Complement existing campaign values with new ones
* @param array $arrayToComplement
*/
public function complement(array $arrayToComplement) {
@ -145,27 +143,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign {
}
}
/**
* ## Merge campaign values
* Merge existing campaign values with new ones.
* Existing values will be overwritten!
*
* @param array $arrayToMerge
*/
public function merge(array $arrayToMerge) {
$this->complement_r($arrayToMerge, $this->values);
}
private function merge_r($orig, &$fill) {
foreach ($orig as $key => $value) {
if (is_array($value)) {
$this->complement_r($orig[$key], $fill[$key]);
} else {
$fill[$key] = $value;
}
}
}
public static abstract function formatValues(array &$values, string $direction);
/**

View file

@ -6,9 +6,8 @@ class CRM_TwingleCampaign_BAO_Configuration {
private static $settingsKeys = [
'twingle_api_key',
'twinglecampaign_xcm_profile',
'twinglecampaign_default_case',
'twinglecampaign_soft_credits',
'twinglecampaign_matomo_integration'
'twinglecampaign_start_case',
'twinglecampaign_soft_credits'
];
@ -28,12 +27,6 @@ class CRM_TwingleCampaign_BAO_Configuration {
Civi::settings()->set('twinglecampaign_soft_credits', 0);
}
// Set twinglecampaign_matomo_integration to '0' if checkbox is unchecked
if (!array_key_exists('twinglecampaign_matomo_integration', $settings)) {
Civi::settings()->set('twinglecampaign_matomo_integration', 0);
}
Civi::settings()->add($settings);
}
@ -70,4 +63,4 @@ class CRM_TwingleCampaign_BAO_Configuration {
}
}
}
}

View file

@ -56,17 +56,16 @@ class CRM_TwingleCampaign_BAO_CustomField {
}
}
/**
* Creates a CustomField by calling CiviCRM API v.3
*
* @param bool $upgrade
* If true: Does not show UF message if custom field already exists
*
* @returns array|False Result of custom field creation api call. False if
* field already existed und wasn't upgraded.
* @throws \CiviCRM_API3_Exception
*/
public function create(bool $upgrade = FALSE) {
public function create(bool $upgrade = false) {
// Check if the field already exists
$field = civicrm_api3(
@ -80,185 +79,46 @@ class CRM_TwingleCampaign_BAO_CustomField {
// If the field does not exist, create it
if ($field['count'] == 0) {
$this->result = civicrm_api3(
'CustomField',
'create',
$this->getSetAttributes());
try {
$this->result = civicrm_api3(
'CustomField',
'create',
$this->getSetAttributes());
// Set field id
$this->id = $this->result['id'];
if ($this->result['is_error'] == 0) {
// Set field id
$this->id = $this->result['id'];
// Log field creation
Civi::log()->info("$this->extensionName has created a new custom field.
label: $this->label
name: $this->name
id: $this->id
group: $this->custom_group_id"
);
return $this->result;
}
else {
throw new CiviCRM_API3_Exception($this->result['error_message']);
}
} catch (CiviCRM_API3_Exception $e) {
$errorMessage = $e->getMessage();
// If the field could not get created: log error
// Log field creation
if ($this->result['is_error'] == 0) {
Civi::log()->info("$this->extensionName has created a new custom field.
label: $this->label
name: $this->name
id: $this->id
group: $this->custom_group_id"
);
}
// If the field could not get created: log error
else {
if ($this->name && $this->custom_group_id) {
Civi::log()
->error("$this->extensionName could not create new custom field \"$this->name\" for group \"$this->custom_group_id\": $errorMessage");
CRM_Utils_System::setUFMessage(E::ts('%1: Creation of custom field \'%2\' failed. Find more information in the logs.',
[1 => $this->extensionName, 2 => $this->name]
));
->error("$this->extensionName could not create new custom field
\"$this->name\" for group \"$this->custom_group_id\":
$this->result['error_message']");
CRM_Utils_System::setUFMessage(E::ts('Creation of custom field \'%1\' failed. Find more information in the logs.', [1 => $this->name]));
}
// If there is not enough information: log simple error message
else {
Civi::log()
->error("$this->extensionName could not create new custom field: $errorMessage");
->error("$this->extensionName could not create new custom field:
$this->result['error_message']");
CRM_Utils_System::setUFMessage(E::ts("Creation of custom field failed. Find more information in the logs."));
}
return $this->result;
}
}
elseif (!$upgrade) {
CRM_Utils_System::setUFMessage(E::ts('Creation of custom field \'%1\' failed, because a custom field with that name already exists. Find more information in the logs.', [1 => $this->name]));
Civi::log()
->error("$this->extensionName could not create new custom field \"$this->name\" for group \"$this->custom_group_id\" because a field with that name already exists.");
return NULL;
}
else {
$this->id = $field['values'][0]['id'];
$this->custom_group_id = $field['values'][0]['custom_group_id'];
return $this->upgrade($field['values'][0]);
}
}
/**
* Upgrade an existing custom field
*
* @param $attributes
* Custom Field data
* @returns array|False Result of custom field creation api call, False if
* field was not upgraded
*/
private function upgrade($attributes) {
$upgrade_necessary = False;
if (key_exists('option_group_id', $attributes)) {
$this->addOptions($attributes);
}
foreach ($this as $var => $value) {
// put array items into attributes
if (array_key_exists($var, $attributes) && $attributes[$var] != $value) {
$this->$var = $attributes[$var];
$upgrade_necessary = True;
}
}
if ($upgrade_necessary) {
try {
$this->result = civicrm_api3(
'CustomField',
'create',
$this->getSetAttributes());
// Log field creation
if ($this->result['is_error'] == 0) {
Civi::log()->info("$this->extensionName has updated a custom field.
label: $this->label
name: $this->name
id: $this->id
group: $this->custom_group_id"
);
return $this->result;
}
else {
throw new CiviCRM_API3_Exception($this->result['error_message']);
}
}
catch (CiviCRM_API3_Exception $e) {
// If the field could not get created: log error
$errorMessage = $e->getMessage();
if ($this->name && $this->custom_group_id) {
Civi::log()
->error("$this->extensionName could not create new custom field \"$this->name\" for group \"$this->custom_group_id\": $errorMessage");
CRM_Utils_System::setUFMessage(E::ts('Creation of custom field \'%1\' failed. Find more information in the logs.', [1 => $this->name]));
}
// If there is not enough information: log simple error message
else {
Civi::log()
->error("$this->extensionName could not create new custom field: $errorMessage");
CRM_Utils_System::setUFMessage(E::ts("Creation of custom field failed. Find more information in the logs."));
}
return $this->result;
}
}
return False;
}
/**
* Add additional options to custom field
*
* @param array $options
*
* @return array
*/
public function addOptions(array $options): array {
$result = [];
try {
foreach ($this->option_values as $key => $value) {
$option_value_exists = civicrm_api3(
'OptionValue',
'get',
[
'sequential' => 1,
'option_group_id' => $options['option_group_id'],
'value' => $key,
]
);
// If the option value does not yet exist, create it
if ($option_value_exists['count'] == 0) {
$result[] = civicrm_api3(
'OptionValue',
'create',
[
'option_group_id' => $options['option_group_id'],
'value' => $key,
'label' => $value,
]
);
}
// If the option value already exist, update it
else {
$result[] = civicrm_api3(
'OptionValue',
'create',
[
'id' => $option_value_exists['values'][0]['id'],
'label' => $value,
'value' => $key,
]
);
}
}
} catch (CiviCRM_API3_Exception $e) {
$errorMessage = $e->getMessage();
Civi::log()
->error("$this->extensionName could not create additional option values for custom field \"$this->name\": $errorMessage");
CRM_Utils_System::setUFMessage(
E::ts('%1 could not create additional option values for custom field \'%2\'. Find more information in the logs.',
[1 => $this->extensionName, 2 => $this->name])
);
}
return $result;
}
/**
@ -277,6 +137,7 @@ class CRM_TwingleCampaign_BAO_CustomField {
return $setAttributes;
}
/**
* Get an instance of a CustomField by its name or get an array with all
* custom fields by leaving parameters empty.
@ -355,12 +216,12 @@ class CRM_TwingleCampaign_BAO_CustomField {
if ($this->label && $this->custom_group_id) {
Civi::log()
->error("$this->extensionName could not delete custom field
\"$this->label\" for group \"$this->custom_group_id\":
\"$this->label\" for group \"$this->custom_group_id\":
$this->result['error_message']");
}
else {
Civi::log()
->error("$this->extensionName could not delete custom field:
->error("$this->extensionName could not delete custom field:
$this->result['error_message']");
}
}
@ -495,13 +356,6 @@ class CRM_TwingleCampaign_BAO_CustomField {
*/
public function getId() {
return $this->id;
}
}#
/**
* @param mixed $option_values
*/
public function setOptionValues($option_values): void {
$this->option_values = $option_values;
}
}
}

View file

@ -158,7 +158,7 @@ class CRM_TwingleCampaign_BAO_OptionValue {
// If a specific option value is required
try {
$option_value = civicrm_api3(
'OptionValue',
'CustomValue',
'get',
[
'sequential' => 1,

View file

@ -2,7 +2,6 @@
use CRM_TwingleCampaign_Utils_ExtensionCache as ExtensionCache;
use CRM_TwingleCampaign_ExtensionUtil as E;
use CRM_TwingleCampaign_Exceptions_TwingleCampaignException as TwingleCampaignException;
class CRM_TwingleCampaign_BAO_TwingleCampaign {
@ -18,47 +17,33 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
private $values;
/**
* ## TwingleCampaign constructor
*
* @param array $values
* @param array|null $values
* @param int|null $id
*
* @throws \CiviCRM_API3_Exception
* @throws \CRM_TwingleCampaign_Exceptions_TwingleCampaignException
*/
public function __construct(array $values = []) {
public function __construct(array $values = [], int $id = NULL) {
$this->prefix = 'twingle_campaign_';
$this->id = $values['id'] ?? NULL;
$this->id = $id ?? NULL;
$this->values['campaign_type_id'] = 'twingle_campaign';
// If there is already an ID for this TwingleProject, get its values from
// the database
if ($this->id != NULL) {
$this->fetch($this->id);
}
// Update the campaign values
$this->update($values);
// Get the parent TwingleProject
// (it doesn't matter how many levels above in the campaign tree it is)
$this->getParentProject();
// If this is a new TwingleCampaign or if it is a cloned TwingleCampaign,
// calculate a cid
if (
!isset($this->values['cid']) ||
(isset($values['clone']) && $values['clone'])
) {
if ($this->id) {
$this->update($values);
$this->getParentProject();
$this->createCid();
$this->createUrl();
}
else {
$this->update($values);
}
// Create an url from the parent TwingleProject url and the cid of this
// TwingleCampaign
$this->createUrl();
}
/**
* ## Create TwingleCampaign
* Create this TwingleCampaign as a campaign in CiviCRM
@ -85,17 +70,19 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
}
}
/**
* ## Fetch TwingleCampaign
* Populate this instance with values from an existing TwingleCampaign.
*
* @throws CiviCRM_API3_Exception
*/
public function fetch(int $id) {
public function fetch() {
$this->values = civicrm_api3('TwingleCampaign', 'getsingle',
['id' => $id]);
['id' => $this->id]);
}
/**
* ## Get Parent Project
* Determines the id of the parent TwingleProject. If there is no parent
@ -103,7 +90,6 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
* deleted.
*
* @throws \CiviCRM_API3_Exception
* @throws \CRM_TwingleCampaign_Exceptions_TwingleCampaignException
*/
private function getParentProject(): void {
@ -114,9 +100,10 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
// Determine the parent project id by looping through the campaign tree
// until the parent campaign type is a TwingleProject
$parent_id = $this->values['parent_id'] ?? civicrm_api3(
'TwingleCampaign',
'getsingle',
$parent_id = $this->values['parent_id'];
$parent_id = $parent_id ?? civicrm_api3(
'TwingleCampaign',
'getsingle',
['id' => $this->id]
)['parent_id'];
@ -134,7 +121,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
}
$parent_campaign_type_id = $parent_campaign['campaign_type_id'];
if ($parent_campaign_type_id != $twingle_project_campaign_type_id && isset($parent_campaign['parent_id'])) {
if (isset($parent_campaign['parent_id'])) {
$parent_id = $parent_campaign['parent_id'];
}
else {
@ -142,6 +129,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
}
}
// Set parent_project_id and retrieve parent_project_url
if ($parent_campaign_type_id == $twingle_project_campaign_type_id) {
$this->values['parent_project_id'] = $parent_id;
@ -184,7 +172,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
' could not determine parent TwingleProject URL.',
$this->getResponse()
);
throw new TwingleCampaignException('Parent project URL missing');
$this->delete();
}
}
@ -197,7 +185,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
ts('No parent TwingleProject found'),
'alert'
);
throw new TwingleCampaignException('No parent TwingleProject found');
$this->delete();
}
}
@ -218,14 +206,16 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
$this->values['parent_project_url'] . '?tw_cid=' . $this->values['cid'];
}
/**
*
*/
private
function createCid() {
$this->values['cid'] = uniqid();
$this->values['cid'] = md5($this->id . '_' . $this->values['name']);
}
/**
* ## Translate field names and custom field names
*
@ -294,6 +284,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
}
}
/**
* ## Delete TwingleCampaign
* Deletes this TwingleCampaign from CiviCRM
@ -305,7 +296,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
} catch (CiviCRM_API3_Exception $e) {
Civi::log()->error(
E::LONG_NAME .
' could not delete TwingleCampaign: ' .
' could delete TwingleCampaign: ' .
$e->getMessage(),
$this->getResponse()
);
@ -313,6 +304,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
}
}
/**
* ## Get a response
* Get a response that describes the status of this TwingleCampaign instance.
@ -326,15 +318,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
*/
public
function getResponse(string $status = NULL): array {
$keys = [
'id',
'name',
'title',
'parent_project_id',
'parent_id',
'cid',
'url',
];
$keys = ['id', 'name', 'title', 'parent_project_id', 'parent_id', 'cid', 'url'];
$response = [];
foreach ($keys as $key) {
if (isset($this->values[$key])) {
@ -357,22 +341,35 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign {
*/
private
function update(array $values) {
$filter = ExtensionCache::getInstance()
->getTemplates()['TwingleCampaign']['campaign_data'];
$filter = ExtensionCache::getInstance()->getTemplates()['TwingleCampaign'];
foreach ($values as $key => $value) {
if (in_array($key, $filter)) {
$this->values[$key] = $value;
$this->values[$key] = $values[$key];
}
}
}
/**
* ## Get ID
* ## Clone this TwingleProject
*
* This method removes the id from this instance and in the next step it
* creates the clone as a new TwingleCampaign with the same values to
* Twingle.
*
* @throws \CiviCRM_API3_Exception
*/
public
function clone() {
// TODO: implement cloning
}
/**
* ## Get ID
* @return mixed|null
*/
public function getId(): int {
return (int) $this->id;
}
}

View file

@ -27,7 +27,7 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign {
$this->id_custom_field = Cache::getInstance()
->getCustomFieldMapping()['twingle_event_id'];
if (!isset($this->values['parent_id'])) {
if (isset($this->values['parent_id'])) {
try {
$this->values['parent_id'] = $this->getParentCampaignId();
} catch (CiviCRM_API3_Exception $e) {
@ -35,7 +35,6 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign {
throw new Exception("Could not identify parent Campaign: $errorMessage");
}
}
}
@ -53,39 +52,32 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign {
if (parent::create()) {
// Get case type
$parentProject = civicrm_api3(
'TwingleProject',
'getsingle',
['id' => $this->values['parent_id']]
);
$caseType = $parentProject['case']
?? Configuration::get('twinglecampaign_default_case');
// check for existence
$result = civicrm_api3('Case', 'get', [
'contact_id' => $this->formattedValues['contact'],
'case_type_id' => Configuration::get('twinglecampaign_start_case'),
'subject' => $this->formattedValues['title'] . ' | Event-ID: ' .
$this->formattedValues['id'],
]);
if ($caseType) {
// check for existence
$result = civicrm_api3('Case', 'get', [
// Open a case
if (
Configuration::get('twinglecampaign_start_case') &&
$result['count'] == 0
) {
$result = civicrm_api3('Case', 'create', [
'contact_id' => $this->formattedValues['contact'],
'case_type_id' => $caseType,
'case_type_id' => Configuration::get('twinglecampaign_start_case'),
'subject' => $this->formattedValues['title'] . ' | Event-ID: ' .
$this->formattedValues['id'],
'start_date' => $this->formattedValues['created_at'],
'status_id' => "Open",
]);
// Open a case
if ($result['count'] == 0) {
$result = civicrm_api3('Case', 'create', [
'contact_id' => $this->formattedValues['contact'],
'case_type_id' => $caseType,
'subject' => $this->formattedValues['title'] . ' | Event-ID: ' .
$this->formattedValues['id'],
'start_date' => $this->formattedValues['created_at'],
'status_id' => "Open",
]);
}
if ($result['is_error'] != 0) {
throw new Exception('Could not create case');
}
}
if ($result['is_error'] != 0) {
throw new Exception('Could not create case');
}
return TRUE;
}
return FALSE;
@ -219,15 +211,13 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign {
private
static function matchContact(string $names, string $email): ?int {
$names = StringOps::split_names($names); // Hopefully just a temporary solution
$firstnames = $names['firstnames'] ?? NULL;
$lastname = $names['lastname'] ?? NULL;
$display_name = $names['display_name'] ?? NULL;
$firstnames = $names['firstnames'];
$lastname = $names['lastname'];
try {
$contact = civicrm_api3('Contact', 'getorcreate', [
'xcm_profile' => Civi::settings()->get('twinglecampaign_xcm_profile'),
'first_name' => $firstnames,
'last_name' => $lastname,
'display_name' => $display_name,
'email' => $email,
]);
return (int) $contact['id'];

View file

@ -31,15 +31,6 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign {
'one_time',
];
// All fields for hex color codes
const colorFields = [
'design_background_color',
'design_primary_color',
'design_font_color',
'design_button_font_color',
'design_button_font_color_light',
];
/**
* ## TwingleProject constructor
*
@ -152,13 +143,11 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign {
*/
private function strToInt(array &$values) {
foreach ($values as $key => $value) {
if (!in_array($key, self::colorFields)) {
if (ctype_digit($value)) {
$values[$key] = intval($value);
}
elseif (is_array($value)) {
$this->strToInt($values[$key]);
}
if (ctype_digit($value)) {
$values[$key] = intval($value);
}
elseif (is_array($value)) {
$this->strToInt($values[$key]);
}
}
}
@ -176,13 +165,15 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign {
*/
public function create(bool $no_hook = FALSE): bool {
# If this project is not meant to be synced, do not create a campaign
if (!$this->values['project_options']['has_civi_crm_activated']) {
return FALSE;
$result = parent::create($no_hook);
// Check if campaign was created successfully
if ($result['is_error'] == 0) {
return TRUE;
}
else {
throw new Exception($result['error_message']);
}
return parent::create($no_hook);
}
/**
@ -302,18 +293,21 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign {
}
// Validate hexadecimal color fields
foreach (self::colorFields as $colorField) {
$colorFields =
[
'design_background_color',
'design_primary_color',
'design_font_color',
];
foreach ($colorFields as $colorField) {
if (
(
!empty($this->values['project_options'][$colorField]) ||
$this->values['project_options'][$colorField] === "0"
) &&
!empty($this->values['project_options'][$colorField]) &&
(
!(
ctype_xdigit($this->values['project_options'][$colorField]) ||
is_integer($this->values['project_options'][$colorField])
) ||
strlen((string) $this->values['project_options'][$colorField]) != 6
strlen((string) $this->values['project_options'][$colorField]) > 6
)
) {
$valid = FALSE;
@ -568,17 +562,13 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign {
}
// Change DateTime string into timestamp
if (isset($values['last_update'])) {
$values['last_update'] =
self::getTimestamp($values['last_update']);
}
$values['last_update'] =
self::getTimestamp($values['last_update']);
// Default project_type to ''
if (isset($values['type'])) {
$values['type'] = $values['type'] == 'default'
? ''
: $values['type'];
}
$values['type'] = $values['type'] == 'default'
? ''
: $values['type'];
// Cast project target to integer
if (isset($values['project_target'])) {
@ -771,14 +761,4 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign {
unset($this->values['payment_methods']);
}
/**
* ## Set project name
*
* @param string $name
*/
public function setName(string $name): void {
$this->values['name'] = $name;
}
}

View file

@ -1,8 +0,0 @@
<?php
/*
* A simple custom exception that indicates a problem within the TwingleCampaign class
*/
class CRM_TwingleCampaign_Exceptions_TwingleCampaignException extends Exception {
}

View file

@ -4,7 +4,6 @@ use CRM_TwingleCampaign_BAO_Configuration as Configuration;
use CRM_TwingleCampaign_ExtensionUtil as E;
include_once E::path() . '/CRM/TwingleCampaign/BAO/Configuration.php';
include_once E::path() . '/CRM/TwingleCampaign/Utils/CaseTypes.php';
/**
* Form controller class
@ -33,9 +32,9 @@ class CRM_TwingleCampaign_Form_Settings extends CRM_Core_Form {
$this->addElement(
'select',
'twinglecampaign_default_case',
E::ts('Default case to open for event initiators'),
getCaseTypes(),
'twinglecampaign_start_case',
E::ts('Start a case for event initiators'),
$this->getCaseTypes(),
['class' => 'crm-select2 huge']
);
@ -46,13 +45,6 @@ class CRM_TwingleCampaign_Form_Settings extends CRM_Core_Form {
FALSE
);
$this->addElement(
'checkbox',
'twinglecampaign_matomo_integration',
E::ts('Use Matomo to track user interaction with Twingle forms'),
FALSE
);
$this->addButtons([
[
'type' => 'submit',
@ -100,5 +92,30 @@ class CRM_TwingleCampaign_Form_Settings extends CRM_Core_Form {
return $xcmProfiles;
}
/**
* Retrieves all case types
*
* @return array
*/
private function getCaseTypes(): array {
$caseTypes = [NULL => E::ts('none')];
try {
$result = civicrm_api3('CaseType', 'get', [
'sequential' => 1,
'options' => ['limit' => 0]
]);
if (is_array($result['values'])) {
foreach ($result['values'] as $case) {
$caseTypes[$case['name']] = $case['title'];
}
}
} catch (CiviCRM_API3_Exception $e) {
Civi::log()->error(
E::LONG_NAME . ' could not retrieve case types: ' .
$e->getMessage());
}
return $caseTypes;
}
}

View file

@ -13,14 +13,13 @@ use CRM_TwingleCampaign_ExtensionUtil as E;
*/
class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base {
// By convention, functions that look like "function upgrade_NNNN()" are
// upgrade tasks. They are executed in order (like Drupal's hook_update_N).
/**
* This update function checks whether all custom fields defined in
* CRM/TwingleCampaign/resources/campaigns.php exist and creates them if not.
* To ensure that all newly created custom fields get filled with data, all
* changed campaigns will get pulled from Twingle.
* @throws \CiviCRM_API3_Exception
*/
public function upgrade_03(): bool {
public function upgrade_01() {
$campaign_info = require E::path() .
'/CRM/TwingleCampaign/resources/campaigns.php';
@ -32,7 +31,7 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base {
new CampaignType($campaign_type);
}
foreach (CampaignType::getCampaignTypes() as $campaign_type) {
$campaign_type->create(TRUE);
$campaign_type->create(true);
}
// Create custom groups
@ -43,61 +42,13 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base {
}
}
$cg = new CustomGroup($custom_group);
$cg->create(TRUE);
$cg->create(true);
}
// If new fields get created during the update, set a flag to set all
// last_update values of the affected campaigns to "0" and trigger a
// synchronization. This ensures that settings on Twingle's side will not
// get overwritten with empty values.
$updatedCampaignTypes = [];
// Create custom fields
foreach ($campaign_info['custom_fields'] as $custom_field) {
$cf = new CustomField($custom_field);
$result = $cf->create(TRUE);
if (!empty($result)) {
preg_match(
'/^Twingle_[a-yA-Z]*/',
$cf->getCustomGroupId(),
$updatedCampaignTypes[]
);
}
}
// Filter changed campaign types
foreach ($updatedCampaignTypes as $key => $value) {
$updatedCampaignTypes[str_replace('_', '', $value[0])]
= TRUE;
unset($updatedCampaignTypes[$key]);
}
// Pull changed campaigns to fill new created fields with data
try {
foreach ($updatedCampaignTypes as $key => $value) {
if ($value === TRUE) {
civicrm_api3(
$key,
'sync',
['pull' => TRUE]
);
}
}
} catch (Exception $e) {
Civi::log()->error(
E::LONG_NAME .
' could not pull campaigns from Twingle to fill the campaign fields that were created on update.' .
$e->getMessage()
);
CRM_Core_Session::setStatus(
E::ts(
'Could not pull campaigns from Twingle to fill the campaign fields that were created within this update: %1',
[1 => $e->getMessage()]
),
E::ts('Scheduled Job'),
'error'
);
$cf->create(true);
}
// Create option values
@ -173,6 +124,7 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base {
E::ts('Scheduled Job'),
error
);
CRM_Utils_System::setUFMessage(E::ts('Could not create scheduled job "TwingleSync". Your Campaigns will not get synchronized to Twingle.'));
}
}
@ -294,4 +246,83 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base {
Civi::settings()->revert('twingle_api_key');
}
/**
* Example: Run a couple simple queries.
*
* @return TRUE on success
* @throws Exception
*
* public function upgrade_4200() {
* $this->ctx->log->info('Applying update 4200');
* CRM_Core_DAO::executeQuery('UPDATE foo SET bar = "whiz"');
* CRM_Core_DAO::executeQuery('DELETE FROM bang WHERE willy = wonka(2)');
* return TRUE;
* } // */
/**
* Example: Run an external SQL script.
*
* @return TRUE on success
* @throws Exception
* public function upgrade_4201() {
* $this->ctx->log->info('Applying update 4201');
* // this path is relative to the extension base dir
* $this->executeSqlFile('sql/upgrade_4201.sql');
* return TRUE;
* } // */
/**
* Example: Run a slow upgrade process by breaking it up into smaller chunk.
*
* @return TRUE on success
* @throws Exception
* public function upgrade_4202() {
* $this->ctx->log->info('Planning update 4202'); // PEAR Log interface
*
* $this->addTask(E::ts('Process first step'), 'processPart1', $arg1, $arg2);
* $this->addTask(E::ts('Process second step'), 'processPart2', $arg3, $arg4);
* $this->addTask(E::ts('Process second step'), 'processPart3', $arg5);
* return TRUE;
* }
* public function processPart1($arg1, $arg2) { sleep(10); return TRUE; }
* public function processPart2($arg3, $arg4) { sleep(10); return TRUE; }
* public function processPart3($arg5) { sleep(10); return TRUE; }
* // */
/**
* Example: Run an upgrade with a query that touches many (potentially
* millions) of records by breaking it up into smaller chunks.
*
* @return TRUE on success
* @throws Exception
* public function upgrade_4203() {
* $this->ctx->log->info('Planning update 4203'); // PEAR Log interface
*
* $minId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM
* civicrm_contribution');
* $maxId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM
* civicrm_contribution'); for ($startId = $minId; $startId <= $maxId;
* $startId += self::BATCH_SIZE) {
* $endId = $startId + self::BATCH_SIZE - 1;
* $title = E::ts('Upgrade Batch (%1 => %2)', array(
* 1 => $startId,
* 2 => $endId,
* ));
* $sql = '
* UPDATE civicrm_contribution SET foobar = whiz(wonky()+wanker)
* WHERE id BETWEEN %1 and %2
* ';
* $params = array(
* 1 => array($startId, 'Integer'),
* 2 => array($endId, 'Integer'),
* );
* $this->addTask($title, 'executeSql', $sql, $params);
* }
* return TRUE;
* } // */
}

View file

@ -40,8 +40,8 @@ class CRM_TwingleCampaign_Utils_APIWrapper {
$response_copy = $response;
// Create soft credit for contribution
if (array_key_exists('contribution', $response)) {
$contribution = array_shift($response_copy['contribution']);
if (array_key_exists('contribution', $response['values'])) {
$contribution = array_shift($response_copy['values']['contribution']);
if (array_key_exists('campaign_id', $contribution)) {
try {
$twingle_event = civicrm_api3(
@ -49,7 +49,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper {
'getsingle',
['id' => $contribution['campaign_id']]
);
$response['soft_credit'] =
$response['values']['soft_credit'] =
self::createSoftCredit($contribution, $twingle_event)['values'];
$event->setResponse($response);
} catch (CiviCRM_API3_Exception $e) {
@ -58,8 +58,8 @@ class CRM_TwingleCampaign_Utils_APIWrapper {
}
}
// Create soft credit for sepa mandate
elseif (array_key_exists('sepa_mandate', $response)) {
$sepa_mandate = array_pop($response_copy['sepa_mandate']);
elseif (array_key_exists('sepa_mandate', $response['values'])) {
$sepa_mandate = array_pop($response_copy['values']['sepa_mandate']);
try {
$contribution = civicrm_api3(
@ -84,7 +84,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper {
'getsingle',
['id' => $contribution['contribution_campaign_id']]
);
$response['soft_credit'] =
$response['values']['soft_credit'] =
self::createSoftCredit($contribution, $twingle_event)['values'];
$event->setResponse($response);
} catch (CiviCRM_API3_Exception $e) {
@ -103,12 +103,12 @@ class CRM_TwingleCampaign_Utils_APIWrapper {
* the de.systopia.twingle extension can include the campaign into the
* contribution which it will create.
*
* @param array $apiRequest
* @param callable $callsame
* @param $apiRequest
* @param $callsame
*
* @return mixed
*/
public static function mapDonation(array $apiRequest, callable $callsame) {
public function mapDonation($apiRequest, $callsame) {
if (array_key_exists(
'campaign_id',
@ -129,7 +129,11 @@ class CRM_TwingleCampaign_Utils_APIWrapper {
}
}
}
elseif (!empty($apiRequest['params']['custom_fields']['event'])) {
elseif (array_key_exists(
'event',
$apiRequest['params']['custom_fields']) &&
!empty($apiRequest['params']['custom_fields']['event'])
) {
try {
$targetCampaign = civicrm_api3(
'TwingleEvent',
@ -200,9 +204,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper {
'contribution_id' => $contribution['id'],
]
);
throw $e;
}
}
}
}

View file

@ -1,27 +0,0 @@
<?php
use CRM_TwingleCampaign_ExtensionUtil as E;
/**
* Retrieves all case types
*
* @return array
*/
function getCaseTypes(): array {
try {
$result = civicrm_api3('CaseType', 'get', [
'sequential' => 1,
'options' => ['limit' => 0]
]);
if (is_array($result['values'])) {
foreach ($result['values'] as $case) {
$caseTypes[$case['name']] = $case['title'];
}
}
} catch (CiviCRM_API3_Exception $e) {
Civi::log()->error(
E::LONG_NAME . ' could not retrieve case types: ' .
$e->getMessage());
}
return $caseTypes;
}

View file

@ -1,75 +0,0 @@
<?php
/**
* A simple class which helps to generate JavaScript snippets which can be
* embedded in a website to track user interaction with Twingle forms via
* Matomo.
*/
class CRM_TwingleCampaign_Utils_MatomoSnippet {
private static function embed_in_base_function($code) {
return implode("\n",[
"<!-- matomo -->",
"<script>",
"window.addEventListener('message', function(event){",
"if(event && event.data && event.data.type === 'donationFinished') {",
$code,
"}",
"} , false);",
"</script>",
"<!-- matomo -->",
]);
}
/**
* Returns JavaScript snippet to track events in Matomo.
*
* @return string
*/
public static function get_event_tracker() {
$code = "_paq.push(['trackEvent', 'twingle', 'donation', event.data.value.recurringRythm, event.data.value.amount]);";
return self::embed_in_base_function($code);
}
/**
* Returns JavaScript snippet to track Matomo goals.
*
* @param $goal_id
* The ID of your Matomo goal.
*
* @return string
*/
public static function get_goal_tracker($goal_id) {
$code = "_paq.push(['trackGoal', $goal_id]);";
return self::embed_in_base_function($code);
}
/**
* Returns JavaScript snippet to track ecommerce activity in Matomo.
*
* @return string
*/
public static function get_ecommerce_tracker() {
$code = implode("\n", [
"_paq.push(['addEcommerceItem', event.data.value.rythm, '', event.data.value.target, event.data.value.amount]);",
"_paq.push(['trackEcommerceOrder', 'anonymizedData', event.data.value.amount]);",
]);
return self::embed_in_base_function($code);
}
/**
* Appends the given code to the original code.
*
* @param $original
* The original code.
* @param $appendix
* The code you want to append to the original code.
*
* @return string
* The combined code after appending the appendix.
*/
public static function append_code($original, $appendix) {
return $original . $appendix;
}
}

View file

@ -49,7 +49,7 @@ class CRM_TwingleCampaign_Utils_StringOperations {
$firstnames = implode(" ", $names);
return ['firstnames' => $firstnames, 'lastname' => $lastname];
}
return ['display_name' => $string];
return $string;
}
/**
@ -71,4 +71,4 @@ class CRM_TwingleCampaign_Utils_StringOperations {
public static function startsWith($haystack, $needle): bool {
return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
}
}

View file

@ -1,7 +1,6 @@
<?php
use CRM_TwingleCampaign_ExtensionUtil as E;
require_once E::path() . '/CRM/TwingleCampaign/Utils/CaseTypes.php';
return [
"campaign_types" => [
@ -113,9 +112,7 @@ return [
"option_values" => [
"default" => E::ts("Default"),
"event" => E::ts("Events"),
"membership" => E::ts("Membership"),
"shop" => E::ts("Shop"),
"giftshop" => E::ts("Gift Shop")
"membership" => E::ts("Membership")
],
"text_length" => 32,
"is_active" => 1,
@ -124,21 +121,6 @@ return [
"help_post" => E::ts("Choose the project type. Allow users to create own events or to pay a membership fee."),
"default_value" => "default"
],
"twingle_project_case" => [
"custom_group_id" => "Twingle_Project_Information",
"label" => E::ts("Case"),
"name" => "twingle_project_case",
"is_required" => FALSE,
"is_searchable" => 1,
"data_type" => "String",
"html_type" => "Select",
"option_values" => getCaseTypes(),
"text_length" => 32,
"is_active" => 1,
"is_view" => FALSE,
"weight" => 3,
"help_post" => E::ts("Which case should get opened for event creators?")
],
"twingle_project_allow_more" => [
"custom_group_id" => "Twingle_Project_Information",
"label" => E::ts("allow more"),

View file

@ -72,8 +72,6 @@ decrease this interval by changing the configuration of the scheduled job named
Furthermore, the synchronization may get triggered also if a donation for an unknown event arrives via the Twingle API
extension.
A CiviCRM site running [not in productive mode](https://docs.civicrm.org/sysadmin/en/latest/misc/staging-production/) will by default not run any scheduled jobs. In that case you can individually enable the TwingleSync job by adding the parameter runInNonProductionEnvironment=TRUE to the job.
## Known Issues
- The **Campaign Manager** displays a *«Campaign XY has been saved»* message even if the input validation failed and the
@ -83,4 +81,4 @@ A CiviCRM site running [not in productive mode](https://docs.civicrm.org/sysadmi
- [ ] Make the Twingle Event Settings for contact matching, case creation and creation of soft credits an individual
setting in each project
- [ ] Make more payment methods available
- [ ] Make more payment methods available

View file

@ -40,13 +40,6 @@ function _civicrm_api3_twingle_campaign_Create_spec(array &$spec) {
'api.required' => 1,
'description' => E::ts('Optional parent id for this Campaign'),
];
$spec['clone'] = [
'name' => 'clone',
'title' => E::ts('Clone'),
'type' => CRM_Utils_Type::T_BOOLEAN,
'api.required' => 0,
'description' => E::ts('Set this value to true if this campaign is about to be cloned to recreate cid'),
];
}
@ -68,10 +61,11 @@ function civicrm_api3_twingle_campaign_Create(array $params): array {
_civicrm_api3_twingle_campaign_Create_spec($allowed_params);
$params = array_intersect_key($params, $allowed_params);
// instantiate TwingleCampaign
$campaign = new TwingleCampaign($params, $params['id']);
// Try to create the TwingleCampaign
try {
// instantiate TwingleCampaign
$campaign = new TwingleCampaign($params);
// try to create the TwingleCampaign
$campaign->create(TRUE);
return civicrm_api3_create_success(
$campaign->getResponse('TwingleCampaign created'),
@ -80,8 +74,15 @@ function civicrm_api3_twingle_campaign_Create(array $params): array {
'Create'
);
} catch(Exception $e){
Civi::log()->error(
E::LONG_NAME .
' could not create TwingleCampaign: ' .
$e->getMessage(),
$campaign->getResponse()
);
return civicrm_api3_create_error(
'Could not create TwingleCampaign: ' . $e->getMessage()
'Could not create TwingleCampaign: ' . $e->getMessage(),
$campaign->getResponse()
);
}

View file

@ -33,13 +33,6 @@ function _civicrm_api3_twingle_campaign_Get_spec(array &$spec) {
'api.required' => 0,
'description' => E::ts('Twingle ID of the parent TwingleProject'),
];
$spec['parent_id'] = [
'name' => 'parent_id',
'title' => E::ts('Parent Project ID'),
'type' => CRM_Utils_Type::T_INT,
'api.required' => 0,
'description' => E::ts('ID of the parent TwingleProject'),
];
$spec['name'] = [
'name' => 'name',
'title' => E::ts('Campaign Name'),
@ -107,9 +100,6 @@ function civicrm_api3_twingle_campaign_Get(array $params): array {
_civicrm_api3_twingle_campaign_Get_spec($allowed_params);
$params = array_intersect_key($params, $allowed_params);
// Do not limit the number of results
$params['options'] = ['limit' => 0];
$returnValues = [];
// Get campaign type id for TwingleCampaign
@ -132,12 +122,13 @@ function civicrm_api3_twingle_campaign_Get(array $params): array {
// Include parent TwingleProject id in $params
$params['parent_id'] = $project['id'];
}
elseif (isset($params['parent_id'])) {
// Include campaign type ot TwingleCampaigns in $params
$params['campaign_type_id'] = $twingle_campaign_campaign_type_id;
// Do not limit the number of results
$params['options'] = ['limit' => 0];
// Get TwingleCampaign children campaigns of the TwingleProject
$campaigns = civicrm_api3('Campaign',
'get',
@ -166,7 +157,7 @@ function civicrm_api3_twingle_campaign_Get(array $params): array {
}
// Translate custom fields
if (!empty($campaigns['values'])) {
if (!empty($campaigns)) {
$custom_field_mapping_reverse =
array_flip(Cache::getInstance()->getCustomFieldMapping());
@ -180,7 +171,7 @@ function civicrm_api3_twingle_campaign_Get(array $params): array {
$returnValues[$campaign['id']][$key] = $value;
}
}
foreach ($returnValues[$campaign['id']] as $key => $value) {
foreach($returnValues[$campaign['id']] as $key => $value) {
if ($key != 'twingle_campaign_id' && strpos($key, 'twingle_campaign_') === 0) {
$returnValues[$campaign['id']][str_replace('twingle_campaign_', '', $key)]
= $value;

View file

@ -20,19 +20,12 @@ function _civicrm_api3_twingle_campaign_Sync_spec(array &$spec) {
'description' => E::ts('The Twingle Campaign ID'),
];
$spec['project_id'] = [
'name' => 'parent_project_id',
'name' => 'project_id',
'title' => E::ts('Parent Twingle Project ID'),
'type' => CRM_Utils_Type::T_INT,
'api.required' => 0,
'description' => E::ts('Twingle ID of the parent TwingleProject'),
];
$spec['parent_id'] = [
'name' => 'parent_id',
'title' => E::ts('Parent Project ID'),
'type' => CRM_Utils_Type::T_INT,
'api.required' => 0,
'description' => E::ts('ID of the parent TwingleProject'),
];
}
/**
@ -59,17 +52,7 @@ function civicrm_api3_twingle_campaign_Sync(array $params): array {
$returnValues = [];
$errors_occurred = 0;
// Abort if TwingleProject does not have TingleCampaign children
if ($campaigns['count'] == 0) {
return civicrm_api3_create_success(
$returnValues,
$params,
'TwingleCampaign',
'Sync'
);
}
if ($campaigns['is_error'] == 0) {
if ($campaigns['is_error'] == 0 && $campaigns['count'] > 0) {
// Instantiate and re-create TwingleCampaigns
foreach ($campaigns['values'] as $campaign) {
@ -113,7 +96,8 @@ function civicrm_api3_twingle_campaign_Sync(array $params): array {
}
else {
return civicrm_api3_create_error(
'Could not get TwingleCampaigns: ' . $campaigns['error_message'],
'Could not get TwingleCampaigns: ' .
$campaigns['error_message'],
$params
);
}

View file

@ -0,0 +1,45 @@
<?php
use CRM_TwingleCampaign_ExtensionUtil as E;
/**
* TwingleEvent.Create API specification (optional)
* This is used for documentation and validation.
*
* @param array $spec description of fields supported by this API call
*
* @see https://docs.civicrm.org/dev/en/latest/framework/api-architecture/
*/
function _civicrm_api3_twingle_event_Create_spec(&$spec) {
$spec['magicword']['api.required'] = 1;
}
/**
* TwingleEvent.Create API
*
* @param array $params
*
* @return array
* API result descriptor
*
* @see civicrm_api3_create_success
*
* @throws API_Exception
*/
function civicrm_api3_twingle_event_Create($params) {
if (array_key_exists('magicword', $params) && $params['magicword'] == 'sesame') {
$returnValues = array(
// OK, return several data rows
12 => ['id' => 12, 'name' => 'Twelve'],
34 => ['id' => 34, 'name' => 'Thirty four'],
56 => ['id' => 56, 'name' => 'Fifty six'],
);
// ALTERNATIVE: $returnValues = []; // OK, success
// ALTERNATIVE: $returnValues = ["Some value"]; // OK, return a single value
// Spec: civicrm_api3_create_success($values = 1, $params = [], $entity = NULL, $action = NULL)
return civicrm_api3_create_success($returnValues, $params, 'TwingleEvent', 'Create');
}
else {
throw new API_Exception(/*error_message*/ 'Everyone knows that the magicword is "sesame"', /*error_code*/ 'magicword_incorrect');
}
}

View file

@ -41,13 +41,6 @@ function _civicrm_api3_twingle_event_Sync_spec(array &$spec) {
'api.required' => 0,
'description' => E::ts('If this is set true, no database change will be made'),
];
$spec['pull'] = [
'name' => 'pull',
'title' => E::ts('Pull'),
'type' => CRM_Utils_Type::T_BOOLEAN,
'api.required' => 0,
'description' => E::ts('If this is set true, the event(s) will be pulled from Twingle and updated locally'),
];
$spec['twingle_api_key'] = [
'name' => 'twingle_api_key',
'title' => E::ts('Twingle API key'),
@ -118,10 +111,6 @@ function civicrm_api3_twingle_event_Sync(array $params): array {
Civi::cache('long')->set('twinglecampaign_twingle_api', $twingleApi);
}
// Set pull flag
$pull = (isset($params['pull']) && $params['pull']);
unset($params['pull']);
// If an id or a event_id is provided, synchronize only this one campaign
if (isset($params['id']) || isset($params['event_id'])) {
@ -152,13 +141,7 @@ function civicrm_api3_twingle_event_Sync(array $params): array {
}
// Synchronize events
if (!empty($event_from_twingle)) {
return _eventSync(
$event,
$event_from_twingle,
$twingleApi,
$params,
$pull
);
return _eventSync($event, $event_from_twingle, $twingleApi, $params);
}
// If Twingle does not know an event with the given event_id, give error
@ -288,13 +271,7 @@ function civicrm_api3_twingle_event_Sync(array $params): array {
$event = _instantiateEvent($event_from_civicrm, $event_from_civicrm['id']);
// sync event
$result = _eventSync(
$event,
$event_from_twingle,
$twingleApi,
$params,
$pull
);
$result = _eventSync($event, $event_from_twingle, $twingleApi, $params);
if ($result['is_error'] != 0) {
$errors_occurred++;
$result_values[$event->getId()] =
@ -417,7 +394,6 @@ function _updateEventLocally(array $event_from_twingle,
* @param array $event_from_twingle
* @param \CRM_TwingleCampaign_BAO_TwingleApiCall $twingleApi
* @param array $params
* @param bool $pull Force pulling event from Twingle and update local campaign
*
* @return array
* @throws \CiviCRM_API3_Exception
@ -425,13 +401,12 @@ function _updateEventLocally(array $event_from_twingle,
function _eventSync(TwingleEvent $event,
array $event_from_twingle,
TwingleApiCall $twingleApi,
array $params,
bool $pull = FALSE): array {
array $params): array {
// If Twingle's timestamp of the event differs from the timestamp of the
// CiviCRM TwingleEvent campaign, update the campaign on CiviCRM's side.
// NOTE: Changes on TwingleEvents are not meant to get pushed to Twingle
if ($event_from_twingle['updated_at'] != $event->lastUpdate() || $pull) {
if ($event_from_twingle['updated_at'] != $event->lastUpdate()) {
return _updateEventLocally($event_from_twingle, $event, $params, $twingleApi);
}

View file

@ -2,7 +2,6 @@
use CRM_TwingleCampaign_ExtensionUtil as E;
use CRM_TwingleCampaign_Utils_ExtensionCache as Cache;
use CRM_TwingleCampaign_Utils_MatomoSnippet as MatomoSnippet;
/**
* TwingleForm.Get API specification (optional)
@ -15,13 +14,6 @@ use CRM_TwingleCampaign_Utils_MatomoSnippet as MatomoSnippet;
function _civicrm_api3_twingle_form_Get_spec(array &$spec) {
$spec['id'] = [
'name' => 'id',
'title' => E::ts('Campaign ID'),
'type' => CRM_Utils_Type::T_INT,
'api.required' => 0,
'description' => E::ts('The campaign ID'),
];
$spec['twingle_project_id'] = [
'name' => 'twingle_project_id',
'title' => E::ts('TwingleProject ID'),
'type' => CRM_Utils_Type::T_INT,
'api.required' => 0,
@ -74,13 +66,6 @@ function civicrm_api3_twingle_form_Get(array $params): array {
// Get custom fields
$custom_field_mapping = Cache::getInstance()->getCustomFieldMapping();
// Replace twingle_project_id key with custom field name
if (key_exists('twingle_project_id', $params)) {
$params[$custom_field_mapping['twingle_project_id']] =
$params['twingle_project_id'];
unset($params['twingle_project_id']);
}
// Replace twingle_project_type key with custom field name
if (key_exists('twingle_project_type', $params)) {
$params[$custom_field_mapping['twingle_project_type']] =
@ -111,49 +96,16 @@ function civicrm_api3_twingle_form_Get(array $params): array {
'project_type' => $value[$custom_field_mapping['twingle_project_type']],
'counter' => $value[$custom_field_mapping['twingle_project_counter']]
];
$matomo_integration_enabled = Civi::settings()->get('twinglecampaign_matomo_integration', False);
switch ($value[$custom_field_mapping['twingle_project_type']]) {
case 'event':
if ($matomo_integration_enabled) {
$returnValues[$value['id']]['embed_code'] =
MatomoSnippet::append_code(
$value[$custom_field_mapping['twingle_project_eventall']],
MatomoSnippet::get_event_tracker()
);
}
else {
$returnValues[$value['id']]['embed_code'] =
$value[$custom_field_mapping['twingle_project_eventall']];
}
break;
case 'shop':
if ($matomo_integration_enabled) {
$returnValues[$value['id']]['embed_code'] =
MatomoSnippet::append_code(
$value[$custom_field_mapping['twingle_project_widget']],
MatomoSnippet::get_ecommerce_tracker()
);
}
else {
$returnValues[$value['id']]['embed_code'] =
$value[$custom_field_mapping['twingle_project_widget']];
}
$returnValues[$value['id']]['embed_code'] =
$value[$custom_field_mapping['twingle_project_eventall']];
break;
default:
if ($matomo_integration_enabled) {
$returnValues[$value['id']]['embed_code'] =
MatomoSnippet::append_code(
$value[$custom_field_mapping['twingle_project_widget']],
MatomoSnippet::get_event_tracker()
);
}
else {
$returnValues[$value['id']]['embed_code'] =
$value[$custom_field_mapping['twingle_project_widget']];
}
$returnValues[$value['id']]['embed_code'] =
$value[$custom_field_mapping['twingle_project_widget']];
}
}
return civicrm_api3_create_success($returnValues, $query, 'TwingleForm', 'Get');
}
else {

View file

@ -12,13 +12,6 @@ use CRM_TwingleCampaign_ExtensionUtil as E;
function _civicrm_api3_twingle_form_Getsingle_spec(array &$spec) {
$spec['id'] = [
'name' => 'id',
'title' => E::ts('Campaign ID'),
'type' => CRM_Utils_Type::T_INT,
'api.required' => 0,
'description' => E::ts('The campaign ID'),
];
$spec['twingle_project_id'] = [
'name' => 'twingle_project_id',
'title' => E::ts('TwingleProject ID'),
'type' => CRM_Utils_Type::T_INT,
'api.required' => 0,

View file

@ -86,7 +86,8 @@ function civicrm_api3_twingle_project_Create(array $params): array {
unset($result['project_id']);
$project = new TwingleProject($result, $params['id']);
unset($params['id']);
$project->merge($params);
$project->update($params);
$project->setEmbedData($params);
}
// If no id is provided, try to create a new project with provided values
else {

View file

@ -35,13 +35,6 @@ function _civicrm_api3_twingle_project_Sync_spec(array &$spec) {
'api.required' => 0,
'description' => E::ts('If this is set true, no database change will be made'),
];
$spec['pull'] = [
'name' => 'pull',
'title' => E::ts('Pull from Twingle'),
'type' => CRM_Utils_Type::T_BOOLEAN,
'api.required' => 0,
'description' => E::ts('If this is set true, the project(s) will be pulled from Twingle and updated locally'),
];
$spec['twingle_api_key'] = [
'name' => 'twingle_api_key',
'title' => E::ts('Twingle API key'),
@ -97,10 +90,6 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
Civi::cache('long')->set('twinglecampaign_twingle_api', $twingleApi);
}
// Set pull flag
$pull = (isset($params['pull']) && $params['pull']);
unset($params['pull']);
// If an id or a project_id is given, synchronize only this one campaign
if (isset($params['id']) || isset($params['project_id'])) {
@ -117,15 +106,9 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
$id = $result['id'];
$project = new TwingleProject($result, $id);
// Synchronize project
// Synchronize projects
if (!empty($project_from_twingle)) {
return _projectSync(
$project,
$project_from_twingle,
$twingleApi,
$params,
$pull
);
return _projectSync($project, $project_from_twingle, $twingleApi, $params);
}
// If Twingle does not know a project with the given project_id, give error
@ -176,7 +159,8 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
$projects_from_twingle = $twingleApi->getProject();
// Get all TwingleProjects from CiviCRM
$projects_from_civicrm = civicrm_api3('TwingleProject', 'get');
$projects_from_civicrm = civicrm_api3('TwingleProject', 'get',
['is_active' => 1,]);
// If call to TwingleProject.get failed, forward error message
if ($projects_from_civicrm['is_error'] != 0) {
@ -191,10 +175,8 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
// Push missing projects to Twingle
$returnValues = [];
foreach ($projects_from_civicrm['values'] as $project_from_civicrm) {
if (
!in_array($project_from_civicrm['project_id'],
array_column($projects_from_twingle, 'id'),
) && $project_from_civicrm['is_active'] == 1) {
if (!in_array($project_from_civicrm['project_id'],
array_column($projects_from_twingle, 'id'))) {
// store campaign id in $id
$id = $project_from_civicrm['id'];
unset($project_from_civicrm['id']);
@ -215,11 +197,8 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
// Create missing projects as campaigns in CiviCRM
foreach ($projects_from_twingle as $project_from_twingle) {
if (
!in_array($project_from_twingle['id'],
array_column($projects_from_civicrm['values'],
'project_id')
)) {
if (!in_array($project_from_twingle['id'],
array_column($projects_from_civicrm['values'], 'project_id'))) {
$project = new TwingleProject($project_from_twingle);
try {
@ -229,16 +208,11 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
$project->getResponse('Ready to create TwingleProject');
}
if ($project->create(TRUE)) {
$returnValues[$project->getId()] =
$project->getResponse('TwingleProject created');
}
else {
$returnValues[$project->getId()] =
$project->getResponse('TwingleProject not selected for synchronization');
}
$project->create(TRUE);
$returnValues[$project->getId()] =
$project->getResponse('TwingleProject created');
} catch (Exception $e) {
$errors[$project_from_twingle['id']] = $e->getMessage();
$errors[$result['id']] = $result['error_message'];
Civi::log()->error(
E::LONG_NAME .
' could not create TwingleProject: ' .
@ -267,12 +241,10 @@ function civicrm_api3_twingle_project_Sync(array $params): array {
// sync project
$result = _projectSync(
$project,
$project_from_twingle,
$twingleApi,
$params,
$pull
);
$project,
$project_from_twingle,
$twingleApi,
$params);
if (!$result['is_error'] == 0) {
$errors[$result['id']] = $result['error_message'];
$returnValues[$project->getId()] =
@ -485,7 +457,6 @@ function _pushProjectToTwingle(TwingleProject $project,
* @param array $project_from_twingle
* @param \CRM_TwingleCampaign_BAO_TwingleApiCall $twingleApi
* @param array $params
* @param bool $pull Force pulling project from Twingle and update local campaign
*
* @return array
* @throws \CiviCRM_API3_Exception
@ -493,13 +464,11 @@ function _pushProjectToTwingle(TwingleProject $project,
function _projectSync(TwingleProject $project,
array $project_from_twingle,
TwingleApiCall $twingleApi,
array $params,
bool $pull = FALSE): array {
array $params): array {
// If Twingle's version of the project is newer than the CiviCRM
// TwingleProject campaign, update the campaign
if ($project_from_twingle['last_update'] > $project->lastUpdate() ||
$pull) {
if ($project_from_twingle['last_update'] > $project->lastUpdate()) {
return _updateProjectLocally($project_from_twingle, $project, $params, $twingleApi);
}

View file

@ -14,12 +14,13 @@
<url desc="Support">https://lab.civicrm.org/Marc_Michalsky/de-forumzfd-twinglecampaign/-/issues</url>
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2024-06-15</releaseDate>
<version>1.0.8</version>
<develStage>stable</develStage>
<releaseDate>2020-09-25</releaseDate>
<version>1.0</version>
<develStage>alpha</develStage>
<compatibility>
<ver>5.74</ver>
<ver>5.14.0</ver>
</compatibility>
<comments>This is a new, undeveloped module</comments>
<requires>
<ext>de.systopia.xcm</ext>
<ext>de.systopia.campaign</ext>

Binary file not shown.

Binary file not shown.

View file

@ -3,21 +3,21 @@ msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.0\n"
"X-Generator: Poedit 2.4.2\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: de_DE\n"
#: CRM/TwingleCampaign/BAO/CustomField.php
msgid ""
"%1: Creation of custom field '%2' failed. Find more information in the logs."
"Creation of custom field '%1' failed. Find more information in the logs."
msgstr ""
"%1: Erstellen des benutzerdefinierten Feldes '%2' fehlgeschlagen. Mehr "
"Informationen in den Logs."
"Erstellung von Custom Field '%1' fehlgeschlagen. Mehr Informationen in den "
"Logs."
#: CRM/TwingleCampaign/BAO/CustomField.php
msgid "Creation of custom field failed. Find more information in the logs."
@ -33,29 +33,6 @@ msgstr ""
"Erstellung der Custom Field '%1' fehlgeschlagen, weil bereits eine Custom "
"Field mit selbem Namen existiert. Mehr Informationen in den Logs."
#: CRM/TwingleCampaign/BAO/CustomField.php
msgid ""
"Creation of custom field '%1' failed. Find more information in the logs."
msgstr ""
"Erstellung von Custom Field '%1' fehlgeschlagen. Mehr Informationen in den "
"Logs."
#: CRM/TwingleCampaign/BAO/CustomField.php
msgid ""
"%1 could not get option group id for custom field '%2'. Find more "
"information in the logs."
msgstr ""
"%1 konnte die Option-Group-ID für das benutzerdefinierte Feld '%2' nicht "
"finden. Mehr Informationen in den Logs."
#: CRM/TwingleCampaign/BAO/CustomField.php
msgid ""
"%1 could not create additional option values for custom field '%2'. Find "
"more information in the logs."
msgstr ""
"%1 konnte dem benutzerdefinierte Feld '%2' keine zusätzlichen Optionen "
"hinzufügen. Mehr Informationen in den Logs."
#: CRM/TwingleCampaign/BAO/CustomGroup.php
msgid ""
"Creation of custom group '%1' failed. Find more information in the logs."
@ -143,8 +120,8 @@ msgid "XCM Profile to match event initiators"
msgstr "XCM-Profil zum Abgleichen von Event-Initiatoren"
#: CRM/TwingleCampaign/Form/Settings.php
msgid "Default case to open for event initiators"
msgstr "Standarfdall, der für Event-Initiatoren eröffnet werden soll"
msgid "Start a case for event initiators"
msgstr "Einen Fall für Event-Initiatoren anlegen"
#: CRM/TwingleCampaign/Form/Settings.php
msgid "Create soft credits for event initiators"
@ -158,22 +135,14 @@ msgstr "Speichern"
msgid "TwingleCampaign configuration saved"
msgstr "TwingleCampaign Konfiguration gespeichert"
#: CRM/TwingleCampaign/Form/Settings.php
msgid "none"
msgstr "keine"
#: CRM/TwingleCampaign/Upgrader/Base.php
msgid "Upgrade %1 to revision %2"
msgstr "Upgrade %1 auf Revision %2"
#: CRM/TwingleCampaign/Upgrader.php
msgid ""
"Could not pull campaigns from Twingle to fill the campaign fields that were "
"created within this update: %1"
msgstr ""
"Die zusätzlichen Kampagnenfelder, die in diesem Update erstellt wurden, "
"konnten nicht von Twingle bezogen werden: %1"
#: CRM/TwingleCampaign/Upgrader.php
msgid "Scheduled Job"
msgstr "Geplante Audgabe"
#: CRM/TwingleCampaign/Upgrader.php
msgid ""
"Syncronizes all TwingleProjects an TwingleEvents between CiviCRM and Twingle"
@ -185,6 +154,18 @@ msgstr ""
msgid "Could not create scheduled job \"TwingleSync\"."
msgstr "Geplante Aufgabe \"TwingleSync\" konnte nicht erstellt werden."
#: CRM/TwingleCampaign/Upgrader.php
msgid "Scheduled Job"
msgstr "Geplante Audgabe"
#: CRM/TwingleCampaign/Upgrader.php
msgid ""
"Could not create scheduled job \"TwingleSync\". Your Campaigns will not get "
"synchronized to Twingle."
msgstr ""
"Geplante Aufgabe \"TwingleSync\" konnte nicht erstellt werden. Ihre "
"Kampagnen werden nicht mit Twingle synchronisiert werden."
#: CRM/TwingleCampaign/Upgrader.php
msgid "Could not delete scheduled job \"TwingleSync\"."
msgstr "Geplante Aufgabe \"TwingleSync\" konnte nicht gelöscht werden."
@ -201,10 +182,6 @@ msgstr ""
msgid "Could not disable scheduled job \"TwingleSync\"."
msgstr "Geplante Aufgabe \"TwingleSync\" konnte nicht deaktiviert werden."
#: CRM/TwingleCampaign/Utils/CaseTypes.php
msgid "none"
msgstr "keine"
#: CRM/TwingleCampaign/resources/campaigns.php
msgid "Twingle Information"
msgstr "Twingle Informationen"
@ -273,14 +250,6 @@ msgstr ""
"Wähle den Projekt-Typ: erlaube Benutzern ihre eigenen Spenden-Events "
"anzulegen oder eine Mitgliedschaft zu bezahlen."
#: CRM/TwingleCampaign/resources/campaigns.php
msgid "Case"
msgstr "Fall"
#: CRM/TwingleCampaign/resources/campaigns.php
msgid "Which case should get opened for event creators?"
msgstr "Welcher Fall soll für Event-Initiatoren eröffnet werden?"
#: CRM/TwingleCampaign/resources/campaigns.php
msgid "allow more"
msgstr "Mehr zulassen"
@ -907,17 +876,6 @@ msgstr "Elternkampagne"
msgid "Optional parent id for this Campaign"
msgstr "Optionale Eltern-ID für diese Kampagne"
#: api/v3/TwingleCampaign/Create.php
msgid "Clone"
msgstr "Klonen"
#: api/v3/TwingleCampaign/Create.php
msgid ""
"Set this value to true if this campaign is about to be cloned to recreate cid"
msgstr ""
"Setze diesen Wert auf true, wenn diese Kampagne gerade geklont wird, damit "
"die cid neu berechnet wird"
#: api/v3/TwingleCampaign/Get.php api/v3/TwingleCampaign/Getsingle.php
msgid "Twingle Campaign CID"
msgstr "Twingle Campaign CID"
@ -934,14 +892,6 @@ msgstr "Eltern Twingle Project ID"
msgid "Twingle ID of the parent TwingleProject"
msgstr "Twingle ID des Eltern-TwingleProject"
#: api/v3/TwingleCampaign/Get.php api/v3/TwingleCampaign/Sync.php
msgid "Parent Project ID"
msgstr "Eltern-Projekt-ID"
#: api/v3/TwingleCampaign/Get.php api/v3/TwingleCampaign/Sync.php
msgid "ID of the parent TwingleProject"
msgstr "ID des Eltern-TWinglePRoject"
#: api/v3/TwingleCampaign/Get.php api/v3/TwingleCampaign/Getsingle.php
#: api/v3/TwingleEvent/Get.php api/v3/TwingleEvent/Getsingle.php
#: api/v3/TwingleProject/Get.php api/v3/TwingleProject/Getsingle.php
@ -1071,18 +1021,6 @@ msgstr "Bestätigt am"
msgid "When the Event was confirmed by its initiator"
msgstr "Wenn das Event vom Initiator bestätigt wurrde"
#: api/v3/TwingleEvent/Sync.php
msgid "Pull"
msgstr "Ziehen"
#: api/v3/TwingleEvent/Sync.php
msgid ""
"If this is set true, the event(s) will be pulled from Twingle and updated "
"locally"
msgstr ""
"Wenn dies auf wahr gesetzt ist, werden die Events von Twingle gezogen und "
"lokal geupdated."
#: api/v3/TwingleEvent/Sync.php api/v3/TwingleSync/Sync.php
msgid "Limit"
msgstr "Limit"
@ -1184,18 +1122,6 @@ msgstr "Twingle Organisations ID"
msgid "Your Twingle Organisation ID"
msgstr "Ihre Twingle Organisations ID"
#: api/v3/TwingleProject/Sync.php
msgid "Pull from Twingle"
msgstr "Von Twingle ziehen"
#: api/v3/TwingleProject/Sync.php
msgid ""
"If this is set true, the project(s) will be pulled from Twingle and updated "
"locally"
msgstr ""
"Wenn dies auf wahr gesetzt ist, werden die Projekte von Twingle gezogen und "
"lokal geupdated."
#: templates/CRM/TwingleCampaign/Form/Settings.tpl
msgid "General Settings"
msgstr "Allgemeine Einstellungen"
@ -1208,10 +1134,6 @@ msgstr "Twingle Event Einstellungen"
msgid "Campaign cloning failed"
msgstr "Klonen der Kampagne fehlgeschlagen"
#: twinglecampaign.php
msgid "TwingleCampaign was cloned."
msgstr "TwingleCampaign wurde geklont"
#: twinglecampaign.php
msgid "TwingleCampaign update failed"
msgstr "TwingleCampaign-Update fehlgeschlagen"

View file

@ -1,5 +1,5 @@
#: ./CRM/TwingleCampaign/BAO/CustomField.php
msgid "%1: Creation of custom field '%2' failed. Find more information in the logs."
msgid "Creation of custom field '%1' failed. Find more information in the logs."
msgstr ""
#: ./CRM/TwingleCampaign/BAO/CustomField.php
@ -10,18 +10,6 @@ msgstr ""
msgid "Creation of custom field '%1' failed, because a custom field with that name already exists. Find more information in the logs."
msgstr ""
#: ./CRM/TwingleCampaign/BAO/CustomField.php
msgid "Creation of custom field '%1' failed. Find more information in the logs."
msgstr ""
#: ./CRM/TwingleCampaign/BAO/CustomField.php
msgid "%1 could not get option group id for custom field '%2'. Find more information in the logs."
msgstr ""
#: ./CRM/TwingleCampaign/BAO/CustomField.php
msgid "%1 could not create additional option values for custom field '%2'. Find more information in the logs."
msgstr ""
#: ./CRM/TwingleCampaign/BAO/CustomGroup.php
msgid "Creation of custom group '%1' failed. Find more information in the logs."
msgstr ""
@ -87,7 +75,7 @@ msgid "XCM Profile to match event initiators"
msgstr ""
#: ./CRM/TwingleCampaign/Form/Settings.php
msgid "Default case to open for event initiators"
msgid "Start a case for event initiators"
msgstr ""
#: ./CRM/TwingleCampaign/Form/Settings.php
@ -102,18 +90,14 @@ msgstr ""
msgid "TwingleCampaign configuration saved"
msgstr ""
#: ./CRM/TwingleCampaign/Form/Settings.php
msgid "none"
msgstr ""
#: ./CRM/TwingleCampaign/Upgrader/Base.php
msgid "Upgrade %1 to revision %2"
msgstr ""
#: ./CRM/TwingleCampaign/Upgrader.php
msgid "Could not pull campaigns from Twingle to fill the campaign fields that were created within this update: %1"
msgstr ""
#: ./CRM/TwingleCampaign/Upgrader.php
msgid "Scheduled Job"
msgstr ""
#: ./CRM/TwingleCampaign/Upgrader.php
msgid "Syncronizes all TwingleProjects an TwingleEvents between CiviCRM and Twingle"
msgstr ""
@ -122,6 +106,14 @@ msgstr ""
msgid "Could not create scheduled job \"TwingleSync\"."
msgstr ""
#: ./CRM/TwingleCampaign/Upgrader.php
msgid "Scheduled Job"
msgstr ""
#: ./CRM/TwingleCampaign/Upgrader.php
msgid "Could not create scheduled job \"TwingleSync\". Your Campaigns will not get synchronized to Twingle."
msgstr ""
#: ./CRM/TwingleCampaign/Upgrader.php
msgid "Could not delete scheduled job \"TwingleSync\"."
msgstr ""
@ -134,10 +126,6 @@ msgstr ""
msgid "Could not disable scheduled job \"TwingleSync\"."
msgstr ""
#: ./CRM/TwingleCampaign/Utils/CaseTypes.php
msgid "none"
msgstr ""
#: ./CRM/TwingleCampaign/resources/campaigns.php
msgid "Twingle Information"
msgstr ""
@ -198,14 +186,6 @@ msgstr ""
msgid "Choose the project type. Allow users to create own events or to pay a membership fee."
msgstr ""
#: ./CRM/TwingleCampaign/resources/campaigns.php
msgid "Case"
msgstr ""
#: ./CRM/TwingleCampaign/resources/campaigns.php
msgid "Which case should get opened for event creators?"
msgstr ""
#: ./CRM/TwingleCampaign/resources/campaigns.php
msgid "allow more"
msgstr ""
@ -806,14 +786,6 @@ msgstr ""
msgid "Optional parent id for this Campaign"
msgstr ""
#: ./api/v3/TwingleCampaign/Create.php
msgid "Clone"
msgstr ""
#: ./api/v3/TwingleCampaign/Create.php
msgid "Set this value to true if this campaign is about to be cloned to recreate cid"
msgstr ""
#: ./api/v3/TwingleCampaign/Get.php ./api/v3/TwingleCampaign/Getsingle.php
msgid "Twingle Campaign CID"
msgstr ""
@ -830,14 +802,6 @@ msgstr ""
msgid "Twingle ID of the parent TwingleProject"
msgstr ""
#: ./api/v3/TwingleCampaign/Get.php ./api/v3/TwingleCampaign/Sync.php
msgid "Parent Project ID"
msgstr ""
#: ./api/v3/TwingleCampaign/Get.php ./api/v3/TwingleCampaign/Sync.php
msgid "ID of the parent TwingleProject"
msgstr ""
#: ./api/v3/TwingleCampaign/Get.php ./api/v3/TwingleCampaign/Getsingle.php ./api/v3/TwingleEvent/Get.php ./api/v3/TwingleEvent/Getsingle.php ./api/v3/TwingleProject/Get.php ./api/v3/TwingleProject/Getsingle.php
msgid "Campaign Name"
msgstr ""
@ -926,14 +890,6 @@ msgstr ""
msgid "When the Event was confirmed by its initiator"
msgstr ""
#: ./api/v3/TwingleEvent/Sync.php
msgid "Pull"
msgstr ""
#: ./api/v3/TwingleEvent/Sync.php
msgid "If this is set true, the event(s) will be pulled from Twingle and updated locally"
msgstr ""
#: ./api/v3/TwingleEvent/Sync.php ./api/v3/TwingleSync/Sync.php
msgid "Limit"
msgstr ""
@ -1026,14 +982,6 @@ msgstr ""
msgid "Your Twingle Organisation ID"
msgstr ""
#: ./api/v3/TwingleProject/Sync.php
msgid "Pull from Twingle"
msgstr ""
#: ./api/v3/TwingleProject/Sync.php
msgid "If this is set true, the project(s) will be pulled from Twingle and updated locally"
msgstr ""
#: ./templates/CRM/TwingleCampaign/Form/Settings.tpl
msgid "General Settings"
msgstr ""
@ -1046,10 +994,6 @@ msgstr ""
msgid "Campaign cloning failed"
msgstr ""
#: ./twinglecampaign.php
msgid "TwingleCampaign was cloned."
msgstr ""
#: ./twinglecampaign.php
msgid "TwingleCampaign update failed"
msgstr ""

View file

@ -17,8 +17,8 @@
<div class="clear"></div>
</div>
<div class="crm-section">
<div class="label">{$form.twinglecampaign_default_case.label}</div>
<div class="content">{$form.twinglecampaign_default_case.html}</div>
<div class="label">{$form.twinglecampaign_start_case.label}</div>
<div class="content">{$form.twinglecampaign_start_case.html}</div>
<div class="clear"></div>
</div>
<div class="crm-section">
@ -26,11 +26,6 @@
<div class="content">{$form.twinglecampaign_soft_credits.html}</div>
<div class="clear"></div>
</div>
<div class="crm-section">
<div class="label">{$form.twinglecampaign_matomo_integration.label}</div>
<div class="content">{$form.twinglecampaign_matomo_integration.html}</div>
<div class="clear"></div>
</div>
</div>

View file

@ -7,9 +7,9 @@
* extension.
*/
class CRM_TwingleCampaign_ExtensionUtil {
const SHORT_NAME = 'twinglecampaign';
const LONG_NAME = 'de.forumzfd.twinglecampaign';
const CLASS_PREFIX = 'CRM_TwingleCampaign';
const SHORT_NAME = "twinglecampaign";
const LONG_NAME = "de.forumzfd.twinglecampaign";
const CLASS_PREFIX = "CRM_TwingleCampaign";
/**
* Translate a string using the extension's domain.
@ -193,9 +193,8 @@ function _twinglecampaign_civix_civicrm_disable() {
* @param $op string, the type of operation being performed; 'check' or 'enqueue'
* @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks
*
* @return mixed
* based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending)
* for 'enqueue', returns void
* @return mixed based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending)
* for 'enqueue', returns void
*
* @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade
*/
@ -221,18 +220,41 @@ function _twinglecampaign_civix_upgrader() {
* Search directory tree for files which match a glob pattern.
*
* Note: Dot-directories (like "..", ".git", or ".svn") will be ignored.
* Note: Delegate to CRM_Utils_File::findFiles(), this function kept only
* for backward compatibility of extension code that uses it.
* Note: In Civi 4.3+, delegate to CRM_Utils_File::findFiles()
*
* @param string $dir base dir
* @param string $pattern , glob pattern, eg "*.txt"
*
* @return array
* @return array(string)
*/
function _twinglecampaign_civix_find_files($dir, $pattern) {
return CRM_Utils_File::findFiles($dir, $pattern);
}
if (is_callable(['CRM_Utils_File', 'findFiles'])) {
return CRM_Utils_File::findFiles($dir, $pattern);
}
$todos = [$dir];
$result = [];
while (!empty($todos)) {
$subdir = array_shift($todos);
foreach (_twinglecampaign_civix_glob("$subdir/$pattern") as $match) {
if (!is_dir($match)) {
$result[] = $match;
}
}
if ($dh = opendir($subdir)) {
while (FALSE !== ($entry = readdir($dh))) {
$path = $subdir . DIRECTORY_SEPARATOR . $entry;
if ($entry{0} == '.') {
}
elseif (is_dir($path)) {
$todos[] = $path;
}
}
closedir($dh);
}
}
return $result;
}
/**
* (Delegated) Implements hook_civicrm_managed().
*
@ -340,7 +362,7 @@ function _twinglecampaign_civix_civicrm_themes(&$themes) {
* @link http://php.net/glob
* @param string $pattern
*
* @return array
* @return array, possibly empty
*/
function _twinglecampaign_civix_glob($pattern) {
$result = glob($pattern);
@ -448,6 +470,8 @@ function _twinglecampaign_civix_civicrm_alterSettingsFolders(&$metaDataFolders =
*
* @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes
*/
function _twinglecampaign_civix_civicrm_entityTypes(&$entityTypes) {
$entityTypes = array_merge($entityTypes, []);
$entityTypes = array_merge($entityTypes, array (
));
}

View file

@ -4,7 +4,6 @@ use CRM_TwingleCampaign_Utils_ExtensionCache as ExtensionCache;
use CRM_TwingleCampaign_BAO_TwingleProject as TwingleProject;
use CRM_TwingleCampaign_BAO_TwingleApiCall as TwingleApiCall;
use CRM_TwingleCampaign_ExtensionUtil as E;
use CRM_TwingleCampaign_BAO_CustomField as CustomField;
require_once 'twinglecampaign.civix.php';
@ -47,14 +46,6 @@ function twinglecampaign_civicrm_config(&$config) {
}
}
function twinglecampaign_civicrm_postSave_civicrm_case_type() {
$twingle_project_case_custom_field =
CustomField::fetch('twingle_project_case');
$newCaseType = json_decode($_POST['json'], True);
$twingle_project_case_custom_field->addOptions(
[$newCaseType['name'] => $newCaseType['title']]
);
}
/**
* Implements hook_civicrm_postSave_Campaign().
@ -68,47 +59,16 @@ function twinglecampaign_civicrm_postSave_civicrm_case_type() {
*/
function twinglecampaign_civicrm_postSave_civicrm_campaign($dao) {
$twingle_project_campaign_type_id = _get_campaign_type_id_twingle_project();
$twingle_campaign_campaign_type_id = _get_campaign_type_id_twingle_campaign();
if (empty($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']) ||
$_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] != TRUE) {
// If $campaign_type_id is a TwingleProject or TwingleCampaign campaign,
// synchronize it
if (
$dao->campaign_type_id == $twingle_project_campaign_type_id ||
$dao->campaign_type_id == $twingle_campaign_campaign_type_id
) {
if (empty($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']) ||
$_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] != TRUE) {
// If the db transaction is still running, add a function to it that will
// be called afterwards
if (CRM_Core_Transaction::isActive()) {
// If request is not an API-Call
if (
((isset($_GET['action']) && $_GET['action'] != 'create') ||
(isset($_POST['action']) && $_POST['action'] != 'create')) ||
(!isset($_GET['action']) && !isset($_POST['action']))
) {
if (_validateAndSendInput($dao->id, $dao->campaign_type_id)) {
// If the db transaction is still running, add a function to it that will
// be called afterwards
if (CRM_Core_Transaction::isActive()) {
if (_validateAndSendInput($dao->id, $dao->campaign_type_id)) {
CRM_Core_Transaction::addCallback(
CRM_Core_Transaction::PHASE_POST_COMMIT,
'twinglecampaign_postSave_campaign_update_callback',
[$dao->id, $dao->campaign_type_id]
);
}
}
// If the transaction is already finished, call the function directly
else {
twinglecampaign_postSave_campaign_update_callback($dao->id, $dao->campaign_type_id);
}
}
else {
CRM_Core_Transaction::addCallback(
CRM_Core_Transaction::PHASE_POST_COMMIT,
'twinglecampaign_postSave_campaign_update_callback',
@ -116,6 +76,12 @@ function twinglecampaign_civicrm_postSave_civicrm_campaign($dao) {
);
}
}
// If the transaction is already finished, call the function directly
else {
twinglecampaign_postSave_campaign_update_callback($dao->id, $dao->campaign_type_id);
}
}
// Remove no hook flag
unset($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']);
@ -139,58 +105,73 @@ function twinglecampaign_postSave_campaign_update_callback(
$twingle_project_campaign_type_id = _get_campaign_type_id_twingle_project();
$twingle_campaign_campaign_type_id = _get_campaign_type_id_twingle_campaign();
// Set $entity for $campaign_type_id
if ($campaign_type_id == $twingle_project_campaign_type_id) {
$entity = 'TwingleProject';
}
elseif ($campaign_type_id == $twingle_campaign_campaign_type_id) {
$entity = 'TwingleCampaign';
}
else {
Civi::log()->error(
E::SHORT_NAME .
" Update of TwingleCampaigns failed: Unknown campaign type (id: $campaign_type_id)"
);
CRM_Core_Session::setStatus(
E::ts('Unknown campaign type'),
E::ts('Campaign type id: %1', [1 => $campaign_type_id]),
error,
[unique => TRUE]
);
return;
}
// If $campaign_type_id is a TwingleProject or TwingleCampaign campaign,
// synchronize it
if (
$campaign_type_id == $twingle_project_campaign_type_id ||
$campaign_type_id == $twingle_campaign_campaign_type_id
) {
if (isset($_POST['action'])) {
if ($_POST['action'] == 'clone' && $entity == 'TwingleProject') {
unset($_POST['action']);
$result = civicrm_api3('TwingleProject', 'getsingle',
['id' => $campaign_id]
);
$id = $result['id'];
unset($result['id']);
$project = new TwingleProject($result, $id);
try {
$project->clone();
} catch (Exception $e) {
Civi::log()->error(
E::LONG_NAME .
' could not clone ' . $entity . ': ' . $e->getMessage()
// Set $entity for $campaign_type_id
if ($campaign_type_id == $twingle_project_campaign_type_id) {
$entity = 'TwingleProject';
}
else {
$entity = 'TwingleCampaign';
}
if (isset($_POST['action'])) {
if ($_POST['action'] == 'clone' && $entity == 'TwingleProject') {
unset($_POST['action']);
$result = civicrm_api3('TwingleProject', 'getsingle',
['id' => $campaign_id]
);
$id = $result['id'];
unset($result['id']);
$project = new TwingleProject($result, $id);
try {
$project->clone();
} catch (Exception $e) {
Civi::log()->error(
E::LONG_NAME .
' could not clone ' . $entity . ': ' . $e->getMessage()
);
CRM_Core_Session::setStatus(
$e->getMessage(),
E::ts("Campaign cloning failed"),
error,
[unique => TRUE]
);
}
}
}
// If a TwingleProject is getting saved
elseif ($entity == 'TwingleProject') {
// Synchronize all child TwingleCampaign campaigns
try {
civicrm_api3(
'TwingleCampaign',
'sync',
['parent_id' => $campaign_id]);
} catch (CiviCRM_API3_Exception $e) {
CRM_Core_Session::setStatus(
$e->getMessage(),
E::ts("Campaign cloning failed"),
error,
[unique => TRUE]
E::ts("TwingleCampaign update failed"),
error, [unique => TRUE]
);
Civi::log()->error(
E::SHORT_NAME .
' Update of TwingleCampaigns failed: ' . $e->getMessage()
);
}
}
if ($_POST['action'] == 'clone' && $entity == 'TwingleCampaign') {
unset($_POST['action']);
else {
try {
civicrm_api3('TwingleCampaign', 'create',
['id' => $campaign_id, 'clone' => true]
);
CRM_Utils_System::setUFMessage(E::ts('TwingleCampaign was cloned.'));
['id' => $campaign_id, 'parent_id' => $_POST['parent_id']]);
CRM_Utils_System::setUFMessage(E::ts('TwingleCampaign was saved.'));
} catch (CiviCRM_API3_Exception $e) {
Civi::log()->error(
'twinglecampaign_postSave_callback ' . $e->getMessage()
@ -198,39 +179,6 @@ function twinglecampaign_postSave_campaign_update_callback(
}
}
}
// If a TwingleProject is getting saved
elseif ($entity == 'TwingleProject') {
// Synchronize all child TwingleCampaign campaigns
try {
civicrm_api3(
'TwingleCampaign',
'sync',
['parent_id' => $campaign_id]);
} catch (CiviCRM_API3_Exception $e) {
CRM_Core_Session::setStatus(
$e->getMessage(),
E::ts("TwingleCampaign update failed"),
error, [unique => TRUE]
);
Civi::log()->error(
E::SHORT_NAME .
' Update of TwingleCampaigns failed: ' . $e->getMessage()
);
}
}
else {
try {
civicrm_api3('TwingleCampaign', 'create',
['id' => $campaign_id, 'parent_id' => $_POST['parent_id']]);
CRM_Utils_System::setUFMessage(E::ts('TwingleCampaign was saved.'));
} catch (CiviCRM_API3_Exception $e) {
Civi::log()->error(
'twinglecampaign_postSave_callback ' . $e->getMessage()
);
}
}
}
function _get_campaign_type_id_twingle_project() {
@ -245,7 +193,6 @@ function _get_campaign_type_id_twingle_campaign() {
/**
* Callback to sync a project after its creation.
*
* @param int $campaign_id
*/
function twinglecampaign_postSave_project_create_callback(
@ -278,7 +225,6 @@ function twinglecampaign_postSave_project_create_callback(
*
* @return bool
* @throws \CiviCRM_API3_Exception
* @throws \Exception
*/
function _validateAndSendInput($id, $campaign_type_id): bool {
@ -313,11 +259,6 @@ function _validateAndSendInput($id, $campaign_type_id): bool {
// Update project
$project->update($customFields);
// Set name if provided
if (isset($_POST['title'])) {
$project->setName($_POST['title']);
}
// Validate project values
$validation = $project->validate();
@ -411,7 +352,8 @@ function _validateAndSendInput($id, $campaign_type_id): bool {
CRM_Core_Session::setStatus(
$errorMessage,
E::ts("Input validation failed"),
error
error,
[unique => TRUE]
);
// Validation failed
return FALSE;