From cc6777e206913fd97ee8b0a1ad56e7e1a9e6d9a9 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 14:40:04 +0200 Subject: [PATCH 01/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20TwingleCampai?= =?UTF-8?q?gn=20cannot=20find=20parent=20campaign?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 7 ++++--- CRM/TwingleCampaign/BAO/TwingleEvent.php | 2 +- api/v3/TwingleCampaign/Create.php | 2 +- api/v3/TwingleCampaign/Get.php | 13 +++++++++++-- api/v3/TwingleCampaign/Sync.php | 21 +++++++++++++++++++-- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index 58433ed..a643f7b 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -32,7 +32,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { $this->id = $id ?? NULL; $this->values['campaign_type_id'] = 'twingle_campaign'; - if ($this->id) { + if (!isset($this->id)) { $this->update($values); $this->getParentProject(); $this->createCid(); @@ -341,10 +341,11 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { */ private function update(array $values) { - $filter = ExtensionCache::getInstance()->getTemplates()['TwingleCampaign']; + $filter = ExtensionCache::getInstance() + ->getTemplates()['TwingleCampaign']['campaign_data']; foreach ($values as $key => $value) { if (in_array($key, $filter)) { - $this->values[$key] = $values[$key]; + $this->values[$key] = $value; } } } diff --git a/CRM/TwingleCampaign/BAO/TwingleEvent.php b/CRM/TwingleCampaign/BAO/TwingleEvent.php index 19de97b..a5fc418 100644 --- a/CRM/TwingleCampaign/BAO/TwingleEvent.php +++ b/CRM/TwingleCampaign/BAO/TwingleEvent.php @@ -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) { diff --git a/api/v3/TwingleCampaign/Create.php b/api/v3/TwingleCampaign/Create.php index 6033871..dbb1df6 100644 --- a/api/v3/TwingleCampaign/Create.php +++ b/api/v3/TwingleCampaign/Create.php @@ -62,7 +62,7 @@ function civicrm_api3_twingle_campaign_Create(array $params): array { $params = array_intersect_key($params, $allowed_params); // instantiate TwingleCampaign - $campaign = new TwingleCampaign($params, $params['id']); + $campaign = new TwingleCampaign($params); // Try to create the TwingleCampaign try { diff --git a/api/v3/TwingleCampaign/Get.php b/api/v3/TwingleCampaign/Get.php index b0670e1..f7de8cc 100644 --- a/api/v3/TwingleCampaign/Get.php +++ b/api/v3/TwingleCampaign/Get.php @@ -33,6 +33,13 @@ 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'), @@ -122,6 +129,8 @@ 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; @@ -157,7 +166,7 @@ function civicrm_api3_twingle_campaign_Get(array $params): array { } // Translate custom fields - if (!empty($campaigns)) { + if (!empty($campaigns['values'])) { $custom_field_mapping_reverse = array_flip(Cache::getInstance()->getCustomFieldMapping()); @@ -171,7 +180,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; diff --git a/api/v3/TwingleCampaign/Sync.php b/api/v3/TwingleCampaign/Sync.php index 4ba8332..c7256cb 100644 --- a/api/v3/TwingleCampaign/Sync.php +++ b/api/v3/TwingleCampaign/Sync.php @@ -20,12 +20,19 @@ function _civicrm_api3_twingle_campaign_Sync_spec(array &$spec) { 'description' => E::ts('The Twingle Campaign ID'), ]; $spec['project_id'] = [ - 'name' => 'project_id', + 'name' => 'parent_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'), + ]; } /** @@ -52,7 +59,17 @@ function civicrm_api3_twingle_campaign_Sync(array $params): array { $returnValues = []; $errors_occurred = 0; - if ($campaigns['is_error'] == 0 && $campaigns['count'] > 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) { // Instantiate and re-create TwingleCampaigns foreach ($campaigns['values'] as $campaign) { From 794a68c7815c3318e6d1139ad1185c66f214f1d2 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 13:18:24 +0200 Subject: [PATCH 02/52] =?UTF-8?q?=F0=9F=94=A7=20use=20uniqid()=20instead?= =?UTF-8?q?=20of=20md5()=20to=20generate=20the=20cid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index a643f7b..cc0d77e 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -212,7 +212,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { */ private function createCid() { - $this->values['cid'] = md5($this->id . '_' . $this->values['name']); + $this->values['cid'] = uniqid(); } From 938371c8c538f2842431f8e5048614b3f422f065 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 13:18:58 +0200 Subject: [PATCH 03/52] =?UTF-8?q?=F0=9F=A7=B9=20code=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleEvent.php | 1 + api/v3/TwingleCampaign/Get.php | 6 +++--- api/v3/TwingleCampaign/Sync.php | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleEvent.php b/CRM/TwingleCampaign/BAO/TwingleEvent.php index a5fc418..fd7eddd 100644 --- a/CRM/TwingleCampaign/BAO/TwingleEvent.php +++ b/CRM/TwingleCampaign/BAO/TwingleEvent.php @@ -35,6 +35,7 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { throw new Exception("Could not identify parent Campaign: $errorMessage"); } } + } diff --git a/api/v3/TwingleCampaign/Get.php b/api/v3/TwingleCampaign/Get.php index f7de8cc..36c6df2 100644 --- a/api/v3/TwingleCampaign/Get.php +++ b/api/v3/TwingleCampaign/Get.php @@ -107,6 +107,9 @@ 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 @@ -135,9 +138,6 @@ function civicrm_api3_twingle_campaign_Get(array $params): array { // 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', diff --git a/api/v3/TwingleCampaign/Sync.php b/api/v3/TwingleCampaign/Sync.php index c7256cb..240c896 100644 --- a/api/v3/TwingleCampaign/Sync.php +++ b/api/v3/TwingleCampaign/Sync.php @@ -113,8 +113,7 @@ 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 ); } From 15b496de1c962b465145a3aafb178d5de9cbeb07 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 13:30:18 +0200 Subject: [PATCH 04/52] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20avoid=20"missing=20i?= =?UTF-8?q?ndex"=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleProject.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index b92313e..f47df4f 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -562,13 +562,17 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { } // Change DateTime string into timestamp - $values['last_update'] = - self::getTimestamp($values['last_update']); + if (isset($values['last_update'])) { + $values['last_update'] = + self::getTimestamp($values['last_update']); + } // Default project_type to '' - $values['type'] = $values['type'] == 'default' - ? '' - : $values['type']; + if (isset($values['type'])) { + $values['type'] = $values['type'] == 'default' + ? '' + : $values['type']; + } // Cast project target to integer if (isset($values['project_target'])) { From ef74a52e9f316891cd4971dd28e2ddd8aa7754e0 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Thu, 15 Apr 2021 20:06:14 +0200 Subject: [PATCH 05/52] =?UTF-8?q?=F0=9F=94=A5=20remove=20TwingleEvent.crea?= =?UTF-8?q?te=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TwingleEvents are created only by event initiators via the embedded form --- api/v3/TwingleEvent/Create.php | 45 ---------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 api/v3/TwingleEvent/Create.php diff --git a/api/v3/TwingleEvent/Create.php b/api/v3/TwingleEvent/Create.php deleted file mode 100644 index 0ae5390..0000000 --- a/api/v3/TwingleEvent/Create.php +++ /dev/null @@ -1,45 +0,0 @@ - ['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'); - } -} From c22911e8860730d0ff2ccdec8ff66ed045799dfd Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Thu, 15 Apr 2021 20:07:48 +0200 Subject: [PATCH 06/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20cannot=20set?= =?UTF-8?q?=20TwingleProject=20url=20via=20TwingleForm.create=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/Campaign.php | 25 +++++++++++++- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 28 ++++++++++------ api/v3/TwingleProject/Create.php | 3 +- twinglecampaign.php | 36 +++++++++++++-------- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/Campaign.php b/CRM/TwingleCampaign/BAO/Campaign.php index 86b0bdc..b22666e 100644 --- a/CRM/TwingleCampaign/BAO/Campaign.php +++ b/CRM/TwingleCampaign/BAO/Campaign.php @@ -125,7 +125,9 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { /** * ## Complement campaign values - * Complement existing campaign values with new ones + * Complement existing campaign values with new ones. + * Existing values will not get overwritten. + * * @param array $arrayToComplement */ public function complement(array $arrayToComplement) { @@ -143,6 +145,27 @@ 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); /** diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index cc0d77e..ca9af4f 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -32,15 +32,14 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { $this->id = $id ?? NULL; $this->values['campaign_type_id'] = 'twingle_campaign'; - if (!isset($this->id)) { - $this->update($values); - $this->getParentProject(); + $this->update($values); + $this->getParentProject(); + if (!isset($this->values['cid'])) { $this->createCid(); - $this->createUrl(); - } - else { - $this->update($values); } + $this->createUrl(); + + } @@ -102,8 +101,8 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { // until the parent campaign type is a TwingleProject $parent_id = $this->values['parent_id']; $parent_id = $parent_id ?? civicrm_api3( - 'TwingleCampaign', - 'getsingle', + 'TwingleCampaign', + 'getsingle', ['id' => $this->id] )['parent_id']; @@ -318,7 +317,15 @@ 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])) { @@ -366,6 +373,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { /** * ## Get ID + * * @return mixed|null */ public function getId(): int { diff --git a/api/v3/TwingleProject/Create.php b/api/v3/TwingleProject/Create.php index 6d2bcd8..2c60095 100644 --- a/api/v3/TwingleProject/Create.php +++ b/api/v3/TwingleProject/Create.php @@ -86,8 +86,7 @@ function civicrm_api3_twingle_project_Create(array $params): array { unset($result['project_id']); $project = new TwingleProject($result, $params['id']); unset($params['id']); - $project->update($params); - $project->setEmbedData($params); + $project->merge($params); } // If no id is provided, try to create a new project with provided values else { diff --git a/twinglecampaign.php b/twinglecampaign.php index e210c34..50f8044 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -62,26 +62,36 @@ function twinglecampaign_civicrm_postSave_civicrm_campaign($dao) { if (empty($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']) || $_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] != TRUE) { + // If request is not an API-Call + if ($_GET['action'] != 'create') { - // If the db transaction is still running, add a function to it that will - // be called afterwards - if (CRM_Core_Transaction::isActive()) { + // 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)) { + 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] - ); + 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 + // If the transaction is already finished, call the function directly + else { + twinglecampaign_postSave_campaign_update_callback($dao->id, $dao->campaign_type_id); + } + + } else { - twinglecampaign_postSave_campaign_update_callback($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] + ); } - } // Remove no hook flag unset($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']); From ba9ab9f3245c0cdc88a49e4d6e770396f6b5f5a0 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Sat, 17 Apr 2021 16:58:10 +0200 Subject: [PATCH 07/52] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20Pull=20all=20campaig?= =?UTF-8?q?ns=20with=20newly=20created=20custom=20fields=20from=20Twingle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🇩🇪 update German translation --- CRM/TwingleCampaign/BAO/CustomField.php | 10 +++- CRM/TwingleCampaign/Upgrader.php | 64 +++++++++++++++++++--- api/v3/TwingleEvent/Sync.php | 33 +++++++++-- api/v3/TwingleProject/Sync.php | 51 +++++++++++++---- l10n/de_DE/LC_MESSAGES/twinglecampaign.mo | Bin 20445 -> 21047 bytes l10n/de_DE/LC_MESSAGES/twinglecampaign.po | 56 +++++++++++++++---- l10n/pot/twinglecampaign.pot | 36 ++++++++++-- 7 files changed, 206 insertions(+), 44 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index dea24f9..174e715 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -62,10 +62,10 @@ class CRM_TwingleCampaign_BAO_CustomField { * * @param bool $upgrade * If true: Does not show UF message if custom field already exists - * + * @returns array Result of custom field creation api call * @throws \CiviCRM_API3_Exception */ - public function create(bool $upgrade = false) { + public function create(bool $upgrade = FALSE): ?array { // Check if the field already exists $field = civicrm_api3( @@ -95,6 +95,7 @@ class CRM_TwingleCampaign_BAO_CustomField { id: $this->id group: $this->custom_group_id" ); + return $this->result; } // If the field could not get created: log error else { @@ -112,12 +113,17 @@ class CRM_TwingleCampaign_BAO_CustomField { $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 { + return NULL; } } diff --git a/CRM/TwingleCampaign/Upgrader.php b/CRM/TwingleCampaign/Upgrader.php index 6cecff9..3d4d94d 100644 --- a/CRM/TwingleCampaign/Upgrader.php +++ b/CRM/TwingleCampaign/Upgrader.php @@ -13,13 +13,14 @@ 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_01() { + public function upgrade_01(): bool { $campaign_info = require E::path() . '/CRM/TwingleCampaign/resources/campaigns.php'; @@ -31,7 +32,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 @@ -42,13 +43,61 @@ 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); - $cf->create(true); + $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 + ); } // Create option values @@ -124,7 +173,6 @@ 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.')); } } diff --git a/api/v3/TwingleEvent/Sync.php b/api/v3/TwingleEvent/Sync.php index 9de54cb..23a8b88 100644 --- a/api/v3/TwingleEvent/Sync.php +++ b/api/v3/TwingleEvent/Sync.php @@ -41,6 +41,13 @@ 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'), @@ -111,6 +118,10 @@ 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'])) { @@ -141,7 +152,13 @@ function civicrm_api3_twingle_event_Sync(array $params): array { } // Synchronize events if (!empty($event_from_twingle)) { - return _eventSync($event, $event_from_twingle, $twingleApi, $params); + return _eventSync( + $event, + $event_from_twingle, + $twingleApi, + $params, + $pull + ); } // If Twingle does not know an event with the given event_id, give error @@ -271,7 +288,13 @@ 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); + $result = _eventSync( + $event, + $event_from_twingle, + $twingleApi, + $params, + $pull + ); if ($result['is_error'] != 0) { $errors_occurred++; $result_values[$event->getId()] = @@ -394,6 +417,7 @@ 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 @@ -401,12 +425,13 @@ function _updateEventLocally(array $event_from_twingle, function _eventSync(TwingleEvent $event, array $event_from_twingle, TwingleApiCall $twingleApi, - array $params): array { + array $params, + bool $pull = FALSE): 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()) { + if ($event_from_twingle['updated_at'] != $event->lastUpdate() || $pull) { return _updateEventLocally($event_from_twingle, $event, $params, $twingleApi); } diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index 7768997..0906f14 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -35,6 +35,13 @@ 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'), @@ -90,6 +97,10 @@ 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'])) { @@ -106,9 +117,15 @@ function civicrm_api3_twingle_project_Sync(array $params): array { $id = $result['id']; $project = new TwingleProject($result, $id); - // Synchronize projects + // Synchronize project if (!empty($project_from_twingle)) { - return _projectSync($project, $project_from_twingle, $twingleApi, $params); + return _projectSync( + $project, + $project_from_twingle, + $twingleApi, + $params, + $pull + ); } // If Twingle does not know a project with the given project_id, give error @@ -175,8 +192,10 @@ 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'))) { + 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']); @@ -197,8 +216,11 @@ 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 { @@ -241,10 +263,12 @@ function civicrm_api3_twingle_project_Sync(array $params): array { // sync project $result = _projectSync( - $project, - $project_from_twingle, - $twingleApi, - $params); + $project, + $project_from_twingle, + $twingleApi, + $params, + $pull + ); if (!$result['is_error'] == 0) { $errors[$result['id']] = $result['error_message']; $returnValues[$project->getId()] = @@ -457,6 +481,7 @@ 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 @@ -464,11 +489,13 @@ function _pushProjectToTwingle(TwingleProject $project, function _projectSync(TwingleProject $project, array $project_from_twingle, TwingleApiCall $twingleApi, - array $params): array { + array $params, + bool $pull = FALSE): 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()) { + if ($project_from_twingle['last_update'] > $project->lastUpdate() || + $pull) { return _updateProjectLocally($project_from_twingle, $project, $params, $twingleApi); } diff --git a/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo b/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo index e4a39ee1fe73b329e902527919b8bfda35ef13d4..47867c327cada245d4485c5c2c0ddb14b240bbfb 100644 GIT binary patch delta 6372 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 HE{*sPr(ISq delta 5625 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 Date: Wed, 21 Apr 2021 09:06:23 +0200 Subject: [PATCH 08/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20campaign=20na?= =?UTF-8?q?me=20does=20not=20get=20pushed=20when=20saving?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleProject.php | 10 ++++++++++ twinglecampaign.php | 3 +++ 2 files changed, 13 insertions(+) diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index f47df4f..46e4a53 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -765,4 +765,14 @@ 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; + } + } diff --git a/twinglecampaign.php b/twinglecampaign.php index 50f8044..d700ffa 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -269,6 +269,9 @@ function _validateAndSendInput($id, $campaign_type_id): bool { // Update project $project->update($customFields); + // Set name + $project->setName($_POST['title']); + // Validate project values $validation = $project->validate(); From cef8c31f31cc8b502afab569e5b281c69dfdf684 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Wed, 26 May 2021 19:01:35 +0200 Subject: [PATCH 09/52] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20define=20cases=20for?= =?UTF-8?q?=20each=20TwingleProject?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/Configuration.php | 2 +- CRM/TwingleCampaign/BAO/TwingleEvent.php | 47 ++++++++++-------- CRM/TwingleCampaign/Form/Settings.php | 32 ++---------- CRM/TwingleCampaign/Upgrader.php | 2 +- CRM/TwingleCampaign/Utils/CaseTypes.php | 28 +++++++++++ CRM/TwingleCampaign/resources/campaigns.php | 16 ++++++ l10n/de_DE/LC_MESSAGES/twinglecampaign.mo | Bin 21047 -> 21245 bytes l10n/de_DE/LC_MESSAGES/twinglecampaign.po | 22 +++++--- l10n/pot/twinglecampaign.pot | 18 +++++-- .../CRM/TwingleCampaign/Form/Settings.tpl | 4 +- 10 files changed, 107 insertions(+), 64 deletions(-) create mode 100644 CRM/TwingleCampaign/Utils/CaseTypes.php diff --git a/CRM/TwingleCampaign/BAO/Configuration.php b/CRM/TwingleCampaign/BAO/Configuration.php index 38e8d5e..6d2614e 100644 --- a/CRM/TwingleCampaign/BAO/Configuration.php +++ b/CRM/TwingleCampaign/BAO/Configuration.php @@ -6,7 +6,7 @@ class CRM_TwingleCampaign_BAO_Configuration { private static $settingsKeys = [ 'twingle_api_key', 'twinglecampaign_xcm_profile', - 'twinglecampaign_start_case', + 'twinglecampaign_default_case', 'twinglecampaign_soft_credits' ]; diff --git a/CRM/TwingleCampaign/BAO/TwingleEvent.php b/CRM/TwingleCampaign/BAO/TwingleEvent.php index fd7eddd..4248c1d 100644 --- a/CRM/TwingleCampaign/BAO/TwingleEvent.php +++ b/CRM/TwingleCampaign/BAO/TwingleEvent.php @@ -53,32 +53,39 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { if (parent::create()) { - // 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'], - ]); + // Get case type + $parentProject = civicrm_api3( + 'TwingleProject', + 'getsingle', + ['id' => $this->values['parent_id']] + ); + $caseType = $parentProject['case'] + ?? Configuration::get('twinglecampaign_default_case'); - // Open a case - if ( - Configuration::get('twinglecampaign_start_case') && - $result['count'] == 0 - ) { - $result = civicrm_api3('Case', 'create', [ + if ($caseType) { + // check for existence + $result = civicrm_api3('Case', 'get', [ 'contact_id' => $this->formattedValues['contact'], - 'case_type_id' => Configuration::get('twinglecampaign_start_case'), + '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'); - } + // 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'); + } + } return TRUE; } return FALSE; diff --git a/CRM/TwingleCampaign/Form/Settings.php b/CRM/TwingleCampaign/Form/Settings.php index d28b7cc..f614ce5 100644 --- a/CRM/TwingleCampaign/Form/Settings.php +++ b/CRM/TwingleCampaign/Form/Settings.php @@ -4,6 +4,7 @@ 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 @@ -32,9 +33,9 @@ class CRM_TwingleCampaign_Form_Settings extends CRM_Core_Form { $this->addElement( 'select', - 'twinglecampaign_start_case', - E::ts('Start a case for event initiators'), - $this->getCaseTypes(), + 'twinglecampaign_default_case', + E::ts('Default case to open for event initiators'), + getCaseTypes(), ['class' => 'crm-select2 huge'] ); @@ -92,30 +93,5 @@ 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; - } - } diff --git a/CRM/TwingleCampaign/Upgrader.php b/CRM/TwingleCampaign/Upgrader.php index 3d4d94d..5c1a706 100644 --- a/CRM/TwingleCampaign/Upgrader.php +++ b/CRM/TwingleCampaign/Upgrader.php @@ -20,7 +20,7 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base { * changed campaigns will get pulled from Twingle. * @throws \CiviCRM_API3_Exception */ - public function upgrade_01(): bool { + public function upgrade_02(): bool { $campaign_info = require E::path() . '/CRM/TwingleCampaign/resources/campaigns.php'; diff --git a/CRM/TwingleCampaign/Utils/CaseTypes.php b/CRM/TwingleCampaign/Utils/CaseTypes.php new file mode 100644 index 0000000..312a23f --- /dev/null +++ b/CRM/TwingleCampaign/Utils/CaseTypes.php @@ -0,0 +1,28 @@ + 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; +} diff --git a/CRM/TwingleCampaign/resources/campaigns.php b/CRM/TwingleCampaign/resources/campaigns.php index 1dbeba8..ffd097c 100644 --- a/CRM/TwingleCampaign/resources/campaigns.php +++ b/CRM/TwingleCampaign/resources/campaigns.php @@ -1,6 +1,7 @@ [ @@ -121,6 +122,21 @@ 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"), diff --git a/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo b/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo index 47867c327cada245d4485c5c2c0ddb14b240bbfb..6527e9a1f4062567d51c49b5e6300d5f551bba16 100644 GIT binary patch delta 5902 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 diff --git a/l10n/de_DE/LC_MESSAGES/twinglecampaign.po b/l10n/de_DE/LC_MESSAGES/twinglecampaign.po index 7e83507..dc16d5d 100644 --- a/l10n/de_DE/LC_MESSAGES/twinglecampaign.po +++ b/l10n/de_DE/LC_MESSAGES/twinglecampaign.po @@ -7,7 +7,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.4.2\n" +"X-Generator: Poedit 2.4.3\n" "Last-Translator: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Language: de_DE\n" @@ -120,8 +120,8 @@ msgid "XCM Profile to match event initiators" msgstr "XCM-Profil zum Abgleichen von Event-Initiatoren" #: CRM/TwingleCampaign/Form/Settings.php -msgid "Start a case for event initiators" -msgstr "Einen Fall für Event-Initiatoren anlegen" +msgid "Default case to open for event initiators" +msgstr "Standarfdall, der für Event-Initiatoren eröffnet werden soll" #: CRM/TwingleCampaign/Form/Settings.php msgid "Create soft credits for event initiators" @@ -135,10 +135,6 @@ 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" @@ -182,6 +178,10 @@ 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" @@ -250,6 +250,14 @@ 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 triggered 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" diff --git a/l10n/pot/twinglecampaign.pot b/l10n/pot/twinglecampaign.pot index b4a3038..3a92564 100644 --- a/l10n/pot/twinglecampaign.pot +++ b/l10n/pot/twinglecampaign.pot @@ -75,7 +75,7 @@ msgid "XCM Profile to match event initiators" msgstr "" #: ./CRM/TwingleCampaign/Form/Settings.php -msgid "Start a case for event initiators" +msgid "Default case to open for event initiators" msgstr "" #: ./CRM/TwingleCampaign/Form/Settings.php @@ -90,10 +90,6 @@ 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 "" @@ -126,6 +122,10 @@ 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 "" @@ -186,6 +186,14 @@ 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 triggered for event creators?" +msgstr "" + #: ./CRM/TwingleCampaign/resources/campaigns.php msgid "allow more" msgstr "" diff --git a/templates/CRM/TwingleCampaign/Form/Settings.tpl b/templates/CRM/TwingleCampaign/Form/Settings.tpl index 9ba2175..a7c7c14 100644 --- a/templates/CRM/TwingleCampaign/Form/Settings.tpl +++ b/templates/CRM/TwingleCampaign/Form/Settings.tpl @@ -17,8 +17,8 @@
-
{$form.twinglecampaign_start_case.label}
-
{$form.twinglecampaign_start_case.html}
+
{$form.twinglecampaign_default_case.label}
+
{$form.twinglecampaign_default_case.html}
From dcae7c6a6982d4d6f1d0a385727e3f8d66ec8866 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Fri, 28 May 2021 23:05:11 +0200 Subject: [PATCH 10/52] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20automatically=20add?= =?UTF-8?q?=20new=20case=20types=20to=20custom=20field=20options?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/CustomField.php | 161 +++++++++++++++--- l10n/de_DE/LC_MESSAGES/de_DE.mo | Bin 0 -> 21914 bytes .../{twinglecampaign.po => de_DE.po} | 31 +++- l10n/de_DE/LC_MESSAGES/twinglecampaign.mo | Bin 21245 -> 0 bytes l10n/pot/twinglecampaign.pot | 16 +- twinglecampaign.php | 9 + 6 files changed, 184 insertions(+), 33 deletions(-) create mode 100644 l10n/de_DE/LC_MESSAGES/de_DE.mo rename l10n/de_DE/LC_MESSAGES/{twinglecampaign.po => de_DE.po} (97%) delete mode 100644 l10n/de_DE/LC_MESSAGES/twinglecampaign.mo diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index 174e715..04324f3 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -56,12 +56,12 @@ 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 Result of custom field creation api call * @throws \CiviCRM_API3_Exception */ @@ -79,38 +79,44 @@ 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()); - // Set field id - $this->id = $this->result['id']; + try { + $this->result = civicrm_api3( + 'CustomField', + 'create', + $this->getSetAttributes()); - // 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" - ); - return $this->result; - } - // If the field could not get created: log error - else { + 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 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\": - $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])); + ->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] + )); } // If there is not enough information: log simple error message else { Civi::log() - ->error("$this->extensionName could not create new custom field: - $this->result['error_message']"); + ->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; @@ -127,6 +133,101 @@ class CRM_TwingleCampaign_BAO_CustomField { } } + /** + * Update an existing custom field + * + * @returns array Result of custom field creation api call + */ + public function update(): array { + + 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; + } + } + + /** + * Add additional options to custom field + * + * @param array $options + * + * @return array + */ + public function addOptions(array $options): array { + $result = []; + + try { + $option_group_id = civicrm_api3( + 'CustomField', + 'getsingle', + ['id' => $this->id] + )['option_group_id']; + } catch (CiviCRM_API3_Exception $e) { + $errorMessage = $e->getMessage(); + Civi::log() + ->error("$this->extensionName could not get get option group id for custom field \"$this->name\": $errorMessage"); + CRM_Utils_System::setUFMessage( + E::ts('%1 could not get option group id for custom field \'%2\'. Find more information in the logs.', + [1 => $this->extensionName, 2 => $this->name]) + ); + } + + try { + foreach ($options as $key => $value) { + $result[] = civicrm_api3( + 'OptionValue', + 'create', + [ + 'option_group_id' => $option_group_id, + 'value' => $key, + 'label' => $value, + ] + ); + } + } 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; + } + /** * Gets all the set attributes of the object and returns them as an array. * @@ -143,7 +244,6 @@ 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. @@ -362,6 +462,13 @@ 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; + } } \ No newline at end of file diff --git a/l10n/de_DE/LC_MESSAGES/de_DE.mo b/l10n/de_DE/LC_MESSAGES/de_DE.mo new file mode 100644 index 0000000000000000000000000000000000000000..b69812f675d2a02221adb4e10593c4952663004a GIT binary patch literal 21914 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 U{WqrdnS=tn4k-)7y#M5104%x`H2?qr literal 0 HcmV?d00001 diff --git a/l10n/de_DE/LC_MESSAGES/twinglecampaign.po b/l10n/de_DE/LC_MESSAGES/de_DE.po similarity index 97% rename from l10n/de_DE/LC_MESSAGES/twinglecampaign.po rename to l10n/de_DE/LC_MESSAGES/de_DE.po index dc16d5d..5736cb0 100644 --- a/l10n/de_DE/LC_MESSAGES/twinglecampaign.po +++ b/l10n/de_DE/LC_MESSAGES/de_DE.po @@ -14,10 +14,10 @@ msgstr "" #: CRM/TwingleCampaign/BAO/CustomField.php msgid "" -"Creation of custom field '%1' failed. Find more information in the logs." +"%1: Creation of custom field '%2' failed. Find more information in the logs." msgstr "" -"Erstellung von Custom Field '%1' fehlgeschlagen. Mehr Informationen in den " -"Logs." +"%1: Erstellen des benutzerdefinierten Feldes '%2' fehlgeschlagen. Mehr " +"Informationen in den Logs." #: CRM/TwingleCampaign/BAO/CustomField.php msgid "Creation of custom field failed. Find more information in the logs." @@ -33,6 +33,29 @@ 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." @@ -255,7 +278,7 @@ msgid "Case" msgstr "Fall" #: CRM/TwingleCampaign/resources/campaigns.php -msgid "Which case should get triggered for event creators?" +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 diff --git a/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo b/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo deleted file mode 100644 index 6527e9a1f4062567d51c49b5e6300d5f551bba16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21245 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 M_=palF6ck`XA+PaddOptions( + [$newCaseType['name'] => $newCaseType['title']] + ); +} /** * Implements hook_civicrm_postSave_Campaign(). From 397ba573433f3f62d7881ff63cbd2c170d0db382 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 23 Jul 2021 16:56:15 +0200 Subject: [PATCH 11/52] =?UTF-8?q?=F0=9F=91=BE=20fix=20bug:=20#2=20CiviCRM?= =?UTF-8?q?=20Error=20on=20independent=20API=20Call=20on=20campaign?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to @iTobi for reporting the bug! --- twinglecampaign.php | 186 ++++++++++++++++++++++---------------------- 1 file changed, 95 insertions(+), 91 deletions(-) diff --git a/twinglecampaign.php b/twinglecampaign.php index d700ffa..d75da8e 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -59,42 +59,53 @@ function twinglecampaign_civicrm_config(&$config) { */ function twinglecampaign_civicrm_postSave_civicrm_campaign($dao) { - if (empty($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']) || - $_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] != TRUE) { + $twingle_project_campaign_type_id = _get_campaign_type_id_twingle_project(); + $twingle_campaign_campaign_type_id = _get_campaign_type_id_twingle_campaign(); - // If request is not an API-Call - if ($_GET['action'] != 'create') { + // 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 the db transaction is still running, add a function to it that will - // be called afterwards - if (CRM_Core_Transaction::isActive()) { + if (empty($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']) || + $_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] != TRUE) { - if (_validateAndSendInput($dao->id, $dao->campaign_type_id)) { + // If request is not an API-Call + if ($_GET['action'] != 'create' && $_POST['action'] != 'create') { - CRM_Core_Transaction::addCallback( - CRM_Core_Transaction::PHASE_POST_COMMIT, - 'twinglecampaign_postSave_campaign_update_callback', - [$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 + // If the transaction is already finished, call the function directly + else { + twinglecampaign_postSave_campaign_update_callback($dao->id, $dao->campaign_type_id); + } + + } else { - twinglecampaign_postSave_campaign_update_callback($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] + ); } - - } - else { - CRM_Core_Transaction::addCallback( - CRM_Core_Transaction::PHASE_POST_COMMIT, - 'twinglecampaign_postSave_campaign_update_callback', - [$dao->id, $dao->campaign_type_id] - ); } + // Remove no hook flag + unset($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']); } - // Remove no hook flag - unset($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']); } /** @@ -115,78 +126,70 @@ 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(); - // 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 - ) { + // Set $entity for $campaign_type_id + if ($campaign_type_id == $twingle_project_campaign_type_id) { + $entity = 'TwingleProject'; + } + else { + $entity = 'TwingleCampaign'; + } - // 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 + if (isset($_POST['action'])) { + if ($_POST['action'] == 'clone' && $entity == 'TwingleProject') { + $_POST['action'] = 'create'; + $result = civicrm_api3('TwingleProject', 'getsingle', + ['id' => $campaign_id] + ); + $id = $result['id']; + unset($result['id']); + $project = new TwingleProject($result, $id); try { - civicrm_api3( - 'TwingleCampaign', - 'sync', - ['parent_id' => $campaign_id]); - } catch (CiviCRM_API3_Exception $e) { + $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("TwingleCampaign update failed"), - error, [unique => TRUE] - ); - Civi::log()->error( - E::SHORT_NAME . - ' Update of TwingleCampaigns failed: ' . $e->getMessage() + E::ts("Campaign cloning failed"), + error, + [unique => TRUE] ); } } - 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() - ); - } + } + + // 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() + ); } } } @@ -203,6 +206,7 @@ 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( From bc921782371eab459bfde3e56fd6f0c80d2de332 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 25 Aug 2021 11:27:52 +0200 Subject: [PATCH 12/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20no=5Fhook=20f?= =?UTF-8?q?lag=20was=20not=20always=20getting=20deleted=20after=20creating?= =?UTF-8?q?=20new=20campaign?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twinglecampaign.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/twinglecampaign.php b/twinglecampaign.php index d75da8e..2e4351a 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -103,9 +103,9 @@ function twinglecampaign_civicrm_postSave_civicrm_campaign($dao) { ); } } - // Remove no hook flag - unset($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']); } + // Remove no hook flag + unset($_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook']); } /** From 29166eef64c2e22258e007b6921736ab5d3fc4cc Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 25 Aug 2021 15:51:41 +0200 Subject: [PATCH 13/52] =?UTF-8?q?=F0=9F=94=8A=20improve=20logging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twinglecampaign.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/twinglecampaign.php b/twinglecampaign.php index 2e4351a..f80cc3d 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -130,9 +130,22 @@ function twinglecampaign_postSave_campaign_update_callback( if ($campaign_type_id == $twingle_project_campaign_type_id) { $entity = 'TwingleProject'; } - else { + 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 (isset($_POST['action'])) { if ($_POST['action'] == 'clone' && $entity == 'TwingleProject') { From be4831bc54acee6b212c23bba0c454a7ac3b0fb4 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 25 Aug 2021 15:58:04 +0200 Subject: [PATCH 14/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20campaign=20cl?= =?UTF-8?q?oning=20fails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twinglecampaign.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/twinglecampaign.php b/twinglecampaign.php index f80cc3d..d966033 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -149,7 +149,7 @@ function twinglecampaign_postSave_campaign_update_callback( if (isset($_POST['action'])) { if ($_POST['action'] == 'clone' && $entity == 'TwingleProject') { - $_POST['action'] = 'create'; + unset($_POST['action']); $result = civicrm_api3('TwingleProject', 'getsingle', ['id' => $campaign_id] ); @@ -252,6 +252,7 @@ function twinglecampaign_postSave_project_create_callback( * * @return bool * @throws \CiviCRM_API3_Exception + * @throws \Exception */ function _validateAndSendInput($id, $campaign_type_id): bool { @@ -286,8 +287,10 @@ function _validateAndSendInput($id, $campaign_type_id): bool { // Update project $project->update($customFields); - // Set name - $project->setName($_POST['title']); + // Set name if provided + if (isset($_POST['title'])) { + $project->setName($_POST['title']); + } // Validate project values $validation = $project->validate(); From 066a0096dfc714ef89c91c4a7cbe9ef7e2e4a7e9 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 25 Aug 2021 15:59:43 +0200 Subject: [PATCH 15/52] =?UTF-8?q?=F0=9F=91=BE=20bugfix:=20no=20error=20mes?= =?UTF-8?q?sage=20on=20exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v3/TwingleProject/Sync.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index 0906f14..4d578ce 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -234,7 +234,7 @@ function civicrm_api3_twingle_project_Sync(array $params): array { $returnValues[$project->getId()] = $project->getResponse('TwingleProject created'); } catch (Exception $e) { - $errors[$result['id']] = $result['error_message']; + $errors[$project_from_twingle['id']] = $e->getMessage(); Civi::log()->error( E::LONG_NAME . ' could not create TwingleProject: ' . From bbbf6e1cc6ae941389fb9e9fe58a64de74016668 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 25 Aug 2021 16:06:50 +0200 Subject: [PATCH 16/52] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20Do=20not=20sync=20Tw?= =?UTF-8?q?ingle=20projects=20to=20CiviCRM=20which=20are=20marked=20as=20s?= =?UTF-8?q?uch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a checkbox in TwingleMANAGER that allows you to enable and disable API calls to the Twingl API (de.systopia.twingle). This commit makes the TwingleCampaign extension pay attention to this checkbox, so if it is unchecked, no campaign will be created in CiviCRM for this Twingle project. --- CRM/TwingleCampaign/BAO/TwingleProject.php | 5 +++++ api/v3/TwingleProject/Sync.php | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index 46e4a53..8f509c0 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -165,6 +165,11 @@ 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 diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index 4d578ce..26a46be 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -230,9 +230,14 @@ function civicrm_api3_twingle_project_Sync(array $params): array { $project->getResponse('Ready to create TwingleProject'); } - $project->create(TRUE); - $returnValues[$project->getId()] = - $project->getResponse('TwingleProject created'); + if ($project->create(TRUE)) { + $returnValues[$project->getId()] = + $project->getResponse('TwingleProject created'); + } + else { + $returnValues[$project->getId()] = + $project->getResponse('TwingleProject not selected for synchronization'); + } } catch (Exception $e) { $errors[$project_from_twingle['id']] = $e->getMessage(); Civi::log()->error( From 06e30f6ef797b66f09c4cb397b2676fd5eedee03 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 17 Sep 2021 10:22:48 +0200 Subject: [PATCH 17/52] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20update=20civix=20gen?= =?UTF-8?q?erated=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twinglecampaign.civix.php | 50 ++++++++++----------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/twinglecampaign.civix.php b/twinglecampaign.civix.php index 7d7e079..575f31e 100644 --- a/twinglecampaign.civix.php +++ b/twinglecampaign.civix.php @@ -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,8 +193,9 @@ 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 */ @@ -220,41 +221,18 @@ 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: In Civi 4.3+, delegate to CRM_Utils_File::findFiles() + * Note: Delegate to CRM_Utils_File::findFiles(), this function kept only + * for backward compatibility of extension code that uses it. * * @param string $dir base dir * @param string $pattern , glob pattern, eg "*.txt" * - * @return array(string) + * @return array */ function _twinglecampaign_civix_find_files($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; + return CRM_Utils_File::findFiles($dir, $pattern); } + /** * (Delegated) Implements hook_civicrm_managed(). * @@ -362,7 +340,7 @@ function _twinglecampaign_civix_civicrm_themes(&$themes) { * @link http://php.net/glob * @param string $pattern * - * @return array, possibly empty + * @return array */ function _twinglecampaign_civix_glob($pattern) { $result = glob($pattern); @@ -470,8 +448,6 @@ 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, array ( - )); + $entityTypes = array_merge($entityTypes, []); } From 108d2c95866cc80447911a5ffe909ca8e1f11f3b Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 4 Oct 2021 09:37:19 +0200 Subject: [PATCH 18/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20cid=20changes?= =?UTF-8?q?=20when=20updating=20TwingleCampaing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 27 +++++++-------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index ca9af4f..1c035b9 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -17,32 +17,31 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { private $values; - /** * ## TwingleCampaign constructor * - * @param array|null $values - * @param int|null $id + * @param array $values * * @throws \CiviCRM_API3_Exception */ - public function __construct(array $values = [], int $id = NULL) { + public function __construct(array $values = []) { $this->prefix = 'twingle_campaign_'; - $this->id = $id ?? NULL; + $this->id = $values['id'] ?? NULL; $this->values['campaign_type_id'] = 'twingle_campaign'; + if ($this->id != NULL) { + $this->fetch($this->id); + } $this->update($values); + $this->getParentProject(); if (!isset($this->values['cid'])) { $this->createCid(); } $this->createUrl(); - - } - /** * ## Create TwingleCampaign * Create this TwingleCampaign as a campaign in CiviCRM @@ -69,19 +68,17 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { } } - /** * ## Fetch TwingleCampaign * Populate this instance with values from an existing TwingleCampaign. * * @throws CiviCRM_API3_Exception */ - public function fetch() { + public function fetch(int $id) { $this->values = civicrm_api3('TwingleCampaign', 'getsingle', - ['id' => $this->id]); + ['id' => $id]); } - /** * ## Get Parent Project * Determines the id of the parent TwingleProject. If there is no parent @@ -128,7 +125,6 @@ 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; @@ -205,7 +201,6 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { $this->values['parent_project_url'] . '?tw_cid=' . $this->values['cid']; } - /** * */ @@ -214,7 +209,6 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { $this->values['cid'] = uniqid(); } - /** * ## Translate field names and custom field names * @@ -283,7 +277,6 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { } } - /** * ## Delete TwingleCampaign * Deletes this TwingleCampaign from CiviCRM @@ -303,7 +296,6 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { } } - /** * ## Get a response * Get a response that describes the status of this TwingleCampaign instance. @@ -380,5 +372,4 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { return (int) $this->id; } - } \ No newline at end of file From f059abf5a846345066e7e307d17582f9fd4ac9a0 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 5 Oct 2021 17:20:37 +0200 Subject: [PATCH 19/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20wrong=20paren?= =?UTF-8?q?t=20TwingleProject=20id's?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 14 ++++++++------ .../Exceptions/TwingleCampaignException.php | 8 ++++++++ api/v3/TwingleCampaign/Create.php | 16 ++++------------ 3 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index 1c035b9..1e773c2 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -2,6 +2,7 @@ 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 { @@ -23,6 +24,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { * @param array $values * * @throws \CiviCRM_API3_Exception + * @throws \CRM_TwingleCampaign_Exceptions_TwingleCampaignException */ public function __construct(array $values = []) { @@ -86,6 +88,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { * deleted. * * @throws \CiviCRM_API3_Exception + * @throws \CRM_TwingleCampaign_Exceptions_TwingleCampaignException */ private function getParentProject(): void { @@ -96,8 +99,7 @@ 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']; - $parent_id = $parent_id ?? civicrm_api3( + $parent_id = $this->values['parent_id'] ?? civicrm_api3( 'TwingleCampaign', 'getsingle', ['id' => $this->id] @@ -117,7 +119,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { } $parent_campaign_type_id = $parent_campaign['campaign_type_id']; - if (isset($parent_campaign['parent_id'])) { + if ($parent_campaign_type_id != $twingle_project_campaign_type_id && isset($parent_campaign['parent_id'])) { $parent_id = $parent_campaign['parent_id']; } else { @@ -167,7 +169,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { ' could not determine parent TwingleProject URL.', $this->getResponse() ); - $this->delete(); + throw new TwingleCampaignException('Parent project URL missing'); } } @@ -180,7 +182,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { ts('No parent TwingleProject found'), 'alert' ); - $this->delete(); + throw new TwingleCampaignException('No parent TwingleProject found'); } } @@ -288,7 +290,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { } catch (CiviCRM_API3_Exception $e) { Civi::log()->error( E::LONG_NAME . - ' could delete TwingleCampaign: ' . + ' could not delete TwingleCampaign: ' . $e->getMessage(), $this->getResponse() ); diff --git a/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php b/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php new file mode 100644 index 0000000..0f99555 --- /dev/null +++ b/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php @@ -0,0 +1,8 @@ +create(TRUE); return civicrm_api3_create_success( $campaign->getResponse('TwingleCampaign created'), @@ -74,15 +73,8 @@ 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(), - $campaign->getResponse() + 'Could not create TwingleCampaign: ' . $e->getMessage() ); } From a01367a161fd12c4ab6799c7859c4cba2135dcd4 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 6 Oct 2021 15:14:32 +0200 Subject: [PATCH 20/52] =?UTF-8?q?=E2=9C=A8=20make=20TwingleCampaings=20clo?= =?UTF-8?q?nable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TwingleCampaings can be cloned. Cloned campaigns will generate a new cid and url. --- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 31 ++++++++++---------- api/v3/TwingleCampaign/Create.php | 7 +++++ l10n/de_DE/LC_MESSAGES/de_DE.mo | Bin 21914 -> 22243 bytes l10n/de_DE/LC_MESSAGES/de_DE.po | 21 +++++++++++-- l10n/pot/twinglecampaign.pot | 12 ++++++++ twinglecampaign.php | 13 ++++++++ 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index 1e773c2..2cbc865 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -32,15 +32,30 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { $this->id = $values['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 (!isset($this->values['cid'])) { + + // 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']) + ) { $this->createCid(); } + + // Create an url from the parent TwingleProject url and the cid of this + // TwingleCampaign $this->createUrl(); } @@ -351,20 +366,6 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { } } - /** - * ## 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 * diff --git a/api/v3/TwingleCampaign/Create.php b/api/v3/TwingleCampaign/Create.php index d4d9db8..e42c00a 100644 --- a/api/v3/TwingleCampaign/Create.php +++ b/api/v3/TwingleCampaign/Create.php @@ -40,6 +40,13 @@ 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'), + ]; } diff --git a/l10n/de_DE/LC_MESSAGES/de_DE.mo b/l10n/de_DE/LC_MESSAGES/de_DE.mo index b69812f675d2a02221adb4e10593c4952663004a..7a64892cd08c3b980950268790513f050bc27c62 100644 GIT binary patch delta 6170 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 F`#W^rzcl~= delta 5886 zcmZA533yId0><$ZNysWfh^-{{AQF*SVy{Gl*dn%AgNQu{V*gY-l+Z!6igq%HovMbR zGq$2t%goRkYiUQ&T4!igOKJb_caLX0bD!s(-#Pc*@1Aqda${Pw-DA~O57*VwUhfzV ze-C3S<0KzrGAW-brL)G2C}+%Y9EoXo8k4bJs4=hpE;<7(;y& zR>Kb*UFMKIQDiM%!I(ze5P`lp0E=TL(l;~Cp3lKx>aU~vnuh^cfS$M$b^mVb0qZgA zX}2z8E>bALjn_~=yp8^NA4Bj7^3o=#qA`J33(H_Emc%6FrA==vjalf0bFnAR$GLa~ z^&*2SIoC7MllILR3hKak)EiAjy~#rB3TpwX!JVl44&gBT5+kt*^CvTKD&}DW40wfM z$L6S^-+*fGIJ#6gL!k~{M9o>TDozIiaW?gen1m~_9bU8NYgKj5uScD~kNSN~m@(C{ zC3<5zs+~;K3uIvg&JHs!_t0+QL?R~+qHgpKcX}F#8nS5A95+FYOp>)H(q}WoUY~UZaC{R*nR?_Cr$XC-Pl4aK1rUp&TQd(;nSphjS>t>>W^ z^;M`{l8+kd%~%U}pq_IM)uC%vubRd%OQsg8W3KiT+ED0@YH%5L$786Gsle0Jz*yAK z=Ac&leAEc!+wjHm7kKs_fIH8NGv7aQAp8&n5+ zqw7@)nH1=(*@EifS@g%ts4v=gs1bUC8uDUHwC?l4WDG(z*dNu6k9{3I(M|EsaykiEcW20?78-uA&Lzf!Lr65gwisE%w#4SiK^Qp1U;j&{aKOhHZAoR*Bg3X3?Ai|=7~ ztickNQ&8u>u=P}0(fJLik@*?fp{7(DXR2DG8tjPWF$J|7Mq^prf*tS>YKr~Zx}0qm z!jji&Z-v@!iKrn@vyMcK#8i8I83s|`i2ZR7YHft@IaR|ot*uatu{Vyv)mR68I9VGT zx+rLS^hFKP5Y&idqB@jq>(i0nnt50akE0glT~vcU3C^2`qvk#WHI-4Q`&uA7*z`fQ zmy3D<*K!JaKmqCp`)&OMYAB0PKe&S$ksr|uJrkWd_CdXQ1JoO}#wwVJm2n>GIqQ(w zGFwq2b_dh6|C89Y9-W&v_`G^PFNQQqTXNuvUAN!R7cNPFQGT} zB5aDcP%l_5$vGc|1GWF-C}?pkN6q~fWI>yQs5gF!>VO|BN7u`thO{1X$-IWzPD@a0 zWG#l_K70kQphoy9`eH~&=U+-yuqy4FP88JB(O4TNpoVm%J--Fjk&jRf9Yl@H8B~Lh zum%Qoa{lcXi&{JVP}_P4>dnVvIhO%ot*|-q7U_Ms0R9C2^@+k zI2!f91NQs{)MES=^_&~1H++U+7(%OB^>L`(GXgagTTw4~vHyRzrrZIj@mvUJ)H-|Slgi1L>JT=>4n-ogHdZ|IO;iB7=&|B_bovWeEF!Z z{jbB1D+Nx`y;aonl0*;qt3B_2kY2!T|7!A z+q!s2rjp^RaNH&FM6Y~`=ndmZ0XS@VC63?MP&T@p@0$VH;#G1=iRx&OIjR#JYSj3)=l zZ{#}?N;1h6a*L#pWuydC7lk^$C5b9^J6WEPTqGMDH`BEIAZ=}(pr9bx1i@gl3p zZc<3*6K@*v#I@uR*-u)M@}w`(vBrVFT@AyAW=$S5ENooik#bMG3XfDe5mb1&-d?Z5 z9nnRef#WhKr)OqFre>s%jStKFG&U $campaign_id, 'clone' => true] + ); + CRM_Utils_System::setUFMessage(E::ts('TwingleCampaign was cloned.')); + } catch (CiviCRM_API3_Exception $e) { + Civi::log()->error( + 'twinglecampaign_postSave_callback ' . $e->getMessage() + ); + } + } } // If a TwingleProject is getting saved From 8b493c53725690cde55776934bf6d155000a1b58 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 6 Oct 2021 15:15:56 +0200 Subject: [PATCH 21/52] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20undefined=20i?= =?UTF-8?q?ndex=20in=20twinglecampaign.php?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twinglecampaign.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/twinglecampaign.php b/twinglecampaign.php index 195ceb4..bda4f1d 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -82,7 +82,11 @@ function twinglecampaign_civicrm_postSave_civicrm_campaign($dao) { $_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] != TRUE) { // If request is not an API-Call - if ($_GET['action'] != 'create' && $_POST['action'] != 'create') { + if ( + ((isset($_GET['action']) && $_GET['action'] != 'create') || + (isset($_POST['action']) && $_POST['action'] != 'create')) || + (!isset($_GET['action']) && !isset($_POST['action'])) + ) { // If the db transaction is still running, add a function to it that will // be called afterwards From 0a93756e031d6cb0971f714822351b62a2a7c1ef Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 15 Dec 2021 08:32:18 +0100 Subject: [PATCH 22/52] =?UTF-8?q?=F0=9F=94=96=201.0=20stable=20release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index f0bd158..24956c7 100644 --- a/info.xml +++ b/info.xml @@ -14,13 +14,13 @@ https://lab.civicrm.org/Marc_Michalsky/de-forumzfd-twinglecampaign/-/issues http://www.gnu.org/licenses/agpl-3.0.html - 2020-09-25 + 2021-12-15 1.0 - alpha + stable 5.14.0 - This is a new, undeveloped module + de.systopia.xcm de.systopia.campaign From 482b8e2d0d1ff4d3c51ae302609da47d2ffc0256 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 17 Dec 2021 09:05:51 +0100 Subject: [PATCH 23/52] =?UTF-8?q?=F0=9F=90=9B=20Fix=20bug=20#5:=20Error=20?= =?UTF-8?q?when=20altering=20any=20case=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/CustomField.php | 31 ++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index 04324f3..a0a9b81 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -205,15 +205,40 @@ class CRM_TwingleCampaign_BAO_CustomField { try { foreach ($options as $key => $value) { - $result[] = civicrm_api3( + + $option_value_exists = civicrm_api3( 'OptionValue', - 'create', + 'get', [ + 'sequential' => 1, 'option_group_id' => $option_group_id, 'value' => $key, - 'label' => $value, ] ); + + // If the option value does not yet exist, create it + if ($option_value_exists['count'] == 0) { + $result[] = civicrm_api3( + 'OptionValue', + 'create', + [ + 'option_group_id' => $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, + ] + ); + } } } catch (CiviCRM_API3_Exception $e) { $errorMessage = $e->getMessage(); From 3e73ed733bb6a753005e368c9fe238e749772982 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 17 Dec 2021 12:13:13 +0100 Subject: [PATCH 24/52] =?UTF-8?q?=E2=9C=A8=20improve=20hex=20color=20valid?= =?UTF-8?q?ation=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleProject.php | 34 +++++++++++++--------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index 8f509c0..fc3f779 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -31,6 +31,13 @@ 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', + ]; + /** * ## TwingleProject constructor * @@ -143,11 +150,13 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { */ private function strToInt(array &$values) { foreach ($values as $key => $value) { - if (ctype_digit($value)) { - $values[$key] = intval($value); - } - elseif (is_array($value)) { - $this->strToInt($values[$key]); + if (!in_array($key, self::colorFields)) { + if (ctype_digit($value)) { + $values[$key] = intval($value); + } + elseif (is_array($value)) { + $this->strToInt($values[$key]); + } } } } @@ -298,21 +307,18 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { } // Validate hexadecimal color fields - $colorFields = - [ - 'design_background_color', - 'design_primary_color', - 'design_font_color', - ]; - foreach ($colorFields as $colorField) { + foreach (self::colorFields as $colorField) { if ( - !empty($this->values['project_options'][$colorField]) && + ( + !empty($this->values['project_options'][$colorField]) || + $this->values['project_options'][$colorField] === "0" + ) && ( !( 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; From fbe30b0ce582f8e9e49a56e6c5804e0be2cdf917 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 17 Dec 2021 12:19:46 +0100 Subject: [PATCH 25/52] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20get=20rid=20of=20?= =?UTF-8?q?the=20warning=20about=20using=20an=20deprecated=20constant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twinglecampaign.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/twinglecampaign.php b/twinglecampaign.php index bda4f1d..04ff8ca 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -411,8 +411,7 @@ function _validateAndSendInput($id, $campaign_type_id): bool { CRM_Core_Session::setStatus( $errorMessage, E::ts("Input validation failed"), - error, - [unique => TRUE] + error ); // Validation failed return FALSE; From 0ab5bb1fa93d50081ad127697367990418b43d82 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 17 Dec 2021 12:23:38 +0100 Subject: [PATCH 26/52] =?UTF-8?q?=F0=9F=A9=B9=20call=20the=20right=20API?= =?UTF-8?q?=20to=20fetch=20OptionValues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/OptionValue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/BAO/OptionValue.php b/CRM/TwingleCampaign/BAO/OptionValue.php index 9de6594..1d808aa 100644 --- a/CRM/TwingleCampaign/BAO/OptionValue.php +++ b/CRM/TwingleCampaign/BAO/OptionValue.php @@ -158,7 +158,7 @@ class CRM_TwingleCampaign_BAO_OptionValue { // If a specific option value is required try { $option_value = civicrm_api3( - 'CustomValue', + 'OptionValue', 'get', [ 'sequential' => 1, From 2abf1676bd64522fa4beadabc5d238f4fd54caa2 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 17 Dec 2021 12:28:15 +0100 Subject: [PATCH 27/52] =?UTF-8?q?=F0=9F=94=96=201.0.1=20stable=20release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - ✨ #4 improve hex color validation - 🐛 #5 fix bug: error when altering any case type - 🗑️ get rid of the warning about using an deprecated constant - 🩹 call the right API to fetch OptionValues --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index 24956c7..e31f067 100644 --- a/info.xml +++ b/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-12-15 - 1.0 + 1.0.1 stable 5.14.0 From cb4c11feee636a85f3f8c1bd6761b3e49f68543d Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 20 Jan 2022 16:52:11 +0100 Subject: [PATCH 28/52] =?UTF-8?q?=F0=9F=90=9B=20bug=20fix:=20color=20field?= =?UTF-8?q?s=20were=20converted=20from=20hex=20to=20dec=20values?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added this two color fields to $colorFields: - design_button_font_color - design_button_font_color_light --- CRM/TwingleCampaign/BAO/TwingleProject.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index fc3f779..2e2cd1d 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -36,6 +36,8 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { 'design_background_color', 'design_primary_color', 'design_font_color', + 'design_button_font_color', + 'design_button_font_color_light', ]; /** From 6a50ea2c166d020f432c9a584a5fc38812704c66 Mon Sep 17 00:00:00 2001 From: Daniel Scholten Date: Thu, 21 Jul 2022 10:42:37 +0200 Subject: [PATCH 29/52] Documentation to enable scheduled job in nonproductive sites --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 60025fa..59ba268 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ 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 @@ -81,4 +83,4 @@ extension. - [ ] 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 \ No newline at end of file +- [ ] Make more payment methods available From 975b77eaf25997b88eef3652f6f6b4776f42ca9b Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 21 Nov 2022 16:12:04 +0100 Subject: [PATCH 30/52] =?UTF-8?q?=F0=9F=94=A7=20do=20not=20only=20fetch=20?= =?UTF-8?q?active=20campaigns=20from=20campaign.get?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v3/TwingleProject/Sync.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index 26a46be..aed3d2a 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -176,8 +176,7 @@ 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', - ['is_active' => 1,]); + $projects_from_civicrm = civicrm_api3('TwingleProject', 'get'); // If call to TwingleProject.get failed, forward error message if ($projects_from_civicrm['is_error'] != 0) { From 6476a163fcd42e059b7fbddd84351c6ec66baf17 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 21 Nov 2022 16:52:38 +0100 Subject: [PATCH 31/52] =?UTF-8?q?=F0=9F=94=96=20bump=20version=20to=201.0.?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index e31f067..b3b1950 100644 --- a/info.xml +++ b/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2021-12-15 - 1.0.1 + 1.0.2 stable 5.14.0 From 51b19ac68d56dd64c4db7a203e2bfce6991e885e Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 28 Feb 2023 15:14:31 +0100 Subject: [PATCH 32/52] =?UTF-8?q?=F0=9F=90=9B=20fix=20bug:=20cannot=20sear?= =?UTF-8?q?ch=20for=20TwingleForm=20by=20twingle=5Fproject=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v3/TwingleForm/Get.php | 14 ++++++++++++++ api/v3/TwingleForm/Getsingle.php | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/api/v3/TwingleForm/Get.php b/api/v3/TwingleForm/Get.php index 3e2f867..6adaf2e 100644 --- a/api/v3/TwingleForm/Get.php +++ b/api/v3/TwingleForm/Get.php @@ -14,6 +14,13 @@ use CRM_TwingleCampaign_Utils_ExtensionCache as Cache; 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, @@ -66,6 +73,13 @@ 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']] = diff --git a/api/v3/TwingleForm/Getsingle.php b/api/v3/TwingleForm/Getsingle.php index e763683..09e18d5 100644 --- a/api/v3/TwingleForm/Getsingle.php +++ b/api/v3/TwingleForm/Getsingle.php @@ -12,6 +12,13 @@ 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, From a4cda1427b920e14ebd4e236fcd60f01a616801c Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 28 Feb 2023 15:22:33 +0100 Subject: [PATCH 33/52] =?UTF-8?q?=F0=9F=94=96=20bump=20version=20to=201.0.?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 🐛 fix bug: cannot search for TwingleForm by twingle_project_id - Documentation to enable scheduled job in nonproductive sites by @RoWo-DS --- info.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/info.xml b/info.xml index b3b1950..b7ae3af 100644 --- a/info.xml +++ b/info.xml @@ -14,8 +14,8 @@ https://lab.civicrm.org/Marc_Michalsky/de-forumzfd-twinglecampaign/-/issues http://www.gnu.org/licenses/agpl-3.0.html - 2021-12-15 - 1.0.2 + 2023-02-28 + 1.0.3 stable 5.14.0 From bfa3ae7e32859e273bc763e60c5069bb316a9c7f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 16:11:30 +0200 Subject: [PATCH 34/52] fix wrong return type --- CRM/TwingleCampaign/BAO/TwingleProject.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index 2e2cd1d..d63dd42 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -181,15 +181,8 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { return FALSE; } - $result = parent::create($no_hook); + return parent::create($no_hook); - // Check if campaign was created successfully - if ($result['is_error'] == 0) { - return TRUE; - } - else { - throw new Exception($result['error_message']); - } } /** From 54adee32a937f0b6ce666bdebcd8dddd147eb2a5 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 16:12:56 +0200 Subject: [PATCH 35/52] Add new project types 'shop' and 'giftshop' --- CRM/TwingleCampaign/resources/campaigns.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/resources/campaigns.php b/CRM/TwingleCampaign/resources/campaigns.php index ffd097c..9c59709 100644 --- a/CRM/TwingleCampaign/resources/campaigns.php +++ b/CRM/TwingleCampaign/resources/campaigns.php @@ -113,7 +113,9 @@ return [ "option_values" => [ "default" => E::ts("Default"), "event" => E::ts("Events"), - "membership" => E::ts("Membership") + "membership" => E::ts("Membership"), + "shop" => E::ts("Shop"), + "giftshop" => E::ts("Gift Shop") ], "text_length" => 32, "is_active" => 1, From 2949ab0168cdd50ccfb0e1036b9e2e014448a098 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 16:15:05 +0200 Subject: [PATCH 36/52] create new option values when custom field is changed --- CRM/TwingleCampaign/BAO/CustomField.php | 117 +++++++++++++----------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index a0a9b81..9666d30 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -62,10 +62,11 @@ class CRM_TwingleCampaign_BAO_CustomField { * @param bool $upgrade * If true: Does not show UF message if custom field already exists * - * @returns array Result of custom field creation api call + * @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): ?array { + public function create(bool $upgrade = FALSE) { // Check if the field already exists $field = civicrm_api3( @@ -129,52 +130,74 @@ class CRM_TwingleCampaign_BAO_CustomField { return NULL; } else { - return NULL; + $this->id = $field['values'][0]['id']; + $this->custom_group_id = $field['values'][0]['custom_group_id']; + return $this->upgrade($field['values'][0]); } } /** - * Update an existing custom field + * Upgrade an existing custom field * - * @returns array Result of custom field creation api call + * @param $attributes + * Custom Field data + * @returns array|False Result of custom field creation api call, False if + * field was not upgraded */ - public function update(): array { + private function upgrade($attributes) { + $upgrade_necessary = False; - try { - $this->result = civicrm_api3( - 'CustomField', - 'create', - $this->getSetAttributes()); + if (key_exists('option_group_id', $attributes)) { + $this->addOptions($attributes); + } - // Log field creation - if ($this->result['is_error'] == 0) { - Civi::log()->info("$this->extensionName has updated a custom field. + 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; } - 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; } /** @@ -188,30 +211,14 @@ class CRM_TwingleCampaign_BAO_CustomField { $result = []; try { - $option_group_id = civicrm_api3( - 'CustomField', - 'getsingle', - ['id' => $this->id] - )['option_group_id']; - } catch (CiviCRM_API3_Exception $e) { - $errorMessage = $e->getMessage(); - Civi::log() - ->error("$this->extensionName could not get get option group id for custom field \"$this->name\": $errorMessage"); - CRM_Utils_System::setUFMessage( - E::ts('%1 could not get option group id for custom field \'%2\'. Find more information in the logs.', - [1 => $this->extensionName, 2 => $this->name]) - ); - } - - try { - foreach ($options as $key => $value) { + foreach ($this->option_values as $key => $value) { $option_value_exists = civicrm_api3( 'OptionValue', 'get', [ 'sequential' => 1, - 'option_group_id' => $option_group_id, + 'option_group_id' => $options['option_group_id'], 'value' => $key, ] ); @@ -222,7 +229,7 @@ class CRM_TwingleCampaign_BAO_CustomField { 'OptionValue', 'create', [ - 'option_group_id' => $option_group_id, + 'option_group_id' => $options['option_group_id'], 'value' => $key, 'label' => $value, ] @@ -347,12 +354,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']"); } } @@ -496,4 +503,4 @@ class CRM_TwingleCampaign_BAO_CustomField { $this->option_values = $option_values; } -} \ No newline at end of file +} From 82b4632d63aa6a502888d32e92508d63a21588b5 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 16:16:50 +0200 Subject: [PATCH 37/52] implement matomo integration --- CRM/TwingleCampaign/BAO/Configuration.php | 11 ++- CRM/TwingleCampaign/Form/Settings.php | 7 ++ CRM/TwingleCampaign/Utils/MatomoSnippet.php | 75 +++++++++++++++++++ api/v3/TwingleForm/Get.php | 42 ++++++++++- .../CRM/TwingleCampaign/Form/Settings.tpl | 5 ++ 5 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 CRM/TwingleCampaign/Utils/MatomoSnippet.php diff --git a/CRM/TwingleCampaign/BAO/Configuration.php b/CRM/TwingleCampaign/BAO/Configuration.php index 6d2614e..4d26232 100644 --- a/CRM/TwingleCampaign/BAO/Configuration.php +++ b/CRM/TwingleCampaign/BAO/Configuration.php @@ -7,7 +7,8 @@ class CRM_TwingleCampaign_BAO_Configuration { 'twingle_api_key', 'twinglecampaign_xcm_profile', 'twinglecampaign_default_case', - 'twinglecampaign_soft_credits' + 'twinglecampaign_soft_credits', + 'twinglecampaign_matomo_integration' ]; @@ -27,6 +28,12 @@ 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); } @@ -63,4 +70,4 @@ class CRM_TwingleCampaign_BAO_Configuration { } } -} \ No newline at end of file +} diff --git a/CRM/TwingleCampaign/Form/Settings.php b/CRM/TwingleCampaign/Form/Settings.php index f614ce5..5b599e0 100644 --- a/CRM/TwingleCampaign/Form/Settings.php +++ b/CRM/TwingleCampaign/Form/Settings.php @@ -46,6 +46,13 @@ 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', diff --git a/CRM/TwingleCampaign/Utils/MatomoSnippet.php b/CRM/TwingleCampaign/Utils/MatomoSnippet.php new file mode 100644 index 0000000..79fd3ec --- /dev/null +++ b/CRM/TwingleCampaign/Utils/MatomoSnippet.php @@ -0,0 +1,75 @@ +", + "", + "", + ]); + } + + /** + * 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 . '\n' . $appendix; + } + +} diff --git a/api/v3/TwingleForm/Get.php b/api/v3/TwingleForm/Get.php index 6adaf2e..86a5475 100644 --- a/api/v3/TwingleForm/Get.php +++ b/api/v3/TwingleForm/Get.php @@ -2,6 +2,7 @@ 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) @@ -110,16 +111,49 @@ 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': - $returnValues[$value['id']]['embed_code'] = - $value[$custom_field_mapping['twingle_project_eventall']]; + 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']]; + } break; default: - $returnValues[$value['id']]['embed_code'] = - $value[$custom_field_mapping['twingle_project_widget']]; + 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']]; + } } } + return civicrm_api3_create_success($returnValues, $query, 'TwingleForm', 'Get'); } else { diff --git a/templates/CRM/TwingleCampaign/Form/Settings.tpl b/templates/CRM/TwingleCampaign/Form/Settings.tpl index a7c7c14..288c13e 100644 --- a/templates/CRM/TwingleCampaign/Form/Settings.tpl +++ b/templates/CRM/TwingleCampaign/Form/Settings.tpl @@ -26,6 +26,11 @@

{$form.twinglecampaign_soft_credits.html}
+
+
{$form.twinglecampaign_matomo_integration.label}
+
{$form.twinglecampaign_matomo_integration.html}
+
+
From de19c3991cfc2aba35ccd98f9dede4fa8796b3d6 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 16:18:56 +0200 Subject: [PATCH 38/52] =?UTF-8?q?=F0=9F=94=96=20bump=20version=20to=201.0.?= =?UTF-8?q?4-dev?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/Upgrader.php | 81 +------------------------------- info.xml | 4 +- 2 files changed, 3 insertions(+), 82 deletions(-) diff --git a/CRM/TwingleCampaign/Upgrader.php b/CRM/TwingleCampaign/Upgrader.php index 5c1a706..09e7401 100644 --- a/CRM/TwingleCampaign/Upgrader.php +++ b/CRM/TwingleCampaign/Upgrader.php @@ -20,7 +20,7 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base { * changed campaigns will get pulled from Twingle. * @throws \CiviCRM_API3_Exception */ - public function upgrade_02(): bool { + public function upgrade_03(): bool { $campaign_info = require E::path() . '/CRM/TwingleCampaign/resources/campaigns.php'; @@ -294,83 +294,4 @@ 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; - * } // */ - } diff --git a/info.xml b/info.xml index b7ae3af..415f6ed 100644 --- a/info.xml +++ b/info.xml @@ -15,8 +15,8 @@ http://www.gnu.org/licenses/agpl-3.0.html 2023-02-28 - 1.0.3 - stable + 1.0.4-dev + dev 5.14.0 From c45f275fc3cf863be3c31a714f542233c9e7d17c Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 16:50:25 +0200 Subject: [PATCH 39/52] =?UTF-8?q?=F0=9F=90=9B=20bug=20fix:=20do=20not=20cr?= =?UTF-8?q?eate=20empty=20option=20values?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/CustomField.php | 1 + CRM/TwingleCampaign/Utils/CaseTypes.php | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index 9666d30..edeb505 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -243,6 +243,7 @@ class CRM_TwingleCampaign_BAO_CustomField { [ 'id' => $option_value_exists['values'][0]['id'], 'label' => $value, + 'value' => $value, ] ); } diff --git a/CRM/TwingleCampaign/Utils/CaseTypes.php b/CRM/TwingleCampaign/Utils/CaseTypes.php index 312a23f..b05282c 100644 --- a/CRM/TwingleCampaign/Utils/CaseTypes.php +++ b/CRM/TwingleCampaign/Utils/CaseTypes.php @@ -8,7 +8,6 @@ use CRM_TwingleCampaign_ExtensionUtil as E; * @return array */ function getCaseTypes(): array { - $caseTypes = [NULL => E::ts('none')]; try { $result = civicrm_api3('CaseType', 'get', [ 'sequential' => 1, From 8863bbeed0df8a718ace6477c75ad9ccf0fec268 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 16:53:47 +0200 Subject: [PATCH 40/52] =?UTF-8?q?=F0=9F=94=96=20bump=20version=20to=201.0.?= =?UTF-8?q?4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- info.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/info.xml b/info.xml index 415f6ed..ee812cb 100644 --- a/info.xml +++ b/info.xml @@ -15,8 +15,8 @@ http://www.gnu.org/licenses/agpl-3.0.html 2023-02-28 - 1.0.4-dev - dev + 1.0.4 + stable 5.14.0 From e5ab52f24b402d4925e42c72d6ef8160bfc8570f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 17:20:24 +0200 Subject: [PATCH 41/52] =?UTF-8?q?=F0=9F=90=9B=20fix=20bug:=20double=20esca?= =?UTF-8?q?ping=20of=20`\n`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/Utils/MatomoSnippet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/Utils/MatomoSnippet.php b/CRM/TwingleCampaign/Utils/MatomoSnippet.php index 79fd3ec..f6b62af 100644 --- a/CRM/TwingleCampaign/Utils/MatomoSnippet.php +++ b/CRM/TwingleCampaign/Utils/MatomoSnippet.php @@ -69,7 +69,7 @@ class CRM_TwingleCampaign_Utils_MatomoSnippet { * The combined code after appending the appendix. */ public static function append_code($original, $appendix) { - return $original . '\n' . $appendix; + return $original . $appendix; } } From dc723ed8aa803002ba202022c21b8a2f886633a3 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 17:45:19 +0200 Subject: [PATCH 42/52] =?UTF-8?q?=F0=9F=90=9B=20bug=20fix:=20wrong=20value?= =?UTF-8?q?=20for=20option=20values?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/CustomField.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index edeb505..da2c824 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -243,7 +243,7 @@ class CRM_TwingleCampaign_BAO_CustomField { [ 'id' => $option_value_exists['values'][0]['id'], 'label' => $value, - 'value' => $value, + 'value' => $key, ] ); } From 571a86ea66bd47b0abe59719c6fad3418e0a7622 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 14 Aug 2023 18:44:36 +0200 Subject: [PATCH 43/52] =?UTF-8?q?=F0=9F=94=96=20bump=20version=20to=201.0.?= =?UTF-8?q?5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index ee812cb..af3474b 100644 --- a/info.xml +++ b/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2023-02-28 - 1.0.4 + 1.0.5 stable 5.14.0 From bcd2b448d21c8c17265ce27e8e57912949750e2d Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 8 Apr 2024 12:18:57 +0200 Subject: [PATCH 44/52] fix udefined constant "error" --- CRM/TwingleCampaign/Upgrader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/Upgrader.php b/CRM/TwingleCampaign/Upgrader.php index 09e7401..f103551 100644 --- a/CRM/TwingleCampaign/Upgrader.php +++ b/CRM/TwingleCampaign/Upgrader.php @@ -96,7 +96,7 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base { [1 => $e->getMessage()] ), E::ts('Scheduled Job'), - error + 'error' ); } From db1ab691388b20372361cfa75de64406f0c96072 Mon Sep 17 00:00:00 2001 From: Dominic Tubach Date: Fri, 19 Apr 2024 10:15:55 +0200 Subject: [PATCH 45/52] APIWrapper: Make `mapDonation()` static becauts it's called static --- CRM/TwingleCampaign/Utils/APIWrapper.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CRM/TwingleCampaign/Utils/APIWrapper.php b/CRM/TwingleCampaign/Utils/APIWrapper.php index 5afe426..4397aa1 100644 --- a/CRM/TwingleCampaign/Utils/APIWrapper.php +++ b/CRM/TwingleCampaign/Utils/APIWrapper.php @@ -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 $apiRequest - * @param $callsame + * @param array $apiRequest + * @param callable $callsame * * @return mixed */ - public function mapDonation($apiRequest, $callsame) { + public static function mapDonation(array $apiRequest, callable $callsame) { if (array_key_exists( 'campaign_id', @@ -207,4 +207,4 @@ class CRM_TwingleCampaign_Utils_APIWrapper { } } -} \ No newline at end of file +} From 9118b622d04beada2fd126f9051ea9b609fecf98 Mon Sep 17 00:00:00 2001 From: Dominic Tubach Date: Fri, 19 Apr 2024 10:29:04 +0200 Subject: [PATCH 46/52] APIWrapper: Rethrow exception --- CRM/TwingleCampaign/Utils/APIWrapper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CRM/TwingleCampaign/Utils/APIWrapper.php b/CRM/TwingleCampaign/Utils/APIWrapper.php index 5afe426..c9c5d68 100644 --- a/CRM/TwingleCampaign/Utils/APIWrapper.php +++ b/CRM/TwingleCampaign/Utils/APIWrapper.php @@ -204,7 +204,9 @@ class CRM_TwingleCampaign_Utils_APIWrapper { 'contribution_id' => $contribution['id'], ] ); + + throw $e; } } -} \ No newline at end of file +} From cbb148b22fe29d6ae9541cd3acf255c02090c549 Mon Sep 17 00:00:00 2001 From: Dominic Tubach Date: Mon, 22 Apr 2024 10:10:51 +0200 Subject: [PATCH 47/52] Avoid `array_key_exists()` on `NULL` --- CRM/TwingleCampaign/Utils/APIWrapper.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CRM/TwingleCampaign/Utils/APIWrapper.php b/CRM/TwingleCampaign/Utils/APIWrapper.php index 5afe426..932a88d 100644 --- a/CRM/TwingleCampaign/Utils/APIWrapper.php +++ b/CRM/TwingleCampaign/Utils/APIWrapper.php @@ -129,11 +129,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper { } } } - elseif (array_key_exists( - 'event', - $apiRequest['params']['custom_fields']) && - !empty($apiRequest['params']['custom_fields']['event']) - ) { + elseif (!empty($apiRequest['params']['custom_fields']['event'])) { try { $targetCampaign = civicrm_api3( 'TwingleEvent', From beb9d8f170d39a2b7947d1bbe6aeee9a0869ea10 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Sat, 15 Jun 2024 11:36:12 +0200 Subject: [PATCH 48/52] take into account the latest changes to the Twingle API --- .../Exceptions/TwingleCampaignException.php | 4 ++-- CRM/TwingleCampaign/Utils/APIWrapper.php | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php b/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php index 0f99555..61baf6b 100644 --- a/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php +++ b/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php @@ -1,8 +1,8 @@ $contribution['campaign_id']] ); - $response['values']['soft_credit'] = + $response['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['values'])) { - $sepa_mandate = array_pop($response_copy['values']['sepa_mandate']); + elseif (array_key_exists('sepa_mandate', $response)) { + $sepa_mandate = array_pop($response_copy['sepa_mandate']); try { $contribution = civicrm_api3( @@ -84,7 +84,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper { 'getsingle', ['id' => $contribution['contribution_campaign_id']] ); - $response['values']['soft_credit'] = + $response['soft_credit'] = self::createSoftCredit($contribution, $twingle_event)['values']; $event->setResponse($response); } catch (CiviCRM_API3_Exception $e) { From de9cd894b71319d7c611eb648af026f9166b58fb Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Sat, 15 Jun 2024 12:12:35 +0200 Subject: [PATCH 49/52] =?UTF-8?q?=F0=9F=94=96=20bump=20version=20to=201.0.?= =?UTF-8?q?7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- info.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/info.xml b/info.xml index af3474b..1b5cc69 100644 --- a/info.xml +++ b/info.xml @@ -14,13 +14,12 @@ https://lab.civicrm.org/Marc_Michalsky/de-forumzfd-twinglecampaign/-/issues http://www.gnu.org/licenses/agpl-3.0.html - 2023-02-28 - 1.0.5 + 2024-06-15 + 1.0.7 stable - 5.14.0 + 5.74 - de.systopia.xcm de.systopia.campaign From 91c70c645a267175c83f84e71eae68d0feebef45 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 18 Jul 2024 15:35:31 +0200 Subject: [PATCH 50/52] Push only active campaigns to Twingle --- api/v3/TwingleProject/Sync.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index aed3d2a..ca72d0e 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -193,8 +193,8 @@ function civicrm_api3_twingle_project_Sync(array $params): array { foreach ($projects_from_civicrm['values'] as $project_from_civicrm) { if ( !in_array($project_from_civicrm['project_id'], - array_column($projects_from_twingle, 'id') - )) { + array_column($projects_from_twingle, 'id'), + ) && $project_from_civicrm['is_active'] == 1) { // store campaign id in $id $id = $project_from_civicrm['id']; unset($project_from_civicrm['id']); From 7415fac88d697df94e68470d9c225c8eadb6b577 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 18 Jul 2024 15:37:30 +0200 Subject: [PATCH 51/52] Cover the case where an event creator passes only one name part --- CRM/TwingleCampaign/BAO/TwingleEvent.php | 6 ++++-- CRM/TwingleCampaign/Utils/StringOperations.php | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleEvent.php b/CRM/TwingleCampaign/BAO/TwingleEvent.php index 4248c1d..faf609b 100644 --- a/CRM/TwingleCampaign/BAO/TwingleEvent.php +++ b/CRM/TwingleCampaign/BAO/TwingleEvent.php @@ -219,13 +219,15 @@ 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']; - $lastname = $names['lastname']; + $firstnames = $names['firstnames'] ?? NULL; + $lastname = $names['lastname'] ?? NULL; + $display_name = $names['display_name'] ?? NULL; 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']; diff --git a/CRM/TwingleCampaign/Utils/StringOperations.php b/CRM/TwingleCampaign/Utils/StringOperations.php index 19c0fd3..98e6657 100644 --- a/CRM/TwingleCampaign/Utils/StringOperations.php +++ b/CRM/TwingleCampaign/Utils/StringOperations.php @@ -49,7 +49,7 @@ class CRM_TwingleCampaign_Utils_StringOperations { $firstnames = implode(" ", $names); return ['firstnames' => $firstnames, 'lastname' => $lastname]; } - return $string; + return ['display_name' => $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; } -} \ No newline at end of file +} From 012f4901e4c1fa4ce9c42ff5ec0958018affd1be Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 18 Jul 2024 15:38:42 +0200 Subject: [PATCH 52/52] =?UTF-8?q?=F0=9F=94=96=20bump=20version=20to=201.0.?= =?UTF-8?q?8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index 1b5cc69..7971b85 100644 --- a/info.xml +++ b/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html 2024-06-15 - 1.0.7 + 1.0.8 stable 5.74