From dfaf46b8f49555b6271e70793060db047e9d3bdf Mon Sep 17 00:00:00 2001 From: Mikey O'Toole Date: Mon, 13 Apr 2020 14:48:51 +0100 Subject: [PATCH 001/221] MkDocs upgrade fix. --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index dc51ca6..e002b42 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,7 +2,7 @@ site_name: Twingle API repo_url: https://github.com/systopia/de.systopia.twingle theme: material -pages: +nav: - 'Home': index.md markdown_extensions: From d4a0120843ea65b8f08a8825a27b592ec57f29b4 Mon Sep 17 00:00:00 2001 From: Mikey O'Toole Date: Mon, 13 Apr 2020 16:37:21 +0100 Subject: [PATCH 002/221] Update mkdocs.yml --- mkdocs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index e002b42..4230310 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,7 @@ site_name: Twingle API repo_url: https://github.com/systopia/de.systopia.twingle -theme: material +theme: + name: material nav: - 'Home': index.md From ceb1f5a7536ba2a45617535c63e5d7124ff75ebd Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 19 May 2020 10:19:12 +0200 Subject: [PATCH 003/221] Back to 1.2-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index bab9d81..f4918e7 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2020-05-19 - 1.2-alpha2 - alpha + + 1.2-dev + dev 5.0 5.19 From 9b5165f5a6ed65b81d776048642d884835bdb063 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Sun, 24 May 2020 18:57:19 +0200 Subject: [PATCH 004/221] [#20] fixed exception handling --- api/v3/TwingleDonation/Cancel.php | 2 +- api/v3/TwingleDonation/Endrecurring.php | 2 +- api/v3/TwingleDonation/Submit.php | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/api/v3/TwingleDonation/Cancel.php b/api/v3/TwingleDonation/Cancel.php index d2bba26..e3dee49 100644 --- a/api/v3/TwingleDonation/Cancel.php +++ b/api/v3/TwingleDonation/Cancel.php @@ -150,7 +150,7 @@ function civicrm_api3_twingle_donation_Cancel($params) { $result = civicrm_api3_create_success($contribution); } - catch (CiviCRM_API3_Exception $exception) { + catch (Exception $exception) { $result = civicrm_api3_create_error($exception->getMessage()); } diff --git a/api/v3/TwingleDonation/Endrecurring.php b/api/v3/TwingleDonation/Endrecurring.php index 318b115..12c93c4 100644 --- a/api/v3/TwingleDonation/Endrecurring.php +++ b/api/v3/TwingleDonation/Endrecurring.php @@ -139,7 +139,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) { $result = civicrm_api3_create_success($contribution); } - catch (CiviCRM_API3_Exception $exception) { + catch (Exception $exception) { $result = civicrm_api3_create_error($exception->getMessage()); } diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 1b63b5c..1fe0d91 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -701,14 +701,16 @@ function civicrm_api3_twingle_donation_Submit($params) { } catch (Exception $ex) { // TODO: more error handling? Civi::log()->debug("Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()); + throw new Exception( + E::ts("Twingle membership postprocessing call has failed, see log for more information") + ); } } - } $result = civicrm_api3_create_success($result_values); } - catch (CiviCRM_API3_Exception $exception) { + catch (Exception $exception) { $result = civicrm_api3_create_error($exception->getMessage()); } From cc048fdd3c7fd58086efd6f66b220b5910bafc8d Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Sun, 24 May 2020 19:08:22 +0200 Subject: [PATCH 005/221] [#20] make sure recurring contribution ID also present if SEPA mandate --- api/v3/TwingleDonation/Submit.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 1fe0d91..c1e0f5a 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -681,13 +681,15 @@ function civicrm_api3_twingle_donation_Submit($params) { $recurring_contribution_id = $contribution_id = ''; if (isset($contribution_recur['id'])) { $recurring_contribution_id = $contribution_recur['id']; + } elseif (!empty($mandate['entity_id']) && $mandate['type'] == 'RCUR') { + $recurring_contribution_id = $mandate['entity_id']; } if (isset($contribution['id'])) { $contribution_id = $contribution['id']; } // run the call - civicrm_api3($pp_entity, $pp_action, [ + civicrm_api3(trim($pp_entity), trim($pp_action), [ 'membership_id' => $membership['id'], 'contact_id' => $contact_id, 'organization_id' => isset($organisation_id) ? $organisation_id : '', From ad8fb0eee76048775161fdb7a8389c4acf1e6de6 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Sun, 24 May 2020 19:47:11 +0200 Subject: [PATCH 006/221] [#24] added option to drop twingle mandate reference --- CRM/Twingle/Form/Settings.php | 7 +++++++ api/v3/TwingleDonation/Submit.php | 6 ++++++ templates/CRM/Twingle/Form/Settings.hlp | 4 ++++ templates/CRM/Twingle/Form/Settings.tpl | 12 ++++++++++++ 4 files changed, 29 insertions(+) diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index b85fe5e..dba6a28 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -28,6 +28,7 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { public static $SETTINGS_LIST = [ 'twingle_prefix', 'twingle_use_sepa', + 'twingle_dont_use_reference', 'twingle_protect_recurring', 'twingle_protect_recurring_activity_type', 'twingle_protect_recurring_activity_subject', @@ -54,6 +55,12 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { E::ts("Use CiviSEPA") ); + $this->add( + 'checkbox', + 'twingle_dont_use_reference', + E::ts("Use CiviSEPA generated reference") + ); + $this->add( 'select', 'twingle_protect_recurring', diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 57793d6..8828c82 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -604,6 +604,12 @@ function civicrm_api3_twingle_donation_Submit($params) { // mandate type. unset($mandate_data['payment_instrument_id']); + // If requested, let CiviSEPA generate the mandate reference + $use_own_mandate_reference = Civi::settings()->get('twingle_dont_use_reference'); + if (!empty($use_own_mandate_reference)) { + unset($mandate_data['reference']); + } + // Create the mandate. $mandate = civicrm_api3('SepaMandate', 'createfull', $mandate_data); diff --git a/templates/CRM/Twingle/Form/Settings.hlp b/templates/CRM/Twingle/Form/Settings.hlp index 8b5ef1b..7b82e7b 100644 --- a/templates/CRM/Twingle/Form/Settings.hlp +++ b/templates/CRM/Twingle/Form/Settings.hlp @@ -16,6 +16,10 @@ {ts domain="de.systopia.twingle" 1="CiviSEPA (org.project60.sepa) extension"}When the %1 is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the debit_manual payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data.{/ts} {/htxt} +{htxt id='id-twingle_dont_use_reference'} + {ts domain="de.systopia.twingle" 1="CiviSEPA (org.project60.sepa) extension"}When the %1 is enabled, you can activate this to use your own references instead of the ones submitted by Twingle.{/ts} +{/htxt} + {htxt id='id-twingle_protect_recurring'} {ts domain="de.systopia.twingle"}Will protect all recurring contributions created by Twingle from termination, since this does NOT terminate the Twingle collection process{/ts} {/htxt} diff --git a/templates/CRM/Twingle/Form/Settings.tpl b/templates/CRM/Twingle/Form/Settings.tpl index 49d068e..e5fa54f 100644 --- a/templates/CRM/Twingle/Form/Settings.tpl +++ b/templates/CRM/Twingle/Form/Settings.tpl @@ -28,6 +28,18 @@ + + {$form.twingle_dont_use_reference.label}   + + {$form.twingle_dont_use_reference.html} +
+ + {$formElements.twingle_dont_use_reference.description} + + + + + {$form.twingle_prefix.label}   From db9c53bd103057860480d96a2378ae7b46025400 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Sun, 24 May 2020 20:26:10 +0200 Subject: [PATCH 007/221] [#20] fixes for mandate ref / postprocessing --- api/v3/TwingleDonation/Submit.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 57793d6..c961cdb 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -707,8 +707,16 @@ function civicrm_api3_twingle_donation_Submit($params) { $recurring_contribution_id = $contribution_id = ''; if (isset($contribution_recur['id'])) { $recurring_contribution_id = $contribution_recur['id']; - } elseif (!empty($mandate['entity_id']) && $mandate['type'] == 'RCUR') { - $recurring_contribution_id = $mandate['entity_id']; + } elseif (!empty($mandate['id'])) { + // load mandate and see... + try { + $mandate_created = civicrm_api3('SepaMandate', 'getsingle', ['id' => $mandate['id']]); + if ($mandate_created['entity_table'] == 'civicrm_contribution_recur') { + $recurring_contribution_id = $mandate['entity_id']; + } + } catch(CiviCRM_API3_Exception $ex) { + Civi::log()->warning("Couldn't load SepaMandate with id '{$mandate['id']}'."); + } } if (isset($contribution['id'])) { $contribution_id = $contribution['id']; @@ -724,7 +732,7 @@ function civicrm_api3_twingle_donation_Submit($params) { ]); // refresh membership data - $result_values['membership'] = civicrm_api3('Membership', 'getsingle', $membership['id']); + $result_values['membership'] = civicrm_api3('Membership', 'getsingle', ['id' => $membership['id']]); } catch (Exception $ex) { // TODO: more error handling? From 30a0b81c8b08442743d58fdffd663fd3806afc71 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Sun, 24 May 2020 20:39:47 +0200 Subject: [PATCH 008/221] [#20] fixes for mandate ref / postprocessing --- api/v3/TwingleDonation/Submit.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index c961cdb..74204bd 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -707,16 +707,8 @@ function civicrm_api3_twingle_donation_Submit($params) { $recurring_contribution_id = $contribution_id = ''; if (isset($contribution_recur['id'])) { $recurring_contribution_id = $contribution_recur['id']; - } elseif (!empty($mandate['id'])) { - // load mandate and see... - try { - $mandate_created = civicrm_api3('SepaMandate', 'getsingle', ['id' => $mandate['id']]); - if ($mandate_created['entity_table'] == 'civicrm_contribution_recur') { - $recurring_contribution_id = $mandate['entity_id']; - } - } catch(CiviCRM_API3_Exception $ex) { - Civi::log()->warning("Couldn't load SepaMandate with id '{$mandate['id']}'."); - } + } elseif (!empty($result_values['sepa_mandate']['entity_id'])) { + $recurring_contribution_id = (int) $result_values['sepa_mandate']['entity_id']; } if (isset($contribution['id'])) { $contribution_id = $contribution['id']; @@ -734,7 +726,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // refresh membership data $result_values['membership'] = civicrm_api3('Membership', 'getsingle', ['id' => $membership['id']]); - } catch (Exception $ex) { + } catch (CiviCRM_API3_Exception $ex) { // TODO: more error handling? Civi::log()->debug("Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()); throw new Exception( From 84fe5137c1bc8d922a2296d4b88b9a5243861514 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Sun, 24 May 2020 20:44:17 +0200 Subject: [PATCH 009/221] [#20] fixes for mandate ref / postprocessing --- api/v3/TwingleDonation/Submit.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 74204bd..d0e4299 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -707,8 +707,11 @@ function civicrm_api3_twingle_donation_Submit($params) { $recurring_contribution_id = $contribution_id = ''; if (isset($contribution_recur['id'])) { $recurring_contribution_id = $contribution_recur['id']; - } elseif (!empty($result_values['sepa_mandate']['entity_id'])) { - $recurring_contribution_id = (int) $result_values['sepa_mandate']['entity_id']; + } elseif (!empty($result_values['sepa_mandate'])) { + $mandate = reset($result_values['sepa_mandate']); + if ($mandate['entity_table'] == 'civicrm_contribution_recur') { + $recurring_contribution_id = (int) $mandate['entity_id']; + } } if (isset($contribution['id'])) { $contribution_id = $contribution['id']; From b269868c660937c6c6ca75a29bf6632093f09f0a Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Tue, 26 May 2020 11:48:48 +0200 Subject: [PATCH 010/221] [#26] set membership campaign --- api/v3/TwingleDonation/Submit.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 5856996..7ef07fb 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -692,10 +692,15 @@ function civicrm_api3_twingle_donation_Submit($params) { $membership_type_id = $profile->getAttribute('membership_type_id'); } if (!empty($membership_type_id)) { - $membership = civicrm_api3('Membership', 'create', array( - 'contact_id' => $contact_id, - 'membership_type_id' => $membership_type_id, - )); + // create the membership + $membership_data = [ + 'contact_id' => $contact_id, + 'membership_type_id' => $membership_type_id, + ]; + if (!empty($params['campaign_id'])) { + $membership_data['campaign_id'] = $params['campaign_id']; + } + $membership = civicrm_api3('Membership', 'create', $membership_data); $result_values['membership'] = $membership; // call the postprocess API From a8fef68799c9eeb921cfc66eba251f900201754d Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Tue, 26 May 2020 12:08:46 +0200 Subject: [PATCH 011/221] [#26] set membership campaign --- api/v3/TwingleDonation/Submit.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 7ef07fb..6003858 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -697,8 +697,11 @@ function civicrm_api3_twingle_donation_Submit($params) { 'contact_id' => $contact_id, 'membership_type_id' => $membership_type_id, ]; + // set campaign if (!empty($params['campaign_id'])) { $membership_data['campaign_id'] = $params['campaign_id']; + } elseif (!empty($campaign = $profile->getAttribute('campaign'))) { + $membership_data['campaign_id'] = $campaign; } $membership = civicrm_api3('Membership', 'create', $membership_data); $result_values['membership'] = $membership; From 35cf2f80e2d6df156c5f7452ab24b81e2d28581a Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Thu, 4 Jun 2020 10:37:01 +0200 Subject: [PATCH 012/221] [#27] implementing campaign options --- CRM/Twingle/Form/Profile.php | 23 ++++++++++++-- CRM/Twingle/Profile.php | 2 ++ CRM/Twingle/Submission.php | 44 ++++++++++++++++++++++---- CRM/Twingle/Tools.php | 6 ++-- api/v3/TwingleDonation/Submit.php | 42 ++++++++++++++---------- templates/CRM/Twingle/Form/Profile.tpl | 5 +++ 6 files changed, 95 insertions(+), 27 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index ea83455..57bfa17 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -357,12 +357,26 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->add( 'select', // field type 'campaign', // field name - E::ts('Campaign (e.g. for donation)'), // field label + E::ts('Default Campaign'), // field label array('' => E::ts('- none -')) + static::getCampaigns(), // list of options FALSE, // is not required array('class' => 'crm-select2 huge') ); + $this->add( + 'select', + 'campaign_targets', + E::ts('Set Campaign for'), + [ + 'contribution' => E::ts("Contribution"), + 'recurring' => E::ts("Recurring Contribution"), + 'membership' => E::ts("Membership"), + 'mandate' => E::ts("SEPA Mandate"), + ], + FALSE, // is not required + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] + ); + $this->add( 'select', // field type 'membership_type_id', // field name @@ -511,9 +525,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $defaults = parent::setDefaultValues(); if (in_array($this->_op, array('create', 'edit'))) { $defaults['name'] = $this->profile->getName(); - foreach ($this->profile->getData() as $element_name => $value) { + $profile_data = $this->profile->getData(); + foreach ($profile_data as $element_name => $value) { $defaults[$element_name] = $value; } + // backwards compatibility, see issue #27 + if (!isset($profile_data['campaign_targets'])) { + $defaults['campaign_targets'] = ['contribution', 'contact']; + } } return $defaults; } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index e61f4df..be93bc6 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -215,6 +215,7 @@ class CRM_Twingle_Profile { 'postinfo_groups', 'donation_receipt_groups', 'campaign', + 'campaign_targets', 'contribution_source', 'custom_field_mapping', 'membership_type_id', @@ -287,6 +288,7 @@ class CRM_Twingle_Profile { 'postinfo_groups' => NULL, 'donation_receipt_groups' => NULL, 'campaign' => NULL, + 'campaign_targets' => ['contribution', 'contact'], 'contribution_source' => NULL, 'custom_field_mapping' => NULL, 'membership_type_id' => NULL, diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index ddd239e..281545c 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -129,6 +129,8 @@ class CRM_Twingle_Submission { * Data to use for contact lookup/to create a contact with. * @param CRM_Twingle_Profile $profile * Profile used for this process + * @param array $submission + * Submission data * * @return int | NULL * The ID of the matching/created contact, or NULL if no matching contact @@ -136,7 +138,7 @@ class CRM_Twingle_Submission { * @throws \CiviCRM_API3_Exception * When invalid data was given. */ - public static function getContact($contact_type, $contact_data, $profile) { + public static function getContact($contact_type, $contact_data, $profile, $submission = []) { // If no parameters are given, do nothing. if (empty($contact_data)) { return NULL; @@ -148,11 +150,8 @@ class CRM_Twingle_Submission { $contact_data['xcm_profile'] = $xcm_profile; } - // add campaign - $campaign_id = (int) $profile->getAttribute('campaign'); - if ($campaign_id) { - $contact_data['campaign_id'] = $campaign_id; - } + // add campaign, see issue #17 + CRM_Twingle_Submission::setCampaign($contact_data, 'contact', $submission, $profile); // Prepare values: country. if (!empty($contact_data['country'])) { @@ -354,4 +353,37 @@ class CRM_Twingle_Submission { return date('j', $earliest_cycle_day); } + /** + * Will set the campaign_id to the entity_data set, if the + * profile is configured to do so. In that case the campaign is taken + * from the submission data. Should that be empty, the profile's default + * campaign is used. + * + * @param array $entity_data + * the data set where the campaign_id should be set + * @param string $context + * defines the type of the entity_data: one of 'contribution', 'membership','mandate', 'recurring', 'contact' + * @param array $submission + * the submitted data + * @param CRM_Twingle_Profile $profile + * the twingle profile used + */ + public static function setCampaign(&$entity_data, $context, $submission, $profile) { + $enabled_contexts = $profile->getAttribute('campaign_targets'); + if ($enabled_contexts === null || !is_array($enabled_contexts)) { + // backward compatibility: + $enabled_contexts = ['contribution', 'contact']; + } + + // check if campaign should be set it this context + if (in_array($context, $enabled_contexts)) { + // use the submitted campaign if set + if (!empty($submission['campaign_id'])) { + $entity_data['campaign_id'] = $submission['campaign_id']; + } // otherwise use the profile's + elseif (!empty($campaign = $profile->getAttribute('campaign'))) { + $entity_data['campaign_id'] = $campaign; + } + } + } } diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php index bb3bbb5..86cd828 100644 --- a/CRM/Twingle/Tools.php +++ b/CRM/Twingle/Tools.php @@ -137,12 +137,12 @@ class CRM_Twingle_Tools { 'source_contact_id' => CRM_Core_Session::getLoggedInContactID(), ]); } catch (Exception $ex) { - Civi::log()->debug("TwingleAPI: Couldn't create recurring protection activity: " . $ex->getMessage()); + Civi::log()->warning("TwingleAPI: Couldn't create recurring protection activity: " . $ex->getMessage()); } break; default: - Civi::log()->debug("TwingleAPI: Unknown recurring contribution protection mode: '{$protection_mode}'"); + Civi::log()->warning("TwingleAPI: Unknown recurring contribution protection mode: '{$protection_mode}'"); break; } } @@ -203,7 +203,7 @@ class CRM_Twingle_Tools { return reset($ooff_mandate['values']); } } catch (Exception $ex) { - Civi::log()->debug("CRM_Twingle_Tools::getMandate failed for [{$contribution_id}]: " . $ex->getMessage()); + Civi::log()->warning("CRM_Twingle_Tools::getMandate failed for [{$contribution_id}]: " . $ex->getMessage()); } } return NULL; diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 6003858..2f3c990 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -403,7 +403,8 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!$contact_id = CRM_Twingle_Submission::getContact( 'Individual', $contact_data, - $profile + $profile, + $params )) { throw new CiviCRM_API3_Exception( E::ts('Individual contact could not be found or created.'), @@ -439,7 +440,8 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!$organisation_id = CRM_Twingle_Submission::getContact( 'Organization', $organisation_data, - $profile + $profile, + $params )) { throw new CiviCRM_API3_Exception( E::ts('Organisation contact could not be found or created.'), @@ -466,7 +468,9 @@ function civicrm_api3_twingle_donation_Submit($params) { CRM_Twingle_Submission::getContact( 'Individual', array('id' => $contact_id) + $submitted_address, - $profile); + $profile, + $params + ); } // Create employer relationship between organization and individual. @@ -537,12 +541,8 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution_data['note'] = $params['purpose']; } - if (!empty($params['campaign_id'])) { - $contribution_data['campaign_id'] = $params['campaign_id']; - } - elseif (!empty($campaign = $profile->getAttribute('campaign'))) { - $contribution_data['campaign_id'] = $campaign; - } + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($contribution_data, 'contribution', $params, $profile); if (!empty($contribution_source = $profile->getAttribute('contribution_source'))) { $contribution_data['source'] = $contribution_source; @@ -590,6 +590,9 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!empty($custom_fields['ContributionRecur'])) { $mandate_data += $custom_fields['ContributionRecur']; } + if (!empty($mandate_source = $profile->getAttribute('contribution_source'))) { + $mandate_data['source'] = $mandate_source; + } // Add cycle day for recurring contributions. if ($params['donation_rhythm'] != 'one_time') { @@ -604,6 +607,9 @@ function civicrm_api3_twingle_donation_Submit($params) { // mandate type. unset($mandate_data['payment_instrument_id']); + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($mandate_data, 'mandate', $params, $profile); + // Create the mandate. $mandate = civicrm_api3('SepaMandate', 'createfull', $mandate_data); @@ -641,7 +647,10 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution_data += $custom_fields['ContributionRecur']; } - $contribution_recur = civicrm_api3('contributionRecur', 'create', $contribution_recur_data); + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($contribution_data, 'recurring', $params, $profile); + + $contribution_recur = civicrm_api3('ContributionRecur', 'create', $contribution_recur_data); if ($contribution_recur['is_error']) { throw new CiviCRM_API3_Exception( E::ts('Could not create recurring contribution.'), @@ -697,12 +706,13 @@ function civicrm_api3_twingle_donation_Submit($params) { 'contact_id' => $contact_id, 'membership_type_id' => $membership_type_id, ]; - // set campaign - if (!empty($params['campaign_id'])) { - $membership_data['campaign_id'] = $params['campaign_id']; - } elseif (!empty($campaign = $profile->getAttribute('campaign'))) { - $membership_data['campaign_id'] = $campaign; + // set campaign, subject to configuration + CRM_Twingle_Submission::setCampaign($membership_data, 'membership', $params, $profile); + // set source + if (!empty($membership_source = $profile->getAttribute('contribution_source'))) { + $membership_data['source'] = $membership_source; } + $membership = civicrm_api3('Membership', 'create', $membership_data); $result_values['membership'] = $membership; @@ -734,7 +744,7 @@ function civicrm_api3_twingle_donation_Submit($params) { } catch (Exception $ex) { // TODO: more error handling? - Civi::log()->debug("Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()); + Civi::log()->warning("Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()); } } diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 17e0c87..708cb5a 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -228,6 +228,11 @@ {$form.campaign.html} + + {$form.campaign_targets.label} + {$form.campaign_targets.html} + + {$form.membership_type_id.label} {$form.membership_type_id.html} From b256b59fe5106b6dede6d12b3d7ef1ff2938556a Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Thu, 4 Jun 2020 10:48:56 +0200 Subject: [PATCH 013/221] [#27] added contact option --- CRM/Twingle/Form/Profile.php | 1 + 1 file changed, 1 insertion(+) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 57bfa17..a38dc7e 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -372,6 +372,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'recurring' => E::ts("Recurring Contribution"), 'membership' => E::ts("Membership"), 'mandate' => E::ts("SEPA Mandate"), + 'contact' => E::ts("Contacts (XCM)"), ], FALSE, // is not required ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] From 1d2c66b375206c5ea3419d0350f54ed6ced1c4db Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Thu, 4 Jun 2020 10:52:11 +0200 Subject: [PATCH 014/221] [#27] remove campaign if it somehow got it before --- CRM/Twingle/Submission.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 281545c..0daee20 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -369,13 +369,15 @@ class CRM_Twingle_Submission { * the twingle profile used */ public static function setCampaign(&$entity_data, $context, $submission, $profile) { + // first: make sure it's not set from other workflows + unset($entity_data['campaign_id']); + + // then: check if campaign should be set it this context $enabled_contexts = $profile->getAttribute('campaign_targets'); if ($enabled_contexts === null || !is_array($enabled_contexts)) { // backward compatibility: $enabled_contexts = ['contribution', 'contact']; } - - // check if campaign should be set it this context if (in_array($context, $enabled_contexts)) { // use the submitted campaign if set if (!empty($submission['campaign_id'])) { From 36a756e4dd599ed3613b7d575514903f97dd9271 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 4 Jun 2020 14:21:06 +0200 Subject: [PATCH 015/221] [#28] Add parameter for preferred language and pass to XCM --- CRM/Twingle/Submission.php | 8 ++++++++ api/v3/TwingleDonation/Submit.php | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index ddd239e..bf8efd0 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -177,6 +177,14 @@ class CRM_Twingle_Submission { } } + // Prepare values: language. + if (!empty($contact_data['preferred_language'])) { + $mapping = CRM_Core_I18n_PseudoConstant::longForShortMapping(); + // Override the default mapping for German. + $mapping['de'] = 'de_DE'; + $contact_data['preferred_language'] = $mapping[$contact_data['preferred_language']]; + } + // Pass to XCM. $contact_data['contact_type'] = $contact_type; $contact = civicrm_api3('Contact', 'getorcreate', $contact_data); diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 5856996..de8fee4 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -224,6 +224,13 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { 'api.required' => 0, 'description' => E::ts('The company of the contact.'), ); + $params['user_extrafield'] = array( + 'name' => 'user_language', + 'title' => E::ts('Language'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('The preferred language of the contact. A 2-digit ISO-639-1 language code.'), + ); $params['user_extrafield'] = array( 'name' => 'user_extrafield', 'title' => E::ts('User extra field'), @@ -376,6 +383,7 @@ function civicrm_api3_twingle_donation_Submit($params) { 'user_birthdate' => 'birth_date', 'user_email' => 'email', 'user_telephone' => 'phone', + 'user_language' => 'preferred_language', 'user_title' => 'formal_title', 'debit_iban' => 'iban', ) as $contact_param => $contact_component) { From 0d4688406955ff7656ad7d030bb4b66833ad320a Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 10 Jun 2020 11:57:21 +0200 Subject: [PATCH 016/221] Add link to Twingle FAQ on connecting with CiviCRM. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd5113d..e8c2a1d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,9 @@ The extension is licensed under ### Configure Twingle -*This section is yet to be completed.* +Please refer to the +[Twingle FAQ on using Twingle with CiviCRM](https://support.twingle.de/faq/de-de/9/46) +(currently only available in German). ### Configure Extended Contact Matcher (XCM) From 25a040f6d8cdcf1307d3ce834f6c550f9a1b14e7 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Mon, 15 Jun 2020 15:55:41 +0200 Subject: [PATCH 017/221] 1.2-beta1 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index f4918e7..4991bef 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.2-dev - dev + 2020-06-15 + 1.2-beta1 + beta 5.0 5.19 From 4ec0fef825516738d22c65207a417525b0cf2345 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Fri, 19 Jun 2020 15:13:31 +0200 Subject: [PATCH 018/221] [#31] only create memberships on initial payments --- api/v3/TwingleDonation/Submit.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index f84d21c..f434d63 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -704,7 +704,10 @@ function civicrm_api3_twingle_donation_Submit($params) { $membership_type_id = $profile->getAttribute('membership_type_id_recur'); } else { - $membership_type_id = $profile->getAttribute('membership_type_id'); + // only create memberships, if this isn't an installment + if (empty($params['parent_trx_id'])) { + $membership_type_id = $profile->getAttribute('membership_type_id'); + } } if (!empty($membership_type_id)) { // create the membership From da790863b574ec346839e95af1df7b1d5541145c Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Fri, 19 Jun 2020 15:25:59 +0200 Subject: [PATCH 019/221] [#31] only create memberships on initial payments --- api/v3/TwingleDonation/Submit.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index f434d63..5537683 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -703,12 +703,11 @@ function civicrm_api3_twingle_donation_Submit($params) { if ($params['donation_rhythm'] != 'one_time') { $membership_type_id = $profile->getAttribute('membership_type_id_recur'); } - else { - // only create memberships, if this isn't an installment - if (empty($params['parent_trx_id'])) { - $membership_type_id = $profile->getAttribute('membership_type_id'); - } + elseif (empty($params['parent_trx_id'])) { + // only create memberships, if this isn't an installment (e.g. parent_trx_id is set) + $membership_type_id = $profile->getAttribute('membership_type_id'); } + if (!empty($membership_type_id)) { // create the membership $membership_data = [ From 66c469f87dc1f81e15f0bccf14b376fe967f7d1e Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Fri, 19 Jun 2020 16:23:19 +0200 Subject: [PATCH 020/221] bump back to 1.2-dev --- info.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/info.xml b/info.xml index 4991bef..1a647bf 100644 --- a/info.xml +++ b/info.xml @@ -14,8 +14,8 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2020-06-15 - 1.2-beta1 + + 1.2-dev beta 5.0 From 22c9631ec6b93af095310e46810fcd41457bd3bb Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 25 Jun 2020 11:36:04 +0200 Subject: [PATCH 021/221] fix custom_field_mapping removed unnecessary json_decode --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index f84d21c..afa3ca3 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -296,7 +296,7 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!empty($params['custom_fields'])) { $custom_field_mapping = $profile->getCustomFieldMapping(); - foreach (json_decode($params['custom_fields']) as $twingle_field => $value) { + foreach ($params['custom_fields'] as $twingle_field => $value) { if (isset($custom_field_mapping[$twingle_field])) { // Get custom field definition to store values by entity the field // extends. From bfcd98e9733c242f9395ac8bbbea63095955bfb3 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Mon, 29 Jun 2020 14:42:27 +0200 Subject: [PATCH 022/221] 1.2-beta2 --- info.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/info.xml b/info.xml index 1a647bf..9361ef6 100644 --- a/info.xml +++ b/info.xml @@ -14,8 +14,8 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.2-dev + 2020-06-29 + 1.2-beta2 beta 5.0 From ccc8f2210d55e60f910c8203987258e18b017eae Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Mon, 29 Jun 2020 14:43:44 +0200 Subject: [PATCH 023/221] back to 1.2-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 9361ef6..50148e4 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2020-06-29 - 1.2-beta2 - beta + + 1.2-dev + 5.0 5.19 From 57b592c8f7ccf34b5c2dd5b47fd3e66a8ee5e1b1 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 1 Jul 2020 13:10:44 +0200 Subject: [PATCH 024/221] Fix develStage in info.xml --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index 50148e4..f4918e7 100644 --- a/info.xml +++ b/info.xml @@ -16,7 +16,7 @@ 1.2-dev - + dev 5.0 5.19 From 735eadd716568825af0fff0a3eece3708a4dffc0 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Tue, 21 Jul 2020 07:23:42 -0500 Subject: [PATCH 025/221] [#31] fixed workflow bug --- api/v3/TwingleDonation/Submit.php | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 5537683..61e5f19 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -699,17 +699,26 @@ function civicrm_api3_twingle_donation_Submit($params) { $result_values['contribution'] = $contribution['values']; } - // Create membership if a membership type is configured within the profile. - if ($params['donation_rhythm'] != 'one_time') { - $membership_type_id = $profile->getAttribute('membership_type_id_recur'); - } - elseif (empty($params['parent_trx_id'])) { - // only create memberships, if this isn't an installment (e.g. parent_trx_id is set) + // MEMBERSHIP CREATION + + // CHECK whether a membership should be created (based on profile settings and data provided) + if ($params['donation_rhythm'] == 'one_time') { + // membership creation based on one-off contributions $membership_type_id = $profile->getAttribute('membership_type_id'); + + } else { + // membership creation based on recurring contributions + if (empty($params['parent_trx_id'])) { + // this is the initial payment + $membership_type_id = $profile->getAttribute('membership_type_id_recur'); + } else { + // this is a follow-up recurring payment + $membership_type_id = false; + } } + // CREATE the membership if required if (!empty($membership_type_id)) { - // create the membership $membership_data = [ 'contact_id' => $contact_id, 'membership_type_id' => $membership_type_id, From e588ebe2d2c1a197eac0e90b4394b09ffaa15828 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Tue, 21 Jul 2020 07:36:10 -0500 Subject: [PATCH 026/221] 1.2-beta3 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index f4918e7..789f79c 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.2-dev - dev + 2020-07-21 + 1.2-beta3 + beta 5.0 5.19 From a81b2d4f6f20b878d93a9e17f25efaa8eb63b49d Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Tue, 21 Jul 2020 07:41:08 -0500 Subject: [PATCH 027/221] back to 1.2-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 789f79c..f4918e7 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2020-07-21 - 1.2-beta3 - beta + + 1.2-dev + dev 5.0 5.19 From 4ff060884a0ab72e3f09306223b6f6a1c738fd0e Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 24 Jul 2020 10:57:14 +0200 Subject: [PATCH 028/221] implement CiviCRM's double opt-in feature for newsletter --- CRM/Twingle/Form/Profile.php | 43 +++++++++++++++++++------- CRM/Twingle/Profile.php | 2 ++ README.md | 3 +- api/v3/TwingleDonation/Submit.php | 23 +++++++++++++- l10n/de_DE/LC_MESSAGES/twingle.po | 4 +++ templates/CRM/Twingle/Form/Profile.tpl | 5 +++ 6 files changed, 67 insertions(+), 13 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index a38dc7e..5f18715 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -327,11 +327,19 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ); } + $this->add( + 'checkbox', // field type + 'double_opt_in', // field name + E::ts('Use Double-Opt-In for newsletter'), // field label + FALSE, // is not required + array() + ); + $this->add( 'select', // field type 'newsletter_groups', // field name E::ts('Sign up for newsletter groups'), // field label - static::getNewsletterGroups(), // list of options + static::getNewsletterGroups($this->profile->getAttribute('double_opt_in')), // list of options FALSE, // is not required array('class' => 'crm-select2 huge', 'multiple' => 'multiple') ); @@ -548,6 +556,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $values['name'] = 'default'; } $this->profile->setName($values['name']); + $this->profile->setAttribute('double_opt_in', isset($values['double_opt_in'])); foreach ($this->profile->getData() as $element_name => $value) { if (isset($values[$element_name])) { $this->profile->setAttribute($element_name, $values[$element_name]); @@ -791,15 +800,16 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { return self::$_contributionStatusOptions; } - /** - * Retrieves active groups used as mailing lists within the system as options - * for select form elements. - * - * @return array - * - * @throws \CiviCRM_API3_Exception - */ - public static function getNewsletterGroups() { + /** + * Retrieves active groups used as mailing lists within the system as options + * for select form elements. + * + * @param $double_opt_in + * + * @return array + * + */ + public static function getNewsletterGroups($double_opt_in) { if (!isset(static::$_newsletterGroups)) { static::$_newsletterGroups = array(); $group_types = civicrm_api3('OptionValue', 'get', array( @@ -807,7 +817,18 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'option_group_id' => 'group_type', 'name' => CRM_Twingle_Submission::GROUP_TYPE_NEWSLETTER, )); - if ($group_types['count'] > 0) { + if ($group_types['count'] > 0 && $double_opt_in) { + $query = civicrm_api3('Group', 'get', array( + 'is_active' => 1, + 'group_type' => "Mailing List", + 'option.limit' => 0, + 'visibility' => 'Public Pages', + 'return' => 'id,name' + )); + foreach ($query['values'] as $group) { + static::$_newsletterGroups[$group['id']] = $group['name']; + } + } elseif ($group_types['count'] > 0) { $group_type = reset($group_types['values']); $query = civicrm_api3('Group', 'get', array( 'is_active' => 1, diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index be93bc6..e0afe35 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -221,6 +221,7 @@ class CRM_Twingle_Profile { 'membership_type_id', 'membership_type_id_recur', 'membership_postprocess_call', + 'double_opt_in' ), // Add payment methods. array_keys(static::paymentInstruments()), @@ -293,6 +294,7 @@ class CRM_Twingle_Profile { 'custom_field_mapping' => NULL, 'membership_type_id' => NULL, 'membership_type_id_recur' => NULL, + 'double_opt_in' => NULL, ) // Add contribution status for all payment methods. + array_fill_keys(array_map(function($attribute) { diff --git a/README.md b/README.md index e8c2a1d..b1b7409 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ for all newly created Twingle projects. | CiviSEPA creditor | When enabled to integrate with CiviSEPA, specify the CiviSEPA creditor to use. | | Gender options | Specify which CiviCRM gender option the incoming Twingle gender value should be mapped to. The list is based on your CiviCRM configuration. | | Record *Payment method* as | Specifiy the payment methods mapping for incoming donations for each Twingle payment method. | +| Double opt-In | Let CiviCRM handle the double opt-in. Group memberships for newsletter mailing lists will be pending until receivement of double opt-in confirmataion. | | Sign up for groups | Whenever the donor checked the newsletter/postal mailing/donation receipt checkbox on the Twingle form, the contact will be added to the groups listed here. | | Assign donation to campaign | The donation will be assigned to the selected campaign. If a campaign ID is being submitted using the `campaign_id` parameter, this setting will be overridden with the submitted value. | | Create membership of type | A membership of the selected type will be created for the Individual contact for incoming one-time donations. If no membership type is selected, no membership will be created. | @@ -147,4 +148,4 @@ The action accepts the following parameters: You may also refer to [the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Cancel.php) -for more insight into this API action. +for more insight into this API action. \ No newline at end of file diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index afa3ca3..d0f9061 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -484,8 +484,29 @@ function civicrm_api3_twingle_donation_Submit($params) { $result_values['organization'] = $organisation_id; } + // If usage of double opt-in is selected, use MailingEventSubscribe.create to add contact to newsletter groups + // defined in the profile + $result_values['newsletter']['double_opt_in'] = ($profile->getAttribute('double_opt_in')) ? 'true' : 'false'; + if ($profile->getAttribute('double_opt_in') && + !empty($params['newsletter']) && + !empty($groups = $profile->getAttribute('newsletter_groups'))) { + $group_memberships = array_column(civicrm_api3('GroupContact', 'get', array ( + 'sequential' => 1, + 'contact_id' => $contact_id + ))['values'], 'group_id'); + foreach ($groups as $group_id) { + if (!in_array($group_id, $group_memberships)) { + $result_values['newsletter'][][$group_id] = civicrm_api3('MailingEventSubscribe', 'create', array( + 'email' => $params['user_email'], + 'group_id' => (int) $group_id, + 'contact_id' => $contact_id, + )); + } else { + $result_values['newsletter'][] = $group_id; + } + } // If requested, add contact to newsletter groups defined in the profile. - if (!empty($params['newsletter']) && !empty($groups = $profile->getAttribute('newsletter_groups'))) { + } elseif (!empty($params['newsletter']) && !empty($groups = $profile->getAttribute('newsletter_groups'))) { foreach ($groups as $group_id) { civicrm_api3('GroupContact', 'create', array( 'group_id' => $group_id, diff --git a/l10n/de_DE/LC_MESSAGES/twingle.po b/l10n/de_DE/LC_MESSAGES/twingle.po index f914552..921eedb 100644 --- a/l10n/de_DE/LC_MESSAGES/twingle.po +++ b/l10n/de_DE/LC_MESSAGES/twingle.po @@ -306,3 +306,7 @@ msgstr "Profil %1 zurücksetzen" #: templates/CRM/Twingle/Page/Profiles.tpl msgid "Delete profile %1" msgstr "Profil % 1 löschen" + +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "Use Double-Opt-In for newsletter" +msgstr "Nutze Double-Opt-In für Newsletter" diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 708cb5a..3e6a07e 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -208,6 +208,11 @@ + + + + + From d3c1aabfb4bb8d01eebf93262c8595113e4779e7 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 14 Aug 2020 10:13:51 +0200 Subject: [PATCH 029/221] [#36] Rename "double_opt_in" property to "newsletter_double_opt_in" --- CRM/Twingle/Form/Profile.php | 6 +++--- CRM/Twingle/Profile.php | 4 ++-- api/v3/TwingleDonation/Submit.php | 4 ++-- templates/CRM/Twingle/Form/Profile.tpl | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 5f18715..3491125 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -329,7 +329,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->add( 'checkbox', // field type - 'double_opt_in', // field name + 'newsletter_double_opt_in', // field name E::ts('Use Double-Opt-In for newsletter'), // field label FALSE, // is not required array() @@ -339,7 +339,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'select', // field type 'newsletter_groups', // field name E::ts('Sign up for newsletter groups'), // field label - static::getNewsletterGroups($this->profile->getAttribute('double_opt_in')), // list of options + static::getNewsletterGroups($this->profile->getAttribute('newsletter_double_opt_in')), // list of options FALSE, // is not required array('class' => 'crm-select2 huge', 'multiple' => 'multiple') ); @@ -556,7 +556,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $values['name'] = 'default'; } $this->profile->setName($values['name']); - $this->profile->setAttribute('double_opt_in', isset($values['double_opt_in'])); + $this->profile->setAttribute('newsletter_double_opt_in', isset($values['newsletter_double_opt_in'])); foreach ($this->profile->getData() as $element_name => $value) { if (isset($values[$element_name])) { $this->profile->setAttribute($element_name, $values[$element_name]); diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index e0afe35..9c86f1a 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -221,7 +221,7 @@ class CRM_Twingle_Profile { 'membership_type_id', 'membership_type_id_recur', 'membership_postprocess_call', - 'double_opt_in' + 'newsletter_double_opt_in' ), // Add payment methods. array_keys(static::paymentInstruments()), @@ -294,7 +294,7 @@ class CRM_Twingle_Profile { 'custom_field_mapping' => NULL, 'membership_type_id' => NULL, 'membership_type_id_recur' => NULL, - 'double_opt_in' => NULL, + 'newsletter_double_opt_in' => NULL, ) // Add contribution status for all payment methods. + array_fill_keys(array_map(function($attribute) { diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index d0f9061..19217b6 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -486,8 +486,8 @@ function civicrm_api3_twingle_donation_Submit($params) { // If usage of double opt-in is selected, use MailingEventSubscribe.create to add contact to newsletter groups // defined in the profile - $result_values['newsletter']['double_opt_in'] = ($profile->getAttribute('double_opt_in')) ? 'true' : 'false'; - if ($profile->getAttribute('double_opt_in') && + $result_values['newsletter']['newsletter_double_opt_in'] = ($profile->getAttribute('newsletter_double_opt_in')) ? 'true' : 'false'; + if ($profile->getAttribute('newsletter_double_opt_in') && !empty($params['newsletter']) && !empty($groups = $profile->getAttribute('newsletter_groups'))) { $group_memberships = array_column(civicrm_api3('GroupContact', 'get', array ( diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 3e6a07e..83dc4cb 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -209,13 +209,13 @@
{$form.double_opt_in.label}{$form.double_opt_in.html}
{$form.newsletter_groups.label} {$form.newsletter_groups.html}
- - + + - - + + From 11558d4fbd93603c707f2133d3bf7cf840f9393b Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 14 Aug 2020 10:19:54 +0200 Subject: [PATCH 030/221] [#36] Save newsletter_double_opt_in property as integer --- CRM/Twingle/Form/Profile.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 3491125..046df2f 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -556,8 +556,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $values['name'] = 'default'; } $this->profile->setName($values['name']); - $this->profile->setAttribute('newsletter_double_opt_in', isset($values['newsletter_double_opt_in'])); foreach ($this->profile->getData() as $element_name => $value) { + if ($element_name == 'newsletter_double_opt_in') { + $values[$element_name] = (int) isset($values[$element_name]); + } if (isset($values[$element_name])) { $this->profile->setAttribute($element_name, $values[$element_name]); } From 94cc262c2170ee74881d474ed8f901ed53bd6b1a Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 14 Aug 2020 10:25:04 +0200 Subject: [PATCH 031/221] [#36] Add help text for the Newsletter Double-Opt-In setting --- templates/CRM/Twingle/Form/Profile.hlp | 4 ++++ templates/CRM/Twingle/Form/Profile.tpl | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index 8a89223..12136cb 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -38,6 +38,10 @@ {ts domain="de.systopia.twingle"}Select which financial type to use for recurring contributions.{/ts} {/htxt} +{htxt id='id-newsletter-double-opt-in'} + {ts domain="de.systopia.twingle"}Select whether to use CiviCRM's Double-Opt-In feature for subscribing to mailing lists. Note that this only works for public mailing lists. Any non-public mailing list selected above will be ignored when this setting is enabled.{/ts} +{/htxt} + {htxt id='id-membership-postprocessing-call'} {ts domain="de.systopia.twingle"}Some organisations have specific conventions on how a membership should be created. Since the Twingle-API can only create a "bare bone" membership object, you can enter a API Call (as 'Entity.Action') to adjust any newly created membership to your organisation's needs.{/ts} {ts domain="de.systopia.twingle"}The API call would receive the following parameters:
    diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 83dc4cb..ec51647 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -214,7 +214,24 @@
- + From 3553ed83b93fab896190db36eb391512e4237ae0 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 14 Aug 2020 10:33:00 +0200 Subject: [PATCH 032/221] [#36] Do not alter the mailing lists available for the profile field since that might be confusing and still produce invalid states --- CRM/Twingle/Form/Profile.php | 17 ++----- api/v3/TwingleDonation/Submit.php | 77 ++++++++++++++++++++----------- 2 files changed, 53 insertions(+), 41 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 046df2f..9c69f6b 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -339,7 +339,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'select', // field type 'newsletter_groups', // field name E::ts('Sign up for newsletter groups'), // field label - static::getNewsletterGroups($this->profile->getAttribute('newsletter_double_opt_in')), // list of options + static::getNewsletterGroups(), // list of options FALSE, // is not required array('class' => 'crm-select2 huge', 'multiple' => 'multiple') ); @@ -811,7 +811,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * @return array * */ - public static function getNewsletterGroups($double_opt_in) { + public static function getNewsletterGroups() { if (!isset(static::$_newsletterGroups)) { static::$_newsletterGroups = array(); $group_types = civicrm_api3('OptionValue', 'get', array( @@ -819,18 +819,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'option_group_id' => 'group_type', 'name' => CRM_Twingle_Submission::GROUP_TYPE_NEWSLETTER, )); - if ($group_types['count'] > 0 && $double_opt_in) { - $query = civicrm_api3('Group', 'get', array( - 'is_active' => 1, - 'group_type' => "Mailing List", - 'option.limit' => 0, - 'visibility' => 'Public Pages', - 'return' => 'id,name' - )); - foreach ($query['values'] as $group) { - static::$_newsletterGroups[$group['id']] = $group['name']; - } - } elseif ($group_types['count'] > 0) { + if ($group_types['count'] > 0) { $group_type = reset($group_types['values']); $query = civicrm_api3('Group', 'get', array( 'is_active' => 1, diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 19217b6..d8577e6 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -484,34 +484,57 @@ function civicrm_api3_twingle_donation_Submit($params) { $result_values['organization'] = $organisation_id; } - // If usage of double opt-in is selected, use MailingEventSubscribe.create to add contact to newsletter groups - // defined in the profile - $result_values['newsletter']['newsletter_double_opt_in'] = ($profile->getAttribute('newsletter_double_opt_in')) ? 'true' : 'false'; - if ($profile->getAttribute('newsletter_double_opt_in') && - !empty($params['newsletter']) && - !empty($groups = $profile->getAttribute('newsletter_groups'))) { - $group_memberships = array_column(civicrm_api3('GroupContact', 'get', array ( - 'sequential' => 1, - 'contact_id' => $contact_id - ))['values'], 'group_id'); - foreach ($groups as $group_id) { - if (!in_array($group_id, $group_memberships)) { - $result_values['newsletter'][][$group_id] = civicrm_api3('MailingEventSubscribe', 'create', array( - 'email' => $params['user_email'], - 'group_id' => (int) $group_id, - 'contact_id' => $contact_id, - )); - } else { - $result_values['newsletter'][] = $group_id; - } - } - // If requested, add contact to newsletter groups defined in the profile. - } elseif (!empty($params['newsletter']) && !empty($groups = $profile->getAttribute('newsletter_groups'))) { + // If usage of double opt-in is selected, use MailingEventSubscribe.create + // to add contact to newsletter groups defined in the profile + $result_values['newsletter']['newsletter_double_opt_in'] = ($profile->getAttribute('newsletter_double_opt_in')) ? 'true' : 'false'; + if ( + $profile->getAttribute('newsletter_double_opt_in') && + !empty($params['newsletter']) && + !empty($groups = $profile->getAttribute('newsletter_groups')) + ) { + $group_memberships = array_column( + civicrm_api3( + 'GroupContact', + 'get', + array( + 'sequential' => 1, + 'contact_id' => $contact_id, + ) + )['values'], + 'group_id' + ); + // TODO: Filter for public mailing list groups? foreach ($groups as $group_id) { - civicrm_api3('GroupContact', 'create', array( - 'group_id' => $group_id, - 'contact_id' => $contact_id, - )); + if (!in_array($group_id, $group_memberships)) { + $result_values['newsletter'][][$group_id] = civicrm_api3( + 'MailingEventSubscribe', + 'create', + array( + 'email' => $params['user_email'], + 'group_id' => (int) $group_id, + 'contact_id' => $contact_id, + ) + ); + } + else { + $result_values['newsletter'][] = $group_id; + } + } + // If requested, add contact to newsletter groups defined in the profile. + } + elseif ( + !empty($params['newsletter']) + && !empty($groups = $profile->getAttribute('newsletter_groups')) + ) { + foreach ($groups as $group_id) { + civicrm_api3( + 'GroupContact', + 'create', + array( + 'group_id' => $group_id, + 'contact_id' => $contact_id, + ) + ); $result_values['newsletter'][] = $group_id; } From 6b42c72bf8ef25c720234c35973bf46500035e4a Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 14 Aug 2020 10:43:06 +0200 Subject: [PATCH 033/221] [#36] Fix indentation --- CRM/Twingle/Form/Profile.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 9c69f6b..90241c2 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -802,15 +802,15 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { return self::$_contributionStatusOptions; } - /** - * Retrieves active groups used as mailing lists within the system as options - * for select form elements. - * - * @param $double_opt_in - * - * @return array - * - */ + /** + * Retrieves active groups used as mailing lists within the system as options + * for select form elements. + * + * @param $double_opt_in + * + * @return array + * + */ public static function getNewsletterGroups() { if (!isset(static::$_newsletterGroups)) { static::$_newsletterGroups = array(); @@ -819,7 +819,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'option_group_id' => 'group_type', 'name' => CRM_Twingle_Submission::GROUP_TYPE_NEWSLETTER, )); - if ($group_types['count'] > 0) { + if ($group_types['count'] > 0) { $group_type = reset($group_types['values']); $query = civicrm_api3('Group', 'get', array( 'is_active' => 1, From 021cd5257b5f958c85d1aee00aece78cce63c381 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 14 Aug 2020 10:48:50 +0200 Subject: [PATCH 034/221] [#36] Fix PHPDoc --- CRM/Twingle/Form/Profile.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 90241c2..be9dd27 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -806,10 +806,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves active groups used as mailing lists within the system as options * for select form elements. * - * @param $double_opt_in - * * @return array * + * @throws \CiviCRM_API3_Exception + * */ public static function getNewsletterGroups() { if (!isset(static::$_newsletterGroups)) { From d140bd9ed7e633c3ccea0d3de50f62363d9cc2a5 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 18 Aug 2020 14:15:59 +0200 Subject: [PATCH 035/221] filter out non-public groups non-public groups are getting ignored --- api/v3/TwingleDonation/Submit.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index d8577e6..984fa9a 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -503,9 +503,15 @@ function civicrm_api3_twingle_donation_Submit($params) { )['values'], 'group_id' ); - // TODO: Filter for public mailing list groups? foreach ($groups as $group_id) { - if (!in_array($group_id, $group_memberships)) { + $is_public_group = civicrm_api3( + 'Group', + 'getsingle', + array( + 'id' => (int) $group_id, + ) + )['visibility'] == 'Public Pages'; + if (!in_array($group_id, $group_memberships) && $is_public_group) { $result_values['newsletter'][][$group_id] = civicrm_api3( 'MailingEventSubscribe', 'create', @@ -516,7 +522,7 @@ function civicrm_api3_twingle_donation_Submit($params) { ) ); } - else { + elseif ($is_public_group) { $result_values['newsletter'][] = $group_id; } } From d7e42035c8a6b21d70bd9c9e8b191dfab633b77d Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 18 Aug 2020 15:00:18 +0200 Subject: [PATCH 036/221] updated double opt-in description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1b7409..c338dce 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ for all newly created Twingle projects. | CiviSEPA creditor | When enabled to integrate with CiviSEPA, specify the CiviSEPA creditor to use. | | Gender options | Specify which CiviCRM gender option the incoming Twingle gender value should be mapped to. The list is based on your CiviCRM configuration. | | Record *Payment method* as | Specifiy the payment methods mapping for incoming donations for each Twingle payment method. | -| Double opt-In | Let CiviCRM handle the double opt-in. Group memberships for newsletter mailing lists will be pending until receivement of double opt-in confirmataion. | +| Double Opt-In | Let CiviCRM handle the double opt-in. Group memberships for newsletter mailing lists stay pending until the subscription gets confirmed. Note that this only works for public mailing lists. Any non-public mailing lists will be ignored. Do not forget to disable Twingle's double opt-in option in the Twingle Manager. | | Sign up for groups | Whenever the donor checked the newsletter/postal mailing/donation receipt checkbox on the Twingle form, the contact will be added to the groups listed here. | | Assign donation to campaign | The donation will be assigned to the selected campaign. If a campaign ID is being submitted using the `campaign_id` parameter, this setting will be overridden with the submitted value. | | Create membership of type | A membership of the selected type will be created for the Individual contact for incoming one-time donations. If no membership type is selected, no membership will be created. | From a65e98509a5203033b460f9f4dc40ca0c577d6e7 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 19 Aug 2020 12:27:46 +0200 Subject: [PATCH 037/221] [#36] Improve help text on Double Opt-In option --- README.md | 36 +++++++++++++------------- templates/CRM/Twingle/Form/Profile.hlp | 3 ++- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index c338dce..bb52ecd 100644 --- a/README.md +++ b/README.md @@ -43,24 +43,24 @@ The *default* profile is used whenever the plugin cannot match the Twingle project ID from any other profile. Therefore the default profile will be used for all newly created Twingle projects. -| Label | Description | -|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Profile name | Internal name, used inside the extension. | -| Project IDs | Twingle project IDs. Separate multiple IDs with commas. | -| Location type | Specify how the address data sent by the form should be categorised in CiviCRM. The list is based on your CiviCRM configuration. | -| Location type for organisations | Specify how the address data sent by the form should be categorised in CiviCRM for organisational donations. The list is based on your CiviCRM configuration. | -| Financial type | Specify which financial type incoming one-time donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. | -| Financial type (recurring) | Specify which financial type incoming recurring donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. | -| CiviSEPA creditor | When enabled to integrate with CiviSEPA, specify the CiviSEPA creditor to use. | -| Gender options | Specify which CiviCRM gender option the incoming Twingle gender value should be mapped to. The list is based on your CiviCRM configuration. | -| Record *Payment method* as | Specifiy the payment methods mapping for incoming donations for each Twingle payment method. | -| Double Opt-In | Let CiviCRM handle the double opt-in. Group memberships for newsletter mailing lists stay pending until the subscription gets confirmed. Note that this only works for public mailing lists. Any non-public mailing lists will be ignored. Do not forget to disable Twingle's double opt-in option in the Twingle Manager. | -| Sign up for groups | Whenever the donor checked the newsletter/postal mailing/donation receipt checkbox on the Twingle form, the contact will be added to the groups listed here. | -| Assign donation to campaign | The donation will be assigned to the selected campaign. If a campaign ID is being submitted using the `campaign_id` parameter, this setting will be overridden with the submitted value. | -| Create membership of type | A membership of the selected type will be created for the Individual contact for incoming one-time donations. If no membership type is selected, no membership will be created. | -| Create membership of type (recurring) | A membership of the selected type will be created for the Individual contact for incoming recurring donations. If no membership type is selected, no membership will be created. | -| Contribution source | The configured value will be set as the "Source" field for the contribution. | -| Custom field mapping | Additional field values may be set to CiviCRM custom fields using a mapping. See the option's help text for the exact format. | +| Label | Description | +|---------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Profile name | Internal name, used inside the extension. | +| Project IDs | Twingle project IDs. Separate multiple IDs with commas. | +| Location type | Specify how the address data sent by the form should be categorised in CiviCRM. The list is based on your CiviCRM configuration. | +| Location type for organisations | Specify how the address data sent by the form should be categorised in CiviCRM for organisational donations. The list is based on your CiviCRM configuration. | +| Financial type | Specify which financial type incoming one-time donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. | +| Financial type (recurring) | Specify which financial type incoming recurring donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. | +| CiviSEPA creditor | When enabled to integrate with CiviSEPA, specify the CiviSEPA creditor to use. | +| Gender options | Specify which CiviCRM gender option the incoming Twingle gender value should be mapped to. The list is based on your CiviCRM configuration. | +| Record *Payment method* as | Specifiy the payment methods mapping for incoming donations for each Twingle payment method. | +| Double Opt-In | Let CiviCRM handle the double opt-in. Group memberships for newsletter mailing lists stay pending until the subscription gets confirmed. Note that this only works for public mailing lists. Any non-public mailing list will be ignored. Do not forget to disable Twingle's double opt-in option in the Twingle Manager. | +| Sign up for groups | Whenever the donor checked the newsletter/postal mailing/donation receipt checkbox on the Twingle form, the contact will be added to the groups listed here. | +| Assign donation to campaign | The donation will be assigned to the selected campaign. If a campaign ID is being submitted using the `campaign_id` parameter, this setting will be overridden with the submitted value. | +| Create membership of type | A membership of the selected type will be created for the Individual contact for incoming one-time donations. If no membership type is selected, no membership will be created. | +| Create membership of type (recurring) | A membership of the selected type will be created for the Individual contact for incoming recurring donations. If no membership type is selected, no membership will be created. | +| Contribution source | The configured value will be set as the "Source" field for the contribution. | +| Custom field mapping | Additional field values may be set to CiviCRM custom fields using a mapping. See the option's help text for the exact format. | ## API documentation diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index 12136cb..bcbe78a 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -39,7 +39,8 @@ {/htxt} {htxt id='id-newsletter-double-opt-in'} - {ts domain="de.systopia.twingle"}Select whether to use CiviCRM's Double-Opt-In feature for subscribing to mailing lists. Note that this only works for public mailing lists. Any non-public mailing list selected above will be ignored when this setting is enabled.{/ts} +

{ts domain="de.systopia.twingle"}Select whether to use CiviCRM's Double-Opt-In feature for subscribing to mailing lists. Note that this only works for public mailing lists. Any non-public mailing list selected above will be ignored when this setting is enabled.{/ts}

+

{ts domain="de.systopia.twingle"}Also, do not forget to disable Twingle's own Double Opt-In option in the Twingle Manager to avoid subscribers receiving multiple confirmation e-mails. Only one or the other option should be enabled.{/ts}

{/htxt} {htxt id='id-membership-postprocessing-call'} From 9d0ac14d359dadb02294f3d5f3b363f6e31ea55c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 19 Aug 2020 12:37:01 +0200 Subject: [PATCH 038/221] Set version to 1.3-dev --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index f4918e7..6fe8dc2 100644 --- a/info.xml +++ b/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html - 1.2-dev + 1.3-dev dev 5.0 From 3139ec0fee590b54092b87d2f90a76aa979e4b0b Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 16 Sep 2020 10:06:43 +0200 Subject: [PATCH 039/221] Fix typo in documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb52ecd..ac72b34 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ enabled. ### Configure CiviCRM -- Go to the Administration console `/civicrm/admin` +- Go to the Administration console at `/civicrm/admin` - Open "Twingle API Configuration" at `/civicrm/admin/settings/twingle` #### Configure CiviSEPA integration From 7328b3893df8d53c9e2fc8a19a8843189d84e1bb Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 25 Sep 2020 12:08:09 +0200 Subject: [PATCH 040/221] trim project_ids --- CRM/Twingle/Profile.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 9c86f1a..f59d236 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -65,7 +65,12 @@ class CRM_Twingle_Profile { */ public function matches($project_id) { $selector = $this->getAttribute('selector'); - $project_ids = explode(',', $selector); + $project_ids = array_map( + function($project_id) { + return trim($project_id); + }, + explode(',', $selector) + ); return in_array($project_id, $project_ids); } From 228e964633315df93bdd719dc19c2f6aa9ed0022 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 10 Nov 2020 11:30:58 +0100 Subject: [PATCH 041/221] [#29] Use correct profile names and validate before saving profile copies --- CRM/Twingle/Form/Profile.php | 38 ++++++++++++++----------- templates/CRM/Twingle/Page/Profiles.tpl | 2 +- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index be9dd27..e00a339 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -139,7 +139,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->_op = 'create'; } - // Verify that profile with the given name exists. + // Verify that a profile with the given name exists. $profile_name = CRM_Utils_Request::retrieve('name', 'String', $this); if (!$this->profile = CRM_Twingle_Profile::getProfile($profile_name)) { $profile_name = NULL; @@ -174,20 +174,22 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // This will be a 'create' actually. $this->_op = 'create'; + // Retrieve the source profile name. + $profile_name = CRM_Utils_Request::retrieve('source_name', 'String', $this); // When copying without a valid profile name, copy the default profile. if (!$profile_name) { $profile_name = 'default'; - $this->profile = CRM_Twingle_Profile::getProfile($profile_name); } + $this->profile = CRM_Twingle_Profile::getProfile($profile_name); - // Set a new name for this profile. + // Propose a new name for this profile. $profile_name = $profile_name . '_copy'; $this->profile->setName($profile_name); CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); break; case 'create': // Load factory default profile values. - $this->profile = CRM_twingle_Profile::createDefaultProfile($profile_name); + $this->profile = CRM_Twingle_Profile::createDefaultProfile($profile_name); CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); break; } @@ -436,13 +438,6 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { parent::buildQuickForm(); } - /** - * @inheritdoc - */ - public function addRules() { - $this->addFormRule(array('CRM_Twingle_Form_Profile', 'validateProfileForm')); - } - /** * Validates the profile form. * @@ -453,12 +448,21 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * TRUE when the form was successfully validated, or an array of error * messages, keyed by form element name. */ - public static function validateProfileForm($values) { - $errors = array(); + public function validate() { + $values = $this->exportValues(); + + // Validate new profile names. + if ( + isset($values['name']) + && ($values['name'] != $this->profile->getName() || $this->_op != 'edit') + && !empty(CRM_Twingle_Profile::getProfile($values['name'])) + ) { + $this->_errors['name'] = E::ts('A profile with this name already exists.'); + } // Restrict profile names to alphanumeric characters and the underscore. if (isset($values['name']) && preg_match("/[^A-Za-z0-9\_]/", $values['name'])) { - $errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); + $this->_errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); } // Validate custom field mapping. @@ -521,10 +525,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { } } catch (Exception $exception) { - $errors['custom_field_mapping'] = $exception->getMessage(); + $this->_errors['custom_field_mapping'] = $exception->getMessage(); } - return empty($errors) ? TRUE : $errors; + return parent::validate(); } /** @@ -551,7 +555,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public function postProcess() { $values = $this->exportValues(); - if (in_array($this->_op, array('create', 'edit'))) { + if (in_array($this->_op, array('create', 'edit', 'copy'))) { if (empty($values['name'])) { $values['name'] = 'default'; } diff --git a/templates/CRM/Twingle/Page/Profiles.tpl b/templates/CRM/Twingle/Page/Profiles.tpl index 30dbfce..f97b9ed 100644 --- a/templates/CRM/Twingle/Page/Profiles.tpl +++ b/templates/CRM/Twingle/Page/Profiles.tpl @@ -39,7 +39,7 @@
+ + + + + + + + + + - - - - - + + @@ -37,6 +39,8 @@ + + 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 literal 0 HcmV?d00001 diff --git a/docs/Img/twpay.jpg b/docs/Img/twpay.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a48197a6adfbcabe5f1d9751cece199a875758b GIT binary patch literal 72798 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 literal 0 HcmV?d00001 diff --git a/docs/Img/xcmdif.jpg b/docs/Img/xcmdif.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8f76b1208205e0d762d7d750478f64a3bacd65aa GIT binary patch literal 8027 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 H{KP*1%yZC@ literal 0 HcmV?d00001 diff --git a/docs/api_tw.md b/docs/api_tw.md new file mode 100644 index 0000000..d19af35 --- /dev/null +++ b/docs/api_tw.md @@ -0,0 +1,87 @@ +# API documentation + +The extension provides a new CiviCRM API entity `TwingleDonation` with API +actions to record a new donation, end a previously submitted recurring donation +and cancel previously submitted donation. + +### Submit donation + +This API action processes submitted Twingle donations and donor information. + +- Entity: `TwingleDonation` +- Action: `Submit` + +The action accepts the following parameters: + +| Parameter | Type | Description | Values/Format | Required | +| -------------------------------------- | ------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| `project_id` | String | The Twingle project ID | | Yes | +| `trx_id` | String | The unique transaction ID of the donation | A unique transaction ID for the donation. | Yes | +| `confirmed_at` | String | The date when the donation was issued | A string representing a date in the format `YmdHis` | Yes | +| `purpose` | String | The purpose of the donation | | | +| `amount` | Integer | The donation amount in minor currency unit | | Yes | +| `currency` | String | The ISO-4217 currency code of the donation | A valid ISO-4217 currency code | Yes | +| `newsletter` | Boolean | Whether to subscribe the contact to the newsletter group defined in the profile | | | +| `postinfo` | Boolean | Whether to subscribe the contact to the postal mailing group defined in the profile | | | +| `donation_receipt` | Boolean | Whether the contact requested a donation receipt | | | +| `payment_method` | String | The Twingle payment method used for the donation | One of:
  • `banktransfer`
  • `debit_manual`
  • `debit_automatic`
  • `creditcard`
  • `mobilephone_germany`
  • `paypal`
  • `sofortueberweisung`
  • `amazonpay`
  • `paydirekt`
  • `applepay`
  • `googlepay`
| Yes | +| `donation_rhythm` | String | The interval which the donation is recurring in | One of:
  • `'one_time',`
  • `'halfyearly',`
  • `'quarterly',`
  • `'yearly',`
  • `'monthly'`
| Yes | +| `debit_iban` | String | The IBAN for SEPA Direct Debit payments | A valid ISO 13616-1:2007 IBAN | Yes, if `payment_method` is `debit_manual` and CiviSEPA is used | +| `debit_bic` | String | The BIC for SEPA Direct Debit payments | A valid ISO 9362 BIC | Yes, if `payment_method` is `debit_manual` and CiviSEPA is used | +| `debit_mandate_reference` | String | The mandate reference for SEPA Direct Debit payments | | | +| `debit_account_holder` | String | The account holder for SEPA Direct Debit payments | | | +| `is_anonymous` | Boolean | Whether the donation is submitted anonymously | | | +| `user_gender` | String | The gender of the contact | | | +| `user_birthdate` | String | The date of birth of the contact | A string representing a date in the format `Ymd` | | +| `user_title` | String | The formal title of the contact | | | +| `user_email` | String | The e-mail address of the contact | A valid e-mail address | | +| `user_firstname` | String | The first name of the contact | | | +| `user_lastname` | String | The last name of the contact | | | +| `user_street` | String | The street address of the contact | | | +| `user_postal_code` | String | The postal code of the contact | | | +| `user_city` | String | The city of the contact | | | +| `user_country` | String | The country of the contact | A [ISO 3166-1 Alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) | | +| `user_telephone` | String | The telephone number of the contact | | | +| `user_company` | String | The company of the contact | | | +| `user_extrafield` | String | Additional information of the contact | | | +| `user_language` | String | The preferred language of the contact. | A [ISO-639-1 2-digit language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) | | +| `campaign_id` | Integer | The CiviCRM ID of a campaign to assign the contribution | A valid CiviCRM Campaign ID. This overrides the campaign ID configured within the profile. | | + +You may also refer to +[the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Submit.php) +for more insight into this API action. + +### End recurring donation + +- Entity: `TwingleDonation` +- Action: `Endrecurring` + +The action accepts the following parameters: + +| Parameter | Type | Description | Values/Format | Required | +| ------------------------- | ------- | ---------------------------------------------- | --------------------------------------------------- | -------- | +| `project_id` | String | The Twingle project ID | | Yes | +| `trx_id` | String | The unique transaction ID of the donation | A unique transaction ID for the donation. | Yes | +| `ended_at` | Integer | The date when the recurring donation was ended | A string representing a date in the format `YmdHis` | Yes | + +You may also refer to +[the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Endrecurring.php) +for more insight into this API action. + +### Cancel donation + +- Entity: `TwingleDonation` +- Action: `Cancel` + +The action accepts the following parameters: + +| Parameter | Type | Description | Values/Format | Required | +| ---------------------------- | ------ | -------------------------------------------------- | --------------------------------------------------- | -------- | +| `project_id` | String | The Twingle project ID | | Yes | +| `trx_id` | String | The unique transaction ID of the donation | A unique transaction ID for the donation. | Yes | +| `cancelled_at` | String | The date when the recurring donation was cancelled | A string representing a date in the format `YmdHis` | Yes | +| `cancel_reason` | String | The reason for the donation being cancelled | | Yes | + +You may also refer to +[the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Cancel.php) +for more insight into this API action. \ No newline at end of file diff --git a/docs/con_civi.md b/docs/con_civi.md new file mode 100644 index 0000000..e1289a9 --- /dev/null +++ b/docs/con_civi.md @@ -0,0 +1,39 @@ +# Twingle API: Creating a Twingle User in CiviCRM + +After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Among other things, certain configurations must be made regarding the general CiviCRM administration. Among other things, there must be in either case a Twingle user in the CiviCRM contacts. + +## Take over user + +The Twingle API only works correctly if a user with the name **Twingle API** exists in CiviCRM. Make sure that you have previously created the corresponding user your CMS user administration (Drupal, Wordpress ...). + +Here, the corresponding steps are described by way of example when using Drupal. + +1. In CiviCRM, go to **Administer**. + +2. In the **Users and Permissions** section, choose **Synchronize Users to Contacts**. + +![](Img/Kon_syn.jpg) + +This function checks each user record in Drupal for a contact record in CiviCRM. If there is no corresponding contact record for a user, a new one will be generated. Check this in your CiviCRM contact management. + +![](Img/civiuser_tw.jpg) + +## Assign API key for the Twingle API user + +The Twingle API user in CiviCRM needs his own API key. The API key is assigned with the help of the API Explorer in CiviCRM. + +1. Select the Twingle API user in CiviCRM. + +2. Look for the corresponding **CiviCRM ID** and remember the ID. + +3. Go to **Support/Developper/API Explorer v4**. + +4. Enter **Contact** in the entity field, **create** in action field and the **ID** of the Twingle User in the **index** field. + +5. In the values field, select **api_key**. + +6. Enter the API key for the Twingle API user in the **add value** field. + +7. Click on **Execute**. + +![](Img/apikey.jpg) diff --git a/docs/con_drup.md b/docs/con_drup.md new file mode 100644 index 0000000..37a4312 --- /dev/null +++ b/docs/con_drup.md @@ -0,0 +1,41 @@ +# Twingle API: Creating a Twingle user and a user roll in your CMS system + +After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Among other things, certain configurations must be made on the CMS platform CiviCRM is implemented on. + +In an CMS system, administration of permissions is made easier by creating roles and assigning permissions to them rather than assigning permissions to each user. + +The Twingle API requires a user with the name Twingle API and a user role with the name Twingle API in your CMS-system. + +Here, the corresponding steps are described by way of example when using Drupal. + +## New User Role in Drupal + +1. In Drupal, go to **Administration/People/Permissions/Roles**. + +2. Type Twingle API in the text box and select **Add role**. To the right of your role there will be a *edit role* function and an *edit permissions* button. The *edit permissions* selection will show only the permission selections for the individual role. + +3. As Permission you only have to select the following entry: **Twingle API: Access Twingle API**. + +## New User Role in Wordpress + +1. In CiviCRM, go to **Administer/User and Permissions (Access Control)**. + +2. Then select the **WordPress Access Control** link. + Here you can adjust the CiviCRM settings for each of the predefined User Roles from WordPress. + +3. Scroll down. As Permission you only have to select the following entry: **Twingle API: Access Twingle API**. + + +![](Img/Twin_per.png) + +## New User in Drupal + +1. In Drupal, go to **Administration/People**. + +2. Then select **Add user**. + +3. In user name field enter **Twingle API** + +4. In the e-mail field enter either **info@example.de** or **mailtest@example.de**. + +5. In Roles select **Twingle API**. diff --git a/docs/con_man.md b/docs/con_man.md new file mode 100644 index 0000000..d943158 --- /dev/null +++ b/docs/con_man.md @@ -0,0 +1,22 @@ +# Twingle API: Configuring the Twingle account on the Twingle website + +The use of the Twingle API extension requires that you already have a Twingle account and that you make some settings in this account for the connection. + +You will have to make the following settings: + +1. API key from your Twingle user + +2. Site key + +3. URL + +Important: The URL must always be the complete URL to the interface. +Examples: + +- Drupal: https://meine-domain.de/sites/all/modules/civicrm/extern/rest.php +- Wordpress (with CiviCRM <5.25): https://meine-domain.de/wp-content/plugins/civicrm/civicrm/extern/rest.php +- Wordpress (with CiviCRM 5.25+): https://meine-domain.de/wp-json/civicrm/v3/rest + + + +[For detailled information please follow this link](https://support.twingle.de/faq/de-de/9-anbindung-externer-systeme/46-wie-kann-ich-civicrm-mit-twingle-nutzen) (in German language only). diff --git a/docs/con_tw.md b/docs/con_tw.md new file mode 100644 index 0000000..470b36c --- /dev/null +++ b/docs/con_tw.md @@ -0,0 +1,31 @@ +# Configuring the Twingle Profile in CiviCRM + +After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Among other things, you have to make some settings in the Twingle Profile in CiviCRM. + +1. In CiviCRM, go to **Administer**. + +2. Choose **Twingle API configuration**. + + ![](Img/Konso.jpg) + +3. Then click on **Configure profiles**. + + ![](Img/SepaKon.jpg) + +4. The Twingle configuration is always done with the help of a profile. Please use the Twingle default profile and click on **Edit**. + + ![](Img/Prof.jpg) + +5. Then you will identify the Twingle API profile window. Start by entering the corresponding information in the **General settings** section. + + ![](Img/GenSet.jpg) + +6. Define the different payment methods in the Payments section. + + ![](Img/twpay.jpg) + +7. Make the settings for the groups. + + ![](Img/Twgrou.jpg) + +8. When you have made all the settings, please press the **Save** button. diff --git a/docs/con_twse.md b/docs/con_twse.md new file mode 100644 index 0000000..aaf7f4c --- /dev/null +++ b/docs/con_twse.md @@ -0,0 +1,25 @@ +# Activating SEPA for the Twingle API extension in CiviCRM + +After the installation of the extension, various configuration steps must be carried out so that the connection functions smoothly. If you would like to create and manage the SEPA mandates yourself for the one-off and recurring payments with CiviCRM, you have to make some settings regarding the SEPA connection. + +1. In CiviCRM, go to **Administer**. + +2. Choose **Twingle API configuration**. + + ![](Img/Konso.jpg) + +3. Then click on **Configure extension settings**. + + ![](Img/SepaKon.jpg) + +4. Tick the boxes **Use CiviSEPA** and **Use CiviSEPA generated reference**. + These options can only be activated if CiviSEPA is installed and used. If it is not activated, the administration of SEPA mandates takes place in Twingle. + +5. Write **TW-** in the **Twingle ID Prefix** field. + To avoid overlaps when assigning CiviCRM IDs and Twingle transaction IDs, a prefix should be assigned here, e.g. "TWNGL" or "Twingle" or similar. + Attention: The prefix should not be changed later, otherwise problems may occur. + +6. In the **Protect Recurring Contributions** field select **No**. + If you choose Yes, all recurring donations created by Twingle can no longer be changed in CiviCRM, but must then be changed accordingly in Twingle. If no recurring payments are processed via Twingle, but only one-off donations, then this does not need to be activated. Otherwise, we strongly recommend setting the button here to **Yes** so that there are no discrepancies between CiviCRM and Twingle. + + ![](Img/Sepa.jpg) diff --git a/docs/con_xcm.md b/docs/con_xcm.md new file mode 100644 index 0000000..0087ca1 --- /dev/null +++ b/docs/con_xcm.md @@ -0,0 +1,59 @@ +# Twingle API: Configuring the Extended Contact Manager extension (XCM) + +After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Twingle API works only correctly when you have previously installed the Extended Contact Manager extension (XCM). + +Taking over contact data using the Twingle API means that they may produce duplicates in your CiviCRM contact management. Before contacts are added or updated in CiviCRM a data check should take place to avoid this problem. This data check is handled by the Extended Contact Manager extension (XCM). This extension must be configured accordingly for use with Twingle by defining a corresponding profile. + +## Creating a Twingle Profile + +Your first task regarding the Extended Contact Manager extension (XCM) configuration will be to create a corresponding Twinge profile. This works best if you copy the Default profile. + +1. In CiviCRM, go to **Administer**. + +2. Select **Xtended Contact Matcher (XCM) Configuration** in the **System Settings** section. + +![](Img/XCMAdmin.jpg) + +3. Click on **Copy** in the **Default** profile. + +4. Rename the new profile with **Twingle** in the **Profile name** field. + +![](Img/ProNam.jpg) + +5. Click **Save** at the bottom of this window. In the Profiles overview you can find your new Twingle profile. + +![](Img/XCM_Profile.jpg) + +## Set up the Extended Contact Manager extension (XCM) + +After you have created the Twingle profile, you must enter the configuration settings for the Twingle connection to CiviCRM in this profile. Generally, you will find a description of all the settings in the [Extended Contact Manager (XCM) documentation](https://docs.civicrm.org/xcm/en/latest/configuration/). + +Here you will find as support screenshots of the various sections of the Extended Contact Manager extension (XCM). The settings are only an example. Please adapt the settings to your individual requirements or environnement. + +#### General section + +![](Img/XCMGen.jpg) + +#### Update section + +![](Img/XCMUpda.jpg) + +#### Assignment rules section + +![](Img/XCMReg.jpg) + +#### Identified contacts section + +![](Img/XCMIde.jpg) + +#### New contact section + +![](Img/XCMNeu.jpg) + +#### Duplicate section + +![](Img/XCMDup.jpg) + +#### Difference Handling section + +![](Img/xcmdif.jpg) diff --git a/docs/install_tw.md b/docs/install_tw.md new file mode 100644 index 0000000..9f90aec --- /dev/null +++ b/docs/install_tw.md @@ -0,0 +1,12 @@ +# Installation Twingle API + +You can find an official release archive from the [release page](https://github.com/systopia/de.systopia.twingle). + +1. First, download and then unpack the archive and move the directory into your CiviCRM extensions folder (e.g., `.../civicrm/ext/`. + If you don't know where your extensions folder is, just have a look in your CiviCRM settings ( **Administer**/**System Settings**/**Directories**)). +2. Next, open the extensions page in the CiviCRM settings (**Administer**/**System Settings**/**Extensions**). +3. Find the extension Twingle API in the *Extensions* tab and click on **Install**. The extension will be set up. + +## Extended Contact Matcher (XCM) + +Please note that for the correct working of Twingle API you still need to install the extension Extended Contact Matcher (XCM). You can find the corresponding information therefore [here](https://docs.civicrm.org/xcm/en/latest/). diff --git a/mkdocs.yml b/mkdocs.yml index 4230310..d6d4222 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,10 +1,18 @@ site_name: Twingle API -repo_url: https://github.com/systopia/de.systopia.twingle theme: name: material nav: -- 'Home': index.md +- Home: index.md +- Installation: install_tw.md +- Configuration: + - Creating a Twingle user in the CMS system: con_drup.md + - Configuring the Extended Contact Manager extension: con_xcm.md + - Creating a Twingle user in CiviCRM: con_civi.md + - Activating SEPA for the Twingle API extension in CiviCRM: con_twse.md + - Configuring the Twingle Profile in CiviCRM: con_tw.md + - Configuring the Twingle Account on the Twingle website: con_man.md + - API documentation: api_tw.md markdown_extensions: - attr_list From 8cd714362d5a59a4320d7386d9cbed737d98090c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 14 Mar 2023 15:17:37 +0100 Subject: [PATCH 080/221] Format and structure fixes for docs --- README.md | 67 ++++++++++---------- docs/{api_tw.md => api.md} | 4 +- docs/con_civi.md | 39 ------------ docs/con_drup.md | 41 ------------- docs/con_man.md | 22 ------- docs/con_tw.md | 31 ---------- docs/con_twse.md | 25 -------- docs/con_xcm.md | 59 ------------------ docs/configuration/account.md | 27 ++++++++ docs/configuration/civisepa.md | 32 ++++++++++ docs/configuration/profiles.md | 30 +++++++++ docs/configuration/user_permissions.md | 82 +++++++++++++++++++++++++ docs/configuration/xcm.md | 75 ++++++++++++++++++++++ docs/{Img => img}/GenSet.jpg | Bin docs/{Img => img}/Kon_syn.jpg | Bin docs/{Img => img}/Konso.jpg | Bin docs/{Img => img}/NewUser_Tw.jpg | Bin docs/{Img => img}/ProNam.jpg | Bin docs/{Img => img}/Prof.jpg | Bin docs/{Img => img}/Role_Twingle.jpg | Bin docs/{Img => img}/Sepa.jpg | Bin docs/{Img => img}/SepaKon.jpg | Bin docs/{Img => img}/Twgrou.jpg | Bin docs/{Img => img}/Twin_per.png | Bin docs/{Img => img}/XCMAdmin.jpg | Bin docs/{Img => img}/XCMAkt.jpg | Bin docs/{Img => img}/XCMDup.jpg | Bin docs/{Img => img}/XCMGen.jpg | Bin docs/{Img => img}/XCMIde.jpg | Bin docs/{Img => img}/XCMNeu.jpg | Bin docs/{Img => img}/XCMPro.jpg | Bin docs/{Img => img}/XCMReg.jpg | Bin docs/{Img => img}/XCMUpda.jpg | Bin docs/{Img => img}/XCM_Profile.jpg | Bin docs/{Img => img}/apikey.jpg | Bin docs/{Img => img}/civiuser_tw.jpg | Bin docs/{Img => img}/twpay.jpg | Bin docs/{Img => img}/xcmdif.jpg | Bin docs/install_tw.md | 12 ---- docs/installation.md | 19 ++++++ mkdocs.yml | 48 ++++++++------- 41 files changed, 325 insertions(+), 288 deletions(-) rename docs/{api_tw.md => api.md} (99%) delete mode 100644 docs/con_civi.md delete mode 100644 docs/con_drup.md delete mode 100644 docs/con_man.md delete mode 100644 docs/con_tw.md delete mode 100644 docs/con_twse.md delete mode 100644 docs/con_xcm.md create mode 100644 docs/configuration/account.md create mode 100644 docs/configuration/civisepa.md create mode 100644 docs/configuration/profiles.md create mode 100644 docs/configuration/user_permissions.md create mode 100644 docs/configuration/xcm.md rename docs/{Img => img}/GenSet.jpg (100%) rename docs/{Img => img}/Kon_syn.jpg (100%) rename docs/{Img => img}/Konso.jpg (100%) rename docs/{Img => img}/NewUser_Tw.jpg (100%) rename docs/{Img => img}/ProNam.jpg (100%) rename docs/{Img => img}/Prof.jpg (100%) rename docs/{Img => img}/Role_Twingle.jpg (100%) rename docs/{Img => img}/Sepa.jpg (100%) rename docs/{Img => img}/SepaKon.jpg (100%) rename docs/{Img => img}/Twgrou.jpg (100%) rename docs/{Img => img}/Twin_per.png (100%) rename docs/{Img => img}/XCMAdmin.jpg (100%) rename docs/{Img => img}/XCMAkt.jpg (100%) rename docs/{Img => img}/XCMDup.jpg (100%) rename docs/{Img => img}/XCMGen.jpg (100%) rename docs/{Img => img}/XCMIde.jpg (100%) rename docs/{Img => img}/XCMNeu.jpg (100%) rename docs/{Img => img}/XCMPro.jpg (100%) rename docs/{Img => img}/XCMReg.jpg (100%) rename docs/{Img => img}/XCMUpda.jpg (100%) rename docs/{Img => img}/XCM_Profile.jpg (100%) rename docs/{Img => img}/apikey.jpg (100%) rename docs/{Img => img}/civiuser_tw.jpg (100%) rename docs/{Img => img}/twpay.jpg (100%) rename docs/{Img => img}/xcmdif.jpg (100%) delete mode 100644 docs/install_tw.md create mode 100644 docs/installation.md diff --git a/README.md b/README.md index 98fa866..a24d097 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,42 @@ -# CiviCRM extension Twingle API[¶](https://docs.civicrm.org/twingle/en/latest/#twingle-api "Permanent link") +# Twingle API -Twingle is a payment service provider that makes it possible to create donation forms with various payment options and embed them on websites or integrate them into your homepage. Interested parties can donate via known payment options (e.g. credit card, PayPal). The procedure is also set up and optimised for mobile devices. If you want to use the Twingle fundraising service, you have to set up a corresponding online account. +Twingle is a payment service provider that makes it possible to create donation +forms with various payment options and embed them on websites or integrate them +into your homepage. Interested parties can donate via known payment options ( +e.g. credit card, PayPal). The procedure is also set up and optimised for mobile +devices. If you want to use the Twingle fundraising service, you have to set up +a corresponding online account. -For further information about Twingle fundraising follow [this link](https://www.twingle.de/). +For further information about Twingle fundraising +see the [Twingle website](https://www.twingle.de/). -Twingle as fundraising service can be connected to CiviCRM via its API with the extension **Twingle API**. +Twingle as fundraising service can be connected to CiviCRM via its API with the +extension **Twingle API**. -## What advantages does the Twingle API extension offer? +## Features -- Donations from Twingle can be automatically created in CiviCRM and assigned to existing or new contacts and administered yourself in CiviCRM. +* Donations from Twingle can be automatically created as contributions in + CiviCRM and assigned to existing or new contacts and administered in CiviCRM. +* Supporters and contacts of donations can be managed in CiviCRM. +* Donations can be submitted with different payment statuses depending on the + payment type +* SEPA mandates can be created for one-off and recurring payments. +* Donors can be added into groups for receiving newsletters, mailings and + donation receipts. +* A memberships can be set up for a donor. +* Data can be entered in user-defined fields -- Supporters and contacts of donations can be managed yourself in CiviCRM and contacts yourself. +## Configuration -- Donations can be declared as closed or open depending on the payment type - -- SEPA mandates can be created for one-off and recurring payments. - -- Donors can be entered into groups for newsletters, mailings and donation receipts. - -- A memberships can be set up for a donor. - -- Data can be entered in user-defined fields - -## How to set up the Twingle API extension - -Following the successful installation of the Twingle API extension, there is some configuration work to do in order to set up the smooth connection between CiviCRM and Twingle fundraising service. +Following the successful installation of the Twingle API extension, there is +some configuration work to do in order to set up the smooth connection between +CiviCRM and Twingle fundraising service. You have to carry out the following configuration steps: -- Creating a Twingle user and a user role in your CMS-System (Drupal, Wordpress ...) - -- Configuring the Extended Contact Matcher (XCM) in CiviCRM - -- Creating a Twingle User and an API key in CiviCRM - -- Activating the SEPA connection in CiviCRM - -- Configuring the Twingle profile in CiviCRM - -- Configuring your Twingle Account on the Twingle website - - - -The Twingle API extension is licensed under [AGPL-3.0](https://github.com/systopia/de.systopia.twingle/blob/master/LICENSE.txt). \ No newline at end of file +* Creating a Twingle user and a user role in your CMS (Drupal, Wordpress, etc.) +* Configuring the *Extended Contact Matcher (XCM)* in CiviCRM +* Creating a Twingle User and an API key in CiviCRM +* Activating the SEPA connection in CiviCRM (optional) +* Configuring the Twingle profile in CiviCRM +* Configuring your Twingle Account on the Twingle website diff --git a/docs/api_tw.md b/docs/api.md similarity index 99% rename from docs/api_tw.md rename to docs/api.md index d19af35..4165d29 100644 --- a/docs/api_tw.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # API documentation -The extension provides a new CiviCRM API entity `TwingleDonation` with API +The extension provides a new CiviCRM API 3 entity `TwingleDonation` with API actions to record a new donation, end a previously submitted recurring donation and cancel previously submitted donation. @@ -84,4 +84,4 @@ The action accepts the following parameters: You may also refer to [the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Cancel.php) -for more insight into this API action. \ No newline at end of file +for more insight into this API action. diff --git a/docs/con_civi.md b/docs/con_civi.md deleted file mode 100644 index e1289a9..0000000 --- a/docs/con_civi.md +++ /dev/null @@ -1,39 +0,0 @@ -# Twingle API: Creating a Twingle User in CiviCRM - -After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Among other things, certain configurations must be made regarding the general CiviCRM administration. Among other things, there must be in either case a Twingle user in the CiviCRM contacts. - -## Take over user - -The Twingle API only works correctly if a user with the name **Twingle API** exists in CiviCRM. Make sure that you have previously created the corresponding user your CMS user administration (Drupal, Wordpress ...). - -Here, the corresponding steps are described by way of example when using Drupal. - -1. In CiviCRM, go to **Administer**. - -2. In the **Users and Permissions** section, choose **Synchronize Users to Contacts**. - -![](Img/Kon_syn.jpg) - -This function checks each user record in Drupal for a contact record in CiviCRM. If there is no corresponding contact record for a user, a new one will be generated. Check this in your CiviCRM contact management. - -![](Img/civiuser_tw.jpg) - -## Assign API key for the Twingle API user - -The Twingle API user in CiviCRM needs his own API key. The API key is assigned with the help of the API Explorer in CiviCRM. - -1. Select the Twingle API user in CiviCRM. - -2. Look for the corresponding **CiviCRM ID** and remember the ID. - -3. Go to **Support/Developper/API Explorer v4**. - -4. Enter **Contact** in the entity field, **create** in action field and the **ID** of the Twingle User in the **index** field. - -5. In the values field, select **api_key**. - -6. Enter the API key for the Twingle API user in the **add value** field. - -7. Click on **Execute**. - -![](Img/apikey.jpg) diff --git a/docs/con_drup.md b/docs/con_drup.md deleted file mode 100644 index 37a4312..0000000 --- a/docs/con_drup.md +++ /dev/null @@ -1,41 +0,0 @@ -# Twingle API: Creating a Twingle user and a user roll in your CMS system - -After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Among other things, certain configurations must be made on the CMS platform CiviCRM is implemented on. - -In an CMS system, administration of permissions is made easier by creating roles and assigning permissions to them rather than assigning permissions to each user. - -The Twingle API requires a user with the name Twingle API and a user role with the name Twingle API in your CMS-system. - -Here, the corresponding steps are described by way of example when using Drupal. - -## New User Role in Drupal - -1. In Drupal, go to **Administration/People/Permissions/Roles**. - -2. Type Twingle API in the text box and select **Add role**. To the right of your role there will be a *edit role* function and an *edit permissions* button. The *edit permissions* selection will show only the permission selections for the individual role. - -3. As Permission you only have to select the following entry: **Twingle API: Access Twingle API**. - -## New User Role in Wordpress - -1. In CiviCRM, go to **Administer/User and Permissions (Access Control)**. - -2. Then select the **WordPress Access Control** link. - Here you can adjust the CiviCRM settings for each of the predefined User Roles from WordPress. - -3. Scroll down. As Permission you only have to select the following entry: **Twingle API: Access Twingle API**. - - -![](Img/Twin_per.png) - -## New User in Drupal - -1. In Drupal, go to **Administration/People**. - -2. Then select **Add user**. - -3. In user name field enter **Twingle API** - -4. In the e-mail field enter either **info@example.de** or **mailtest@example.de**. - -5. In Roles select **Twingle API**. diff --git a/docs/con_man.md b/docs/con_man.md deleted file mode 100644 index d943158..0000000 --- a/docs/con_man.md +++ /dev/null @@ -1,22 +0,0 @@ -# Twingle API: Configuring the Twingle account on the Twingle website - -The use of the Twingle API extension requires that you already have a Twingle account and that you make some settings in this account for the connection. - -You will have to make the following settings: - -1. API key from your Twingle user - -2. Site key - -3. URL - -Important: The URL must always be the complete URL to the interface. -Examples: - -- Drupal: https://meine-domain.de/sites/all/modules/civicrm/extern/rest.php -- Wordpress (with CiviCRM <5.25): https://meine-domain.de/wp-content/plugins/civicrm/civicrm/extern/rest.php -- Wordpress (with CiviCRM 5.25+): https://meine-domain.de/wp-json/civicrm/v3/rest - - - -[For detailled information please follow this link](https://support.twingle.de/faq/de-de/9-anbindung-externer-systeme/46-wie-kann-ich-civicrm-mit-twingle-nutzen) (in German language only). diff --git a/docs/con_tw.md b/docs/con_tw.md deleted file mode 100644 index 470b36c..0000000 --- a/docs/con_tw.md +++ /dev/null @@ -1,31 +0,0 @@ -# Configuring the Twingle Profile in CiviCRM - -After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Among other things, you have to make some settings in the Twingle Profile in CiviCRM. - -1. In CiviCRM, go to **Administer**. - -2. Choose **Twingle API configuration**. - - ![](Img/Konso.jpg) - -3. Then click on **Configure profiles**. - - ![](Img/SepaKon.jpg) - -4. The Twingle configuration is always done with the help of a profile. Please use the Twingle default profile and click on **Edit**. - - ![](Img/Prof.jpg) - -5. Then you will identify the Twingle API profile window. Start by entering the corresponding information in the **General settings** section. - - ![](Img/GenSet.jpg) - -6. Define the different payment methods in the Payments section. - - ![](Img/twpay.jpg) - -7. Make the settings for the groups. - - ![](Img/Twgrou.jpg) - -8. When you have made all the settings, please press the **Save** button. diff --git a/docs/con_twse.md b/docs/con_twse.md deleted file mode 100644 index aaf7f4c..0000000 --- a/docs/con_twse.md +++ /dev/null @@ -1,25 +0,0 @@ -# Activating SEPA for the Twingle API extension in CiviCRM - -After the installation of the extension, various configuration steps must be carried out so that the connection functions smoothly. If you would like to create and manage the SEPA mandates yourself for the one-off and recurring payments with CiviCRM, you have to make some settings regarding the SEPA connection. - -1. In CiviCRM, go to **Administer**. - -2. Choose **Twingle API configuration**. - - ![](Img/Konso.jpg) - -3. Then click on **Configure extension settings**. - - ![](Img/SepaKon.jpg) - -4. Tick the boxes **Use CiviSEPA** and **Use CiviSEPA generated reference**. - These options can only be activated if CiviSEPA is installed and used. If it is not activated, the administration of SEPA mandates takes place in Twingle. - -5. Write **TW-** in the **Twingle ID Prefix** field. - To avoid overlaps when assigning CiviCRM IDs and Twingle transaction IDs, a prefix should be assigned here, e.g. "TWNGL" or "Twingle" or similar. - Attention: The prefix should not be changed later, otherwise problems may occur. - -6. In the **Protect Recurring Contributions** field select **No**. - If you choose Yes, all recurring donations created by Twingle can no longer be changed in CiviCRM, but must then be changed accordingly in Twingle. If no recurring payments are processed via Twingle, but only one-off donations, then this does not need to be activated. Otherwise, we strongly recommend setting the button here to **Yes** so that there are no discrepancies between CiviCRM and Twingle. - - ![](Img/Sepa.jpg) diff --git a/docs/con_xcm.md b/docs/con_xcm.md deleted file mode 100644 index 0087ca1..0000000 --- a/docs/con_xcm.md +++ /dev/null @@ -1,59 +0,0 @@ -# Twingle API: Configuring the Extended Contact Manager extension (XCM) - -After the installation of the Twingle API extension, various configuration steps must be carried out so that the connection functions smoothly. Twingle API works only correctly when you have previously installed the Extended Contact Manager extension (XCM). - -Taking over contact data using the Twingle API means that they may produce duplicates in your CiviCRM contact management. Before contacts are added or updated in CiviCRM a data check should take place to avoid this problem. This data check is handled by the Extended Contact Manager extension (XCM). This extension must be configured accordingly for use with Twingle by defining a corresponding profile. - -## Creating a Twingle Profile - -Your first task regarding the Extended Contact Manager extension (XCM) configuration will be to create a corresponding Twinge profile. This works best if you copy the Default profile. - -1. In CiviCRM, go to **Administer**. - -2. Select **Xtended Contact Matcher (XCM) Configuration** in the **System Settings** section. - -![](Img/XCMAdmin.jpg) - -3. Click on **Copy** in the **Default** profile. - -4. Rename the new profile with **Twingle** in the **Profile name** field. - -![](Img/ProNam.jpg) - -5. Click **Save** at the bottom of this window. In the Profiles overview you can find your new Twingle profile. - -![](Img/XCM_Profile.jpg) - -## Set up the Extended Contact Manager extension (XCM) - -After you have created the Twingle profile, you must enter the configuration settings for the Twingle connection to CiviCRM in this profile. Generally, you will find a description of all the settings in the [Extended Contact Manager (XCM) documentation](https://docs.civicrm.org/xcm/en/latest/configuration/). - -Here you will find as support screenshots of the various sections of the Extended Contact Manager extension (XCM). The settings are only an example. Please adapt the settings to your individual requirements or environnement. - -#### General section - -![](Img/XCMGen.jpg) - -#### Update section - -![](Img/XCMUpda.jpg) - -#### Assignment rules section - -![](Img/XCMReg.jpg) - -#### Identified contacts section - -![](Img/XCMIde.jpg) - -#### New contact section - -![](Img/XCMNeu.jpg) - -#### Duplicate section - -![](Img/XCMDup.jpg) - -#### Difference Handling section - -![](Img/xcmdif.jpg) diff --git a/docs/configuration/account.md b/docs/configuration/account.md new file mode 100644 index 0000000..c141036 --- /dev/null +++ b/docs/configuration/account.md @@ -0,0 +1,27 @@ +# Twingle account settings on the Twingle website + +The use of the Twingle API extension requires that you already have a Twingle +account and that you make some settings in this account for the connection. + +You will have to provide the following settings in your Twingle account settings +in order to send donations to CiviCRM: + +1. API key from your Twingle user +2. Site key +3. URL + +Important: The URL must always be the complete URL to the CiviCRM REST API +endpoint. +Examples: + +- Drupal (with the *AuthX* extension): https://example.org/civicrm/ajax/rest +- Drupal (legacy + method): https://example.org/sites/all/modules/civicrm/extern/rest.php +- Wordpress (with CiviCRM < + 5.25): https://example.org/wp-content/plugins/civicrm/civicrm/extern/rest.php +- Wordpress (with CiviCRM + 5.25+): https://example.org/wp-json/civicrm/v3/rest + +For detailled information, please see +the [Twingle documentation](https://support.twingle.de/faq/de-de/9-anbindung-externer-systeme/46-wie-kann-ich-civicrm-mit-twingle-nutzen) ( +in German language only). diff --git a/docs/configuration/civisepa.md b/docs/configuration/civisepa.md new file mode 100644 index 0000000..28dbef2 --- /dev/null +++ b/docs/configuration/civisepa.md @@ -0,0 +1,32 @@ +# Activating CiviSEPA integration + +The Twingle API extension provides integration with the [ +*CiviSEPA*](https://civicrm.org/extensions/civisepa-sepa-direct-debit-extension) +extension. This allows for managing SEPA mandates and collections with +*CiviSEPA* for donations being initiated via a *Twingle* form. + +1. In CiviCRM, go to **Administer**. +2. Choose **Twingle API configuration**. + ![](../img/Konso.jpg) + +3. Then click on **Configure extension settings**. + ![](../img/SepaKon.jpg) + +4. Tick the boxes **Use CiviSEPA** and **Use CiviSEPA generated reference**. + These options can only be activated if CiviSEPA is installed and used. If it + is not activated, the administration of SEPA mandates will have to take place + in Twingle, which is subject to configuration of your available payment + methods. +5. Write **TW-** in the **Twingle ID Prefix** field. + To avoid overlaps when assigning CiviCRM IDs and Twingle transaction IDs, a + prefix should be assigned here, e.g. "TWNGL" or "Twingle" or similar. + Attention: The prefix should not be changed later, otherwise problems may + occur. +6. In the **Protect Recurring Contributions** field select **No**. + If you choose Yes, all recurring donations created by Twingle can no longer + be changed in CiviCRM, but must then be changed accordingly in Twingle. If no + recurring payments are processed via Twingle, but only one-off donations, + then this does not need to be activated. Otherwise, we strongly recommend + setting the button here to **Yes** so that there are no discrepancies between + CiviCRM and Twingle. + ![](../img/Sepa.jpg) diff --git a/docs/configuration/profiles.md b/docs/configuration/profiles.md new file mode 100644 index 0000000..34612c1 --- /dev/null +++ b/docs/configuration/profiles.md @@ -0,0 +1,30 @@ +# Configuring the Twingle Profile in CiviCRM + +The Twingle API extension is being configured through configuration profiles. +This allows you to have different sets of configuration, as you might want to +handle donation submissions differently, depending on which form was used. +Each profile can react to one ore more form IDs being submitted along with +donation data. + +1. In CiviCRM, go to **Administer**. +2. Choose **Twingle API configuration**. + ![](../img/Konso.jpg) + +3. Then click on **Configure profiles**. + ![](../img/SepaKon.jpg) + +4. The Twingle configuration is always done with the help of a profile. Please + use the Twingle default profile and click on **Edit**. + ![](../img/Prof.jpg) + +5. Then you will identify the Twingle API profile window. Start by entering the + corresponding information in the **General settings** section. + ![](../img/GenSet.jpg) + +6. Define the different payment methods in the Payments section. + ![](../img/twpay.jpg) + +7. Make the settings for the groups. + ![](../img/Twgrou.jpg) + +8. When you have made all the settings, please press the **Save** button. diff --git a/docs/configuration/user_permissions.md b/docs/configuration/user_permissions.md new file mode 100644 index 0000000..68e81ef --- /dev/null +++ b/docs/configuration/user_permissions.md @@ -0,0 +1,82 @@ +# User, permissions, and API authentication + +After the installation of the Twingle API extension, various configuration steps +must be carried out so that the connection functions smoothly. Among other +things, certain configurations must be made on the CMS platform CiviCRM is +implemented on. + +Connecting to the Twingle API via CiviCRM's REST interface requires a user with +appropriate permissions in your CMS-system. + +You might want to create a specific user role to assign permissions necessary +for calling the Twingle API only. This section describes how to accomplish this +in *Drupal* and *Wordpress*: + +## New User Role in Drupal + +1. In Drupal, go to **Administration/People/Permissions/Roles**. +2. Type Twingle API in the text box and select **Add role**. To the right of + your role there will be a *edit role* function and an *edit permissions* + button. The *edit permissions* selection will show only the permission + selections for the individual role. +3. As Permission you only have to select the following entry: **Twingle API: + Access Twingle API**. + +## New User Role in Wordpress + +1. In CiviCRM, go to **Administer/User and Permissions (Access Control)**. +2. Then select the **WordPress Access Control** link. + Here you can adjust the CiviCRM settings for each of the predefined User + Roles from WordPress. +3. Scroll down. As Permission you only have to select the following entry: * + *Twingle API: Access Twingle API**. + +![](../img/Twin_per.png) + +## New User in Drupal + +1. In Drupal, go to **Administration/People**. +2. Then select **Add user**. +3. In user name field enter something like **Twingle API** +5. In Roles select **Twingle API**. + +## Take over user + +The Twingle API only works correctly if a contact connected to the permissioned +user exists in CiviCRM. + +Here, the corresponding steps are described by way of example when using Drupal. + +1. In CiviCRM, go to **Administer**. +2. In the **Users and Permissions** section, choose **Synchronize Users to + Contacts**. + +![](../img/Kon_syn.jpg) + +This function checks each user record in Drupal for a contact record in CiviCRM. +If there is no corresponding contact record for a user, a new one will be +generated. Check this in your CiviCRM contact management. + +![](../img/civiuser_tw.jpg) + +## Assign API key for the Twingle API user + +The Twingle API contact in CiviCRM needs their own API key for authenticating +against CiviCRM's REST API endpoint. The API key is assigned with the help of +the API Explorer in CiviCRM. + +1. Select the Twingle API contact in CiviCRM. +2. Look for the corresponding **CiviCRM ID** and remember the ID. +3. Go to **Support/Developper/API Explorer v4**. +4. Enter **Contact** in the entity field, **create** in action field and the + **ID** of the Twingle User in the **index** field. +5. In the values field, select **api_key**. +6. Enter the API key for the Twingle API user in the **add value** field. +7. Click on **Execute**. + +![](../img/apikey.jpg) + +!!!note + You can also create API keys for contacts by using the [*API + Key*](https://civicrm.org/extensions/api-key) extension or with administrator + tools like *cv* or *drush*. diff --git a/docs/configuration/xcm.md b/docs/configuration/xcm.md new file mode 100644 index 0000000..87d36e5 --- /dev/null +++ b/docs/configuration/xcm.md @@ -0,0 +1,75 @@ +# Configuring the Extended Contact Manager extension (XCM) + +After the installation of the Twingle API extension, various configuration steps +must be carried out so that the connection functions smoothly. Twingle API +depends on the *Extended Contact Manager (XCM)* extension. + +Taking over contact data using the Twingle API means that they may produce +duplicates in your CiviCRM contact management. Before contacts are added or +updated in CiviCRM a data check should take place to avoid this problem. This +data check is handled by the *Extended Contact Manager (XCM)* extension. This +extension must be configured accordingly for use with Twingle by defining a +corresponding profile. + +## Creating an XCM Profile + +Your first task regarding the Extended Contact Manager extension (XCM) +configuration will be to create an XCM profile to be used for the Twingle API. +This works best if you copy the *Default* profile. + +1. In CiviCRM, go to **Administer**. + +2. Select **Xtended Contact Matcher (XCM) Configuration** in the **System + Settings** section. + +![](../img/XCMAdmin.jpg) + +3. Click on **Copy** in the **Default** profile. + +4. Rename the new profile with **Twingle** in the **Profile name** field. + +![](../img/ProNam.jpg) + +5. Click **Save** at the bottom of this window. In the Profiles overview you can + find your new Twingle profile. + +![](../img/XCM_Profile.jpg) + +## Set up the Extended Contact Manager extension + +After you have created the XCM profile, you must enter the configuration +settings for the Twingle connection to CiviCRM in this profile. Generally, you +will find a description of all the settings in +the [Extended Contact Manager (XCM) documentation](https://docs.civicrm.org/xcm/en/latest/configuration/). + +Here you will find as support screenshots of the various sections of the +Extended Contact Manager extension (XCM). The settings are only an example. +Please adapt the settings to your individual requirements or environnement. + +#### General section + +![](../img/XCMGen.jpg) + +#### Update section + +![](../img/XCMUpda.jpg) + +#### Assignment rules section + +![](../img/XCMReg.jpg) + +#### Identified contacts section + +![](../img/XCMIde.jpg) + +#### New contact section + +![](../img/XCMNeu.jpg) + +#### Duplicate section + +![](../img/XCMDup.jpg) + +#### Difference Handling section + +![](../img/xcmdif.jpg) diff --git a/docs/Img/GenSet.jpg b/docs/img/GenSet.jpg similarity index 100% rename from docs/Img/GenSet.jpg rename to docs/img/GenSet.jpg diff --git a/docs/Img/Kon_syn.jpg b/docs/img/Kon_syn.jpg similarity index 100% rename from docs/Img/Kon_syn.jpg rename to docs/img/Kon_syn.jpg diff --git a/docs/Img/Konso.jpg b/docs/img/Konso.jpg similarity index 100% rename from docs/Img/Konso.jpg rename to docs/img/Konso.jpg diff --git a/docs/Img/NewUser_Tw.jpg b/docs/img/NewUser_Tw.jpg similarity index 100% rename from docs/Img/NewUser_Tw.jpg rename to docs/img/NewUser_Tw.jpg diff --git a/docs/Img/ProNam.jpg b/docs/img/ProNam.jpg similarity index 100% rename from docs/Img/ProNam.jpg rename to docs/img/ProNam.jpg diff --git a/docs/Img/Prof.jpg b/docs/img/Prof.jpg similarity index 100% rename from docs/Img/Prof.jpg rename to docs/img/Prof.jpg diff --git a/docs/Img/Role_Twingle.jpg b/docs/img/Role_Twingle.jpg similarity index 100% rename from docs/Img/Role_Twingle.jpg rename to docs/img/Role_Twingle.jpg diff --git a/docs/Img/Sepa.jpg b/docs/img/Sepa.jpg similarity index 100% rename from docs/Img/Sepa.jpg rename to docs/img/Sepa.jpg diff --git a/docs/Img/SepaKon.jpg b/docs/img/SepaKon.jpg similarity index 100% rename from docs/Img/SepaKon.jpg rename to docs/img/SepaKon.jpg diff --git a/docs/Img/Twgrou.jpg b/docs/img/Twgrou.jpg similarity index 100% rename from docs/Img/Twgrou.jpg rename to docs/img/Twgrou.jpg diff --git a/docs/Img/Twin_per.png b/docs/img/Twin_per.png similarity index 100% rename from docs/Img/Twin_per.png rename to docs/img/Twin_per.png diff --git a/docs/Img/XCMAdmin.jpg b/docs/img/XCMAdmin.jpg similarity index 100% rename from docs/Img/XCMAdmin.jpg rename to docs/img/XCMAdmin.jpg diff --git a/docs/Img/XCMAkt.jpg b/docs/img/XCMAkt.jpg similarity index 100% rename from docs/Img/XCMAkt.jpg rename to docs/img/XCMAkt.jpg diff --git a/docs/Img/XCMDup.jpg b/docs/img/XCMDup.jpg similarity index 100% rename from docs/Img/XCMDup.jpg rename to docs/img/XCMDup.jpg diff --git a/docs/Img/XCMGen.jpg b/docs/img/XCMGen.jpg similarity index 100% rename from docs/Img/XCMGen.jpg rename to docs/img/XCMGen.jpg diff --git a/docs/Img/XCMIde.jpg b/docs/img/XCMIde.jpg similarity index 100% rename from docs/Img/XCMIde.jpg rename to docs/img/XCMIde.jpg diff --git a/docs/Img/XCMNeu.jpg b/docs/img/XCMNeu.jpg similarity index 100% rename from docs/Img/XCMNeu.jpg rename to docs/img/XCMNeu.jpg diff --git a/docs/Img/XCMPro.jpg b/docs/img/XCMPro.jpg similarity index 100% rename from docs/Img/XCMPro.jpg rename to docs/img/XCMPro.jpg diff --git a/docs/Img/XCMReg.jpg b/docs/img/XCMReg.jpg similarity index 100% rename from docs/Img/XCMReg.jpg rename to docs/img/XCMReg.jpg diff --git a/docs/Img/XCMUpda.jpg b/docs/img/XCMUpda.jpg similarity index 100% rename from docs/Img/XCMUpda.jpg rename to docs/img/XCMUpda.jpg diff --git a/docs/Img/XCM_Profile.jpg b/docs/img/XCM_Profile.jpg similarity index 100% rename from docs/Img/XCM_Profile.jpg rename to docs/img/XCM_Profile.jpg diff --git a/docs/Img/apikey.jpg b/docs/img/apikey.jpg similarity index 100% rename from docs/Img/apikey.jpg rename to docs/img/apikey.jpg diff --git a/docs/Img/civiuser_tw.jpg b/docs/img/civiuser_tw.jpg similarity index 100% rename from docs/Img/civiuser_tw.jpg rename to docs/img/civiuser_tw.jpg diff --git a/docs/Img/twpay.jpg b/docs/img/twpay.jpg similarity index 100% rename from docs/Img/twpay.jpg rename to docs/img/twpay.jpg diff --git a/docs/Img/xcmdif.jpg b/docs/img/xcmdif.jpg similarity index 100% rename from docs/Img/xcmdif.jpg rename to docs/img/xcmdif.jpg diff --git a/docs/install_tw.md b/docs/install_tw.md deleted file mode 100644 index 9f90aec..0000000 --- a/docs/install_tw.md +++ /dev/null @@ -1,12 +0,0 @@ -# Installation Twingle API - -You can find an official release archive from the [release page](https://github.com/systopia/de.systopia.twingle). - -1. First, download and then unpack the archive and move the directory into your CiviCRM extensions folder (e.g., `.../civicrm/ext/`. - If you don't know where your extensions folder is, just have a look in your CiviCRM settings ( **Administer**/**System Settings**/**Directories**)). -2. Next, open the extensions page in the CiviCRM settings (**Administer**/**System Settings**/**Extensions**). -3. Find the extension Twingle API in the *Extensions* tab and click on **Install**. The extension will be set up. - -## Extended Contact Matcher (XCM) - -Please note that for the correct working of Twingle API you still need to install the extension Extended Contact Matcher (XCM). You can find the corresponding information therefore [here](https://docs.civicrm.org/xcm/en/latest/). diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..352a50f --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,19 @@ +# Installation + +You can find an official release archive from +the [release page](https://github.com/systopia/de.systopia.twingle). + +1. First, download and then unpack the archive and move the directory into your + CiviCRM extensions folder (e.g.,`.../civicrm/ext/`. + If you don't know where your extensions folder is, just have a look in your + CiviCRM settings ( **Administer**/**System Settings**/**Directories**)). +2. Next, open the extensions page in the CiviCRM settings (**Administer**/* + *System Settings**/**Extensions**). +3. Find the extension Twingle API in the*Extensions*tab and click on**Install**. + The extension will be set up. + +## Extended Contact Matcher (XCM) + +Please note that for the correct working of Twingle API you still need to +install the extension Extended Contact Matcher (XCM), see +the [documentation](https://docs.civicrm.org/xcm). diff --git a/mkdocs.yml b/mkdocs.yml index d6d4222..6fe26ca 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,28 +1,32 @@ site_name: Twingle API -theme: +theme: name: material nav: -- Home: index.md -- Installation: install_tw.md -- Configuration: - - Creating a Twingle user in the CMS system: con_drup.md - - Configuring the Extended Contact Manager extension: con_xcm.md - - Creating a Twingle user in CiviCRM: con_civi.md - - Activating SEPA for the Twingle API extension in CiviCRM: con_twse.md - - Configuring the Twingle Profile in CiviCRM: con_tw.md - - Configuring the Twingle Account on the Twingle website: con_man.md - - API documentation: api_tw.md + - Introduction: index.md + - Installation: installation.md + - Configuration: + - User, permissions and API authentication: configuration/user_permissions.md + - Extended Contact Manager (XCM) extension: configuration/xcm.md + - CiviSEPA integration: configuration/civisepa.md + - Twingle Profiles: configuration/profiles.md + - Configuring the Twingle Account on the Twingle website: configuration/account.md + - API documentation: api.md markdown_extensions: -- attr_list -- admonition -- def_list -- codehilite -- toc: - permalink: true -- pymdownx.superfences -- pymdownx.inlinehilite -- pymdownx.tilde -- pymdownx.betterem -- pymdownx.mark + - attr_list + - admonition + - def_list + - pymdownx.highlight: + guess_lang: false + - toc: + permalink: true + - pymdownx.superfences + - pymdownx.inlinehilite + - pymdownx.tilde + - pymdownx.betterem + - pymdownx.mark + +plugins: + - search: + lang: en \ No newline at end of file From 3b643b2e54d6b8fb5e88977bee17796c4d1a8645 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 14 Mar 2023 15:22:23 +0100 Subject: [PATCH 081/221] Add repo URL to mkdocs configuration --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 6fe26ca..2765312 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,5 @@ site_name: Twingle API +repo_url: https://github.com/systopia/de.systopia.twingle theme: name: material From 945992d8beb919d8c1eb7f2efa435ed2ddf9d235 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 14 Mar 2023 15:36:50 +0100 Subject: [PATCH 082/221] Add missing "pi_" prefixes for new payment instruments --- CRM/Twingle/Profile.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 4491fbe..2e052d2 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -284,11 +284,11 @@ class CRM_Twingle_Profile { 'pi_paydirekt' => E::ts('paydirekt'), 'pi_applepay' => E::ts('Apple Pay'), 'pi_googlepay' => E::ts('Google Pay'), - 'paydirekt' => E::ts('Paydirekt'), - 'twint' => E::ts('Twint'), - 'ideal' => E::ts('iDEAL'), - 'post_finance' => E::ts('Postfinance'), - 'bancontact' => E::ts('Bancontact'), + 'pi_paydirekt' => E::ts('Paydirekt'), + 'pi_twint' => E::ts('Twint'), + 'pi_ideal' => E::ts('iDEAL'), + 'pi_post_finance' => E::ts('Postfinance'), + 'pi_bancontact' => E::ts('Bancontact'), ]; } From b581b37838387cc1fa411b76085b4a66cc26a605 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 14 Mar 2023 15:37:21 +0100 Subject: [PATCH 083/221] Version 1.4-alpha3 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index abcb061..4bf0f11 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.4-dev - dev + 2023-03-14 + 1.4-alpha3 + alpha 5.0 5.19 From c88be905326ea862315bf8d6608b73f395fde9a8 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 14 Mar 2023 15:37:35 +0100 Subject: [PATCH 084/221] Back to dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 4bf0f11..abcb061 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2023-03-14 - 1.4-alpha3 - alpha + + 1.4-dev + dev 5.0 5.19 From c62af9582eb3739c439efbedc9a229c46f2c6251 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 14 Feb 2023 09:27:04 +0100 Subject: [PATCH 085/221] [#61] fix bug on settings page The array passed to $this->addEntityRef() was incorrectly structured --- CRM/Twingle/Form/Settings.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index dba6a28..631fb05 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -90,12 +90,16 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { ); $this->addEntityRef( - 'twingle_protect_recurring_activity_assignee', - E::ts('Assigned To'), - [ - 'contact_type' => ['IN' => ['Individual', 'Organization']], + 'twingle_protect_recurring_activity_assignee', + E::ts('Assigned To'), + [ + 'api' => [ + 'params' => [ + 'contact_type' => ['IN' => ['Individual', 'Organization']], 'check_permissions' => 0, - ] + ], + ], + ] ); $this->addButtons(array( From b9f1e321009ac2ddc7039411b75211f2e9ea9981 Mon Sep 17 00:00:00 2001 From: peth-systopia Date: Fri, 21 Apr 2023 15:19:02 +0200 Subject: [PATCH 086/221] Update README.md --- README.md | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index a24d097..0568a6b 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,5 @@ # Twingle API -Twingle is a payment service provider that makes it possible to create donation -forms with various payment options and embed them on websites or integrate them -into your homepage. Interested parties can donate via known payment options ( -e.g. credit card, PayPal). The procedure is also set up and optimised for mobile -devices. If you want to use the Twingle fundraising service, you have to set up -a corresponding online account. +This extension integrates [Twingle donation and membership forms](https://www.twingle.de/) with CiviCRM. -For further information about Twingle fundraising -see the [Twingle website](https://www.twingle.de/). - -Twingle as fundraising service can be connected to CiviCRM via its API with the -extension **Twingle API**. - -## Features - -* Donations from Twingle can be automatically created as contributions in - CiviCRM and assigned to existing or new contacts and administered in CiviCRM. -* Supporters and contacts of donations can be managed in CiviCRM. -* Donations can be submitted with different payment statuses depending on the - payment type -* SEPA mandates can be created for one-off and recurring payments. -* Donors can be added into groups for receiving newsletters, mailings and - donation receipts. -* A memberships can be set up for a donor. -* Data can be entered in user-defined fields - -## Configuration - -Following the successful installation of the Twingle API extension, there is -some configuration work to do in order to set up the smooth connection between -CiviCRM and Twingle fundraising service. - -You have to carry out the following configuration steps: - -* Creating a Twingle user and a user role in your CMS (Drupal, Wordpress, etc.) -* Configuring the *Extended Contact Matcher (XCM)* in CiviCRM -* Creating a Twingle User and an API key in CiviCRM -* Activating the SEPA connection in CiviCRM (optional) -* Configuring the Twingle profile in CiviCRM -* Configuring your Twingle Account on the Twingle website +You can read the full documentation, including installation and configuration instructions and API specification, [here](https://docs.civicrm.org/twingle/en/latest/). From 018d2f2ac34b23a62b4b47a95541b2c84e67e8c8 Mon Sep 17 00:00:00 2001 From: peth-systopia Date: Fri, 21 Apr 2023 15:24:55 +0200 Subject: [PATCH 087/221] Delete index.md --- docs/index.md | 1 - 1 file changed, 1 deletion(-) delete mode 120000 docs/index.md diff --git a/docs/index.md b/docs/index.md deleted file mode 120000 index 32d46ee..0000000 --- a/docs/index.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file From f4dfc4b9374f160aa997dea3ba0215552ecdcef6 Mon Sep 17 00:00:00 2001 From: peth-systopia Date: Fri, 21 Apr 2023 15:28:40 +0200 Subject: [PATCH 088/221] Create index.md --- docs/index.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs/index.md diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..0d2ede0 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,15 @@ +# Twingle API +Twingle is a payment service provider that makes it possible to create donation forms with various payment options and embed them on websites or integrate them into your homepage. Interested parties can donate via known payment options ( e.g. credit card, PayPal). The procedure is also set up and optimised for mobile devices. If you want to use the Twingle fundraising service, you have to set up a corresponding online account. + +For further information about Twingle fundraising see the [Twingle](https://www.twingle.de) website. + +Twingle as fundraising service can be connected to CiviCRM via its API with the extension Twingle API. + +## Features¶ +* Donations from Twingle can be automatically created as contributions in CiviCRM and assigned to existing or new contacts and administered in CiviCRM. +* Supporters and contacts of donations can be managed in CiviCRM. +* Donations can be submitted with different payment statuses depending on the payment type +* SEPA mandates can be created for one-off and recurring payments. +* Donors can be added to groups for receiving newsletters, mailings and donation receipts. +* A memberships can be set up for a donor. +* Data can be entered in user-defined fields From aae3a6b6f102da2c972dbc9f94181b98ca569a21 Mon Sep 17 00:00:00 2001 From: peth-systopia Date: Fri, 21 Apr 2023 15:29:13 +0200 Subject: [PATCH 089/221] Update index.md --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 0d2ede0..8099f7b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,7 +5,7 @@ For further information about Twingle fundraising see the [Twingle](https://www. Twingle as fundraising service can be connected to CiviCRM via its API with the extension Twingle API. -## Features¶ +## Features * Donations from Twingle can be automatically created as contributions in CiviCRM and assigned to existing or new contacts and administered in CiviCRM. * Supporters and contacts of donations can be managed in CiviCRM. * Donations can be submitted with different payment statuses depending on the payment type From 518f8809c7d8167c350b0ba3afd7f59da540661a Mon Sep 17 00:00:00 2001 From: peth-systopia Date: Fri, 21 Apr 2023 15:51:28 +0200 Subject: [PATCH 090/221] Update index.md --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 8099f7b..8abbdd0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,5 +11,5 @@ Twingle as fundraising service can be connected to CiviCRM via its API with the * Donations can be submitted with different payment statuses depending on the payment type * SEPA mandates can be created for one-off and recurring payments. * Donors can be added to groups for receiving newsletters, mailings and donation receipts. -* A memberships can be set up for a donor. +* A membership can be set up for a donor. * Data can be entered in user-defined fields From bd6c60c5390a587a09135a4916b4091a033a64ac Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Mon, 15 May 2023 12:03:32 +0200 Subject: [PATCH 091/221] replaced old debug-log call with current one. --- CRM/Twingle/Upgrader/Base.php | 2 +- api/v3/TwingleDonation/Cancel.php | 2 +- api/v3/TwingleDonation/Endrecurring.php | 2 +- api/v3/TwingleDonation/Submit.php | 2 +- info.xml | 1 - 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CRM/Twingle/Upgrader/Base.php b/CRM/Twingle/Upgrader/Base.php index 5f48218..07e9629 100644 --- a/CRM/Twingle/Upgrader/Base.php +++ b/CRM/Twingle/Upgrader/Base.php @@ -274,7 +274,7 @@ class CRM_Twingle_Upgrader_Base { $setting = new CRM_Core_BAO_Setting(); $setting->name = $this->extensionName . ':version'; $setting->delete(); - CRM_Core_Error::debug_log_message("Migrated extension schema revision ID for {$this->extensionName} from civicrm_setting (deprecated) to civicrm_extension.\n"); + Civi::log()->debug("Migrated extension schema revision ID for {$this->extensionName} from civicrm_setting (deprecated) to civicrm_extension.\n"); } } diff --git a/api/v3/TwingleDonation/Cancel.php b/api/v3/TwingleDonation/Cancel.php index e3dee49..e007059 100644 --- a/api/v3/TwingleDonation/Cancel.php +++ b/api/v3/TwingleDonation/Cancel.php @@ -67,7 +67,7 @@ function _civicrm_api3_twingle_donation_Cancel_spec(&$params) { function civicrm_api3_twingle_donation_Cancel($params) { // Log call if debugging is enabled within civicrm.settings.php. if (defined('TWINGLE_API_LOGGING') && TWINGLE_API_LOGGING) { - CRM_Core_Error::debug_log_message('TwingleDonation.Cancel: ' . json_encode($params, JSON_PRETTY_PRINT)); + Civi::log()->debug('TwingleDonation.Cancel: ' . json_encode($params, JSON_PRETTY_PRINT)); } try { diff --git a/api/v3/TwingleDonation/Endrecurring.php b/api/v3/TwingleDonation/Endrecurring.php index 12c93c4..9daa59b 100644 --- a/api/v3/TwingleDonation/Endrecurring.php +++ b/api/v3/TwingleDonation/Endrecurring.php @@ -60,7 +60,7 @@ function _civicrm_api3_twingle_donation_endrecurring_spec(&$params) { function civicrm_api3_twingle_donation_endrecurring($params) { // Log call if debugging is enabled within civicrm.settings.php. if (defined('TWINGLE_API_LOGGING') && TWINGLE_API_LOGGING) { - CRM_Core_Error::debug_log_message('TwingleDonation.Endrecurring: ' . json_encode($params, JSON_PRETTY_PRINT)); + Civi::log()->debug('TwingleDonation.Endrecurring: ' . json_encode($params, JSON_PRETTY_PRINT)); } try { diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 4e3e6dd..5579675 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -265,7 +265,7 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { function civicrm_api3_twingle_donation_Submit($params) { // Log call if debugging is enabled within civicrm.settings.php. if (defined('TWINGLE_API_LOGGING') && TWINGLE_API_LOGGING) { - CRM_Core_Error::debug_log_message('TwingleDonation.Submit: ' . json_encode($params, JSON_PRETTY_PRINT)); + Civi::log()->debug('TwingleDonation.Submit: ' . json_encode($params, JSON_PRETTY_PRINT)); } try { diff --git a/info.xml b/info.xml index abcb061..6285f7b 100644 --- a/info.xml +++ b/info.xml @@ -18,7 +18,6 @@ 1.4-dev dev - 5.0 5.19 From ab27dccbe7348956cdba5abee314769c98d06276 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 16 Aug 2023 11:22:54 +0200 Subject: [PATCH 092/221] improve default profile behavior --- CRM/Twingle/Form/Profile.php | 29 ++++++++++++++------------ CRM/Twingle/Page/Profiles.php | 6 ++++-- CRM/Twingle/Profile.php | 22 ++++++++++++++++++- templates/CRM/Twingle/Form/Profile.tpl | 4 +++- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index b95ddc4..0a781d1 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -194,25 +194,28 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Assign template variables. $this->assign('op', $this->_op); $this->assign('profile_name', $profile_name); + $this->assign('is_default', $this->profile->is_default()); // Add form elements. - $is_default = $profile_name == 'default'; - $this->add( - ($is_default ? 'static' : 'text'), - 'name', - E::ts('Profile name'), - array(), - !$is_default - ); - $this->add( 'text', // field type - 'selector', // field name - E::ts('Project IDs'), // field label - ['class' => 'huge'], - TRUE // is required + 'name', // field name + E::ts('Profile name'), + ['class' => 'huge'] + ($this->profile->is_default() && $this->_op == 'edit' ? ['readonly'] : []), + !$this->profile->is_default() ); + // Do only display selector if this is not the default profile + if (!$this->profile->is_default()) { + $this->add( + 'text', // field type + 'selector', // field name + E::ts('Project IDs'), // field label + ['class' => 'huge'], + TRUE // is required + ); + } + $this->add( 'select', 'xcm_profile', diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index eb5bf0c..d3bade3 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -20,8 +20,10 @@ class CRM_Twingle_Page_Profiles extends CRM_Core_Page { public function run() { CRM_Utils_System::setTitle(E::ts("Twingle API Profiles")); $profiles = []; - foreach (CRM_Twingle_Profile::getProfiles() as $profile_name => $profile) { - $profiles[$profile_name]['name'] = $profile_name; + foreach (CRM_Twingle_Profile::getProfiles() as $profile_id => $profile) { + $profiles[$profile_id]['id'] = $profile_id; + $profiles[$profile_id]['name'] = $profile->getName(); + $profiles[$profile_id]['is_default'] = $profile->is_default(); foreach (CRM_Twingle_Profile::allowedAttributes() as $attribute) { $profiles[$profile_name][$attribute] = $profile->getAttribute($attribute); } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 2e052d2..e3e1bb0 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -124,6 +124,15 @@ class CRM_Twingle_Profile { $this->name = $name; } + /** + * Is this the default profile? + * + * @return bool + */ + public function is_default() { + return $this->name == 'default'; + } + /** * Retrieves an attribute of the profile. * @@ -359,18 +368,29 @@ class CRM_Twingle_Profile { * @param $project_id * * @return CRM_Twingle_Profile + * @throws \CRM_Twingle_Exceptions_ProfileException + * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileForProject($project_id) { $profiles = self::getProfiles(); + $default_profile = NULL; foreach ($profiles as $profile) { if ($profile->matches($project_id)) { return $profile; } + if ($profile->is_default()) { + $default_profile = $profile; + } } // If none matches, use the default profile. - return $profiles['default']; + if (!empty($default_profile)) { + return $default_profile; + } + else { + throw new ProfileException('Could not find default profile', ProfileException::ERROR_CODE_DEFAULT_PROFILE_NOT_FOUND); + } } /** diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 00794ef..df54418 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -28,6 +28,7 @@
+ {if not $form.is_default} - + @@ -34,10 +34,16 @@ {foreach from=$profiles item=profile} {assign var="profile_name" value=$profile.name} - + From 225c4efd255c560e3d2d640096d40e6c43f7ffc3 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 14:58:24 +0200 Subject: [PATCH 094/221] remove unnecessary default values --- CRM/Twingle/Form/Profile.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index b95ddc4..fb5ef0c 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -278,22 +278,19 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'select', 'prefix_male', E::ts('Prefix option for submitted value "male"'), - static::getPrefixOptions(), - FALSE + static::getPrefixOptions() ); $this->add( 'select', 'prefix_female', E::ts('Prefix option for submitted value "female"'), - static::getPrefixOptions(), - FALSE + static::getPrefixOptions() ); $this->add( 'select', 'prefix_other', E::ts('Prefix option for submitted value "other"'), - static::getPrefixOptions(), - FALSE + static::getPrefixOptions() ); $payment_instruments = CRM_Twingle_Profile::paymentInstruments(); From 5a9a911c014f71624377754b59467ff1a3a4b61f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 15:06:10 +0200 Subject: [PATCH 095/221] remove duplicate array keys --- CRM/Twingle/Profile.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 2e052d2..2619b32 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -281,7 +281,6 @@ class CRM_Twingle_Profile { 'pi_paypal' => E::ts('PayPal'), 'pi_sofortueberweisung' => E::ts('SOFORT Überweisung'), 'pi_amazonpay' => E::ts('Amazon Pay'), - 'pi_paydirekt' => E::ts('paydirekt'), 'pi_applepay' => E::ts('Apple Pay'), 'pi_googlepay' => E::ts('Google Pay'), 'pi_paydirekt' => E::ts('Paydirekt'), @@ -319,7 +318,6 @@ class CRM_Twingle_Profile { 'pi_paydirekt' => NULL, 'pi_applepay' => NULL, 'pi_googlepay' => NULL, - 'pi_paydirekt' => NULL, 'pi_twint' => NULL, 'pi_ideal' => NULL, 'pi_post_finance' => NULL, From 3644086ab3fc3e2bfe799ac675ff1ecedd637a53 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 15:08:18 +0200 Subject: [PATCH 096/221] set correct value for debit cards --- CRM/Twingle/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 2619b32..b1beb49 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -309,7 +309,7 @@ class CRM_Twingle_Profile { 'financial_type_id_recur' => 1, // "Donation" 'pi_banktransfer' => 5, // "EFT" 'pi_debit_manual' => NULL, - 'pi_debit_automatic' => 3, // Debit + 'pi_debit_automatic' => 2, // Debit 'pi_creditcard' => 1, // "Credit Card" 'pi_mobilephone_germany' => NULL, 'pi_paypal' => NULL, From 0b2b8d6523d1ecda7a0b46d50f9b70fe0d84c0ab Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 15:04:18 +0200 Subject: [PATCH 097/221] do not add the xcm default profile manually as an option it simply does not work --- CRM/Twingle/Form/Profile.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index fb5ef0c..f6df7da 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -613,9 +613,6 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getXCMProfiles() { if (!isset(static::$_xcm_profiles)) { - static::$_xcm_profiles = array( - '' => E::ts("<default profile>"), - ); if (method_exists('CRM_Xcm_Configuration', 'getProfileList')) { $profiles = CRM_Xcm_Configuration::getProfileList(); foreach ($profiles as $profile_key => $profile_name) { From c3f4db86008be6af62717bee2ac1aab45d9aab28 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 15:01:37 +0200 Subject: [PATCH 098/221] replace traditional syntax arrays --- CRM/Twingle/Form/Profile.php | 124 +++++++++++++++++------------------ 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index f6df7da..1148396 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -299,7 +299,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->add( 'select', // field type $pi_name, // field name - E::ts('Record %1 as', array(1 => $pi_label)), // field label + E::ts('Record %1 as', [1 => $pi_label]), // field label static::getPaymentInstruments(), // list of options TRUE // is required ); @@ -307,7 +307,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->add( 'select', $pi_name . '_status', - E::ts('Record %1 donations with contribution status', array(1 => $pi_label)), + E::ts('Record %1 donations with contribution status', [1 => $pi_label]), static::getContributionStatusOptions(), TRUE ); @@ -328,7 +328,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'newsletter_double_opt_in', // field name E::ts('Use Double-Opt-In for newsletter'), // field label FALSE, // is not required - array() + [] ); $this->add( @@ -337,7 +337,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { E::ts('Sign up for newsletter groups'), // field label static::getNewsletterGroups(), // list of options FALSE, // is not required - array('class' => 'crm-select2 huge', 'multiple' => 'multiple') + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( @@ -346,7 +346,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { E::ts('Sign up for postal mail groups'), // field label static::getPostinfoGroups(), // list of options FALSE, // is not required - array('class' => 'crm-select2 huge', 'multiple' => 'multiple') + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( @@ -355,16 +355,16 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { E::ts('Sign up for Donation receipt groups'), // field label static::getDonationReceiptGroups(), // list of options FALSE, // is not required - array('class' => 'crm-select2 huge', 'multiple' => 'multiple') + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( 'select', // field type 'campaign', // field name E::ts('Default Campaign'), // field label - array('' => E::ts('- none -')) + static::getCampaigns(), // list of options + ['' => E::ts('- none -')] + static::getCampaigns(), // list of options FALSE, // is not required - array('class' => 'crm-select2 huge') + ['class' => 'crm-select2 huge'] ); $this->add( @@ -386,17 +386,17 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'select', // field type 'membership_type_id', // field name E::ts('Create membership of type'), // field label - array('' => E::ts('- none -')) + static::getMembershipTypes(), // list of options + ['' => E::ts('- none -')] + static::getMembershipTypes(), // list of options FALSE, // is not required - array('class' => 'crm-select2 huge') + ['class' => 'crm-select2 huge'] ); $this->add( 'select', // field type 'membership_type_id_recur', // field name E::ts('Create membership of type (recurring)'), // field label - array('' => E::ts('- none -')) + static::getMembershipTypes(), // list of options + ['' => E::ts('- none -')] + static::getMembershipTypes(), // list of options FALSE, // is not required - array('class' => 'crm-select2 huge') + ['class' => 'crm-select2 huge'] ); $this->add( 'text', @@ -410,7 +410,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'text', // field type 'contribution_source', // field name E::ts('Contribution source'), // field label - array() + [] ); $this->add( @@ -431,16 +431,16 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'textarea', // field type 'custom_field_mapping', // field name E::ts('Custom field mapping'), // field label - array() + [] ); - $this->addButtons(array( - array( + $this->addButtons([ + [ 'type' => 'submit', 'name' => E::ts('Save'), 'isDefault' => TRUE, - ), - )); + ], + ]); // Export form elements. parent::buildQuickForm(); @@ -544,7 +544,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public function setDefaultValues() { $defaults = parent::setDefaultValues(); - if (in_array($this->_op, array('create', 'edit', 'copy'))) { + if (in_array($this->_op, ['create', 'edit', 'copy'])) { $defaults['name'] = $this->profile->getName(); $profile_data = $this->profile->getData(); foreach ($profile_data as $element_name => $value) { @@ -594,11 +594,11 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getLocationTypes() { if (!isset(static::$_locationTypes)) { - static::$_locationTypes = array(); - $query = civicrm_api3('LocationType', 'get', array( + static::$_locationTypes = []; + $query = civicrm_api3('LocationType', 'get', [ 'option.limit' => 0, 'is_active' => 1, - )); + ]); foreach ($query['values'] as $type) { static::$_locationTypes[$type['id']] = $type['name']; } @@ -633,12 +633,12 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getFinancialTypes() { if (!isset(static::$_financialTypes)) { - static::$_financialTypes = array(); - $query = civicrm_api3('FinancialType', 'get', array( + static::$_financialTypes = []; + $query = civicrm_api3('FinancialType', 'get', [ 'option.limit' => 0, 'is_active' => 1, 'return' => 'id,name' - )); + ]); foreach ($query['values'] as $type) { static::$_financialTypes[$type['id']] = $type['name']; } @@ -656,12 +656,12 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getMembershipTypes() { if (!isset(static::$_membershipTypes)) { - static::$_membershipTypes = array(); - $query = civicrm_api3('MembershipType', 'get', array( + static::$_membershipTypes = []; + $query = civicrm_api3('MembershipType', 'get', [ 'option.limit' => 0, 'is_active' => 1, 'return' => 'id,name' - )); + ]); foreach ($query['values'] as $type) { static::$_membershipTypes[$type['id']] = $type['name']; } @@ -679,16 +679,16 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getGenderOptions() { if (!isset(static::$_genderOptions)) { - static::$_genderOptions = array(); - $query = civicrm_api3('OptionValue', 'get', array( + static::$_genderOptions = []; + $query = civicrm_api3('OptionValue', 'get', [ 'option.limit' => 0, 'option_group_id' => 'gender', 'is_active' => 1, - 'return' => array( + 'return' => [ 'value', 'label', - ), - )); + ], + ]); foreach ($query['values'] as $gender) { static::$_genderOptions[$gender['value']] = $gender['label']; } @@ -706,16 +706,16 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getPrefixOptions() { if (!isset(static::$_prefixOptions)) { - static::$_prefixOptions = array('' => E::ts('none')); - $query = civicrm_api3('OptionValue', 'get', array( + static::$_prefixOptions = ['' => E::ts('none')]; + $query = civicrm_api3('OptionValue', 'get', [ 'option.limit' => 0, 'option_group_id' => 'individual_prefix', 'is_active' => 1, - 'return' => array( + 'return' => [ 'value', 'label', - ), - )); + ], + ]); foreach ($query['values'] as $prefix) { static::$_prefixOptions[$prefix['value']] = $prefix['label']; } @@ -732,11 +732,11 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getSepaCreditors() { if (!isset(static::$_sepaCreditors)) { - static::$_sepaCreditors = array(); + static::$_sepaCreditors = []; if (CRM_Twingle_Submission::civiSepaEnabled()) { - $result = civicrm_api3('SepaCreditor', 'get', array( + $result = civicrm_api3('SepaCreditor', 'get', [ 'option.limit' => 0, - )); + ]); foreach ($result['values'] as $sepa_creditor) { static::$_sepaCreditors[$sepa_creditor['id']] = $sepa_creditor['name']; } @@ -755,13 +755,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getPaymentInstruments() { if (!isset(self::$_paymentInstruments)) { - self::$_paymentInstruments = array(); - $query = civicrm_api3('OptionValue', 'get', array( + self::$_paymentInstruments = []; + $query = civicrm_api3('OptionValue', 'get', [ 'option.limit' => 0, 'option_group_id' => 'payment_instrument', 'is_active' => 1, 'return' => 'value,label' - )); + ]); foreach ($query['values'] as $payment_instrument) { // Do not include CiviSEPA payment instruments, but add a SEPA option if // enabled. @@ -793,14 +793,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $query = civicrm_api3( 'OptionValue', 'get', - array( + [ 'option.limit' => 0, 'option_group_id' => 'contribution_status', - 'return' => array( + 'return' => [ 'value', 'label', - ) - ) + ] + ] ); foreach ($query['values'] as $contribution_status) { @@ -822,20 +822,20 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getNewsletterGroups() { if (!isset(static::$_newsletterGroups)) { - static::$_newsletterGroups = array(); - $group_types = civicrm_api3('OptionValue', 'get', array( + static::$_newsletterGroups = []; + $group_types = civicrm_api3('OptionValue', 'get', [ 'option.limit' => 0, 'option_group_id' => 'group_type', 'name' => CRM_Twingle_Submission::GROUP_TYPE_NEWSLETTER, - )); + ]); if ($group_types['count'] > 0) { $group_type = reset($group_types['values']); - $query = civicrm_api3('Group', 'get', array( + $query = civicrm_api3('Group', 'get', [ 'is_active' => 1, - 'group_type' => array('LIKE' => '%' . CRM_Utils_Array::implodePadded($group_type['value']) . '%'), + 'group_type' => ['LIKE' => '%' . CRM_Utils_Array::implodePadded($group_type['value']) . '%'], 'option.limit' => 0, 'return' => 'id,name' - )); + ]); foreach ($query['values'] as $group) { static::$_newsletterGroups[$group['id']] = $group['name']; } @@ -856,12 +856,12 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getGroups() { if (!isset(static::$_groups)) { - static::$_groups = array(); - $query = civicrm_api3('Group', 'get', array( + static::$_groups = []; + $query = civicrm_api3('Group', 'get', [ 'option.limit' => 0, 'is_active' => 1, 'return' => 'id,name' - )); + ]); foreach ($query['values'] as $group) { static::$_groups[$group['id']] = $group['name']; } @@ -902,14 +902,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public static function getCampaigns() { if (!isset(static::$_campaigns)) { - static::$_campaigns = array(); - $query = civicrm_api3('Campaign', 'get', array( + static::$_campaigns = []; + $query = civicrm_api3('Campaign', 'get', [ 'option.limit' => 0, - 'return' => array( + 'return' => [ 'id', 'title', - ) - )); + ] + ]); foreach ($query['values'] as $campaign) { static::$_campaigns[$campaign['id']] = $campaign['title']; } From a868e87ba722f3ddf61c01648a1f2d36108e01f0 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 15:05:34 +0200 Subject: [PATCH 099/221] minor changes --- CRM/Twingle/Profile.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index b1beb49..0f9115e 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -52,14 +52,12 @@ class CRM_Twingle_Profile { /** * Logs (production) access to this profile - * - * @return bool */ public function logAccess() { CRM_Core_DAO::executeQuery(" - UPDATE civicrm_twingle_profile - SET - last_access = NOW(), + UPDATE civicrm_twingle_profile + SET + last_access = NOW(), access_counter = access_counter + 1 WHERE name = %1", [1 => [$this->name, 'String']]); } @@ -90,7 +88,7 @@ class CRM_Twingle_Profile { $custom_field_mapping = []; if (!empty($custom_field_definition = $this->getAttribute('custom_field_mapping'))) { foreach (preg_split('/\r\n|\r|\n/', $custom_field_definition, -1, PREG_SPLIT_NO_EMPTY) as $custom_field_map) { - list($twingle_field_name, $custom_field_name) = explode("=", $custom_field_map); + [$twingle_field_name, $custom_field_name] = explode("=", $custom_field_map); $custom_field_mapping[$twingle_field_name] = $custom_field_name; } } @@ -133,12 +131,7 @@ class CRM_Twingle_Profile { * @return mixed | NULL */ public function getAttribute($attribute_name, $default = NULL) { - if (isset($this->data[$attribute_name])) { - return $this->data[$attribute_name]; - } - else { - return $default; - } + return $this->data[$attribute_name] ?? $default; } /** From e442ca6249143c277483aafe3a2fa760f6af5ecf Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 17 Aug 2023 10:06:03 +0200 Subject: [PATCH 100/221] fix index --- CRM/Twingle/Page/Profiles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index d3bade3..a4c85b0 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -25,7 +25,7 @@ class CRM_Twingle_Page_Profiles extends CRM_Core_Page { $profiles[$profile_id]['name'] = $profile->getName(); $profiles[$profile_id]['is_default'] = $profile->is_default(); foreach (CRM_Twingle_Profile::allowedAttributes() as $attribute) { - $profiles[$profile_name][$attribute] = $profile->getAttribute($attribute); + $profiles[$profile_id][$attribute] = $profile->getAttribute($attribute); } } $this->assign('profiles', $profiles); From 3241583542d1aa759427e648402769f4441498ea Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 17 Aug 2023 10:08:51 +0200 Subject: [PATCH 101/221] use variable to avoid multiple method calls --- CRM/Twingle/Form/Profile.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 0a781d1..b8f71f2 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -191,22 +191,25 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { break; } + // Is this the default profile? + $is_default = $this->profile->is_default(); + // Assign template variables. $this->assign('op', $this->_op); $this->assign('profile_name', $profile_name); - $this->assign('is_default', $this->profile->is_default()); + $this->assign('is_default', $is_default); // Add form elements. $this->add( 'text', // field type 'name', // field name E::ts('Profile name'), - ['class' => 'huge'] + ($this->profile->is_default() && $this->_op == 'edit' ? ['readonly'] : []), - !$this->profile->is_default() + ['class' => 'huge'] + ($is_default && $this->_op == 'edit' ? ['readonly'] : []), + !$is_default ); // Do only display selector if this is not the default profile - if (!$this->profile->is_default()) { + if (!$is_default) { $this->add( 'text', // field type 'selector', // field name From fd99f3b24ff1bea7145c63595882dac2381926c5 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 29 Aug 2023 16:35:03 +0200 Subject: [PATCH 102/221] add default option add a 'select profile' default option --- CRM/Twingle/Form/Profile.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 1148396..ba542eb 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -614,6 +614,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public static function getXCMProfiles() { if (!isset(static::$_xcm_profiles)) { if (method_exists('CRM_Xcm_Configuration', 'getProfileList')) { + static::$_xcm_profiles = array( + '' => E::ts("<select profile>"), + ); $profiles = CRM_Xcm_Configuration::getProfileList(); foreach ($profiles as $profile_key => $profile_name) { static::$_xcm_profiles[$profile_key] = $profile_name; From ab5b0b3929b4cd32444bc44bcb0240e376e15f3c Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 29 Aug 2023 16:39:28 +0200 Subject: [PATCH 103/221] use correct array key --- CRM/Twingle/Page/Profiles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index 49396d4..4c96456 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -26,7 +26,7 @@ class CRM_Twingle_Page_Profiles extends CRM_Core_Page { $profiles[$profile_id]['is_default'] = $profile->is_default(); $profiles[$profile_id]['selectors'] = $profile->getProjectIds(); foreach (CRM_Twingle_Profile::allowedAttributes() as $attribute) { - $profiles[$profile_name][$attribute] = $profile->getAttribute($attribute); + $profiles[$profile_id][$attribute] = $profile->getAttribute($attribute); } } $this->assign('profiles', $profiles); From b7b0e6d610a2c1c0387ed7c78041c4fcebfee787 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 29 Aug 2023 17:02:05 +0200 Subject: [PATCH 104/221] use custom css file instead of inline style --- CRM/Twingle/Page/Profiles.php | 3 +++ css/twingle.css | 3 +++ templates/CRM/Twingle/Page/Profiles.tpl | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 css/twingle.css diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index 4c96456..3387d07 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -32,6 +32,9 @@ class CRM_Twingle_Page_Profiles extends CRM_Core_Page { $this->assign('profiles', $profiles); $this->assign('profile_stats', CRM_Twingle_Profile::getProfileStats()); + // Add custom css + Civi::resources()->addStyleFile(E::LONG_NAME, 'css/twingle.css'); + parent::run(); } diff --git a/css/twingle.css b/css/twingle.css new file mode 100644 index 0000000..341a393 --- /dev/null +++ b/css/twingle.css @@ -0,0 +1,3 @@ +.twingle-profile-list { + border-bottom: 1px solid #cfcec3; +} diff --git a/templates/CRM/Twingle/Page/Profiles.tpl b/templates/CRM/Twingle/Page/Profiles.tpl index 992fe64..7ce718e 100644 --- a/templates/CRM/Twingle/Page/Profiles.tpl +++ b/templates/CRM/Twingle/Page/Profiles.tpl @@ -34,7 +34,7 @@ {foreach from=$profiles item=profile} {assign var="profile_name" value=$profile.name} - + {foreach from=$profiles item=profile} + {assign var="profile_id" value=$profile.id} {assign var="profile_name" value=$profile.name} @@ -42,12 +43,12 @@ From a16be91822c92859386c05a2c7cb1406dd091851 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 16 Aug 2023 14:26:23 +0200 Subject: [PATCH 130/221] include profile name in update query --- CRM/Twingle/Profile.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index ae62782..2c336f1 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -235,10 +235,11 @@ class CRM_Twingle_Profile { if ($this->id !== NULL) { // existing profile -> just update the config CRM_Core_DAO::executeQuery( - "UPDATE civicrm_twingle_profile SET config = %2 WHERE id = %1", + "UPDATE civicrm_twingle_profile SET config = %2, name = %3 WHERE id = %1", [ 1 => [$this->id, 'String'], 2 => [json_encode($this->data), 'String'], + 3 => [$this->name, 'String'], ]); } else { From 6f6b9e059936a84ef9b2853c275a8d78564e2399 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 16 Aug 2023 14:32:38 +0200 Subject: [PATCH 131/221] use correct error code --- CRM/Twingle/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 2c336f1..335e95c 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -298,7 +298,7 @@ class CRM_Twingle_Profile { } catch (Exception $e) { throw new ProfileException( E::ts("Could not delete profile: %1", [1 => $e->getMessage()]), - ProfileException::ERROR_CODE_COULD_NOT_RESET_PROFILE + ProfileException::ERROR_CODE_COULD_NOT_DELETE_PROFILE ); } } From c7e51b4d3cb705ab49b7c5f5edbc980c93d4793d Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 16 Aug 2023 14:45:36 +0200 Subject: [PATCH 132/221] do not attempt to delete unverified profile_id --- CRM/Twingle/Form/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index d7fe333..996f22d 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -160,7 +160,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { switch ($this->_op) { case 'delete': - if ($this->profile_id) { + if ($this->profile) { CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', [1 => $this->profile->getName()])); $this->addButtons([ [ From 09dda832a48004878c2fa659bb3ecc698462a7d5 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 6 Sep 2023 16:24:03 +0200 Subject: [PATCH 133/221] validate profile when copying --- CRM/Twingle/Form/Profile.php | 30 +++++++++++++++++++++++++----- CRM/Twingle/Profile.php | 8 +++++++- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 996f22d..5205b52 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -180,12 +180,32 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { if (!$source_id) { $this->profile = CRM_Twingle_Profile::createDefaultProfile(); } else { - $source_profile = CRM_Twingle_Profile::getProfile($source_id); - $this->profile = $source_profile->copy(); + try { + $source_profile = CRM_Twingle_Profile::getProfile($source_id); + $this->profile = $source_profile->copy(); + $this->profile->validate(); + } catch (ProfileValidationError $e) { + if ($e->getErrorCode() == ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED) { + Civi::log()->error($e->getLogMessage()); + CRM_Core_Session::setStatus(E::ts('The profile is invalid and cannot be copied.'), E::ts('Error')); + CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1')); + return; + } + } catch (ProfileException $e) { + if ($e->getErrorCode() == ProfileException::ERROR_CODE_PROFILE_NOT_FOUND) { + Civi::log()->error($e->getLogMessage()); + CRM_Core_Session::setStatus(E::ts('The profile to be copied could not be found.'), E::ts('Error')); + CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1')); + return; + } + } + catch (Civi\Core\Exception\DBQueryException $e) { + Civi::log()->error($e->getMessage()); + CRM_Core_Session::setStatus(E::ts('A database error has occurred. See the log for details.'), E::ts('Error')); + CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1')); + return; + } } - // Propose a new name for this profile. - $profile_name = $this->profile->getName() . '_copy'; - $this->profile->setName($profile_name); CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); break; diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 335e95c..5d9f53a 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -80,8 +80,14 @@ class CRM_Twingle_Profile { */ public function copy() { $copy = clone $this; + + // Remove unique data $copy->id = NULL; $copy->data['selector'] = NULL; + + // Propose a new name for this profile. + $profile_name = $this->getName() . '_copy'; + $copy->setName($profile_name); return $copy; } @@ -484,7 +490,7 @@ class CRM_Twingle_Profile { return new CRM_Twingle_Profile($profile_data->name, json_decode($profile_data->config, 1), (int) $profile_data->id); } } - return NULL; + throw new ProfileException('Profile not found.', ProfileException::ERROR_CODE_PROFILE_NOT_FOUND); } /** From 4feeb01611309c8385bdf08abe086354e726f885 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 6 Sep 2023 16:29:55 +0200 Subject: [PATCH 134/221] make sure that default values are present --- CRM/Twingle/Form/Profile.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 5205b52..199e421 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -640,6 +640,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public function setDefaultValues() { $defaults = parent::setDefaultValues(); if (in_array($this->_op, ['create', 'edit', 'copy'])) { + if (!$this->profile) { + $this->profile = CRM_Twingle_Profile::createDefaultProfile()->copy(); + } $defaults['name'] = $this->profile->getName(); $profile_data = $this->profile->getData(); foreach ($profile_data as $element_name => $value) { From aef1ae739653a2eb6d58729d7090af7528fe30ff Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 6 Sep 2023 16:34:56 +0200 Subject: [PATCH 135/221] refactoring --- CRM/Twingle/Profile.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 5d9f53a..d5109a7 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -221,7 +221,8 @@ class CRM_Twingle_Profile { * Verifies whether the profile is valid (i.e. consistent and not colliding * with other profiles). * - * @throws Exception + * @throws \CRM\Twingle\Exceptions\ProfileValidationError + * @throws \Civi\Core\Exception\DBQueryException * When the profile could not be successfully validated. */ public function verifyProfile() { @@ -231,7 +232,9 @@ class CRM_Twingle_Profile { } /** - * Persists the profile within the CiviCRM settings. + * Persists the profile within the database. + * + * @throws \CRM\Twingle\Exceptions\ProfileException */ public function saveProfile() { // make sure it's valid @@ -269,7 +272,7 @@ class CRM_Twingle_Profile { /** * Deletes the profile from the database * - * @throws \CRM_Twingle_Exceptions_ProfileException + * @throws \CRM\Twingle\Exceptions\ProfileException */ public function deleteProfile() { // Do only reset default profile @@ -481,6 +484,7 @@ class CRM_Twingle_Profile { * * @return CRM_Twingle_Profile | NULL * @throws \Civi\Core\Exception\DBQueryException + * @throws \CRM\Twingle\Exceptions\ProfileException */ public static function getProfile(int $id = NULL) { if (!empty($id)) { From f81b476a3054707dd67a111d47eb7b6264e0a3af Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 5 Oct 2023 14:32:29 +0200 Subject: [PATCH 136/221] fix exception on profile creation --- CRM/Twingle/Form/Profile.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 199e421..430d335 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -149,8 +149,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { } // Verify that a profile with the given id exists. - - if ($this->_op != 'copy') { + if ($this->_op != 'copy' && $this->_op != 'create') { $this->profile_id = CRM_Utils_Request::retrieve('id', 'Int', $this); $this->profile = CRM_Twingle_Profile::getProfile($this->profile_id); } From 5efed1f6c8d91e3bbea1c6233b91879efa86b10c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 16:03:07 +0100 Subject: [PATCH 137/221] Fix @throws tags with wrong class name --- CRM/Twingle/Profile.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index d5109a7..8d9a269 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -221,7 +221,7 @@ class CRM_Twingle_Profile { * Verifies whether the profile is valid (i.e. consistent and not colliding * with other profiles). * - * @throws \CRM\Twingle\Exceptions\ProfileValidationError + * @throws \Civi\Twingle\Exceptions\ProfileValidationError * @throws \Civi\Core\Exception\DBQueryException * When the profile could not be successfully validated. */ @@ -234,7 +234,7 @@ class CRM_Twingle_Profile { /** * Persists the profile within the database. * - * @throws \CRM\Twingle\Exceptions\ProfileException + * @throws \Civi\Twingle\Exceptions\ProfileException */ public function saveProfile() { // make sure it's valid @@ -272,7 +272,7 @@ class CRM_Twingle_Profile { /** * Deletes the profile from the database * - * @throws \CRM\Twingle\Exceptions\ProfileException + * @throws \Civi\Twingle\Exceptions\ProfileException */ public function deleteProfile() { // Do only reset default profile @@ -484,7 +484,7 @@ class CRM_Twingle_Profile { * * @return CRM_Twingle_Profile | NULL * @throws \Civi\Core\Exception\DBQueryException - * @throws \CRM\Twingle\Exceptions\ProfileException + * @throws \Civi\Twingle\Exceptions\ProfileException */ public static function getProfile(int $id = NULL) { if (!empty($id)) { From bd54c039c834345153505246795e85a9113e72b8 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 15 May 2023 15:57:06 +0200 Subject: [PATCH 138/221] make all fields available for custom mapping This is useful to be able to map fields like `purpose` or `remarks` to custom fields. --- api/v3/TwingleDonation/Submit.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 6bd5462..2fceaae 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -306,11 +306,10 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!empty($params['custom_fields'])) { $custom_field_mapping = $profile->getCustomFieldMapping(); - // Include user_extrafield in custom_field_mapping if it is referenced there. - // See issue #50. - if (!empty($params['user_extrafield']) && isset($custom_field_mapping['user_extrafield'])) { - $params['custom_fields']['user_extrafield'] = $params['user_extrafield']; - } + // Make all params available for custom field mapping + $allowed_params = []; + _civicrm_api3_twingle_donation_Submit_spec($allowed_params); + $params['custom_fields'] += array_intersect_key($params, $custom_field_mapping, $allowed_params); foreach ($params['custom_fields'] as $twingle_field => $value) { if (isset($custom_field_mapping[$twingle_field])) { From 47756f68b4671188e149bf1f380e27687854a544 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 3 Apr 2024 12:02:32 +0200 Subject: [PATCH 139/221] Correct indentation --- api/v3/TwingleDonation/Submit.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 2fceaae..502bef7 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -306,10 +306,10 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!empty($params['custom_fields'])) { $custom_field_mapping = $profile->getCustomFieldMapping(); - // Make all params available for custom field mapping - $allowed_params = []; - _civicrm_api3_twingle_donation_Submit_spec($allowed_params); - $params['custom_fields'] += array_intersect_key($params, $custom_field_mapping, $allowed_params); + // Make all params available for custom field mapping + $allowed_params = []; + _civicrm_api3_twingle_donation_Submit_spec($allowed_params); + $params['custom_fields'] += array_intersect_key($params, $custom_field_mapping, $allowed_params); foreach ($params['custom_fields'] as $twingle_field => $value) { if (isset($custom_field_mapping[$twingle_field])) { From d7b066751a71831e90367140571ed35e377a1150 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 3 Apr 2024 12:22:39 +0200 Subject: [PATCH 140/221] PHP Code Sniffer fixes --- CRM/Twingle/Profile.php | 3 +++ CRM/Twingle/Tools.php | 11 +++++++++-- CRM/Twingle/Upgrader.php | 5 +++-- api/v3/TwingleDonation/Submit.php | 10 ++++++++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index a78f576..e4494dd 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -353,6 +353,7 @@ class CRM_Twingle_Profile { ], ] // Add contribution status for all payment methods. + // phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus + array_fill_keys(array_map(function($attribute) { return $attribute . '_status'; }, array_keys(static::paymentInstruments())), CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED)); @@ -440,6 +441,7 @@ class CRM_Twingle_Profile { $stats = []; $profile_data = CRM_Core_DAO::executeQuery('SELECT name, last_access, access_counter FROM civicrm_twingle_profile'); while ($profile_data->fetch()) { + // phpcs:disable Drupal.Arrays.Array.ArrayIndentation $stats[$profile_data->name] = [ 'name' => $profile_data->name, 'last_access' => $profile_data->last_access, @@ -451,6 +453,7 @@ class CRM_Twingle_Profile { ? ((int) $profile_data->access_counter) . 'x' : E::ts('never'), ]; + // phpcs:enable } return $stats; } diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php index aa1bb1c..5c4007c 100644 --- a/CRM/Twingle/Tools.php +++ b/CRM/Twingle/Tools.php @@ -123,10 +123,13 @@ class CRM_Twingle_Tools { break; case CRM_Twingle_Config::RCUR_PROTECTION_EXCEPTION: + // phpcs:disable Generic.Files.LineLength.TooLong throw new Exception(E::ts( 'This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.' )); + // phpcs:enable + case CRM_Twingle_Config::RCUR_PROTECTION_ACTIVITY: // create contact source activity // first: get the contact ID @@ -157,8 +160,12 @@ class CRM_Twingle_Tools { 'target_id' => $target_id, 'assignee_id' => Civi::settings()->get('twingle_protect_recurring_activity_assignee'), 'status_id' => Civi::settings()->get('twingle_protect_recurring_activity_status'), - 'details' => E::ts("Recurring contribution [%1] (Transaction ID '%2') was terminated by a user. You need to end the corresponding record in Twingle as well, or it will still be collected.", - [1 => $recurring_contribution_id, 2 => $trxn_id]), + // phpcs:disable Generic.Files.LineLength.TooLong + 'details' => E::ts( + "Recurring contribution [%1] (Transaction ID '%2') was terminated by a user. You need to end the corresponding record in Twingle as well, or it will still be collected.", + [1 => $recurring_contribution_id, 2 => $trxn_id] + ), + // phpcs:enable 'source_contact_id' => CRM_Core_Session::getLoggedInContactID(), ]); } diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index abba9d8..8741dac 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -89,8 +89,9 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { foreach ($profiles_data as $profile_name => $profile_data) { $profile = new CRM_Twingle_Profile($profile_name, $profile_data); $data = json_encode($profile->getData()); - CRM_Core_DAO::executeQuery( - 'INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, NOW(), 0)', + CRM_Core_DAO::executeQuery(<< [$profile_name, 'String'], 2 => [$data, 'String'], diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 502bef7..8f63aea 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -321,7 +321,8 @@ function civicrm_api3_twingle_donation_Submit($params) { // Chain a CustomGroup.getsingle API call. 'api.CustomGroup.getsingle' => [], ]); - $custom_fields[$custom_field['api.CustomGroup.getsingle']['extends']][$custom_field_mapping[$twingle_field]] = $value; + $entity = $custom_field['api.CustomGroup.getsingle']['extends']; + $custom_fields[$entity][$custom_field_mapping[$twingle_field]] = $value; } } } @@ -652,6 +653,7 @@ function civicrm_api3_twingle_donation_Submit($params) { $mandate_data = $contribution_data // ... CiviSEPA mandate attributes, ... + // phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus + [ 'type' => ($params['donation_rhythm'] == 'one_time' ? 'OOFF' : 'RCUR'), 'iban' => $params['debit_iban'], @@ -664,6 +666,7 @@ function civicrm_api3_twingle_donation_Submit($params) { 'creditor_id' => $creditor_id, ] // ... and frequency unit and interval from a static mapping. + // phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus + CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']); // Add custom field values. if (!empty($custom_fields['ContributionRecur'])) { @@ -748,7 +751,10 @@ function civicrm_api3_twingle_donation_Submit($params) { // Create contribution. $contribution_data += [ - 'contribution_status_id' => $profile->getAttribute("pi_{$params['payment_method']}_status", CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED), + 'contribution_status_id' => $profile->getAttribute( + "pi_{$params['payment_method']}_status", + CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED + ), 'receive_date' => $params['confirmed_at'], ]; From fc40af8db53d9559206b36c2386750430c88552c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 4 Apr 2024 12:13:53 +0200 Subject: [PATCH 141/221] Fix code style --- CRM/Twingle/Form/Settings.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index 6303dc9..0ff7454 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -25,7 +25,8 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Form_Settings extends CRM_Core_Form { /** - * @var arraylistofallsettingsoptions + * @var array + * List of all settings options. */ public static $SETTINGS_LIST = [ 'twingle_prefix', @@ -133,7 +134,8 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { // if activity creation is active, make sure the fields are set $protection_mode = CRM_Utils_Array::value('twingle_protect_recurring', $this->_submitValues); if ($protection_mode == CRM_Twingle_Config::RCUR_PROTECTION_ACTIVITY) { - foreach (['twingle_protect_recurring_activity_type', + foreach ([ + 'twingle_protect_recurring_activity_type', 'twingle_protect_recurring_activity_subject', 'twingle_protect_recurring_activity_status', 'twingle_protect_recurring_activity_assignee', From 8bcdff4a855f621fec11ba255112c1d4ff57046e Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 5 Apr 2024 12:24:11 +0200 Subject: [PATCH 142/221] Fix PHPStan issues --- CRM/Twingle/Config.php | 2 +- CRM/Twingle/Form/Profile.php | 238 +++++++++++----------- CRM/Twingle/Form/Settings.php | 24 ++- CRM/Twingle/Page/Configuration.php | 2 +- CRM/Twingle/Page/Profiles.php | 2 +- CRM/Twingle/Profile.php | 101 +++++---- CRM/Twingle/Submission.php | 135 ++++++------ CRM/Twingle/Tools.php | 35 ++-- CRM/Twingle/Upgrader.php | 10 +- Civi/Twingle/Exceptions/BaseException.php | 18 +- api/v3/TwingleDonation/Cancel.php | 18 +- api/v3/TwingleDonation/Endrecurring.php | 22 +- api/v3/TwingleDonation/Submit.php | 138 +++++++------ phpcs.xml.dist | 1 + phpstan.neon.template | 1 + twingle.php | 2 +- 16 files changed, 385 insertions(+), 364 deletions(-) diff --git a/CRM/Twingle/Config.php b/CRM/Twingle/Config.php index d75b7b4..29acf82 100644 --- a/CRM/Twingle/Config.php +++ b/CRM/Twingle/Config.php @@ -27,7 +27,7 @@ class CRM_Twingle_Config { * Get the options for protecting a recurring contribution linked Twingle * against ending or cancellation (because Twingle would keep on collecting them) * - * @return array + * @return array */ public static function getRecurringProtectionOptions() { return [ diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index efffdce..950aba2 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -16,7 +16,8 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; -use Civi\Twingle\Exceptions\ProfileException as ProfileException; +use Civi\Twingle\Exceptions\ProfileException; +use Civi\Twingle\Exceptions\BaseException; /** * Form controller class @@ -30,7 +31,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * * The profile object the form is acting on. */ - protected $profile; + protected ?CRM_Twingle_Profile $profile = NULL; /** * @var string @@ -40,120 +41,128 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { protected $_op; /** - * @var array + * @var array * * A static cache of retrieved payment instruments found within * self::getPaymentInstruments(). */ - protected static $_paymentInstruments = NULL; + protected static $_paymentInstruments; /** - * @var array + * @var array * * A static cache of retrieved contribution statuses found within * static::getContributionStatusOptions(). */ - protected static $_contributionStatusOptions = NULL; + protected static array $_contributionStatusOptions; /** - * @var array + * @var array * * A static cache of retrieved groups found within static::getGroups(). */ - protected static $_groups = NULL; + protected static array $_groups; /** - * @var array + * @var array * * A static cache of retrieved newsletter groups found within * static::getNewsletterGroups(). */ - protected static $_newsletterGroups = NULL; + protected static array $_newsletterGroups; /** - * @var array + * @var array * * A static cache of retrieved campaigns found within static::getCampaigns(). */ - protected static $_campaigns = NULL; + protected static array $_campaigns; /** - * @var array + * @var array * * A static cache of retrieved financial types found within * static::getFinancialTypes(). */ - protected static $_financialTypes = NULL; + protected static array $_financialTypes; /** - * @var array + * @var array * * A static cache of retrieved genders found within * static::getGenderOptions(). */ - protected static $_genderOptions = NULL; + protected static array $_genderOptions; /** - * @var array + * @var array * * A static cache of retrieved prefixes found within * static::getGenderOptions(). */ - protected static $_prefixOptions = NULL; + protected static array $_prefixOptions; /** - * @var array + * @var array * * A static cache of retrieved location types found within * static::getLocationTypes(). */ - protected static $_locationTypes = NULL; + protected static array $_locationTypes; /** - * @var array + * @var array * * A static cache of retrieved location types found within * static::getXCMProfiles(). */ - protected static $_xcm_profiles = NULL; + protected static array $_xcm_profiles; /** - * @var array + * @var array * * A static cache of retrieved membership types found within * static::getMembershipTypes(). */ - protected static $_membershipTypes = NULL; + protected static array $_membershipTypes; /** - * @var array + * @var array * * A static cache of retrieved CiviSEPA creditors found within * static::getSepaCreditors(). */ - protected static $_sepaCreditors = NULL; + protected static array $_sepaCreditors; + + public function preProcess(): void { + // "Create" is the default operation. + $op = CRM_Utils_Request::retrieve('op', 'String', $this); + $this->_op = is_string($op) ? $op : 'create'; + + // Verify that a profile with the given name exists. + $profile_name = CRM_Utils_Request::retrieve('name', 'String', $this); + if (is_string($profile_name)) { + $this->profile = CRM_Twingle_Profile::getProfile($profile_name); + } + + // Set redirect destination. + $this->controller->_destination = CRM_Utils_System::url( + 'civicrm/admin/settings/twingle/profiles', + 'reset=1' + ); + + parent::preProcess(); + } /** * Builds the form structure. */ - public function buildQuickForm() { - // "Create" is the default operation. - if (!$this->_op = CRM_Utils_Request::retrieve('op', 'String', $this)) { - $this->_op = 'create'; - } - - // Verify that a profile with the given name exists. - $profile_name = CRM_Utils_Request::retrieve('name', 'String', $this); - if (!$this->profile = CRM_Twingle_Profile::getProfile($profile_name)) { - $profile_name = NULL; - } - - // Set redirect destination. - $this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1'); + public function buildQuickForm(): void { + $profile_name = (isset($this->profile) ? $this->profile->getName() : NULL); switch ($this->_op) { case 'delete': - if ($profile_name) { + if (isset($profile_name)) { CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', [1 => $profile_name])); $this->addButtons([ [ @@ -168,10 +177,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { case 'edit': // When editing without a valid profile name, edit the default profile. - if (!$profile_name) { + if (!isset($profile_name)) { $profile_name = 'default'; $this->profile = CRM_Twingle_Profile::getProfile($profile_name); } + if (!isset($this->profile)) { + throw new BaseException(E::ts('Could not retrieve profile with name "%1"', [1 => $profile_name])); + } CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', [1 => $this->profile->getName()])); break; @@ -179,10 +191,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Retrieve the source profile name. $profile_name = CRM_Utils_Request::retrieve('source_name', 'String', $this); // When copying without a valid profile name, copy the default profile. - if (!$profile_name) { + if (!is_string($profile_name)) { $profile_name = 'default'; } - $this->profile = clone CRM_Twingle_Profile::getProfile($profile_name); + $originalProfile = CRM_Twingle_Profile::getProfile($profile_name); + if (!isset($originalProfile)) { + throw new BaseException(E::ts('Could not retrieve profile with name "%1"', [1 => $profile_name])); + } + $this->profile = clone $originalProfile; // Propose a new name for this profile. $profile_name = $profile_name . '_copy'; @@ -192,7 +208,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { case 'create': // Load factory default profile values. - $this->profile = CRM_Twingle_Profile::createDefaultProfile($profile_name); + $this->profile = CRM_Twingle_Profile::createDefaultProfile($profile_name ?? 'default'); CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); break; } @@ -354,10 +370,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // field name 'newsletter_double_opt_in', // field label - E::ts('Use Double-Opt-In for newsletter'), - // is not required - FALSE, - [] + E::ts('Use Double-Opt-In for newsletter') ); $this->add( @@ -461,8 +474,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->add( 'text', 'membership_postprocess_call', - E::ts('API Call for Membership Postprocessing'), - FALSE + E::ts('API Call for Membership Postprocessing') ); $this->addRule( 'membership_postprocess_call', @@ -521,9 +533,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Validates the profile form. * - * @return bool|array - * TRUE when the form was successfully validated, or an array of error - * messages, keyed by form element name. + * @return bool + * TRUE when the form was successfully validated. */ public function validate() { $values = $this->exportValues(); @@ -531,14 +542,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Validate new profile names. if ( isset($values['name']) - && ($values['name'] != $this->profile->getName() || $this->_op != 'edit') - && !empty(CRM_Twingle_Profile::getProfile($values['name'])) + && (!isset($this->profile) || $values['name'] != $this->profile->getName() || $this->_op != 'edit') + && NULL !== CRM_Twingle_Profile::getProfile($values['name']) ) { $this->_errors['name'] = E::ts('A profile with this name already exists.'); } // Restrict profile names to alphanumeric characters and the underscore. - if (isset($values['name']) && preg_match('/[^A-Za-z0-9\_]/', $values['name'])) { + if (isset($values['name']) && 1 === preg_match('/[^A-Za-z0-9\_]/', $values['name'])) { $this->_errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); } @@ -548,14 +559,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { if (isset($values['custom_field_mapping'])) { $custom_field_mapping = preg_split('/\r\n|\r|\n/', $values['custom_field_mapping'], -1, PREG_SPLIT_NO_EMPTY); if (!is_array($custom_field_mapping)) { - throw new Exception( + throw new BaseException( E::ts('Could not parse custom field mapping.') ); } foreach ($custom_field_mapping as $custom_field_map) { $custom_field_map = explode('=', $custom_field_map); if (count($custom_field_map) !== 2) { - throw new Exception( + throw new BaseException( E::ts('Could not parse custom field mapping.') ); } @@ -568,12 +579,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'id' => $custom_field_id, ]); } - catch (CiviCRM_API3_Exception $exception) { - throw new Exception( + catch (CRM_Core_Exception $exception) { + throw new BaseException( E::ts( 'Custom field custom_%1 does not exist.', [1 => $custom_field_id] - ) + ), + NULL, + $exception ); } @@ -592,18 +605,20 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ], ]); } - catch (CiviCRM_API3_Exception $exception) { - throw new Exception( + catch (CRM_Core_Exception $exception) { + throw new BaseException( E::ts( 'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.', [1 => $custom_field['id']] - ) - ); + ), + NULL, + $exception + ); } } } } - catch (Exception $exception) { + catch (BaseException $exception) { $this->_errors['custom_field_mapping'] = $exception->getMessage(); } @@ -612,12 +627,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Set the default values (i.e. the profile's current data) in the form. + * + * @return array */ public function setDefaultValues() { $defaults = parent::setDefaultValues(); - if (in_array($this->_op, ['create', 'edit', 'copy'])) { - $defaults['name'] = $this->profile->getName(); - $profile_data = $this->profile->getData(); + if (in_array($this->_op, ['create', 'edit', 'copy'], TRUE)) { + $defaults['name'] = isset($this->profile) ? $this->profile->getName() : NULL; + $profile_data = isset($this->profile) ? $this->profile->getData() : []; foreach ($profile_data as $element_name => $value) { $defaults[$element_name] = $value; } @@ -632,11 +649,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Store the values submitted with the form in the profile. */ - public function postProcess() { + public function postProcess(): void { $values = $this->exportValues(); try { - if (in_array($this->_op, ['create', 'edit', 'copy'])) { - if (empty($values['name'])) { + if (!isset($this->profile)) { + throw new BaseException(E::ts('No profile set.')); + } + if (in_array($this->_op, ['create', 'edit', 'copy'], TRUE)) { + if (!is_string($values['name'])) { $values['name'] = 'default'; } $this->profile->setName($values['name']); @@ -670,9 +690,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves location types present within the system as options for select * form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getLocationTypes() { if (!isset(static::$_locationTypes)) { @@ -682,7 +700,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'is_active' => 1, ]); foreach ($query['values'] as $type) { - static::$_locationTypes[$type['id']] = $type['name']; + static::$_locationTypes[(int) $type['id']] = $type['name']; } } return static::$_locationTypes; @@ -691,11 +709,11 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Retrieves XCM profiles (if supported). 'default' profile is always available * - * @return array + * @return array */ public static function getXCMProfiles() { if (!isset(static::$_xcm_profiles)) { - if (method_exists('CRM_Xcm_Configuration', 'getProfileList')) { + if (class_exists('CRM_Xcm_Configuration')) { static::$_xcm_profiles = [ '' => E::ts('<select profile>'), ]; @@ -712,9 +730,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves financial types present within the system as options for select * form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getFinancialTypes() { if (!isset(static::$_financialTypes)) { @@ -725,7 +741,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'return' => 'id,name', ]); foreach ($query['values'] as $type) { - static::$_financialTypes[$type['id']] = $type['name']; + static::$_financialTypes[(int) $type['id']] = $type['name']; } } return static::$_financialTypes; @@ -735,9 +751,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves membership types present within the system as options for select * form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getMembershipTypes() { if (!isset(static::$_membershipTypes)) { @@ -758,9 +772,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves genders present within the system as options for select form * elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getGenderOptions() { if (!isset(static::$_genderOptions)) { @@ -775,7 +787,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ], ]); foreach ($query['values'] as $gender) { - static::$_genderOptions[$gender['value']] = $gender['label']; + static::$_genderOptions[(int) $gender['value']] = $gender['label']; } } return static::$_genderOptions; @@ -785,9 +797,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves prefixes present within the system as options for select form * elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getPrefixOptions() { if (!isset(static::$_prefixOptions)) { @@ -802,7 +812,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ], ]); foreach ($query['values'] as $prefix) { - static::$_prefixOptions[$prefix['value']] = $prefix['label']; + static::$_prefixOptions[(int) $prefix['value']] = $prefix['label']; } } return static::$_prefixOptions; @@ -811,9 +821,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Retrieves CiviSEPA creditors as options for select form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getSepaCreditors() { if (!isset(static::$_sepaCreditors)) { @@ -823,7 +831,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'option.limit' => 0, ]); foreach ($result['values'] as $sepa_creditor) { - static::$_sepaCreditors[$sepa_creditor['id']] = $sepa_creditor['name']; + static::$_sepaCreditors[(int) $sepa_creditor['id']] = $sepa_creditor['name']; } } } @@ -834,9 +842,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves payment instruments present within the system as options for * select form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getPaymentInstruments() { if (!isset(self::$_paymentInstruments)) { @@ -869,9 +875,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Retrieves contribution statuses as options for select form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getContributionStatusOptions() { if (!isset(self::$_contributionStatusOptions)) { @@ -889,7 +893,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ); foreach ($query['values'] as $contribution_status) { - self::$_contributionStatusOptions[$contribution_status['value']] = $contribution_status['label']; + self::$_contributionStatusOptions[(int) $contribution_status['value']] = $contribution_status['label']; } } @@ -900,9 +904,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves active groups used as mailing lists within the system as options * for select form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array * */ public static function getNewsletterGroups() { @@ -935,9 +937,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Retrieves active groups as options for select form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getGroups() { if (!isset(static::$_groups)) { @@ -948,7 +948,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'return' => 'id,name', ]); foreach ($query['values'] as $group) { - static::$_groups[$group['id']] = $group['name']; + static::$_groups[(int) $group['id']] = $group['name']; } } return static::$_groups; @@ -958,9 +958,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves active groups used as postal mailing lists within the system as * options for select form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getPostinfoGroups() { return static::getGroups(); @@ -970,9 +968,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * Retrieves active groups used as donation receipt requester lists within the * system as options for select form elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getDonationReceiptGroups() { return static::getGroups(); @@ -981,9 +977,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Retrieves campaigns as options for select elements. * - * @return array - * - * @throws \CiviCRM_API3_Exception + * @return array */ public static function getCampaigns() { if (!isset(static::$_campaigns)) { @@ -996,7 +990,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ], ]); foreach ($query['values'] as $campaign) { - static::$_campaigns[$campaign['id']] = $campaign['title']; + static::$_campaigns[(int) $campaign['id']] = $campaign['title']; } } return static::$_campaigns; diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index 6303dc9..7852311 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -25,7 +25,8 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Form_Settings extends CRM_Core_Form { /** - * @var arraylistofallsettingsoptions + * @var array + * List of all settings options. */ public static $SETTINGS_LIST = [ 'twingle_prefix', @@ -41,7 +42,7 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { /** * @inheritdoc */ - public function buildQuickForm() { + public function buildQuickForm(): void { // Set redirect destination. $this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle', 'reset=1'); @@ -131,15 +132,14 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { parent::validate(); // if activity creation is active, make sure the fields are set - $protection_mode = CRM_Utils_Array::value('twingle_protect_recurring', $this->_submitValues); + $protection_mode = $this->_submitValues['twingle_protect_recurring'] ?? NULL; if ($protection_mode == CRM_Twingle_Config::RCUR_PROTECTION_ACTIVITY) { foreach (['twingle_protect_recurring_activity_type', 'twingle_protect_recurring_activity_subject', 'twingle_protect_recurring_activity_status', 'twingle_protect_recurring_activity_assignee', ] as $activity_field) { - $current_value = CRM_Utils_Array::value($activity_field, $this->_submitValues); - if (empty($current_value)) { + if (NULL !== ($this->_submitValues[$activity_field] ?? NULL)) { $this->_errors[$activity_field] = E::ts('This is required for activity creation'); } } @@ -151,12 +151,12 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { /** * @inheritdoc */ - public function postProcess() { + public function postProcess(): void { $values = $this->exportValues(); // store settings foreach (self::$SETTINGS_LIST as $setting) { - Civi::settings()->set($setting, CRM_Utils_Array::value($setting, $values)); + Civi::settings()->set($setting, $values[$setting]); } parent::postProcess(); @@ -164,11 +164,13 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { /** * Get a list of option group items - * @param $group_id string group ID or name - * @return array list of ID(value) => label - * @throws CiviCRM_API3_Exception + * @param string $group_id + * Group ID or name. + * @param array $reserved + * @return array list of ID(value) => label + * @throws \CRM_Core_Exception */ - protected function getOptionValueList($group_id, $reserved = [0, 1]) { + protected function getOptionValueList(string $group_id, array $reserved = [0, 1]): array { $list = ['' => E::ts('-select-')]; $query = civicrm_api3('OptionValue', 'get', [ 'option_group_id' => $group_id, diff --git a/CRM/Twingle/Page/Configuration.php b/CRM/Twingle/Page/Configuration.php index f30cf67..d0e0e3c 100644 --- a/CRM/Twingle/Page/Configuration.php +++ b/CRM/Twingle/Page/Configuration.php @@ -19,7 +19,7 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Page_Configuration extends CRM_Core_Page { - public function run() { + public function run(): void { parent::run(); } diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index e8f014b..80d7de2 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -19,7 +19,7 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Page_Profiles extends CRM_Core_Page { - public function run() { + public function run():void { CRM_Utils_System::setTitle(E::ts('Twingle API Profiles')); $profiles = []; foreach (CRM_Twingle_Profile::getProfiles() as $profile_name => $profile) { diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index e4494dd..6553505 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -28,20 +28,20 @@ class CRM_Twingle_Profile { * @var string * The name of the profile. */ - protected $name = NULL; + protected $name; /** - * @var array + * @var array * The properties of the profile. */ - protected $data = NULL; + protected $data; /** * CRM_Twingle_Profile constructor. * * @param string $name * The name of the profile. - * @param array $data + * @param array $data * The properties of the profile */ public function __construct($name, $data) { @@ -56,7 +56,7 @@ class CRM_Twingle_Profile { /** * Logs (production) access to this profile */ - public function logAccess() { + public function logAccess(): void { CRM_Core_DAO::executeQuery(' UPDATE civicrm_twingle_profile SET @@ -80,19 +80,29 @@ class CRM_Twingle_Profile { }, explode(',', $selector) ); - return in_array($project_id, $project_ids); + return in_array($project_id, $project_ids, TRUE); } /** - * @return array + * Retrieves the profile's configured custom field mapping. + * + * @return array * The profile's configured custom field mapping */ public function getCustomFieldMapping() { $custom_field_mapping = []; - if (!empty($custom_field_definition = $this->getAttribute('custom_field_mapping'))) { - foreach (preg_split('/\r\n|\r|\n/', $custom_field_definition, -1, PREG_SPLIT_NO_EMPTY) as $custom_field_map) { - [$twingle_field_name, $custom_field_name] = explode('=', $custom_field_map); - $custom_field_mapping[$twingle_field_name] = $custom_field_name; + if (is_string($custom_field_definition = $this->getAttribute('custom_field_mapping'))) { + $custom_field_maps = preg_split( + '/\r\n|\r|\n/', + $custom_field_definition, + -1, + PREG_SPLIT_NO_EMPTY + ); + if (FALSE !== $custom_field_maps) { + foreach ($custom_field_maps as $custom_field_map) { + [$twingle_field_name, $custom_field_name] = explode('=', $custom_field_map); + $custom_field_mapping[$twingle_field_name] = $custom_field_name; + } } } return $custom_field_mapping; @@ -101,7 +111,7 @@ class CRM_Twingle_Profile { /** * Retrieves all data attributes of the profile. * - * @return array + * @return array */ public function getData() { return $this->data; @@ -119,9 +129,9 @@ class CRM_Twingle_Profile { /** * Sets the profile name. * - * @param $name + * @param string $name */ - public function setName($name) { + public function setName(string $name): void { $this->name = $name; } @@ -146,8 +156,8 @@ class CRM_Twingle_Profile { * @throws \Civi\Twingle\Exceptions\ProfileException * When the attribute name is not known. */ - public function setAttribute($attribute_name, $value) { - if (!in_array($attribute_name, self::allowedAttributes())) { + public function setAttribute($attribute_name, $value): void { + if (!in_array($attribute_name, self::allowedAttributes(), TRUE)) { throw new ProfileException( E::ts('Unknown attribute %1.', [1 => $attribute_name]), ProfileException::ERROR_CODE_UNKNOWN_PROFILE_ATTRIBUTE @@ -160,27 +170,19 @@ class CRM_Twingle_Profile { /** * Get the CiviCRM transaction ID (to be used in contributions and recurring contributions) * - * @param $twingle_id string Twingle ID + * @param string $twingle_id Twingle ID * @return string CiviCRM transaction ID */ - public function getTransactionID($twingle_id) { + public function getTransactionID(string $twingle_id) { $prefix = Civi::settings()->get('twingle_prefix'); - if (empty($prefix)) { - return $twingle_id; - } - else { - return $prefix . $twingle_id; - } + return ($prefix ?? '') . $twingle_id; } /** * Verifies whether the profile is valid (i.e. consistent and not colliding * with other profiles). - * - * @throws Exception - * When the profile could not be successfully validated. */ - public function verifyProfile() { + public function verifyProfile(): void { // TODO: check // data of this profile consistent? // conflicts with other profiles? @@ -189,14 +191,14 @@ class CRM_Twingle_Profile { /** * Persists the profile within the CiviCRM settings. */ - public function saveProfile() { + public function saveProfile(): void { // make sure it's valid $this->verifyProfile(); // check if the profile exists $profile_id = CRM_Core_DAO::singleValueQuery( 'SELECT id FROM civicrm_twingle_profile WHERE name = %1', [1 => [$this->name, 'String']]); - if ($profile_id) { + if (isset($profile_id)) { // existing profile -> just update the config CRM_Core_DAO::executeQuery( 'UPDATE civicrm_twingle_profile SET config = %2 WHERE name = %1', @@ -219,7 +221,7 @@ class CRM_Twingle_Profile { /** * Deletes the profile from the database */ - public function deleteProfile() { + public function deleteProfile(): void { CRM_Core_DAO::executeQuery( 'DELETE FROM civicrm_twingle_profile WHERE name = %1', [1 => [$this->name, 'String']] @@ -229,7 +231,7 @@ class CRM_Twingle_Profile { /** * Returns an array of attributes allowed for a profile. * - * @return array + * @return array */ public static function allowedAttributes() { return array_merge( @@ -273,9 +275,9 @@ class CRM_Twingle_Profile { /** * Retrieves a list of supported payment methods. * - * @return array + * @return array */ - public static function paymentInstruments() { + public static function paymentInstruments(): array { return [ 'pi_banktransfer' => E::ts('Bank transfer'), 'pi_debit_manual' => E::ts('Debit manual'), @@ -364,10 +366,9 @@ class CRM_Twingle_Profile { * which is responsible for processing the project's data. * Returns the default profile if no match was found. * - * @param $project_id + * @param string $project_id * * @return CRM_Twingle_Profile - * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileForProject($project_id) { $profiles = self::getProfiles(); @@ -379,9 +380,8 @@ class CRM_Twingle_Profile { } // If none matches, use the default profile. - $default_profile = $profiles['default']; - if (!empty($default_profile)) { - return $default_profile; + if (isset($profiles['default'])) { + return $profiles['default']; } else { throw new ProfileException( @@ -396,26 +396,21 @@ class CRM_Twingle_Profile { * * @param string $name * - * @return CRM_Twingle_Profile | NULL + * @return CRM_Twingle_Profile|NULL */ public static function getProfile($name) { - if (!empty($name)) { - $profile_data = CRM_Core_DAO::singleValueQuery( - 'SELECT config FROM civicrm_twingle_profile WHERE name = %1', - [1 => [$name, 'String']] - ); - if ($profile_data) { - return new CRM_Twingle_Profile($name, json_decode($profile_data, 1)); - } - } - return NULL; + $profile_data = CRM_Core_DAO::singleValueQuery( + 'SELECT config FROM civicrm_twingle_profile WHERE name = %1', + [1 => [$name, 'String']] + ); + return isset($profile_data) ? new CRM_Twingle_Profile($name, (array) json_decode($profile_data, TRUE)) : NULL; } /** * Retrieves the list of all profiles persisted within the current CiviCRM * settings, including the default profile. * - * @return array + * @return array * profile_name => CRM_Twingle_Profile */ public static function getProfiles() { @@ -439,7 +434,9 @@ class CRM_Twingle_Profile { */ public static function getProfileStats() { $stats = []; - $profile_data = CRM_Core_DAO::executeQuery('SELECT name, last_access, access_counter FROM civicrm_twingle_profile'); + $profile_data = CRM_Core_DAO::executeQuery( + 'SELECT name, last_access, access_counter FROM civicrm_twingle_profile' + ); while ($profile_data->fetch()) { // phpcs:disable Drupal.Arrays.Array.ArrayIndentation $stats[$profile_data->name] = [ diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 7c8ed9c..a6ce330 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -16,6 +16,7 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; +use Civi\Twingle\Exceptions\BaseException; class CRM_Twingle_Submission { @@ -40,18 +41,18 @@ class CRM_Twingle_Submission { public const EMPLOYER_RELATIONSHIP_TYPE_ID = 5; /** - * @param array &$params + * @param array &$params * A reference to the parameters array of the submission. * * @param \CRM_Twingle_Profile $profile * The Twingle profile to use for validation, defaults to the default * profile. * - * @throws \CiviCRM_API3_Exception + * @throws \CRM_Core_Exception * When invalid parameters have been submitted. */ - public static function validateSubmission(&$params, $profile = NULL) { - if (!$profile) { + public static function validateSubmission(&$params, $profile = NULL): void { + if (!isset($profile)) { $profile = CRM_Twingle_Profile::createDefaultProfile(); } @@ -62,8 +63,8 @@ class CRM_Twingle_Submission { 'quarterly', 'yearly', 'monthly', - ])) { - throw new CiviCRM_API3_Exception( + ], TRUE)) { + throw new CRM_Core_Exception( E::ts('Invalid donation rhythm.'), 'invalid_format' ); @@ -71,8 +72,9 @@ class CRM_Twingle_Submission { // Get the payment instrument defined within the profile, or return an error // if none matches (i.e. an unknown payment method was submitted). - if (!$payment_instrument_id = $profile->getAttribute('pi_' . $params['payment_method'])) { - throw new CiviCRM_API3_Exception( + $payment_instrument_id = $profile->getAttribute('pi_' . $params['payment_method']); + if (!isset($payment_instrument_id)) { + throw new CRM_Core_Exception( E::ts('Payment method could not be matched to existing payment instrument.'), 'invalid_format' ); @@ -80,16 +82,16 @@ class CRM_Twingle_Submission { $params['payment_instrument_id'] = $payment_instrument_id; // Validate date for parameter "confirmed_at". - if (!DateTime::createFromFormat('YmdHis', $params['confirmed_at'])) { - throw new CiviCRM_API3_Exception( + if (FALSE === DateTime::createFromFormat('YmdHis', $params['confirmed_at'])) { + throw new CRM_Core_Exception( E::ts('Invalid date for parameter "confirmed_at".'), 'invalid_format' ); } // Validate date for parameter "user_birthdate". - if (!empty($params['user_birthdate']) && !DateTime::createFromFormat('Ymd', $params['user_birthdate'])) { - throw new CiviCRM_API3_Exception( + if (!empty($params['user_birthdate']) && FALSE === DateTime::createFromFormat('Ymd', $params['user_birthdate'])) { + throw new CRM_Core_Exception( E::ts('Invalid date for parameter "user_birthdate".'), 'invalid_format' ); @@ -97,9 +99,10 @@ class CRM_Twingle_Submission { // Get the gender ID defined within the profile, or return an error if none // matches (i.e. an unknown gender was submitted). - if (!empty($params['user_gender'])) { - if (!$gender_id = $profile->getAttribute('gender_' . $params['user_gender'])) { - throw new CiviCRM_API3_Exception( + if (is_string($params['user_gender'])) { + $gender_id = $profile->getAttribute('gender_' . $params['user_gender']); + if (!isset($gender_id)) { + throw new CRM_Core_Exception( E::ts('Gender could not be matched to existing gender.'), 'invalid_format' ); @@ -108,12 +111,12 @@ class CRM_Twingle_Submission { } // Validate custom fields parameter, if given. - if (!empty($params['custom_fields'])) { + if (isset($params['custom_fields'])) { if (is_string($params['custom_fields'])) { $params['custom_fields'] = json_decode($params['custom_fields'], TRUE); } if (!is_array($params['custom_fields'])) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('Invalid format for custom fields.'), 'invalid_format' ); @@ -121,13 +124,13 @@ class CRM_Twingle_Submission { } // Validate campaign_id, if given. - if (!empty($params['campaign_id'])) { + if (isset($params['campaign_id'])) { // Check whether campaign_id is a numeric string and cast it to an integer. if (is_numeric($params['campaign_id'])) { $params['campaign_id'] = intval($params['campaign_id']); } else { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('campaign_id must be a numeric string. '), 'invalid_format' ); @@ -140,7 +143,7 @@ class CRM_Twingle_Submission { ['id' => $params['campaign_id']] ); } - catch (CiviCRM_API3_Exception $e) { + catch (CRM_Core_Exception $e) { unset($params['campaign_id']); } } @@ -152,28 +155,33 @@ class CRM_Twingle_Submission { * * @param string $contact_type * The contact type to look for/to create. - * @param array $contact_data + * @param array $contact_data * Data to use for contact lookup/to create a contact with. * @param CRM_Twingle_Profile $profile * Profile used for this process - * @param array $submission + * @param array $submission * Submission data * * @return int|NULL * The ID of the matching/created contact, or NULL if no matching contact * was found and no new contact could be created. - * @throws \CiviCRM_API3_Exception + * @throws \CRM_Core_Exception * When invalid data was given. */ - public static function getContact($contact_type, $contact_data, $profile, $submission = []) { + public static function getContact( + string $contact_type, + array $contact_data, + CRM_Twingle_Profile $profile, + array $submission = [] + ) { // If no parameters are given, do nothing. - if (empty($contact_data)) { + if ([] === $contact_data) { return NULL; } // add xcm profile $xcm_profile = $profile->getAttribute('xcm_profile'); - if (!empty($xcm_profile)) { + if (isset($xcm_profile) && '' !== $xcm_profile) { $contact_data['xcm_profile'] = $xcm_profile; } @@ -181,7 +189,7 @@ class CRM_Twingle_Submission { CRM_Twingle_Submission::setCampaign($contact_data, 'contact', $submission, $profile); // Prepare values: country. - if (!empty($contact_data['country'])) { + if (isset($contact_data['country'])) { if (is_numeric($contact_data['country'])) { // If a country ID is given, update the parameters. $contact_data['country_id'] = $contact_data['country']; @@ -190,12 +198,12 @@ class CRM_Twingle_Submission { else { // Look up the country depending on the given ISO code. $country = civicrm_api3('Country', 'get', ['iso_code' => $contact_data['country']]); - if (!empty($country['id'])) { + if (isset($country['id'])) { $contact_data['country_id'] = $country['id']; unset($contact_data['country']); } else { - throw new \CiviCRM_API3_Exception( + throw new \CRM_Core_Exception( E::ts('Unknown country %1.', [1 => $contact_data['country']]), 'invalid_format' ); @@ -204,7 +212,7 @@ class CRM_Twingle_Submission { } // Prepare values: language. - if (!empty($contact_data['preferred_language'])) { + if (is_string($contact_data['preferred_language']) && '' !== $contact_data['preferred_language']) { $mapping = CRM_Core_I18n_PseudoConstant::longForShortMapping(); // Override the default mapping for German. $mapping['de'] = 'de_DE'; @@ -214,39 +222,31 @@ class CRM_Twingle_Submission { // Pass to XCM. $contact_data['contact_type'] = $contact_type; $contact = civicrm_api3('Contact', 'getorcreate', $contact_data); - if (empty($contact['id'])) { - return NULL; - } - return $contact['id']; + return isset($contact['id']) ? (int) $contact['id'] : NULL; } /** * Shares an organisation's work address, unless the contact already has one. * - * @param $contact_id + * @param int $contact_id * The ID of the contact to share the organisation address with. - * @param $organisation_id + * @param int $organisation_id * The ID of the organisation whose address to share with the contact. - * @param $location_type_id + * @param int $location_type_id * The ID of the location type to use for address lookup. * * @return boolean * Whether the organisation address has been shared with the contact. * - * @throws \CiviCRM_API3_Exception + * @throws \CRM_Core_Exception * When looking up or creating the shared address failed. */ public static function shareWorkAddress( - $contact_id, - $organisation_id, - $location_type_id = self::LOCATION_TYPE_ID_WORK + int $contact_id, + int $organisation_id, + int $location_type_id = self::LOCATION_TYPE_ID_WORK ) { - if (empty($organisation_id)) { - // Only if organisation exists. - return FALSE; - } - // Check whether organisation has a WORK address. $existing_org_addresses = civicrm_api3('Address', 'get', [ 'contact_id' => $organisation_id, @@ -285,13 +285,9 @@ class CRM_Twingle_Submission { * @param int $organisation_id * The ID of the employer contact. * - * @throws \CiviCRM_API3_Exception + * @throws \CRM_Core_Exception */ - public static function updateEmployerRelation($contact_id, $organisation_id) { - if (empty($contact_id) || empty($organisation_id)) { - return; - } - + public static function updateEmployerRelation(int $contact_id, int $organisation_id): void { // see if there is already one $existing_relationship = civicrm_api3('Relationship', 'get', [ 'relationship_type_id' => self::EMPLOYER_RELATIONSHIP_TYPE_ID, @@ -318,15 +314,15 @@ class CRM_Twingle_Submission { * functionality is activated within the Twingle extension settings. * * @return bool - * @throws \CiviCRM_API3_Exception + * @throws \CRM_Core_Exception */ public static function civiSepaEnabled() { $sepa_extension = civicrm_api3('Extension', 'get', [ 'full_name' => 'org.project60.sepa', 'is_active' => 1, ]); - return Civi::settings()->get('twingle_use_sepa') - && $sepa_extension['count']; + return (bool) Civi::settings()->get('twingle_use_sepa') + && $sepa_extension['count'] >= 0; } /** @@ -337,7 +333,7 @@ class CRM_Twingle_Submission { * The submitted "donation_rhythm" paramter according to the API action * specification. * - * @return array + * @return array{'frequency_unit'?: string, 'frequency_interval'?: int} * An array with "frequency_unit" and "frequency_interval" keys, to be added * to contribution parameter arrays. */ @@ -378,19 +374,21 @@ class CRM_Twingle_Submission { * @return int * The next possible day of this or the next month to start collecting. */ - public static function getSEPACycleDay($start_date, $creditor_id) { + public static function getSEPACycleDay($start_date, $creditor_id): int { $buffer_days = (int) CRM_Sepa_Logic_Settings::getSetting('pp_buffer_days'); $frst_notice_days = (int) CRM_Sepa_Logic_Settings::getSetting('batching.FRST.notice', $creditor_id); - $earliest_rcur_date = strtotime("$start_date + $frst_notice_days days + $buffer_days days"); + if (FALSE === ($earliest_rcur_date = strtotime("$start_date + $frst_notice_days days + $buffer_days days"))) { + throw new BaseException(E::ts('Could not calculate SEPA cycle day from configuration.')); + } // Find the next cycle day $cycle_days = CRM_Sepa_Logic_Settings::getListSetting('cycledays', range(1, 28), $creditor_id); $earliest_cycle_day = $earliest_rcur_date; - while (!in_array(date('j', $earliest_cycle_day), $cycle_days)) { + while (!in_array(date('j', $earliest_cycle_day), $cycle_days, TRUE)) { $earliest_cycle_day = strtotime('+ 1 day', $earliest_cycle_day); } - return date('j', $earliest_cycle_day); + return (int) date('j', $earliest_cycle_day); } /** @@ -399,16 +397,21 @@ class CRM_Twingle_Submission { * from the submission data. Should that be empty, the profile's default * campaign is used. * - * @param array $entity_data + * @param array $entity_data * the data set where the campaign_id should be set * @param string $context * defines the type of the entity_data: one of 'contribution', 'membership','mandate', 'recurring', 'contact' - * @param array $submission + * @param array $submission * the submitted data * @param CRM_Twingle_Profile $profile * the twingle profile used */ - public static function setCampaign(&$entity_data, $context, $submission, $profile) { + public static function setCampaign( + array &$entity_data, + string $context, + array $submission, + CRM_Twingle_Profile $profile + ): void { // first: make sure it's not set from other workflows unset($entity_data['campaign_id']); @@ -418,13 +421,13 @@ class CRM_Twingle_Submission { // backward compatibility: $enabled_contexts = ['contribution', 'contact']; } - if (in_array($context, $enabled_contexts)) { + if (in_array($context, $enabled_contexts, TRUE)) { // use the submitted campaign if set - if (!empty($submission['campaign_id'])) { + if (is_numeric($submission['campaign_id'])) { $entity_data['campaign_id'] = $submission['campaign_id']; } // otherwise use the profile's - elseif (!empty($campaign = $profile->getAttribute('campaign'))) { + elseif (is_numeric($campaign = $profile->getAttribute('campaign'))) { $entity_data['campaign_id'] = $campaign; } } diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php index 5c4007c..9725a96 100644 --- a/CRM/Twingle/Tools.php +++ b/CRM/Twingle/Tools.php @@ -16,6 +16,7 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; +use Civi\Twingle\Exceptions\BaseException; class CRM_Twingle_Tools { @@ -29,11 +30,11 @@ class CRM_Twingle_Tools { * Check if the attempted modification of the recurring contribution is allowed. * If not, an exception will be raised * - * @param $recurring_contribution_id int - * @param $change array + * @param int $recurring_contribution_id + * @param array $change * @throws Exception if the change is not allowed */ - public static function checkRecurringContributionChange($recurring_contribution_id, $change) { + public static function checkRecurringContributionChange(int $recurring_contribution_id, array $change): void { // check if a change to the status is planned if (empty($change['contribution_status_id'])) { return; @@ -77,14 +78,17 @@ class CRM_Twingle_Tools { } // this _IS_ on of the cases where we should step in: - CRM_Twingle_Tools::processRecurringContributionTermination($recurring_contribution_id, $recurring_contribution); + CRM_Twingle_Tools::processRecurringContributionTermination( + $recurring_contribution_id, + $recurring_contribution + ); } /** * @param $recurring_contribution_id int recurring contribution ID to check * @param $recurring_contribution array recurring contribution data, optional * @return bool|null true, false or null if can't be determined - * @throws CiviCRM_API3_Exception + * @throws \CRM_Core_Exception */ public static function isTwingleRecurringContribution($recurring_contribution_id, $recurring_contribution = NULL) { // this currently only works with prefixes @@ -106,11 +110,13 @@ class CRM_Twingle_Tools { /** * Execute the recurring contribution protection * - * @param $recurring_contribution_id int recurring contribution ID - * @param $recurring_contribution array recurring contribution fields + * @param int $recurring_contribution_id + * Recurring contribution ID. + * @param array $recurring_contribution + * Recurring contribution fields. * @throws Exception could be one of the measures */ - public static function processRecurringContributionTermination($recurring_contribution_id, $recurring_contribution) { + public static function processRecurringContributionTermination(int $recurring_contribution_id, array $recurring_contribution) { // check if we're suspended if (self::$protection_suspended) { return; @@ -124,7 +130,7 @@ class CRM_Twingle_Tools { case CRM_Twingle_Config::RCUR_PROTECTION_EXCEPTION: // phpcs:disable Generic.Files.LineLength.TooLong - throw new Exception(E::ts( + throw new BaseException(E::ts( 'This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.' )); @@ -183,10 +189,10 @@ class CRM_Twingle_Tools { /** * Check if the given payment instrument is SEPA * - * @param $payment_instrument_id string payment instrument + * @param string $payment_instrument_id * @return boolean */ - public static function isSDD($payment_instrument_id) { + public static function isSDD(string $payment_instrument_id) { static $sepa_payment_instruments = NULL; if ($sepa_payment_instruments === NULL) { // init with instrument names @@ -208,11 +214,10 @@ class CRM_Twingle_Tools { /** * Get a CiviSEPA mandate for the given contribution ID * - * @param $contribution_id integer contribution ID *or* recurring contribution ID - * @return integer mandate ID or null + * @param int $contribution_id contribution ID *or* recurring contribution ID + * @return array|null mandate or null */ - public static function getMandateFor($contribution_id) { - $contribution_id = (int) $contribution_id; + public static function getMandateFor(int $contribution_id): ?array { if ($contribution_id) { try { // try recurring mandate diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 8741dac..2af4667 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -25,7 +25,7 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { /** * Installer script */ - public function install() { + public function install(): void { // create a DB table for the twingle profiles $this->executeSqlFile('sql/civicrm_twingle_profile.sql'); @@ -43,7 +43,7 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { * /** * Copy financial_type_id setting to new setting financial_type_id_recur. */ - public function upgrade_4000() { + public function upgrade_4000(): bool { $this->ctx->log->info('Applying update 4000: Copying Financial type to new setting Financial type (recurring).'); foreach (CRM_Twingle_Profile::getProfiles() as $profile) { $profile->setAttribute('financial_type_id_recur', $profile->getAttribute('financial_type_id')); @@ -57,7 +57,7 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { * * @link https://civicrm.org/advisory/civi-sa-2019-21-poi-saved-search-and-report-instance-apis */ - public function upgrade_5011() { + public function upgrade_5011(): bool { // Do not use CRM_Core_BAO::getItem() or Civi::settings()->get(). // Extract and unserialize directly from the database. $twingle_profiles_query = CRM_Core_DAO::executeQuery(" @@ -78,14 +78,14 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { * @return TRUE on success * @throws Exception */ - public function upgrade_5140() { + public function upgrade_5140(): bool { $this->ctx->log->info('Converting twingle profiles.'); // create a DB table for the twingle profiles $this->executeSqlFile('sql/civicrm_twingle_profile.sql'); // migrate the current profiles - if ($profiles_data = Civi::settings()->get('twingle_profiles')) { + if (is_array($profiles_data = Civi::settings()->get('twingle_profiles'))) { foreach ($profiles_data as $profile_name => $profile_data) { $profile = new CRM_Twingle_Profile($profile_name, $profile_data); $data = json_encode($profile->getData()); diff --git a/Civi/Twingle/Exceptions/BaseException.php b/Civi/Twingle/Exceptions/BaseException.php index f1ce9e3..5aa721e 100644 --- a/Civi/Twingle/Exceptions/BaseException.php +++ b/Civi/Twingle/Exceptions/BaseException.php @@ -35,14 +35,16 @@ class BaseException extends \Exception { /** * BaseException Constructor - * @param string $message - * Error message - * @param string $error_code - * A meaningful error code + * @param string|null $message + * Error message + * @param string|null $error_code + * A meaningful error code + * @param \Throwable|null $previous + * A previously thrown exception to include. */ - public function __construct(string $message = '', string $error_code = '') { - parent::__construct($message, 1); - $this->log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : ''; + public function __construct(?string $message = '', ?string $error_code = '', ?\Throwable $previous = NULL) { + parent::__construct($message, 1, $previous); + $this->log_message = '' !== $message ? E::LONG_NAME . ': ' . $message : ''; $this->code = $error_code; } @@ -59,7 +61,7 @@ class BaseException extends \Exception { * @return string */ public function getErrorCode() { - return $this->code; + return (string) $this->code; } } diff --git a/api/v3/TwingleDonation/Cancel.php b/api/v3/TwingleDonation/Cancel.php index 7e1eaa5..9061476 100644 --- a/api/v3/TwingleDonation/Cancel.php +++ b/api/v3/TwingleDonation/Cancel.php @@ -21,7 +21,7 @@ use CRM_Twingle_ExtensionUtil as E; * TwingleDonation.Cancel API specification (optional) * This is used for documentation and validation. * - * @param array $params description of fields supported by this API call + * @param array> $params description of fields supported by this API call * * @return void * @@ -61,8 +61,8 @@ function _civicrm_api3_twingle_donation_Cancel_spec(&$params) { /** * TwingleDonation.Cancel API * - * @param array $params - * @return array API result descriptor + * @param array $params + * @return array API result descriptor * @see civicrm_api3_create_success * @see civicrm_api3_create_error */ @@ -75,7 +75,7 @@ function civicrm_api3_twingle_donation_Cancel($params) { try { // Validate date for parameter "cancelled_at". if (!DateTime::createFromFormat('YmdHis', $params['cancelled_at'])) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('Invalid date for parameter "cancelled_at".'), 'invalid_format' ); @@ -89,7 +89,7 @@ function civicrm_api3_twingle_donation_Cancel($params) { ]); $contribution_type = 'Contribution'; } - catch (CiviCRM_API3_Exception $exception) { + catch (CRM_Core_Exception $exception) { $contribution = civicrm_api3('ContributionRecur', 'getsingle', [ 'trxn_id' => $default_profile->getTransactionID($params['trx_id']), ]); @@ -101,9 +101,9 @@ function civicrm_api3_twingle_donation_Cancel($params) { && CRM_Twingle_Tools::isSDD($contribution['payment_instrument_id']) ) { // End SEPA mandate if applicable. - $mandate = CRM_Twingle_Tools::getMandateFor($contribution['id']); + $mandate = CRM_Twingle_Tools::getMandateFor((int) $contribution['id']); if (!$mandate) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('SEPA Mandate for contribution [%1 not found.', [1 => $contribution['id']]), 'api_error' ); @@ -112,7 +112,7 @@ function civicrm_api3_twingle_donation_Cancel($params) { // Mandates can not be terminated in the past. $end_date = date_create_from_format('YmdHis', $params['cancelled_at']); - if ($end_date) { + if (FALSE !== $end_date) { // Mandates can not be terminated in the past: $end_date = date('Ymd', max( time(), @@ -128,7 +128,7 @@ function civicrm_api3_twingle_donation_Cancel($params) { $end_date, $params['cancel_reason'] )) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('Could not terminate SEPA mandate'), 'api_error' ); diff --git a/api/v3/TwingleDonation/Endrecurring.php b/api/v3/TwingleDonation/Endrecurring.php index 5d7b445..68023f9 100644 --- a/api/v3/TwingleDonation/Endrecurring.php +++ b/api/v3/TwingleDonation/Endrecurring.php @@ -21,7 +21,7 @@ use CRM_Twingle_ExtensionUtil as E; * TwingleDonation.Endrecurring API specification (optional) * This is used for documentation and validation. * - * @param array $params description of fields supported by this API call + * @param array> $params description of fields supported by this API call * * @return void * @@ -54,8 +54,8 @@ function _civicrm_api3_twingle_donation_endrecurring_spec(&$params) { /** * TwingleDonation.Endrecurring API * - * @param array $params - * @return array API result descriptor + * @param array $params + * @return array API result descriptor * @see civicrm_api3_create_success * @see civicrm_api3_create_error */ @@ -67,8 +67,8 @@ function civicrm_api3_twingle_donation_endrecurring($params) { try { // Validate date for parameter "ended_at". - if (!DateTime::createFromFormat('YmdHis', $params['ended_at'])) { - throw new CiviCRM_API3_Exception( + if (FALSE === DateTime::createFromFormat('YmdHis', $params['ended_at'])) { + throw new CRM_Core_Exception( E::ts('Invalid date for parameter "ended_at".'), 'invalid_format' ); @@ -86,9 +86,9 @@ function civicrm_api3_twingle_donation_endrecurring($params) { && CRM_Twingle_Tools::isSDD($contribution['payment_instrument_id']) ) { // END SEPA MANDATE - $mandate = CRM_Twingle_Tools::getMandateFor($contribution['id']); - if (!$mandate) { - throw new CiviCRM_API3_Exception( + $mandate = CRM_Twingle_Tools::getMandateFor((int) $contribution['id']); + if (!isset($mandate)) { + throw new CRM_Core_Exception( E::ts('SEPA Mandate for recurring contribution [%1 not found.', [1 => $contribution['id']]), 'api_error' ); @@ -96,7 +96,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) { $mandate_id = $mandate['id']; $end_date = date_create_from_format('YmdHis', $params['ended_at']); - if ($end_date) { + if (FALSE !== $end_date) { // Mandates can not be terminated in the past: $end_date = date('Ymd', max( time(), @@ -109,7 +109,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) { // verify that the mandate has not been terminated in the past if ($mandate['status'] != 'FRST' && $mandate['status'] != 'RCUR') { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('SEPA Mandate [%1] already terminated.', [1 => $mandate_id]), 'api_error' ); @@ -120,7 +120,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) { $end_date, E::ts('Mandate closed by TwingleDonation.Endrecurring API call') )) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('Could not terminate SEPA mandate'), 'api_error' ); diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 8f63aea..ecaeac8 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -16,12 +16,13 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; +use Civi\Twingle\Exceptions\BaseException; /** * TwingleDonation.Submit API specification * This is used for documentation and validation. * - * @param array $params + * @param array> $params * Description of fields supported by this API call. * * @return void @@ -259,8 +260,8 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { /** * TwingleDonation.Submit API * - * @param array $params - * @return array API result descriptor + * @param array $params + * @return array API result descriptor * @see civicrm_api3_create_success * @see civicrm_api3_create_error */ @@ -294,7 +295,7 @@ function civicrm_api3_twingle_donation_Submit($params) { 'trxn_id' => $profile->getTransactionID($params['trx_id']), ]); if ($existing_contribution['count'] > 0 || $existing_contribution_recur['count'] > 0) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('Contribution with the given transaction ID already exists.'), 'api_error' ); @@ -303,7 +304,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // Extract custom field values using the profile's mapping of Twingle fields // to CiviCRM custom fields. $custom_fields = []; - if (!empty($params['custom_fields'])) { + if (is_array($params['custom_fields'])) { $custom_field_mapping = $profile->getCustomFieldMapping(); // Make all params available for custom field mapping @@ -343,11 +344,9 @@ function civicrm_api3_twingle_donation_Submit($params) { 'user_city' => 'city', 'user_country' => 'country', ] as $address_param => $address_component) { - if (!empty($params[$address_param])) { + if (isset($params[$address_param]) && '' !== $params[$address_param]) { $params[$address_component] = $params[$address_param]; - if ($address_param != $address_component) { - unset($params[$address_param]); - } + unset($params[$address_param]); } } @@ -369,13 +368,13 @@ function civicrm_api3_twingle_donation_Submit($params) { } // Prepare parameter mapping for organisation. - if (!empty($params['user_company'])) { + if (is_string($params['user_company']) && '' !== $params['user_company']) { $params['organization_name'] = $params['user_company']; unset($params['user_company']); } // Remove parameter "id". - if (!empty($params['id'])) { + if (isset($params['id'])) { unset($params['id']); } @@ -419,67 +418,67 @@ function civicrm_api3_twingle_donation_Submit($params) { } // Get the prefix ID defined within the profile - if (!empty($params['user_gender'])) { - $prefix_id = (int) $profile->getAttribute('prefix_' . $params['user_gender']); - if ($prefix_id) { - $contact_data['prefix_id'] = $prefix_id; - } + if ( + isset($params['user_gender']) + && NULL !== ($prefix_id = $profile->getAttribute('prefix_' . $params['user_gender'])) + ) { + $contact_data['prefix_id'] = $prefix_id; } // Add custom field values. - if (!empty($custom_fields['Contact'])) { + if (isset($custom_fields['Contact'])) { $contact_data += $custom_fields['Contact']; } - if (!empty($custom_fields['Individual'])) { + if (isset($custom_fields['Individual'])) { $contact_data += $custom_fields['Individual']; } // Organisation lookup. - if (!empty($params['organization_name'])) { + if (is_string($params['organization_name']) && '' !== $params['organization_name']) { $organisation_data = [ 'organization_name' => $params['organization_name'], ]; // Add custom field values. - if (!empty($custom_fields['Organization'])) { + if (isset($custom_fields['Organization'])) { $organisation_data += $custom_fields['Organization']; } - if (!empty($submitted_address)) { + if ([] !== $submitted_address) { $organisation_data += $submitted_address; // Use configured location type for organisation address. $organisation_data['location_type_id'] = (int) $profile->getAttribute('location_type_id_organisation'); } - if (!$organisation_id = CRM_Twingle_Submission::getContact( + if (!is_int($organisation_id = CRM_Twingle_Submission::getContact( 'Organization', $organisation_data, $profile, $params - )) { - throw new CiviCRM_API3_Exception( + ))) { + throw new CRM_Core_Exception( E::ts('Organisation contact could not be found or created.'), 'api_error' ); } } - elseif (!empty($submitted_address)) { + elseif ([] !== $submitted_address) { $contact_data += $submitted_address; } - if (!$contact_id = CRM_Twingle_Submission::getContact( + if (!is_int($contact_id = CRM_Twingle_Submission::getContact( 'Individual', $contact_data, $profile, $params - )) { - throw new CiviCRM_API3_Exception( + ))) { + throw new CRM_Core_Exception( E::ts('Individual contact could not be found or created.'), 'api_error' ); } // Save user_extrafield as contact note. - if (!empty($params['user_extrafield'])) { + if (isset($params['user_extrafield']) && '' != $params['user_extrafield']) { civicrm_api3('Note', 'create', [ 'entity_table' => 'civicrm_contact', 'entity_id' => $contact_id, @@ -512,13 +511,13 @@ function civicrm_api3_twingle_donation_Submit($params) { // If usage of double opt-in is selected, use MailingEventSubscribe.create // to add contact to newsletter groups defined in the profile $result_values['newsletter']['newsletter_double_opt_in'] - = ($profile->getAttribute('newsletter_double_opt_in')) + = (bool) $profile->getAttribute('newsletter_double_opt_in') ? 'true' : 'false'; if ( - $profile->getAttribute('newsletter_double_opt_in') && - !empty($params['newsletter']) && - !empty($groups = $profile->getAttribute('newsletter_groups')) + (bool) $profile->getAttribute('newsletter_double_opt_in') + && isset($params['newsletter']) + && is_array($groups = $profile->getAttribute('newsletter_groups')) ) { $group_memberships = array_column( civicrm_api3( @@ -539,7 +538,7 @@ function civicrm_api3_twingle_donation_Submit($params) { 'id' => (int) $group_id, ] )['visibility'] == 'Public Pages'; - if (!in_array($group_id, $group_memberships) && $is_public_group) { + if (!in_array($group_id, $group_memberships, FALSE) && $is_public_group) { $result_values['newsletter'][][$group_id] = civicrm_api3( 'MailingEventSubscribe', 'create', @@ -557,8 +556,8 @@ function civicrm_api3_twingle_donation_Submit($params) { // If requested, add contact to newsletter groups defined in the profile. } elseif ( - !empty($params['newsletter']) - && !empty($groups = $profile->getAttribute('newsletter_groups')) + isset($params['newsletter']) + && is_array($groups = $profile->getAttribute('newsletter_groups')) ) { foreach ($groups as $group_id) { civicrm_api3( @@ -575,7 +574,10 @@ function civicrm_api3_twingle_donation_Submit($params) { } // If requested, add contact to postinfo groups defined in the profile. - if (!empty($params['postinfo']) && !empty($groups = $profile->getAttribute('postinfo_groups'))) { + if ( + isset($params['postinfo']) + && is_array($groups = $profile->getAttribute('postinfo_groups')) + ) { foreach ($groups as $group_id) { civicrm_api3('GroupContact', 'create', [ 'group_id' => $group_id, @@ -588,7 +590,10 @@ function civicrm_api3_twingle_donation_Submit($params) { // If requested, add contact to donation_receipt groups defined in the // profile. - if (!empty($params['donation_receipt']) && !empty($groups = $profile->getAttribute('donation_receipt_groups'))) { + if ( + isset($params['donation_receipt']) + && is_array($groups = $profile->getAttribute('donation_receipt_groups')) + ) { foreach ($groups as $group_id) { civicrm_api3('GroupContact', 'create', [ 'group_id' => $group_id, @@ -611,18 +616,18 @@ function civicrm_api3_twingle_donation_Submit($params) { ]; // Add custom field values. - if (!empty($custom_fields['Contribution'])) { + if (isset($custom_fields['Contribution'])) { $contribution_data += $custom_fields['Contribution']; } - if (!empty($params['purpose'])) { + if (isset($params['purpose'])) { $contribution_data['note'] = $params['purpose']; } // set campaign, subject to configuration CRM_Twingle_Submission::setCampaign($contribution_data, 'contribution', $params, $profile); - if (!empty($contribution_source = $profile->getAttribute('contribution_source'))) { + if (NULL !== ($contribution_source = $profile->getAttribute('contribution_source'))) { $contribution_data['source'] = $contribution_source; } @@ -637,8 +642,8 @@ function civicrm_api3_twingle_donation_Submit($params) { 'debit_iban', 'debit_bic', ] as $sepa_attribute) { - if (empty($params[$sepa_attribute])) { - throw new CiviCRM_API3_Exception( + if (!isset($params[$sepa_attribute])) { + throw new CRM_Core_Exception( E::ts('Missing attribute %1 for SEPA mandate', [ 1 => $sepa_attribute, ]), @@ -648,6 +653,11 @@ function civicrm_api3_twingle_donation_Submit($params) { } $creditor_id = $profile->getAttribute('sepa_creditor_id'); + if (!is_int($creditor_id)) { + throw new BaseException( + E::ts('SEPA creditor is not configured for profile "%1".', [1 => $profile->getName()]) + ); + } // Compose mandate data from contribution data, ... $mandate_data = @@ -669,10 +679,10 @@ function civicrm_api3_twingle_donation_Submit($params) { // phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus + CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']); // Add custom field values. - if (!empty($custom_fields['ContributionRecur'])) { + if (isset($custom_fields['ContributionRecur'])) { $mandate_data += $custom_fields['ContributionRecur']; } - if (!empty($mandate_source = $profile->getAttribute('contribution_source'))) { + if (NULL !== ($mandate_source = $profile->getAttribute('contribution_source'))) { $mandate_data['source'] = $mandate_source; } @@ -691,7 +701,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // If requested, let CiviSEPA generate the mandate reference $use_own_mandate_reference = Civi::settings()->get('twingle_dont_use_reference'); - if (!empty($use_own_mandate_reference)) { + if ((bool) $use_own_mandate_reference) { unset($mandate_data['reference']); } @@ -730,7 +740,7 @@ function civicrm_api3_twingle_donation_Submit($params) { + CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']); // Add custom field values. - if (!empty($custom_fields['ContributionRecur'])) { + if (isset($custom_fields['ContributionRecur'])) { $contribution_recur_data += $custom_fields['ContributionRecur']; $contribution_data += $custom_fields['ContributionRecur']; } @@ -740,7 +750,7 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution_recur = civicrm_api3('ContributionRecur', 'create', $contribution_recur_data); if ($contribution_recur['is_error']) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('Could not create recurring contribution.'), 'api_error' ); @@ -766,7 +776,7 @@ function civicrm_api3_twingle_donation_Submit($params) { ]); $contribution_data['contribution_recur_id'] = $parent_contribution['id']; } - catch (Exception $exception) { + catch (CRM_Core_Exception $exception) { $result_values['parent_contribution'] = E::ts( 'Could not find recurring contribution with given parent transaction ID.' ); @@ -775,7 +785,7 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution = civicrm_api3('Contribution', 'create', $contribution_data); if ($contribution['is_error']) { - throw new CiviCRM_API3_Exception( + throw new CRM_Core_Exception( E::ts('Could not create contribution'), 'api_error' ); @@ -799,12 +809,12 @@ function civicrm_api3_twingle_donation_Submit($params) { } else { // this is a follow-up recurring payment - $membership_type_id = FALSE; + $membership_type_id = NULL; } } // CREATE the membership if required - if (!empty($membership_type_id)) { + if (isset($membership_type_id)) { $membership_data = [ 'contact_id' => $contact_id, 'membership_type_id' => $membership_type_id, @@ -821,7 +831,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // call the postprocess API $postprocess_call = $profile->getAttribute('membership_postprocess_call'); - if (!empty($postprocess_call)) { + if (is_string($postprocess_call)) { [$pp_entity, $pp_action] = explode('.', $postprocess_call, 2); try { // gather the contribution IDs @@ -829,7 +839,7 @@ function civicrm_api3_twingle_donation_Submit($params) { if (isset($contribution_recur['id'])) { $recurring_contribution_id = $contribution_recur['id']; } - elseif (!empty($result_values['sepa_mandate'])) { + elseif (isset($result_values['sepa_mandate'])) { $mandate = reset($result_values['sepa_mandate']); if ($mandate['entity_table'] == 'civicrm_contribution_recur') { $recurring_contribution_id = (int) $mandate['entity_id']; @@ -851,14 +861,20 @@ function civicrm_api3_twingle_donation_Submit($params) { // refresh membership data $result_values['membership'] = civicrm_api3('Membership', 'getsingle', ['id' => $membership['id']]); } - catch (CiviCRM_API3_Exception $ex) { + catch (CRM_Core_Exception $exception) { // TODO: more error handling? - Civi::log() - ->warning( - "Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage() - ); - throw new Exception( - E::ts('Twingle membership postprocessing call has failed, see log for more information') + Civi::log()->warning( + sprintf( + 'Twingle membership postprocessing call %s.%s has failed: %s', + $pp_entity, + $pp_action, + $exception->getMessage() + ) + ); + throw new BaseException( + E::ts('Twingle membership postprocessing call has failed, see log for more information'), + NULL, + $exception ); } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 07d420f..0e10e72 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -22,6 +22,7 @@ + diff --git a/phpstan.neon.template b/phpstan.neon.template index 9f2f699..a65c395 100644 --- a/phpstan.neon.template +++ b/phpstan.neon.template @@ -9,5 +9,6 @@ parameters: - {VENDOR_DIR}/civicrm/civicrm-core/Civi/ - {VENDOR_DIR}/civicrm/civicrm-core/CRM/ - {VENDOR_DIR}/civicrm/civicrm-core/api/ + - {VENDOR_DIR}/civicrm/civicrm-packages/ bootstrapFiles: - {VENDOR_DIR}/autoload.php diff --git a/twingle.php b/twingle.php index f22eafc..8a838ea 100644 --- a/twingle.php +++ b/twingle.php @@ -8,7 +8,7 @@ use CRM_Twingle_ExtensionUtil as E; */ function twingle_civicrm_pre($op, $objectName, $id, &$params) { if ($objectName == 'ContributionRecur' && $op == 'edit') { - CRM_Twingle_Tools::checkRecurringContributionChange($id, $params); + CRM_Twingle_Tools::checkRecurringContributionChange((int) $id, $params); } } From 96c072eb8ec9f05e7262c222df9bb09043347f0a Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 7 Aug 2023 16:46:57 +0200 Subject: [PATCH 143/221] let CRM_Twingle_Profile class handle its validation --- CRM/Twingle/Form/Profile.php | 94 +++----------------- CRM/Twingle/Profile.php | 165 +++++++++++++++++++++++++++++++---- 2 files changed, 163 insertions(+), 96 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 312b0fb..0412b1c 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -553,89 +553,23 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { * TRUE when the form was successfully validated. */ public function validate() { - $values = $this->exportValues(); - // Validate new profile names. - if ( - isset($values['name']) - && (!isset($this->profile) || $values['name'] != $this->profile->getName() || $this->_op != 'edit') - && NULL !== CRM_Twingle_Profile::getProfile($values['name']) - ) { - $this->_errors['name'] = E::ts('A profile with this name already exists.'); - } + if (in_array($this->_op, ['create', 'edit', 'copy'])) { + // Create profile with new values + $profile_values = $this->exportValues(); + $profile = new CRM_Twingle_Profile( + $profile_values['name'], + $profile_values, + $this->profile_id + ); - // Restrict profile names to alphanumeric characters and the underscore. - if (isset($values['name']) && 1 === preg_match('/[^A-Za-z0-9\_]/', $values['name'])) { - $this->_errors['name'] = - E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); - } - - // Validate custom field mapping. - try { - if (isset($values['custom_field_mapping'])) { - $custom_field_mapping = preg_split('/\r\n|\r|\n/', $values['custom_field_mapping'], -1, PREG_SPLIT_NO_EMPTY); - if (!is_array($custom_field_mapping)) { - throw new BaseException( - E::ts('Could not parse custom field mapping.') - ); - } - foreach ($custom_field_mapping as $custom_field_map) { - $custom_field_map = explode('=', $custom_field_map); - if (count($custom_field_map) !== 2) { - throw new BaseException( - E::ts('Could not parse custom field mapping.') - ); - } - [$twingle_field_name, $custom_field_name] = $custom_field_map; - $custom_field_id = substr($custom_field_name, strlen('custom_')); - - // Check for custom field existence - try { - $custom_field = civicrm_api3('CustomField', 'getsingle', [ - 'id' => $custom_field_id, - ]); - } - catch (CRM_Core_Exception $exception) { - throw new BaseException( - E::ts( - 'Custom field custom_%1 does not exist.', - [1 => $custom_field_id] - ), - NULL, - $exception - ); - } - - // Only allow custom fields on relevant entities. - try { - $custom_group = civicrm_api3('CustomGroup', 'getsingle', [ - 'id' => $custom_field['custom_group_id'], - 'extends' => [ - 'IN' => [ - 'Contact', - 'Individual', - 'Organization', - 'Contribution', - 'ContributionRecur', - ], - ], - ]); - } - catch (CRM_Core_Exception $exception) { - throw new BaseException( - E::ts( - 'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.', - [1 => $custom_field['id']] - ), - NULL, - $exception - ); - } - } + // Validate profile data + try { + $profile->validate(); + } + catch (ProfileValidationError $e) { + $this->setElementError($e->getAffectedFieldName(), $e->getMessage()); } - } - catch (BaseException $exception) { - $this->_errors['custom_field_mapping'] = $exception->getMessage(); } return parent::validate(); diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index f7ad35d..dddee4e 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -99,14 +99,7 @@ class CRM_Twingle_Profile { * @return bool */ public function matches($project_id) { - $selector = $this->getAttribute('selector'); - $project_ids = array_map( - function($project_id) { - return trim($project_id); - }, - explode(',', $selector) - ); - return in_array($project_id, $project_ids, TRUE); + return in_array($project_id, $this->getProjectIds()); } /** @@ -179,6 +172,29 @@ class CRM_Twingle_Profile { $this->name = $name; } + /** + * Is this the default profile? + * + * @return bool + */ + public function is_default() { + return $this->name == 'default'; + } + + /** + * Retrieves the profile's project IDs. + * + * @return array + */ + public function getProjectIds(): array { + return array_map( + function($project_id) { + return trim($project_id); + }, + explode(',', $this->getAttribute("selector")) + ); + } + /** * Retrieves an attribute of the profile. * @@ -225,21 +241,138 @@ class CRM_Twingle_Profile { /** * Verifies whether the profile is valid (i.e. consistent and not colliding * with other profiles). + * + * @throws \CRM_Twingle_Exceptions_ProfileValidationError + * @throws \Civi\Core\Exception\DBQueryException + * When the profile could not be successfully validated. */ - public function verifyProfile(): void { - // TODO: check - // data of this profile consistent? - // conflicts with other profiles? + public function validate() { + + // Name cannot be empty + if (empty($this->getName())) { + throw new ProfileValidationError( + 'name', + E::ts('Profile name cannot be empty.'), + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ); + } + + // Restrict profile names to alphanumeric characters, space and the underscore. + $contains_illegal_characters = preg_match("/[^A-Za-z0-9_\s]/", $this->getName()); + if ($contains_illegal_characters) { + throw new ProfileValidationError( + 'name', + E::ts('Only alphanumeric characters, space and the underscore (_) are allowed for profile names.'), + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ); + } + + // Check if profile name is already used for other profile + $profile_name_duplicates = array_filter( + CRM_Twingle_Profile::getProfiles(), function($profile) { + return $profile->getName() == $this->getName() && $this->getId() != $profile->getId(); + }); + if (!empty($profile_name_duplicates)) { + throw new ProfileValidationError( + 'name', + E::ts("A profile with the name '%1' already exists.", [1 => $this->getName()]), + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ); + } + + // Check if project_id is already used in other profile + $profiles = $this::getProfiles(); + foreach ($profiles as $profile) { + if ($profile->getId() == $this->getId() || $profile->is_default()) continue; + $project_ids = $this->getProjectIds(); + $id_duplicates = array_intersect($profile->getProjectIds(), $project_ids); + if (!empty($id_duplicates)) { + throw new ProfileValidationError( + 'selector', + E::ts( + "Project ID(s) [%1] already used in profile '%2'.", + [ + 1 => implode(", ", $id_duplicates), + 2 => $profile->getName() + ] + ), + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ); + } + } + + // Validate custom field mapping. + $custom_field_mapping = $this->getAttribute('custom_field_mapping', FALSE); + if ($custom_field_mapping) { + $custom_field_mapping = preg_split('/\r\n|\r|\n/', $custom_field_mapping, -1, PREG_SPLIT_NO_EMPTY); + $parsing_error = new ProfileValidationError( + 'custom_field_mapping', + E::ts('Could not parse custom field mapping.'), + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ); + if (!is_array($custom_field_mapping)) { + throw $parsing_error; + } + foreach ($custom_field_mapping as $custom_field_map) { + $custom_field_map = explode("=", $custom_field_map); + if (count($custom_field_map) !== 2) { + throw $parsing_error; + } + [$twingle_field_name, $custom_field_name] = $custom_field_map; + $custom_field_id = substr($custom_field_name, strlen('custom_')); + + // Check for custom field existence + try { + $custom_field = civicrm_api3( + 'CustomField', 'getsingle', ['id' => $custom_field_id] + ); + } + catch (CiviCRM_API3_Exception $exception) { + throw new ProfileValidationError( + 'custom_field_mapping', + E::ts( + 'Custom field custom_%1 does not exist.', + [1 => $custom_field_id] + ), + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ); + } + + // Only allow custom fields on relevant entities. + try { + civicrm_api3('CustomGroup', 'getsingle', + [ + 'id' => $custom_field['custom_group_id'], + 'extends' => [ + 'IN' => [ + 'Contact', + 'Individual', + 'Organization', + 'Contribution', + 'ContributionRecur', + ], + ], + ]); + } catch (CiviCRM_API3_Exception $exception) { + throw new ProfileValidationError( + 'custom_field_mapping', + E::ts( + 'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.', + [1 => $custom_field['id']] + ), + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ); + } + } + } } /** * Persists the profile within the database. * - * @throws \Civi\Twingle\Exceptions\ProfileException + * @throws \CRM_Twingle_Exceptions_ProfileException */ - public function saveProfile(): void { - // make sure it's valid - $this->verifyProfile(); + public function saveProfile() { try { if ($this->id !== NULL) { From 8d1d93d77a01e675ab51717781175349ec995c6e Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 17 Aug 2023 10:41:45 +0200 Subject: [PATCH 144/221] display a warning instead of an error if the project_id is a duplicate --- CRM/Twingle/Form/Profile.php | 8 +++++++- CRM/Twingle/Profile.php | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 0412b1c..245091f 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -568,7 +568,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $profile->validate(); } catch (ProfileValidationError $e) { - $this->setElementError($e->getAffectedFieldName(), $e->getMessage()); + switch ($e->getErrorCode()) { + case ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED: + $this->setElementError($e->getAffectedFieldName(), $e->getMessage()); + break; + case ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_WARNING: + CRM_Core_Session::setStatus($e->getMessage(), E::ts('Warning')); + } } } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index dddee4e..35373a1 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -296,7 +296,7 @@ class CRM_Twingle_Profile { 2 => $profile->getName() ] ), - ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_WARNING ); } } From 6114772d07c81ef1a76601996957b73304f6b7b0 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 5 Apr 2024 13:18:45 +0200 Subject: [PATCH 145/221] PHP Code Sniffer and PHPStan fixes --- CRM/Twingle/Form/Profile.php | 38 ++-- CRM/Twingle/Profile.php | 171 +++++++++++------- Civi/Twingle/Exceptions/BaseException.php | 12 +- .../Exceptions/ProfileValidationError.php | 9 +- 4 files changed, 138 insertions(+), 92 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 245091f..109013f 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -16,8 +16,9 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; -use Civi\Twingle\Exceptions\ProfileException; use Civi\Twingle\Exceptions\BaseException; +use Civi\Twingle\Exceptions\ProfileException; +use Civi\Twingle\Exceptions\ProfileValidationError; /** * Form controller class @@ -168,7 +169,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { switch ($this->_op) { case 'delete': - if ($this->profile) { + if (isset($this->profile)) { CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', [1 => $this->profile->getName()])); $this->addButtons([ [ @@ -185,23 +186,26 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Retrieve the source profile name. $source_id = CRM_Utils_Request::retrieve('source_id', 'Int', $this); // When copying without a valid profile id, copy the default profile. - if (!$source_id) { + if (!is_int($source_id)) { $this->profile = CRM_Twingle_Profile::createDefaultProfile(); - } else { + } + else { try { $source_profile = CRM_Twingle_Profile::getProfile($source_id); $this->profile = $source_profile->copy(); $this->profile->validate(); - } catch (ProfileValidationError $e) { - if ($e->getErrorCode() == ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED) { - Civi::log()->error($e->getLogMessage()); + } + catch (ProfileValidationError $exception) { + if ($exception->getErrorCode() == ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED) { + Civi::log()->error($exception->getLogMessage()); CRM_Core_Session::setStatus(E::ts('The profile is invalid and cannot be copied.'), E::ts('Error')); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1')); return; } - } catch (ProfileException $e) { - if ($e->getErrorCode() == ProfileException::ERROR_CODE_PROFILE_NOT_FOUND) { - Civi::log()->error($e->getLogMessage()); + } + catch (ProfileException $exception) { + if ($exception->getErrorCode() == ProfileException::ERROR_CODE_PROFILE_NOT_FOUND) { + Civi::log()->error($exception->getLogMessage()); CRM_Core_Session::setStatus(E::ts('The profile to be copied could not be found.'), E::ts('Error')); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1')); return; @@ -209,7 +213,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { } catch (Civi\Core\Exception\DBQueryException $e) { Civi::log()->error($e->getMessage()); - CRM_Core_Session::setStatus(E::ts('A database error has occurred. See the log for details.'), E::ts('Error')); + CRM_Core_Session::setStatus( + E::ts('A database error has occurred. See the log for details.'), + E::ts('Error') + ); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1')); return; } @@ -218,7 +225,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { break; case 'edit': - CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', [1 => $this->profile->getName()])); + CRM_Utils_System::setTitle( + E::ts('Edit Twingle API profile %1', [1 => $this->profile->getName()]) + ); break; case 'create': @@ -554,8 +563,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public function validate() { - if (in_array($this->_op, ['create', 'edit', 'copy'])) { - // Create profile with new values + if (in_array($this->_op, ['create', 'edit', 'copy'], TRUE)) { + // Create profile with new values. $profile_values = $this->exportValues(); $profile = new CRM_Twingle_Profile( $profile_values['name'], @@ -572,6 +581,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { case ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED: $this->setElementError($e->getAffectedFieldName(), $e->getMessage()); break; + case ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_WARNING: CRM_Core_Session::setStatus($e->getMessage(), E::ts('Warning')); } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 35373a1..4e186ad 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -17,6 +17,7 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; use Civi\Twingle\Exceptions\ProfileException as ProfileException; +use Civi\Twingle\Exceptions\ProfileValidationError; /** * Profiles define how incoming submissions from the Twingle API are @@ -25,16 +26,16 @@ use Civi\Twingle\Exceptions\ProfileException as ProfileException; class CRM_Twingle_Profile { /** - * @var int $id + * @var int * The id of the profile. */ - protected $id = NULL; + protected ?int $id; /** - * @var string $name + * @var string * The name of the profile. */ - protected $name; + protected string $name; /** * @var array @@ -99,7 +100,7 @@ class CRM_Twingle_Profile { * @return bool */ public function matches($project_id) { - return in_array($project_id, $this->getProjectIds()); + return in_array($project_id, $this->getProjectIds(), TRUE); } /** @@ -141,7 +142,7 @@ class CRM_Twingle_Profile { * * @return int */ - public function getId() { + public function getId(): ?int { return $this->id; } @@ -150,7 +151,7 @@ class CRM_Twingle_Profile { * * @param int $id */ - public function setId(int $id) { + public function setId(int $id): void { $this->id = $id; } @@ -159,7 +160,7 @@ class CRM_Twingle_Profile { * * @return string */ - public function getName() { + public function getName(): string { return $this->name; } @@ -177,21 +178,21 @@ class CRM_Twingle_Profile { * * @return bool */ - public function is_default() { - return $this->name == 'default'; + public function is_default(): bool { + return $this->name === 'default'; } /** * Retrieves the profile's project IDs. * - * @return array + * @return array */ public function getProjectIds(): array { return array_map( function($project_id) { return trim($project_id); }, - explode(',', $this->getAttribute("selector")) + explode(',', $this->getAttribute('selector') ?? '') ); } @@ -242,14 +243,14 @@ class CRM_Twingle_Profile { * Verifies whether the profile is valid (i.e. consistent and not colliding * with other profiles). * - * @throws \CRM_Twingle_Exceptions_ProfileValidationError + * @throws \Civi\Twingle\Exceptions\ProfileValidationError * @throws \Civi\Core\Exception\DBQueryException * When the profile could not be successfully validated. */ - public function validate() { + public function validate(): void { // Name cannot be empty - if (empty($this->getName())) { + if ('' === $this->getName()) { throw new ProfileValidationError( 'name', E::ts('Profile name cannot be empty.'), @@ -258,7 +259,7 @@ class CRM_Twingle_Profile { } // Restrict profile names to alphanumeric characters, space and the underscore. - $contains_illegal_characters = preg_match("/[^A-Za-z0-9_\s]/", $this->getName()); + $contains_illegal_characters = (1 !== preg_match('/[^A-Za-z0-9_\s]/', $this->getName())); if ($contains_illegal_characters) { throw new ProfileValidationError( 'name', @@ -269,10 +270,11 @@ class CRM_Twingle_Profile { // Check if profile name is already used for other profile $profile_name_duplicates = array_filter( - CRM_Twingle_Profile::getProfiles(), function($profile) { - return $profile->getName() == $this->getName() && $this->getId() != $profile->getId(); - }); - if (!empty($profile_name_duplicates)) { + CRM_Twingle_Profile::getProfiles(), + function($profile) { + return $profile->getName() == $this->getName() && $this->getId() != $profile->getId(); + }); + if ([] !== $profile_name_duplicates) { throw new ProfileValidationError( 'name', E::ts("A profile with the name '%1' already exists.", [1 => $this->getName()]), @@ -283,17 +285,19 @@ class CRM_Twingle_Profile { // Check if project_id is already used in other profile $profiles = $this::getProfiles(); foreach ($profiles as $profile) { - if ($profile->getId() == $this->getId() || $profile->is_default()) continue; + if ($profile->getId() == $this->getId() || $profile->is_default()) { + continue; + }; $project_ids = $this->getProjectIds(); $id_duplicates = array_intersect($profile->getProjectIds(), $project_ids); - if (!empty($id_duplicates)) { + if ([] !== $id_duplicates) { throw new ProfileValidationError( 'selector', E::ts( "Project ID(s) [%1] already used in profile '%2'.", [ - 1 => implode(", ", $id_duplicates), - 2 => $profile->getName() + 1 => implode(', ', $id_duplicates), + 2 => $profile->getName(), ] ), ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_WARNING @@ -302,8 +306,8 @@ class CRM_Twingle_Profile { } // Validate custom field mapping. - $custom_field_mapping = $this->getAttribute('custom_field_mapping', FALSE); - if ($custom_field_mapping) { + $custom_field_mapping = $this->getAttribute('custom_field_mapping'); + if (is_string($custom_field_mapping)) { $custom_field_mapping = preg_split('/\r\n|\r|\n/', $custom_field_mapping, -1, PREG_SPLIT_NO_EMPTY); $parsing_error = new ProfileValidationError( 'custom_field_mapping', @@ -314,7 +318,7 @@ class CRM_Twingle_Profile { throw $parsing_error; } foreach ($custom_field_mapping as $custom_field_map) { - $custom_field_map = explode("=", $custom_field_map); + $custom_field_map = explode('=', $custom_field_map); if (count($custom_field_map) !== 2) { throw $parsing_error; } @@ -323,18 +327,22 @@ class CRM_Twingle_Profile { // Check for custom field existence try { + /** + * @phpstan-var array $custom_field + */ $custom_field = civicrm_api3( 'CustomField', 'getsingle', ['id' => $custom_field_id] ); } - catch (CiviCRM_API3_Exception $exception) { + catch (CRM_Core_Exception $exception) { throw new ProfileValidationError( 'custom_field_mapping', E::ts( 'Custom field custom_%1 does not exist.', [1 => $custom_field_id] ), - ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED, + $exception ); } @@ -353,14 +361,16 @@ class CRM_Twingle_Profile { ], ], ]); - } catch (CiviCRM_API3_Exception $exception) { + } + catch (CRM_Core_Exception $exception) { throw new ProfileValidationError( 'custom_field_mapping', E::ts( 'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.', [1 => $custom_field['id']] ), - ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED + ProfileValidationError::ERROR_CODE_PROFILE_VALIDATION_FAILED, + $exception ); } } @@ -370,15 +380,14 @@ class CRM_Twingle_Profile { /** * Persists the profile within the database. * - * @throws \CRM_Twingle_Exceptions_ProfileException + * @throws \Civi\Twingle\Exceptions\ProfileException */ - public function saveProfile() { - + public function saveProfile(): void { try { - if ($this->id !== NULL) { + if (isset($this->id)) { // existing profile -> just update the config CRM_Core_DAO::executeQuery( - "UPDATE civicrm_twingle_profile SET config = %2, name = %3 WHERE id = %1", + 'UPDATE civicrm_twingle_profile SET config = %2, name = %3 WHERE id = %1', [ 1 => [$this->id, 'String'], 2 => [json_encode($this->data), 'String'], @@ -388,17 +397,20 @@ class CRM_Twingle_Profile { else { // new profile -> add new entry to the DB CRM_Core_DAO::executeQuery( - "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)", + << [$this->name, 'String'], 2 => [json_encode($this->data), 'String'], ]); } } - catch (Exception $e) { + catch (Exception $exception) { throw new ProfileException( - E::ts("Could not save/update profile: %1", [1 => $e->getMessage()]), - ProfileException::ERROR_CODE_COULD_NOT_SAVE_PROFILE + E::ts('Could not save/update profile: %1', [1 => $exception->getMessage()]), + ProfileException::ERROR_CODE_COULD_NOT_SAVE_PROFILE, + $exception ); } } @@ -408,7 +420,7 @@ class CRM_Twingle_Profile { * * @throws \Civi\Twingle\Exceptions\ProfileException */ - public function deleteProfile() { + public function deleteProfile(): void { // Do only reset default profile if ($this->getName() == 'default') { try { @@ -417,31 +429,31 @@ class CRM_Twingle_Profile { $default_profile->saveProfile(); // Reset counter - CRM_Core_DAO::executeQuery("UPDATE civicrm_twingle_profile SET access_counter = 0, last_access = NULL WHERE id = %1", [ - 1 => [ - $this->id, - 'Integer' - ] - ]); - } catch (Exception $e) { + CRM_Core_DAO::executeQuery( + 'UPDATE civicrm_twingle_profile SET access_counter = 0, last_access = NULL WHERE id = %1', + [1 => [$this->id, 'Integer']] + ); + } + catch (Exception $exception) { throw new ProfileException( - E::ts("Could not reset default profile: %1", [1 => $e->getMessage()]), - ProfileException::ERROR_CODE_COULD_NOT_RESET_PROFILE + E::ts('Could not reset default profile: %1', [1 => $exception->getMessage()]), + ProfileException::ERROR_CODE_COULD_NOT_RESET_PROFILE, + $exception ); } } else { try { - CRM_Core_DAO::executeQuery("DELETE FROM civicrm_twingle_profile WHERE id = %1", [ - 1 => [ - $this->id, - 'Integer' - ] - ]); - } catch (Exception $e) { + CRM_Core_DAO::executeQuery( + 'DELETE FROM civicrm_twingle_profile WHERE id = %1', + [1 => [$this->id, 'Integer']] + ); + } + catch (Exception $exception) { throw new ProfileException( - E::ts("Could not delete profile: %1", [1 => $e->getMessage()]), - ProfileException::ERROR_CODE_COULD_NOT_DELETE_PROFILE + E::ts('Could not delete profile: %1', [1 => $exception->getMessage()]), + ProfileException::ERROR_CODE_COULD_NOT_DELETE_PROFILE, + $exception ); } } @@ -620,11 +632,20 @@ class CRM_Twingle_Profile { * @throws \Civi\Twingle\Exceptions\ProfileException */ public static function getProfile(int $id = NULL) { - if (!empty($id)) { - $profile_data = CRM_Core_DAO::executeQuery("SELECT id, name, config FROM civicrm_twingle_profile WHERE id = %1", - [1 => [$id, 'Integer']]); + if (isset($id)) { + /** + * @var CRM_Core_DAO $profile_data + */ + $profile_data = CRM_Core_DAO::executeQuery( + 'SELECT id, name, config FROM civicrm_twingle_profile WHERE id = %1', + [1 => [$id, 'Integer']] + ); if ($profile_data->fetch()) { - return new CRM_Twingle_Profile($profile_data->name, json_decode($profile_data->config, 1), (int) $profile_data->id); + return new CRM_Twingle_Profile( + $profile_data->name, + json_decode($profile_data->config, TRUE), + (int) $profile_data->id + ); } } throw new ProfileException('Profile not found.', ProfileException::ERROR_CODE_PROFILE_NOT_FOUND); @@ -634,16 +655,23 @@ class CRM_Twingle_Profile { * Retrieves the list of all profiles persisted within the current CiviCRM * settings, including the default profile. * - * @return array - * profile_name => CRM_Twingle_Profile + * @return array + * An array of profiles with profile IDs as keys and profile objects as values. * @throws \Civi\Core\Exception\DBQueryException */ - public static function getProfiles() { + public static function getProfiles(): array { // todo: cache? $profiles = []; - $profile_data = CRM_Core_DAO::executeQuery("SELECT id, name, config FROM civicrm_twingle_profile"); + /** + * @var CRM_Core_DAO $profile_data + */ + $profile_data = CRM_Core_DAO::executeQuery('SELECT id, name, config FROM civicrm_twingle_profile'); while ($profile_data->fetch()) { - $profiles[$profile_data->id] = new CRM_Twingle_Profile($profile_data->name, json_decode($profile_data->config, 1), (int) $profile_data->id); + $profiles[(int) $profile_data->id] = new CRM_Twingle_Profile( + $profile_data->name, + json_decode($profile_data->config, TRUE), + (int) $profile_data->id + ); } return $profiles; } @@ -651,17 +679,20 @@ class CRM_Twingle_Profile { /** * Get the stats (access_count, last_access) for all twingle profiles * - * @return CRM_Twingle_Profile[] + * @return array> * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileStats() { $stats = []; + /** + * @var CRM_Core_DAO $profile_data + */ $profile_data = CRM_Core_DAO::executeQuery( 'SELECT name, last_access, access_counter FROM civicrm_twingle_profile' ); while ($profile_data->fetch()) { // phpcs:disable Drupal.Arrays.Array.ArrayIndentation - $stats[$profile_data->name] = [ + $stats[(string) $profile_data->name] = [ 'name' => $profile_data->name, 'last_access' => $profile_data->last_access, 'last_access_txt' => $profile_data->last_access diff --git a/Civi/Twingle/Exceptions/BaseException.php b/Civi/Twingle/Exceptions/BaseException.php index 5aa721e..a5413d5 100644 --- a/Civi/Twingle/Exceptions/BaseException.php +++ b/Civi/Twingle/Exceptions/BaseException.php @@ -28,21 +28,21 @@ use CRM_Twingle_ExtensionUtil as E; class BaseException extends \Exception { /** - * @var int|string + * @var string */ protected $code; protected string $log_message; /** * BaseException Constructor - * @param string|null $message + * @param string $message * Error message - * @param string|null $error_code + * @param string $error_code * A meaningful error code - * @param \Throwable|null $previous + * @param \Throwable $previous * A previously thrown exception to include. */ - public function __construct(?string $message = '', ?string $error_code = '', ?\Throwable $previous = NULL) { + public function __construct(string $message = '', string $error_code = '', \Throwable $previous = NULL) { parent::__construct($message, 1, $previous); $this->log_message = '' !== $message ? E::LONG_NAME . ': ' . $message : ''; $this->code = $error_code; @@ -61,7 +61,7 @@ class BaseException extends \Exception { * @return string */ public function getErrorCode() { - return (string) $this->code; + return $this->code; } } diff --git a/Civi/Twingle/Exceptions/ProfileValidationError.php b/Civi/Twingle/Exceptions/ProfileValidationError.php index da29705..de1b242 100644 --- a/Civi/Twingle/Exceptions/ProfileValidationError.php +++ b/Civi/Twingle/Exceptions/ProfileValidationError.php @@ -38,8 +38,13 @@ class ProfileValidationError extends BaseException { * @param string $error_code * A meaningful error code */ - public function __construct(string $affected_field_name, string $message = '', string $error_code = '') { - parent::__construct($message, $error_code); + public function __construct( + string $affected_field_name, + string $message = '', + string $error_code = '', + ?\Throwable $previous = NULL + ) { + parent::__construct($message, $error_code, $previous); $this->affected_field_name = $affected_field_name; } From 88850bbce3448a02157f3155b305e6a0fb6c11f0 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 5 Apr 2024 13:46:03 +0200 Subject: [PATCH 146/221] PHPStan fixes --- CRM/Twingle/Form/Profile.php | 109 ++++++++++++++--------------------- 1 file changed, 42 insertions(+), 67 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 43307c4..28a3340 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -102,7 +102,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { protected static array $_genderOptions; /** - * @var array + * @var array * * A static cache of retrieved prefixes found within * static::getGenderOptions(). @@ -110,7 +110,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { protected static array $_prefixOptions; /** - * @var array + * @var array * * A static cache of retrieved location types found within * static::getLocationTypes(). @@ -150,6 +150,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { if ($this->_op != 'copy' && $this->_op != 'create') { $this->profile_id = CRM_Utils_Request::retrieve('id', 'Int', $this); $this->profile = CRM_Twingle_Profile::getProfile($this->profile_id); + if (!isset($this->profile)) { + throw new ProfileException(E::ts('Profile with ID "%1" not found', [1 => $this->profile_id])); + } } // Set redirect destination. @@ -192,6 +195,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { else { try { $source_profile = CRM_Twingle_Profile::getProfile($source_id); + if (!isset($source_profile)) { + throw new ProfileException(E::ts('Profile with ID "%1" not found', [1 => $source_id])); + } $this->profile = $source_profile->copy(); $this->profile->validate(); } @@ -225,6 +231,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { break; case 'edit': + if (!isset($this->profile)) { + throw new ProfileException(E::ts('Profile with ID "%1" not found', [1 => $this->profile_id])); + } CRM_Utils_System::setTitle( E::ts('Edit Twingle API profile %1', [1 => $this->profile->getName()]) ); @@ -247,8 +256,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Add form elements. $this->add( - 'text', // field type - 'name', // field name + 'text', + 'name', E::ts('Profile name'), ['class' => 'huge'] + ($is_default && $this->_op == 'edit' ? ['readonly'] : []), !$is_default @@ -257,11 +266,11 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Do only display selector if this is not the default profile if (!$is_default) { $this->add( - 'text', // field type - 'selector', // field name - E::ts('Project IDs'), // field label + 'text', + 'selector', + E::ts('Project IDs'), ['class' => 'huge'], - TRUE // is required + TRUE ); } @@ -290,27 +299,17 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ); $this->add( - // field type 'select', - // field name 'financial_type_id', - // field label E::ts('Financial type'), - // list of options static::getFinancialTypes(), - // is required TRUE ); $this->add( - // field type 'select', - // field name 'financial_type_id_recur', - // field label E::ts('Financial type (recurring)'), - // list of options static::getFinancialTypes(), - // is required TRUE ); @@ -359,15 +358,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->assign('payment_instruments', $payment_instruments); foreach ($payment_instruments as $pi_name => $pi_label) { $this->add( - // field type 'select', - // field name $pi_name, - // field label E::ts('Record %1 as', [1 => $pi_label]), - // list of options static::getPaymentInstruments(), - // is required TRUE ); @@ -391,66 +385,43 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { } $this->add( - // field type 'checkbox', - // field name 'newsletter_double_opt_in', - // field label E::ts('Use Double-Opt-In for newsletter') ); $this->add( - // field type 'select', - // field name 'newsletter_groups', - // field label E::ts('Sign up for newsletter groups'), - // list of options static::getNewsletterGroups(), - // is not required FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - // field type 'select', - // field name 'postinfo_groups', - // field label E::ts('Sign up for postal mail groups'), - // list of options static::getPostinfoGroups(), - // is not required FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - // field type 'select', - // field name 'donation_receipt_groups', - // field label E::ts('Sign up for Donation receipt groups'), - // list of options static::getDonationReceiptGroups(), - // is not required FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - // field type 'select', - // field name 'campaign', - // field label E::ts('Default Campaign'), - // list of options ['' => E::ts('- none -')] + static::getCampaigns(), - // is not required FALSE, ['class' => 'crm-select2 huge'] ); @@ -472,28 +443,18 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ); $this->add( - // field type 'select', - // field name 'membership_type_id', - // field label E::ts('Create membership of type'), - // list of options ['' => E::ts('- none -')] + static::getMembershipTypes(), - // is not required FALSE, ['class' => 'crm-select2 huge'] ); $this->add( - // field type 'select', - // field name 'membership_type_id_recur', - // field label E::ts('Create membership of type (recurring)'), - // list of options ['' => E::ts('- none -')] + static::getMembershipTypes(), - // is not required FALSE, ['class' => 'crm-select2 huge'] ); @@ -510,11 +471,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ); $this->add( - // field type 'text', - // field name 'contribution_source', - // field label E::ts('Contribution source'), [] ); @@ -529,17 +487,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'city' => E::ts('City'), 'country' => E::ts('Country'), ], - // is not required FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - // field type 'textarea', - // field name 'custom_field_mapping', - // field label E::ts('Custom field mapping'), [] ); @@ -599,8 +553,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public function setDefaultValues() { $defaults = parent::setDefaultValues(); - if (in_array($this->_op, ['create', 'edit', 'copy'])) { - if (!$this->profile) { + if (in_array($this->_op, ['create', 'edit', 'copy'], TRUE)) { + if (!isset($this->profile)) { $this->profile = CRM_Twingle_Profile::createDefaultProfile()->copy(); } $defaults['name'] = $this->profile->getName(); @@ -665,6 +619,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public static function getLocationTypes() { if (!isset(static::$_locationTypes)) { static::$_locationTypes = []; + /** + * @phpstan-var array{values: array} $query + */ $query = civicrm_api3('LocationType', 'get', [ 'option.limit' => 0, 'is_active' => 1, @@ -687,6 +644,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { static::$_xcm_profiles = [ '' => E::ts('<select profile>'), ]; + /** + * @phpstan-var array $profiles + */ $profiles = CRM_Xcm_Configuration::getProfileList(); foreach ($profiles as $profile_key => $profile_name) { static::$_xcm_profiles[$profile_key] = $profile_name; @@ -705,6 +665,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public static function getFinancialTypes() { if (!isset(static::$_financialTypes)) { static::$_financialTypes = []; + /** + * @phpstan-var array{values: array} $query + */ $query = civicrm_api3('FinancialType', 'get', [ 'option.limit' => 0, 'is_active' => 1, @@ -726,13 +689,16 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public static function getMembershipTypes() { if (!isset(static::$_membershipTypes)) { static::$_membershipTypes = []; + /** + * @phpstan-var array{values: array} $query + */ $query = civicrm_api3('MembershipType', 'get', [ 'option.limit' => 0, 'is_active' => 1, 'return' => 'id,name', ]); foreach ($query['values'] as $type) { - static::$_membershipTypes[$type['id']] = $type['name']; + static::$_membershipTypes[(int) $type['id']] = $type['name']; } } return static::$_membershipTypes; @@ -747,6 +713,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public static function getGenderOptions() { if (!isset(static::$_genderOptions)) { static::$_genderOptions = []; + /** + * @phpstan-var array{values: array} $query + */ $query = civicrm_api3('OptionValue', 'get', [ 'option.limit' => 0, 'option_group_id' => 'gender', @@ -772,6 +741,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public static function getPrefixOptions() { if (!isset(static::$_prefixOptions)) { static::$_prefixOptions = ['' => E::ts('none')]; + /** + * @phpstan-var array{values: array} $query + */ $query = civicrm_api3('OptionValue', 'get', [ 'option.limit' => 0, 'option_group_id' => 'individual_prefix', @@ -782,7 +754,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ], ]); foreach ($query['values'] as $prefix) { - static::$_prefixOptions[(int) $prefix['value']] = $prefix['label']; + static::$_prefixOptions[$prefix['value']] = $prefix['label']; } } return static::$_prefixOptions; @@ -797,6 +769,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { if (!isset(static::$_sepaCreditors)) { static::$_sepaCreditors = []; if (CRM_Twingle_Submission::civiSepaEnabled()) { + /** + * @phpstan-var array{values: array} $result + */ $result = civicrm_api3('SepaCreditor', 'get', [ 'option.limit' => 0, ]); From a91fbd0c20a32dc4f15014521350431c47446509 Mon Sep 17 00:00:00 2001 From: Maria <70949178+mariav0@users.noreply.github.com> Date: Mon, 5 Jun 2023 16:00:39 +0200 Subject: [PATCH 147/221] Update Profile.php adding generic payment method --- CRM/Twingle/Profile.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 356e3a0..b50f7d2 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -525,6 +525,7 @@ class CRM_Twingle_Profile { 'pi_ideal' => E::ts('iDEAL'), 'pi_post_finance' => E::ts('Postfinance'), 'pi_bancontact' => E::ts('Bancontact'), + 'pi_generic' => E::ts('Generic Payment Method'), ]; } @@ -564,6 +565,7 @@ class CRM_Twingle_Profile { 'pi_ideal' => NULL, 'pi_post_finance' => NULL, 'pi_bancontact' => NULL, + 'pi_generic' => NULL, 'sepa_creditor_id' => NULL, 'gender_male' => 2, 'gender_female' => 1, From 313d2f648f2b7419da4faae390fdf6058229ad44 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 5 Apr 2024 14:29:56 +0200 Subject: [PATCH 148/221] Show error messages for missing configuration values --- CRM/Twingle/Form/Profile.php | 16 +++++ CRM/Twingle/Profile.php | 122 ++++++++++++++++++++++++++--------- 2 files changed, 106 insertions(+), 32 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 28a3340..af1832a 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -562,10 +562,26 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { foreach ($profile_data as $element_name => $value) { $defaults[$element_name] = $value; } + // backwards compatibility, see issue #27 if (!isset($profile_data['campaign_targets'])) { $defaults['campaign_targets'] = ['contribution', 'contact']; } + + // Show warning when there is configuration missing for required fields. + $requiredConfig = CRM_Twingle_Profile::allowedAttributes(TRUE); + foreach ($requiredConfig as $key => $metadata) { + if (!isset($profile_data[$key]) && $metadata['required']) { + CRM_Core_Session::setStatus( + E::ts( + 'The required configuration option "%1" has no value. Saving the profile might set this option to a possibly unwanted default value.', + [1 => $metadata['label'] ?? $key] + ), + E::ts('Error'), + 'error' + ); + } + } } return $defaults; } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index b50f7d2..523cb18 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -462,45 +462,103 @@ class CRM_Twingle_Profile { /** * Returns an array of attributes allowed for a profile. * - * @return array + * @return array|array */ - public static function allowedAttributes() { - return array_merge( + public static function allowedAttributes(bool $asMetadata = FALSE) { + $attributes = array_merge( [ - 'selector', - 'xcm_profile', - 'location_type_id', - 'location_type_id_organisation', - 'financial_type_id', - 'financial_type_id_recur', - 'sepa_creditor_id', - 'gender_male', - 'gender_female', - 'gender_other', - 'prefix_male', - 'prefix_female', - 'prefix_other', - 'newsletter_groups', - 'postinfo_groups', - 'donation_receipt_groups', - 'campaign', - 'campaign_targets', - 'contribution_source', - 'custom_field_mapping', - 'membership_type_id', - 'membership_type_id_recur', - 'membership_postprocess_call', - 'newsletter_double_opt_in', - 'required_address_components', + 'selector' => [ + 'label' => E::ts('Project IDs'), + 'required' => TRUE, + ], + 'xcm_profile' => ['required' => FALSE], + 'location_type_id' => [ + 'label' => E::ts('Location type'), + 'required' => TRUE, + ], + 'location_type_id_organisation' => [ + 'label' => E::ts('Location type for organisations'), + 'required' => TRUE, + ], + 'financial_type_id' => [ + 'label' => E::ts('Financial type'), + 'required' => TRUE, + ], + 'financial_type_id_recur' => [ + 'label' => E::ts('Financial type (recurring)'), + 'required' => TRUE, + ], + 'sepa_creditor_id' => [ + 'label' => E::ts('CiviSEPA creditor'), + 'required' => CRM_Twingle_Submission::civiSepaEnabled(), + ], + 'gender_male' => [ + 'label' => E::ts('Gender option for submitted value "male"'), + 'required' => TRUE, + ], + 'gender_female' => [ + 'label' => E::ts('Gender option for submitted value "female"'), + 'required' => TRUE, + ], + 'gender_other' => [ + 'label' => E::ts('Gender option for submitted value "other"'), + 'required' => TRUE, + ], + 'prefix_male' => [ + 'label' => E::ts('Prefix option for submitted value "male"'), + 'required' => TRUE, + ], + 'prefix_female' => [ + 'label' => E::ts('Prefix option for submitted value "female"'), + 'required' => TRUE, + ], + 'prefix_other' => [ + 'label' => E::ts('Prefix option for submitted value "other"'), + 'required' => TRUE, + ], + 'newsletter_groups' => ['required' => FALSE], + 'postinfo_groups' => ['required' => FALSE], + 'donation_receipt_groups' => ['required' => FALSE], + 'campaign' => ['required' => FALSE], + 'campaign_targets' => ['required' => FALSE], + 'contribution_source' => ['required' => FALSE], + 'custom_field_mapping' => ['required' => FALSE], + 'membership_type_id' => ['required' => FALSE], + 'membership_type_id_recur' => ['required' => FALSE], + 'membership_postprocess_call' => ['required' => FALSE], + 'newsletter_double_opt_in' => ['required' => FALSE], + 'required_address_components' => ['required' => FALSE], ], // Add payment methods. - array_keys(static::paymentInstruments()), + array_combine( + array_keys(static::paymentInstruments()), + array_map( + function ($value) { + return [ + 'label' => $value, + 'required' => TRUE, + ]; + }, + static::paymentInstruments() + )), // Add contribution status for all payment methods. - array_map(function ($attribute) { - return $attribute . '_status'; - }, array_keys(static::paymentInstruments())) + array_combine( + array_map(function($attribute) { + return $attribute . '_status'; + }, array_keys(static::paymentInstruments())), + array_map( + function($value) { + return [ + 'label' => $value . ' - ' . E::ts('Contribution Status'), + 'required' => TRUE, + ]; + }, + static::paymentInstruments() + )), ); + + return $asMetadata ? $attributes : array_keys($attributes); } /** From 3612122650f033252ac3c69c88878fb97c4e1dfe Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 8 Apr 2024 12:31:14 +0200 Subject: [PATCH 149/221] Update translation (seems to have caused GetText seek errors) --- l10n/de_DE/LC_MESSAGES/twingle.mo | Bin 6337 -> 6167 bytes l10n/de_DE/LC_MESSAGES/twingle.po | 7 +++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/l10n/de_DE/LC_MESSAGES/twingle.mo b/l10n/de_DE/LC_MESSAGES/twingle.mo index 831829b27dd23f27893e66bac0d000323a16189b..eff6c7e6ef72276b0d8a65e60300db9c0c5cd6fc 100644 GIT binary patch delta 932 zcmXZbUr1AN6u|NGi*3!?Tr*c0E0&bknaZw8)Fj=DOb{aWP(k<*G-5A}hL4d*^kRaH zU$Z}>hlnsCs2B-CAVocd4-u6ZjDidjBJ-{P(f8nB?DIRn-QPLqo_qJiy_)d6Z}60g z{!~X$L@xS7{8+>=-oPl{!v=hTNvsyf9QX1@kpMv%*_XT6g7;AmFQNxma4&u>es=au zkUmcE2)Ez|+=OeWNq*Zy#%Y?Y6KN-!#T~ee+TR~LW}I+|13QUsVFn-DdE>a(H?Oxd zgU#&DB1z>P@{x~xX{A-vwtw1v8`7iWEF(lSxE1H|JHAGW$^vD3jmTTn)8WwieiRQ7 zx8Ok>M!laY)T+~{LwJC#_!PCy7wkjB#SCjyQY;c|oWU4gLv42sx8ZZt(N|Fue?td< zpf((%iZ<4RaqP!N%%P6#0uJE>cHvH!06Bg>O(Bj?k6XIb8D?2BWC|-jaO^?pHL^ThT71-T3pXqw-ZNknC7I1g+A*+)DdS;51zy}%%T1Z zuHY_whovhj*4ON}<@zN% k8QR};q9dI>n=PCg$rqBbqxtOV+(@juGtuc*=0g6u|DbVnu>b%7 delta 1101 zcmY+DU279T6hLQSw@s@yNmGsZMU2I5(LZAy4q@gjdviRs@ z7{nja=TiDu-+cDTUr_xAp6lF>2&L!jox6AL+}V6>9=CF*M~9OU|Ax`>y>VjHb}%hQEDEt{Z^M&hj&wGj^#QC9Ogkf{WnIxG zH_0C}X5MFEmxF1(TenG>EFQ1;HEhG1`)vOVB9 zw_p=~gcV3CriZ~Ug_vF^G1(?&hXhVQIm!Z*Mpxl1do=koT}S*ix|Oe^#R(x$QTw?N>@BGdIrEFbXNg@^Uaa%Nz~M<}Z}*pPHJCyD9b(ssoHmXQQ5`Kt^U@iX=R+$|T?*bJfk#twpQ4`axZly5 zHSS^j%Fehi@qIgf@I9{PiktPv{j@vS?d{c{bO&jt;(lHDarJe5CEZK=-9fM4sXXtc XJG+BQtFhR)+i1CO6Y~d!{OH&pzX0{R diff --git a/l10n/de_DE/LC_MESSAGES/twingle.po b/l10n/de_DE/LC_MESSAGES/twingle.po index 921eedb..1bc928f 100644 --- a/l10n/de_DE/LC_MESSAGES/twingle.po +++ b/l10n/de_DE/LC_MESSAGES/twingle.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" #: CRM/Twingle/Form/Profile.php msgid "Delete Twingle API profile %1" @@ -307,6 +307,5 @@ msgstr "Profil %1 zurücksetzen" msgid "Delete profile %1" msgstr "Profil % 1 löschen" -#: templates/CRM/Twingle/Page/Profiles.tpl -msgid "Use Double-Opt-In for newsletter" -msgstr "Nutze Double-Opt-In für Newsletter" +#~ msgid "Use Double-Opt-In for newsletter" +#~ msgstr "Nutze Double-Opt-In für Newsletter" From 670984854f4432ac0a48fbac86cc49b0a84b9d22 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 9 Apr 2024 13:14:37 +0200 Subject: [PATCH 150/221] Fix accidentally flipped condition --- CRM/Twingle/Profile.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 523cb18..1a150af 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -259,8 +259,7 @@ class CRM_Twingle_Profile { } // Restrict profile names to alphanumeric characters, space and the underscore. - $contains_illegal_characters = (1 !== preg_match('/[^A-Za-z0-9_\s]/', $this->getName())); - if ($contains_illegal_characters) { + if (1 === preg_match('/[^A-Za-z0-9_\s]/', $this->getName())) { throw new ProfileValidationError( 'name', E::ts('Only alphanumeric characters, space and the underscore (_) are allowed for profile names.'), From 02bac833defcb2d29dbab32b18c4748abc4d7f4d Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 26 Apr 2024 16:15:19 +0200 Subject: [PATCH 151/221] fix #86 --- CRM/Twingle/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 1a150af..66c68cf 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -205,7 +205,7 @@ class CRM_Twingle_Profile { * @return mixed | NULL */ public function getAttribute($attribute_name, $default = NULL) { - return $this->data[$attribute_name] ?? $default; + return !empty($this->data[$attribute_name]) ? $this->data[$attribute_name] : $default; } /** From 48c49c181410bb06a72d53dc8e2de0cac2180d37 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 30 Apr 2024 10:21:32 +0200 Subject: [PATCH 152/221] avoid the use of empty() --- CRM/Twingle/Profile.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 66c68cf..15588b3 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -205,7 +205,9 @@ class CRM_Twingle_Profile { * @return mixed | NULL */ public function getAttribute($attribute_name, $default = NULL) { - return !empty($this->data[$attribute_name]) ? $this->data[$attribute_name] : $default; + return (isset($this->data[$attribute_name]) && $this->data[$attribute_name] !== '') + ? $this->data[$attribute_name] + : $default; } /** From 10f6ca4e897a89002edb493cc2083765b568a555 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 26 Apr 2024 18:19:16 +0200 Subject: [PATCH 153/221] add profile settings for note mapping --- CRM/Twingle/Form/Profile.php | 25 +++++++++++++++ CRM/Twingle/Profile.php | 4 +++ templates/CRM/Twingle/Form/Profile.hlp | 12 ++++++- templates/CRM/Twingle/Form/Profile.tpl | 44 ++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index af1832a..d0a1beb 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -498,6 +498,31 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { [] ); + $this->add( + 'select', + 'map_as_contribution_notes', + E::ts('Create contribution notes for'), + [ + 'purpose' => E::ts('Purpose'), + 'remarks' => E::ts('Remarks'), + ], + // is not required + FALSE, + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] + ); + + $this->add( + 'select', + 'map_as_contact_notes', + E::ts('Create contact notes for'), + [ + 'user_extrafield' => E::ts('User Extra Field'), + ], + // is not required + FALSE, + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] + ); + $this->addButtons([ [ 'type' => 'submit', diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 1a150af..0580eeb 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -527,6 +527,8 @@ class CRM_Twingle_Profile { 'membership_postprocess_call' => ['required' => FALSE], 'newsletter_double_opt_in' => ['required' => FALSE], 'required_address_components' => ['required' => FALSE], + 'map_as_contribution_notes' => ['required' => FALSE], + 'map_as_contact_notes' => ['required' => FALSE], ], // Add payment methods. array_combine( @@ -643,6 +645,8 @@ class CRM_Twingle_Profile { 'city', 'country', ], + 'map_as_contribution_notes' => [], + 'map_as_contact_notes' => [], ] // Add contribution status for all payment methods. // phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index e3841d7..b8d67a4 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -75,4 +75,14 @@
  • ContributionRecur – Will be set on the recurring contribution and deriving single contributions
  • {/ts} {/htxt} -{/crmScope} \ No newline at end of file + +{htxt id='id-map_as_contribution_notes'} + {ts domain="de.systopia.twingle"}

    Create a contribution note for each field specified in this selection.

    +

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    {/ts} +{/htxt} + +{htxt id='id-map_as_contact_notes'} + {ts domain="de.systopia.twingle"}

    Create a contact note for each field specified in this selection.

    +

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    {/ts} +{/htxt} +{/crmScope} diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index df54418..83accec 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -313,6 +313,50 @@
    + + + + + + + + + + - {if not $form.is_default} + {if not $is_default} + + + + + + + + + + @@ -338,21 +324,7 @@ From 03a37aed3126dbf27095aefaf0a5c268aa4b2cca Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 6 May 2024 15:02:29 +0200 Subject: [PATCH 173/221] add the organisation instead of the individual to donation_receipt group --- api/v3/TwingleDonation/Submit.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index bac1fd6..d307424 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -605,7 +605,8 @@ function civicrm_api3_twingle_donation_Submit($params) { } // If requested, add contact to donation_receipt groups defined in the - // profile. + // profile. If an organisation is provided, add it to the groups instead. + // (see issue #83) if ( isset($params['donation_receipt']) && is_array($groups = $profile->getAttribute('donation_receipt_groups')) @@ -613,7 +614,7 @@ function civicrm_api3_twingle_donation_Submit($params) { foreach ($groups as $group_id) { civicrm_api3('GroupContact', 'create', [ 'group_id' => $group_id, - 'contact_id' => $contact_id, + 'contact_id' => $organisation_id ?? $contact_id, ]); $result_values['donation_receipt'][] = $group_id; From ab5d0906d7a0d192039df9e5b33fb5d75df6c572 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 15:38:28 +0200 Subject: [PATCH 174/221] fix accidentally flipped condition --- CRM/Twingle/Submission.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 70540ca..258f153 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -73,7 +73,7 @@ class CRM_Twingle_Submission { // Get the payment instrument defined within the profile, or return an error // if none matches (i.e. an unknown payment method was submitted). $payment_instrument_id = $profile->getAttribute('pi_' . $params['payment_method'], ''); - if ('' !== $payment_instrument_id) { + if ('' === $payment_instrument_id) { throw new CRM_Core_Exception( E::ts('Payment method could not be matched to existing payment instrument.'), 'invalid_format' From 4432060d0586e2f9259a2867eccca1f7a1de802e Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 11 Jun 2024 13:00:12 +0200 Subject: [PATCH 175/221] add a condition to check if the value is 1 --- api/v3/TwingleDonation/Submit.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index d307424..9ebbfb6 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -533,6 +533,7 @@ function civicrm_api3_twingle_donation_Submit($params) { if ( (bool) $profile->getAttribute('newsletter_double_opt_in') && isset($params['newsletter']) + && 1 == $params['newsletter'] && is_array($groups = $profile->getAttribute('newsletter_groups')) ) { $group_memberships = array_column( @@ -573,6 +574,7 @@ function civicrm_api3_twingle_donation_Submit($params) { } elseif ( isset($params['newsletter']) + && 1 == $params['newsletter'] && is_array($groups = $profile->getAttribute('newsletter_groups')) ) { foreach ($groups as $group_id) { @@ -592,6 +594,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // If requested, add contact to postinfo groups defined in the profile. if ( isset($params['postinfo']) + && 1 == $params['postinfo'] && is_array($groups = $profile->getAttribute('postinfo_groups')) ) { foreach ($groups as $group_id) { @@ -609,6 +612,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // (see issue #83) if ( isset($params['donation_receipt']) + && 1 == $params['donation_receipt'] && is_array($groups = $profile->getAttribute('donation_receipt_groups')) ) { foreach ($groups as $group_id) { From cd008d95458f84ee077aab514161e43d687a84e3 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 12 Jun 2024 10:51:01 +0200 Subject: [PATCH 176/221] fix: Check for $creditor_id always fails --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 9ebbfb6..687f245 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -670,7 +670,7 @@ function civicrm_api3_twingle_donation_Submit($params) { } $creditor_id = $profile->getAttribute('sepa_creditor_id'); - if (!is_int($creditor_id)) { + if (!isset($creditor_id) || '' === $creditor_id) { throw new BaseException( E::ts('SEPA creditor is not configured for profile "%1".', [1 => $profile->getName()]) ); From 0cf7ccb1cba251667616a3c52e09c07f7688fbd6 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 12 Jun 2024 15:18:35 +0200 Subject: [PATCH 177/221] Code style --- CRM/Twingle/Form/Profile.php | 3 ++- CRM/Twingle/Tools.php | 5 ++++- api/v3/TwingleDonation/Submit.php | 12 ++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 2159d3b..086dc2b 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -607,7 +607,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { if (!isset($profile_data[$key]) && $required) { CRM_Core_Session::setStatus( E::ts( - 'The required configuration option "%1" has no value. Saving the profile might set this option to a possibly unwanted default value.', + 'The required configuration option "%1" has no value.' + . ' Saving the profile might set this option to a possibly unwanted default value.', [1 => $metadata['label'] ?? $key] ), E::ts('Error'), diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php index 9725a96..e2abc92 100644 --- a/CRM/Twingle/Tools.php +++ b/CRM/Twingle/Tools.php @@ -116,7 +116,10 @@ class CRM_Twingle_Tools { * Recurring contribution fields. * @throws Exception could be one of the measures */ - public static function processRecurringContributionTermination(int $recurring_contribution_id, array $recurring_contribution) { + public static function processRecurringContributionTermination( + int $recurring_contribution_id, + array $recurring_contribution + ) { // check if we're suspended if (self::$protection_suspended) { return; diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 687f245..daceb36 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -532,8 +532,7 @@ function civicrm_api3_twingle_donation_Submit($params) { : 'false'; if ( (bool) $profile->getAttribute('newsletter_double_opt_in') - && isset($params['newsletter']) - && 1 == $params['newsletter'] + && (bool) ($params['newsletter'] ?? FALSE) && is_array($groups = $profile->getAttribute('newsletter_groups')) ) { $group_memberships = array_column( @@ -573,8 +572,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // If requested, add contact to newsletter groups defined in the profile. } elseif ( - isset($params['newsletter']) - && 1 == $params['newsletter'] + (bool) ($params['newsletter'] ?? FALSE) && is_array($groups = $profile->getAttribute('newsletter_groups')) ) { foreach ($groups as $group_id) { @@ -593,8 +591,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // If requested, add contact to postinfo groups defined in the profile. if ( - isset($params['postinfo']) - && 1 == $params['postinfo'] + (bool) ($params['postinfo'] ?? FALSE) && is_array($groups = $profile->getAttribute('postinfo_groups')) ) { foreach ($groups as $group_id) { @@ -611,8 +608,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // profile. If an organisation is provided, add it to the groups instead. // (see issue #83) if ( - isset($params['donation_receipt']) - && 1 == $params['donation_receipt'] + (bool) ($params['donation_receipt'] ?? FALSE) && is_array($groups = $profile->getAttribute('donation_receipt_groups')) ) { foreach ($groups as $group_id) { From 1dbc84225315bad27a5ead53a9df27e1a7fe6f85 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 12 Jun 2024 15:20:52 +0200 Subject: [PATCH 178/221] Version 1.5-alpha1 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index d6e896f..fe9fbb5 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.5-dev - dev + 2024-06-12 + 1.5-alpha1 + alpha 5.56 From 221f9c72f3ad1d6b825ea8ac4620e7eb3a8076bf Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 12 Jun 2024 15:21:10 +0200 Subject: [PATCH 179/221] Back to 1.5-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index fe9fbb5..d0876c8 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2024-06-12 - 1.5-alpha1 - alpha + + 1.5-dev + dev 5.56 From 90f27f70c7b09163da30f3359fe037a55601debe Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 15:08:44 +0200 Subject: [PATCH 180/221] improve newsletter subcription result values --- api/v3/TwingleDonation/Submit.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index daceb36..379def0 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -526,7 +526,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // If usage of double opt-in is selected, use MailingEventSubscribe.create // to add contact to newsletter groups defined in the profile - $result_values['newsletter']['newsletter_double_opt_in'] + $result_values['newsletter_double_opt_in'] = (bool) $profile->getAttribute('newsletter_double_opt_in') ? 'true' : 'false'; @@ -555,7 +555,7 @@ function civicrm_api3_twingle_donation_Submit($params) { ] )['visibility'] == 'Public Pages'; if (!in_array($group_id, $group_memberships, FALSE) && $is_public_group) { - $result_values['newsletter'][][$group_id] = civicrm_api3( + $result = civicrm_api3( 'MailingEventSubscribe', 'create', [ @@ -564,9 +564,12 @@ function civicrm_api3_twingle_donation_Submit($params) { 'contact_id' => $contact_id, ] ); + $subscription = CRM_Utils_Array::first($result['values']); + $subscription['group_id'] = $group_id; + $result_values['newsletter_subscriptions'][] = $subscription; } elseif ($is_public_group) { - $result_values['newsletter'][] = $group_id; + $result_values['newsletter_group_ids'][] = $group_id; } } // If requested, add contact to newsletter groups defined in the profile. @@ -584,8 +587,7 @@ function civicrm_api3_twingle_donation_Submit($params) { 'contact_id' => $contact_id, ] ); - - $result_values['newsletter'][] = $group_id; + $result_values['newsletter_group_ids'][] = $group_id; } } From 67283fa1a78d3bc77103e8a2bd000662fb3162ea Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 15:53:44 +0200 Subject: [PATCH 181/221] improve donation receipt result values --- api/v3/TwingleDonation/Submit.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 379def0..5ce8e84 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -618,8 +618,7 @@ function civicrm_api3_twingle_donation_Submit($params) { 'group_id' => $group_id, 'contact_id' => $organisation_id ?? $contact_id, ]); - - $result_values['donation_receipt'][] = $group_id; + $result_values['donation_receipt_group_ids'][] = $group_id; } } From c0af2e16ab3ad10b725dafbf5024d972b7281429 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 15:54:13 +0200 Subject: [PATCH 182/221] improve SEPA mandate result values --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 5ce8e84..43cf7b8 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -725,7 +725,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // Create the mandate. $mandate = civicrm_api3('SepaMandate', 'createfull', $mandate_data); - $result_values['sepa_mandate'] = $mandate['values']; + $result_values['sepa_mandate'] = CRM_Utils_Array::first($mandate['values']); } else { // Set financial type depending on donation rhythm. This applies for From ff24256bc17fbc3c063c4623a961092f401e655b Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 15:54:49 +0200 Subject: [PATCH 183/221] improve contribution result values --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 43cf7b8..c8ef884 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -822,7 +822,7 @@ function civicrm_api3_twingle_donation_Submit($params) { } } - $result_values['contribution'] = $contribution['values']; + $result_values['contribution'] = CRM_Utils_Array::first($contribution['values']); } // MEMBERSHIP CREATION From 61f45034c6dd83cc714f36d1e8152397063874ba Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 13 Jun 2024 13:03:17 +0200 Subject: [PATCH 184/221] Update help text for custom field mapping configuration option to reflect that all parameters are supported. --- templates/CRM/Twingle/Form/Profile.hlp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index b8d67a4..a8efdc5 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -62,10 +62,10 @@ {/htxt} {htxt id='id-custom_field_mapping'} - {ts domain="de.systopia.twingle"}

    Map Twingle custom fields to CiviCRM custom fields using the following format (each assignment in a separate line):

    + {ts domain="de.systopia.twingle"}

    Map Twingle custom fields to CiviCRM fields using the following format (each assignment in a separate line):

    twingle_field_1=custom_123
    twingle_field_2=custom_789

    Always use the custom_[id] notation for CiviCRM custom fields.

    -

    This only works for fields that Twingle themselves provide in the custom_fields parameter, not for any parameters; e.g. user_extrafield always ends up in a note.

    +

    This works for fields that Twingle themselves provide in the custom_fields parameter, and for any other parameter (e.g. user_extrafield)

    Only custom fields extending one of the following CiviCRM entities are allowed:

    • Contact – Will be set on the Individual contact
    • From a8c8401be3421c3da01eb38e93ad4c5a850c47b9 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 13 Jun 2024 13:03:49 +0200 Subject: [PATCH 185/221] Update translation template --- l10n/de.systopia.twingle.pot | 1016 ++++++++++++++++++++++++++++++++++ l10n/pot/twingle.pot | 312 ----------- 2 files changed, 1016 insertions(+), 312 deletions(-) create mode 100644 l10n/de.systopia.twingle.pot delete mode 100644 l10n/pot/twingle.pot diff --git a/l10n/de.systopia.twingle.pot b/l10n/de.systopia.twingle.pot new file mode 100644 index 0000000..439b9b5 --- /dev/null +++ b/l10n/de.systopia.twingle.pot @@ -0,0 +1,1016 @@ +#: ./CRM/Twingle/Config.php +msgid "No" +msgstr "" + +#: ./CRM/Twingle/Config.php +msgid "Raise Exception" +msgstr "" + +#: ./CRM/Twingle/Config.php +msgid "Create Activity" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Profile with ID \"%1\" not found" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Delete Twingle API profile %1" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Reset" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Delete" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "The profile is invalid and cannot be copied." +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Error" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "The profile to be copied could not be found." +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "A database error has occurred. See the log for details." +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "New Twingle API profile" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Edit Twingle API profile %1" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "New Profile" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Profile name" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Project IDs" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Contact Matcher (XCM) Profile" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Location type" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Location type for organisations" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Financial type" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Financial type (recurring)" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +msgid "Gender option for submitted value \"male\"" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +msgid "Gender option for submitted value \"female\"" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +msgid "Gender option for submitted value \"other\"" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +msgid "Prefix option for submitted value \"male\"" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +msgid "Prefix option for submitted value \"female\"" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +msgid "Prefix option for submitted value \"other\"" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Record %1 as" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Record %1 donations with contribution status" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +msgid "CiviSEPA creditor" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Use Double-Opt-In for newsletter" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Sign up for newsletter groups" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Sign up for postal mail groups" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Sign up for Donation receipt groups" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Default Campaign" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "- none -" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Set Campaign for" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Contribution" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Recurring Contribution" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Membership" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "SEPA Mandate" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Contacts (XCM)" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Create membership of type" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Create membership of type (recurring)" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "API Call for Membership Postprocessing" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "The API call must have the form 'Entity.Action'." +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Contribution source" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Required address components" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Street" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Postal Code" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "City" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "Country" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Custom field mapping" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Create contribution notes for" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "Purpose" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "Remarks" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Create contact notes for" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "User Extra Field" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Form/Settings.php +msgid "Save" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Warning" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "No profile set." +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "<select profile>" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "none" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "CiviSEPA" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "No mailing lists available" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Twingle ID Prefix" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Use CiviSEPA" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Use CiviSEPA generated reference" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Protect Recurring Contributions" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Activity Type" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Subject" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Status" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "Assigned To" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "This is required for activity creation" +msgstr "" + +#: ./CRM/Twingle/Form/Settings.php +msgid "-select-" +msgstr "" + +#: ./CRM/Twingle/Page/Profiles.php ./managed/Navigation__twingle_configuration.mgd.php +msgid "Twingle API Profiles" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Unknown attribute %1." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Profile name cannot be empty." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Only alphanumeric characters, space and the underscore (_) are allowed for profile names." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "A profile with the name '%1' already exists." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Project ID(s) [%1] already used in profile '%2'." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Could not parse custom field mapping." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Custom field custom_%1 does not exist." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities." +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Could not save/update profile: %1" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Could not reset default profile: %1" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Could not delete profile: %1" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Contribution Status" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Bank transfer" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Debit manual" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Debit automatic" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Credit card" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Mobile phone Germany" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "PayPal" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "SOFORT Überweisung" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Amazon Pay" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Apple Pay" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Google Pay" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Paydirekt" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Twint" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "iDEAL" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Postfinance" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Bancontact" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "Generic Payment Method" +msgstr "" + +#: ./CRM/Twingle/Profile.php +msgid "never" +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Invalid donation rhythm." +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Payment method could not be matched to existing payment instrument." +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Invalid date for parameter \"confirmed_at\"." +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Invalid date for parameter \"user_birthdate\"." +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Gender could not be matched to existing gender." +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Invalid format for custom fields." +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "campaign_id must be a numeric string. " +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Unknown country %1." +msgstr "" + +#: ./CRM/Twingle/Submission.php +msgid "Could not calculate SEPA cycle day from configuration." +msgstr "" + +#: ./CRM/Twingle/Tools.php +msgid "This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected." +msgstr "" + +#: ./CRM/Twingle/Tools.php +msgid "Recurring contribution [%1] (Transaction ID '%2') was terminated by a user. You need to end the corresponding record in Twingle as well, or it will still be collected." +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +msgid "Project ID" +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +msgid "The Twingle project ID." +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +msgid "Transaction ID" +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +msgid "The unique transaction ID of the donation" +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php +msgid "Cancelled at" +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php +msgid "The date when the donation was cancelled, format: YmdHis." +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php +msgid "Cancel reason" +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php +msgid "The reason for the donation being cancelled." +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php +msgid "Invalid date for parameter \"cancelled_at\"." +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php +msgid "SEPA Mandate for contribution [%1 not found." +msgstr "" + +#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php +msgid "Could not terminate SEPA mandate" +msgstr "" + +#: ./api/v3/TwingleDonation/Endrecurring.php +msgid "Ended at" +msgstr "" + +#: ./api/v3/TwingleDonation/Endrecurring.php +msgid "The date when the recurring donation was ended, format: YmdHis." +msgstr "" + +#: ./api/v3/TwingleDonation/Endrecurring.php +msgid "Invalid date for parameter \"ended_at\"." +msgstr "" + +#: ./api/v3/TwingleDonation/Endrecurring.php +msgid "SEPA Mandate for recurring contribution [%1 not found." +msgstr "" + +#: ./api/v3/TwingleDonation/Endrecurring.php +msgid "SEPA Mandate [%1] already terminated." +msgstr "" + +#: ./api/v3/TwingleDonation/Endrecurring.php +msgid "Mandate closed by TwingleDonation.Endrecurring API call" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Confirmed at" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The date when the donation was issued, format: YmdHis." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The purpose of the donation." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Amount" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The donation amount in minor currency unit." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Currency" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The ISO-4217 currency code of the donation." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Newsletter" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Whether to subscribe the contact to the newsletter group defined in the profile." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Postal mailing" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Whether to subscribe the contact to the postal mailing group defined in the profile." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Donation receipt" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Whether the contact requested a donation receipt." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Payment method" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The Twingle payment method used for the donation." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Donation rhythm" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The interval which the donation is recurring in." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "SEPA IBAN" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The IBAN for SEPA Direct Debit payments, conforming with ISO 13616-1:2007." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "SEPA BIC" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The BIC for SEPA Direct Debit payments, conforming with ISO 9362." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "SEPA Direct Debit Mandate reference" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The mandate reference for SEPA Direct Debit payments." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "SEPA Direct Debit Account holder" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The account holder for SEPA Direct Debit payments." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Anonymous donation" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Whether the donation is submitted anonymously." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Gender" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The gender of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Date of birth" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The date of birth of the contact, format: Ymd." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Formal title" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The formal title of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Email address" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The e-mail address of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "First name" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The first name of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Last name" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The last name of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Street address" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The street address of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Postal code" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The postal code of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The city of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The country of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Telephone" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The telephone number of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Company" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The company of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Language" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The preferred language of the contact. A 2-digit ISO-639-1 language code." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "User extra field" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Additional information of the contact." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Campaign ID" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "The CiviCRM ID of a campaign to assign the contribution." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Custom fields" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Additional information for either the contact or the (recurring) contribution." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Additional remarks for the donation." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Contribution with the given transaction ID already exists." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Organisation contact could not be found or created." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Individual contact could not be found or created." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Missing attribute %1 for SEPA mandate" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "SEPA creditor is not configured for profile \"%1\"." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Could not create recurring contribution." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Could not find recurring contribution with given parent transaction ID." +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Could not create contribution" +msgstr "" + +#: ./api/v3/TwingleDonation/Submit.php +msgid "Twingle membership postprocessing call has failed, see log for more information" +msgstr "" + +#: ./managed/Navigation__twingle_configuration.mgd.php +msgid "Twingle API Configuration" +msgstr "" + +#: ./managed/Navigation__twingle_configuration.mgd.php +msgid "Twingle API Settings" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Select which location type to use for addresses for individuals, either when no organisation name is specified, or an organisation address can not be shared with the individual contact." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Put your project's Twingle ID in here, to activate this profile for that project." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "You can also provide multiple project IDs separated by a comma." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "The Contact Matcher (XCM) manages the identification or creation of the related contact." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "We recommend creating a new XCM profile only to be used with the Twingle API." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Select which location type to use for addresses for organisations and shared organisation addresses for individual contacts." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Select which financial type to use for one-time contributions." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Select which financial type to use for recurring contributions." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Select whether to use CiviCRM's Double-Opt-In feature for subscribing to mailing lists. Note that this only works for public mailing lists. Any non-public mailing list selected above will be ignored when this setting is enabled." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Also, do not forget to disable Twingle's own Double Opt-In option in the Twingle Manager to avoid subscribers receiving multiple confirmation e-mails. Only one or the other option should be enabled." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Some organisations have specific conventions on how a membership should be created. Since the Twingle-API can only create a \"bare bone\" membership object, you can enter a API Call (as 'Entity.Action') to adjust any newly created membership to your organisation's needs." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "The API call would receive the following parameters:
        \n
      • membership_id: The ID of the newly created membership
      • \n
      • contact_id: The ID of the contact involved
      • \n
      • organization_id: The ID of the contact's organisation, potentially empty
      • \n
      • contribution_id: The ID contribution received, potentially empty
      • \n
      • recurring_contribution_id: The ID of the recurring contribution. If empty, this was only a one-off donation.
      • \n
      " +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Select the address components that must be present to create or update an address for the contact." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Depending on your XCM settings, the transferred address might replace an existing one." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "Since in some cases Twingle send the country of the user as the only address parameter, depending on your XCM configuration, not declaring other address components as required might lead to the current user address being overwritten with an address containing the country only." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "

      Map Twingle custom fields to CiviCRM fields using the following format (each assignment in a separate line):

      \n
      twingle_field_1=custom_123
      twingle_field_2=custom_789
      \n

      Always use the custom_[id] notation for CiviCRM custom fields.

      \n

      This works for fields that Twingle themselves provide in the custom_fields parameter, and for any other parameter (e.g. user_extrafield)

      \n

      Only custom fields extending one of the following CiviCRM entities are allowed:

      \n
        \n
      • Contact – Will be set on the Individual contact
      • \n
      • Individual – Will be set on the Individual contact
      • \n
      • Organization – Will be set on the Organization contact, if an organisation name was submitted
      • \n
      • Contribution – Will be set on the contribution
      • \n
      • ContributionRecur – Will be set on the recurring contribution and deriving single contributions
      • \n
      " +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "

      Create a contribution note for each field specified in this selection.

      \n

      Tip: You can enable or disable this fields in the TwingleMANAGER.

      " +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "

      Create a contact note for each field specified in this selection.

      \n

      Tip: You can enable or disable this fields in the TwingleMANAGER.

      " +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "General settings" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Help" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "XCM Profile" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Gender/Prefix for value 'male'" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Gender/Prefix for value 'female'" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Gender/Prefix for value 'other'" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Payment methods" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Groups and Correlations" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Newsletter Double Opt-In" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Membership Postprocessing" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Are you sure you want to reset the default profile?" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Are you sure you want to delete the profile %1?" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Profile name not given or invalid." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Settings.hlp +msgid "When the %1 is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the debit_manual payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Settings.hlp +msgid "When the %1 is enabled, you can activate this to use your own references instead of the ones submitted by Twingle." +msgstr "" + +#: ./templates/CRM/Twingle/Form/Settings.hlp +msgid "Will protect all recurring contributions created by Twingle from termination, since this does NOT terminate the Twingle collection process" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Settings.hlp +msgid "You can use this setting to add a prefix to the Twingle transaction ID, in order to avoid collisions with other transaction ids." +msgstr "" + +#: ./templates/CRM/Twingle/Page/Configuration.tpl +msgid "Profiles" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Configuration.tpl +msgid "Configure profiles" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Configuration.tpl +msgid "Settings" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Configuration.tpl +msgid "Configure extension settings" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "New profile" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Selectors" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Used" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Last Used" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Operations" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Edit profile %1" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Edit" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Copy profile %1" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Copy" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Reset profile %1" +msgstr "" + +#: ./templates/CRM/Twingle/Page/Profiles.tpl +msgid "Delete profile %1" +msgstr "" + +#: ./twingle.php +msgid "Twingle API: Access Twingle API" +msgstr "" + +#: ./twingle.php +msgid "Allows access to the Twingle API actions." +msgstr "" + diff --git a/l10n/pot/twingle.pot b/l10n/pot/twingle.pot deleted file mode 100644 index 7de3f72..0000000 --- a/l10n/pot/twingle.pot +++ /dev/null @@ -1,312 +0,0 @@ -#: ./CRM/Twingle/Form/Profile.php -msgid "Delete Twingle API profile %1" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Reset" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Delete" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Edit Twingle API profile %1" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "New Twingle API profile" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Profile name" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Project IDs" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Location type" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Financial Type" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Gender option for submitted value \"male\"" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Gender option for submitted value \"female\"" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Gender option for submitted value \"other\"" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Record %1 as" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "CiviSEPA creditor" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Sign up for newsletter groups" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Sign up for postal mail groups" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Sign up for Donation receipt groups" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Form/Settings.php -msgid "Save" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Only alphanumeric characters and the underscore (_) are allowed for profile names." -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Create contribution notes for" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php -msgid "Purpose" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php -msgid "Remarks" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "Create contact notes for" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "User Extra Field" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "CiviSEPA" -msgstr "" - -#: ./CRM/Twingle/Form/Profile.php -msgid "No mailing lists available" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Unknown attribute %1." -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Bank transfer" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Debit manual" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Debit automatic" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Credit card" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Mobile phone Germany" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "PayPal" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "SOFORT Überweisung" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Amazon Pay" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "paydirekt" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Apple Pay" -msgstr "" - -#: ./CRM/Twingle/Profile.php -msgid "Google Pay" -msgstr "" - -#: ./CRM/Twingle/Submission.php -msgid "Invalid donation rhythm." -msgstr "" - -#: ./CRM/Twingle/Submission.php -msgid "Payment method could not be matched to existing payment instrument." -msgstr "" - -#: ./CRM/Twingle/Submission.php -msgid "Invalid date for parameter \"confirmed_at\"." -msgstr "" - -#: ./CRM/Twingle/Submission.php -msgid "Invalid date for parameter \"user_birthdate\"." -msgstr "" - -#: ./CRM/Twingle/Submission.php -msgid "Gender could not be matched to existing gender." -msgstr "" - -#: ./CRM/Twingle/Submission.php -msgid "Unknown country %1." -msgstr "" - -#: ./api/v3/TwingleDonation/Cancel.php -msgid "Invalid date for parameter \"cancelled_at\"." -msgstr "" - -#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php -msgid "Could not terminate SEPA mandate" -msgstr "" - -#: ./api/v3/TwingleDonation/Endrecurring.php -msgid "Invalid date for parameter \"ended_at\"." -msgstr "" - -#: ./api/v3/TwingleDonation/Endrecurring.php -msgid "Mandate closed by TwingleDonation.Endrecurring API call" -msgstr "" - -#: ./api/v3/TwingleDonation/Submit.php -msgid "Contribution with the given transaction ID already exists." -msgstr "" - -#: ./api/v3/TwingleDonation/Submit.php -msgid "Individual contact could not be found or created." -msgstr "" - -#: ./api/v3/TwingleDonation/Submit.php -msgid "Organisation contact could not be found or created." -msgstr "" - -#: ./api/v3/TwingleDonation/Submit.php -msgid "Missing attribute %1 for SEPA mandate" -msgstr "" - -#: ./api/v3/TwingleDonation/Submit.php -msgid "Could not create recurring contribution." -msgstr "" - -#: ./api/v3/TwingleDonation/Submit.php -msgid "Could not create contribution" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "General settings" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "Payment methods" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "Groups" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "Create contribution note for" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "Create contact note for" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.hlp -msgid "

      Create a contribution note for each field specified in this selection.

      \n

      Tip: You can enable or disable this fields in the TwingleMANAGER.

      " -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.hlp -msgid "

      Create a contact note for each field specified in this selection.

      \n

      Tip: You can enable or disable this fields in the TwingleMANAGER.

      " -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "Are you sure you want to reset the default profile?" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "Are you sure you want to delete the profile %1?" -msgstr "" - -#: ./templates/CRM/Twingle/Form/Profile.tpl -msgid "Profile name not given or invalid." -msgstr "" - -#: ./templates/CRM/Twingle/Form/Settings.hlp -msgid "When the %1 is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the debit_manual payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data." -msgstr "" - -#: ./templates/CRM/Twingle/Form/Settings.tpl -msgid "Help" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Configuration.tpl -msgid "Profiles" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Configuration.tpl -msgid "Configure profiles" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Configuration.tpl -msgid "Settings" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Configuration.tpl -msgid "Configure extension settings" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "New profile" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Properties" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Operations" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Selector" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Edit profile %1" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Edit" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Reset profile %1" -msgstr "" - -#: ./templates/CRM/Twingle/Page/Profiles.tpl -msgid "Delete profile %1" -msgstr "" - From f7b15ac4f69864a5b68998c0431de9772db4f4ef Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 13 Jun 2024 13:03:57 +0200 Subject: [PATCH 186/221] Update German translation --- l10n/de_DE/LC_MESSAGES/twingle.mo | Bin 7350 -> 29888 bytes l10n/de_DE/LC_MESSAGES/twingle.po | 1029 +++++++++++++++++++++++++++-- 2 files changed, 974 insertions(+), 55 deletions(-) diff --git a/l10n/de_DE/LC_MESSAGES/twingle.mo b/l10n/de_DE/LC_MESSAGES/twingle.mo index 9fd805479ba6759289b95892b87803fec1e57720..78498f0172762c1ca981c4a566147748306906b4 100644 GIT binary patch literal 29888 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 z zjISICdjg&MEc7BmlTSv^1a-<)n5tq!t8%RXD38%XthrLSwBkhF`Fj6$f~8n8O~=2U zpk$wA+NBlRm_L_XCt5U5YAl}6{;?cljv27Tm0`e%hE7@yvy1oiF>F3(#+yJ3OpUb< zYrN8O8GG}JlvpvM=5r#vBeQB6$hq61>rArHRg+4;Lb4*0L=K=BL-0uF!V3-JVmVvk zWlB+VC5sW67S;<6lbzYRPK1cD_T$xTm?0A+qy_|rgD!`W6=s)yZd+WI`Ay{ocRzo< zVQEcQp;ff&8gMMJL~BU?gW|B$X2KFt@w7Rh@+fqou zm;ksM(8W>;tPiiM{Sqv{8&Rvi8xf*miv!tpvlV7xSec(4A7YdknlGt%!iBo%6u0eF zimUaTOiu_<#7%EY*lJbi>AU27&D4XY3KgFF9R}Ysc|}VD7U8>(H?W>gkDKXqo=e!f zP;PIGg@hj?(@JX2XB4Fy*yUxH<`H%&*a z8aHZ-r8X?R=mzB*@#>P~qor20ZD_=D`;!wz&==c#8P->sVAZvn5kI++vqrHkEc-$^ zNx79sz0#8_$>4I2yPT|%7I!KLNAL#SNW#tx?_7k`HV<@SS@UJKIr3zZ+v7kWBsh}9 zvKyJzeW>dsUP@TG=FnGZYem!!S+aPJuz4vFj%60*&S9;h5cV3>_VNSs+5FJ~ac)nq zzRZzql{@A02H0v@IHQ*~B+Q#b3`|{$x_qw&>{;y!OOU{%h8y<*tK{ELQS55C8oTVDdAvzIATYtP&NiWE?9lHx^KFq{;W%^!n?tt?_~FcfPW zazR{|6$#2n!owUGhudSeVVj9DS3@R_1`t50g`5@$GZSgyAj2@Nvk?iA*%Ehn^RL}T zNXT1wv!$OGW>7y8?2^)yYOAL3SaL+8)^{nquyHWpcr`8-yBDiRp33yz22MKMwx|Ho z`*RE0fzTtU@nREetqADe;vlIuhSrAOyvL!1$P{ev1;XUbjr2xi?Bt0&FMa83%WRN!yXm?H3W<=M$8Ky?hpq*E0kS2 zdKc=%?dYZNedO)QqiTm{%uRHOF9uuT*;CanF@ zxIqq%hI)N>mUkQEP?Vii4a;^pH;miXzO;)LQKe4VP?pHZ&xEb{4nyUs_5S3Oe?Md= zbzK5d5>eWeHJasQsyt=yc~l=Hhz(A}LwnGY^R_2o&#kzsmKi{qjd&~Clu(Rmn>Qh^ zF7kT5D?gz_7%|6?Voo4U4Ex>M4n%dGi9mJJph7aoCchD|%pI*h+o`dgfzb-a3{0`@ z6)baeQsbA8B`={~ zaF@Gii|N+l9okd$X&djF$T{WQwGQYVEzhEn$u>lC}relh0qxi6Qz8aZ<{W<%23DpQGMegNyk zo&Z@XZJQJ~EC$k#;UG+IlseIMJ};rgU3h-+e*d3rlxptL!Px3iD5n>S_)TZ2T)rX- z@>9d)_v?0cHY%Uu%1C0kY~Zy1^XIkN7h<22y6!!fb@rkQi#wXod3O#=@*?kaSNRtG zCkQNZ+se=mvtPy};*|Q7hD?*i+b#EDc?%zi=I3MrL*Td+f)6(=O`!N*tAMj~-$ie8a;QUSc3kiyvgu_bosD@^Yo;mRU zf>^-o>E8%{qjldO5{zYa)N^m9Wrdx_x_1vM?TeRn!(~I z7uE4U%G9+R#KR(Tek#emGE?c%XN5=lkul{-9cFgNEsFytaUuFXIe`Rnma}88WmR%^ zqoaSYR(;OH<=foRl9k&%;Px3fmY_tQ)TS4MAlTw))fkk54DMl;S&Imgc~7R*#ZYfW zl_){bFx;sBG;cd(@b&IYIMT*K4FS95>BGrJCxln&{g^>r*(Wj^GPsa4Y@{p`_bTQO z%{c*+yvsL0DHLkS!h8v~*UJ@^J7P05RmJkwikHu;h)wLp7UrqIhjfu0ry6;btdT$1 oY05>)V&p{|ACS2hZM3v?<{#+H>Hl7HyIT2cH|#jureGHRAE|+|)c^nh delta 2578 zcmYk+Sxi({7{Kv^ORdP_zLn*=0HT13)&&I_6kI?Da5viKG92JC!=3ToJ0diezBKVg zTXQsxiD_b&n5Ooj(zv9ynrLFuHZ_e8ed^|e-Pg3yHrDq44FmCnGrx1MbI$$l_kH8_ z?=vp09{6(dm{W=oX67+Zj#4U$S!4NNTz*2SGk68h;;wN@W#R)IkE5SdY87VVGHk$X z>_`68Q9dT&36%3+$H{mdtCSj0cUa_eBZt!#U>RDt6KCKdoQcO#4mgMM{hK%e?_w_g zf?44%WC7yHWO^NqY+=kUy{tXAz~mPy=T3eDy4gmDqzt_$E%pk5Mx4HL_Pdz}Yy4 z{I+5tN+2Fe>W`oV^e(Q)%P5(7h-_6^yyaY+g(O|A#Q{0Eo`oFLf|OP5N7>MxzCMW3 z4t*#Y7{Dp`GRm93fpXwmX)oYBuHQ!~)mK=6|Kc>vBP!WnDfyQJ8@O>FcO&IfVQ#L; zP--t;;rbK>yejwU90@dw-SWK|xB};(G~phU^G=`y^cqU--$p6r2PgsD!y0@zh5Sox z){yTd*oGDwlxBMmCGyX(5P!otIFVB%bCoz9Yf!p+C(47numlex&r+vR0)Gdkmo6hm zsk;L#D37|2jX0LmmSGD@GrfqFcnPIxen2^BG>svp%0Vg3bXnNqj zrDG*i7D@@qPy*jMbbmk{U?CZBP~M~$C9)$!Ur@)=|9%)1eXHX72&n_-UhNN45HnMp!Q_3U{2s4L= z^oG2x^uU(%O`f013>8adPRhE0DGe#3h`EO6r$z&x(veatiF$afWkGACN+4-l&D_kC zQW0-zNLq)7qGV)R13|3@O!CrZhLBUM=TS{u7ZQb)BDD(cu_M zuNR^8hIF5p1jq{radX|)-dp&q+G?pn=upXts&yr9l@qgLSAuHT_Owca`8Y_D$) zjV!E)r`w$%?wOqh%guv=D)W3{*t}}ZobG8m&{ibw26iN{+&C89Re7)t+x&DS5#xSSkn^N$c&$D->>gZjn^z#??0M^=ijY zx}77n8CjG!4i{-dQ?2>CX`Q*fwb)$SS}|I?6{a{mH?L936b;I^#RI3`A_0Mp#k6a6 z+_>r)JG{gk3|CeUof5UZK&w!?UVfxYTcNhLWTZ=GY!PGnL`;ZFY|~pYL6=Mi14D*OHpmJDu7k61yYNuG-hD zBT+@QwAW$#KCf!Wd=+wOgeWnYj{OVGPY3eHZPziX5I0BdL*_rXVoIHMlR>}s%2QP< RZ=h&{O^HbvnIjcb{{tNlxQ74$ diff --git a/l10n/de_DE/LC_MESSAGES/twingle.po b/l10n/de_DE/LC_MESSAGES/twingle.po index 0e8d890..4907d37 100644 --- a/l10n/de_DE/LC_MESSAGES/twingle.po +++ b/l10n/de_DE/LC_MESSAGES/twingle.po @@ -16,6 +16,22 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.0.1\n" +#: CRM/Twingle/Config.php +msgid "No" +msgstr "Nein" + +#: CRM/Twingle/Config.php +msgid "Raise Exception" +msgstr "Ausnahme auslösen" + +#: CRM/Twingle/Config.php +msgid "Create Activity" +msgstr "Aktivität erstellen" + +#: CRM/Twingle/Form/Profile.php +msgid "Profile with ID \"%1\" not found" +msgstr "Profil mit ID \"%1\" nicht gefunden" + #: CRM/Twingle/Form/Profile.php msgid "Delete Twingle API profile %1" msgstr "Twingle-API-Profil %1 löschen" @@ -29,49 +45,107 @@ msgid "Delete" msgstr "Löschen" #: CRM/Twingle/Form/Profile.php -msgid "Edit Twingle API profile %1" -msgstr "Twingle-API-Profil %1 bearbeiten" +msgid "The profile is invalid and cannot be copied." +msgstr "Das Profil ist ungültig und kann nicht kopiert werden." + +#: CRM/Twingle/Form/Profile.php +msgid "Error" +msgstr "Fehler" + +#: CRM/Twingle/Form/Profile.php +msgid "The profile to be copied could not be found." +msgstr "Das zu kopierende Profil konnte nicht gefunden werden." + +#: CRM/Twingle/Form/Profile.php +msgid "A database error has occurred. See the log for details." +msgstr "" +"Ein Datenbankfehler ist aufgetreten. Siehe das Protokoll für Einzeilheiten." #: CRM/Twingle/Form/Profile.php msgid "New Twingle API profile" msgstr "Neues Twingle-API-Profil" +#: CRM/Twingle/Form/Profile.php +msgid "Edit Twingle API profile %1" +msgstr "Twingle-API-Profil %1 bearbeiten" + +#: CRM/Twingle/Form/Profile.php +msgid "New Profile" +msgstr "Neues Profil" + #: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Page/Profiles.tpl msgid "Profile name" msgstr "Profil-Name" -#: CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Project IDs" msgstr "Projekt-IDs" #: CRM/Twingle/Form/Profile.php +msgid "Contact Matcher (XCM) Profile" +msgstr "Extended Contact Matcher (XCM)-Profil" + +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Location type" msgstr "Adresskategorie" -#: CRM/Twingle/Form/Profile.php -msgid "Financial Type" +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "Location type for organisations" +msgstr "Adresskategorie für Organisationen" + +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "Financial type" msgstr "Zuwendungsart" -#: CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "Financial type (recurring)" +msgstr "Zuwendungsart (wiederkehrend)" + +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Gender option for submitted value \"male\"" msgstr "Geschlechtsoption für übermittelten Wert \"male\"" -#: CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Gender option for submitted value \"female\"" msgstr "Geschlechtsoption für übermittelten Wert \"female\"" -#: CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Gender option for submitted value \"other\"" msgstr "Geschlechtsoption für übermittelten Wert \"other\"" +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +msgid "Prefix option for submitted value \"male\"" +msgstr "Anredeoption für übermittelten Wert \"male\"" + +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +msgid "Prefix option for submitted value \"female\"" +msgstr "Anredeoption für übermittelten Wert \"female\"" + +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php +msgid "Prefix option for submitted value \"other\"" +msgstr "Anredeoption für übermittelten Wert \"other\"" + #: CRM/Twingle/Form/Profile.php msgid "Record %1 as" msgstr "%1 erfassen als" #: CRM/Twingle/Form/Profile.php +msgid "Record %1 donations with contribution status" +msgstr "%1 erfassen mit Zuwendungsstatus" + +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "CiviSEPA creditor" msgstr "CiviSEPA-Kreditor" +#: CRM/Twingle/Form/Profile.php +msgid "Use Double-Opt-In for newsletter" +msgstr "Nutze Double-Opt-In für Newsletter" + #: CRM/Twingle/Form/Profile.php msgid "Sign up for newsletter groups" msgstr "Newsletter-Gruppen beitreten" @@ -84,27 +158,91 @@ msgstr "Postversand-Gruppen beitreten" msgid "Sign up for Donation receipt groups" msgstr "Zuwendungsbescheinigungs-Gruppen beitreten" -#: CRM/Twingle/Form/Profile.php CRM/Twingle/Form/Settings.php -msgid "Save" -msgstr "Speichern" +#: CRM/Twingle/Form/Profile.php +msgid "Default Campaign" +msgstr "Standardkampagne" #: CRM/Twingle/Form/Profile.php -msgid "" -"Only alphanumeric characters and the underscore (_) are allowed for profile " -"names." -msgstr "" -"Nur alphanumerische Zeichen und der Unterstrich (_) sind für Profilnamen " -"erlaubt." +msgid "- none -" +msgstr "- keine -" + +#: CRM/Twingle/Form/Profile.php +msgid "Set Campaign for" +msgstr "Kampagne setzen für" + +#: CRM/Twingle/Form/Profile.php +msgid "Contribution" +msgstr "Zuwendung" + +#: CRM/Twingle/Form/Profile.php +msgid "Recurring Contribution" +msgstr "Wiederkehrende Zuwendung" + +#: CRM/Twingle/Form/Profile.php +msgid "Membership" +msgstr "Mitgliedschaft" + +#: CRM/Twingle/Form/Profile.php +msgid "SEPA Mandate" +msgstr "SEPA-Lastschriftmandat" + +#: CRM/Twingle/Form/Profile.php +msgid "Contacts (XCM)" +msgstr "Kontakte (XCM)" + +#: CRM/Twingle/Form/Profile.php +msgid "Create membership of type" +msgstr "Mitgliedschaft mit Typ erstellen" + +#: CRM/Twingle/Form/Profile.php +msgid "Create membership of type (recurring)" +msgstr "Mitgliedschaft mit Typ erstellen (wiederkehrend)" + +#: CRM/Twingle/Form/Profile.php +msgid "API Call for Membership Postprocessing" +msgstr "API-Aufruf für Mitgliedschafts-Nachbearbeitung" + +#: CRM/Twingle/Form/Profile.php +msgid "The API call must have the form 'Entity.Action'." +msgstr "Der API-Aufruf muss in der Form 'Entität.Aktion' angegeben werden." + +#: CRM/Twingle/Form/Profile.php +msgid "Contribution source" +msgstr "Herkunft der Zuwendung" + +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl +msgid "Required address components" +msgstr "Erforderliche Adresskomponenten" + +#: CRM/Twingle/Form/Profile.php +msgid "Street" +msgstr "Straße" + +#: CRM/Twingle/Form/Profile.php +msgid "Postal Code" +msgstr "Postleitzahl" + +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php +msgid "City" +msgstr "Ort" + +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php +msgid "Country" +msgstr "Land" + +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl +msgid "Custom field mapping" +msgstr "Zuordnung benutzerdefinierter Felder" #: CRM/Twingle/Form/Profile.php msgid "Create contribution notes for" msgstr "Zuwendungs-Notizen erstellen für" -#: CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php msgid "Purpose" msgstr "Zweck" -#: CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php msgid "Remarks" msgstr "Anmerkungen" @@ -116,6 +254,26 @@ msgstr "Kontakt-Notizen erstellen für" msgid "User Extra Field" msgstr "Benutzer-Extra-Feld" +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Form/Settings.php +msgid "Save" +msgstr "Speichern" + +#: CRM/Twingle/Form/Profile.php +msgid "Warning" +msgstr "Warnung" + +#: CRM/Twingle/Form/Profile.php +msgid "No profile set." +msgstr "Kein Profil eingestellt." + +#: CRM/Twingle/Form/Profile.php +msgid "<select profile>" +msgstr "<Profil auswählen>" + +#: CRM/Twingle/Form/Profile.php +msgid "none" +msgstr "keines" + #: CRM/Twingle/Form/Profile.php msgid "CiviSEPA" msgstr "CiviSEPA" @@ -124,17 +282,114 @@ msgstr "CiviSEPA" msgid "No mailing lists available" msgstr "Keine Versandlisten verfügbar" +#: CRM/Twingle/Form/Settings.php +msgid "Twingle ID Prefix" +msgstr "Twingle-ID-Präfix" + +#: CRM/Twingle/Form/Settings.php +msgid "Use CiviSEPA" +msgstr "CiviSEPA verwenden" + +#: CRM/Twingle/Form/Settings.php +msgid "Use CiviSEPA generated reference" +msgstr "Von CiviSEPA erstellte Referenc verwenden" + +#: CRM/Twingle/Form/Settings.php +msgid "Protect Recurring Contributions" +msgstr "Wiederkehrende Zuwendungen schützen" + +#: CRM/Twingle/Form/Settings.php +msgid "Activity Type" +msgstr "Aktivitätstyp" + +#: CRM/Twingle/Form/Settings.php +msgid "Subject" +msgstr "Betreff" + +#: CRM/Twingle/Form/Settings.php +msgid "Status" +msgstr "Status" + +#: CRM/Twingle/Form/Settings.php +msgid "Assigned To" +msgstr "Zugewiesen an" + +#: CRM/Twingle/Form/Settings.php +msgid "This is required for activity creation" +msgstr "Diese Angaben sind erforderlich für das Erstellen von Aktivitäten" + +#: CRM/Twingle/Form/Settings.php +msgid "-select-" +msgstr "- auswählen -" + +#: CRM/Twingle/Page/Profiles.php +#: managed/Navigation__twingle_configuration.mgd.php +msgid "Twingle API Profiles" +msgstr "Twingle-API-Profile" + #: CRM/Twingle/Profile.php msgid "Unknown attribute %1." msgstr "Unbekanntes Attribut %1." +#: CRM/Twingle/Profile.php +msgid "Profile name cannot be empty." +msgstr "Profilname darf nicht leer sein." + +#: CRM/Twingle/Profile.php +msgid "" +"Only alphanumeric characters, space and the underscore (_) are allowed for " +"profile names." +msgstr "" +"Nur alphanumerische Zeichen und der Unterstrich (_) sind für Profilnamen " +"erlaubt." + +#: CRM/Twingle/Profile.php +msgid "A profile with the name '%1' already exists." +msgstr "Ein profil mit dem Namen '%1' existiert bereits." + +#: CRM/Twingle/Profile.php +msgid "Project ID(s) [%1] already used in profile '%2'." +msgstr "Projekt-ID(s) [%1] werden ebreits in Profil '%2' verwendet." + +#: CRM/Twingle/Profile.php +msgid "Could not parse custom field mapping." +msgstr "Zuordnung benutzerdefinierter Felder konnte nicht verarbeitet werden." + +#: CRM/Twingle/Profile.php +msgid "Custom field custom_%1 does not exist." +msgstr "Benutezrdefiniertes Feld custom_%1 existiert nicht." + +#: CRM/Twingle/Profile.php +msgid "" +"Custom field custom_%1 is not in a CustomGroup that extends one of the " +"supported CiviCRM entities." +msgstr "" +"Benutzerdefiniertes Feld custom_%1 ist in einer benutzerdefinierten " +"Feldgruppe, die eine nicht unterstützte Entität erweitert." + +#: CRM/Twingle/Profile.php +msgid "Could not save/update profile: %1" +msgstr "Speichern/Aktualisieren von Profil fehlgeschlagen: %1" + +#: CRM/Twingle/Profile.php +msgid "Could not reset default profile: %1" +msgstr "Zurücksetzen des Standardprofils fehlgeschlagen: %1" + +#: CRM/Twingle/Profile.php +msgid "Could not delete profile: %1" +msgstr "Löschen des Profils fehlgeschlagen: %1" + +#: CRM/Twingle/Profile.php +msgid "Contribution Status" +msgstr "Zuwendungsstatus" + #: CRM/Twingle/Profile.php msgid "Bank transfer" msgstr "Banküberweisung" #: CRM/Twingle/Profile.php msgid "Debit manual" -msgstr "manuelle Abbuchung" +msgstr "Manuelle Abbuchung" #: CRM/Twingle/Profile.php msgid "Debit automatic" @@ -160,10 +415,6 @@ msgstr "SOFORT-Überweisung" msgid "Amazon Pay" msgstr "Amazon Pay" -#: CRM/Twingle/Profile.php -msgid "paydirekt" -msgstr "paydirekt" - #: CRM/Twingle/Profile.php msgid "Apple Pay" msgstr "Apple Pay" @@ -172,9 +423,37 @@ msgstr "Apple Pay" msgid "Google Pay" msgstr "Google Pay" +#: CRM/Twingle/Profile.php +msgid "Paydirekt" +msgstr "Paydirekt" + +#: CRM/Twingle/Profile.php +msgid "Twint" +msgstr "Twint" + +#: CRM/Twingle/Profile.php +msgid "iDEAL" +msgstr "iDEAL" + +#: CRM/Twingle/Profile.php +msgid "Postfinance" +msgstr "Postfinance" + +#: CRM/Twingle/Profile.php +msgid "Bancontact" +msgstr "Bancontact" + +#: CRM/Twingle/Profile.php +msgid "Generic Payment Method" +msgstr "Generische Zahlungsmethode" + +#: CRM/Twingle/Profile.php +msgid "never" +msgstr "nie" + #: CRM/Twingle/Submission.php msgid "Invalid donation rhythm." -msgstr "Ungültiger Zuwendungsrhythmus" +msgstr "Ungültiger Zuwendungsrhythmus." #: CRM/Twingle/Submission.php msgid "Payment method could not be matched to existing payment instrument." @@ -195,77 +474,670 @@ msgid "Gender could not be matched to existing gender." msgstr "" "Geschlecht konnte keiner existierenden Geschlechtsoption zugeordnet werden." +#: CRM/Twingle/Submission.php +msgid "Invalid format for custom fields." +msgstr "Ungültiges Format für benutzerdefinierte Felder." + +#: CRM/Twingle/Submission.php +msgid "campaign_id must be a numeric string. " +msgstr "campaign_id muss eine numerische Zeichenkette sein. " + #: CRM/Twingle/Submission.php msgid "Unknown country %1." msgstr "Unbekanntes Land %1." +#: CRM/Twingle/Submission.php +msgid "Could not calculate SEPA cycle day from configuration." +msgstr "SEPA-Einzugstag konnte nicht aus der Konfiguration berechnet werden." + +#: CRM/Twingle/Tools.php +msgid "" +"This is a Twingle recurring contribution. It should be terminated through " +"the Twingle interface, otherwise it will still be collected." +msgstr "" +"Dies ist eine wiederkehrende Twingle-Zuwendung. Sie sollte durch die Twingle-" +"Benutzeroberfläche beendet werden, da sie ansonsten weiter eingezogen wird." + +#: CRM/Twingle/Tools.php +msgid "" +"Recurring contribution [%1] (Transaction ID '%2') was terminated by a user. " +"You need to end the corresponding record in Twingle as well, or it will " +"still be collected." +msgstr "" +"Wiederkehrende Zuwendung [%1] (Transaktions-ID '%2') wurde von einem " +"Benutzer beendet. Es ist erforderlich, den zugehörigen Datensatz auch in " +"Twingle zu beenden, da die Zuwendung ansonsten weiter eingezogen wird." + +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Submit.php +msgid "Project ID" +msgstr "Projekt-ID" + +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Submit.php +msgid "The Twingle project ID." +msgstr "Die Twingle-Projekt-ID." + +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Submit.php +msgid "Transaction ID" +msgstr "Transaktions-ID" + +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Submit.php +msgid "The unique transaction ID of the donation" +msgstr "Die eindeutige Transaktions-ID der Zuwendung" + +#: api/v3/TwingleDonation/Cancel.php +msgid "Cancelled at" +msgstr "Storniert am" + +#: api/v3/TwingleDonation/Cancel.php +msgid "The date when the donation was cancelled, format: YmdHis." +msgstr "Das Datum der Stornierung der Zuwendung, Format: YmdHis." + +#: api/v3/TwingleDonation/Cancel.php +msgid "Cancel reason" +msgstr "Stornierungsgrund" + +#: api/v3/TwingleDonation/Cancel.php +msgid "The reason for the donation being cancelled." +msgstr "Der Grund der Stornierung der Zuwendung." + #: api/v3/TwingleDonation/Cancel.php msgid "Invalid date for parameter \"cancelled_at\"." msgstr "Ungültiges Datum für Parameter \"cancelled_at\"." +#: api/v3/TwingleDonation/Cancel.php +msgid "SEPA Mandate for contribution [%1 not found." +msgstr "SEPA-Lastschriftmandat für Zuwendung [%1] nicht gefunden." + #: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php msgid "Could not terminate SEPA mandate" msgstr "Konnte SEPA-Mandat nicht beenden" +#: api/v3/TwingleDonation/Endrecurring.php +msgid "Ended at" +msgstr "Beendet am" + +#: api/v3/TwingleDonation/Endrecurring.php +msgid "The date when the recurring donation was ended, format: YmdHis." +msgstr "" +"Das Datum der Beendigung der wiederkehrenden Zuwendung, Format: YmdHis." + #: api/v3/TwingleDonation/Endrecurring.php msgid "Invalid date for parameter \"ended_at\"." msgstr "Ungültiges Datum für Parameter \"ended_at\"." +#: api/v3/TwingleDonation/Endrecurring.php +msgid "SEPA Mandate for recurring contribution [%1 not found." +msgstr "" +"SEPA-lastschriftmandat für wiederkehrende Zuwendung [%1] nicht gefunden." + +#: api/v3/TwingleDonation/Endrecurring.php +msgid "SEPA Mandate [%1] already terminated." +msgstr "SEPA-lastschriftmandat [%1] wurde bereits beendet." + #: api/v3/TwingleDonation/Endrecurring.php msgid "Mandate closed by TwingleDonation.Endrecurring API call" msgstr "Mandat geschlossen durch TwingleDonation.Endrecurring API-Aufruf" #: api/v3/TwingleDonation/Submit.php -msgid "Contribution with the given transaction ID already exists." -msgstr "Zuwendung mit der gegebenen Transkations-ID existiert bereits." +msgid "Confirmed at" +msgstr "Bestätigt am" #: api/v3/TwingleDonation/Submit.php -msgid "Individual contact could not be found or created." -msgstr "Kontakt für Person konnte nicht gefunden oder erstellt werden." +msgid "The date when the donation was issued, format: YmdHis." +msgstr "Das Datum der Ausstellung der Zuwendung, Format: YmdHis." + +#: api/v3/TwingleDonation/Submit.php +msgid "The purpose of the donation." +msgstr "Der Anlass der Zuwendung." + +#: api/v3/TwingleDonation/Submit.php +msgid "Amount" +msgstr "Betrag" + +#: api/v3/TwingleDonation/Submit.php +msgid "The donation amount in minor currency unit." +msgstr "" +"Der Zuwendungsbetrag in untergeordneter Währungseinheit (z. B. Euro-Cent)" + +#: api/v3/TwingleDonation/Submit.php +msgid "Currency" +msgstr "Währung" + +#: api/v3/TwingleDonation/Submit.php +msgid "The ISO-4217 currency code of the donation." +msgstr "Der ISO-4217-Code der Währung der Zuwendung." + +#: api/v3/TwingleDonation/Submit.php +msgid "Newsletter" +msgstr "Newsletter" + +#: api/v3/TwingleDonation/Submit.php +msgid "" +"Whether to subscribe the contact to the newsletter group defined in the " +"profile." +msgstr "" +"Ob der Kontakt in die im Profil definierte Newsletter-Gruppe aufgenommen " +"werden soll." + +#: api/v3/TwingleDonation/Submit.php +msgid "Postal mailing" +msgstr "Postverteiler" + +#: api/v3/TwingleDonation/Submit.php +msgid "" +"Whether to subscribe the contact to the postal mailing group defined in the " +"profile." +msgstr "" +"Ob der Kontakt in die im Profil definierte Postverteilergruppe aufgenommen " +"werden soll." + +#: api/v3/TwingleDonation/Submit.php +msgid "Donation receipt" +msgstr "Zuwendungsbescheinigung" + +#: api/v3/TwingleDonation/Submit.php +msgid "Whether the contact requested a donation receipt." +msgstr "Ob der Kontakt eine Zuwendungsbescheinigung angefordert hat." + +#: api/v3/TwingleDonation/Submit.php +msgid "Payment method" +msgstr "Zahlungsmethode" + +#: api/v3/TwingleDonation/Submit.php +msgid "The Twingle payment method used for the donation." +msgstr "Die für die Zuwendung verwendete Twingle-Zahlungsmethode." + +#: api/v3/TwingleDonation/Submit.php +msgid "Donation rhythm" +msgstr "Zuwendungsrhythmus" + +#: api/v3/TwingleDonation/Submit.php +msgid "The interval which the donation is recurring in." +msgstr "Das Intervall, in dem die Zuwendung wiederkehrt." + +#: api/v3/TwingleDonation/Submit.php +msgid "SEPA IBAN" +msgstr "SEPA-IBAN" + +#: api/v3/TwingleDonation/Submit.php +msgid "" +"The IBAN for SEPA Direct Debit payments, conforming with ISO 13616-1:2007." +msgstr "Die IBAN für SEPA-Lastschriftzahlungen, konform mit ISO 13616-1:2007." + +#: api/v3/TwingleDonation/Submit.php +msgid "SEPA BIC" +msgstr "SEPA-BIC" + +#: api/v3/TwingleDonation/Submit.php +msgid "The BIC for SEPA Direct Debit payments, conforming with ISO 9362." +msgstr "Die BIC für SEPA-Lastschriftzahlungen, konform mit ISO 9362." + +#: api/v3/TwingleDonation/Submit.php +msgid "SEPA Direct Debit Mandate reference" +msgstr "SEPA-Lastschriftmandatsreferenz" + +#: api/v3/TwingleDonation/Submit.php +msgid "The mandate reference for SEPA Direct Debit payments." +msgstr "Die Mandatsreferenz für SEPA-Lastschriftzahlungen." + +#: api/v3/TwingleDonation/Submit.php +msgid "SEPA Direct Debit Account holder" +msgstr "Inhaber des SEPA-Lastschriftkontos" + +#: api/v3/TwingleDonation/Submit.php +msgid "The account holder for SEPA Direct Debit payments." +msgstr "Der Kontoinhaber für SEPA-Lastschriften." + +#: api/v3/TwingleDonation/Submit.php +msgid "Anonymous donation" +msgstr "Anonyme Zuwendung" + +#: api/v3/TwingleDonation/Submit.php +msgid "Whether the donation is submitted anonymously." +msgstr "Ob die Zuwendung anonym übermittelt wird." + +#: api/v3/TwingleDonation/Submit.php +msgid "Gender" +msgstr "Geschlecht" + +#: api/v3/TwingleDonation/Submit.php +msgid "The gender of the contact." +msgstr "Das Geschlecht des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Date of birth" +msgstr "Geburtsdatum" + +#: api/v3/TwingleDonation/Submit.php +msgid "The date of birth of the contact, format: Ymd." +msgstr "Das Geburtsdatum des Kontakts, Format: Ymd." + +#: api/v3/TwingleDonation/Submit.php +msgid "Formal title" +msgstr "Formeller Titel" + +#: api/v3/TwingleDonation/Submit.php +msgid "The formal title of the contact." +msgstr "Der formelle Titel des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Email address" +msgstr "E-Mail-Adresse" + +#: api/v3/TwingleDonation/Submit.php +msgid "The e-mail address of the contact." +msgstr "Die E-Mail-Adresse des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "First name" +msgstr "Vorname" + +#: api/v3/TwingleDonation/Submit.php +msgid "The first name of the contact." +msgstr "Der Vorname des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Last name" +msgstr "Nachname" + +#: api/v3/TwingleDonation/Submit.php +msgid "The last name of the contact." +msgstr "Der Nachname des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Street address" +msgstr "Straße" + +#: api/v3/TwingleDonation/Submit.php +msgid "The street address of the contact." +msgstr "Die Straße des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Postal code" +msgstr "Postleitzahl" + +#: api/v3/TwingleDonation/Submit.php +msgid "The postal code of the contact." +msgstr "Die Postleitzahl des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "The city of the contact." +msgstr "Der Wohnort des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "The country of the contact." +msgstr "Das Land des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Telephone" +msgstr "Telefonnummer" + +#: api/v3/TwingleDonation/Submit.php +msgid "The telephone number of the contact." +msgstr "Die Telefonnummer des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Company" +msgstr "Firma" + +#: api/v3/TwingleDonation/Submit.php +msgid "The company of the contact." +msgstr "Die Firma/Arbeitgeber des Kontakts." + +#: api/v3/TwingleDonation/Submit.php +msgid "Language" +msgstr "Sprache" + +#: api/v3/TwingleDonation/Submit.php +msgid "" +"The preferred language of the contact. A 2-digit ISO-639-1 language code." +msgstr "" +"Die bevorzugte Sprache des Kontakts. Ein zweistelliger ISO-639-1-Sprachcode." + +#: api/v3/TwingleDonation/Submit.php +msgid "User extra field" +msgstr "Zusätzliches Benutzerfeld (user extra field)" + +#: api/v3/TwingleDonation/Submit.php +msgid "Additional information of the contact." +msgstr "Zusätzliche Kontaktinformationen." + +#: api/v3/TwingleDonation/Submit.php +msgid "Campaign ID" +msgstr "Kampagnen-ID" + +#: api/v3/TwingleDonation/Submit.php +msgid "The CiviCRM ID of a campaign to assign the contribution." +msgstr "" +"Die CiviCRM-ID einer Kampagne, der die Zuwendung zugeordnet werden soll." + +#: api/v3/TwingleDonation/Submit.php +msgid "Custom fields" +msgstr "Benutzerdefinierte Felder" + +#: api/v3/TwingleDonation/Submit.php +msgid "" +"Additional information for either the contact or the (recurring) " +"contribution." +msgstr "" +"Zusätzliche Informationen für entweder den Kontakt oder die (wiederkehrende) " +"Zuwendung." + +#: api/v3/TwingleDonation/Submit.php +msgid "Additional remarks for the donation." +msgstr "Zusätzliche Anmerkungen für die Zuwendung." + +#: api/v3/TwingleDonation/Submit.php +msgid "Contribution with the given transaction ID already exists." +msgstr "Zuwendung mit der gegebenen Transkations-ID existiert bereits." #: api/v3/TwingleDonation/Submit.php msgid "Organisation contact could not be found or created." msgstr "Kontakt für Organisation konnte nicht gefunden oder erstellt werden." +#: api/v3/TwingleDonation/Submit.php +msgid "Individual contact could not be found or created." +msgstr "Kontakt für Person konnte nicht gefunden oder erstellt werden." + #: api/v3/TwingleDonation/Submit.php msgid "Missing attribute %1 for SEPA mandate" msgstr "Fehlendes Attribute %1 für SEPA-Mandat" +#: api/v3/TwingleDonation/Submit.php +msgid "SEPA creditor is not configured for profile \"%1\"." +msgstr "SEPA-Kreditor ist nicht konfiguriert für Profil \"%1\"." + #: api/v3/TwingleDonation/Submit.php msgid "Could not create recurring contribution." -msgstr "Wiederkehrende Zuwendung konnte nicht erstellen." +msgstr "Wiederkehrende Zuwendung konnte nicht erstellt werden." + +#: api/v3/TwingleDonation/Submit.php +msgid "Could not find recurring contribution with given parent transaction ID." +msgstr "" +"Wiederkehrende Zuwendung mit angegebener Transkations-ID konnte nicht " +"gefunden werden." #: api/v3/TwingleDonation/Submit.php msgid "Could not create contribution" msgstr "Zuwendung konnte nicht erstellt werden" +#: api/v3/TwingleDonation/Submit.php +msgid "" +"Twingle membership postprocessing call has failed, see log for more " +"information" +msgstr "" +"Die Nachbearbeitung (postprocessing) der Twingle-Mitgliedschaft ist " +"fehlgeschlagen, siehe Protokoll für weitere Informationen." + +#: managed/Navigation__twingle_configuration.mgd.php +msgid "Twingle API Configuration" +msgstr "Twingle-API-Konfiguration" + +#: managed/Navigation__twingle_configuration.mgd.php +msgid "Twingle API Settings" +msgstr "Twingle-API-Einstellungen" + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Select which location type to use for addresses for individuals, either when " +"no organisation name is specified, or an organisation address can not be " +"shared with the individual contact." +msgstr "" +"Wählen Sie die zu verwendende Adresskategorie für Personen, entweder wenn " +"kein Organisationsname angegeben wurde, oder die Organisationsadresse nicht " +"mit dem Personen-Kontakt geteilt werden kann." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Put your project's Twingle ID in here, to activate this profile for that " +"project." +msgstr "" +"Geben Sie hier die Twingle-ID des Projekts ein, um das Profil für dieses " +"Projekt zu aktivieren." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "You can also provide multiple project IDs separated by a comma." +msgstr "" +"Es können auch mehrere durch Kommata getrennte Projekt-IDs angegeben werden." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"The Contact Matcher (XCM) manages the identification or creation of the " +"related contact." +msgstr "" +"Der Extended Contact Matcher (XCM) verwaltet die Identifizierung und " +"Erstellung des zugehörigen Kontakts." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"We recommend creating a new XCM profile only to be used with the Twingle API." +msgstr "" +"Es wird empfohlen, ein neues XCM-Profil zur ausschließlichen Verwendung mit " +"der Twingle-API zu erstellen." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Select which location type to use for addresses for organisations and shared " +"organisation addresses for individual contacts." +msgstr "" +"Wählen Sie die zu verwendende Adresskategorie für Organisationen und " +"geteilte Organisationsadressen für Personen-Kontakte." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "Select which financial type to use for one-time contributions." +msgstr "Wählen Sie die Zuwendungsart für einmalige Zuwendungen." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "Select which financial type to use for recurring contributions." +msgstr "Wählen Sie die Zuwendungsart für wiederkehrende Zuwendungen." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Select whether to use CiviCRM's Double-Opt-In feature for subscribing to " +"mailing lists. Note that this only works for public mailing lists. Any non-" +"public mailing list selected above will be ignored when this setting is " +"enabled." +msgstr "" +"Wählen Sie, ob das Double-Opt-In-Verfahren von CiviCRM für das Abonnieren " +"von E-Mail-Verteilern verwendet werden soll. Beachten Sie, dass dies nur für " +"öffentliche Verteilerlisten funktioniert. Alle ausgewählten nicht-" +"öffentlichen Verteilerlisten werden bei Aktivierung dieser Einstellung " +"ignoriert." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Also, do not forget to disable Twingle's own Double Opt-In option in the " +"Twingle Manager to avoid subscribers receiving multiple confirmation e-" +"mails. Only one or the other option should be enabled." +msgstr "" +"Vergessen Sie außerdem nicht, das Double-Opt-In-Verfahren im Twingle-Manager " +"auszuschalten, um zu verhindern, dass Abonnenten mehrere Bestätigungs-E-Mail-" +"Nachrichten erhalten. Nur eines der beiden Verfahren sollte aktiviert werden." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Some organisations have specific conventions on how a membership should be " +"created. Since the Twingle-API can only create a \"bare bone\" membership " +"object, you can enter a API Call (as 'Entity.Action') to adjust any newly " +"created membership to your organisation's needs." +msgstr "" +"Einige Organisationen haben bestimmte Vorschriften bzgl. der Erstellung von " +"Mitgliedschaften. Da die Twingle-API nur ein \"reines\" " +"Mitgliedschaftsobjekt erstellt, können Sie einen API-Aufruf (als 'Entität." +"Aktion') angeben, um neu erstellt Mitgliedschaften an die Anforderungen " +"Ihrer Organisation anzupassen." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"The API call would receive the following parameters:
        \n" +"
      • membership_id: The ID of the newly created " +"membership
      • \n" +"
      • contact_id: The ID of the contact involved
      • \n" +"
      • organization_id: The ID of the contact's " +"organisation, potentially empty
      • \n" +"
      • contribution_id: The ID contribution received, " +"potentially empty
      • \n" +"
      • recurring_contribution_id: The ID of the recurring " +"contribution. If empty, this was only a one-off donation.
      • \n" +"
      " +msgstr "" +"Der API-Aufruf nimmt die folgenden Parameter entgegen:
        \n" +"
      • membership_id: Die ID der neu erstellten " +"Mitgliedschaft
      • \n" +"
      • contact_id: Die ID des betreffenden Kontakts
      • \n" +"
      • organization_id: Die ID der dem Kontakt " +"zugeordneten Organisation (optional)
      • \n" +"
      • contribution_id: Die ID der erhaltenen Zuwendung " +"(optional)
      • \n" +"
      • recurring_contribution_id: Die ID der " +"wiederkehrenden Zuwendung (optional, falls leer war dies eine einmalige " +"Zuwendung)
      • \n" +"
      " + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Select the address components that must be present to create or update an " +"address for the contact." +msgstr "" +"Wählen Sie die erforderlichen Adresskomponenten für die Erstellung oder " +"Aktualisierung der Adresse des Kontakts." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Depending on your XCM settings, the transferred address might replace an " +"existing one." +msgstr "" +"Abhängig von den XCM-Einstellungen kann die übertragene Adresse eine " +"bestehende ersetzen." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Since in some cases Twingle send the country of the user as the only address " +"parameter, depending on your XCM configuration, not declaring other address " +"components as required might lead to the current user address being " +"overwritten with an address containing the country only." +msgstr "" +"Da Twingle in einigen Fällen das Land des Benutzers als den einzigen " +"Adressparameter übermittelt, kann - abhängig von Ihrer XCM-Konfiguration - " +"die Definition anderer Adresskomponenten als nicht erforderlich dazu führen, " +"dass die bestehende Adresse mit einer neuen überschrieben wird, die nur das " +"Land enthält." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"

      Map Twingle custom fields to CiviCRM fields using the following format " +"(each assignment in a separate line):

      \n" +"
      twingle_field_1=custom_123
      twingle_field_2=custom_789
      \n" +"

      Always use the custom_[id] notation for CiviCRM custom " +"fields.

      \n" +"

      This works for fields that Twingle themselves provide in the " +"custom_fields parameter, and for any other parameter (e.g. " +"user_extrafield)

      \n" +"

      Only custom fields extending one of the following CiviCRM entities " +"are allowed:

      \n" +"
        \n" +"
      • Contact – Will be set on the Individual " +"contact
      • \n" +"
      • Individual – Will be set on the Individual " +"contact
      • \n" +"
      • Organization – Will be set on the " +"Organization contact, if an organisation name was submitted
      • \n" +"
      • Contribution – Will be set on the " +"contribution
      • \n" +"
      • ContributionRecur – Will be set on the " +"recurring contribution and deriving single contributions
      • \n" +"
      " +msgstr "" +"

      Zuordnung von Twingle-Feldern zu benutzerdefinierten CiviCRM-Feldern mit " +"folgendem Format (jede Zuordnung in einer neuen Zeile):

      \n" +"
      twingle_field_1=custom_123
      twingle_field_2=custom_789
      \n" +"

      Verwenden Sie immer die Notation custom_[id] für " +"benutzerdefinierte Felder in CiviCRM.

      \n" +"

      Unterstützt werden Felder, die Twingle im Parameter " +"custom_fields bereitstellt, sowie für alle anderen Parameter (z." +" B. user_extrafield)

      \n" +"

      Es werden nur benutzerdefinierte CiviCRM-Felder der folgenden " +"Entitäten unterstützt:

      \n" +"
        \n" +"
      • Kontakt – wird am Personen-Kontakt gesetzt\n" +"
      • Person – wird am Personen-Kontakt gesetzt\n" +"
      • Organisation – wird am Organisations-" +"Kontakt gesetzt, sofern ein Organisationsname übermittelt wurde
      • \n" +"
      • Zuwendung – wird an der Zuwendung gesetzt\n" +"
      • Wiederkehrende Zuwendung – wird an der " +"wiederkehrenden Zuwendung sowie an abgeleiteten Einzel-Zuwendungen gesetzt\n" +"
      " + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"

      Create a contribution note for each field specified in this selection.\n" +"

      Tip: You can enable or disable this fields in the TwingleMANAGER.

      " +msgstr "" +"

      Erstelle eine Zuwendungs-Notiz für jedes Feld, das in dieser Auswahl " +"angegeben ist.

      \n" +"

      Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder " +"deaktivieren.

      " + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"

      Create a contact note for each field specified in this selection.

      \n" +"

      Tip: You can enable or disable this fields in the TwingleMANAGER.

      " +msgstr "" +"

      Erstelle eine Kontakt-Notiz für jedes Feld, das in dieser Auswahl " +"angegeben ist.

      \n" +"

      Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder " +"deaktivieren.

      " + #: templates/CRM/Twingle/Form/Profile.tpl msgid "General settings" msgstr "Allgemeine Einstellungen" +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "Help" +msgstr "Hilfe" + +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "XCM Profile" +msgstr "XCM-Profil" + +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "Gender/Prefix for value 'male'" +msgstr "Geschlechts-/Anredeoption für übermittelten Wert \"male\"" + +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "Gender/Prefix for value 'female'" +msgstr "Geschlechts-/Anredeoption für übermittelten Wert \"female\"" + +#: templates/CRM/Twingle/Form/Profile.tpl +msgid "Gender/Prefix for value 'other'" +msgstr "Geschlechts-/Anredeoption für übermittelten Wert \"other\"" + #: templates/CRM/Twingle/Form/Profile.tpl msgid "Payment methods" msgstr "Zahlungsmethoden" #: templates/CRM/Twingle/Form/Profile.tpl -msgid "Groups" -msgstr "Gruppen" +msgid "Groups and Correlations" +msgstr "Gruppen und Beziehungen" #: templates/CRM/Twingle/Form/Profile.tpl -msgid "Create contribution note for" -msgstr "Zuwendungs-Notiz erstellen für" +msgid "Newsletter Double Opt-In" +msgstr "Double-Opt-In für Newsletter" #: templates/CRM/Twingle/Form/Profile.tpl -msgid "Create contact note for" -msgstr "Kontakt-Notiz erstellen für" - -#: templates/CRM/Twingle/Form/Profile.hlp -msgid "Create a contribution note for each field specified in this selection. Tip: You can enable or disable this fields in the TwingleMANAGER." -msgstr "Erstelle eine Zuwendungs-Notiz für jedes Feld, das in dieser Auswahl angegeben ist. Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder deaktivieren." - -#: templates/CRM/Twingle/Form/Profile.hlp -msgid "Create a contact note for each field specified in this selection. Tip: You can enable or disable this fields in the TwingleMANAGER." -msgstr "Erstelle eine Kontakt-Notiz für jedes Feld, das in dieser Auswahl angegeben ist. Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder deaktivieren." +msgid "Membership Postprocessing" +msgstr "Mitgliedschafts--Nachbearbeitung (Postprocessing)" #: templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to reset the default profile?" @@ -291,9 +1163,30 @@ msgstr "" "debit_manual), wird bei Einsendung einer Twingle-Zuwendung durch " "die API ein SEPA-Mandat mit den gegebenen Daten erzeugt." -#: templates/CRM/Twingle/Form/Settings.tpl -msgid "Help" -msgstr "Hilfe" +#: templates/CRM/Twingle/Form/Settings.hlp +msgid "" +"When the %1 is enabled, you can activate this to use your own references " +"instead of the ones submitted by Twingle." +msgstr "" +"Wenn die %1 aktiviert ist, können Sie diese Option aktivieren, um Ihre " +"eigenen Referenzen statt der von Twingle übermittelten zu verwenden." + +#: templates/CRM/Twingle/Form/Settings.hlp +msgid "" +"Will protect all recurring contributions created by Twingle from " +"termination, since this does NOT terminate the Twingle collection process" +msgstr "" +"Schützt alle von Twingle erstellten wiederkehrenden Zuwendungen vor " +"Beendigung, da dies nicht den Einzug bei Twingle beendet." + +#: templates/CRM/Twingle/Form/Settings.hlp +msgid "" +"You can use this setting to add a prefix to the Twingle transaction ID, in " +"order to avoid collisions with other transaction ids." +msgstr "" +"Sie können diese Einstellung verwenden, um ein Präfix der Twingle-" +"Transaktions-ID voranzustellen, um Kollisionen mit anderen Transaktions-IDs " +"auszuschließen." #: templates/CRM/Twingle/Page/Configuration.tpl msgid "Profiles" @@ -316,17 +1209,21 @@ msgid "New profile" msgstr "Neues Profil" #: templates/CRM/Twingle/Page/Profiles.tpl -msgid "Properties" -msgstr "Eigenschaften" +msgid "Selectors" +msgstr "Selektoren" + +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "Used" +msgstr "Verwendet" + +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "Last Used" +msgstr "Zuletzt verwendet" #: templates/CRM/Twingle/Page/Profiles.tpl msgid "Operations" msgstr "Operationen" -#: templates/CRM/Twingle/Page/Profiles.tpl -msgid "Selector" -msgstr "Selektor" - #: templates/CRM/Twingle/Page/Profiles.tpl msgid "Edit profile %1" msgstr "Profil %1 bearbeiten" @@ -335,6 +1232,14 @@ msgstr "Profil %1 bearbeiten" msgid "Edit" msgstr "Bearbeiten" +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "Copy profile %1" +msgstr "Profil %1 kopieren" + +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "Copy" +msgstr "Kopieren" + #: templates/CRM/Twingle/Page/Profiles.tpl msgid "Reset profile %1" msgstr "Profil %1 zurücksetzen" @@ -343,5 +1248,19 @@ msgstr "Profil %1 zurücksetzen" msgid "Delete profile %1" msgstr "Profil % 1 löschen" -#~ msgid "Use Double-Opt-In for newsletter" -#~ msgstr "Nutze Double-Opt-In für Newsletter" +#: twingle.php +msgid "Twingle API: Access Twingle API" +msgstr "Twingle-API: Zugriff auf Twingle-API" + +#: twingle.php +msgid "Allows access to the Twingle API actions." +msgstr "Gewährt Zugriff auf Aktionen der Twingle-API." + +#~ msgid "Groups" +#~ msgstr "Gruppen" + +#~ msgid "Create contact note for" +#~ msgstr "Kontakt-Notiz erstellen für" + +#~ msgid "Properties" +#~ msgstr "Eigenschaften" From 96d0e5fbec5ad4953f8e1598713475aed0126bec Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 13 Jun 2024 13:24:34 +0200 Subject: [PATCH 187/221] Code style --- api/v3/TwingleDonation/Submit.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index c8ef884..cef2e33 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -535,6 +535,7 @@ function civicrm_api3_twingle_donation_Submit($params) { && (bool) ($params['newsletter'] ?? FALSE) && is_array($groups = $profile->getAttribute('newsletter_groups')) ) { + // TODO: Ensure the values being integers. $group_memberships = array_column( civicrm_api3( 'GroupContact', @@ -564,7 +565,7 @@ function civicrm_api3_twingle_donation_Submit($params) { 'contact_id' => $contact_id, ] ); - $subscription = CRM_Utils_Array::first($result['values']); + $subscription = reset($result['values']); $subscription['group_id'] = $group_id; $result_values['newsletter_subscriptions'][] = $subscription; } @@ -725,7 +726,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // Create the mandate. $mandate = civicrm_api3('SepaMandate', 'createfull', $mandate_data); - $result_values['sepa_mandate'] = CRM_Utils_Array::first($mandate['values']); + $result_values['sepa_mandate'] = reset($mandate['values']); } else { // Set financial type depending on donation rhythm. This applies for @@ -798,12 +799,15 @@ function civicrm_api3_twingle_donation_Submit($params) { } $contribution = civicrm_api3('Contribution', 'create', $contribution_data); - if ($contribution['is_error']) { + /** @phpstan-var array{'values': array>, 'is_error'?: string} $contribution */ + if ((bool) ($contribution['is_error'] ?? FALSE)) { throw new CRM_Core_Exception( E::ts('Could not create contribution'), 'api_error' ); } + $contribution = reset($contribution['values']); + /** @phpstan-var array{'id': int} $contribution */ // Add notes to the contribution. /** @phpstan-var array $contribution_note_mappings */ @@ -816,13 +820,13 @@ function civicrm_api3_twingle_donation_Submit($params) { ) { Note::create(FALSE) ->addValue('entity_table', 'civicrm_contribution') - ->addValue('entity_id', reset($contribution['values'])['id']) + ->addValue('entity_id', $contribution['id']) ->addValue('note', reset($params[$target])) ->execute(); } } - $result_values['contribution'] = CRM_Utils_Array::first($contribution['values']); + $result_values['contribution'] = $contribution; } // MEMBERSHIP CREATION From 8d30b2a52a38f1c976388c1fa4d01d62b5dec6a4 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 13 Jun 2024 13:34:49 +0200 Subject: [PATCH 188/221] Fix excess `reset()` in note creation --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index daceb36..bcaf275 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -816,7 +816,7 @@ function civicrm_api3_twingle_donation_Submit($params) { Note::create(FALSE) ->addValue('entity_table', 'civicrm_contribution') ->addValue('entity_id', reset($contribution['values'])['id']) - ->addValue('note', reset($params[$target])) + ->addValue('note', $params[$target]) ->execute(); } } From 07435ad9976756dae2edeaa19bd2a902dcb59fbb Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 13 Jun 2024 13:34:34 +0200 Subject: [PATCH 189/221] remove unnecessary `reset()` for $params[$target] --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index cef2e33..be27fc8 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -821,7 +821,7 @@ function civicrm_api3_twingle_donation_Submit($params) { Note::create(FALSE) ->addValue('entity_table', 'civicrm_contribution') ->addValue('entity_id', $contribution['id']) - ->addValue('note', reset($params[$target])) + ->addValue('note', $params[$target]) ->execute(); } } From a363e1c888a83d44889ae9e3b345331833c77de1 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 13 Jun 2024 13:47:07 +0200 Subject: [PATCH 190/221] Version 1.5-alpha2 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index d0876c8..d0aa028 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.5-dev - dev + 2024-06-13 + 1.5-alpha2 + alpha 5.56 From 6606d09dce06292659f0ee9516cb728a43304edb Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 13 Jun 2024 13:47:22 +0200 Subject: [PATCH 191/221] Back to 1.5-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index d0aa028..d0876c8 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2024-06-13 - 1.5-alpha2 - alpha + + 1.5-dev + dev 5.56 From 72bfa3fb2c91a486e4bdedb4050b9c173d101959 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 14:52:30 +0200 Subject: [PATCH 192/221] create custom exceptions --- CRM/Twingle/Exceptions/BaseException.php | 43 +++++++++++++++++++ CRM/Twingle/Exceptions/ProfileException.php | 16 +++++++ .../Exceptions/ProfileValidationError.php | 34 +++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 CRM/Twingle/Exceptions/BaseException.php create mode 100644 CRM/Twingle/Exceptions/ProfileException.php create mode 100644 CRM/Twingle/Exceptions/ProfileValidationError.php diff --git a/CRM/Twingle/Exceptions/BaseException.php b/CRM/Twingle/Exceptions/BaseException.php new file mode 100644 index 0000000..f61a4fe --- /dev/null +++ b/CRM/Twingle/Exceptions/BaseException.php @@ -0,0 +1,43 @@ +log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : ''; + $this->error_code = $error_code; + } + + /** + * Returns the error message, but with the extension name prefixed. + * @return string + */ + public function getLogMessage() { + return $this->log_message; + } + + /** + * Returns the error code. + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } + +} diff --git a/CRM/Twingle/Exceptions/ProfileException.php b/CRM/Twingle/Exceptions/ProfileException.php new file mode 100644 index 0000000..1141d10 --- /dev/null +++ b/CRM/Twingle/Exceptions/ProfileException.php @@ -0,0 +1,16 @@ +affected_field_name = $affected_field_name; + } + + /** + * Returns the name of the profile field that caused the exception. + * @return string + */ + public function getAffectedFieldName() { + return $this->affected_field_name; + } + +} From c971b6f8ebe82c66ea333e961a4aa5ad3047791f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 7 Aug 2023 16:46:57 +0200 Subject: [PATCH 193/221] let CRM_Twingle_Profile class handle its validation --- CRM/Twingle/Form/Profile.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 086dc2b..41d50be 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -566,6 +566,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { CRM_Core_Session::setStatus($e->getMessage(), E::ts('Warning')); } } + catch (ProfileValidationError $e) { + $this->setElementError($e->getAffectedFieldName(), $e->getMessage()); + } } return parent::validate(); From db94f26d6d0601509830c3ac37aacc4767656611 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 16 Aug 2023 14:03:44 +0200 Subject: [PATCH 194/221] use new namespace style --- CRM/Twingle/Exceptions/BaseException.php | 4 +++- CRM/Twingle/Exceptions/ProfileException.php | 4 +++- CRM/Twingle/Exceptions/ProfileValidationError.php | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CRM/Twingle/Exceptions/BaseException.php b/CRM/Twingle/Exceptions/BaseException.php index f61a4fe..eeb5354 100644 --- a/CRM/Twingle/Exceptions/BaseException.php +++ b/CRM/Twingle/Exceptions/BaseException.php @@ -1,12 +1,14 @@ Date: Wed, 16 Aug 2023 17:02:48 +0200 Subject: [PATCH 195/221] override the $code property inherited from Exception in BaseException --- CRM/Twingle/Exceptions/BaseException.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CRM/Twingle/Exceptions/BaseException.php b/CRM/Twingle/Exceptions/BaseException.php index eeb5354..cebf692 100644 --- a/CRM/Twingle/Exceptions/BaseException.php +++ b/CRM/Twingle/Exceptions/BaseException.php @@ -10,8 +10,11 @@ use CRM_Twingle_ExtensionUtil as E; */ class BaseException extends \Exception { - private string $error_code; - private string $log_message; + /** + * @var int|string + */ + protected $code; + protected string $log_message; /** * BaseException Constructor @@ -23,7 +26,7 @@ class BaseException extends \Exception { public function __construct(string $message = '', string $error_code = '') { parent::__construct($message, 1); $this->log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : ''; - $this->error_code = $error_code; + $this->code = $error_code; } /** @@ -39,7 +42,7 @@ class BaseException extends \Exception { * @return string */ public function getErrorCode() { - return $this->error_code; + return $this->code; } } From 7c7c040b30874db7cded9c7529a442da8c911a23 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 17 Aug 2023 10:29:00 +0200 Subject: [PATCH 196/221] add error code for profile validation warning --- CRM/Twingle/Exceptions/ProfileValidationError.php | 1 + 1 file changed, 1 insertion(+) diff --git a/CRM/Twingle/Exceptions/ProfileValidationError.php b/CRM/Twingle/Exceptions/ProfileValidationError.php index e00c6c2..97a50ab 100644 --- a/CRM/Twingle/Exceptions/ProfileValidationError.php +++ b/CRM/Twingle/Exceptions/ProfileValidationError.php @@ -10,6 +10,7 @@ class ProfileValidationError extends BaseException { private string $affected_field_name; public const ERROR_CODE_PROFILE_VALIDATION_FAILED = 'profile_validation_failed'; + public const ERROR_CODE_PROFILE_VALIDATION_WARNING = 'profile_validation_warning'; /** * ProfileValidationError Constructor From eacc9cf496df268d495e63732f86b41326d54290 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 17 Aug 2023 12:51:28 +0200 Subject: [PATCH 197/221] pass $error_code to parent BaseException --- CRM/Twingle/Exceptions/ProfileValidationError.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Exceptions/ProfileValidationError.php b/CRM/Twingle/Exceptions/ProfileValidationError.php index 97a50ab..b7a8f52 100644 --- a/CRM/Twingle/Exceptions/ProfileValidationError.php +++ b/CRM/Twingle/Exceptions/ProfileValidationError.php @@ -22,7 +22,7 @@ class ProfileValidationError extends BaseException { * A meaningful error code */ public function __construct(string $affected_field_name, string $message = '', string $error_code = '') { - parent::__construct($message, 1); + parent::__construct($message, $error_code); $this->affected_field_name = $affected_field_name; } From 1a5f77c0908a204990051f95e3d137642b3b9355 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 6 Sep 2023 16:26:02 +0200 Subject: [PATCH 198/221] refactoring --- CRM/Twingle/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index b6f6225..3e4f6cc 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -666,7 +666,7 @@ class CRM_Twingle_Profile { * @param string $project_id * * @return CRM_Twingle_Profile - * @throws \CRM_Twingle_Exceptions_ProfileException + * @throws \CRM\Twingle\Exceptions\ProfileException * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileForProject($project_id) { From ea46e6a74780ffb46bae056b967b23199444b47b Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 8 Sep 2023 16:04:21 +0200 Subject: [PATCH 199/221] cherry pick of "make sure that default values are present" --- CRM/Twingle/Profile.php | 1 + 1 file changed, 1 insertion(+) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 3e4f6cc..10d412c 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -683,6 +683,7 @@ class CRM_Twingle_Profile { } // If none matches, use the default profile. + $default_profile = $profiles['default']; if (!empty($default_profile)) { return $default_profile; } From 8cfa270dff697e064eb318fd4dab57a8634a5958 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 21 Mar 2024 11:53:57 +0100 Subject: [PATCH 200/221] implement TwingleShop integration --- CRM/Twingle/Exceptions/BaseException.php | 48 -- CRM/Twingle/Form/Profile.php | 45 +- CRM/Twingle/Form/Settings.php | 55 +- CRM/Twingle/Page/Profiles.php | 1 + CRM/Twingle/Profile.php | 32 +- CRM/Twingle/Submission.php | 158 +++- CRM/Twingle/Upgrader.php | 11 + Civi/Api4/TwingleProduct.php | 12 + Civi/Api4/TwingleShop.php | 12 + Civi/Twingle/Exceptions/BaseException.php | 31 +- .../remotes/origin/master | 67 ++ ...tion.php~implement TwingleShop integration | 2 +- .../remotes/origin/master} | 0 ...rror.php~implement TwingleShop integration | 2 +- .../remotes/origin/master} | 0 Civi/Twingle/Shop/ApiCall.php | 269 +++++++ Civi/Twingle/Shop/BAO/TwingleProduct.php | 649 +++++++++++++++ Civi/Twingle/Shop/BAO/TwingleShop.php | 478 +++++++++++ Civi/Twingle/Shop/DAO/TwingleProduct.php | 327 ++++++++ Civi/Twingle/Shop/DAO/TwingleShop.php | 307 ++++++++ Civi/Twingle/Shop/Exceptions/ApiCallError.php | 19 + .../Shop/Exceptions/LineItemException.php | 14 + .../Shop/Exceptions/ProductException.php | 26 + .../Twingle/Shop/Exceptions/ShopException.php | 22 + Civi/Twingle/Shop/Utils/TwingleShopUtils.php | 155 ++++ api/v3/TwingleDonation/Submit.php | 41 +- api/v3/TwingleProduct/Create.php | 138 ++++ api/v3/TwingleProduct/Delete.php | 72 ++ api/v3/TwingleProduct/Get.php | 137 ++++ api/v3/TwingleProduct/Getsingle.php | 54 ++ api/v3/TwingleShop/Create.php | 80 ++ api/v3/TwingleShop/Delete.php | 79 ++ api/v3/TwingleShop/Fetch.php | 97 +++ api/v3/TwingleShop/Get.php | 111 +++ api/v3/TwingleShop/Getsingle.php | 54 ++ css/twingle_shop.css | 37 + info.xml | 2 +- js/twingle_shop.js | 741 ++++++++++++++++++ sql/auto_uninstall.sql | 21 + sql/civicrm_twingle_shop.sql | 66 ++ templates/CRM/Twingle/Form/Profile.hlp | 9 + templates/CRM/Twingle/Form/Profile.tpl | 76 +- templates/CRM/Twingle/Form/Settings.hlp | 4 + templates/CRM/Twingle/Form/Settings.tpl | 26 +- templates/CRM/Twingle/Page/Profiles.tpl | 7 +- .../api/v3/TwingleProduct/CreateTest.php | 54 ++ .../api/v3/TwingleProduct/DeleteTest.php | 54 ++ .../phpunit/api/v3/TwingleProduct/GetTest.php | 54 ++ .../api/v3/TwingleProduct/GetsingleTest.php | 54 ++ .../phpunit/api/v3/TwingleShop/CreateTest.php | 54 ++ .../phpunit/api/v3/TwingleShop/DeleteTest.php | 54 ++ tests/phpunit/api/v3/TwingleShop/GetTest.php | 54 ++ .../api/v3/TwingleShop/GetsingleTest.php | 54 ++ tests/phpunit/bootstrap.php | 65 ++ twingle.civix.php | 22 + twingle.php | 25 + .../CRM/Twingle/TwingleProduct.entityType.php | 10 + xml/schema/CRM/Twingle/TwingleProduct.xml | 75 ++ .../CRM/Twingle/TwingleShop.entityType.php | 10 + xml/schema/CRM/Twingle/TwingleShop.xml | 73 ++ 60 files changed, 5200 insertions(+), 106 deletions(-) delete mode 100644 CRM/Twingle/Exceptions/BaseException.php create mode 100644 Civi/Api4/TwingleProduct.php create mode 100644 Civi/Api4/TwingleShop.php create mode 100644 Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master rename CRM/Twingle/Exceptions/ProfileException.php => Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration (94%) rename Civi/Twingle/Exceptions/{ProfileException.php => ProfileException.php~refs/remotes/origin/master} (100%) rename CRM/Twingle/Exceptions/ProfileValidationError.php => Civi/Twingle/Exceptions/ProfileValidationError.php~implement TwingleShop integration (96%) rename Civi/Twingle/Exceptions/{ProfileValidationError.php => ProfileValidationError.php~refs/remotes/origin/master} (100%) create mode 100644 Civi/Twingle/Shop/ApiCall.php create mode 100644 Civi/Twingle/Shop/BAO/TwingleProduct.php create mode 100644 Civi/Twingle/Shop/BAO/TwingleShop.php create mode 100644 Civi/Twingle/Shop/DAO/TwingleProduct.php create mode 100644 Civi/Twingle/Shop/DAO/TwingleShop.php create mode 100644 Civi/Twingle/Shop/Exceptions/ApiCallError.php create mode 100644 Civi/Twingle/Shop/Exceptions/LineItemException.php create mode 100644 Civi/Twingle/Shop/Exceptions/ProductException.php create mode 100644 Civi/Twingle/Shop/Exceptions/ShopException.php create mode 100644 Civi/Twingle/Shop/Utils/TwingleShopUtils.php create mode 100644 api/v3/TwingleProduct/Create.php create mode 100644 api/v3/TwingleProduct/Delete.php create mode 100644 api/v3/TwingleProduct/Get.php create mode 100644 api/v3/TwingleProduct/Getsingle.php create mode 100644 api/v3/TwingleShop/Create.php create mode 100644 api/v3/TwingleShop/Delete.php create mode 100644 api/v3/TwingleShop/Fetch.php create mode 100644 api/v3/TwingleShop/Get.php create mode 100644 api/v3/TwingleShop/Getsingle.php create mode 100644 css/twingle_shop.css create mode 100644 js/twingle_shop.js create mode 100644 sql/auto_uninstall.sql create mode 100644 sql/civicrm_twingle_shop.sql create mode 100644 tests/phpunit/api/v3/TwingleProduct/CreateTest.php create mode 100644 tests/phpunit/api/v3/TwingleProduct/DeleteTest.php create mode 100644 tests/phpunit/api/v3/TwingleProduct/GetTest.php create mode 100644 tests/phpunit/api/v3/TwingleProduct/GetsingleTest.php create mode 100644 tests/phpunit/api/v3/TwingleShop/CreateTest.php create mode 100644 tests/phpunit/api/v3/TwingleShop/DeleteTest.php create mode 100644 tests/phpunit/api/v3/TwingleShop/GetTest.php create mode 100644 tests/phpunit/api/v3/TwingleShop/GetsingleTest.php create mode 100644 tests/phpunit/bootstrap.php create mode 100644 xml/schema/CRM/Twingle/TwingleProduct.entityType.php create mode 100644 xml/schema/CRM/Twingle/TwingleProduct.xml create mode 100644 xml/schema/CRM/Twingle/TwingleShop.entityType.php create mode 100644 xml/schema/CRM/Twingle/TwingleShop.xml diff --git a/CRM/Twingle/Exceptions/BaseException.php b/CRM/Twingle/Exceptions/BaseException.php deleted file mode 100644 index cebf692..0000000 --- a/CRM/Twingle/Exceptions/BaseException.php +++ /dev/null @@ -1,48 +0,0 @@ -log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : ''; - $this->code = $error_code; - } - - /** - * Returns the error message, but with the extension name prefixed. - * @return string - */ - public function getLogMessage() { - return $this->log_message; - } - - /** - * Returns the error code. - * @return string - */ - public function getErrorCode() { - return $this->code; - } - -} diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 41d50be..73022cd 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -251,6 +251,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Assign template variables. $this->assign('op', $this->_op); + $this->assign('twingle_use_shop', (int) Civi::settings()->get('twingle_use_shop')); $this->assign('profile_name', $profile_name); $this->assign('is_default', $is_default); @@ -354,6 +355,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { static::getPrefixOptions() ); + // Add script and css for Twingle Shop integration + Civi::resources()->addScriptUrl(E::url('js/twingle_shop.js')); + Civi::resources()->addStyleFile(E::LONG_NAME, 'css/twingle_shop.css'); + $payment_instruments = CRM_Twingle_Profile::paymentInstruments(); $this->assign('payment_instruments', $payment_instruments); foreach ($payment_instruments as $pi_name => $pi_label) { @@ -523,6 +528,42 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); + if (Civi::settings()->get('twingle_use_shop')) { + $this->add( + 'checkbox', // field type + 'enable_shop_integration', // field name + E::ts('Enable Shop Integration'), // field label + FALSE, + [] + ); + + $this->add( + 'select', // field type + 'shop_financial_type', // field name + E::ts('Default Financial Type'), // field label + static::getFinancialTypes(), // list of options + TRUE, + ['class' => 'crm-select2 huge'] + ); + + $this->add( + 'select', // field type + 'shop_donation_financial_type', // field name + E::ts('Financial Type for top up donations'), // field label + static::getFinancialTypes(), // list of options + TRUE, + ['class' => 'crm-select2 huge'] + ); + + $this->add( + 'checkbox', // field type + 'shop_map_products', // field name + E::ts('Map Products as Price Fields'), // field label + FALSE, // is not required + [] + ); + } + $this->addButtons([ [ 'type' => 'submit', @@ -566,9 +607,6 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { CRM_Core_Session::setStatus($e->getMessage(), E::ts('Warning')); } } - catch (ProfileValidationError $e) { - $this->setElementError($e->getAffectedFieldName(), $e->getMessage()); - } } return parent::validate(); @@ -993,5 +1031,4 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { } return static::$_campaigns; } - } diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index 0634dbc..a92535e 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -29,14 +29,16 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { * List of all settings options. */ public static $SETTINGS_LIST = [ - 'twingle_prefix', - 'twingle_use_sepa', - 'twingle_dont_use_reference', - 'twingle_protect_recurring', - 'twingle_protect_recurring_activity_type', - 'twingle_protect_recurring_activity_subject', - 'twingle_protect_recurring_activity_status', - 'twingle_protect_recurring_activity_assignee', + 'twingle_prefix', + 'twingle_use_sepa', + 'twingle_dont_use_reference', + 'twingle_protect_recurring', + 'twingle_protect_recurring_activity_type', + 'twingle_protect_recurring_activity_subject', + 'twingle_protect_recurring_activity_status', + 'twingle_protect_recurring_activity_assignee', + 'twingle_use_shop', + 'twingle_access_key', ]; /** @@ -105,13 +107,25 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { ] ); - $this->addButtons([ - [ - 'type' => 'submit', - 'name' => E::ts('Save'), - 'isDefault' => TRUE, - ], - ]); + $this->add( + 'checkbox', + 'twingle_use_shop', + E::ts("Use Twingle Shop Integration") + ); + + $this->add( + 'text', + 'twingle_access_key', + E::ts("Twingle Access Key") + ); + + $this->addButtons(array( + array ( + 'type' => 'submit', + 'name' => E::ts('Save'), + 'isDefault' => TRUE, + ) + )); // set defaults foreach (self::$SETTINGS_LIST as $setting) { @@ -124,8 +138,7 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { } /** - * Custom form validation, because the activity creation fields - * are only mandatory if activity creation is active + * Custom form validation, as some fields are mandatory only when others are active. * @return bool */ public function validate() { @@ -146,6 +159,14 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { } } + // Twingle Access Key is required if Shop Integration is enabled + if ( + CRM_Utils_Array::value('twingle_use_shop', $this->_submitValues) && + !CRM_Utils_Array::value('twingle_access_key', $this->_submitValues, FALSE) + ) { + $this->_errors['twingle_access_key'] = E::ts("An Access Key is required to enable Twingle Shop Integration"); + } + return (0 == count($this->_errors)); } diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index 790d340..da8743e 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -33,6 +33,7 @@ class CRM_Twingle_Page_Profiles extends CRM_Core_Page { } $this->assign('profiles', $profiles); $this->assign('profile_stats', CRM_Twingle_Profile::getProfileStats()); + $this->assign('twingle_use_shop', (int) Civi::settings()->get('twingle_use_shop')); // Add custom css Civi::resources()->addStyleFile(E::LONG_NAME, 'css/twingle.css'); diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 10d412c..a0d0cff 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -43,6 +43,16 @@ class CRM_Twingle_Profile { */ protected $data; + /** + * @var array $check_box_fields + * List of check box fields + */ + public $check_box_fields = [ + 'newsletter_double_opt_in', + 'enable_shop_integration', + 'shop_map_products', + ]; + /** * CRM_Twingle_Profile constructor. * @@ -197,6 +207,16 @@ class CRM_Twingle_Profile { ); } + /** + * Determine if Twingle Shop integration is enabled in general and + * specifically for this profile. + * @return bool + */ + public function isShopEnabled(): bool { + return Civi::settings()->get('twingle_use_shop') && + $this->data['enable_shop_integration']; + } + /** * Retrieves an attribute of the profile. * @@ -532,6 +552,10 @@ class CRM_Twingle_Profile { 'required_address_components' => ['required' => FALSE], 'map_as_contribution_notes' => ['required' => FALSE], 'map_as_contact_notes' => ['required' => FALSE], + 'enable_shop_integration' => ['required' => FALSE], + 'shop_financial_type' => ['required' => FALSE], + 'shop_donation_financial_type' => ['required' => FALSE], + 'shop_map_products' => ['required' => FALSE], ], // Add payment methods. array_combine( @@ -650,6 +674,10 @@ class CRM_Twingle_Profile { ], 'map_as_contribution_notes' => [], 'map_as_contact_notes' => [], + 'enable_shop_integration' => FALSE, + 'shop_financial_type' => 1, + 'shop_donation_financial_type' => 1, + 'shop_map_products' => FALSE, ] // Add contribution status for all payment methods. // phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus @@ -666,7 +694,7 @@ class CRM_Twingle_Profile { * @param string $project_id * * @return CRM_Twingle_Profile - * @throws \CRM\Twingle\Exceptions\ProfileException + * @throws \Civi\Twingle\Exceptions\ProfileException * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileForProject($project_id) { @@ -683,7 +711,6 @@ class CRM_Twingle_Profile { } // If none matches, use the default profile. - $default_profile = $profiles['default']; if (!empty($default_profile)) { return $default_profile; } @@ -780,5 +807,4 @@ class CRM_Twingle_Profile { } return $stats; } - } diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 258f153..606a714 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -17,6 +17,8 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; use Civi\Twingle\Exceptions\BaseException; +use Civi\Twingle\Shop\Exceptions\LineItemException; +use Civi\Twingle\Shop\BAO\TwingleProduct; class CRM_Twingle_Submission { @@ -41,7 +43,18 @@ class CRM_Twingle_Submission { public const EMPLOYER_RELATIONSHIP_TYPE_ID = 5; /** - * @param array &$params + * List of allowed product attributes. + */ + const ALLOWED_PRODUCT_ATTRIBUTES = [ + 'name', + 'internal_id', + 'price', + 'count', + 'total_value', + ]; + + /** + * @param array &$params * A reference to the parameters array of the submission. * * @param \CRM_Twingle_Profile $profile @@ -123,6 +136,22 @@ class CRM_Twingle_Submission { } } + // Validate products + if (!empty($params['products']) && $profile->isShopEnabled()) { + if (is_string($params['products'])) { + $products = json_decode($params['products'], TRUE); + $params['products'] = array_map(function ($product) { + return array_intersect_key($product, array_flip(self::ALLOWED_PRODUCT_ATTRIBUTES)); + }, $products); + } + if (!is_array($params['products'])) { + throw new CiviCRM_API3_Exception( + E::ts('Invalid format for products.'), + 'invalid_format' + ); + } + } + // Validate campaign_id, if given. if (isset($params['campaign_id'])) { // Check whether campaign_id is a numeric string and cast it to an integer. @@ -433,4 +462,131 @@ class CRM_Twingle_Submission { } } + /** + * @param $values + * Processed data + * @param $submission + * Submission data + * @param $profile + * The twingle profile used + * + * @throws \CiviCRM_API3_Exception + * @throws \CRM_Core_Exception + * @throws \Civi\Twingle\Shop\Exceptions\LineItemException + */ + public static function createLineItems($values, $submission, $profile): array { + $line_items = []; + $sum_line_items = 0; + + $contribution_id = $values['contribution']['id']; + if (empty($contribution_id)) { + throw new LineItemException( + "Could not find contribution id for line item assignment.", + LineItemException::ERROR_CODE_CONTRIBUTION_NOT_FOUND + ); + } + + foreach ($submission['products'] as $product) { + + $line_item_data = [ + 'entity_table' => "civicrm_contribution", + 'contribution_id' => $contribution_id, + 'entity_id' => $contribution_id, + 'label' => $product['name'], + 'qty' => $product['count'], + 'unit_price' => $product['price'], + 'line_total' => $product['total_value'], + 'sequential' => 1, + ]; + + // Try to find the TwingleProduct with its corresponding PriceField + // for this product + try { + $price_field = TwingleProduct::findByExternalId($product['id']); + } + catch (Exception $e) { + Civi::log()->error(E::LONG_NAME . + ": An error occurred when searching for TwingleShop with the external ID " . + $product['id'], ['exception' => $e]); + $price_field = NULL; + } + // If found, use the financial type and price field id from the price field + if ($price_field) { + + // Log warning if price differs from the submission + if ($price_field->price != (int) $product['price']) { + Civi::log()->warning(E::LONG_NAME . + ": Price for product " . $product['name'] . " differs from the PriceField. " . + "Using the price from the submission.", ['price_field' => $price_field->price, 'submission' => $product['price']]); + } + + // Log warning if name differs from the submission + if ($price_field->name != $product['name']) { + Civi::log()->warning(E::LONG_NAME . + ": Name for product " . $product['name'] . " differs from the PriceField " . + "Using the name from the submission.", ['price_field' => $price_field->name, 'submission' => $product['name']]); + } + + // Set the financial type and price field id + $line_item_data['financial_type_id'] = $price_field->financial_type_id; + $line_item_data['price_field_value_id'] = $price_field->getPriceFieldValueId(); + $line_item_data['price_field_id'] = $price_field->price_field_id; + $line_item_data['description'] = $price_field->description; + } + // If not found, use the shops default financial type + else { + $financial_type_id = $profile->getAttribute('shop_financial_type', 1); + $line_item_data['financial_type_id'] = $financial_type_id; + } + + // Create the line item + $line_item = civicrm_api3('LineItem', 'create', $line_item_data); + + if (!empty($line_item['is_error'])) { + $line_item_name = $line_item_data['name']; + throw new CiviCRM_API3_Exception( + E::ts("Could not create line item for product '$line_item_name'"), + 'api_error' + ); + } + $line_items[] = array_pop($line_item['values']); + + $sum_line_items += $product['total_value']; + } + + // Create line item for donation part + $donation_sum = (float) $values['contribution']['total_amount'] - $sum_line_items; + if ($donation_sum > 0) { + $donation_financial_type_id = $profile->getAttribute('shop_donation_financial_type', 1); + $donation_label = civicrm_api3('FinancialType', 'getsingle', [ + 'return' => ['name'], + 'id' => $donation_financial_type_id, + ])['name']; + + $donation_line_item_data = [ + 'entity_table' => "civicrm_contribution", + 'contribution_id' => $contribution_id, + 'entity_id' => $contribution_id, + 'label' => $donation_label, + 'qty' => 1, + 'unit_price' => $donation_sum, + 'line_total' => $donation_sum, + 'financial_type_id' => $donation_financial_type_id, + 'sequential' => 1, + ]; + + $donation_line_item = civicrm_api3('LineItem', 'create', $donation_line_item_data); + + if (!empty($donation_line_item['is_error'])) { + throw new CiviCRM_API3_Exception( + E::ts("Could not create line item for donation"), + 'api_error' + ); + } + + $line_items[] = array_pop($donation_line_item['values']); + } + + return $line_items; + } } diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 70f0180..aa80b58 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -137,4 +137,15 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { return TRUE; } + /** + * The Upgrade to 1.5.1 creates the tables civicrm_twingle_product and + * civicrm_twingle_shop. + * + * @return TRUE on success + */ + public function upgrade_5151() { + $this->ctx->log->info('Creating tables for Twingle Shop.'); + $this->executeSqlFile('sql/civicrm_twingle_shop.sql'); + return TRUE; + } } diff --git a/Civi/Api4/TwingleProduct.php b/Civi/Api4/TwingleProduct.php new file mode 100644 index 0000000..839de01 --- /dev/null +++ b/Civi/Api4/TwingleProduct.php @@ -0,0 +1,12 @@ +. - */ - -declare(strict_types = 1); namespace Civi\Twingle\Exceptions; @@ -28,7 +11,7 @@ use CRM_Twingle_ExtensionUtil as E; class BaseException extends \Exception { /** - * @var string + * @var int|string */ protected $code; protected string $log_message; @@ -36,15 +19,13 @@ class BaseException extends \Exception { /** * BaseException Constructor * @param string $message - * Error message + * Error message * @param string $error_code - * A meaningful error code - * @param \Throwable $previous - * A previously thrown exception to include. + * A meaningful error code */ - public function __construct(string $message = '', string $error_code = '', \Throwable $previous = NULL) { - parent::__construct($message, 1, $previous); - $this->log_message = '' !== $message ? E::LONG_NAME . ': ' . $message : ''; + public function __construct(string $message = '', string $error_code = '') { + parent::__construct($message, 1); + $this->log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : ''; $this->code = $error_code; } diff --git a/Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master b/Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master new file mode 100644 index 0000000..a5413d5 --- /dev/null +++ b/Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master @@ -0,0 +1,67 @@ +. + */ + +declare(strict_types = 1); + +namespace Civi\Twingle\Exceptions; + +use CRM_Twingle_ExtensionUtil as E; + +/** + * A simple custom exception class that indicates a problem within a class + * of the Twingle API extension. + */ +class BaseException extends \Exception { + + /** + * @var string + */ + protected $code; + protected string $log_message; + + /** + * BaseException Constructor + * @param string $message + * Error message + * @param string $error_code + * A meaningful error code + * @param \Throwable $previous + * A previously thrown exception to include. + */ + public function __construct(string $message = '', string $error_code = '', \Throwable $previous = NULL) { + parent::__construct($message, 1, $previous); + $this->log_message = '' !== $message ? E::LONG_NAME . ': ' . $message : ''; + $this->code = $error_code; + } + + /** + * Returns the error message, but with the extension name prefixed. + * @return string + */ + public function getLogMessage() { + return $this->log_message; + } + + /** + * Returns the error code. + * @return string + */ + public function getErrorCode() { + return $this->code; + } + +} diff --git a/CRM/Twingle/Exceptions/ProfileException.php b/Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration similarity index 94% rename from CRM/Twingle/Exceptions/ProfileException.php rename to Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration index 7011507..b9e5954 100644 --- a/CRM/Twingle/Exceptions/ProfileException.php +++ b/Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration @@ -1,6 +1,6 @@ + * @var string $apiToken + */ + private string $apiToken; + + /** + * The ID of your organization in the Twingle database. + * Automatically retrieved by sending a request with the associated API token. + * @var int $organisationId + */ + public int $organisationId; + + /** + * This boolean indicates whether the connection was successful. + * + * @var bool $isConnected + */ + public bool $isConnected; + + /** + * Limit the number of items requested per API call. + * @var int $limit + */ + public int $limit = 40; + + /** + * Header for cURL request. + * @var string[] $header + */ + private array $header; + + /** + * The cURL wrapper + * @var \Civi\Twingle\Shop\CurlWrapper $curlWrapper + */ + private CurlWrapper $curlWrapper; + + /** + * Protected TwingleApiCall constructor. + * Use \Civi\Twingle\ApiCall::singleton() instead. + * @param \Civi\Twingle\Shop\CurlWrapper $curlWrapper + */ + protected function __construct(CurlWrapper $curlWrapper) { + $this->curlWrapper = $curlWrapper; + $this->isConnected = FALSE; + } + + /** + * Returns \Civi\Twingle\Shop\ApiCall singleton + * + * @param \Civi\Twingle\Shop\CurlWrapper|null $curlWrapper + * Optional cURL wrapper for testing purposes + * @return \Civi\Twingle\Shop\ApiCall + */ + public static function singleton(CurlWrapper $curlWrapper = null): ApiCall { + if (empty(self::$singleton)) { + $curlWrapper = $curlWrapper ?? new CurlWrapper(); + self::$singleton = new ApiCall($curlWrapper); + return self::$singleton; + } + else { + return self::$singleton; + } + } + + /** + * Try to connect to the Twingle API and retrieve the organisation ID. + * + * @return bool + * returns TRUE if the connection was successfully established + * + * @throws \Civi\Twingle\Shop\Exceptions\ApiCallError + */ + public function connect(): bool { + + $this->isConnected = FALSE; + + try { + // Get api token from settings + $apiToken = \Civi::settings()->get("twingle_access_key"); + if (empty($apiToken)) { + throw new \TypeError(); + } + $this->apiToken = $apiToken; + } catch (\TypeError $e) { + throw new ApiCallError( + E::ts("Could not find Twingle API token"), + ApiCallError::ERROR_CODE_API_TOKEN_MISSING, + ); + } + + $this->header = [ + "x-access-code: $this->apiToken", + 'Content-Type: application/json', + ]; + + $url = self::PROTOCOL . 'organisation' . self::BASE_URL . "/"; + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($curl, CURLOPT_HTTPHEADER, $this->header); + + $response = json_decode(curl_exec($curl), TRUE); + + if (empty($response)) { + curl_close($curl); + throw new ApiCallError( + E::ts("Call to Twingle API failed. Please check your api token."), + ApiCallError::ERROR_CODE_CONNECTION_FAILED, + ); + } + self::check_response_and_close($response, $curl); + + $this->organisationId = array_column($response, 'id')[0]; + $this->isConnected = TRUE; + return $this->isConnected; + } + + /** + * Check response on cURL + * + * @param $response + * the cURL response to check + * @param $curl + * the cURL resource + * + * @return bool + * returns true if the response is fine + * + * @throws \Civi\Twingle\Shop\Exceptions\ApiCallError + */ + protected static function check_response_and_close($response, $curl) { + + $curl_status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); + curl_close($curl); + + if ($response == FALSE) { + throw new ApiCallError( + E::ts('GET curl failed'), + ApiCallError::ERROR_CODE_GET_REQUEST_FAILED, + ); + } + if ($curl_status_code == 404) { + throw new ApiCallError( + E::ts('http status code 404 (not found)'), + ApiCallError::ERROR_CODE_404, + ); + } + elseif ($curl_status_code == 500) { + throw new ApiCallError( + E::ts('https status code 500 (internal error)'), + ApiCallError::ERROR_CODE_500, + ); + } + + return TRUE; + } + + /** + * Sends a GET cURL and returns the result array. + * + * @param $entity + * Twingle entity + * + * @param null $params + * Optional GET parameters + * + * @return array + * Returns the result array of the or FALSE, if the cURL failed + * @throws \Civi\Twingle\Shop\Exceptions\ApiCallError + */ + public function get( + string $entity, + string $entityId = NULL, + string $endpoint = NULL, + string $endpointId = NULL, + array $params = NULL + ): array { + + // Throw an error, if connection is not yet established + if ($this->isConnected == FALSE) { + throw new ApiCallError( + E::ts("Connection not yet established. Use connect() method."), + ApiCallError::ERROR_CODE_NOT_CONNECTED, + ); + } + + // Build URL and initialize cURL + $url = self::PROTOCOL . $entity . self::BASE_URL; + if (!empty($entityId)) { + $url .= "/$entityId"; + } + if (!empty($endpoint)) { + $url .= "/$endpoint"; + } + if (!empty($endpointId)) { + $url .= "/$endpointId"; + } + if (!empty($params)) { + $url .= '?' . http_build_query($params); + } + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($curl, CURLOPT_HTTPHEADER, $this->header); + + // Execute cURL + $response = json_decode(curl_exec($curl), TRUE); + self::check_response_and_close($response, $curl); + + return $response; + } +} + +/** + * A simple wrapper for the cURL functions to allow for easier testing. + */ +class CurlWrapper { + public function init($url) { + return curl_init($url); + } + + public function setopt($ch, $option, $value) { + return curl_setopt($ch, $option, $value); + } + + public function exec($ch) { + return curl_exec($ch); + } + + public function getinfo($ch, $option) { + return curl_getinfo($ch, $option); + } + + public function close($ch) { + curl_close($ch); + } +} diff --git a/Civi/Twingle/Shop/BAO/TwingleProduct.php b/Civi/Twingle/Shop/BAO/TwingleProduct.php new file mode 100644 index 0000000..3e2d120 --- /dev/null +++ b/Civi/Twingle/Shop/BAO/TwingleProduct.php @@ -0,0 +1,649 @@ + CRM_Utils_Type::T_INT, + "external_id" => CRM_Utils_Type::T_INT, + "name" => CRM_Utils_Type::T_STRING, + "is_active" => CRM_Utils_Type::T_BOOLEAN, + "description" => CRM_Utils_Type::T_STRING, + "price" => CRM_Utils_Type::T_INT, + "created_at" => CRM_Utils_Type::T_INT, + "tw_created_at" => CRM_Utils_Type::T_INT, + "updated_at" => CRM_Utils_Type::T_INT, + "tw_updated_at" => CRM_Utils_Type::T_INT, + "is_orphaned" => CRM_Utils_Type::T_BOOLEAN, + "is_outdated" => CRM_Utils_Type::T_BOOLEAN, + "project_id" => CRM_Utils_Type::T_INT, + "sort" => CRM_Utils_Type::T_INT, + "financial_type_id" => CRM_Utils_Type::T_INT, + "twingle_shop_id" => CRM_Utils_Type::T_INT, + "price_field_id" => CRM_Utils_Type::T_INT, + # "text" => \CRM_Utils_Type::T_STRING, + # "images" => \CRM_Utils_Type::T_STRING, + # "categories" = \CRM_Utils_Type::T_STRING, + # "internal_id" => \CRM_Utils_Type::T_STRING, + # "has_zero_price" => \CRM_Utils_Type::T_BOOLEAN, + # "name_plural" => \CRM_Utils_Type::T_STRING, + # "max_count" => \CRM_Utils_Type::T_INT, + # "has_textinput" => \CRM_Utils_Type::T_BOOLEAN, + # "count" => \CRM_Utils_Type::T_INT, + ]; + + /** + * Change attribute names to match the database column names. + * + * @param array $values + * Array with product data from Twingle API + * + * @return array + */ + public static function renameTwingleAttrs(array $values) { + $new_values = []; + foreach ($values as $key => $value) { + // replace 'id' with 'external_id' + if ($key == 'id') { + $key = 'external_id'; + } + // replace 'updated_at' with 'tw_updated_at' + if ($key == 'updated_at') { + $key = 'tw_updated_at'; + } + // replace 'created_at' with 'tw_created_at' + if ($key == 'created_at') { + $key = 'tw_created_at'; + } + $new_values[$key] = $value; + } + return $new_values; + } + + /** + * Load product data. + * + * @param array $product_data + * Array with product data + * + * @return void + * + * @throws ProductException + * @throws \Exception + */ + public function load(array $product_data): void { + // Filter for allowed attributes + filter_attributes( + $product_data, + self::ALLOWED_ATTRIBUTES, + self::CAN_BE_ZERO, + ); + + // Amend data from corresponding PriceFieldValue + if (isset($product_data['price_field_id'])) { + try { + $price_field_value = civicrm_api3('PriceFieldValue', 'getsingle', [ + 'price_field_id' => $product_data['price_field_id'], + ]); + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts("Could not find PriceFieldValue for Twingle Product ['id': %1, 'external_id': %2]: %3", + [ + 1 => $product_data['id'], + 2 => $product_data['external_id'], + 3 => $e->getMessage(), + ]), + ProductException::ERROR_CODE_PRICE_FIELD_VALUE_NOT_FOUND); + } + $product_data['name'] = $product_data['name'] ?? $price_field_value['label']; + $product_data['price'] = $product_data['price'] ?? $price_field_value['amount']; + $product_data['financial_type_id'] = $product_data['financial_type_id'] ?? $price_field_value['financial_type_id']; + $product_data['is_active'] = $product_data['is_active'] ?? $price_field_value['is_active']; + $product_data['sort'] = $product_data['sort'] ?? $price_field_value['weight']; + $product_data['description'] = $product_data['description'] ?? $price_field_value['description']; + } + + // Change data types + try { + convert_str_to_int($product_data, self::STR_TO_INT_CONVERSION); + convert_int_to_bool($product_data, self::INT_TO_BOOL_CONVERSION); + convert_str_to_date($product_data, self::STR_TO_DATE_CONVERSION); + convert_null_to_int($product_data, self::NULL_TO_INT_CONVERSION); + } + catch (\Exception $e) { + throw new ProductException($e->getMessage(), ProductException::ERROR_CODE_ATTRIBUTE_WRONG_DATA_TYPE); + } + + // Validate data types + try { + validate_data_types($product_data, self::ALLOWED_ATTRIBUTES); + } + catch (\Exception $e) { + throw new ProductException($e->getMessage(), ProductException::ERROR_CODE_ATTRIBUTE_WRONG_DATA_TYPE); + } + + // Set attributes + foreach ($product_data as $key => $value) { + $this->$key = $value; + } + } + + /** + * Creates a price field to represents this product in CiviCRM. + * + * @param string $mode + * 'create' or 'edit' + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + public function createPriceField() { + // Define mode for PriceField + $mode = $this->price_field_id ? 'edit' : 'create'; + $action = $mode == 'create' ? 'create' : 'update'; + + // Check if PriceSet for this Shop already exists + try { + $price_field = civicrm_api3('PriceField', 'get', [ + 'name' => 'tw_product_' . $this->external_id, + ]); + if ($price_field['count'] > 0 && $mode == 'create') { + throw new ProductException( + E::ts('PriceField for this Twingle Product already exists.'), + ProductException::ERROR_CODE_PRICE_FIELD_ALREADY_EXISTS, + ); + } elseif ($price_field['count'] == 0 && $mode == 'edit') { + throw new ProductException( + E::ts('PriceField for this Twingle Product does not exist and cannot be edited.'), + ProductException::ERROR_CODE_PRICE_FIELD_NOT_FOUND, + ); + } + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('Could not check if PriceField for this Twingle Product already exists.'), + ProductException::ERROR_CODE_PRICE_FIELD_NOT_FOUND, + ); + } + + // Try to find corresponding price set via TwingleShop + try { + $shop = civicrm_api3('TwingleShop', 'getsingle', [ + 'id' => $this->twingle_shop_id, + ]); + $this->price_set_id = (int) $shop['price_set_id']; + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('Could not find PriceSet for this Twingle Product.'), + ProductException::ERROR_CODE_PRICE_SET_NOT_FOUND, + ); + } + + // Create PriceField + $price_field_data = [ + 'price_set_id' => $this->price_set_id, + 'name' => 'tw_product_' . $this->external_id, + 'label' => $this->name, + 'is_active' => $this->is_active, + 'weight' => $this->sort, + 'html_type' => 'Text', + ]; + // Add id if in edit mode + if ($mode == 'edit') { + $price_field_data['id'] = $this->price_field_id; + } + try { + $price_field = civicrm_api4( + 'PriceField', + $action, + ['values' => $price_field_data], + )->first(); + $this->price_field_id = (int) $price_field['id']; + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('Could not create PriceField for this Twingle Product: %1', + [1 => $e->getMessage()]), + ProductException::ERROR_CODE_COULD_NOT_CREATE_PRICE_FIELD); + } + + // Try to find existing PriceFieldValue if in edit mode + $price_field_value = NULL; + if ($mode == 'edit') { + try { + $price_field_value = civicrm_api3('PriceFieldValue', 'getsingle', [ + 'price_field_id' => $this->price_field_id, + ]); + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('Could not find PriceFieldValue for this Twingle Product: %1', + [1 => $e->getMessage()]), + ProductException::ERROR_CODE_PRICE_FIELD_VALUE_NOT_FOUND); + } + } + + // Create PriceFieldValue + $price_field_value_data = [ + 'price_field_id' => $this->price_field_id, + 'financial_type_id' => $this->financial_type_id, + 'label' => $this->name, + 'amount' => $this->price, + 'is_active' => $this->is_active, + 'description' => $this->description, + ]; + // Add id if in edit mode + if ($mode == 'edit' && $price_field_value) { + $price_field_value_data['id'] = $price_field_value['id']; + } + try { + civicrm_api4( + 'PriceFieldValue', + $action, + ['values' => $price_field_value_data], + ); + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('Could not create PriceFieldValue for this Twingle Product: %1', + [1 => $e->getMessage()]), + ProductException::ERROR_CODE_COULD_NOT_CREATE_PRICE_FIELD_VALUE); + } + } + + /** + * Returns this TwingleProduct's attributes. + * + * @return array + * @throws \CRM_Core_Exception + */ + public function getAttributes() { + // Filter for allowed attributes + return array_intersect_key( + get_object_vars($this), + $this::ALLOWED_ATTRIBUTES + ) // Add financial type id of this product if it exists + + ['financial_type_id' => $this->getFinancialTypeId()]; + } + + /** + * Find TwingleProduct by its external ID. + * + * @param int $external_id + * External id of the product (by Twingle) + * + * @return TwingleProduct|null + * TwingleProduct object or NULL if not found + * + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + * @throws \Civi\Core\Exception\DBQueryException + */ + public static function findByExternalId($external_id) { + $dao = TwingleShopDAO::executeQuery("SELECT * FROM civicrm_twingle_product WHERE external_id = %1", + [1 => [$external_id, 'String']]); + if ($dao->fetch()) { + $product = new self(); + $product->load($dao->toArray()); + return $product; + } + return NULL; + } + + /** + * Add Twingle Product + * + * @param string $mode + * 'create' or 'edit' + * @return array + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + * @throws \Exception + */ + public function add($mode = 'create') { + + $tx = new CRM_Core_Transaction(); + + // Define mode + $mode = $this->id ? 'edit' : 'create'; + + // Try to lookup object in database + try { + $dao = TwingleShopDAO::executeQuery("SELECT * FROM civicrm_twingle_product WHERE external_id = %1", + [1 => [$this->external_id, 'String']]); + if ($dao->fetch()) { + $this->copyValues(array_merge($dao->toArray(), $this->getAttributes())); + } + } + catch (\Civi\Core\Exception\DBQueryException $e) { + throw new ProductException( + E::ts('Could not find TwingleProduct in database: ' . $e->getMessage()), + ShopException::ERROR_CODE_COULD_NOT_FIND_SHOP_IN_DB); + } + + // Register pre-hook + $twingle_product_values = $this->getAttributes(); + try { + \CRM_Utils_Hook::pre($mode, 'TwingleProduct', $this->id, $twingle_product_values); + } catch (\Exception $e) { + $tx->rollback(); + throw $e; + } + $this->load($twingle_product_values); + + // Set latest tw_updated_at as new updated_at + $this->updated_at = \CRM_Utils_Time::date('Y-m-d H:i:s', $this->tw_updated_at); + + // Convert created_at to date string + $this->created_at = \CRM_Utils_Time::date('Y-m-d H:i:s', $this->created_at); + + // Save object to database + try { + $this->save(); + } catch (\Exception $e) { + $tx->rollback(); + throw new ProductException( + E::ts('Could not save TwingleProduct to database: ' . $e->getMessage()), + ProductException::ERROR_CODE_COULD_NOT_CREATE_PRODUCT); + } + $result = self::findById($this->id); + /* @var self $result */ + $this->load($result->getAttributes()); + + // Register post-hook + $twingle_product_values = $this->getAttributes(); + try { + \CRM_Utils_Hook::post($mode, 'TwingleProduct', $this->id, $twingle_product_values); + } + catch (\Exception $e) { + $tx->rollback(); + throw $e; + } + $this->load($twingle_product_values); + + return $result->toArray(); + } + + /** + * Delete TwingleProduct along with associated PriceField and PriceFieldValue. + * + * @override \Civi\Twingle\Shop\DAO\TwingleProduct::delete + * @throws \CRM_Core_Exception + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + function delete($useWhere = FALSE) { + // Register post-hook + $twingle_product_values = $this->getAttributes(); + \CRM_Utils_Hook::pre('delete', 'TwingleProduct', $this->id, $twingle_product_values); + $this->load($twingle_product_values); + + // Delete TwingleProduct + parent::delete($useWhere); + + // Register post-hook + \CRM_Utils_Hook::post('delete', 'TwingleProduct', $this->id, $instance); + + // Free global arrays associated with this object + $this->free(); + + return true; + } + + /** + * Complements the data with the data that was fetched from Twingle. + * + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + public function complementWithDataFromTwingle($product_from_twingle) { + // Complement with data from Twingle + $this->load([ + 'project_id' => $product_from_twingle['project_id'], + 'tw_updated_at' => $product_from_twingle['updated_at'], + 'tw_created_at' => $product_from_twingle['created_at'], + ]); + } + + /** + * Check if the product is outdated. + * + * @param $product_from_twingle + * + * @return void + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + public function checkOutdated($product_from_twingle) { + // Mark outdated products which have a newer timestamp in Twingle + if ($this->updated_at < intval($product_from_twingle['updated_at'])) { + // Overwrite the product with the data from Twingle + $this->load(self::renameTwingleAttrs($product_from_twingle)); + $this->is_outdated = TRUE; + } + } + + /** + * Compare two products + * + * @param TwingleProduct $product_to_compare_with + * Product from database + * + * @return bool + */ + public function equals($product_to_compare_with) { + return + $this->name === $product_to_compare_with->name && + $this->description === $product_to_compare_with->description && + $this->text === $product_to_compare_with->text && + $this->price === $product_to_compare_with->price && + $this->external_id === $product_to_compare_with->external_id; + } + + /** + * Returns the financial type id of this product. + * + * @return int|null + * @throws \CRM_Core_Exception + */ + public function getFinancialTypeId(): ?int { + if (!empty($this->price_field_id)) { + $price_set = \Civi\Api4\PriceField::get() + ->addSelect('financial_type_id') + ->addWhere('id', '=', $this->price_field_id) + ->execute() + ->first(); + return $price_set['financial_type_id']; + } + return NULL; + } + + /** + * Returns the price field value id of this product. + * + * @return int|null + * @throws \CRM_Core_Exception + */ + public function getPriceFieldValueId() { + if (!empty($this->price_field_id)) { + $price_field_value = \Civi\Api4\PriceFieldValue::get() + ->addSelect('id') + ->addWhere('price_field_id', '=', $this->price_field_id) + ->execute() + ->first(); + return $price_field_value['id']; + } + return NULL; + } + + /** + * Delete PriceField and PriceFieldValue of this TwingleProduct if they exist. + * + * @return void + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + public function deletePriceField(): void { + // Before we can delete the PriceField we need to delete the associated + // PriceFieldValue + try { + $result = civicrm_api3('PriceFieldValue', 'getsingle', + ['price_field_id' => $this->price_field_id]); + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('An Error occurred while searching for the associated PriceFieldValue: ' . $e->getMessage()), + ProductException::ERROR_CODE_PRICE_FIELD_VALUE_NOT_FOUND); + } + try { + civicrm_api3('PriceFieldValue', 'delete', ['id' => $result['id']]); + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('Could not delete associated PriceFieldValue: ' . $e->getMessage()), + ProductException::ERROR_CODE_COULD_NOT_DELETE_PRICE_FIELD_VALUE); + } + + // Try to delete PriceField + // If no PriceField is found, we assume that it has already been deleted + try { + civicrm_api3('PriceField', 'delete', + ['id' => $this->price_field_id]); + } + catch (CRM_Core_Exception $e) { + // Check if PriceField yet exists + try { + $result = civicrm_api3('PriceField', 'get', + ['id' => $this->price_field_id]); + // Throw exception if PriceField still exists + if ($result['count'] > 0) { + throw new ProductException( + E::ts('PriceField for this Twingle Product still exists.'), + ProductException::ERROR_CODE_PRICE_FIELD_STILL_EXISTS); + } + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts('An Error occurred while searching for the associated PriceField: ' . $e->getMessage()), + ProductException::ERROR_CODE_PRICE_FIELD_NOT_FOUND); + } + throw new ProductException( + E::ts('Could not delete associated PriceField: ' . $e->getMessage()), + ProductException::ERROR_CODE_COULD_NOT_DELETE_PRICE_FIELD); + } + $this->price_field_id = NULL; + } +} diff --git a/Civi/Twingle/Shop/BAO/TwingleShop.php b/Civi/Twingle/Shop/BAO/TwingleShop.php new file mode 100644 index 0000000..c27853c --- /dev/null +++ b/Civi/Twingle/Shop/BAO/TwingleShop.php @@ -0,0 +1,478 @@ + \CRM_Utils_Type::T_INT, + 'project_identifier' => \CRM_Utils_Type::T_STRING, + 'numerical_project_id' => \CRM_Utils_Type::T_INT, + 'name' => \CRM_Utils_Type::T_STRING, + 'price_set_id' => \CRM_Utils_Type::T_INT, + 'financial_type_id' => \CRM_Utils_Type::T_INT, + ]; + + public const STR_TO_INT_CONVERSION = [ + 'id', + 'numerical_project_id', + 'price_set_id', + 'financial_type_id', + ]; + + /** + * @var array $products + * Array of Twingle Shop products (Cache) + */ + public $products; + + /** + * FK to Financial Type + * + * @var int + */ + public $financial_type_id; + + /** + * TwingleShop constructor + */ + public function __construct() { + parent::__construct(); + // Get TwingleApiCall singleton + $this->twingleApi = ApiCall::singleton(); + } + + /** + * Get Twingle Shop from database by its project identifier + * (like 'tw620214349ac97') + * + * @param string $project_identifier + * Twingle project identifier + * + * @return TwingleShop + * + * @throws ShopException + * @throws \Civi\Twingle\Shop\Exceptions\ApiCallError + * @throws \CRM_Core_Exception + */ + public static function findByProjectIdentifier(string $project_identifier) { + $shop = new TwingleShop(); + $shop->get('project_identifier', $project_identifier); + if (!$shop->id) { + $shop->fetchDataFromTwingle($project_identifier); + } + else { + $shop->price_set_id = civicrm_api3('PriceSet', 'getvalue', + ['return' => 'id', 'name' => $project_identifier]); + } + return $shop; + } + + /** + * Load Twingle Shop data + * + * @param array $shop_data + * Array with shop data + * + * @return void + * + * @throws ShopException + */ + public function load(array $shop_data): void { + // Filter for allowed attributes + filter_attributes($shop_data, self::ALLOWED_ATTRIBUTES); + + // Convert string to int + try { + convert_str_to_int($shop_data, self::STR_TO_INT_CONVERSION); + } + catch (Exception $e) { + throw new ShopException($e->getMessage(), ShopException::ERROR_CODE_ATTRIBUTE_WRONG_DATA_TYPE); + } + + // Validate data types + try { + validate_data_types($shop_data, self::ALLOWED_ATTRIBUTES); + } + catch (Exception $e) { + throw new ShopException($e->getMessage(), ShopException::ERROR_CODE_ATTRIBUTE_WRONG_DATA_TYPE); + } + + // Set attributes + foreach ($shop_data as $key => $value) { + $this->$key = $value; + } + } + + /** + * Get attributes + * + * @return array + */ + function getAttributes(): array { + return [ + 'id' => $this->id, + 'project_identifier' => $this->project_identifier, + 'numerical_project_id' => $this->numerical_project_id, + 'name' => $this->name, + 'price_set_id' => $this->price_set_id, + 'financial_type_id' => $this->financial_type_id, + ]; + } + + /** + * Add Twingle Shop + * + * @param string $mode + * 'create' or 'edit' + * @return array + * @throws \Civi\Twingle\Shop\Exceptions\ShopException + */ + public function add($mode = 'create') { + + // Try to lookup object in database + try { + $dao = TwingleShopDAO::executeQuery("SELECT * FROM civicrm_twingle_shop WHERE project_identifier = %1", + [1 => [$this->project_identifier, 'String']]); + if ($dao->fetch()) { + $this->load($dao->toArray()); + } + } catch (\Civi\Core\Exception\DBQueryException $e) { + throw new ShopException( + E::ts('Could not find TwingleShop in database: ' . $e->getMessage()), + ShopException::ERROR_CODE_COULD_NOT_FIND_SHOP_IN_DB); + } + + // Register pre-hook + $twingle_shop_values = $this->getAttributes(); + \CRM_Utils_Hook::pre($mode, 'TwingleShop', $this->id, $twingle_shop_values); + $this->load($twingle_shop_values); + + // Save object to database + $result = $this->save(); + + // Register post-hook + \CRM_Utils_Hook::post($mode, 'TwingleShop', $this->id, $instance); + + return $result->toArray(); + } + + /** + * Delete object by deleting the associated PriceSet and letting the foreign + * key constraint do the rest. + * + * @throws \Civi\Twingle\Shop\Exceptions\ShopException* + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + function deleteByConstraint() { + // Register post-hook + $twingle_shop_values = $this->getAttributes(); + \CRM_Utils_Hook::pre('delete', 'TwingleShop', $this->id, $twingle_shop_values); + $this->load($twingle_shop_values); + + // Delete associated products + $this->deleteProducts(); + + // Try to get single PriceSet + try { + civicrm_api3('PriceSet', 'getsingle', + ['id' => $this->price_set_id]); + } + catch (\CRM_Core_Exception $e) { + if ($e->getMessage() != 'Expected one PriceSet but found 0') { + throw new ShopException( + E::ts('Could not find associated PriceSet: ' . $e->getMessage()), + ShopException::ERROR_CODE_PRICE_SET_NOT_FOUND); + } + else { + // If no PriceSet is found, we can simply delete the TwingleShop + return $this->delete(); + } + } + + // Deleting the associated PriceSet will also lead to the deletion of this + // TwingleShop because of the foreign key constraint and cascading. + try { + $result = civicrm_api3('PriceSet', 'delete', + ['id' => $this->price_set_id]); + } catch (\CRM_Core_Exception $e) { + throw new ShopException( + E::ts('Could not delete associated PriceSet: ' . $e->getMessage()), + ShopException::ERROR_CODE_COULD_NOT_DELETE_PRICE_SET); + } + + // Register post-hook + \CRM_Utils_Hook::post('delete', 'TwingleShop', $this->id, $instance); + + // Free global arrays associated with this object + $this->free(); + + return $result['is_error'] == 0; + } + + /** + * Fetch Twingle Shop products from Twingle + * + * @return array + * array of CRM_Twingle_Shop_BAO_Product + * + * @throws \Civi\Twingle\Shop\Exceptions\ApiCallError; + * @throws \Civi\Twingle\Shop\Exceptions\ProductException; + * @throws \Civi\Core\Exception\DBQueryException + * @throws \CRM_Core_Exception + */ + public function fetchProducts(): array { + // Establish connection, if not already connected + if (!$this->twingleApi->isConnected) { + $this->twingleApi->connect(); + } + + // Fetch products from Twingle API + $products_from_twingle = $this->twingleApi->get( + 'project', + $this->numerical_project_id, + 'products', + ); + + // Fetch products from database + if ($this->id) { + $products_from_db = $this->getProducts(); + + $products_from_twingle = array_reduce($products_from_twingle, function($carry, $product) { + $carry[$product['id']] = $product; + return $carry; + }, []); + + foreach ($products_from_db as $product) { + /* @var TwingleProductBAO $product */ + + // Find orphaned products which are in the database but not in Twingle + $found = array_key_exists($product->external_id, $products_from_twingle); + if (!$found) { + $product->is_orphaned = TRUE; + } + else { + // Complement with data from Twingle + $product->complementWithDataFromTwingle($products_from_twingle[$product->external_id]); + // Mark outdated products which have a newer version in Twingle + $product->checkOutdated($products_from_twingle[$product->external_id]); + } + $this->products[] = $product; + } + } + + // Create array with external_id as key + $products = array_reduce($this->products ?? [], function($carry, $product) { + $carry[$product->external_id] = $product; + return $carry; + }, []); + + // Add new products from Twingle + foreach ($products_from_twingle as $product_from_twingle) { + $found = array_key_exists($product_from_twingle['id'], $products); + if (!$found) { + $product = new TwingleProduct(); + $product->load(TwingleProduct::renameTwingleAttrs($product_from_twingle)); + $product->twingle_shop_id = $this->id; + $this->products[] = $product; + } + } + return $this->products; + } + + /** + * Get associated products. + * + * @return array[Civi\Twingle\Shop\BAO\TwingleProduct] + * @throws \Civi\Core\Exception\DBQueryException + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + public function getProducts() { + $products = []; + + $result = TwingleProductBAO::executeQuery( + "SELECT * FROM civicrm_twingle_product WHERE twingle_shop_id = %1", + [1 => [$this->id, 'Integer']] + ); + + while ($result->fetch()) { + $product = new TwingleProductBAO(); + $product->load($result->toArray()); + $products[] = $product; + } + + return $products; + } + + /** + * Creates Twingle Shop as a price set in CiviCRM. + * + * @param string $mode + * 'create' or 'edit' + * @throws \Civi\Twingle\Shop\Exceptions\ShopException + */ + public function createPriceSet($mode = 'create') { + + // Define mode + $mode = $this->price_set_id ? 'edit' : 'create'; + + // Check if PriceSet for this Shop already exists + try { + $price_set = civicrm_api3('PriceSet', 'get', [ + 'name' => $this->project_identifier, + ]); + if ($price_set['count'] > 0 && $mode == 'create') { + throw new ShopException( + E::ts('PriceSet for this Twingle Shop already exists.'), + ShopException::ERROR_CODE_PRICE_SET_ALREADY_EXISTS, + ); + } + elseif ($price_set['count'] == 0 && $mode == 'edit') { + throw new ShopException( + E::ts('PriceSet for this Twingle Shop does not exist and cannot be edited.'), + ShopException::ERROR_CODE_PRICE_SET_NOT_FOUND, + ); + } + } catch (\CRM_Core_Exception $e) { + throw new ShopException( + E::ts('Could not check if PriceSet for this TwingleShop already exists.'), + ShopException::ERROR_CODE_PRICE_SET_NOT_FOUND, + ); + } + + // Create PriceSet + $price_set_data = [ + 'name' => $this->project_identifier, + 'title' => "$this->name ($this->project_identifier)", + 'is_active' => 1, + 'extends' => 2, + 'financial_type_id' => $this->financial_type_id, + ]; + // Set id if in edit mode + if ($mode == 'edit') { + $price_set_data['id'] = $this->price_set_id; + } + try { + $price_set = civicrm_api4('PriceSet', 'create', + ['values' => $price_set_data])->first(); + $this->price_set_id = (int) $price_set['id']; + } catch (\CRM_Core_Exception $e) { + throw new ShopException( + E::ts('Could not create PriceSet for this TwingleShop.'), + ShopException::ERROR_CODE_COULD_NOT_CREATE_PRICE_SET, + ); + } + } + + /** + * Retrieves the numerical project ID and the name of this shop from Twingle. + * + * @throws \Civi\Twingle\Shop\Exceptions\ShopException + * @throws \Civi\Twingle\Shop\Exceptions\ApiCallError + */ + private function fetchDataFromTwingle() { + + // Establish connection, if not already connected + if (!$this->twingleApi->isConnected) { + $this->twingleApi->connect(); + } + + // Get shops from Twingle if not cached + $shops = \Civi::cache('long')->get('twingle_shops'); + if (empty($shops)) { + $this::fetchShops($this->twingleApi); + $shops = \Civi::cache('long')->get('twingle_shops'); + } + + // Set Shop ID and name + foreach ($shops as $shop) { + if (isset($shop['identifier']) && $shop['identifier'] == $this->project_identifier) { + $this->numerical_project_id = $shop['id']; + $this->name = $shop['name']; + } + } + + // Throw an Exception if this Twingle Project is not of type 'shop' + if (!isset($this->numerical_project_id)) { + throw new ShopException( + E::ts('This Twingle Project is not a shop.'), + ShopException::ERROR_CODE_NOT_A_SHOP, + ); + } + } + + /** + * Retrieves all Twingle projects of the type 'shop'. + * + * @throws \Civi\Twingle\Shop\Exceptions\ShopException + */ + static private function fetchShops(ApiCall $api): void { + $organisationId = $api->organisationId; + try { + $projects = $api->get( + 'project', + NULL, + 'by-organisation', + $organisationId, + ); + $shops = array_filter( + $projects, + function($project) { + return isset($project['type']) && $project['type'] == 'shop'; + } + ); + \Civi::cache('long')->set('twingle_shops', $shops); + } + catch (Exception $e) { + throw new ShopException( + E::ts('Could not retrieve Twingle projects from API. + Please check your API credentials.'), + ShopException::ERROR_CODE_COULD_NOT_GET_PROJECTS, + ); + } + } + + /** + * Deletes all associated products. + * + * @return void + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + */ + public function deleteProducts() { + try { + $products = $this->getProducts(); + } catch (\Civi\Core\Exception\DBQueryException $e) { + throw new ProductException( + E::ts('Could not retrieve associated products: ' . $e->getMessage()), + ProductException::ERROR_CODE_COULD_NOT_GET_PRODUCTS + ); + } + try { + foreach ($products as $product) { + $product->delete(); + } + } + catch (ProductException $e) { + throw new ProductException( + E::ts('Could not delete associated products: ' . $e->getMessage()), + ProductException::ERROR_CODE_COULD_NOT_DELETE_PRICE_SET + ); + } + } + +} diff --git a/Civi/Twingle/Shop/DAO/TwingleProduct.php b/Civi/Twingle/Shop/DAO/TwingleProduct.php new file mode 100644 index 0000000..9d4f075 --- /dev/null +++ b/Civi/Twingle/Shop/DAO/TwingleProduct.php @@ -0,0 +1,327 @@ +__table = 'civicrm_twingle_product'; + parent::__construct(); + } + + /** + * Returns localized title of this entity. + * + * @param bool $plural + * Whether to return the plural version of the title. + */ + public static function getEntityTitle($plural = FALSE) { + return $plural ? E::ts('Twingle Products') : E::ts('Twingle Product'); + } + + /** + * Returns foreign keys and entity references. + * + * @return array + * [CRM_Core_Reference_Interface] + */ + public static function getReferenceColumns() { + if (!isset(\Civi::$statics[__CLASS__]['links'])) { + \Civi::$statics[__CLASS__]['links'] = static::createReferenceColumns(__CLASS__); + \Civi::$statics[__CLASS__]['links'][] = new \CRM_Core_Reference_Basic(self::getTableName(), 'price_field_id', 'civicrm_contact', 'id'); + \Civi::$statics[__CLASS__]['links'][] = new \CRM_Core_Reference_Basic(self::getTableName(), 'twingle_shop_id', 'civicrm_twingle_shop', 'id'); + \CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', \Civi::$statics[__CLASS__]['links']); + } + return \Civi::$statics[__CLASS__]['links']; + } + + /** + * Returns all the column names of this table + * + * @return array + */ + public static function &fields() { + if (!isset(\Civi::$statics[__CLASS__]['fields'])) { + \Civi::$statics[__CLASS__]['fields'] = [ + 'id' => [ + 'name' => 'id', + 'type' => \CRM_Utils_Type::T_INT, + 'title' => E::ts('ID'), + 'description' => E::ts('Unique TwingleProduct ID'), + 'required' => TRUE, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_product.id', + 'table_name' => 'civicrm_twingle_product', + 'entity' => 'TwingleProduct', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'localizable' => 0, + 'html' => [ + 'type' => 'Number', + ], + 'readonly' => TRUE, + 'add' => NULL, + ], + 'external_id' => [ + 'name' => 'external_id', + 'type' => \CRM_Utils_Type::T_INT, + 'title' => E::ts('External ID'), + 'description' => E::ts('The ID of this product in the Twingle database'), + 'required' => TRUE, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_product.external_id', + 'table_name' => 'civicrm_twingle_product', + 'entity' => 'TwingleProduct', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'localizable' => 0, + 'html' => [ + 'type' => 'Number', + ], + 'add' => NULL, + ], + 'price_field_id' => [ + 'name' => 'price_field_id', + 'type' => \CRM_Utils_Type::T_INT, + 'title' => E::ts('Price Field ID'), + 'description' => E::ts('FK to Price Field'), + 'required' => TRUE, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_product.price_field_id', + 'table_name' => 'civicrm_twingle_product', + 'entity' => 'TwingleProduct', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'localizable' => 0, + 'FKClassName' => 'CRM_Contact_DAO_Contact', + 'add' => NULL, + ], + 'twingle_shop_id' => [ + 'name' => 'twingle_shop_id', + 'type' => \CRM_Utils_Type::T_INT, + 'title' => E::ts('Twingle Shop ID'), + 'description' => E::ts('FK to Twingle Shop'), + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_product.twingle_shop_id', + 'table_name' => 'civicrm_twingle_product', + 'entity' => 'TwingleProduct', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'localizable' => 0, + 'FKClassName' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'add' => NULL, + ], + 'created_at' => [ + 'name' => 'created_at', + 'type' => \CRM_Utils_Type::T_DATE + \CRM_Utils_Type::T_TIME, + 'title' => E::ts('Created At'), + 'description' => E::ts('Timestamp of when the product was created in the database'), + 'required' => TRUE, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_product.created_at', + 'table_name' => 'civicrm_twingle_product', + 'entity' => 'TwingleProduct', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'localizable' => 0, + 'add' => NULL, + ], + 'updated_at' => [ + 'name' => 'updated_at', + 'type' => \CRM_Utils_Type::T_DATE + \CRM_Utils_Type::T_TIME, + 'title' => E::ts('Updated At'), + 'description' => E::ts('Timestamp of when the product was last updated in the database'), + 'required' => TRUE, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_product.updated_at', + 'table_name' => 'civicrm_twingle_product', + 'entity' => 'TwingleProduct', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'localizable' => 0, + 'add' => NULL, + ], + ]; + \CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', \Civi::$statics[__CLASS__]['fields']); + } + return \Civi::$statics[__CLASS__]['fields']; + } + + /** + * Return a mapping from field-name to the corresponding key (as used in fields()). + * + * @return array + * Array(string $name => string $uniqueName). + */ + public static function &fieldKeys() { + if (!isset(\Civi::$statics[__CLASS__]['fieldKeys'])) { + \Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(\CRM_Utils_Array::collect('name', self::fields())); + } + return \Civi::$statics[__CLASS__]['fieldKeys']; + } + + /** + * Returns the names of this table + * + * @return string + */ + public static function getTableName() { + return self::$_tableName; + } + + /** + * Returns if this table needs to be logged + * + * @return bool + */ + public function getLog() { + return self::$_log; + } + + /** + * Returns the list of fields that can be imported + * + * @param bool $prefix + * + * @return array + */ + public static function &import($prefix = FALSE) { + $r = \CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'twingle_product', $prefix, []); + return $r; + } + + /** + * Returns the list of fields that can be exported + * + * @param bool $prefix + * + * @return array + */ + public static function &export($prefix = FALSE) { + $r = \CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'twingle_product', $prefix, []); + return $r; + } + + /** + * Returns the list of indices + * + * @param bool $localize + * + * @return array + */ + public static function indices($localize = TRUE) { + $indices = []; + return ($localize && !empty($indices)) ? \CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices; + } + +} diff --git a/Civi/Twingle/Shop/DAO/TwingleShop.php b/Civi/Twingle/Shop/DAO/TwingleShop.php new file mode 100644 index 0000000..bef6db7 --- /dev/null +++ b/Civi/Twingle/Shop/DAO/TwingleShop.php @@ -0,0 +1,307 @@ +__table = 'civicrm_twingle_shop'; + parent::__construct(); + } + + /** + * Returns localized title of this entity. + * + * @param bool $plural + * Whether to return the plural version of the title. + */ + public static function getEntityTitle($plural = FALSE) { + return $plural ? E::ts('Twingle Shops') : E::ts('Twingle Shop'); + } + + /** + * Returns foreign keys and entity references. + * + * @return array + * [CRM_Core_Reference_Interface] + */ + public static function getReferenceColumns() { + if (!isset(\Civi::$statics[__CLASS__]['links'])) { + \Civi::$statics[__CLASS__]['links'] = static::createReferenceColumns(__CLASS__); + \Civi::$statics[__CLASS__]['links'][] = new \CRM_Core_Reference_Basic(self::getTableName(), 'price_set_id', 'civicrm_price_set', 'id'); + \CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', \Civi::$statics[__CLASS__]['links']); + } + return \Civi::$statics[__CLASS__]['links']; + } + + /** + * Returns all the column names of this table + * + * @return array + */ + public static function &fields() { + if (!isset(\Civi::$statics[__CLASS__]['fields'])) { + \Civi::$statics[__CLASS__]['fields'] = [ + 'id' => [ + 'name' => 'id', + 'type' => \CRM_Utils_Type::T_INT, + 'title' => E::ts('ID'), + 'description' => E::ts('Unique TwingleShop ID'), + 'required' => TRUE, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_shop.id', + 'table_name' => 'civicrm_twingle_shop', + 'entity' => 'TwingleShop', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'localizable' => 0, + 'html' => [ + 'type' => 'Number', + ], + 'readonly' => TRUE, + 'add' => NULL, + ], + 'project_identifier' => [ + 'name' => 'project_identifier', + 'type' => \CRM_Utils_Type::T_STRING, + 'title' => E::ts('Project Identifier'), + 'description' => E::ts('Twingle Project Identifier'), + 'required' => TRUE, + 'maxlength' => 32, + 'size' => \CRM_Utils_Type::MEDIUM, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_shop.project_identifier', + 'table_name' => 'civicrm_twingle_shop', + 'entity' => 'TwingleShop', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], + 'add' => NULL, + ], + 'numerical_project_id' => [ + 'name' => 'numerical_project_id', + 'type' => \CRM_Utils_Type::T_INT, + 'title' => E::ts('Numerical Project ID'), + 'description' => E::ts('Numerical Twingle Project Identifier'), + 'required' => TRUE, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_shop.numerical_project_id', + 'table_name' => 'civicrm_twingle_shop', + 'entity' => 'TwingleShop', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'localizable' => 0, + 'html' => [ + 'type' => 'Number', + ], + 'add' => NULL, + ], + 'price_set_id' => [ + 'name' => 'price_set_id', + 'type' => \CRM_Utils_Type::T_INT, + 'title' => E::ts('Price Set ID'), + 'description' => E::ts('FK to Price Set'), + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_shop.price_set_id', + 'table_name' => 'civicrm_twingle_shop', + 'entity' => 'TwingleShop', + 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'localizable' => 0, + 'FKClassName' => 'CRM_Price_DAO_PriceSet', + 'add' => NULL, + ], + 'name' => [ + 'name' => 'name', + 'type' => \CRM_Utils_Type::T_STRING, + 'title' => E::ts('Name'), + 'description' => E::ts('name of the shop'), + 'required' => TRUE, + 'maxlength' => 64, + 'size' => \CRM_Utils_Type::BIG, + 'usage' => [ + 'import' => FALSE, + 'export' => FALSE, + 'duplicate_matching' => FALSE, + 'token' => FALSE, + ], + 'where' => 'civicrm_twingle_shop.name', + 'table_name' => 'civicrm_twingle_shop', + 'entity' => 'TwingleShop', + 'bao' => 'CRM_Twingle_Shop_DAO_TwingleShop', + 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], + 'add' => NULL, + ], + ]; + \CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', \Civi::$statics[__CLASS__]['fields']); + } + return \Civi::$statics[__CLASS__]['fields']; + } + + /** + * Return a mapping from field-name to the corresponding key (as used in fields()). + * + * @return array + * Array(string $name => string $uniqueName). + */ + public static function &fieldKeys() { + if (!isset(\Civi::$statics[__CLASS__]['fieldKeys'])) { + \Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(\CRM_Utils_Array::collect('name', self::fields())); + } + return \Civi::$statics[__CLASS__]['fieldKeys']; + } + + /** + * Returns the names of this table + * + * @return string + */ + public static function getTableName() { + return self::$_tableName; + } + + /** + * Returns if this table needs to be logged + * + * @return bool + */ + public function getLog() { + return self::$_log; + } + + /** + * Returns the list of fields that can be imported + * + * @param bool $prefix + * + * @return array + */ + public static function &import($prefix = FALSE) { + $r = \CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'twingle_shop', $prefix, []); + return $r; + } + + /** + * Returns the list of fields that can be exported + * + * @param bool $prefix + * + * @return array + */ + public static function &export($prefix = FALSE) { + $r = \CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'twingle_shop', $prefix, []); + return $r; + } + + /** + * Returns the list of indices + * + * @param bool $localize + * + * @return array + */ + public static function indices($localize = TRUE) { + $indices = []; + return ($localize && !empty($indices)) ? \CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices; + } + +} diff --git a/Civi/Twingle/Shop/Exceptions/ApiCallError.php b/Civi/Twingle/Shop/Exceptions/ApiCallError.php new file mode 100644 index 0000000..7d611ca --- /dev/null +++ b/Civi/Twingle/Shop/Exceptions/ApiCallError.php @@ -0,0 +1,19 @@ + $value) { + // Skip empty values + if (empty($value)) { + continue; + } + + // Find expected data type + $expected_data_type = strtolower(\CRM_Utils_Type::typeToString($allowed_attributes[$key])); // It could be so easy... + + // Validate data type + if (!\CRM_Utils_Type::validatePhpType($value, $expected_data_type)) { + $given_type = gettype($value); + throw new \Exception( + "Data type of attribute '$key' is $given_type, but $expected_data_type was expected." + ); + } + } +} + diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index be27fc8..17cb107 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -254,7 +254,14 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { 'title' => E::ts('Custom fields'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'), + 'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'), + ); + $params['products'] = [ + 'name' => 'products', + 'title' => E::ts('Products'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('Products ordered via TwingleShop'), ]; $params['remarks'] = [ 'name' => 'remarks', @@ -634,6 +641,11 @@ function civicrm_api3_twingle_donation_Submit($params) { 'total_amount' => $params['amount'] / 100, ]; + // If the submission contains products, do not auto-create a line item + if (!empty($params['products']) && $profile->isShopEnabled()) { + $contribution_data['skipLineItem'] = 1; + } + // Add custom field values. if (isset($custom_fields['Contribution'])) { $contribution_data += $custom_fields['Contribution']; @@ -727,6 +739,27 @@ function civicrm_api3_twingle_donation_Submit($params) { $mandate = civicrm_api3('SepaMandate', 'createfull', $mandate_data); $result_values['sepa_mandate'] = reset($mandate['values']); + + // Add contribution data to result_values for later use + $contribution_id = $result_values['sepa_mandate']['entity_id']; + if ($contribution_id) { + $contribution = civicrm_api3( + 'Contribution', + 'getsingle', + ['id' => $contribution_id] + ); + $result_values['contribution'] = $contribution; + } else { + $mandate_id = $result_values['sepa_mandate']['id']; + $message = E::LONG_NAME . ": could not find contribution for sepa mandate $mandate_id"; + throw new CiviCRM_API3_Exception($message, 'api_error'); + } + + // Add products as line items to the contribution + if (!empty($params['products']) && $profile->isShopEnabled()) { + $line_items = CRM_Twingle_Submission::createLineItems($result_values, $params, $profile); + $result_values['contribution']['line_items'] = $line_items; + } } else { // Set financial type depending on donation rhythm. This applies for @@ -827,6 +860,12 @@ function civicrm_api3_twingle_donation_Submit($params) { } $result_values['contribution'] = $contribution; + + // Add products as line items to the contribution + if (!empty($params['products']) && $profile->isShopEnabled()) { + $line_items = CRM_Twingle_Submission::createLineItems($result_values, $params, $profile); + $result_values['contribution']['line_items'] = $line_items; + } } // MEMBERSHIP CREATION diff --git a/api/v3/TwingleProduct/Create.php b/api/v3/TwingleProduct/Create.php new file mode 100644 index 0000000..36bb48a --- /dev/null +++ b/api/v3/TwingleProduct/Create.php @@ -0,0 +1,138 @@ + 'id', + 'title' => E::ts('TwingleProduct ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('The TwingleProduct ID in the database'), + ]; + $spec['external_id'] = [ + 'name' => 'external_id', + 'title' => E::ts('Twingle ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + 'description' => E::ts('External product ID in Twingle database'), + ]; + $spec['project_id'] = [ + 'name' => 'project_id', + 'title' => E::ts('Twingle Shop ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + 'description' => E::ts('ID of the corresponding Twingle Shop'), + ]; + $spec['name'] = [ + 'name' => 'name', + 'title' => E::ts('Product Name'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + 'description' => E::ts('Name of the product'), + ]; + $spec['is_active'] = [ + 'name' => 'is_active', + 'title' => E::ts('Is active?'), + 'type' => CRM_Utils_Type::T_BOOLEAN, + 'api.required' => 0, + 'api.default' => 1, + 'description' => E::ts('Is the product active?'), + ]; + $spec['description'] = [ + 'name' => 'description', + 'title' => E::ts('Product Description'), + 'type' => CRM_Utils_Type::T_TEXT, + 'api.required' => 0, + 'description' => E::ts('Short description of the product'), + ]; + $spec['price'] = [ + 'name' => 'price', + 'title' => E::ts('Product Price'), + 'type' => CRM_Utils_Type::T_FLOAT, + 'api.required' => 0, + 'description' => E::ts('Price of the product'), + ]; + $spec['sort'] = [ + 'name' => 'sort', + 'title' => E::ts('Sort'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('Sort order of the product'), + ]; + $spec['financial_type_id'] = [ + 'name' => 'financial_type_id', + 'title' => E::ts('Financial Type ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + 'description' => E::ts('ID of the financial type of the product'), + ]; + $spec['twingle_shop_id'] = [ + 'name' => 'twingle_shop_id', + 'title' => E::ts('FK to TwingleShop'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + 'description' => E::ts('FK to TwingleShop'), + ]; + $spec['tw_updated_at'] = [ + 'name' => 'tw_updated_at', + 'title' => E::ts('Twingle timestamp'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + 'description' => E::ts('Timestamp of last update in Twingle db'), + ]; + $spec['price_field_id'] = [ + 'name' => 'price_field_id', + 'title' => E::ts('FK to PriceField'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('FK to PriceField'), + ]; +} + +/** + * TwingleProduct.Create API + * + * @param array $params + * + * @return array + * API result descriptor + * + * @see civicrm_api3_create_success + * + * @throws API_Exception + * @throws \Exception + */ +function civicrm_api3_twingle_product_Create($params): array { + // Filter for allowed params + $allowed_params = []; + _civicrm_api3_twingle_product_Create_spec($allowed_params); + $params = array_intersect_key($params, $allowed_params); + + try { + // Create TwingleProduct and load params + $product = new TwingleProduct(); + $product->load($params); + + // Save TwingleProduct + $product->add(); + $result = $product->getAttributes(); + return civicrm_api3_create_success($result, $params, 'TwingleProduct', 'Create'); + } + catch (ProductException $e) { + return civicrm_api3_create_error($e->getMessage(), [ + 'error_code' => $e->getCode(), + 'params' => $params, + ]); + } +} diff --git a/api/v3/TwingleProduct/Delete.php b/api/v3/TwingleProduct/Delete.php new file mode 100644 index 0000000..60c9591 --- /dev/null +++ b/api/v3/TwingleProduct/Delete.php @@ -0,0 +1,72 @@ + 'id', + 'title' => E::ts('TwingleProduct ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('The TwingleProduct ID in CiviCRM'), + ]; + $spec['external_id'] = [ + 'name' => 'external_id', + 'title' => E::ts('External TwingleProduct ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('Twingle\'s ID of the product'), + ]; +} + +/** + * TwingleProduct.Delete API + * + * @param array $params + * + * @return array + * API result descriptor + * + * @throws API_Exception*@throws \Exception + * @throws \Exception + * @see civicrm_api3_create_success + * + */ +function civicrm_api3_twingle_product_Delete($params) { + // Filter for allowed params + $allowed_params = []; + _civicrm_api3_twingle_product_Delete_spec($allowed_params); + $params = array_intersect_key($params, $allowed_params); + + // Find TwingleProduct via getsingle API + $product_data = civicrm_api3('TwingleProduct', 'getsingle', $params); + if ($product_data['is_error']) { + return civicrm_api3_create_error($product_data['error_message'], + ['error_code' => $product_data['error_code'], 'params' => $params] + ); + } + + // Get TwingleProduct object + $product = TwingleProduct::findById($product_data['id']); + + // Delete TwingleProduct and associated PriceField and PriceFieldValue + $result = $product->delete(); + if ($result) { + return civicrm_api3_create_success(1, $params, 'TwingleProduct', 'Delete'); + } + else { + return civicrm_api3_create_error( + E::ts('TwingleProduct could not be deleted.'), + ['error_code' => 'delete_failed', 'params' => $params] + ); + } +} diff --git a/api/v3/TwingleProduct/Get.php b/api/v3/TwingleProduct/Get.php new file mode 100644 index 0000000..a7f64ca --- /dev/null +++ b/api/v3/TwingleProduct/Get.php @@ -0,0 +1,137 @@ + 'id', + 'title' => E::ts('TwingleProduct ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('The TwingleProduct ID in CiviCRM'), + ]; + $spec['external_id'] = [ + 'name' => 'external_id', + 'title' => E::ts('External TwingleProduct ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('Twingle\'s ID of the product'), + ]; + $spec['price_field_id'] = [ + 'name' => 'Price Field ID', + 'title' => E::ts('Price Field ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('FK to civicrm_price_field'), + ]; + $spec['twingle_shop_id'] = [ + 'name' => 'twingle_shop_id', + 'title' => E::ts('TwingleShop ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('The TwingleShop ID in CiviCRM'), + ]; + $spec['project_identifier'] = [ + 'name' => 'project_identifier', + 'title' => E::ts('Project Identifier'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('Twingle project identifier'), + ]; + $spec['numerical_project_id'] = [ + 'name' => 'numerical_project_id', + 'title' => E::ts('Numerical Project Identifier'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('Twingle numerical project identifier'), + ]; +} + +/** + * TwingleProduct.Get API + * + * @param array $params + * + * @return array + * API result descriptor + * + * @throws API_Exception + * @see civicrm_api3_create_success + * + */ +function civicrm_api3_twingle_product_Get($params) { + // Filter for allowed params + $allowed_params = []; + _civicrm_api3_twingle_product_Get_spec($allowed_params); + $params = array_intersect_key($params, $allowed_params); + + // Build query + $query = 'SELECT ctp.* FROM civicrm_twingle_product ctp + INNER JOIN civicrm_twingle_shop cts ON ctp.twingle_shop_id = cts.id'; + $query_params = []; + + if (!empty($params)) { + $query = $query . ' WHERE'; + $possible_params = []; + _civicrm_api3_twingle_product_Get_spec($possible_params); + $param_count = 1; + $altered_params = []; + + // Specify product fields to define table prefix + $productFields = array_keys(TwingleProduct::fields()); + + // Alter params (prefix with table name) + foreach ($possible_params as $param) { + if (!empty($params[$param['name']])) { + // Prefix with table name + $table_prefix = in_array($param['name'], $productFields) ? 'ctp.' : 'cts.'; + $altered_params[] = [ + 'name' => $table_prefix . $param['name'], + 'value' => $params[$param['name']], + 'type' => $param['type'], + ]; + } + } + + // Add altered params to query + foreach ($altered_params as $param) { + $query = $query . ' ' . $param['name'] . " = %$param_count AND"; + $query_params[$param_count] = [ + $param['value'], + $param['type'] == CRM_Utils_Type::T_INT ? 'Integer' : 'String', + ]; + $param_count++; + } + } + + // Cut away last 'AND' + $query = substr($query, 0, -4); + + // Execute query + try { + $dao = TwingleProduct::executeQuery($query, $query_params); + } + catch (Exception $e) { + return civicrm_api3_create_error($e->getMessage(), [ + 'error_code' => $e->getCode(), + 'params' => $params, + ]); + } + + // Prepare return values + $returnValues = []; + while ($dao->fetch()) { + $returnValues[] = $dao->toArray(); + } + + return civicrm_api3_create_success($returnValues, $params, 'TwingleProduct', 'Get'); +} diff --git a/api/v3/TwingleProduct/Getsingle.php b/api/v3/TwingleProduct/Getsingle.php new file mode 100644 index 0000000..06eb88a --- /dev/null +++ b/api/v3/TwingleProduct/Getsingle.php @@ -0,0 +1,54 @@ + 'missing_parameter', 'params' => $params] + ); + } + + // Find TwingleProduct via get API + $returnValues = civicrm_api3('TwingleProduct', 'get', $params); + $count = $returnValues['count']; + + // Check whether only a single TwingleProduct is found + if ($count != 1) { + return civicrm_api3_create_error( + "Expected one TwingleProduct but found $count", + ['error_code' => 'not_found', 'params' => $params] + ); + } + return $returnValues['values'][$returnValues['id']]; +} diff --git a/api/v3/TwingleShop/Create.php b/api/v3/TwingleShop/Create.php new file mode 100644 index 0000000..ebb34f4 --- /dev/null +++ b/api/v3/TwingleShop/Create.php @@ -0,0 +1,80 @@ + 'project_identifier', + 'title' => E::ts('Project Identifier'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + 'description' => E::ts('Twingle project identifier'), + ]; + $spec['numerical_project_id'] = [ + 'name' => 'numerical_project_id', + 'title' => E::ts('Numerical Project Identifier'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + 'description' => E::ts('Numerical Twingle project identifier'), + ]; + $spec['name'] = [ + 'name' => 'name', + 'title' => E::ts('Shop Name'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + 'description' => E::ts('Name of the shop'), + ]; + $spec['financial_type_id'] = [ + 'name' => 'financial_type_id', + 'title' => E::ts('Financial Type ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + 'description' => E::ts('FK to civicrm_financial_type'), + ]; +} + +/** + * TwingleShop.Create API + * + * @param array $params + * + * @return array + * API result descriptor + * + * @see civicrm_api3_create_success + * + * @throws API_Exception + */ +function civicrm_api3_twingle_shop_Create($params) { + // Filter for allowed params + $allowed_params = []; + _civicrm_api3_twingle_shop_Create_spec($allowed_params); + $params = array_intersect_key($params, $allowed_params); + + try { + // Create TwingleShop and load params + $shop = new TwingleShop(); + $shop->load($params); + + // Save TwingleShop + $result = $shop->add(); + + // Return success + return civicrm_api3_create_success($result, $params, 'TwingleShop', 'Create'); + } + catch (ShopException $e) { + return civicrm_api3_create_error($e->getMessage(), [ + 'error_code' => $e->getErrorCode(), + 'params' => $params, + ]); + } +} diff --git a/api/v3/TwingleShop/Delete.php b/api/v3/TwingleShop/Delete.php new file mode 100644 index 0000000..d1f3323 --- /dev/null +++ b/api/v3/TwingleShop/Delete.php @@ -0,0 +1,79 @@ + 'id', + 'title' => E::ts('TwingleShop ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('The TwingleShop ID in CiviCRM'), + ]; + $spec['project_identifier'] = [ + 'name' => 'project_identifier', + 'title' => E::ts('Project Identifier'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('Twingle project identifier'), + ]; +} + +/** + * TwingleShop.Delete API + * + * @param array $params + * + * @return array + * API result descriptor + * + * @throws \API_Exception + * @throws \Civi\Twingle\Shop\Exceptions\ShopException + * @throws \Exception + * @see civicrm_api3_create_success + * + */ +function civicrm_api3_twingle_shop_Delete($params) { + // Filter for allowed params + $allowed_params = []; + _civicrm_api3_twingle_shop_Delete_spec($allowed_params); + $params = array_intersect_key($params, $allowed_params); + + // Find TwingleShop via getsingle API + $shop_data = civicrm_api3('TwingleShop', 'getsingle', $params); + if ($shop_data['is_error']) { + return civicrm_api3_create_error($shop_data['error_message'], + ['error_code' => $shop_data['error_code'], 'params' => $params] + ); + } + + // Get TwingleShop object + $shop = TwingleShop::findById($shop_data['id']); + + // Delete TwingleShop + /* @var \Civi\Twingle\Shop\BAO\TwingleShop $shop */ + $result = $shop->deleteByConstraint(); + if ($result) { + return civicrm_api3_create_success(1, $params, 'TwingleShop', 'Delete'); + } + elseif ($result === 0) { + return civicrm_api3_create_error( + E::ts('TwingleShop could not be found.'), + ['error_code' => 'not_found', 'params' => $params] + ); + } + else { + return civicrm_api3_create_error( + E::ts('TwingleShop could not be deleted.'), + ['error_code' => 'delete_failed', 'params' => $params] + ); + } +} diff --git a/api/v3/TwingleShop/Fetch.php b/api/v3/TwingleShop/Fetch.php new file mode 100644 index 0000000..961f42b --- /dev/null +++ b/api/v3/TwingleShop/Fetch.php @@ -0,0 +1,97 @@ + 'project_identifiers', + 'title' => E::ts('Project Identifiers'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + 'description' => E::ts('Comma separated list of Twingle project identifiers.'), + ]; +} + +/** + * TwingleShop.Fetch API + * + * @param array $params + * + * @return array + * API result descriptor + * + * @see civicrm_api3_create_success + * + * @throws API_Exception + */ +function civicrm_api3_twingle_shop_Fetch($params) { + // Filter for allowed params + $allowed_params = []; + _civicrm_api3_twingle_shop_Fetch_spec($allowed_params); + $params = array_intersect_key($params, $allowed_params); + + $returnValues = []; + + // Explode string with project IDs and trim + $projectIds = array_map( + function ($projectId) { + return trim($projectId); + }, + explode(',', $params['project_identifiers']) + ); + + // Get products for all projects of type 'shop' + foreach ($projectIds as $projectId) { + try { + $shop = TwingleShop::findByProjectIdentifier($projectId); + $products = $shop->fetchProducts(); + $returnValues[$projectId] = []; + $returnValues[$projectId] += $shop->getAttributes(); + $returnValues[$projectId]['products'] = array_map(function ($product) { + return $product->getAttributes(); + }, $products); + } + catch (ShopException|ApiCallError|ProductException $e) { + // If this project identifier doesn't belong to a project of type + // 'shop', just skip it + if ($e->getErrorCode() == ShopException::ERROR_CODE_NOT_A_SHOP) { + $returnValues[$projectId] = "project is not of type 'shop'"; + continue; + } + // Else, log error and throw exception + else { + Civi::log()->error( + $e->getMessage(), + [ + 'project_identifier' => $projectId, + 'params' => $params, + ] + ); + return civicrm_api3_create_error($e->getMessage(), [ + 'error_code' => $e->getErrorCode(), + 'project_identifier' => $projectId, + 'params' => $params, + ]); + } + } + } + + return civicrm_api3_create_success( + $returnValues, + $params, + 'TwingleShop', + 'Fetch' + ); +} diff --git a/api/v3/TwingleShop/Get.php b/api/v3/TwingleShop/Get.php new file mode 100644 index 0000000..2915212 --- /dev/null +++ b/api/v3/TwingleShop/Get.php @@ -0,0 +1,111 @@ + 'id', + 'title' => E::ts('TwingleShop ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('The TwingleShop ID in CiviCRM'), + ]; + $spec['project_identifier'] = [ + 'name' => 'project_identifier', + 'title' => E::ts('Project Identifier'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('Twingle project identifier'), + ]; + $spec['numerical_project_id'] = [ + 'name' => 'numerical_project_id', + 'title' => E::ts('Numerical Project Identifier'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('Twingle numerical project identifier'), + ]; + $spec['name'] = [ + 'name' => 'name', + 'title' => E::ts('Name'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('Name of the TwingleShop'), + ]; + $spec['price_set_id'] = [ + 'name' => 'price_set_id', + 'title' => E::ts('Price Set ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('FK to civicrm_price_set'), + ]; +} + +/** + * TwingleShop.Get API + * + * @param array $params + * + * @return array + * API result descriptor + * + * @see civicrm_api3_create_success + * + * @throws API_Exception + */ +function civicrm_api3_twingle_shop_Get($params) { + // Filter for allowed params + $allowed_params = []; + _civicrm_api3_twingle_shop_Get_spec($allowed_params); + $params = array_intersect_key($params, $allowed_params); + + // Build query + $query = 'SELECT * FROM civicrm_twingle_shop'; + $query_params = []; + + if (!empty($params)) { + $query = $query . ' WHERE'; + $possible_params = []; + _civicrm_api3_twingle_shop_Get_spec($possible_params); + $param_count = 1; + + foreach ($possible_params as $param) { + if (!empty($params[$param['name']])) { + $query = $query . ' ' . $param['name'] . " = %$param_count AND"; + $query_params[$param_count] = [ + $params[$param['name']], + $param['type'] == CRM_Utils_Type::T_INT ? 'Integer' : 'String' + ]; + $param_count++; + } + } + // Cut away last 'AND' + $query = substr($query, 0, -4); + } + + // Execute query + try { + $dao = TwingleShop::executeQuery($query, $query_params); + } + catch (\Exception $e) { + return civicrm_api3_create_error($e->getMessage(), [ + 'error_code' => $e->getCode(), + 'params' => $params, + ]); + } + + // Prepare return values + $returnValues = []; + while ($dao->fetch()) { + $returnValues[] = $dao->toArray(); + } + + return civicrm_api3_create_success($returnValues, $params, 'TwingleShop', 'Get'); +} diff --git a/api/v3/TwingleShop/Getsingle.php b/api/v3/TwingleShop/Getsingle.php new file mode 100644 index 0000000..ff5cf86 --- /dev/null +++ b/api/v3/TwingleShop/Getsingle.php @@ -0,0 +1,54 @@ + 'missing_parameter', 'params' => $params] + ); + } + + // Find TwingleShop via get API + $returnValues = civicrm_api3('TwingleShop', 'get', $params); + $count = $returnValues['count']; + + // Check whether only a single TwingleShop is found + if ($count != 1) { + return civicrm_api3_create_error( + "Expected one TwingleShop but found $count", + ['error_code' => 'not_found', 'params' => $params] + ); + } + return $returnValues['values'][$returnValues['id']]; +} diff --git a/css/twingle_shop.css b/css/twingle_shop.css new file mode 100644 index 0000000..898001f --- /dev/null +++ b/css/twingle_shop.css @@ -0,0 +1,37 @@ +.twingle-shop-table-caption { + font-weight: bold; + font-size: 13px; + padding: 6px; + text-align: left; +} + +.twingle-shop-table-divider { + border-top: 1px solid #ddd; + margin-top: 20px; + margin-bottom: 4px; +} + +#twingle-shop-spinner { + animation: spin 2s linear infinite; +} + +.twingle-shop-table tbody tr { + height: 32px; +} + +.twingle-shop-table-button { + margin: 10px 15px 0 0 !important; +} + +.twingle-shop-cell-button { + margin: 3px 5px 3px 5px; +} + +.strikethrough { + text-decoration: line-through; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/info.xml b/info.xml index d0876c8..d715ec8 100644 --- a/info.xml +++ b/info.xml @@ -18,7 +18,7 @@ 1.5-dev dev - 5.56 + 5.58 diff --git a/js/twingle_shop.js b/js/twingle_shop.js new file mode 100644 index 0000000..fb7dd40 --- /dev/null +++ b/js/twingle_shop.js @@ -0,0 +1,741 @@ +/** + * This file contains the JavaScript code for the Twingle Shop integration. + */ + +/** + * This function initializes the Twingle Shop integration. + */ +function twingleShopInit() { + cj('#twingle-shop-spinner').hide(); + + // Run once on page load + load_financial_types(); + twingle_shop_active_changed(); + twingle_map_products_changed(); + twingle_fetch_products(); + + // Add event listeners + cj('#enable_shop_integration:checkbox').change(twingle_shop_active_changed); + cj('#shop_map_products:checkbox').change(twingle_map_products_changed); + cj('#btn_fetch_products').click(function (event) { + event.preventDefault(); // Prevent the default form submission behavior + twingle_fetch_products(); + }); +} + +// Define financial types as global variable +let financialTypes = {}; + +/** + * Load financial types from CiviCRM + */ +function load_financial_types() { + CRM.api3('FinancialType', 'get', { + 'sequential': 1, + 'options': { 'limit': 0 }, + }).then(function (result) { + financialTypes = result.values.reduce((obj, item) => { + obj[item.id] = item.name; + return obj; + }, {}); + }); +} + +/** + * Fetches the Twingle products for the given project identifiers. + */ +function twingle_fetch_products() { + let active = cj('#shop_map_products:checkbox:checked').length; + if (active) { + cj('#twingle-shop-spinner').show(); + CRM.api3('TwingleShop', 'fetch', { + 'project_identifiers': cj('#selectors :input').val(), + }).then(function (result) { + if (result.is_error === 1) { + cj('#btn_fetch_products').crmError(result.error_message, ts('Could not fetch products', [])); + cj('#twingle-shop-spinner').hide(); + return; + } + buildShopTables(result); + cj('#twingle-shop-spinner').hide(); + }, function () { + cj('#btn_fetch_products').crmError(ts('Could not fetch products. Please check your Twingle API key.', [])); + cj('#twingle-shop-spinner').hide(); + }); + } +} + +/** + * Update the form fields based on whether shop integration is currently active + */ +function twingle_shop_active_changed() { + let active = cj('#enable_shop_integration:checkbox:checked').length; + if (active) { + cj('.twingle-shop-element').show(); + } else { + cj('.twingle-shop-element').hide(); + } +} + +/** + * Display fetch button and product mapping when the corresponding option is active + */ +function twingle_map_products_changed() { + let active = cj('#shop_map_products:checkbox:checked').length; + if (active) { + cj('.twingle-product-mapping').show(); + } else { + cj('.twingle-product-mapping').hide(); + } +} + +/** + * This function builds the shop tables. + * @param shopData + */ +function buildShopTables(shopData) { + + let productTables = []; + + // Create table for each project (shop) + for (const key in shopData.values) { + productTables.push(new ProductsTable(shopData.values[key])); + } + + // Add table container to DOM + const tableContainer = document.getElementById('tableContainer'); + + // Add tables to table container + for (const productTable of productTables) { + tableContainer.appendChild(productTable.table); + } +} + +/** + * Get the value of the default financial type for the shops defined in this profile. + * @returns {string|string} + */ +function getShopDefaultFinancialType() { + const default_selection = document.getElementById('s2id_shop_financial_type'); + const selected = default_selection.getElementsByClassName('select2-chosen')[0]; + return selected ? selected.textContent : ''; +} + +/** + * Get the value of the default financial type. + * @returns {string} + */ +function getShopDefaultFinancialTypeValue() { + const shopDefaultFinancialType = getShopDefaultFinancialType(); + return Object.keys(financialTypes).find(key => financialTypes[key] === shopDefaultFinancialType); +} + +/** + * This class represents a Twingle Product. + */ +class Product { + + /** + * Creates a new Product object. + * @param productData + * @param parentTable + */ + constructor(productData, parentTable) { + this.parentTable = parentTable; + this.setProps(productData); + } + + /** + * Sets the properties of this product. + * @param productData + * @private + */ + setProps(productData) { + this.id = productData.id; + this.name = productData.name; + this.isActive = productData.is_active; + this.price = productData.price; + this.sort = productData.sort; + this.description = productData.description; + this.projectId = productData.project_id; + this.externalId = productData.external_id; + this.isOutdated = productData.is_outdated; + this.isOrphaned = productData.is_orphaned; + // this.updatedAt = productData.updated_at; + this.createdAt = productData.created_at; + this.twUpdatedAt = productData.tw_updated_at; + this.financialTypeId = productData.financial_type_id; + this.priceFieldId = productData.price_field_id; + } + + /** + * Dumps the product data. + * @returns {{id, name, is_active, price, sort, description, project_id, external_id, financial_type_id, tw_updated_at, twingle_shop_id: *}} + */ + dumpData() { + return { + 'id': this.id, + 'name': this.name, + 'is_active': this.isActive, + 'price': this.price, + 'sort': this.sort, + 'description': this.description, + 'project_id': this.projectId, + 'external_id': this.externalId, + 'financial_type_id': this.financialTypeId, + 'price_field_id': this.priceFieldId, + 'tw_updated_at': this.twUpdatedAt, + 'twingle_shop_id': this.parentTable.id, + }; + } + + /** + * Creates a button for creating, updating or deleting the price field for + * this product. + * @param action + * @param handler + * @returns {HTMLButtonElement} + * @private + */ + createProductButton(action, handler) { + // Create button + const button = document.createElement('button'); + button.id = action + '_twingle_product_tw_' + this.externalId; + button.classList.add('twingle-shop-cell-button'); + + // Add button text + let text = action === 'create' ? ts('Create', []) : action === 'update' ? ts('Update', []) : ts('Delete', []); + button.textContent = ' ' + ts(text, []); + + // Add button handler + if (handler) { + button.onclick = handler; + } else { + button.disabled = true; + } + + // Deactivate 'create' button if product hast no financial type + if (action === 'create' && this.financialTypeId === null) { + button.disabled = true; + } + + // Add icon + const icon = document.createElement('i'); + const iconClass = action === 'create' ? 'fa-plus-circle' : action === 'update' ? 'fa-refresh' : 'fa-trash'; + icon.classList.add('crm-i', iconClass); + button.insertBefore(icon, button.firstChild); + + return button; + } + + /** + * Creates a handler for creating a price field for this product. + * @returns {(function(*): void)|*} + * @private + */ + createPriceFieldHandler() { + const self = this; + return function (event) { + event.preventDefault(); + const action = event.target.innerText.includes('Update') ? 'updated' : 'created'; + CRM.api3('TwingleProduct', 'create', self.dumpData()) + .then(function (result) { + if (result.is_error === 1) { + cj('#create_twingle_product_tw_' + self.id).crmError(result.error_message, ts('Could not create Price Field for this product', [])); + } else { + self.update(result.values); + CRM.alert(ts(`The Price Field was ${action} successfully.`, []), ts(`Price Field ${action}`, []), 'success', {'expires': 5000}); + } + }, function (error) { + cj('#create_twingle_product_tw_' + self.id).crmError(error.message, ts('Could not create Price Field for this product', [])); + }); + }; + } + + /** + * Creates a handler for creating a price field for this product. + * @returns {(function(*): void)|*} + * @private + */ + deletePriceFieldHandler() { + let self = this; + return function (event) { + event.preventDefault(); + const options = { + 'title': ts('Delete Price Field', []), + 'message': ts('Are you sure you want to delete the price field associated with this product?', []), + }; + CRM.confirm(options) + .on('crmConfirm:yes', function () { + CRM.api3('TwingleProduct', 'delete', { 'id': self.id }) + .then(function (result) { + if (result.is_error === 1) { + cj('#create_twingle_product_tw_' + self.id).crmError(result.error_message, ts('Could not delete Price Field', [])); + } else { + self.update(); + } + CRM.alert(ts('The Price Field was deleted successfully.', []), ts('Price Field deleted', []), 'success', {'expires': 5000}); + }, function (error) { + cj('#create_twingle_product_tw_' + self.id).crmError(error.message, ts('Could not delete Price Field', [])); + }); + }); + }; + } + + /** + * Creates a new row with the product name and buttons for creating, updating + * or deleting the price field for this product. + * @returns {*} + */ + createRow() { + let row; + + // Clear row + if (this.row) { + for (let i = this.row.cells.length - 1; i >= 0; i--) { + // Delete everything from row + this.row.deleteCell(i); + } + row = this.row; + } else { + // Create new row element + row = document.createElement('tr'); + + // Add id to row + row.id = 'twingle_product_tw_' + this.externalId; + } + + // Add cell with product name + const nameCell = document.createElement('td'); + if (this.isOrphaned) { + nameCell.classList.add('strikethrough'); + } + nameCell.textContent = this.name; + row.appendChild(nameCell); + + // Add cell for buttons + let buttonCell = row.insertCell(1); + + // Add product buttons which allow to create, update or delete the price + // field for this product + if (this.parentTable.id) { + let buttons = this.createProductButtons(); + for (const button of buttons) { + buttonCell.appendChild(button); + } + } + + // Add financial type dropdown for each product if price set exists + if (this.parentTable.id) { + let dropdown = this.createFinancialTypeDropdown(); + const cell = document.createElement('td'); + cell.classList.add('twingle-shop-financial-type-select'); + cell.appendChild(dropdown); + row.insertCell(2).appendChild(cell); + } + // else add default financial type + else { + const cell = document.createElement('td'); + cell.classList.add('twingle-shop-financial-type-default'); + cell.innerHTML = '' + getShopDefaultFinancialType() + ''; + row.insertCell(1).appendChild(cell); + } + + this.row = row; + return this.row; + } + + /** + * Determining which actions are available for this product and creating a + * button for each of them. + * @returns {Array} Array of buttons + */ + createProductButtons() { + let actionsAndHandlers = []; + let buttons = []; + + // Determine actions; if product has price field id, it can be updated or + // deleted, otherwise it can be created + if (this.priceFieldId) { + if (this.isOutdated) { + actionsAndHandlers.push(['update', this.createPriceFieldHandler()]); + } else if (!this.isOrphaned) { + actionsAndHandlers.push(['update', null]); + } + actionsAndHandlers.push(['delete', this.deletePriceFieldHandler()]); + } else { + actionsAndHandlers.push(['create', this.createPriceFieldHandler()]); + } + + // Create button for each action + for (const [action, handler] of actionsAndHandlers) { + buttons.push(this.createProductButton(action, handler)); + } + + return buttons; + } + + /** + * Creates a dropdown for selecting the financial type for this product. + * @returns {HTMLSelectElement} + * @private + */ + createFinancialTypeDropdown() { + // Create new dropdown element + const dropdown = document.createElement('select'); + dropdown.id = 'twingle_product_tw_' + this.externalId + '_financial_type'; + + // Add empty option if no price field exists + if (!this.priceFieldId) { + let option = document.createElement('option'); + option.value = ''; + option.innerHTML = '<' + ts('select financial type', []) + '>'; + option.selected = true; + option.disabled = true; + dropdown.appendChild(option); + } + + // Add options for each financial type available in CiviCRM + for (const key in financialTypes) { + let option = document.createElement('option'); + option.value = key; + option.text = financialTypes[key]; // financialTypes is defined in twingle_shop.tpl as smarty variable + if (this.financialTypeId !== null && this.financialTypeId.toString() === key) { + option.selected = true; + } + dropdown.appendChild(option); + } + + // Add handlers + let self = this; + dropdown.onchange = function () { + + // Enable 'create' button if financial type is selected + const createButton = document.getElementById('twingle_product_tw_' + self.externalId).getElementsByClassName('twingle-shop-cell-button')[0]; + if (createButton.textContent.includes('Create')) { + createButton.disabled = dropdown.value === '0'; + } + + // Update financial type + self.financialTypeId = dropdown.value; + }; + + return dropdown; + } + + /** + * Updates the product properties and rebuilds the row. + * @param productData + */ + update(productData = null) { + if (productData) { + this.setProps(productData); + } else { + this.reset(); + } + this.createRow(); + } + + /** + * Resets the product properties. + */ + reset() { + this.financialTypeId = null; + this.priceFieldId = null; + this.isOutdated = null; + this.isOutdated = null; + // this.updatedAt = null; + this.createdAt = null; + this.id = null; + } + +} + +/** + * This class represents a Twingle Shop. + */ +class ProductsTable { + + /** + * Creates a new ProductsTable object. + * @param projectData + */ + constructor(projectData) { + this.setProps(projectData); + } + + /** + * Sets the properties of this project. + * @param projectData + * @private + */ + setProps(projectData) { + this.id = projectData.id; + this.name = projectData.name; + this.numericalProjectId = projectData.numerical_project_id; + this.projectIdentifier = projectData.project_identifier; + this.products = projectData.products.map(productData => new Product(productData, this)); + this.priceSetId = projectData.price_set_id; + this.table = this.buildTable(); + } + + /** + * Dumps the projects data. + * @returns {{price_set_id, financial_type_id, numerical_project_id, name, id, project_identifier, products: *}} + */ + dumpData() { + return { + 'id': this.id, + 'name': this.name, + 'numerical_project_id': this.numericalProjectId, + 'project_identifier': this.projectIdentifier, + 'price_set_id': this.priceSetId, + 'products': this.products.map(product => product.dumpData()), + 'financial_type_id': getShopDefaultFinancialTypeValue() + }; + } + + /** + * Builds the table for this project (shop). + * @returns {HTMLTableElement} + * @private + */ + buildTable() { + let table; + + // Clear table body + if (this.table) { + this.clearTableHeader(); + this.clearTableBody(); + this.updateTableButtons(); + table = this.table; + } else { + // Create new table element + table = document.createElement('table'); + table.classList.add('twingle-shop-table'); + table.id = this.projectIdentifier; + + // Add caption + const caption = table.createCaption(); + caption.textContent = this.name + ' (' + this.projectIdentifier + ')'; + caption.classList.add('twingle-shop-table-caption'); + + // Add table body + const tbody = document.createElement('tbody'); + table.appendChild(tbody); + + // Add table buttons + this.addTableButtons(table); + } + + // Add header row + const thead = table.createTHead(); + const headerRow = thead.insertRow(); + const headers = [ts('Product', []), ts('Financial Type', [])]; + + // Add price field column if price set exists + if (this.priceSetId) { + headers.splice(1, 0, ts('Price Field', [])); + } + + for (const headerText of headers) { + const headerCell = document.createElement('th'); + headerCell.textContent = headerText; + headerRow.appendChild(headerCell); + } + + // Add products to table + this.addProductsToTable(table); + + return table; + } + + /** + * Adds buttons for creating, updating or deleting the price set for the + * given project (shop). + * @private + */ + addTableButtons(table) { + table.appendChild(this.createTableButton('update', this.updatePriceSetHandler())); + if (this.priceSetId === null) { + table.appendChild(this.createTableButton('create', this.createPriceSetHandler())); + } else { + table.appendChild(this.createTableButton('delete', this.deletePriceSetHandler())); + } + } + + /** + * Creates a button for creating, updating or deleting the price set for the + * given project (shop). + * @param action + * @param handler + * @returns {HTMLButtonElement} + * @private + */ + createTableButton(action, handler) { + // Create button + const button = document.createElement('button'); + button.id = 'btn_' + action + '_twingle_shop_' + this.projectIdentifier; + button.classList.add('crm-button', 'twingle-shop-table-button'); + + // Add button text + const text = action === 'create' ? ts('Create Price Set', []) : action === 'update' ? ts('Update Price Set', []) : ts('Delete Price Set', []); + button.textContent = ' ' + ts(text, []); + + // Add button handler + button.onclick = handler; + + // Add icon + const icon = document.createElement('i'); + const iconClass = action === 'create' ? 'fa-plus-circle' : action === 'update' ? 'fa-refresh' : 'fa-trash'; + icon.classList.add('crm-i', iconClass); + button.insertBefore(icon, button.firstChild); + + return button; + } + + /** + * Adds products to table body. + * @param table + * @private + */ + addProductsToTable(table) { + // Get table body + const tbody = table.getElementsByTagName('tbody')[0]; + + // Add products to table body + for (const product of this.products) { + // Add row for product + const row = product.createRow(); + // Add row to table + tbody.appendChild(row); + } + } + + /** + * Updates the table buttons. + */ + updateTableButtons() { + const table_buttons = this.table.getElementsByClassName('twingle-shop-table-button'); + // Remove all price set buttons from table + while (table_buttons.length > 0) { + table_buttons[0].remove(); + } + this.addTableButtons(this.table); + } + + /** + * Clears the table header. + * @private + */ + clearTableHeader() { + const thead = this.table.getElementsByTagName('thead')[0]; + while (thead.firstChild) { + thead.removeChild(thead.firstChild); + } + } + + /** + * Clears the table body. + */ + clearTableBody() { + const tbody = this.table.getElementsByTagName('tbody')[0]; + while (tbody.firstChild) { + tbody.removeChild(tbody.firstChild); + } + } + + /** + * Creates a handler for creating the price set for the given project (shop). + * @returns {(function(*): void)|*} + */ + createPriceSetHandler() { + let self = this; + return function (event) { + event.preventDefault(); + CRM.api3('TwingleShop', 'create', self.dumpData()) + .then(function (result) { + if (result.is_error === 1) { + cj('#btn_create_price_set_' + self.projectIdentifier).crmError(result.error_message, ts('Could not create Twingle Shop', [])); + } else { + self.update(); + CRM.alert(ts('The Price Set was created successfully.', []), ts('Price Field created', []), 'success', {'expires': 5000}); + } + }, function (error) { + cj('#btn_create_price_set_' + self.projectIdentifier).crmError(error.message, ts('Could not create TwingleShop', [])); + }); + }; + } + + /** + * Creates a handler for deleting the price set for the given project (shop). + * @returns {(function(*): void)|*} + */ + deletePriceSetHandler() { + let self = this; + return function (event) { + event.preventDefault(); + const options = { + 'title': ts('Delete Price Set', []), + 'message': ts('Are you sure you want to delete the price set associated with this Twingle Shop?', []), + }; + CRM.confirm(options) + .on('crmConfirm:yes', function () { + CRM.api3('TwingleShop', 'delete', { + 'project_identifier': self.projectIdentifier, + }).then(function (result) { + if (result.is_error === 1) { + cj('#btn_create_price_set_' + self.projectIdentifier).crmError(result.error_message, ts('Could not delete Twingle Shop', [])); + } else { + self.update(); + CRM.alert(ts('The Price Set was deleted successfully.', []), ts('Price Set deleted', []), 'success', {'expires': 5000}); + } + }, function (error) { + cj('#btn_delete_price_set_' + self.projectIdentifier).crmError(error.message, ts('Could not delete Twingle Shop', [])); + }); + }); + }; + } + + /** + * Creates a handler for updating the price set for the given project (shop). + * @returns {(function(*): void)|*} + */ + updatePriceSetHandler() { + let self = this; + return function (event) { + cj('#twingle-shop-spinner').show(); + if (event) { + event.preventDefault(); + } + CRM.api3('TwingleShop', 'fetch', { + 'project_identifiers': self.projectIdentifier, + }).then(function (result) { + if (result.is_error === 1) { + cj('#btn_create_price_set_' + self.projectIdentifier).crmError(result.error_message, ts('Could not delete Twingle Shop', [])); + cj('#twingle-shop-spinner').hide(); + } else { + self.update(result.values[self.projectIdentifier]); + cj('#twingle-shop-spinner').hide(); + } + }, function (error) { + cj('#btn_update_price_set_' + self.projectIdentifier).crmError(error.message, ts('Could not update Twingle Shop', [])); + cj('#twingle-shop-spinner').hide(); + }); + }; + } + + /** + * Updates the project properties and rebuilds the table. + * @param projectData + */ + update(projectData) { + if (!projectData) { + const updatePriceSet = this.updatePriceSetHandler(); + updatePriceSet(); + } else { + this.setProps(projectData); + this.buildTable(); + } + } +} diff --git a/sql/auto_uninstall.sql b/sql/auto_uninstall.sql new file mode 100644 index 0000000..b37b946 --- /dev/null +++ b/sql/auto_uninstall.sql @@ -0,0 +1,21 @@ +-- +--------------------------------------------------------------------+ +-- | Copyright CiviCRM LLC. All rights reserved. | +-- | | +-- | This work is published under the GNU AGPLv3 license with some | +-- | permitted exceptions and without any warranty. For full license | +-- | and copyright information, see https://civicrm.org/licensing | +-- +--------------------------------------------------------------------+ +-- +-- Generated from drop.tpl +-- DO NOT EDIT. Generated by CRM_Core_CodeGen +---- /******************************************************* +-- * +-- * Clean up the existing tables-- * +-- *******************************************************/ + +SET FOREIGN_KEY_CHECKS=0; + +DROP TABLE IF EXISTS `civicrm_twingle_product`; +DROP TABLE IF EXISTS `civicrm_twingle_shop`; + +SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file diff --git a/sql/civicrm_twingle_shop.sql b/sql/civicrm_twingle_shop.sql new file mode 100644 index 0000000..918b0ef --- /dev/null +++ b/sql/civicrm_twingle_shop.sql @@ -0,0 +1,66 @@ +-- +--------------------------------------------------------------------+ +-- | Copyright CiviCRM LLC. All rights reserved. | +-- | | +-- | This work is published under the GNU AGPLv3 license with some | +-- | permitted exceptions and without any warranty. For full license | +-- | and copyright information, see https://civicrm.org/licensing | +-- +--------------------------------------------------------------------+ +-- +-- Generated from schema.tpl +-- DO NOT EDIT. Generated by CRM_Core_CodeGen +-- +-- /******************************************************* +-- * +-- * Clean up the existing tables - this section generated from drop.tpl +-- * +-- *******************************************************/ + +SET FOREIGN_KEY_CHECKS=0; + +DROP TABLE IF EXISTS `civicrm_twingle_product`; +DROP TABLE IF EXISTS `civicrm_twingle_shop`; + +SET FOREIGN_KEY_CHECKS=1; +-- /******************************************************* +-- * +-- * Create new tables +-- * +-- *******************************************************/ + +-- /******************************************************* +-- * +-- * civicrm_twingle_shop +-- * +-- * This table contains the Twingle Shop data. Each Twingle Shop is linked to a corresponding Price Set. +-- * +-- *******************************************************/ +CREATE TABLE `civicrm_twingle_shop` ( + `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique TwingleShop ID', + `project_identifier` varchar(32) NOT NULL COMMENT 'Twingle Project Identifier', + `numerical_project_id` int unsigned NOT NULL COMMENT 'Numerical Twingle Project Identifier', + `price_set_id` int unsigned COMMENT 'FK to Price Set', + `name` varchar(64) NOT NULL COMMENT 'name of the shop', + PRIMARY KEY (`id`), + CONSTRAINT FK_civicrm_twingle_shop_price_set_id FOREIGN KEY (`price_set_id`) REFERENCES `civicrm_price_set`(`id`) ON DELETE CASCADE +) + ENGINE=InnoDB; + +-- /******************************************************* +-- * +-- * civicrm_twingle_product +-- * +-- * This table contains the Twingle Product data. +-- * +-- *******************************************************/ +CREATE TABLE `civicrm_twingle_product` ( + `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique TwingleProduct ID', + `external_id` int unsigned NOT NULL COMMENT 'The ID of this product in the Twingle database', + `price_field_id` int unsigned NOT NULL COMMENT 'FK to Price Field', + `twingle_shop_id` int unsigned COMMENT 'FK to Twingle Shop', + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Timestamp of when the product was created in the database', + `updated_at` datetime NOT NULL COMMENT 'Timestamp of when the product was last updated in the Twingle database', + PRIMARY KEY (`id`), + CONSTRAINT FK_civicrm_twingle_product_price_field_id FOREIGN KEY (`price_field_id`) REFERENCES `civicrm_price_field`(`id`) ON DELETE CASCADE, + CONSTRAINT FK_civicrm_twingle_product_twingle_shop_id FOREIGN KEY (`twingle_shop_id`) REFERENCES `civicrm_twingle_shop`(`id`) ON DELETE CASCADE +) + ENGINE=InnoDB; diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index a8efdc5..8098450 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -85,4 +85,13 @@ {ts domain="de.systopia.twingle"}

      Create a contact note for each field specified in this selection.

      Tip: You can enable or disable this fields in the TwingleMANAGER.

      {/ts} {/htxt} + +{htxt id='id-enable_shop_integration'} +

      {ts domain="de.systopia.twingle"}Enable the processing of orders via Twingle Shop for this profile. The ordered products will then appear as line items in the contribution.{/ts}

      +{/htxt} + +{htxt id='id-shop_map_products'} +

      {ts domain="de.systopia.twingle"}If this option is enabled, all Twingle Shop products corresponding to the specified project IDs will be retrieved from Twingle and mapped as price sets and price fields. Each Twingle Shop is mapped as a price set with its products as price fields.

      +

      This allows you to manually create contributions with the same line items for phone orders, for example, as would be the case for orders placed through the Twingle Shop.

      +{/htxt} {/crmScope} diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 1577b5f..8224e84 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -46,7 +46,7 @@ class="helpicon" > -
    + {/if} @@ -353,6 +353,71 @@
    {$form.double_opt_in.label}{$form.double_opt_in.html}{$form.newsletter_groups.label}{$form.newsletter_groups.html}
    {$form.newsletter_groups.label}{$form.newsletter_groups.html}{$form.newsletter_double_opt_in.label}{$form.newsletter_double_opt_in.html}
    {$form.newsletter_double_opt_in.label} + {$form.newsletter_double_opt_in.label} + + {$form.newsletter_double_opt_in.html}
    {ts domain="de.systopia.twingle"}Edit{/ts} - {ts domain="de.systopia.twingle"}Copy{/ts} + {ts domain="de.systopia.twingle"}Copy{/ts} {if $profile_name == 'default'} {ts domain="de.systopia.twingle"}Reset{/ts} {else} From be55ad70a8fcf6183b9966daca83f68e55f278de Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 10 Nov 2020 15:27:56 +0100 Subject: [PATCH 042/221] [#29] Prevent source profile be overwritten --- CRM/Twingle/Form/Profile.php | 7 ++----- templates/CRM/Twingle/Form/Profile.tpl | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index e00a339..8322940 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -171,16 +171,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', array(1 => $this->profile->getName()))); break; case 'copy': - // This will be a 'create' actually. - $this->_op = 'create'; - // Retrieve the source profile name. $profile_name = CRM_Utils_Request::retrieve('source_name', 'String', $this); // When copying without a valid profile name, copy the default profile. if (!$profile_name) { $profile_name = 'default'; } - $this->profile = CRM_Twingle_Profile::getProfile($profile_name); + $this->profile = clone CRM_Twingle_Profile::getProfile($profile_name); // Propose a new name for this profile. $profile_name = $profile_name . '_copy'; @@ -536,7 +533,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public function setDefaultValues() { $defaults = parent::setDefaultValues(); - if (in_array($this->_op, array('create', 'edit'))) { + if (in_array($this->_op, array('create', 'edit', 'copy'))) { $defaults['name'] = $this->profile->getName(); $profile_data = $this->profile->getData(); foreach ($profile_data as $element_name => $value) { diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index ec51647..f5e95f5 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -14,7 +14,7 @@
    - {if $op == 'create' or $op == 'edit'} + {if $op == 'create' or $op == 'edit' or $op == 'copy'}
    From 921ea49debc5ec5b1e89a81b93470b29cab4920d Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Fri, 19 Feb 2021 14:44:06 +0100 Subject: [PATCH 043/221] [#43] [#44] validate campaign_id cast numeric string to integer and test if a related campaign exists --- CRM/Twingle/Submission.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 0daee20..b96c64e 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -117,6 +117,30 @@ class CRM_Twingle_Submission { ); } } + + // Validate campaign_id, if given. + if (!empty($params['campaign_id'])) { + // Check whether campaign_id is a numeric string and cast it to an integer. + if (is_numeric($params['campaign_id'])) { + $params['campaign_id'] = intval($params['campaign_id']); + } + else { + throw new CiviCRM_API3_Exception( + E::ts('campaign_id must be a numeric string. '), + 'invalid_format' + ); + } + // Check whether given campaign_id exists and if not, unset the parameter. + try { + civicrm_api3( + 'Campaign', + 'getsingle', + ['id' => $params['campaign_id']] + ); + } catch (CiviCRM_API3_Exception $e) { + unset($params['campaign_id']); + } + } } /** From c06ba098c190c2509362064927ca8e5832c31c47 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Fri, 19 Feb 2021 14:52:32 +0100 Subject: [PATCH 044/221] [#44] change campaign_id data type to string --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 8d95be3..21890d4 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -234,7 +234,7 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { $params['campaign_id'] = array( 'name' => 'campaign_id', 'title' => E::ts('Campaign ID'), - 'type' => CRM_Utils_Type::T_INT, + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, 'description' => E::ts('The CiviCRM ID of a campaign to assign the contribution.'), ); From 287bb52e90dc8c72ab7a94d9a20372db978e68de Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Sat, 27 Feb 2021 20:12:43 +0100 Subject: [PATCH 045/221] add a paragraph to warn users against systopia/de.systopia.xcm#78 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index ac72b34..0e2e580 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,14 @@ Please refer to the Make sure you use an XCM profile with the option *Match contacts by contact ID* enabled. +Be careful when enabling the *"Change Primary Detail?"* option. While it might +appear useful to update even primary contact details, this might lead to a +loss of contact information due to the fact that along with a submission that +contains e.g. a PayPal donation the `user_country` is transmitted as the only +address detail. The `user_country` then will be treated by the XCM as a whole +new address. So the contact may end up with a new address that contains only +the country. + ### Configure CiviCRM - Go to the Administration console at `/civicrm/admin` From 0ce2d2530bcd339550ce7c227c00563028e36d96 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Tue, 9 Mar 2021 21:39:09 +0100 Subject: [PATCH 046/221] fix [#47] | Don't create new address only from user_country --- api/v3/TwingleDonation/Submit.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 21890d4..e1e7a13 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -335,6 +335,16 @@ function civicrm_api3_twingle_donation_Submit($params) { } } + // Do not creat a new address if user_country is the only address + // parameter. See issue #47 + if ( + !array_key_exists('street_address', $params) && + !array_key_exists('postal_code', $params) && + !array_key_exists('city', $params) + ) { + unset($params['country']); + } + // Prepare parameter mapping for organisation. if (!empty($params['user_company'])) { $params['organization_name'] = $params['user_company']; From c5f3b1081b525315bbadd9fab4c166c7164cbf3f Mon Sep 17 00:00:00 2001 From: mariav0 <70949178+mariav0@users.noreply.github.com> Date: Thu, 20 May 2021 13:42:18 +0200 Subject: [PATCH 047/221] Update Profile.hlp added information: This only works for fields that Twingle itself provides in the custom_fields parameter, not for any parameters; i.e. user_extrafield always ends up in a note. --- templates/CRM/Twingle/Form/Profile.hlp | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index bcbe78a..9c95e70 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -58,6 +58,7 @@ {ts domain="de.systopia.twingle"}

    Map Twingle custom fields to CiviCRM custom fields using the following format (each assignment in a separate line):

    twingle_field_1=custom_123
    twingle_field_2=custom_789

    Always use the custom_[id] notation for CiviCRM custom fields.

    +

    This only works for fields that Twingle itself provides in the custom_fields parameter, not for any parameters; i.e. user_extrafield always ends up in a note.

    Only custom fields extending one of the following CiviCRM entities are allowed:

    • Contact – Will be set on the Individual contact
    • From c889cf08e877b31d5c40573ad3cbd66bc05da1c8 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 20 May 2021 13:56:43 +0200 Subject: [PATCH 048/221] [#49] Improve help text on custom fields mapping --- templates/CRM/Twingle/Form/Profile.hlp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index 9c95e70..d83b35e 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -58,7 +58,7 @@ {ts domain="de.systopia.twingle"}

      Map Twingle custom fields to CiviCRM custom fields using the following format (each assignment in a separate line):

      twingle_field_1=custom_123
      twingle_field_2=custom_789

      Always use the custom_[id] notation for CiviCRM custom fields.

      -

      This only works for fields that Twingle itself provides in the custom_fields parameter, not for any parameters; i.e. user_extrafield always ends up in a note.

      +

      This only works for fields that Twingle themselves provide in the custom_fields parameter, not for any parameters; e.g. user_extrafield always ends up in a note.

      Only custom fields extending one of the following CiviCRM entities are allowed:

      • Contact – Will be set on the Individual contact
      • From cadf895def3b04b5e0cdd5f475cd268da02f49a3 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 6 Sep 2021 11:10:48 +0200 Subject: [PATCH 049/221] [#51] Update civix-generated code --- twingle.civix.php | 148 ++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 78 deletions(-) diff --git a/twingle.civix.php b/twingle.civix.php index 7d5bd46..c407f6f 100644 --- a/twingle.civix.php +++ b/twingle.civix.php @@ -7,9 +7,9 @@ * extension. */ class CRM_Twingle_ExtensionUtil { - const SHORT_NAME = "twingle"; - const LONG_NAME = "de.systopia.twingle"; - const CLASS_PREFIX = "CRM_Twingle"; + const SHORT_NAME = 'twingle'; + const LONG_NAME = 'de.systopia.twingle'; + const CLASS_PREFIX = 'CRM_Twingle'; /** * Translate a string using the extension's domain. @@ -24,9 +24,9 @@ class CRM_Twingle_ExtensionUtil { * Translated text. * @see ts */ - public static function ts($text, $params = array()) { + public static function ts($text, $params = []) { if (!array_key_exists('domain', $params)) { - $params['domain'] = array(self::LONG_NAME, NULL); + $params['domain'] = [self::LONG_NAME, NULL]; } return ts($text, $params); } @@ -82,7 +82,7 @@ use CRM_Twingle_ExtensionUtil as E; /** * (Delegated) Implements hook_civicrm_config(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_config + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ function _twingle_civix_civicrm_config(&$config = NULL) { static $configured = FALSE; @@ -100,7 +100,7 @@ function _twingle_civix_civicrm_config(&$config = NULL) { array_unshift($template->template_dir, $extDir); } else { - $template->template_dir = array($extDir, $template->template_dir); + $template->template_dir = [$extDir, $template->template_dir]; } $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); @@ -112,7 +112,7 @@ function _twingle_civix_civicrm_config(&$config = NULL) { * * @param $files array(string) * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_xmlMenu */ function _twingle_civix_civicrm_xmlMenu(&$files) { foreach (_twingle_civix_glob(__DIR__ . '/xml/Menu/*.xml') as $file) { @@ -123,7 +123,7 @@ function _twingle_civix_civicrm_xmlMenu(&$files) { /** * Implements hook_civicrm_install(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install */ function _twingle_civix_civicrm_install() { _twingle_civix_civicrm_config(); @@ -135,12 +135,12 @@ function _twingle_civix_civicrm_install() { /** * Implements hook_civicrm_postInstall(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall */ function _twingle_civix_civicrm_postInstall() { _twingle_civix_civicrm_config(); if ($upgrader = _twingle_civix_upgrader()) { - if (is_callable(array($upgrader, 'onPostInstall'))) { + if (is_callable([$upgrader, 'onPostInstall'])) { $upgrader->onPostInstall(); } } @@ -149,7 +149,7 @@ function _twingle_civix_civicrm_postInstall() { /** * Implements hook_civicrm_uninstall(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall */ function _twingle_civix_civicrm_uninstall() { _twingle_civix_civicrm_config(); @@ -161,12 +161,12 @@ function _twingle_civix_civicrm_uninstall() { /** * (Delegated) Implements hook_civicrm_enable(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable */ function _twingle_civix_civicrm_enable() { _twingle_civix_civicrm_config(); if ($upgrader = _twingle_civix_upgrader()) { - if (is_callable(array($upgrader, 'onEnable'))) { + if (is_callable([$upgrader, 'onEnable'])) { $upgrader->onEnable(); } } @@ -175,13 +175,13 @@ function _twingle_civix_civicrm_enable() { /** * (Delegated) Implements hook_civicrm_disable(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable * @return mixed */ function _twingle_civix_civicrm_disable() { _twingle_civix_civicrm_config(); if ($upgrader = _twingle_civix_upgrader()) { - if (is_callable(array($upgrader, 'onDisable'))) { + if (is_callable([$upgrader, 'onDisable'])) { $upgrader->onDisable(); } } @@ -193,10 +193,11 @@ function _twingle_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 http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade */ function _twingle_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { if ($upgrader = _twingle_civix_upgrader()) { @@ -217,49 +218,27 @@ function _twingle_civix_upgrader() { } /** - * Search directory tree for files which match a glob pattern + * 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 $dir string, base dir - * @param $pattern string, glob pattern, eg "*.txt" - * @return array(string) + * @param string $dir base dir + * @param string $pattern , glob pattern, eg "*.txt" + * + * @return array */ function _twingle_civix_find_files($dir, $pattern) { - if (is_callable(array('CRM_Utils_File', 'findFiles'))) { - return CRM_Utils_File::findFiles($dir, $pattern); - } - - $todos = array($dir); - $result = array(); - while (!empty($todos)) { - $subdir = array_shift($todos); - foreach (_twingle_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(). * * Find any *.mgd.php files, merge their content, and return. * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_managed */ function _twingle_civix_civicrm_managed(&$entities) { $mgdFiles = _twingle_civix_find_files(__DIR__, '*.mgd.php'); @@ -285,7 +264,7 @@ function _twingle_civix_civicrm_managed(&$entities) { * * Note: This hook only runs in CiviCRM 4.4+. * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_caseTypes */ function _twingle_civix_civicrm_caseTypes(&$caseTypes) { if (!is_dir(__DIR__ . '/xml/case')) { @@ -296,14 +275,13 @@ function _twingle_civix_civicrm_caseTypes(&$caseTypes) { $name = preg_replace('/\.xml$/', '', basename($file)); if ($name != CRM_Case_XMLProcessor::mungeCaseType($name)) { $errorMessage = sprintf("Case-type file name is malformed (%s vs %s)", $name, CRM_Case_XMLProcessor::mungeCaseType($name)); - CRM_Core_Error::fatal($errorMessage); - // throw new CRM_Core_Exception($errorMessage); + throw new CRM_Core_Exception($errorMessage); } - $caseTypes[$name] = array( + $caseTypes[$name] = [ 'module' => E::LONG_NAME, 'name' => $name, 'file' => $file, - ); + ]; } } @@ -314,7 +292,7 @@ function _twingle_civix_civicrm_caseTypes(&$caseTypes) { * * Note: This hook only runs in CiviCRM 4.5+. * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_angularModules + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_angularModules */ function _twingle_civix_civicrm_angularModules(&$angularModules) { if (!is_dir(__DIR__ . '/ang')) { @@ -332,6 +310,25 @@ function _twingle_civix_civicrm_angularModules(&$angularModules) { } } +/** + * (Delegated) Implements hook_civicrm_themes(). + * + * Find any and return any files matching "*.theme.php" + */ +function _twingle_civix_civicrm_themes(&$themes) { + $files = _twingle_civix_glob(__DIR__ . '/*.theme.php'); + foreach ($files as $file) { + $themeMeta = include $file; + if (empty($themeMeta['name'])) { + $themeMeta['name'] = preg_replace(':\.theme\.php$:', '', basename($file)); + } + if (empty($themeMeta['ext'])) { + $themeMeta['ext'] = E::LONG_NAME; + } + $themes[$themeMeta['name']] = $themeMeta; + } +} + /** * Glob wrapper which is guaranteed to return an array. * @@ -342,11 +339,12 @@ function _twingle_civix_civicrm_angularModules(&$angularModules) { * * @link http://php.net/glob * @param string $pattern - * @return array, possibly empty + * + * @return array */ function _twingle_civix_glob($pattern) { $result = glob($pattern); - return is_array($result) ? $result : array(); + return is_array($result) ? $result : []; } /** @@ -357,16 +355,18 @@ function _twingle_civix_glob($pattern) { * 'Mailing', or 'Administer/System Settings' * @param array $item - the item to insert (parent/child attributes will be * filled for you) + * + * @return bool */ function _twingle_civix_insert_navigation_menu(&$menu, $path, $item) { // If we are done going down the path, insert menu if (empty($path)) { - $menu[] = array( - 'attributes' => array_merge(array( + $menu[] = [ + 'attributes' => array_merge([ 'label' => CRM_Utils_Array::value('name', $item), 'active' => 1, - ), $item), - ); + ], $item), + ]; return TRUE; } else { @@ -377,9 +377,9 @@ function _twingle_civix_insert_navigation_menu(&$menu, $path, $item) { foreach ($menu as $key => &$entry) { if ($entry['attributes']['name'] == $first) { if (!isset($entry['child'])) { - $entry['child'] = array(); + $entry['child'] = []; } - $found = _twingle_civix_insert_navigation_menu($entry['child'], implode('/', $path), $item, $key); + $found = _twingle_civix_insert_navigation_menu($entry['child'], implode('/', $path), $item); } } return $found; @@ -390,7 +390,7 @@ function _twingle_civix_insert_navigation_menu(&$menu, $path, $item) { * (Delegated) Implements hook_civicrm_navigationMenu(). */ function _twingle_civix_navigationMenu(&$nodes) { - if (!is_callable(array('CRM_Core_BAO_Navigation', 'fixNavigationMenu'))) { + if (!is_callable(['CRM_Core_BAO_Navigation', 'fixNavigationMenu'])) { _twingle_civix_fixNavigationMenu($nodes); } } @@ -432,17 +432,11 @@ function _twingle_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) { /** * (Delegated) Implements hook_civicrm_alterSettingsFolders(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_alterSettingsFolders */ function _twingle_civix_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) { - static $configured = FALSE; - if ($configured) { - return; - } - $configured = TRUE; - $settingsDir = __DIR__ . DIRECTORY_SEPARATOR . 'settings'; - if (is_dir($settingsDir) && !in_array($settingsDir, $metaDataFolders)) { + if (!in_array($settingsDir, $metaDataFolders) && is_dir($settingsDir)) { $metaDataFolders[] = $settingsDir; } } @@ -452,10 +446,8 @@ function _twingle_civix_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) { * * Find any *.entityType.php files, merge their content, and return. * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes */ - function _twingle_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, array ( - )); + $entityTypes = array_merge($entityTypes, []); } From 9751e8cee4f4b08241da530aa69a561954a28293 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 8 Sep 2021 14:46:27 +0200 Subject: [PATCH 050/221] [#53] Remove duplicate XCM call for individual address --- api/v3/TwingleDonation/Submit.php | 59 +++++++++++++------------------ 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 21890d4..9ea475f 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -400,27 +400,6 @@ function civicrm_api3_twingle_donation_Submit($params) { $contact_data += $custom_fields['Individual']; } - if (!$contact_id = CRM_Twingle_Submission::getContact( - 'Individual', - $contact_data, - $profile, - $params - )) { - throw new CiviCRM_API3_Exception( - E::ts('Individual contact could not be found or created.'), - 'api_error' - ); - } - - // Save user_extrafield as contact note. - if (!empty($params['user_extrafield'])) { - civicrm_api3('Note', 'create', array( - 'entity_table' => 'civicrm_contact', - 'entity_id' => $contact_id, - 'note' => $params['user_extrafield'], - )); - } - // Organisation lookup. if (!empty($params['organization_name'])) { $organisation_data = array( @@ -449,6 +428,31 @@ function civicrm_api3_twingle_donation_Submit($params) { ); } } + elseif (!empty($submitted_address)) { + $contact_data += $submitted_address; + } + + if (!$contact_id = CRM_Twingle_Submission::getContact( + 'Individual', + $contact_data, + $profile, + $params + )) { + throw new CiviCRM_API3_Exception( + E::ts('Individual contact could not be found or created.'), + 'api_error' + ); + } + + // Save user_extrafield as contact note. + if (!empty($params['user_extrafield'])) { + civicrm_api3('Note', 'create', array( + 'entity_table' => 'civicrm_contact', + 'entity_id' => $contact_id, + 'note' => $params['user_extrafield'], + )); + } + // Share organisation address with individual contact, using configured // location type for organisation address. $address_shared = ( @@ -460,19 +464,6 @@ function civicrm_api3_twingle_donation_Submit($params) { ) ); - // Address is not shared, use submitted address with - // configured location type. - if (!$address_shared && !empty($submitted_address)) { - // Do not use `Address.create` API action, let XCM decide - // whether to create an address. - CRM_Twingle_Submission::getContact( - 'Individual', - array('id' => $contact_id) + $submitted_address, - $profile, - $params - ); - } - // Create employer relationship between organization and individual. if (isset($organisation_id)) { CRM_Twingle_Submission::updateEmployerRelation($contact_id, $organisation_id); From a30b8f02cb583dc537cdd58bf148af5d65546d81 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Tue, 9 Mar 2021 21:39:09 +0100 Subject: [PATCH 051/221] fix [#47] | Don't create new address only from user_country --- api/v3/TwingleDonation/Submit.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 9ea475f..1aa4197 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -335,6 +335,16 @@ function civicrm_api3_twingle_donation_Submit($params) { } } + // Do not creat a new address if user_country is the only address + // parameter. See issue #47 + if ( + !array_key_exists('street_address', $params) && + !array_key_exists('postal_code', $params) && + !array_key_exists('city', $params) + ) { + unset($params['country']); + } + // Prepare parameter mapping for organisation. if (!empty($params['user_company'])) { $params['organization_name'] = $params['user_company']; From 9969c99f7070da60d6661bff6d66f3d2b3aa2a9a Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 17 Nov 2021 16:23:29 +0100 Subject: [PATCH 052/221] Make required address components configurable The required address components can be selected in the corresponding profile. --- CRM/Twingle/Form/Profile.php | 14 ++++++++++++++ CRM/Twingle/Profile.php | 9 ++++++++- api/v3/TwingleDonation/Submit.php | 22 ++++++++++++++-------- templates/CRM/Twingle/Form/Profile.hlp | 6 ++++++ templates/CRM/Twingle/Form/Profile.tpl | 21 +++++++++++++++++++++ 5 files changed, 63 insertions(+), 9 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 8322940..b95ddc4 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -416,6 +416,20 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { array() ); + $this->add( + 'select', + 'required_address_components', + E::ts('Required address components'), + [ + 'street_address' => E::ts("Street"), + 'postal_code' => E::ts("Postal Code"), + 'city' => E::ts("City"), + 'country' => E::ts("Country"), + ], + FALSE, // is not required + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] + ); + $this->add( 'textarea', // field type 'custom_field_mapping', // field name diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index f59d236..e6a6642 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -226,7 +226,8 @@ class CRM_Twingle_Profile { 'membership_type_id', 'membership_type_id_recur', 'membership_postprocess_call', - 'newsletter_double_opt_in' + 'newsletter_double_opt_in', + 'required_address_components', ), // Add payment methods. array_keys(static::paymentInstruments()), @@ -300,6 +301,12 @@ class CRM_Twingle_Profile { 'membership_type_id' => NULL, 'membership_type_id_recur' => NULL, 'newsletter_double_opt_in' => NULL, + 'required_address_components' => [ + 'street_address', + 'postal_code', + 'city', + 'country', + ], ) // Add contribution status for all payment methods. + array_fill_keys(array_map(function($attribute) { diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 1aa4197..ce75369 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -335,14 +335,20 @@ function civicrm_api3_twingle_donation_Submit($params) { } } - // Do not creat a new address if user_country is the only address - // parameter. See issue #47 - if ( - !array_key_exists('street_address', $params) && - !array_key_exists('postal_code', $params) && - !array_key_exists('city', $params) - ) { - unset($params['country']); + // Do not creat a new address if 'country' is the only address + // component. See issue #47 + $required_address_components = + $profile->getAttribute('required_address_components'); + $unset_address_params = False; + foreach ($required_address_components as $req) { + if (empty($params[$req])) { + $unset_address_params = True; + } + } + if ($unset_address_params) { + foreach($required_address_components as $req) { + unset($params[$req]); + } } // Prepare parameter mapping for organisation. diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index d83b35e..b4c6ff9 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -54,6 +54,12 @@
      {/ts} {/htxt} +{htxt id='id-required_address_components'} +

      {ts domain="de.systopia.twingle"}Select the address components that must be present to create a new address for the contact.{/ts}

      +

      {ts domain="de.systopia.twingle"}Depending on your XCM settings, the newly transferred address will replace the old one. This behavior may be intentional, as you always want to have the most current address.{/ts}

      +

      {ts domain="de.systopia.twingle"}ATTENTION: In some cases Twingle sends only the country of the user. If no other address components are selected in the required address components, the current user address will be overwritten with an address containing only the country, depending on the XCM settings.{/ts}

      +{/htxt} + {htxt id='id-custom_field_mapping'} {ts domain="de.systopia.twingle"}

      Map Twingle custom fields to CiviCRM custom fields using the following format (each assignment in a separate line):

      twingle_field_1=custom_123
      twingle_field_2=custom_789
      diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index f5e95f5..49a0097 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -290,6 +290,27 @@
    {$form.contribution_source.html}
    {$form.required_address_components.label} + + {$form.required_address_components.html}
    {$form.custom_field_mapping.label} From d910ce4846b38c380c17ce0daf0da7cd1b4eab1c Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 17 Nov 2021 16:52:14 +0100 Subject: [PATCH 053/221] Comment updated --- api/v3/TwingleDonation/Submit.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index ce75369..1dddb72 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -335,8 +335,9 @@ function civicrm_api3_twingle_donation_Submit($params) { } } - // Do not creat a new address if 'country' is the only address - // component. See issue #47 + // Make required address components configurable to prevent existing + // contact addresses from being overwritten with incomplete address + // information. See issue #47 $required_address_components = $profile->getAttribute('required_address_components'); $unset_address_params = False; From 48164479f72d7e16d2cd1c84f5f549755894db2d Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 17 Nov 2021 18:20:25 +0100 Subject: [PATCH 054/221] hard code array of address components to unset --- api/v3/TwingleDonation/Submit.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 1dddb72..f773054 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -347,7 +347,12 @@ function civicrm_api3_twingle_donation_Submit($params) { } } if ($unset_address_params) { - foreach($required_address_components as $req) { + foreach([ + 'street_address', + 'postal_code', + 'city', + 'country', + ] as $req) { unset($params[$req]); } } From dbac84d13abb6d542c110eda18b5da3597e69313 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 19 Apr 2022 17:49:59 +0200 Subject: [PATCH 055/221] Version 1.3-alpha1 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 6fe8dc2..577e67e 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.3-dev - dev + 2022-04-19 + 1.3-alpha1 + alpha 5.0 5.19 From 36958cb9ed6e1ccfe5e2516d6b53615ad5af7dd0 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 19 Apr 2022 17:50:15 +0200 Subject: [PATCH 056/221] Back to dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 577e67e..6fe8dc2 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2022-04-19 - 1.3-alpha1 - alpha + + 1.3-dev + dev 5.0 5.19 From 6779349505ba35a54fa5a69948c40d50b6d68dc3 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 2 May 2022 14:30:35 +0200 Subject: [PATCH 057/221] [#47] Simplify evaluating required address components and re-arrange profile form --- api/v3/TwingleDonation/Submit.php | 33 +++++++++----------- templates/CRM/Twingle/Form/Profile.hlp | 8 +++-- templates/CRM/Twingle/Form/Profile.tpl | 42 +++++++++++++------------- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index f773054..4025f97 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -335,25 +335,20 @@ function civicrm_api3_twingle_donation_Submit($params) { } } - // Make required address components configurable to prevent existing - // contact addresses from being overwritten with incomplete address - // information. See issue #47 - $required_address_components = - $profile->getAttribute('required_address_components'); - $unset_address_params = False; - foreach ($required_address_components as $req) { - if (empty($params[$req])) { - $unset_address_params = True; - } - } - if ($unset_address_params) { - foreach([ - 'street_address', - 'postal_code', - 'city', - 'country', - ] as $req) { - unset($params[$req]); + // Remove address data when any address component that is configured as + // required is missing. + // See https://github.com/systopia/de.systopia.twingle/issues/47 + foreach ($profile->getAttribute('required_address_components', []) as $required_address_component) { + if (empty($params[$required_address_component])) { + foreach ([ + 'street_address', + 'postal_code', + 'city', + 'country', + ] as $address_param) { + unset($params[$address_param]); + } + break; } } diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index b4c6ff9..e3841d7 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -12,6 +12,7 @@ | written permission from the original author(s). | +-------------------------------------------------------------*} +{crmScope extensionKey='de.systopia.twingle'} {htxt id='id-location_type_id'} {ts domain="de.systopia.twingle"}Select which location type to use for addresses for individuals, either when no organisation name is specified, or an organisation address can not be shared with the individual contact.{/ts} {/htxt} @@ -55,9 +56,9 @@ {/htxt} {htxt id='id-required_address_components'} -

    {ts domain="de.systopia.twingle"}Select the address components that must be present to create a new address for the contact.{/ts}

    -

    {ts domain="de.systopia.twingle"}Depending on your XCM settings, the newly transferred address will replace the old one. This behavior may be intentional, as you always want to have the most current address.{/ts}

    -

    {ts domain="de.systopia.twingle"}ATTENTION: In some cases Twingle sends only the country of the user. If no other address components are selected in the required address components, the current user address will be overwritten with an address containing only the country, depending on the XCM settings.{/ts}

    +

    {ts}Select the address components that must be present to create or update an address for the contact.{/ts}

    +

    {ts}Depending on your XCM settings, the transferred address might replace an existing one.{/ts}

    +

    {ts}Since in some cases Twingle send the country of the user as the only address parameter, depending on your XCM configuration, not declaring other address components as required might lead to the current user address being overwritten with an address containing the country only.{/ts}

    {/htxt} {htxt id='id-custom_field_mapping'} @@ -74,3 +75,4 @@
  • ContributionRecur – Will be set on the recurring contribution and deriving single contributions
  • {/ts} {/htxt} +{/crmScope} \ No newline at end of file diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 49a0097..00794ef 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -113,6 +113,27 @@
    {$form.location_type_id_organisation.html}
    {$form.required_address_components.label} + + {$form.required_address_components.html}
    {$form.financial_type_id.label} @@ -290,27 +311,6 @@ {$form.contribution_source.html}
    {$form.required_address_components.label} - - {$form.required_address_components.html}
    {$form.custom_field_mapping.label} From c81e10faaa91504b1acb04564c4fa7aa9cd53487 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 2 May 2022 15:24:58 +0200 Subject: [PATCH 058/221] [#28] Add API parameter documentation and fix typo in API sepc --- README.md | 3 ++- api/v3/TwingleDonation/Submit.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dd5113d..848a792 100644 --- a/README.md +++ b/README.md @@ -102,10 +102,11 @@ The action accepts the following parameters: | `user_street` | String | The street address of the contact | | | | `user_postal_code` | String | The postal code of the contact | | | | `user_city` | String | The city of the contact | | | -| `user_country` | String | The country of the contact | [ISO 3166-1 Alpha-2 country codes](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) | | +| `user_country` | String | The country of the contact | A [ISO 3166-1 Alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) | | | `user_telephone` | String | The telephone number of the contact | | | | `user_company` | String | The company of the contact | | | | `user_extrafield` | String | Additional information of the contact | | | +| `user_language` | String | The preferred language of the contact. | A [ISO-639-1 2-digit language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) | | | `campaign_id` | Integer | The CiviCRM ID of a campaign to assign the contribution | A valid CiviCRM Campaign ID. This overrides the campaign ID configured within the profile. | | You may also refer to diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index de8fee4..9a64f3e 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -224,7 +224,7 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { 'api.required' => 0, 'description' => E::ts('The company of the contact.'), ); - $params['user_extrafield'] = array( + $params['user_language'] = array( 'name' => 'user_language', 'title' => E::ts('Language'), 'type' => CRM_Utils_Type::T_STRING, From 3654f92bf805bcafea22f1df090616e42739f2cf Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 2 May 2022 15:36:03 +0200 Subject: [PATCH 059/221] Add link to docs.civicrm.org --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index 6fe8dc2..03da3a9 100644 --- a/info.xml +++ b/info.xml @@ -10,7 +10,7 @@ https://github.com/systopia/de.systopia.twingle - https://github.com/systopia/de.systopia.twingle/blob/master/README.md + https://docs.civicrm.org/twingle/en/latest https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html From 6036f62a22b526813e1b8a51dbc5d65f15f32e9e Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 2 May 2022 15:36:12 +0200 Subject: [PATCH 060/221] Version 1.3-beta1 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 03da3a9..3b87ed3 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.3-dev - dev + 2022-05-02 + 1.3-beta1 + beta 5.0 5.19 From 6fbc1d4a5d8123b5e72dea0a47a045533eaecdf6 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 2 May 2022 15:36:32 +0200 Subject: [PATCH 061/221] Back to dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 3b87ed3..03da3a9 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2022-05-02 - 1.3-beta1 - beta + + 1.3-dev + dev 5.0 5.19 From 62399657e75cf0c973341830459e84626f439792 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Wed, 11 May 2022 20:55:42 +0200 Subject: [PATCH 062/221] [#42] added data structure and upgrader/migration --- CRM/Twingle/Upgrader.php | 146 +++++++------------------------- sql/civicrm_twingle_profile.sql | 16 ++++ 2 files changed, 48 insertions(+), 114 deletions(-) create mode 100644 sql/civicrm_twingle_profile.sql diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 35c1283..1724753 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -6,32 +6,12 @@ use CRM_Twingle_ExtensionUtil as E; */ class CRM_Twingle_Upgrader extends CRM_Twingle_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). - /** - * Example: Run an external SQL script when the module is installed. - * + * Installer script + */ public function install() { - $this->executeSqlFile('sql/myinstall.sql'); - } - - /** - * Example: Work with entities usually not available during the install step. - * - * This method can be used for any post-install tasks. For example, if a step - * of your installation depends on accessing an entity that is itself - * created during the installation (e.g., a setting or a managed entity), do - * so here to avoid order of operation problems. - * - public function postInstall() { - $customFieldId = civicrm_api3('CustomField', 'getvalue', array( - 'return' => array("id"), - 'name' => "customFieldCreatedViaManagedHook", - )); - civicrm_api3('Setting', 'create', array( - 'myWeirdFieldSetting' => array('id' => $customFieldId, 'weirdness' => 1), - )); + // create a DB table for the twingle profiles + $this->executeSqlFile('sql/civicrm_twingle_profile.sql'); } /** @@ -41,96 +21,6 @@ class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base { $this->executeSqlFile('sql/myuninstall.sql'); } - /** - * Example: Run a simple query when a module is enabled. - * - public function enable() { - CRM_Core_DAO::executeQuery('UPDATE foo SET is_active = 1 WHERE bar = "whiz"'); - } - - /** - * Example: Run a simple query when a module is disabled. - * - public function disable() { - CRM_Core_DAO::executeQuery('UPDATE foo SET is_active = 0 WHERE bar = "whiz"'); - } - - /** - * 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; - } // */ - /** * Copy financial_type_id setting to new setting financial_type_id_recur. */ @@ -163,4 +53,32 @@ class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base { return TRUE; } + /** + * Upgrading to 1.4.0 needs to convert the profiles into the new infrastructure + * + * @return TRUE on success + * @throws Exception + */ + public function upgrade_5140() { + $this->ctx->log->info('Converting twingle profiles.'); + + // create a DB table for the twingle profiles + $this->executeSqlFile('sql/civicrm_twingle_profile.sql'); + + // migrate the current profiles + if ($profiles_data = Civi::settings()->get('twingle_profiles')) { + foreach ($profiles_data as $profile_name => $profile_data) { + $profile = new CRM_Twingle_Profile($profile_name, $profile_data); + $data = json_encode($profile->getData()); + CRM_Core_DAO::executeQuery( + "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)", + [ + 1 => [$profile_name, 'String'], + 2 => [$data, 'String'] + ]); + } + } + + return TRUE; + } } diff --git a/sql/civicrm_twingle_profile.sql b/sql/civicrm_twingle_profile.sql new file mode 100644 index 0000000..479e231 --- /dev/null +++ b/sql/civicrm_twingle_profile.sql @@ -0,0 +1,16 @@ +-- /******************************************************* +-- ** civicrm_twingle_profile +-- ** +-- ** stores twingle profile data v1.4+ +-- ********************************************************/ + +CREATE TABLE IF NOT EXISTS `civicrm_twingle_profile`( + `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(255) COMMENT 'configuration name, i.e. internal ID', + `config` text COMMENT 'JSON encoded configuration', + `last_access` datetime COMMENT 'timestamp of the last access (through the api)', + `access_counter` int unsigned COMMENT 'number of accesses (through the api)', + PRIMARY KEY (`id`), + UNIQUE INDEX (`name`) +) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; + From fd47b91b65cd1e6acf3387b642678abfbcd1e079 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Wed, 11 May 2022 21:37:37 +0200 Subject: [PATCH 063/221] [#42] refactored profile management --- CRM/Twingle/Profile.php | 104 +++++++++++++++++++++------------------ CRM/Twingle/Upgrader.php | 3 ++ 2 files changed, 58 insertions(+), 49 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index e6a6642..127622c 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -21,12 +21,6 @@ use CRM_Twingle_ExtensionUtil as E; */ class CRM_Twingle_Profile { - /** - * @var CRM_Twingle_Profile[] $_profiles - * Caches the profile objects. - */ - protected static $_profiles = NULL; - /** * @var string $name * The name of the profile. @@ -56,6 +50,20 @@ class CRM_Twingle_Profile { ); } + /** + * Logs (production) access to this profile + * + * @return bool + */ + public function logAccess() { + CRM_Core_DAO::executeQuery(" + UPDATE civicrm_twingle_profile + SET + last_access = NOW(), + access_counter = access_counter + 1 + WHERE name = %1", [1 => [$this->name, 'String']]); + } + /** * Checks whether the profile's selector matches the given project ID. * @@ -79,7 +87,7 @@ class CRM_Twingle_Profile { * The profile's configured custom field mapping */ public function getCustomFieldMapping() { - $custom_field_mapping = array(); + $custom_field_mapping = []; if (!empty($custom_field_definition = $this->getAttribute('custom_field_mapping'))) { foreach (preg_split('/\r\n|\r|\n/', $custom_field_definition, -1, PREG_SPLIT_NO_EMPTY) as $custom_field_map) { list($twingle_field_name, $custom_field_name) = explode("=", $custom_field_map); @@ -144,7 +152,7 @@ class CRM_Twingle_Profile { */ public function setAttribute($attribute_name, $value) { if (!in_array($attribute_name, self::allowedAttributes())) { - throw new Exception(E::ts('Unknown attribute %1.', array(1 => $attribute_name))); + throw new Exception(E::ts('Unknown attribute %1.', [1 => $attribute_name])); } // TODO: Check if value is acceptable. $this->data[$attribute_name] = $value; @@ -182,17 +190,36 @@ class CRM_Twingle_Profile { * Persists the profile within the CiviCRM settings. */ public function saveProfile() { - self::$_profiles[$this->getName()] = $this; + // make sure it's valid $this->verifyProfile(); - self::storeProfiles(); + + // check if the profile exists + $profile_id = CRM_Core_DAO::singleValueQuery( + "SELECT id FROM civicrm_twingle_profile WHERE name = %1", [1 => [$this->name, 'String']]); + if ($profile_id) { + // existing profile -> just update the config + CRM_Core_DAO::executeQuery( + "UPDATE civicrm_twingle_profile SET config = %2 WHERE name = %1", + [ + 1 => [$this->name, 'String'], + 2 => [json_encode($this->data), 'String'] + ]); + } else { + // new profile -> add new entry to the DB + CRM_Core_DAO::executeQuery( + "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)", + [ + 1 => [$this->name, 'String'], + 2 => [json_encode($this->data), 'String'] + ]); + } } /** - * Deletes the profile from the CiviCRM settings. + * Deletes the profile from the database */ public function deleteProfile() { - unset(self::$_profiles[$this->getName()]); - self::storeProfiles(); + CRM_Core_DAO::executeQuery("DELETE FROM civicrm_twingle_profile WHERE name = %1", [1 => [$this->name, 'String']]); } /** @@ -202,7 +229,7 @@ class CRM_Twingle_Profile { */ public static function allowedAttributes() { return array_merge( - array( + [ 'selector', 'xcm_profile', 'location_type_id', @@ -228,7 +255,7 @@ class CRM_Twingle_Profile { 'membership_postprocess_call', 'newsletter_double_opt_in', 'required_address_components', - ), + ], // Add payment methods. array_keys(static::paymentInstruments()), @@ -245,7 +272,7 @@ class CRM_Twingle_Profile { * @return array */ public static function paymentInstruments() { - return array( + return [ 'pi_banktransfer' => E::ts('Bank transfer'), 'pi_debit_manual' => E::ts('Debit manual'), 'pi_debit_automatic' => E::ts('Debit automatic'), @@ -257,7 +284,7 @@ class CRM_Twingle_Profile { 'pi_paydirekt' => E::ts('paydirekt'), 'pi_applepay' => E::ts('Apple Pay'), 'pi_googlepay' => E::ts('Google Pay'), - ); + ]; } /** @@ -269,7 +296,7 @@ class CRM_Twingle_Profile { * @return CRM_Twingle_Profile */ public static function createDefaultProfile($name = 'default') { - return new CRM_Twingle_Profile($name, array( + return new CRM_Twingle_Profile($name, [ 'selector' => '', 'xcm_profile' => '', 'location_type_id' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, @@ -307,7 +334,7 @@ class CRM_Twingle_Profile { 'city', 'country', ], - ) + ] // Add contribution status for all payment methods. + array_fill_keys(array_map(function($attribute) { return $attribute . '_status'; @@ -344,9 +371,10 @@ class CRM_Twingle_Profile { * @return CRM_Twingle_Profile | NULL */ public static function getProfile($name) { - $profiles = self::getProfiles(); - if (isset($profiles[$name])) { - return $profiles[$name]; + $profile_data = CRM_Core_DAO::singleValueQuery("SELECT config FROM civicrm_twingle_profile WHERE name = %1", [ + 1 => [$name, 'String']]); + if ($profile_data) { + return new CRM_Twingle_Profile($name, json_decode($profile_data, 1)); } else { return NULL; @@ -360,33 +388,11 @@ class CRM_Twingle_Profile { * @return CRM_Twingle_Profile[] */ public static function getProfiles() { - if (self::$_profiles === NULL) { - self::$_profiles = array(); - if ($profiles_data = Civi::settings()->get('twingle_profiles')) { - foreach ($profiles_data as $profile_name => $profile_data) { - self::$_profiles[$profile_name] = new CRM_Twingle_Profile($profile_name, $profile_data); - } - } + $profiles = []; + $profile_data = CRM_Core_DAO::executeQuery("SELECT name, config FROM civicrm_twingle_profile"); + while ($profile_data->fetch()) { + $profiles[$profile_data->name] = new CRM_Twingle_Profile($profile_data->name, json_decode($profile_data->config, 1)); } - - // Include the default profile if it was not overridden within the settings. - if (!isset(self::$_profiles['default'])) { - self::$_profiles['default'] = self::createDefaultProfile(); - self::storeProfiles(); - } - - return self::$_profiles; - } - - - /** - * Persists the list of profiles into the CiviCRM settings. - */ - public static function storeProfiles() { - $profile_data = array(); - foreach (self::$_profiles as $profile_name => $profile) { - $profile_data[$profile_name] = $profile->data; - } - Civi::settings()->set('twingle_profiles', $profile_data); + return $profiles; } } diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 1724753..39c4c48 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -12,6 +12,9 @@ class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base { public function install() { // create a DB table for the twingle profiles $this->executeSqlFile('sql/civicrm_twingle_profile.sql'); + + // add a default profile + CRM_Twingle_Profile::createDefaultProfile()->saveProfile(); } /** From bf2a73f5194a3e3c6a2b1781ad1aedac50235b13 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Wed, 11 May 2022 21:45:55 +0200 Subject: [PATCH 064/221] [#42] log (production) access --- CRM/Twingle/Profile.php | 1 + api/v3/TwingleDonation/Submit.php | 1 + 2 files changed, 2 insertions(+) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 127622c..9ac1538 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -388,6 +388,7 @@ class CRM_Twingle_Profile { * @return CRM_Twingle_Profile[] */ public static function getProfiles() { + // todo: cache? $profiles = []; $profile_data = CRM_Core_DAO::executeQuery("SELECT name, config FROM civicrm_twingle_profile"); while ($profile_data->fetch()) { diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index abea337..22d2355 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -278,6 +278,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // Get the profile defined for the given form ID, or the default profile // if none matches. $profile = CRM_Twingle_Profile::getProfileForProject($params['project_id']); + $profile->logAccess(); // Validate submitted parameters CRM_Twingle_Submission::validateSubmission($params, $profile); From b5b34ff6782c90af052062b7c407d02160183f8f Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Thu, 12 May 2022 13:04:03 +0200 Subject: [PATCH 065/221] [#42] fix for getProfile empty name --- CRM/Twingle/Profile.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 9ac1538..e5c0faf 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -366,19 +366,19 @@ class CRM_Twingle_Profile { /** * Retrieves the profile with the given name. * - * @param $name + * @param string $name * * @return CRM_Twingle_Profile | NULL */ public static function getProfile($name) { - $profile_data = CRM_Core_DAO::singleValueQuery("SELECT config FROM civicrm_twingle_profile WHERE name = %1", [ - 1 => [$name, 'String']]); - if ($profile_data) { - return new CRM_Twingle_Profile($name, json_decode($profile_data, 1)); - } - else { - return NULL; + if (!empty($name)) { + $profile_data = CRM_Core_DAO::singleValueQuery("SELECT config FROM civicrm_twingle_profile WHERE name = %1", [ + 1 => [$name, 'String']]); + if ($profile_data) { + return new CRM_Twingle_Profile($name, json_decode($profile_data, 1)); + } } + return NULL; } /** From 65424ab4bc61924d2d1a58c807f907af85336482 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Thu, 12 May 2022 13:25:53 +0200 Subject: [PATCH 066/221] [#42] added stats --- CRM/Twingle/Page/Profiles.php | 4 +++- CRM/Twingle/Profile.php | 24 +++++++++++++++++++++++- templates/CRM/Twingle/Page/Profiles.tpl | 4 ++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index f9fad8a..eb5bf0c 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -18,7 +18,8 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Page_Profiles extends CRM_Core_Page { public function run() { - $profiles = array(); + CRM_Utils_System::setTitle(E::ts("Twingle API Profiles")); + $profiles = []; foreach (CRM_Twingle_Profile::getProfiles() as $profile_name => $profile) { $profiles[$profile_name]['name'] = $profile_name; foreach (CRM_Twingle_Profile::allowedAttributes() as $attribute) { @@ -26,6 +27,7 @@ class CRM_Twingle_Page_Profiles extends CRM_Core_Page { } } $this->assign('profiles', $profiles); + $this->assign('profile_stats', CRM_Twingle_Profile::getProfileStats()); parent::run(); } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index e5c0faf..58a8352 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -385,7 +385,8 @@ class CRM_Twingle_Profile { * Retrieves the list of all profiles persisted within the current CiviCRM * settings, including the default profile. * - * @return CRM_Twingle_Profile[] + * @return array + * profile_name => CRM_Twingle_Profile */ public static function getProfiles() { // todo: cache? @@ -396,4 +397,25 @@ class CRM_Twingle_Profile { } return $profiles; } + + /** + * Get the stats (access_count, last_access) for all twingle profiles + * + * @return CRM_Twingle_Profile[] + */ + public static function getProfileStats() { + $stats = []; + $profile_data = CRM_Core_DAO::executeQuery("SELECT name, last_access, access_counter FROM civicrm_twingle_profile"); + while ($profile_data->fetch()) { + $stats[$profile_data->name] = [ + 'name' => $profile_data->name, + 'last_access' => $profile_data->last_access, + 'last_access_txt' => $profile_data->last_access ? date('Y-m-d H:i:s', strtotime($profile_data->last_access)) : E::ts("never"), + 'access_counter' => $profile_data->access_counter, + 'access_counter_txt' => $profile_data->access_counter ? ((int) $profile_data->access_counter) . 'x' : E::ts("never"), + ]; + } + return $stats; + } + } diff --git a/templates/CRM/Twingle/Page/Profiles.tpl b/templates/CRM/Twingle/Page/Profiles.tpl index f97b9ed..b5b869e 100644 --- a/templates/CRM/Twingle/Page/Profiles.tpl +++ b/templates/CRM/Twingle/Page/Profiles.tpl @@ -26,6 +26,8 @@
    {ts domain="de.systopia.twingle"}Profile name{/ts} {ts domain="de.systopia.twingle"}Properties{/ts}{ts domain="de.systopia.twingle"}Used{/ts}{ts domain="de.systopia.twingle"}Last Used{/ts} {ts domain="de.systopia.twingle"}Operations{/ts}
    {ts domain="de.systopia.twingle"}Selector{/ts}: {$profile.selector}
    {ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.access_counter_txt}{/ts}{ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.last_access_txt}{/ts} {ts domain="de.systopia.twingle"}Edit{/ts} {ts domain="de.systopia.twingle"}Copy{/ts} From c96abd84077edcba28c4ac9f2b4971963434b726 Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Thu, 12 May 2022 13:29:16 +0200 Subject: [PATCH 067/221] [#42] added logging exception --- twingle.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/twingle.php b/twingle.php index 214d041..8551f2b 100644 --- a/twingle.php +++ b/twingle.php @@ -153,6 +153,19 @@ function twingle_civicrm_alterAPIPermissions($entity, $action, &$params, &$permi $permissions['twingle_donation']['endrecurring'] = array('access Twingle API'); } +/** + * Make sure, that the last_access and access_counter column is not logged + * + * @param array $logTableSpec + */ +function twingle_civicrm_alterLogTables(&$logTableSpec) +{ + if (isset($logTableSpec['civicrm_twingle_profile'])) { + $logTableSpec['civicrm_twingle_profile']['exceptions'] = ['last_access', 'access_counter']; + } +} + + // --- Functions below this ship commented out. Uncomment as required. --- /** From c52dc775322c47c3ca5df99de5f17748cff9018b Mon Sep 17 00:00:00 2001 From: "B. Endres" Date: Fri, 13 May 2022 10:15:28 +0200 Subject: [PATCH 068/221] [#42] migrate profiles with last_access NOW() --- CRM/Twingle/Upgrader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 39c4c48..9b3af0c 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -74,7 +74,7 @@ class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base { $profile = new CRM_Twingle_Profile($profile_name, $profile_data); $data = json_encode($profile->getData()); CRM_Core_DAO::executeQuery( - "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)", + "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, NOW(), 0)", [ 1 => [$profile_name, 'String'], 2 => [$data, 'String'] From aa0c35ca1b8c4fa24e92a73b6c49d4650b4997de Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 31 May 2022 11:00:14 +0200 Subject: [PATCH 069/221] Version 1.3 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 03da3a9..d1b4862 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.3-dev - dev + 2022-05-31 + 1.3 + stable 5.0 5.19 From 4be5471d411827c13dedb64badfa1ca84444256c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 31 May 2022 11:00:31 +0200 Subject: [PATCH 070/221] Back to dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index d1b4862..8d608de 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2022-05-31 - 1.3 - stable + + 1.4-dev + dev 5.0 5.19 From c1a1dce52e41776fae9d8835082e087382e76b2c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 31 May 2022 11:02:47 +0200 Subject: [PATCH 071/221] Version 1.4-alpha1 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 8d608de..26bc22d 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.4-dev - dev + 2022-05-31 + 1.4-alpha1 + alpha 5.0 5.19 From 29e0b50cd15ed014a6ccb2310ee2f28acd36269f Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 31 May 2022 11:03:04 +0200 Subject: [PATCH 072/221] Back to dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 26bc22d..8d608de 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2022-05-31 - 1.4-alpha1 - alpha + + 1.4-dev + dev 5.0 5.19 From d3c07c10fa031d27db59157a961bd12496d89da0 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 27 Jun 2022 17:28:53 +0200 Subject: [PATCH 073/221] [#50] Include user_extrafield in custom_field_mapping --- api/v3/TwingleDonation/Submit.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 22d2355..4e3e6dd 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -304,6 +304,12 @@ function civicrm_api3_twingle_donation_Submit($params) { if (!empty($params['custom_fields'])) { $custom_field_mapping = $profile->getCustomFieldMapping(); + // Include user_extrafield in custom_field_mapping if it is referenced there. + // See issue #50. + if(!empty($params['user_extrafield']) && isset($custom_field_mapping['user_extrafield'])) { + $params['custom_fields']['user_extrafield'] = $params['user_extrafield']; + } + foreach ($params['custom_fields'] as $twingle_field => $value) { if (isset($custom_field_mapping[$twingle_field])) { // Get custom field definition to store values by entity the field From 40842ae325caaeb5320715be32604fe9fbe04942 Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 21 Dec 2022 15:10:56 +0100 Subject: [PATCH 074/221] [#58] civix upgrade --- info.xml | 11 +- mixin/menu-xml@1.0.0.mixin.php | 31 ++++++ mixin/polyfill.php | 101 +++++++++++++++++++ twingle.civix.php | 179 ++++----------------------------- twingle.php | 70 ++----------- 5 files changed, 168 insertions(+), 224 deletions(-) create mode 100644 mixin/menu-xml@1.0.0.mixin.php create mode 100644 mixin/polyfill.php diff --git a/info.xml b/info.xml index 8d608de..6dd8a90 100644 --- a/info.xml +++ b/info.xml @@ -14,18 +14,25 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - + 1.4-dev dev 5.0 5.19 - + de.systopia.xcm CRM/Twingle + 22.10.0 + + menu-xml@1.0.0 + + + + diff --git a/mixin/menu-xml@1.0.0.mixin.php b/mixin/menu-xml@1.0.0.mixin.php new file mode 100644 index 0000000..4c0b227 --- /dev/null +++ b/mixin/menu-xml@1.0.0.mixin.php @@ -0,0 +1,31 @@ +addListener('hook_civicrm_xmlMenu', function ($e) use ($mixInfo) { + if (!$mixInfo->isActive()) { + return; + } + + $files = (array) glob($mixInfo->getPath('xml/Menu/*.xml')); + foreach ($files as $file) { + $e->files[] = $file; + } + }); + +}; diff --git a/mixin/polyfill.php b/mixin/polyfill.php new file mode 100644 index 0000000..f57c5eb --- /dev/null +++ b/mixin/polyfill.php @@ -0,0 +1,101 @@ +')) { + $mixinVers[$name] = $ver; + } + } + $mixins = []; + foreach ($mixinVers as $name => $ver) { + $mixins[] = "$name@$ver"; + } + + // Imitate CRM_Extension_MixInfo. + $mixInfo = new class() { + + /** + * @var string + */ + public $longName; + + /** + * @var string + */ + public $shortName; + + public $_basePath; + + public function getPath($file = NULL) { + return $this->_basePath . ($file === NULL ? '' : (DIRECTORY_SEPARATOR . $file)); + } + + public function isActive() { + return \CRM_Extension_System::singleton()->getMapper()->isActiveModule($this->shortName); + } + + }; + $mixInfo->longName = $longName; + $mixInfo->shortName = $shortName; + $mixInfo->_basePath = $basePath; + + // Imitate CRM_Extension_BootCache. + $bootCache = new class() { + + public function define($name, $callback) { + $envId = \CRM_Core_Config_Runtime::getId(); + $oldExtCachePath = \Civi::paths()->getPath("[civicrm.compile]/CachedExtLoader.{$envId}.php"); + $stat = stat($oldExtCachePath); + $file = Civi::paths()->getPath('[civicrm.compile]/CachedMixin.' . md5($name . ($stat['mtime'] ?? 0)) . '.php'); + if (file_exists($file)) { + return include $file; + } + else { + $data = $callback(); + file_put_contents($file, '<' . "?php\nreturn " . var_export($data, 1) . ';'); + return $data; + } + } + + }; + + // Imitate CRM_Extension_MixinLoader::run() + // Parse all live mixins before trying to scan any classes. + global $_CIVIX_MIXIN_POLYFILL; + foreach ($mixins as $mixin) { + // If the exact same mixin is defined by multiple exts, just use the first one. + if (!isset($_CIVIX_MIXIN_POLYFILL[$mixin])) { + $_CIVIX_MIXIN_POLYFILL[$mixin] = include_once $basePath . '/mixin/' . $mixin . '.mixin.php'; + } + } + foreach ($mixins as $mixin) { + // If there's trickery about installs/uninstalls/resets, then we may need to register a second time. + if (!isset(\Civi::$statics[__FUNCTION__][$mixin])) { + \Civi::$statics[__FUNCTION__][$mixin] = 1; + $func = $_CIVIX_MIXIN_POLYFILL[$mixin]; + $func($mixInfo, $bootCache); + } + } +}; diff --git a/twingle.civix.php b/twingle.civix.php index c407f6f..4cd74d1 100644 --- a/twingle.civix.php +++ b/twingle.civix.php @@ -24,7 +24,7 @@ class CRM_Twingle_ExtensionUtil { * Translated text. * @see ts */ - public static function ts($text, $params = []) { + public static function ts($text, $params = []): string { if (!array_key_exists('domain', $params)) { $params['domain'] = [self::LONG_NAME, NULL]; } @@ -41,7 +41,7 @@ class CRM_Twingle_ExtensionUtil { * Ex: 'http://example.org/sites/default/ext/org.example.foo'. * Ex: 'http://example.org/sites/default/ext/org.example.foo/css/foo.css'. */ - public static function url($file = NULL) { + public static function url($file = NULL): string { if ($file === NULL) { return rtrim(CRM_Core_Resources::singleton()->getUrl(self::LONG_NAME), '/'); } @@ -79,6 +79,13 @@ class CRM_Twingle_ExtensionUtil { use CRM_Twingle_ExtensionUtil as E; +function _twingle_civix_mixin_polyfill() { + if (!class_exists('CRM_Extension_MixInfo')) { + $polyfill = __DIR__ . '/mixin/polyfill.php'; + (require $polyfill)(E::LONG_NAME, E::SHORT_NAME, E::path()); + } +} + /** * (Delegated) Implements hook_civicrm_config(). * @@ -91,9 +98,9 @@ function _twingle_civix_civicrm_config(&$config = NULL) { } $configured = TRUE; - $template =& CRM_Core_Smarty::singleton(); + $template = CRM_Core_Smarty::singleton(); - $extRoot = dirname(__FILE__) . DIRECTORY_SEPARATOR; + $extRoot = __DIR__ . DIRECTORY_SEPARATOR; $extDir = $extRoot . 'templates'; if (is_array($template->template_dir)) { @@ -105,19 +112,7 @@ function _twingle_civix_civicrm_config(&$config = NULL) { $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); -} - -/** - * (Delegated) Implements hook_civicrm_xmlMenu(). - * - * @param $files array(string) - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_xmlMenu - */ -function _twingle_civix_civicrm_xmlMenu(&$files) { - foreach (_twingle_civix_glob(__DIR__ . '/xml/Menu/*.xml') as $file) { - $files[] = $file; - } + _twingle_civix_mixin_polyfill(); } /** @@ -130,6 +125,7 @@ function _twingle_civix_civicrm_install() { if ($upgrader = _twingle_civix_upgrader()) { $upgrader->onInstall(); } + _twingle_civix_mixin_polyfill(); } /** @@ -151,7 +147,7 @@ function _twingle_civix_civicrm_postInstall() { * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall */ -function _twingle_civix_civicrm_uninstall() { +function _twingle_civix_civicrm_uninstall(): void { _twingle_civix_civicrm_config(); if ($upgrader = _twingle_civix_upgrader()) { $upgrader->onUninstall(); @@ -163,13 +159,14 @@ function _twingle_civix_civicrm_uninstall() { * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable */ -function _twingle_civix_civicrm_enable() { +function _twingle_civix_civicrm_enable(): void { _twingle_civix_civicrm_config(); if ($upgrader = _twingle_civix_upgrader()) { if (is_callable([$upgrader, 'onEnable'])) { $upgrader->onEnable(); } } + _twingle_civix_mixin_polyfill(); } /** @@ -178,7 +175,7 @@ function _twingle_civix_civicrm_enable() { * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable * @return mixed */ -function _twingle_civix_civicrm_disable() { +function _twingle_civix_civicrm_disable(): void { _twingle_civix_civicrm_config(); if ($upgrader = _twingle_civix_upgrader()) { if (is_callable([$upgrader, 'onDisable'])) { @@ -217,136 +214,6 @@ function _twingle_civix_upgrader() { } } -/** - * Search directory tree for files which match a glob pattern. - * - * Note: Dot-directories (like "..", ".git", or ".svn") will be ignored. - * Note: Delegate to CRM_Utils_File::findFiles(), this function kept only - * for backward compatibility of extension code that uses it. - * - * @param string $dir base dir - * @param string $pattern , glob pattern, eg "*.txt" - * - * @return array - */ -function _twingle_civix_find_files($dir, $pattern) { - return CRM_Utils_File::findFiles($dir, $pattern); -} - -/** - * (Delegated) Implements hook_civicrm_managed(). - * - * Find any *.mgd.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_managed - */ -function _twingle_civix_civicrm_managed(&$entities) { - $mgdFiles = _twingle_civix_find_files(__DIR__, '*.mgd.php'); - sort($mgdFiles); - foreach ($mgdFiles as $file) { - $es = include $file; - foreach ($es as $e) { - if (empty($e['module'])) { - $e['module'] = E::LONG_NAME; - } - if (empty($e['params']['version'])) { - $e['params']['version'] = '3'; - } - $entities[] = $e; - } - } -} - -/** - * (Delegated) Implements hook_civicrm_caseTypes(). - * - * Find any and return any files matching "xml/case/*.xml" - * - * Note: This hook only runs in CiviCRM 4.4+. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_caseTypes - */ -function _twingle_civix_civicrm_caseTypes(&$caseTypes) { - if (!is_dir(__DIR__ . '/xml/case')) { - return; - } - - foreach (_twingle_civix_glob(__DIR__ . '/xml/case/*.xml') as $file) { - $name = preg_replace('/\.xml$/', '', basename($file)); - if ($name != CRM_Case_XMLProcessor::mungeCaseType($name)) { - $errorMessage = sprintf("Case-type file name is malformed (%s vs %s)", $name, CRM_Case_XMLProcessor::mungeCaseType($name)); - throw new CRM_Core_Exception($errorMessage); - } - $caseTypes[$name] = [ - 'module' => E::LONG_NAME, - 'name' => $name, - 'file' => $file, - ]; - } -} - -/** - * (Delegated) Implements hook_civicrm_angularModules(). - * - * Find any and return any files matching "ang/*.ang.php" - * - * Note: This hook only runs in CiviCRM 4.5+. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_angularModules - */ -function _twingle_civix_civicrm_angularModules(&$angularModules) { - if (!is_dir(__DIR__ . '/ang')) { - return; - } - - $files = _twingle_civix_glob(__DIR__ . '/ang/*.ang.php'); - foreach ($files as $file) { - $name = preg_replace(':\.ang\.php$:', '', basename($file)); - $module = include $file; - if (empty($module['ext'])) { - $module['ext'] = E::LONG_NAME; - } - $angularModules[$name] = $module; - } -} - -/** - * (Delegated) Implements hook_civicrm_themes(). - * - * Find any and return any files matching "*.theme.php" - */ -function _twingle_civix_civicrm_themes(&$themes) { - $files = _twingle_civix_glob(__DIR__ . '/*.theme.php'); - foreach ($files as $file) { - $themeMeta = include $file; - if (empty($themeMeta['name'])) { - $themeMeta['name'] = preg_replace(':\.theme\.php$:', '', basename($file)); - } - if (empty($themeMeta['ext'])) { - $themeMeta['ext'] = E::LONG_NAME; - } - $themes[$themeMeta['name']] = $themeMeta; - } -} - -/** - * Glob wrapper which is guaranteed to return an array. - * - * The documentation for glob() says, "On some systems it is impossible to - * distinguish between empty match and an error." Anecdotally, the return - * result for an empty match is sometimes array() and sometimes FALSE. - * This wrapper provides consistency. - * - * @link http://php.net/glob - * @param string $pattern - * - * @return array - */ -function _twingle_civix_glob($pattern) { - $result = glob($pattern); - return is_array($result) ? $result : []; -} - /** * Inserts a navigation menu item at a given place in the hierarchy. * @@ -429,18 +296,6 @@ function _twingle_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) { } } -/** - * (Delegated) Implements hook_civicrm_alterSettingsFolders(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_alterSettingsFolders - */ -function _twingle_civix_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) { - $settingsDir = __DIR__ . DIRECTORY_SEPARATOR . 'settings'; - if (!in_array($settingsDir, $metaDataFolders) && is_dir($settingsDir)) { - $metaDataFolders[] = $settingsDir; - } -} - /** * (Delegated) Implements hook_civicrm_entityTypes(). * diff --git a/twingle.php b/twingle.php index 8551f2b..0e72d8e 100644 --- a/twingle.php +++ b/twingle.php @@ -21,15 +21,6 @@ function twingle_civicrm_config(&$config) { _twingle_civix_civicrm_config($config); } -/** - * Implements hook_civicrm_xmlMenu(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu - */ -function twingle_civicrm_xmlMenu(&$files) { - _twingle_civix_civicrm_xmlMenu($files); -} - /** * Implements hook_civicrm_install(). * @@ -84,54 +75,6 @@ function twingle_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { return _twingle_civix_civicrm_upgrade($op, $queue); } -/** - * Implements hook_civicrm_managed(). - * - * Generate a list of entities to create/deactivate/delete when this module - * is installed, disabled, uninstalled. - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed - */ -function twingle_civicrm_managed(&$entities) { - _twingle_civix_civicrm_managed($entities); -} - -/** - * Implements hook_civicrm_caseTypes(). - * - * Generate a list of case-types. - * - * Note: This hook only runs in CiviCRM 4.4+. - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes - */ -function twingle_civicrm_caseTypes(&$caseTypes) { - _twingle_civix_civicrm_caseTypes($caseTypes); -} - -/** - * Implements hook_civicrm_angularModules(). - * - * Generate a list of Angular modules. - * - * Note: This hook only runs in CiviCRM 4.5+. It may - * use features only available in v4.6+. - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_angularModules - */ -function twingle_civicrm_angularModules(&$angularModules) { - _twingle_civix_civicrm_angularModules($angularModules); -} - -/** - * Implements hook_civicrm_alterSettingsFolders(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders - */ -function twingle_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) { - _twingle_civix_civicrm_alterSettingsFolders($metaDataFolders); -} - /** * Implements hook_civicrm_permission(). * @@ -165,7 +108,6 @@ function twingle_civicrm_alterLogTables(&$logTableSpec) } } - // --- Functions below this ship commented out. Uncomment as required. --- /** @@ -173,9 +115,8 @@ function twingle_civicrm_alterLogTables(&$logTableSpec) * * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_preProcess * -function twingle_civicrm_preProcess($formName, &$form) { -} // */ + // */ /** * Implements hook_civicrm_navigationMenu(). @@ -193,3 +134,12 @@ function twingle_civicrm_navigationMenu(&$menu) { )); _twingle_civix_navigationMenu($menu); } // */ + +/** + * Implements hook_civicrm_entityTypes(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes + */ +function twingle_civicrm_entityTypes(&$entityTypes) { + _twingle_civix_civicrm_entityTypes($entityTypes); +} From 92d15e7c7cda42ab0607ed1a6fc153c96faf753a Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 14 Feb 2023 09:27:04 +0100 Subject: [PATCH 075/221] [#61] fix bug on settings page The array passed to $this->addEntityRef() was incorrectly structured --- CRM/Twingle/Form/Settings.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index dba6a28..631fb05 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -90,12 +90,16 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { ); $this->addEntityRef( - 'twingle_protect_recurring_activity_assignee', - E::ts('Assigned To'), - [ - 'contact_type' => ['IN' => ['Individual', 'Organization']], + 'twingle_protect_recurring_activity_assignee', + E::ts('Assigned To'), + [ + 'api' => [ + 'params' => [ + 'contact_type' => ['IN' => ['Individual', 'Organization']], 'check_permissions' => 0, - ] + ], + ], + ] ); $this->addButtons(array( From 6132e7ad8023603843f0d0619e6eb50ea7a26a85 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 16 Feb 2023 13:34:56 +0100 Subject: [PATCH 076/221] Add new payment methods --- CRM/Twingle/Profile.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 58a8352..4491fbe 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -284,6 +284,11 @@ class CRM_Twingle_Profile { 'pi_paydirekt' => E::ts('paydirekt'), 'pi_applepay' => E::ts('Apple Pay'), 'pi_googlepay' => E::ts('Google Pay'), + 'paydirekt' => E::ts('Paydirekt'), + 'twint' => E::ts('Twint'), + 'ideal' => E::ts('iDEAL'), + 'post_finance' => E::ts('Postfinance'), + 'bancontact' => E::ts('Bancontact'), ]; } @@ -314,6 +319,11 @@ class CRM_Twingle_Profile { 'pi_paydirekt' => NULL, 'pi_applepay' => NULL, 'pi_googlepay' => NULL, + 'pi_paydirekt' => NULL, + 'pi_twint' => NULL, + 'pi_ideal' => NULL, + 'pi_post_finance' => NULL, + 'pi_bancontact' => NULL, 'sepa_creditor_id' => NULL, 'gender_male' => 2, 'gender_female' => 1, From f5c212780549506cb0a8a38657fe7a2ddc97443e Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 6 Mar 2023 15:43:06 +0100 Subject: [PATCH 077/221] Version 1.4-alpha2 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 6dd8a90..b9e9b67 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.4-dev - dev + 2023-03-06 + 1.4-alpha2 + alpha 5.0 5.19 From 30ad4635495905c976af4eddf8d6a112e7a521f1 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 6 Mar 2023 15:52:07 +0100 Subject: [PATCH 078/221] Back to dev --- info.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/info.xml b/info.xml index b9e9b67..abcb061 100644 --- a/info.xml +++ b/info.xml @@ -14,14 +14,14 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2023-03-06 - 1.4-alpha2 - alpha + + 1.4-dev + dev 5.0 5.19 - + de.systopia.xcm From 4d750b1ab6d79f16632e7608170536854fe55d6c Mon Sep 17 00:00:00 2001 From: Michael Amos Date: Mon, 13 Mar 2023 16:04:08 +0100 Subject: [PATCH 079/221] Documentation update. --- README.md | 163 ++++++-------------------------------- docs/Img/GenSet.jpg | Bin 0 -> 53231 bytes docs/Img/Kon_syn.jpg | Bin 0 -> 31786 bytes docs/Img/Konso.jpg | Bin 0 -> 97730 bytes docs/Img/NewUser_Tw.jpg | Bin 0 -> 69695 bytes docs/Img/ProNam.jpg | Bin 0 -> 42206 bytes docs/Img/Prof.jpg | Bin 0 -> 17061 bytes docs/Img/Role_Twingle.jpg | Bin 0 -> 61856 bytes docs/Img/Sepa.jpg | Bin 0 -> 20359 bytes docs/Img/SepaKon.jpg | Bin 0 -> 11939 bytes docs/Img/Twgrou.jpg | Bin 0 -> 36329 bytes docs/Img/Twin_per.png | Bin 0 -> 23633 bytes docs/Img/XCMAdmin.jpg | Bin 0 -> 285376 bytes docs/Img/XCMAkt.jpg | Bin 0 -> 50023 bytes docs/Img/XCMDup.jpg | Bin 0 -> 18558 bytes docs/Img/XCMGen.jpg | Bin 0 -> 67917 bytes docs/Img/XCMIde.jpg | Bin 0 -> 29646 bytes docs/Img/XCMNeu.jpg | Bin 0 -> 32150 bytes docs/Img/XCMPro.jpg | Bin 0 -> 124673 bytes docs/Img/XCMReg.jpg | Bin 0 -> 77742 bytes docs/Img/XCMUpda.jpg | Bin 0 -> 160490 bytes docs/Img/XCM_Profile.jpg | Bin 0 -> 78872 bytes docs/Img/apikey.jpg | Bin 0 -> 45799 bytes docs/Img/civiuser_tw.jpg | Bin 0 -> 50279 bytes docs/Img/twpay.jpg | Bin 0 -> 72798 bytes docs/Img/xcmdif.jpg | Bin 0 -> 8027 bytes docs/api_tw.md | 87 ++++++++++++++++++++ docs/con_civi.md | 39 +++++++++ docs/con_drup.md | 41 ++++++++++ docs/con_man.md | 22 +++++ docs/con_tw.md | 31 ++++++++ docs/con_twse.md | 25 ++++++ docs/con_xcm.md | 59 ++++++++++++++ docs/install_tw.md | 12 +++ mkdocs.yml | 12 ++- 35 files changed, 350 insertions(+), 141 deletions(-) create mode 100644 docs/Img/GenSet.jpg create mode 100644 docs/Img/Kon_syn.jpg create mode 100644 docs/Img/Konso.jpg create mode 100644 docs/Img/NewUser_Tw.jpg create mode 100644 docs/Img/ProNam.jpg create mode 100644 docs/Img/Prof.jpg create mode 100644 docs/Img/Role_Twingle.jpg create mode 100644 docs/Img/Sepa.jpg create mode 100644 docs/Img/SepaKon.jpg create mode 100644 docs/Img/Twgrou.jpg create mode 100644 docs/Img/Twin_per.png create mode 100644 docs/Img/XCMAdmin.jpg create mode 100644 docs/Img/XCMAkt.jpg create mode 100644 docs/Img/XCMDup.jpg create mode 100644 docs/Img/XCMGen.jpg create mode 100644 docs/Img/XCMIde.jpg create mode 100644 docs/Img/XCMNeu.jpg create mode 100644 docs/Img/XCMPro.jpg create mode 100644 docs/Img/XCMReg.jpg create mode 100644 docs/Img/XCMUpda.jpg create mode 100644 docs/Img/XCM_Profile.jpg create mode 100644 docs/Img/apikey.jpg create mode 100644 docs/Img/civiuser_tw.jpg create mode 100644 docs/Img/twpay.jpg create mode 100644 docs/Img/xcmdif.jpg create mode 100644 docs/api_tw.md create mode 100644 docs/con_civi.md create mode 100644 docs/con_drup.md create mode 100644 docs/con_man.md create mode 100644 docs/con_tw.md create mode 100644 docs/con_twse.md create mode 100644 docs/con_xcm.md create mode 100644 docs/install_tw.md diff --git a/README.md b/README.md index 9b4fec0..98fa866 100644 --- a/README.md +++ b/README.md @@ -1,160 +1,45 @@ -# Twingle API +# CiviCRM extension Twingle API[¶](https://docs.civicrm.org/twingle/en/latest/#twingle-api "Permanent link") -Extension to connect to the Twingle fundraising service via its API. +Twingle is a payment service provider that makes it possible to create donation forms with various payment options and embed them on websites or integrate them into your homepage. Interested parties can donate via known payment options (e.g. credit card, PayPal). The procedure is also set up and optimised for mobile devices. If you want to use the Twingle fundraising service, you have to set up a corresponding online account. -* [About Twingle](https://www.twingle.de/) +For further information about Twingle fundraising follow [this link](https://www.twingle.de/). -The extension is licensed under -[AGPL-3.0](https://github.com/systopia/de.systopia.twingle/blob/master/LICENSE.txt). +Twingle as fundraising service can be connected to CiviCRM via its API with the extension **Twingle API**. -## Configuration +## What advantages does the Twingle API extension offer? -### Configure Twingle +- Donations from Twingle can be automatically created in CiviCRM and assigned to existing or new contacts and administered yourself in CiviCRM. -Please refer to the -[Twingle FAQ on using Twingle with CiviCRM](https://support.twingle.de/faq/de-de/9/46) -(currently only available in German). +- Supporters and contacts of donations can be managed yourself in CiviCRM and contacts yourself. -### Configure Extended Contact Matcher (XCM) +- Donations can be declared as closed or open depending on the payment type -Make sure you use an XCM profile with the option *Match contacts by contact ID* -enabled. +- SEPA mandates can be created for one-off and recurring payments. -Be careful when enabling the *"Change Primary Detail?"* option. While it might -appear useful to update even primary contact details, this might lead to a -loss of contact information due to the fact that along with a submission that -contains e.g. a PayPal donation the `user_country` is transmitted as the only -address detail. The `user_country` then will be treated by the XCM as a whole -new address. So the contact may end up with a new address that contains only -the country. +- Donors can be entered into groups for newsletters, mailings and donation receipts. -### Configure CiviCRM +- A memberships can be set up for a donor. -- Go to the Administration console at `/civicrm/admin` -- Open "Twingle API Configuration" at `/civicrm/admin/settings/twingle` +- Data can be entered in user-defined fields -#### Configure CiviSEPA integration +## How to set up the Twingle API extension -Open "Configure extension settings" at -`/civicrm/admin/settings/twingle/settings` and configure whether to integrate -with the [CiviSEPA](https://github.com/project60/org.project60.sepa) extension. +Following the successful installation of the Twingle API extension, there is some configuration work to do in order to set up the smooth connection between CiviCRM and Twingle fundraising service. -This enables you to map incoming donations from Twingle with a specific payment -method (e.g. *debit_manual*) to be processed with CiviSEPA, that is, creating a -SEPA mandate and managing recurring payments. +You have to carry out the following configuration steps: -#### Configure profiles +- Creating a Twingle user and a user role in your CMS-System (Drupal, Wordpress ...) -Open "Configure profiles" at `/civicrm/admin/settings/twingle/profiles`. +- Configuring the Extended Contact Matcher (XCM) in CiviCRM -The *default* profile is used whenever the plugin cannot match the Twingle -project ID from any other profile. Therefore the default profile will be used -for all newly created Twingle projects. +- Creating a Twingle User and an API key in CiviCRM -| Label | Description | -|---------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Profile name | Internal name, used inside the extension. | -| Project IDs | Twingle project IDs. Separate multiple IDs with commas. | -| Location type | Specify how the address data sent by the form should be categorised in CiviCRM. The list is based on your CiviCRM configuration. | -| Location type for organisations | Specify how the address data sent by the form should be categorised in CiviCRM for organisational donations. The list is based on your CiviCRM configuration. | -| Financial type | Specify which financial type incoming one-time donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. | -| Financial type (recurring) | Specify which financial type incoming recurring donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. | -| CiviSEPA creditor | When enabled to integrate with CiviSEPA, specify the CiviSEPA creditor to use. | -| Gender options | Specify which CiviCRM gender option the incoming Twingle gender value should be mapped to. The list is based on your CiviCRM configuration. | -| Record *Payment method* as | Specifiy the payment methods mapping for incoming donations for each Twingle payment method. | -| Double Opt-In | Let CiviCRM handle the double opt-in. Group memberships for newsletter mailing lists stay pending until the subscription gets confirmed. Note that this only works for public mailing lists. Any non-public mailing list will be ignored. Do not forget to disable Twingle's double opt-in option in the Twingle Manager. | -| Sign up for groups | Whenever the donor checked the newsletter/postal mailing/donation receipt checkbox on the Twingle form, the contact will be added to the groups listed here. | -| Assign donation to campaign | The donation will be assigned to the selected campaign. If a campaign ID is being submitted using the `campaign_id` parameter, this setting will be overridden with the submitted value. | -| Create membership of type | A membership of the selected type will be created for the Individual contact for incoming one-time donations. If no membership type is selected, no membership will be created. | -| Create membership of type (recurring) | A membership of the selected type will be created for the Individual contact for incoming recurring donations. If no membership type is selected, no membership will be created. | -| Contribution source | The configured value will be set as the "Source" field for the contribution. | -| Custom field mapping | Additional field values may be set to CiviCRM custom fields using a mapping. See the option's help text for the exact format. | +- Activating the SEPA connection in CiviCRM + +- Configuring the Twingle profile in CiviCRM + +- Configuring your Twingle Account on the Twingle website -## API documentation -The extension provides a new CiviCRM API entity `TwingleDonation` with API -actions to record a new donation, end a previously submitted recurring donation -and cancel previously submitted donation. - -### Submit donation - -This API action processes submitted Twingle donations and donor information. - -- Entity: `TwingleDonation` -- Action: `Submit` - -The action accepts the following parameters: - -| Parameter | Type | Description | Values/Format | Required | -|----------------------------------------|---------|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------| -| `project_id` | String | The Twingle project ID | | Yes | -| `trx_id` | String | The unique transaction ID of the donation | A unique transaction ID for the donation. | Yes | -| `confirmed_at` | String | The date when the donation was issued | A string representing a date in the format `YmdHis` | Yes | -| `purpose` | String | The purpose of the donation | | | -| `amount` | Integer | The donation amount in minor currency unit | | Yes | -| `currency` | String | The ISO-4217 currency code of the donation | A valid ISO-4217 currency code | Yes | -| `newsletter` | Boolean | Whether to subscribe the contact to the newsletter group defined in the profile | | | -| `postinfo` | Boolean | Whether to subscribe the contact to the postal mailing group defined in the profile | | | -| `donation_receipt` | Boolean | Whether the contact requested a donation receipt | | | -| `payment_method` | String | The Twingle payment method used for the donation | One of:
    • `banktransfer`
    • `debit_manual`
    • `debit_automatic`
    • `creditcard`
    • `mobilephone_germany`
    • `paypal`
    • `sofortueberweisung`
    • `amazonpay`
    • `paydirekt`
    • `applepay`
    • `googlepay`
    | Yes | -| `donation_rhythm` | String | The interval which the donation is recurring in | One of:
    • `'one_time',`
    • `'halfyearly',`
    • `'quarterly',`
    • `'yearly',`
    • `'monthly'`
    | Yes | -| `debit_iban` | String | The IBAN for SEPA Direct Debit payments | A valid ISO 13616-1:2007 IBAN | Yes, if `payment_method` is `debit_manual` and CiviSEPA is used | -| `debit_bic` | String | The BIC for SEPA Direct Debit payments | A valid ISO 9362 BIC | Yes, if `payment_method` is `debit_manual` and CiviSEPA is used | -| `debit_mandate_reference` | String | The mandate reference for SEPA Direct Debit payments | | | -| `debit_account_holder` | String | The account holder for SEPA Direct Debit payments | | | -| `is_anonymous` | Boolean | Whether the donation is submitted anonymously | | | -| `user_gender` | String | The gender of the contact | | | -| `user_birthdate` | String | The date of birth of the contact | A string representing a date in the format `Ymd` | | -| `user_title` | String | The formal title of the contact | | | -| `user_email` | String | The e-mail address of the contact | A valid e-mail address | | -| `user_firstname` | String | The first name of the contact | | | -| `user_lastname` | String | The last name of the contact | | | -| `user_street` | String | The street address of the contact | | | -| `user_postal_code` | String | The postal code of the contact | | | -| `user_city` | String | The city of the contact | | | -| `user_country` | String | The country of the contact | A [ISO 3166-1 Alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) | | -| `user_telephone` | String | The telephone number of the contact | | | -| `user_company` | String | The company of the contact | | | -| `user_extrafield` | String | Additional information of the contact | | | -| `user_language` | String | The preferred language of the contact. | A [ISO-639-1 2-digit language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) | | -| `campaign_id` | Integer | The CiviCRM ID of a campaign to assign the contribution | A valid CiviCRM Campaign ID. This overrides the campaign ID configured within the profile. | | - -You may also refer to -[the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Submit.php) -for more insight into this API action. - -### End recurring donation - -- Entity: `TwingleDonation` -- Action: `Endrecurring` - -The action accepts the following parameters: - -| Parameter | Type | Description | Values/Format | Required | -|---------------------------|---------|------------------------------------------------|-------------------------------------------------------|----------| -| `project_id` | String | The Twingle project ID | | Yes | -| `trx_id` | String | The unique transaction ID of the donation | A unique transaction ID for the donation. | Yes | -| `ended_at` | Integer | The date when the recurring donation was ended | A string representing a date in the format `YmdHis` | Yes | - -You may also refer to -[the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Endrecurring.php) -for more insight into this API action. - -### Cancel donation - -- Entity: `TwingleDonation` -- Action: `Cancel` - -The action accepts the following parameters: - -| Parameter | Type | Description | Values/Format | Required | -|------------------------------|--------|----------------------------------------------------|-------------------------------------------------------|----------| -| `project_id` | String | The Twingle project ID | | Yes | -| `trx_id` | String | The unique transaction ID of the donation | A unique transaction ID for the donation. | Yes | -| `cancelled_at` | String | The date when the recurring donation was cancelled | A string representing a date in the format `YmdHis` | Yes | -| `cancel_reason` | String | The reason for the donation being cancelled | | Yes | - -You may also refer to -[the code](https://github.com/systopia/de.systopia.twingle/blob/master/api/v3/TwingleDonation/Cancel.php) -for more insight into this API action. \ No newline at end of file +The Twingle API extension is licensed under [AGPL-3.0](https://github.com/systopia/de.systopia.twingle/blob/master/LICENSE.txt). \ No newline at end of file diff --git a/docs/Img/GenSet.jpg b/docs/Img/GenSet.jpg new file mode 100644 index 0000000000000000000000000000000000000000..072f50f57f315b9f42ee4c0a0d50ddd8cae186e1 GIT binary patch literal 53231 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 literal 0 HcmV?d00001 diff --git a/docs/Img/Kon_syn.jpg b/docs/Img/Kon_syn.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c9ba9d52f34844ffb2f3256d34ef1f1379f3a6de GIT binary patch literal 31786 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 literal 0 HcmV?d00001 diff --git a/docs/Img/Konso.jpg b/docs/Img/Konso.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5dfb07e26c07dfdd774ff69f4c279a1f57ff0c12 GIT binary patch literal 97730 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ɠQ#Cd3`o*rj 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 KLN^Zm#{D;&V!s*y literal 0 HcmV?d00001 diff --git a/docs/Img/ProNam.jpg b/docs/Img/ProNam.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf5e906dd9124851520582f15207f20c5d2f7bc1 GIT binary patch literal 42206 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 EFQraQhX4Qo literal 0 HcmV?d00001 diff --git a/docs/Img/Prof.jpg b/docs/Img/Prof.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d8246b428fc6c331752baa864a9dbe2d7d17e33b GIT binary patch literal 17061 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 CW8o$M literal 0 HcmV?d00001 diff --git a/docs/Img/Role_Twingle.jpg b/docs/Img/Role_Twingle.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b686527c4d9bcafe6834afeeb2da4bb5d0c6e4df GIT binary patch literal 61856 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 literal 0 HcmV?d00001 diff --git a/docs/Img/SepaKon.jpg b/docs/Img/SepaKon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9b8793e6a53d81cf99518806fe5486f17f6bf454 GIT binary patch literal 11939 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 literal 0 HcmV?d00001 diff --git a/docs/Img/Twin_per.png b/docs/Img/Twin_per.png new file mode 100644 index 0000000000000000000000000000000000000000..1ea0e10adcf5684b7512a6eaf97d467463b9da90 GIT binary patch literal 23633 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 QPE-R>fAX;CSF2b50lw29XaE2J literal 0 HcmV?d00001 diff --git a/docs/Img/XCMAdmin.jpg b/docs/Img/XCMAdmin.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ad6f9286050f8e6c64bad97fbedaa8b0c961b76 GIT binary patch literal 285376 zcmeFZbx<8mw>P?hAi>?;-Q8V-I~#W=cU~b# zbN~A4R(G&IbA)eiVy3&KY@_z$p%Fwjs) ze;F*$0Z<=c{uaV~fct;|j|fc!`wT%9q2(8pkXJWzjm&Im{YkgX$;~5^)F2sLRMz*Ko>xFhTEW^UYjnufq?paPSBp{}!8K{Ouz&6bv*B3_QXI1O#}D|0)H*!u@R?9vg>(l1e=ZfrC>c z`S;aFTxtnPv)MU3F1J2DZQYc#7RV9}H;?tVX?y&U5{iy4T&1NNVTT2Cg$p2?m$^(;RHbO(CI1oW#akk_f82A)cs#) z$CKyD$+Cm)-T@t4*3*Y3&lvB3^I+)WsArv$Ij((A{dO|p1o5UVxhL@YmzWwf zYw*4MpXZ!pDz$=-z29vph>=|dEKdae-EXxyqhy&FA^icA^ZrcD5Z%1P8^I#4;CrBy zzcMD{#qW%q0c%-{29~ftdlN;H{e~?l0pr5D`JtBuDkm+FEo6=CdJ*elGQ+$Nz3#?9 zTntQVjiJ~N-uHVfHZFiGv802y{K|T!pdC6@XKe&8h1V4S&>W(=B4?9wI6VUqPCPj3 zmw`l;*m!bh5=x1f`$|4dmFOt-l-iDDKDPFfyW07~rw|&Xi|K>Cy2FQ0*@~13Gkd4i z2Jl1&GLPpR^l~apEIO(^#8GkZ`)7U;gGtIL>AMa$br!0z!n!>8^=)O|8!|9A8-8a- z@VFW2rpXPQe_jJ&L!}q&wLFR{pJ~yjEZs>bY7`cC&fCmaEWLVxa`hR`tNi{X4oJu; zNQbk@l2T3MWXw2{OPu8wwHPaff~`vl04Dl3 zTt|W`%oD98t3_6w=9ujZ%kG>&bmG{AY34!@;iQ=)X%0MJ`9qor#Pb%b~Xyhh{oZbu6z{plRJ>mP-z=uC7VC zRN$HU5r=<}Qz=}3g!7uAw)q*2fa^~H47Rzn++3acTTH0(FTPB?kPK;my#Q51ro!id zm9h@%+|U|dhL#PcSvr&q*2x6Jiv%w9z>Er~Ub9(uLXNCyLEn&vPN(~xgpZB`2A;&Q z4l+J=gH{m3Lq+AyT*v)y7)C-8a3vUScWWDhMlsY{K6v7QRV#zLva{W_FBK|~qR%fX z-LDdhv_PXYoom4cqwE^`MFamibGYnN1D>-(%B*uBkUeqDUf+7s3Z2K`L3;zXP1#F1 zoO@=r=s?n_NgAb;JGQ2zmTcT5y6an;ZGmjhwc(6QMBLPxl-`rVP!`6C(vOPk>7NtK ze9hi4eB=(Wu5{0YP8VfJc*^;=&l0K6N3EJRQ?KU^6emP6W85w&@*6iD)i}`K1q2|I z1a;=rC2qfSF@2h7(1s!z$mnOjZ9`L)!1JX&(5@v@8!-`CQ#jQdU{?${%P1p$R9X>3 zA_UHbQZ@30%-lHyi4U2X(Qwd3t5#(#S1>o+RBF+$d6p3WO;L{`^W0qRouWyquD;3 zEjbbk9Rg2v3F#GdKXfR-6MaLHl|(TI9WT7v0@bsZJCT>8B<_l8h+s^silA?mpvwtZ zS#!%Y_E}?5T)DUhjDFhbxXy8ddp@HmITM-I>C-^teeN@r!N3joH+EED`QSZ&Wr94l zrI8j)BW|1w_0#gJg3dRqnqRI?VU)6yB)EHt`^FjW>jX55pF5?2H#2jLEg9Zo z?S`_n9+Ps1)wZoA&N&^O7rO~kKG|U)i`lU>Zs6VEq7$Dm{|SXU`SB9Ww>W#`l47)3 zx3#()hHL-sutYXuUtzZX3P`>ajo}LzVx@H1m{@6Za74IeV8NYDX~5ZgKzki#ZqZXJ z6xa4bIiklrefEO+vDxHIiDOIAU-&TDCn&`w%^w1L7j)}>fZ$zl!NxsN14xvN?EWA^ z31iJ}R|UV7g2zF|{kyH-sUU4T=79L>CwToR!evAgLpwD73h|VGPT#RMmI`Lo^}Ks6 z)f#Q`9-9yBnTqIdW?o&_03;ftLW0!M)F_Ua4Jf$mX`{n4rL_xAF6P&DT;ZkHNY&e& zojX?+|Iltbsbcx*P#H4b1#esGMLULu(W+!tZY29D-0wk}F2)f_P9R+YYLEW45VHqGKs!vT z$`TAz93{=wT;T*?MslL;PiKB%mF4*TD6@A!wmb>FS=**K`!)@NH?orp_A(b)#NCjd zhB0Q;W8hf6ArHsF!ma&&@C2y>Ria&}cxRMhv~h#@_h8G_CPk@!as2|Stx*oCQlk$4 zcR;wpWZOBK1IM2tB@yfsraxNSZ1}P#)?8$Dvd=Ge&q#b(NI%Fj<~i2O*!t1xbDygF zun;O%u8%R#mtMm4C=3)78E{y={A7ipKsaPE^RLRO{HBgTbeTHYbX|$G@HNq)6QJ#y z0cN$K8Y3;TPb@vMF0Mijw(`MgEn`-&s(VVIyWxz%l70yDN{AmKS@yYDbf~FVx(n#3 zzl>&P^fH$v@aU8?MNtiKGT~Sj2ZzAY#Du}SYjHZ5&o4Ns%Q*s*O+DG^hDgnGpJLG{ z&@`?0w9#8|>0mCmEB;+l4Y3LmWh6*)oV_y>p-S{y<5Lpi`x!C^Ns zh=1dE4pAX(g5f8oSgSyum$6*-C}wS264kjbE%|4AM#GO^+EJfi5ImA-U|H8o;1SAqLzT{rfxk~a@?0&| z1i<`WJsr5;AR;L}@X%A7&n|biUWw8}&&iiE&hbAiMFPv|ozmBYy9f>1*fLA!8H}IH0ReyIn6FGtKhec` zCd<78R;(<8UY81juANcxBeploU)Ih#6Mnt}k^&1}F(K$eLQfJe(>FmTFBhljTT(Ao zk3Ow)Jz4j!?|`a6E1H{Ln~f(w)wdW%{mZa!wfbP|gHA)d>uGjvwufy;%d9bqJK~+&j-5hE1 zuv7-k8u`!@aL{2Ped3cM9A7hKX+tPjrlY?4I?^a?MDovovom2bw58M(NH`e!^Ry=4 zBJ-cUnBh6==v~LJay~c?h>gL?f@f1FGFQTq0tfYGPb`zPpzuwl+oUZq{;1Xlfz_L4 zs85AgJl6DC7bw#hL%J$fv)H>vNJ7&hvHJ-cD987kTtBIL(S=CDM#YyNB9iwOa?utN z$fC-a<^^{oAUoGf8(z>OHutFP>&n=M3uS6OO=p8+F8Q$942;NfB@vN-cd zzvi~bR~tyj!kh3?ZeDzfHn6i^I@#JbDU`x`Zs4#vd(L_cOu^yBB>m&|V7k&3elHTzl{E}P;Hr_|(v?PNu(7^=wnE11;|9z0UI{mv z7k0~-&j%{0td+kc3Go2+=i70vDeG9D^s$#WX@v)i4C?4q6~p4`waX#2w}llS)KAM~ z%BCigo-YRMUQL)H#j@_Kp5mWsHr6}KzZ&+1_nkhqcRVZCv}n2)gvBd4#e4=) zhk+fS)+%WHeA)bIORSYrtD!kE?(e{7WKw{u4~L7!`dPsEcrFo>r+|VSdj-9xSS1Y3 zRxUyOnsD}=U+kh5WW3U`-;Yw5%UqJqd7YjdMif|jFVRFf?$5rBlc7IFj9Ik>R=qR^%FhOsx)h3I7jMH6JiQPsD@6z23hj&0kAuK)BUyOGA)Vk#P8?Y=Efj z;siT%LQZDqS}OT7g|;uWBfWs>bsrJ7dy4vDWej0#l&k~Vu>^y6pYYU9;7t>uNpl`o z(4(k?RK#tGo#?SZ_2QsxzlU_QDWirQ#yB(`De8132KXCmL=bE6qvA)5&xx-Bx~T;n z7AWUI*m_uO5qBfHbN`9pi?_GVecW0cKL^#EL zjDEEzkkQvM3|Zj1`?`ge@(@HYN8h@|cyR}- z>Z)hJbQXBg4gVkr>v_Z%f21~H|UUXuci<#c!6kS=N^MeIiS0*L^4T{^~lwg=6w`=NO6y*PX5GaY`{%xg3 z_iSmcc1%2=^BwR461#SI2Q<9)KD+7fsRqB?Y!0p%e^ArI-CO(XQ;-fvtmTaf_x`E)!e-jncF;v;$2-0?{)4HGUPEI>NH*Oqcj($Xk z!KIdLX(oom{`_VL{u5k-e?&W@HP#n~DcOD&75r$eXu0p^PR9UaU|G?jg)Bw|72tah z)pW{1nkaYo>C?+qtOZr(|1$u`30LsP@=u_muM|0*{B?obfGRcTm){PgYjL`V6G^}W zgdP?>Il5v{#2C8Cx%QJYWq0vIPv=@{+Vg8blf4KD6vhWqHe5tT0m1|nYhna|BVi0G zzWgn}{h)2%M6yf?F7sM>HcEDj0=K$S{1?@DpG9!qFz4riFhuexbdto6A(?8D{W@(p zcV}eypT2tFpMOjuO}d`Q9VcM5948WaHE`b?y~ZXI%<^Qo#_ubbKBW&~ZNlIm=183Q zKL=C$|F?Bp>bPwkSkLlqMHiECFeQ|f&AhPGBUdIwz0lf47P-rfQCuLX}b<(eO) z7ODQ)B8J%8a_$y8%=tysDTdgh)OEqDCP`3_Z_xde-J^+G8<9l)A#VTYVOkZWSa?4s z0qFQW=lVB7# z@tZah5qbTV5*70&xFqBjHX8O{YSUf^_>aQ$r}=*~uK^~JIax2H>ff$k^!WWG7~xc}G|Ml)|^_lh&_ zmiWGe^m*4rYd60Do?@5#fnl{4Nc0z!{aXDER!LjC$!z#Y_U)z=VX3Te=sFo-Y8vwh2N70Ll?`v~ zmSgSNS~nn4TGHx1^1fDi2N+luG{pw7SPQVZ5Pco8boWUMH5S5(f~BEMCZTz>qNRk6 zv<2-@lXy>9^xVeiR94p;R`f?dJOu72+*cT0E#>(kzJaA@M2~z9RTWLr(ek%7*qB`9 zd=X99)3LG}a}~;G7Z-Dlc`UPSNu?N|H+XW2ErA=|gaa8s^i~p1#(g|LnAwtpS)DCx zRetnN7lw0p?5jI(H>iVwCe*Qn`1Bs>mIN+a*M}g%MJj6b>HxxU@G<^PsP{beGWB>6 zTOQyxdj|7h^PC>D4Lqs2xFY+*p0xme`HU7~6Pey?p;94GN>ks2scD~==3^$EK_)6< zQo56-J)`$sN?TTEzNNxKPp9tOr!GZ@yRLA8*Wfva6wjK@Oh-uFU?v9(m#L*@O-1B~y=%gLO|h9(&65}K;OV}p!*RQK^M!@wR3Tb(4bh1|p1pw^K|uZ` z@~fnZ3iWF<&p;e^496aW%I-FXG`)^UvobHEl%n9}cjxS_xfJ`6Inr2TJM`b#tRHkS zRdpwl--htnm$u<0e$5Pj74?TmB+ZCiZ3*9=KPeb*_4byn zisq+BQzUO>)|=UY+UaO#AXde-syf+GHa9`-`RtvH$yVWnvkRI-OTI(a_5I+rS7isk zjoQ__)LI2GpbF)e4CuY|G#wV>wVv}dIi3);@0CcpCabJOwmReaRbu}!|9_BbggwJ- zPSXWlm31KQQVqV}F)dSsUk3L>5YX`Uv@3@cekQG;hI3QdNc;NFa$=SXckmO8FXY^6 z(>$NXUQR5RSGl106!$e>^y=tyP8-&KN=j7Cd!h!5V1hQB5q~vW=zQO0k5V@{Av9}x zBP5tfq@}@1fk|N%A6ZCLm*J1U&2iVOrkwnx{k#Nzdg>TmYGdPhsJ~?LAD&p0l;OU` zbD3E7Eh`?Y)WYCit~)o;yTvmfuRdMg2>5%OF79?j)SO|y*?I6-Ypqo}4`}WL?wO~a zB59xwjXk69$2g@r+~d*{VAq`;L(PGvte*8z`e~PPaz8R$fmfEv5{| zQ`evTrnjR9#JrbwSz%O(RXi7FusaD-*-9FGMpo39P;LZ(mS0kO7qjTjcFD%|{zK~j z#d`wvC{GGJm<|$@eJM9@Zl%W47Ai%S#IlqT#tVC*gM=^#C+vwVaLp0rrz>1VH_$~$ zOb^RVH&4s`-NubPAVw$h=U}ZhZxo%irNuu0tlse7enT5cP70;CK;OkR3PCeGSAjS* ziJaEYGp8-S9WF8h5xk^C5q^wAApubq*Q+`rbj!N94;R%{v#8u!O`zrCv$z1~UI$aw zx#;tD$*~jTWWvyh?rWZX=%FVKY`e36qHf61&%^0St z?-IsM`l{dA>axRyV7vO75lDQ=lD(hisb6y~9vyf*uDul@pRwKxUuxlISEaFksHkYr$Q@!eYH) z;W^uK^1ecf9rDf4zm6n8)RC};lry&tRu{NnDMWMFLq=Q~xSXzur#dZ7nP|`DlY+*G zt0B8dr*>ebTgY8&=Z4H0FE8u7gOq8UPB4zsHA`>Sx<59Kr`jPH3j1Le%*pP)li#zP zr#HGHNtffd#{kk`oXF$I>jGky6rvWJa#h8rWx{VhEXN$gL^{s4e z6E{AYImXztw19qP#IS4;@(;y2qFP5T$+cOMG!S7d_HEL8JLl`mdm)d}(|tzPBa zYo(Q}N8ChAX)TOdojUj9(XJ?Wr8+oeh+VyGbXH*$T)frxl`HAWr#uzwZYHOc9-|v7 zH?m7K2{5JyZXMrB zl9m+o&Z4JNk0?UX&RGW{+|H}>&}2eDAEWXE8kzZR3aQVS?YR4Eu994$=*r{>@|QHB zF?8LSuC~!PBq%bVe$)+T#cN(BDRA>Uubfy=H{x_UFz9}rOnPB)3M$iKUI4SMd|JyF zs@)@e(5((aX~V=M_Lz}ZguvF@=@oleS1_Rc3`r1@pnW>5?`8!4-p+G5n{y+5SQ1=MI>D>+Ijt+x z5cT;xp;gzh!&c{WXz=X41YCD8SOnL)_-#JiJD99>-GGgzXul7BEkeswq_iD>6XE)j z+JL|C^*ePLhGc+4qk0ym`3Csc!j}kniuqrq&3g_#NlFzcsjL1jshlI-3|1(s27`k-0nLueEP-`*RhLEv*eB7@`{lQu^9@#t2Gu(5!QEOS zy62q+>GKBZB%4xF;vwaZ)gQg4Q?8w0VJMu&A6SVFRb`}kj##@L&^%+(Pc==IgQTQN zJ|Q*OfBN*RPoh3)dz=y`J+j;Usw4YZ(+Jcu3jwytCds^ zN}xUe-3rH;;sR`Uip_xPpy%9C^+qdIy04vg?CFD$-b&pNiwQ+*iNTp>wzm;Zelt>b z{KK>La(LaoW$svw1B&;OMM?6v-gBxfiZ8Qk=J% zx4)Q04tvmlIQ|3>$Ie>LP^>-g7){Odpe?}6t3`<{XA1)MEQ zNy(ym)vIVN>g!od{x83{53>lRv!@_djh9K)uMNRbN<7v&J*WT zjT4cOnR9>lW^K0T)F78(bq;MC|mWD?}=|o({~f=inPkeaEYI($v89Qr)@*cw0=h-R4GDQ zJt@680flAxOth{;wEQ%iucexvm4}iOj)F`qZA|vY(eUWArP`ul3ssPf6F0<9?a|g= zbJ9~-*vrQH`=pb7*YSu=SSYVAE!c}fYEj7ypvE%ilA8bddVRuv+*2s`dM zr-xWi7e#}>`g{92XJECk%e2R3p5wAM22y7A7{K@>aaI+nEuI*)kvi26)twc)(Tal7 zCP|8K+DCCIm(l{`Hv#ndO)vLARWMMoZ{59OuN&ZW&p$3j|iJ7R-VAFncm5DE+ z!znMs`SgPDMauM5+_ysFxy9Dr^*k-6q2~{DsIwO4&AOO{Nu4z zkO}Ah>8=BnNx4kHnx|QGqPFUoB!`;B0ytSV&D3@|vnKS?zlp$sg$Wj|8%8`rFDOI# zoKn#CIdh0C;2qFMG(Plr%<2`fm-p5@DrSTKW-!h5W{}g6=PS2;$aeAC?F`iSeSk1+ zOgMR8YkaC+Gcrh<8`??Ir31w7FqhaM)P*FW?`<^Ma;s?^H<~pPw^MxYsuk&if%&6v zDAP?8s1pCAxClOVP~;PCLQ^cXrj+OvNPrG;`In2_x@E+-F)H|(!??kk9>-2S$PEJWcw--p%4bC=H*Il^Rj1cRN2D2Hrj?#(f@3yu&SZ5l%s>ai3&OYp z@(tTDgts4|>@;{BNJduS@=$Fy^!iQg`^|f5I%hy~oRkks6yqD(zCtZbKg%p!RVuo> zq6r^b!m70Ax;tl&JiSsVNvy-3{hkttEH+^joPD?V5jFXoo|ek$6<^1mlv-_c70=I; zF&aQ9<%G3(JbOUnsEIIcaxoudo7HIK|hmrute+&^-jj;srjK%KRDZPio6BnVoaFu^F(2P+pHPRH*}Uqwlz}Hzkf3~2>v|zDt;|5 zX6@`uG*9?Tf~q2hOWBh?^ef34mx^k9{n+oa5$=@>X^mAWP&c81#El|dy0u44^Ud>nxhA^cb)UP= z?!3u>LkEze)1q}xdCzNVISWHHr9E$IDoCTH)|oF!*KG#NqVyf0q3;my?vxIaqhEEc zMZe%VUI9jEbb*9WB`T{ApJi*uaW-~=bb_UX%d1H`&~qeK-!x1sJm*fjV%c|oHU`?8 zi?%Y6saCh>6|iQmxtPQUGap+qI;&yK>Y8uVy-j%Vopxylqc~KO|emGPU+SBgqQCxYS?MV)LJb(0et_23nDQ zO^)60#|1_nhu+~&_;{>>I6i-Zlgb*cT8c9-XEjBWG*IO+aPdpFv3 zFw|EksMwQS&zC(4jpH{Rm_wa@cvX-DhJEr!V@!3lNbBW^J)fTu)p<@a)Im^$hx<)) zaox>|i?E){Mq&Xa!hNY9|=9#Zs7LJnEa_51y&!ow=YW#`c@$qo>t){~*!>qQ8L;EQ03 z02_#h|AArocm+hYWDD-3b;@F;T2|hQ^3~SV^~2Kbxq;UJAm7E zPCd;ra=F!N^U^^5k*ze^JfO`o-!w{pKjm7@SDs1WEs#o34O}XDwan6w*rPiW;smUJV zUclol@WY2C+gZk&SI55M1h;oM0q<6<=k6R zgC>{Ml^2fMNB9yKhW5^jqqgH`MgjJGQ8s7+#PAAs6ryc;uX$-P4PIf{)gEKhZFtON z%Ul5u>889lJcfr$-%ksq!|FfnZ);twqrqqDL0LsWs}s16ukB+W#d%kJy<7Rv2kV;k z$~gAZxi$B}Z;eHFp0Q2CPD%QZW9Q8P<*+Z3K);wL_tASQBVK$q^D6B-D!uC0edOko z^sil1%X7Cv{|NyN{~?wZvN?xG2C>N15MAkO&g4hun5Na zUQS|GV9HcSuO`~-sHHTX6}mvvV1Gjez?OavHBcn@3wtXGeQETsdp zqFRWKUS9g&4mdp#w$k(12GLg#g%N{q{c# zDGPV0l#O;~=_lCzRCsyC-nQ*Ige<+MU4e+&tW@irWgT_FHg`)2Z&3X4sOQ_p>iE_Ylrg0go*f=vl^5 z*%@u*+o;%Yf;AVly>Yo3YoNeiy&W})Ck=C$uHOMlsGCf427(P5CcH~~@Z|#)E}~Yw z}UkMp)FKU#r)aXMSrk>iEgLNhIVeZT$1A%CT@pML0js zseI#dgG9o8l64dl+QMsa$eE11^LawmKh?J>t5B~udMwu3kq4^-HBc1CFujaYQGQ7m zCz|~LG{>XIC`gIzkJ`B4s-|rPbn|RG%;pX0w{EnRkuHMBC|B_`=Dw1AqdczG(8&7$ z*S7E`X?4c5?#5VP{Kr|rxb8^nROrjqmMiZhA&+B$62IGi|LhcoM8`+hRSF?lO-W%Lnqu1hIIM(b%`dO@|W?J~ao zG{1G~uIpxQli;&aAjZR8H_a_xnf2kWhN|YGTJ&gHIIvO^A=cO{YNL3MNcMy%wRg=J z0d6iFS=g~3wK{S8TXy(isaES{#Hjtx=`(~B12FT6Q3U#qUx;E3t^jVh+I_J}FD1s&GNVy1?tI$c$@op5-Z3De3i z+IShQVrt3L2w*6f2O^cUo^I&)9tafLQ9J7Tk z#?v`?6aq(%!?~p_9+l4gFszSebpOcW`$rm&4gPe#57K4A3fb@JvM;(%P0u!Oj(zWd z|53?o@JAAR{=6o=1Cak^{Z|72O5k4!{40U~GbO;qKP(*fFmjgg$D+R%Qm`g=V~Mc& z@Jim_vk{bTga7xFiTiiJ-Fd?OWzbvDGpFAk+~zyrv9Q1QZqkDA9dNaV5_AtvIi$## zz7P7Fq2RxZKg`KL%!&PI4x|%8zQa034&4hIbccxM0zOJvD<-K)`-;#Rp}Sr=)ZJ82 z_9M7VU!QeOXS6eXJ?y z4E)E`Qt6Th<~1YJ8&3B2;Z!#2ijr;!(SlN%!7i(^nGDd2gq5WjX}URfpDN>2~FL8 zR4i3%25Vx@#d{s7o&7wdLKs6MQ>xFZsaRk=SHi_&jg}6evC{qgRs7UKT{Gzb!-I0w zG`UgE%cIl|ko(=U=L^=Laxkk>%}ez)oxG4dP)teJu6;>%NlxP#q>bYObhTJnn@j69 zAzcQro7L1zX5Zg|1Uy&aT})<0P9jk?u z)COfG15U`;xJsWBIa#k$6I?pH#G7wf}QmI-k&H#tE%iSH#gD_7V zHm#m~RHKg_b0Rp9%-f^mD?;QM2v530Y^}N|s57WA2ecCY2ofy%1?Yy>p;C+rReEgw zSn}!TeuMa)t_sqYEvU^Yq+7mgdp*woV+()?RSq5fo;!G^l~ ziUb<@R!@4(&m}dVJ$7U_WvRHxHV&w~$V3D8Vl4CzhN`<`h`FI$Caf|X<$AR^=-cz~ z3>qqck6ah1tB!3Flp3EI%f7F0h`=Gz{!oK#G%68flHu!65!K6B8`7J#(<6ik;VDM@ zVteqyR%2%_XC1SD1vggKT}P%vHI4mG6dZvjS{9vkCUca-4um$u3w*~Ez|s%D4jX1N@lI&s28lVM4+m1{M z8q1I7B<*}~gr1%>V+l4aC#4dV$w*q5pCAg5)-X*&(cI4AejJ^vz<|+`G1fY?9}qv) zY|KiJ>(>hPO7)P5Ay(^ zqaI1Ygb{wD)ST@#C2cL7)YKJ~c|=s?>hPEtx3?5ojgD5jzTXxzRCBiH=(_Y5YQxOt zc^Vf*dJ&?0*yc27t%22lX3d!K(j}Zfb_Go`PfCX|PY8#v2Jkvcr_f#3EwjhFFW+av zwtM;tOOZu|CJn`51Q=`V6bUbVFS;UvBV&cDi7)!9tnV>38(|czke~p&ht}*@WSW)6 zt5lzlZ_O!m5wc4zavgwRslywaMWPS@&Q0|U!Ow3z=zx{Lpd~5em2LZ}@T=l`Dh<|$ zBWOL3NKOLm9Gm7+OEaVf!xg$UT;+2nI2ipkf)uV1A5 zds2pJ+0GqAYBbmo()H-5yoiuKa2t1f#C%MSBmafCh>LdMEup6W_`_*W{!C8a%6DK6 zBQzk(5=t>e7IaOMM3CT)#q}{SrC`N11II|paxCR#XKES&8qu@Zi|U>n;Q=nQ;Y*2E z6b9l*I;e{Z`z|P=h1%@t&Pi5vAEu^3u-Cz3M<`~9cQRz=bpr1ZDrMgSO5L%E6PdwmX|RUpO^Xc;9Lw0aN;cNTQ&iny$I~Gz z6aTT#Y6W@pdB!v|UP@<9!c|H@GhbqDC#XpBc%qzawXERAHGK0z5d>&!97*81mg;HPKv_U=eYCVf0n z+dGRt-S}WC%i*#Fi=;xj;mAyB5jbN=lD2Lo>8`U(YH|@EOL~b9P=YUU1#4!aoB*gwd_llh%8u3M)25?(iR&xEi+FG z&`9vP=F>W7vb5^-q>YpAJ}eCzWN~RdtVo>pp%DV~GBPrzX`lUsr|p&Jo4w+Q|1*rZ zt>$Ay^1))79cwKs(Pv`GNn`#!Co|JU^lM&XzLZ?lFhzR>|J#i$c+QE+gN9K@!&!fvo=#*YyRkz8qqLAcCnOo1X@q=m4$w+h%zHIvdgqwW*)&A` z9LFXO?AGGqI_f|e1P57Oo9)8R`u>qbo!4%0h}AO>K`Z0mxBOnN&@^V z?9sh1&8;O})NGcR(mXbmeJkC~OR7^e7Vg?@t=0CpL1kv)h-HpCWlHj1=*_G@<~sHk z=dJ`-%juq2SiJguZ@*=CqG+QeHhf#uNrE$I)$H0}I<0rewT;0^AAN}ZrZdt1V0Ydt ztUIHGiAN0D!#27S&Kca}sj6~#M9O~qaq}D8@^g7ykl;u0NoZb|1ukV<^1!Y$4)57_ zg7_FzCsGI`sOHjQx2wtR)2fz(Mt)Bo1xmyZ^Q){c;~F(C%+bo$Jlj#!f679fxh&fC zJcPozzM6vsFDu9AnfOiBc5Sa;(#pu@;2J)Bk^zyahHo`@ zWhwd_9IKqw#5r6sTC}WK8WC^Sw*{5i!b(wm`}AEDsdAIOwAQpm$t=i%9AarWYHGBT z;b0Qnly2HqDjt#D%NSlP<>;0Y<&xjWxth~gN-g_0pXMifqM9mZHQ)y8$-UvT^?7F7 zZXKqg>jqtei&WOWH;P5>|6k0VWmjBXux@d8cXxM(;O^eIG%mp%g44K5J zMVeD;MH0hvDqz{+=rwZxZ5|VDfT80jJHHyl>EDv6%6_yw-6|^K#SNMyRv^^Zan*C( z1H{bDCevMs#!X>68dJxGgKTR9qKQ|w4 zGw-NnU@5Kj&83`SQaRTItCk_&B1zz&p5?xooW4roB2rO>H?GylZTY@NcU(N1er+|MfXn*;S*|nAIZoa1@<@I7{M+ez0Re zYkU{dcO4-61VXuH=-(!--Uvw?g_y>&=Dome%m(Il$5DiLf9N`n$$xp&cyVu@%LK$z zWbUipe>Qe<5f|odZ>vbQon?cbbOuWnQ}1IGBuDi9v<-+(v?)8>6&|zbm6Ph++bkF# zS5bbL8?*b3X)BUXdCOUh6OtRFZVdL})BAlgFwZUpT92ASKjX|z&LWjQco0HK%Mlx~ zgwP6B4|2Ig^3Xt~j=wg{1f3t1BZQ9A#^(4&^tnN@G|SGGt7owqu7fh!&tlreRMd;_ z{pqfXuuT`l3bWNp|0C#(r$f#k(QN}60~l7yeuTSnSyyHp z^%1+oL7Su^p=n5Sg|}bX7|#Yrc^ggaBfll!# z!=Wi1XgRR7 zN*AYSFBBdPfW__C=U^!6&ZRy?{+MuWtraAjmNw|>cmbNatAevt2Wv}5vc|{UrE3jb zq7@T@#(VHIxj#I)vkhd}e&Ao@g$$uBNw!1**e$D6WljJJzx zx+0#P+|QfXDn(p({F?_g;tDN{sJr%VRFR=JF;Ku=oPb762GG7@RjQd&oF~y6bVZht zUsa8n#>=wx`|zJk-(i@p`Bu;~Pb=qsnN|iGuKdSfPd#UpL z&TO>O-p%*qZr76#fb>zqpF4DtW%F&SQG7S|VFUWl+5Q5RXr~2pqmi}g>g1oqx#yf#u#TfBv1cP zn*lO#6wZo%DVA2>J4UCAIdJ7=+m8VT2KQM8o$ilXMybQ90{{nS$9%u>c~;tVH=G<= z2gC6%zW^?`qM?S1#x=uHvv1P>9)md8GF-d(k(uzk-Or5Gk@Bp7tsI0rx ztAS8|a=fK1_^GKq-;Kidz%Mo`tB*fS5fItJ02#*vz>TM3yVPWHb1ihay#XrTw>%HD zV0!8d;?f)X1zMBr`0=v&Vv9n)fMYvnN?~OQJ$P0IsKH6QBd;H~lMFyvr0;$yHrm<3$b3JJEEfZ=k ztk=xq*zxXGDqK4uWJBV{)l6etlQ+1+n9O0=*qZBE;}Q0%$(uM~9uWE*{YFEHgd0ps zAL{AYT$iI0KZMqZfFpWv$o4Ad;Qe{?_R`tfi(V{WOUeAWtgQ)+r72IkKg*>k0W5tE zS>Z$kU^X)$^D_NJMurtnHs87&4B{C1mu=~5>7NS*h1YGKb@Fo4>OF5*uu`XqTjbtV zJH%!B<8px!zN_-bTBf7IGQVXkwFh)5oVJ>kZn1m3KZYp^n-NTj8j;V>%NWqo(-FRY zU251Fm+x)nB=i<*Soic+w5P9VcG07^Yox21+U^ag(bTQ$ge6Grlr6GYZC)nqTl|HY z^``E%$41Fww^}=a`A54e+!Oxk<2&ZR+E#zZr`yb6vHzfES-H{#I;g`or;k-GS116) zv`Wxl3nJ~a?T+TQd}K@^6fSgavjp9v^C^ zKF?57ms{T}J1xgHQ&~ARNB|;#s6U=q^wg#XFU}gpa`V4wjNQ1J)~}UT%Nb=0bYvdU zWC%0wRG?s-D(W{{r<=HGDnt{y9{90;}>!O zEB{6cR2n7L`oIQrvbBt<{@;9sOTszAbjjidY;5ihT}Cvszx1mjY*x6;>q*Z(B_ z2UXP3?_{X`Qled> zU!Uy%__1g7Gh4npSM`ebrr0TQ3y?O3*ItI*72gq2)QtuDkh3WgbHS?+Yaov!8>N`O zl``_#EBqT~Z|q8LkOkjkVlYx(zbZ{n8)=XRtCsIna=jW~E0L=>lyu%Qv)TKnHLXF! zEq87~i!O8DLn!uNQXURH%sZbCGe&{oWDiM1K=sdrlmT*m`p6b)u1`ioQ22t$IGr=O zYZ*h&7P=>9H@u}C0LZ*a%$xd-FhDYrN*;B<8+$iSJf&)5q4E{eQQp~ju;WDG1X10Q zQc&RsLu64+$cj>PTXJe^M5R7E>B)akTDB^sH;oLpJ#xad8Exye1lub$EE~Qo2QPE| z^eN+5@n&t}ur%xNYC1;xrabMi!A6S&WQO$!N`X)TuXRUtP9oG(IqtG%^5h%MxJDtB zWZ8ZTO@xX<%gYj9pMZ2+7ZaAUPf==>*N#<_wAD=vtI1AgK`@7xI$c$>``^B$4BNn*S zM?0MqE3a8(ke-(mEmTW-cxd$1GFR zcKNY_EjLIy$YjdSA)x4S>cSqoleg@Wqh@4_Toz^$e%Y9wLmhuS^pCFPDuv3u@laj1 zoXj2)_zNpTe;4x0)AbR9pQ`OnOvD$P%al;s)V#OpW2C6WJVanEk9wY?ID;crv?!@e zC&?VuWb;(1NXSSI*NsrzIQx+d1cnYmB<5>t#Ttz#oejS<3kI$~6ct*AST|(U70VvO z|E%T!tBLq>2GG9+{yiQm=Yhr?WDFWy_bx^YyI?;|w-z#QZEH?*vl$D0D$@6gVvuI3b>&YCm zS@U!dQTfLmU4+LBBj!G^GMZf~IXYbMe&!+A!eMLwh-m@^>R*z@*o}tw`Y6Q?INQ@( z+%apZEzsT>sIaL`9e&%Y|Afk`YlrXQ1nyrUZDQpPemA-=l&e17b&r%d(Nq^_OwZ0S zN>LdJD^rx)|^+j9vOaWu%Rv5f5l( zJ_bYIxhK>jBwKLYNmXV;{G;BIy0u%va5D&D%DZj&&bNP@WgkCkyHokovhAtE!a+?P zk@f}E$fRwdcPUje|2|%7Z(sblO{mfT4+@KU6YDonNxJmL)*GJpyhmpPJIqDR^G!E7 zk53+>TphN3maU2Y8da`l)S~fdE7RkLJ>29T$K68~gyi4VH^93`WE>W=y}R@b+Dvce z8Kty-K;y60@%b*X#pFl@h@(^`b6(qVQr$RM{~iKj6iI5-7uEaeZR|~8{T-DNMnHg+ zloWA$bEm~u?b7A>DlRbF%fhDuLq!BlfJ{WZ60|Sp$u9?#-qH=9?dvo!3)Nn7y5z{0 zi`J6w4N0rJ3&!-yig8zt>k%}1?o|%#;gHcogEPu7>f_<$?fIl*hpxd8DUh-f`*UeO69Px4Dyur-=ANxv6v!O+d7Aa{ z4>vJKO(!kZt7L*=(^#QNUTX6KXX!-a5HRFD7PwPNJ34O1pDy7lI6IgBes^*$$lJmu zhW~;NmePs&QJ=IXP470r^yZyx^TG-|78Rq-xq6DIvg6dl)5=@d!Psuq$+`9qtT~P~ z^#zhtHlV4>`=39#QT5^pW{b}^7V_*O3&HESfX$(mJS_SvL^I$%gj#>NeBZDl>L zH&;}lWm)Lox5ADm%I`DC2#10i)q#lzr1khU02<)0CF@Q0AZC)l_U8;QZ@V@Gq`Bh=p&fCR?>oMrpZe{_bQ?`;&O0(!rFlUO1dMX z+NNALHkoy!5eanum^6Al6EIP*h*fPmNl@FaK`%JjgdZVxmSr5xQ&8rs+ELNRF~u59 zP4N@Wu#YIgbT-b-;oSa6Vz%siEOHJkOG$q_xl*}WOE0P)C+=@u7Ah;!fA-0aeg^blvxsA(SES?S)PNjFnt}j^1E_~+_ z#({YAW2kae3&=x^nbVfHxy~w?0%X$|0Q$TsAjh0Mw1f2LB~~7UvEPLuPaX*I*cEv& zYwc5=RWQ&*&_h~`3Es1ObEpe9Aj=^q!GT77h&3*HkZCG8ZGK^dFcaZ)JsD9sN|41< zyi%4Aiu{#fUSH-HbiM=yY*nE%Rsn6HQom``c^s$HG#s1kY6J4~8DM8`*-Er0!gJ9f zd566CW;snAc&e&vEXMVroh>vPCA#y@B-F4R;K&-nW4A~^9}k=V$x2Jz`tczpxDio# z0>Xh@AyVGJO(Z6QN$tbJikm$~A0(wblUPW!XAK$5%}w;S{Gw%7hUAiv+Jb59v)F3Q z)33e3&p5d0OWS-=ZPRICeySRpky%G?1+AcvdcRlp%5-5zY2)%G&?19uO=E{!TFj>& zsL-GgdnvW_%VS6Pi(%E!rD>!C+nUgu%tAkuPwyaxv;m{x!I1c}0UT$YcpNu3sjaB| zsqeg(wVwdt7h#^7!-%I- z6^o(n^{*zeJj&=}*<+cWN1R34v9&9n(jt@0wVzo2pwt`s3`BPPsChtYMsD4mz(kuY zIGl!7i(27W;kz+h%g$JZs`Yl+Du3cGSR}6vCN-TiY3YI)P8>RIM9+GiTm%KI8t>?c z_=@+igc5RXu%R$;P*{(fMMg}OXvY?DknzUmJ`B}1*g2Tk0MTR>w+B#GTBK6nJgDMQ z5FU%e=s+c*L%}6y{)Zx)B+%{pn**tV5<~Y_X-;gA8+)>ERm1Y(>AR|S3HBT1SLE5a zDOC%h?i|0;z^!csEO}446wbpr_iS~cG@dDaYuqS0@x#(8^zH98J3s$5n^}8>ju18GZV8cJZfRvvZN`aaZDaGdr{v9#)+6_DqT@W zqZyTrdp%35BCs}W1fEyvxuOSk1W}w$;qdBAohCJzrW>suWR}Ddr_#vPV=Rc5>Ih(T zk7fY!ybea14_V8W|78oF=7q~qNs6>+VeR1?ca-_tB>NRZFJEGwATXDI!L{L^Zm>J~R9K;U`g3k#v;N)6+oAQbWDCPU@CO`+zk+A{?)NaO%5lmuBL zc8&B|5zN7!CNt%#h!7q!YE z#BxwW(xlf5Lx6_6T5t|e`D;|l20)~@yP5sea2mVW99)~bux=`^?z&jtT)o8z3yWFd z`UCW!Tp>L>#gz?#6E)Zl-3N+hJp>z*iY{-Q<;5Ev4byt@W zcZ}Eta-eSf`=RTwIhL>}3>ZaSm^acYWA`+^`_PV>qPT28|4#SlVuS zCvHJWugs<@`*<5Sc-!kO7~5h>-Q$S0M_Pn2e_ylX`& zXGBNgU`Z0)^cDI>{+RV==xfG5V3x1lf!dn>isW+;i+G|d5!t{CWX|y-?rf-RJ2Pi$ z)V>f}%H(9a#IiD})kll+mxY@tcSHFWt$q>S#rW_X=p^Eh`u29SQZP(L!&v@Ibap$A z8>B7Ugt2>4+qdMNktVpLJtQwSC9JL8mFU*+cskpvT)47an0x}kLQFrC%WXIb z&dd(dbI5R5Lm3*Q;fT&h;Kk!VN7nA}wrv5o-|a%^o9Y*_Gtd8Iz)_r?=X#RNej_8_ zF#5IJWKVp_GC62OZV{WPJ{m^Jm!xpakxPUl_P`*!lc5ziC9&G{yRo*QJeFigseVV; z5}S_pn~H{;JulY`*p}-`@Ktj6%{*a|HN}bEbXp^GsMo)i*ibfrDOX2Qw6`3_Q z1I&L=7F%?zgz)aEI;3n?Vh<6-YE$o=^Zbzn6}i(kSeF#8MMFA^g-OSkT>5MbELLhT z=%?1H3~B3vf_NEdprq9_d}S%NTU9mo%CERFHz+?#N{*g?*Jf{yT!Us5rsJm$i`05o zJ4-hvx~uB7U93=(#1I6Y+x%ejejByAnu%wj`YevQhM?c8NvFy={2T2M*}v9~D~lxpLWv?q<4 z?*Qg<$et6MA-)V5r(~O2f&9|l{&C*TRI@joO1mn?Q4mp$C8m(Ne9Gg~=HhW<&dj<( z@2#3Tcu9FAyY(zj#P!|7XPAs1fF7WKn6Poj^reWc_};@PG%R-W=?))QnP%H0C~r!z z4h{aDFIM{@A+=7>){QkS2Ws{y{;8@ub)4n>oPpek(M}%cum-nTwKhIWK+g!r!#8>r zrXU@KA3$(|5%A0+-!WTe(?Gvkcv?rHR^jb^OHli0h~ zH*>H|_F>xvY%S}X$VJNK!_?C8;jU*UyQr4J<4NX6)?Ak>SlgD*Xmj;G0I!@_ZBo+sQB) zhHX@bobl!8(4yj9vJbpSKDRg}1B{I}|3x%sGM;hD1aQ>FzB~4`Dz7XG<9SYAHJ;Ix zmcu*gd_ju<6`~2bRK+v@zE6?kmp?x zDUGeQ5>;_PtEcQ?q&|`1>(}xP-Abo|wl5XkF|nqYx4ojE0BNu)&wxcGwmHe?FQNw> zD#KaOpjeEiv~1~-;cqfkAL5mDK|M?AFXfl0>!l;^a_*jW@V?tMn8jH}B;!5u6L_j> zQcAr68g31blicoAB|#$o6aPc%>uQG`o3Fn@d`rjmnhsT~ z*92u7++Cz?vV=Ne3sePBl4NO9i4v1_dyX&Ht`btjnf+OPb|n_NqQ^&OIGmg?lG=Ui ze-NIXyL`p1O)Yo4IVyBu|EfGbSE>`JqguHT2>K9l6(q4HZ@CDGl~&AxyQ->|sf@+4 zYS<;;#b~owU{Tm`4l3K`fWQ?7Npw% zk5mWj<7ai6zBt}*QR1zrIB=oZ_b8eoKt&ax-BQn>ArJX=@9VCu*qYd-lZ|~ktmvjy z++5deFnoz*mMn7H zJP#q_>EOZ;wNxp0=FP#zT{oB)sR>Yh@kh>2HwIMDFzXn~tL0vLrhlGKb@dJ%3*>y7gpFHWamUzRaxAyY4-UB_JRx5gH*e9Y^$Bx;99wWpDTKXOD&o)g(`yUvC z^r{NV460y;MX5s&BSaNHPA}<7B&08|SzCMjsGASQ92kYX?T08uJ1aX03G`$V`-uel z>+h2WP#HrT0iA{?r)cnK(e$w8#6HhN<_t7er|xcD>al`_0H_UT&q^i}2^sXRIgv&+ zYgQ6pO+(VrEE)n7GhUA~yaS04&}3WC99@~XiX}^t6LeME*`cxwCsoq}NWQtZ$|GBQ zQGs*q_I7b7Bn)X%yTnebiG-I&30WN`NJ4%KGv+HOAp|a9@1$PH%F0G%vneJ0O8Vor zAl8@IUQaELSK`o#g><#J`Sf*I+5SGzPOe<1tIdj0$6UNvFI`d0${moNHUUInBf7La ze-ck_#bd5sLcQ0Lw?}hROz)ki<#DpvHyRX4m(J=3UCk6Z99)5FCk;mvUi>2T2a&xt zu~p49i=0-iJLXzqX>vd&TXtN!vVMPm+%t|)NlSn&on_VW^pq*xawgrp@36iPmhmU% zN9zZ#n<%)T3|6Ze3v0Mnuhm@4$-zGyTzS9VyYydlXLYwZoLegn`64NoPCr?o1apc$ zj*jF3wffxxMAkvX^y>Oru!~0jaw+=^fo2gUW?1=gRW4;rR>f`dFQnxj)JB$ zK-1MkjksKu?cRhWLRPuWzirIeIaW>plL5W&PFN^35J;VIzTWT&&u7Pe1 ziG`4vG_}AfXLZ@Ajub7L3zrOlYH%6!{-lzXKFYlsB%;2Z2k&5j)O(A+hRB-%W6M32 zq_6!dk9GP1Q12vA>tb9idH#BK(5suJCyJ*&nnZJ3f@KU-RA8vUjzrwi_}zj-8}G3_ ztfN5mC>d=-P_G+BuC)m3yKb>3K#rLp7B5b$;qN%N0xungTNS4C`^h3Ke1t6UD}1KI z6xIq8{KSNd;tQ>4Dz1ku9T}i&v*tTsx?8oEHBzZPrcwK_GKuKAroOOU`s*E9=ISy_ ztVB~)yH(oyNaEzl_zNZ|Uk3*IrlM$z9-fr%(%2f>Oa{C07XB)h;mLsp)<^Tw8p3O6da^3(HV6AZqwITb-djC3(xu1 zDI(N_^q+Wo9CSLOaXzegI{2k3$O7+H#`yG@0UPzccwh;;78x>L=y-ySqJlW-`5CB4 zl31Ll*6ubg5KPIsIIyRmRyBS`&8%C4jE6~;P3Gj3dm)9Agv54LsRdnPZI`U5qt{XC zEF_k^$Uu(mWJF)jS{n1+AavaJi70N+Vl~ikl#a{39769@!lkNWr|BTJJH(@JnD7R{7rrx|McHC6z^*nnn)v0AT`5IlSrGjOn zl2(M1)G}!~W98!clSB%f^ewR5up>qd3k zk~b+5<5pf0cTMQk%SA}f&dsw~&SV3+J8X4y?rp@$2Gc=+w9aOwPqQC9(tNTLMa}+7 zc@jW`hV|r-XMC`dcw{}~`?EPDJ%YqJpNeJ)?+5)Ui6gPSp_$WTOukd~qtUY%8FXue zBWcQ(C^>j@h&X%@a ze#S~&F}dA|PSm~8IP1`uc8=YU8^u!}s2s)ibt7V389+FzSRzUaP1Ahi1V6rF#*ZVF z%8=6#oRypL{~pTJ{JnAMQXou~P2JvC3#V{A)9*%!EPCJyTAL@ydKGQ4-o-gABe!i9 zEm44)AwiI(9w<-C21pS^?L3+E`wvQ~dd^riu;rwq9^^Wzf1;x6Sqqu2(T8E2GAkqa z)UrxVs2`THPY70_bKlM`-i^|^Mc2*AKp~@)TZ1Fy6Hh#FQq$@wmADDS`y-1-r^J|< zZa@r~rs7ADv1nX2D}wLw*mPLHYA`IF z(foBP4LrSNrliA2k*~t`76lIpAglhu=QAKCIe)}r=uTwH0dtb2!hUAbH((p6qvSP6 zixWNibC@mQyW8fmA6o3+T-(>>_%P&dxP@||++;$xJw-i-nD zO(r<*hW`;NrK&zmzmJtVm8?acxg`lwm!mL(9MBz}C>*o`$BK~jl-O>x=AFq&NI}LQ z#+eleS<6>3^q*UlXi7-dX1`)yHV4)DK%W*yPUrE9)1`@+S5Fr&L35YTlJM(_g-)C# z8tb#;L}t%b6a`*e(E#g`+UgS@6q5newZC`ri8NfITQX{D*vR9W&eO&v=N<<0wDcJt z(EWR>Z4@0erj-W-QW`95xCo^h0;JTg`%P@OiY)Qk zIxfmc*_yu)3>I_W;jtF=)`0@>C4{?>G4u-6?&$NBx@dR=py1nYt~`q1ucXP$2CalK zq*f`U{4lnV=sUp~kF*VBmxi`n{dD&h6&f`qP7=`*65FP?75(6y%9s;JK^Lejnk=#o zP*#$HsT`Az@@eb4ZcA-|Bk|TXT60pgmQQiWjP{X#E~)T4nJN;Nk z^*Tv$$%oqw8uaVDjs9!`BNL_v!@>{WS#c*BXly@sN=)yNyK7i{xIH)VHD{oWW}EHp z4ltzHzKJN?;fj~Ecx6st#_iD~jF&u4$EFJ=UTfZmRjRGA^>7MH8@V#Ve%bo_Psbx5 zj^1Kt|4@>aK)f35VJ#6TPckCEK30;TsBzWvlf08RT8GZ1Lu@=xt}Jy#BPLe9T+0b% zKv9KCw&Hk)nv_C7=N<_dG-zxpKJu)E=-6gzkY;{B@*6Kt{dllL@6g!j9@U!Put&M! z!>=ec{P;)nLctVzjn|3F?9J#)Gk*RDtIF+|-77^CPTBKsIv5+E;e z_=fVR_SeW7uC}(5fBq%wYnAvZ7B72i&c>=8w*3sgFiW|Eg~dvH=okN`;s2nJINh@r za~@526_{9wY>^Cg%jQnkP4BUB8Lws^;baHY+*=#!*x&bI2 zr3cdQVY~SPAy!u8{64D*3Y6`jtIhK(l4-e%Ei6Awu%xZ%d|?T0E2KVE5+F9}1bKa`fW?>XR?q2^ z`;5hn=D(L(hJx`#ueI`DQL$Mw5fWtR^j_VPl1fV1BRb<%YPMngWwsdTz35VfS|U0+u#&X{t-T~xS7z(XD%7qcc#n3eqOZ+#Y&_v_D?Z*cR( zQwrg?Qv}?9J@Q}noIQfA>C8U^y|!QW60C{F4{7F;NwpUKz+Gn{`U>&3_@|!#1z~;D z3J9_>b2MhY)&t5ZEhaSJF^}cv0Bi_DgzXuvvfW<@&yx@7vV)XOfIt{!bxGi{s%%Dr zk}`>-wGKV^s_v+PRC913+F~hFnxW!}EijP5R%RUi3Jj)X8K^~g{`ZxN{RT>+U=YK8 z_-E6BRc#T0|F88bK6m@8%X=4Zyr@Ci%mcy9o6SadqDG(S16ul(KqqFF=b?A=$@axY zXQJi&Ff*g}{h<~z0fj<=e2KIM3*L>7R4gJdwzT;mu)~n99q$-cE26(WcX*2~t3ita z|4$|3XQ^m@P8Mi9LK?mZzH|j@Rl|n!;KaWD5@h z0D~WLS6yzYh(Y5C$<7IiV-dyEvI&7&T=n;V_ZEImYu*3B=EZ*=P*ruMJqm!TkE78;JI{Tr1pPS*@y$Z#fBe9x)c!@Fz!*B?_Hn%pzBMZlpsPMJftSiDYcBD2jtFI5v0UYT~1Og7=cyqFeD_ zbynymmh*&n5f%DYIODstz_qNZ%oZYf#G7&gEF)NHL>{x_VBo~`Z4!MY+rAru$@yim zzhJzlgnWju+>e+2dTI;@H?j5+jlf4TZ>%xPN9}z!faxW^_ml)v2yT&-hGTH3Ay$_M zpCRiclgp!fYQ~-I;?%`YK&zO}(%jGO2I?pCtSUP%5z3bVChHfLJZ_>zT))PT8G*Um zU>Bw!&*TQ*m-2{^f|p1l%cagO?}`uhW9U`yuiS(H3^;~B#s+G<68@t!fPD#00E-}> zvroBN1+T;M-BI$Phw zJ}DtCH^W!RGCTeL@Rt6PZM=$y449DpW2VOv40@YF&H4r`jiL zSkSo91Kp)ecgZvpF@@f#v)wxTGF;tJ_-FSq(zQTkT`=eQsg^?|hP0W+PC3SVk5;rX zRyA!J`LGWbAEgzEJksF$Bm#J2?1#@>0ODO|!Js!I0LgL@$j~yG<;fw;+{PYTo~y!E zdZeUW6Cr=h^ENO+%!u`XzWKN!D2L}PY0W@|R;&n15P_ZkIwg97gcK4Epc@`l1{^o6 zh@)qv;@ZRpXm1`fN^EMGdY3TQ0~{ma6uzD0NZgcd(sbd<>T|5W=tY(Y=u7UH@3k9$iMfr6^NnVX{aP}a2(Jum#{Q&3GrmTK#ZtF z>^W~uhHk+YQ*~39IqB~waPoA0)nPbNNW*i0Fr0eB=r4TuUaGRn*;}Nx6!H&$?>+7Z zGo&Ye2pP87Kjx^2B1|BftE&%rjpbBNQB=Zm66(rI3*Ti(Uznn_GV~r*oUwz?HHV$!Ruc|Y{t^CF}zlkaNZFiW1kM}n%2296) zP~ZDSU%zPjeQedQB_M8$*$2a}J6>Z##9TzCt=<(BudJDuc`+AwYYpS*QmXMjbauY* zT;T3}5xyv~;0TzTs~MQZDw>5^MS6^2Dlm6m(!1Uvr6g#U!>1DB1Bvybu0QtKKxHV< zQ;8av;2;g}_I)7)kH)wCnu2VGz`dTLas|A4W)fJuZP~P=gwQ@XdJIF1qbIiUzFH%7 zZlVW%-M;NX|i88!@{9BS>`5mmBtmet!2M~tdMVh>_{AT4g z5}ZywWJT0p{A*tiM2R4dIt{N3MiqI9)vf2!V$zMqpbk3($`BrAyv|)>V#^F?Zkj5L z$~aCddR^xO1)Yqi zG}VHYh>JJkcUBWiRelfTF|g~qE~Lw9-ORojWs0cFewBi7d#3$#13f0}xO_F?7cL#T zETkww2P`;_24YjUQmp=;!?FEbAG#VOk8nZjL>U1i8Y$GQP_-(q|VL4m%?*_lq%ZnfW zR%5M53%aHpZq!dWAp%s{ggoB`-WFoZB?X|Y3BebtbQStz4dr8PSlI%OtCDl-(u%#> z-Hzjn?qA}b<#MmSlLHnjQI0&NpOs9_cw!H~NgarbFPvyJp36xkuQl~lu8hY%NRNS~ zMf5f{e2C2V1|1u9WEjS_KKU2;Cw`p$rie++AK|m~t0^#y0B}F3bLSdOpH3L)Ii!vH zmNc=(+5(Y-X-7Q{_#cyoSW%i{QZdgmeh^&KFLCp%0Ge8F5P48UCWFdkr-@1J%@}NI zDz9h1`r4Ke&}SoMad$is+M!%HkbnnIpy-=kE{6e(WInSD_DtDf+c;KN0poBFP1qYs%u}+z8uC>jD%^=T?y}BiFT8JX5ho%k^%KMuM5joJm+Tcvb6dhh>syvkH&=BH4wmN2Fm%M1dg zMT8foE|+9p=>Q4$5Vdz|DskWSuGXczb#myyX|dsjXDQkzjHftlMx@my!~fjW=20Cn z7fee?p|KVsK(kw8W-c!H7q~S8@i~pUV-!JW%((Z9^&(YiEc*x8W*w@3+PeYGzRIZ% z^qW0dZNB9M&fXlk9h+if6gm*|slx~DYiBUDP|rG8v!sG>=7Fhkt026^Vv>>GTVK(+ z)H_wl&?TNs2^nA*zd_Q1U_Y^gXQnW>B1p@f9?rxC#Fillk;_*dh!9_i-<4!4{PiW! zb*1lD4yU*6NK&5x*SNU}8RZ%pj1E;_mDS`A$H>;$%UyW=Op#&uW!oRh6FGM!(j=vU zN(KVDExiSk@?^`CwLwZ(G%7^-v-@(R3Yt+861=Mb3bgb4|rf3~O_{MJb)|8k)1+F66CGO^NLoqnFh z6)WAub>8ARlxAz-`T6!4@y?i0N-p=TBo<&nr>u;*%|pM;)#P96m(eL z26j^QoPuNw7kw2l^zcnS_~!}g=;U`I{$E5}WlrIKkDiDPh*j5lHtDMmMd<#86NZ!N zLcqEf9uSxEfju{C)-?{oK%9KEC?>h|WKvYK0(6TSjK$laH2qTZBC*@kH|Rs1STXyR zL7pw*Fc1<5DJ%@wWf77?s476;jJ;IGKz5d%Tw_`P_EGYb?f)X>OXvm1f!ZBdVx_`u zqG8sA<*4=Z={j6{lC}zMG%D~UF6_8?_fS%|3+^T9a5BRmt^GQO&c~`vtq(k!-9qK| z{U;H6X_r13opAUwpRHyKES9sN>EC$$>&4U9hk79lVcp@Vp?~_~ic>3v`mp~&aVZ=8 zZDs{T)>%b`xD2!xk^Gsqy^oZTmp*FR3D&t2wyOYRXhAMVm61weXl$u9NLfK(kZFnq z9~+#)I0d`WCObs}0TdY?R>FuIEsP8d7o(YD&af={dJwJNnL%Z=9vo<#_pb=* zegfyGepH$>u5I_@y?mJJaW!Yo`I^;UYsa*N6vmr)oxv{h5!|Cgxzx9aMXF1!$G81K z_6~=yFLTC7;^ZX)Iw$6z(2|h~*`u@;deUOB$hIA{QetKHreN5*{EC{S%Igc1?QK>M$>*$@}kx!-`8PhZk@j1*a{nh6N)=$|tk#Ja-?I_g;*MhZpB zlQV5h+7aDW4^DI(f!ho^Rr%jjHx~u?zR!#Xpvczpp^69hP0bZrWyl-ZCmy&>NBy%n5|8Qh@` zwVatmO6iQ>j7ZqyzvcvOOf~O?y$%{!bl0*##>T&U?ctu0e^=LDsnCZR&NRV}w^iRR z@0jv8mMficEcn^&UG{ZkOKqp@b1H2YH|ktHa_wjRiOwI*!vOnxm(VS>AM9c_jPqU> z%X5cfkjY5R$QWG@{~w0RT!LggK*RAQ>dn%rTV zbL^30-jDj%lk;yH@tx?`EUZmG@ZyZQhgpeQo`k=XD#79pu}nNgj_`xYtgeAO=n63# zO}`1yYuTdly>Ls{n*h3OhMe zQ)8QVvzd`}KS3Cqg3#LK9c5tOgqu)foF~27=w;I*2J{Wc$y=$vbJ=7$<0sb zZ0P;HlUi%&U&d7nT71ESC}*J~j`qA7T#lWJ9o1iE$}livVELPAk}I(KM5b-6cmIu}_6F+jt{xyAq~}w8 zQIyqB+q;cn_r3S&5U>?V6N9j|4kURwX$_gWMo#Q&`CibxAQp4}5S~YzO#I_Df%0Um2*7f$%jk3hq*GOi0~k3mvbE{%)kTu3k~}lCM-hKSu1anF9m*v14CN)9C36PDghb4Y`TPD=dWn zyh60^NQ=@17A3B~J=1({h3@XQeJK+>qh$pnuWM#ZmHr3g865EEy=*Ric>R%l&y`pF zsB!Jy^ot*OeP=TA(rN7Shbu|+a$GGkx0@Y)o$ro(4#6h zTNV{O^9WX?Kg5XrJ|Q*255Bs%Kw3e-T&Ar5MiB2bHPIH2#5n-2vBFf-E}`+PJRZD* zs!+9|kQ)2eJc1~RK(nSUJe8lk@~Hb-S=ag+)q_HtWK=?BM2EdCsyZ5;c1laRZpNM+ zn;xs=nC_J!zTyC~ZIJ;!O=PPlLc`v z>uz2Mr-yAWmD`O=QKif{X)WlaRtC5nHR}WabhlnC3%^qt^lEAhQCALOX_`Mx&Yibu z4pb!cg84^3uOWrMPr|0oV!Xf;sacoUf$qaB3>=*l1|^hMhbN!W;(%HJOaBWNsCM2Tw$S2k=-LapwMxLsNtWL?Yh6+Z zgEbnnQ|n8P*x>bXKl%iPUDtS&D>MAO5(ZXDesd!ws7m9%9l6naSR-5|iF@YURNA9Y z%yPvGjm(*?IZ7C8%q@TcE@hsqVl|?oByGEqgrlMF4Kyd11njxip3)w4@(Ls$*8-hN zdTU8Nb%L!x(Nukn8rc#9coDj3rR8}(K|x{@0~LlVefi|eFKf-`c~BOECWHs%j0wDp zR(GytVK|>UI4uzg1-B|o_&7SX8VPMxO5OtZGlIDbzy%wRknPAeChv1?RUIfPZ_>E7 z2I440SaRwy-Qj}yYq>PwI79k-pQ+!q*+>hIonc;xL=ib%hAyo{XA%w}XVXPadP25s zQh;}}q%KW`q3KA-3gh1==ifq^%r|+`vzBxHXnAceg}cMl2kacT1S*DqKAsIS(sA;j z-D-!&qd4+seTtJ+O%^)~%+{wfoy8kj`aA#x}&)n7!uuA1jO&>dD zX_!|xtzfeN2cF3VueMgLhXdu#j#FNSyeSXbLr?yW^U=p+eq`HU`7jxs_2)M6H!Ovq zyE~K(x}x1H$NYNNO{aOziM#&~Mq*OBggpn|*tx?aJW4U_mw0o6q)v`RpT3kOHX(^N z!JM*$@*ynhr0j{f54sxQLVRg`QrTQ|+P~rAxC&qWg|0&xx|F4HdS~RiWv+INXacpG ztrb)@Gc)}UrlA&N#%F0!L3>t8#Qz~&waYX$_F1uN!T14XG_+x73$^|L@3_>dCPns; z#ks4V)>3Z&S8bOuv-+Y9sgCxXx}}TaD&^>qmt_Y!cSI2>>eM(hS=PQW}_v#z46rfxn+gU$gFZ=Fg=j2wQr%)x&MjwD{b+~!i8w_ z!&}0u8DF48K#bDwmE(h)zd<-b{(tqzecuQ1b&@qML6-^haemABy6UwH?LHf{rdw8l z)k=5pl|?@tlj<-l*A#oy()`J1c2?wRNnh|;{1Sis6|Jobo_?4U88%aXhEI6P=JJxa zK;>g_>*%aIDV^9mzMG5v89EKY)|adRPmGtL@;24@{5g37NNvjQNLg9hpk*0FNMo+Z zV2YTxk9rSE?$C{(JpSn!B?v_sYDj06m5$VHUpz;!`b0**qMo5RouR4RRUtpx)4?M^ zOH0eeBZBkjePj$jvlZ%r^&v`6XCToDg+G@X_#xY1X2v@L`2A+7b;>dE>LKN~K z7AU!sIygWPW$L}*%3psGup{*)l3C8i8Tuu2*NSzh5ogdy_Kk@eP#92U+gj^VB7${V zhJsfsGf87CDaFu$+_xqEZkFx%BwY{V!o?bcnMAV$*hd;piVuuX8@9b8cG&G_yb1)4 zn@37PDL$_$f7N6?avVl1h|U2wJuYyt{Dq=J*MJ-L4MMDrs-Lj9xRwJdx1`lZ&G7@r zGH1UdVW`+Dc&li~oySRIpy1TPSOuz$k%dH7^$iANJ@XCJrL&o$WEHGJtX%6Bncl0f zXKYm!%A+O~&;=v@uBIBL`~)o46ut_oGNLgk+!8-6kgeL#wC;_A9>(1?t zPTbAT4Tg=aRkHjIx#;`A*48$6$38Dh&z#z=?ufG2FpCFUY(n*7+Zz~Af!DiKf{ zsA&4~=9S#z&~qzxJbg7)5MVJ@<(J{+Hwh-egg%q(gHztP%(1cjsNV0CK>u_c`JNB9 z!Zcj?XJZg#j`yD*C@g6-1q;TKfQi0v`ekW47li@{RN!76kD~zd=vov5Q5guMdwlOa zo)Svubsu_(>Qb76ROk?|{BXm2nK;5@A_j_?&A}j>GOVgHmbWpvx^^+@4EzA31U`C0 z-TRO^e>;KC$(*ZdNy6u_FUOSTWr`I3NUC)P`Hy|gEF66`pA6+vA6l55^Ek4;Hq_kO zw_2v17-P1$^PXasXz1J8BNGo82qh%M9msrZ#7*Qr-*v;L=B`;}WU6&{mtK0+<)K5T z&WztaNXvq%vCARQZMk~@>;6vO(?e8ElGz^z#R+)mX;Z|<-;hEt|1>}abhp$>tL?vc z;gP}Vmu=DzL;>-XxS(~f{Mm6&ITVN_1JO*@(}$bv$$wPY3HM>Ad==WujXGY;n4bY! zSsjES!rF393b14Hg1r-)!G;HRJRyO$z1CH3By-=DPnqO;4Ux>A2x-Le8%OD`?a zr&O4`Bp2uriKbS*=1CUMI5VV=4U*xc4d!(&ijsV%U*6=hY><4pj1WzEQ|aziovAFE zw|84eNwZ#$1_FoN+>Mv8v=B88^|Y~tkYu#Pq9P$g$cGb|wZv+&qjOFI6JUF{(PLDe zEAf3=fV-jqRhooC*+FFoKze{m!|M!^=BO$U04O9d6jo?)TzpxMv3u+`Hx_AH-^J8N zf(m+?gJ>l%+&JLM6Xe7RK#<<}z`Y}H6azW&wsU0(q8d1o1&;?X%H} zLy)w0+;7b~hdLw>o^E~Q2Z^hRSZHQ~?TU?q$Cb`UEz>v)I$pqhzRjYO)ziPmwe{7* zkPFQMEa@uooOn?JX{&h=q&7)lIpuF3@7c`J*Af^J9xnbwsq_n8v1AU=^c+Fx1f?a_ zlMhd-Hf;d*O!@_9H3P6P7mcxU>2YCe=v?$VNAZXY7u8FhW~!= zkyC)dCe0ti{EfzXk6fA>j~`RC_Wh#cOcN*{v8K&XT`gRO&|k`M(Iwp!%~{x<2LHkE zE~F~nLTk*1j@uUc_VSU7AX*dR3^#4M}aWuFc_;SsV`+(jO+XIVVU7f6y_#~ zr5s+NT8ux)_x#fUQ0F-VKkTLWC>IQ~_~9Nfygt{yi>rB0cB09)rK_T1gB6u9QnJJ_ zm{np;Xp2LvnOa1GCSsNSs}9C#59^4h{L)b$dl(=^L$zr3jhTL z&N?fGRLL?c7>x1~7z+lyFoiIXW*Q0vq_~2)iV|tkUPLhXIqrAH{Y8NJpKLD=w9xMS z-dMyJr7nQO?O<-r16;#Ny7-03J085~14C z;nhp`MdPv8^K+gHIbQBo?>V6ji$OeMkiwkBpD}t5q0;=Ku|@8Vj{EU}@#Y}v=0fB8 zgQft)v52W*gEGqjN_cB9;XSJY?YC{fO9u|)GUuH|G( zIf-Nzj*87k3r-kWRAO(AG$jcD2yq5mg~g8XVL>P%B#o#&wA67*xCMp1B5=XGHo<6{ z1N;HAS+O+||3*mn_@`xP>}WyAvvX5K3c$oP`!X6t?0^iZzygV1ddXe!{iNJMge?ib z!^bdk)yfcrTFbolJ0Vj1?3ywRjFR$p7nHBN!#Lm$#xN>1lCdp{mLFa!UQ|t~SQKd# z3|LOm?9o7LFxkB27pt;->Df{agk|bA?b8nnY9)jg!wpUY0S@p90h0sf7X%6~{Q$y4 z*a)>Er$Y6XF0r_bm@jx<&c6`a5s`YIqp9~UjPzgl=nc&hU7NC#idwURMH5fQL!wx4 zeznbF8SsyUu-&2{Tv*m{Y5hp@3oZcZ*Izt+Kb^F@yQ`#SE8VGA%GOc8RiizeIU;1L z=1BO5qTvVI_SGbn(cbVsm=d)_0ps%+MMAx{-|{3j_>b!CdTagRcvWU|sQOEl(h}c9 zDBu_zTkm(|z7H94pAY(0fB!`HSg88ZtWQciU%zx$xV8Zk3;h3r4SN0iFuihuHk@-Z z_1#FsS)|69U6m)8g=B>cyD9|kHY-9A@Rd(v!@6)(5&@vGBQ+=bIbUvX5iF9K?6$*Y zm?-%RG9VhLUgsGj=w>wWQCV2wr~;gaNcDo^ZcH>6)7${qfUq#RFK{aUG>1$Z{31}e zh~2DKArAk3*nj04GmILY6>ZIDUK)>de7tI5+2(O2x->tF<+};xlf8;PgYwOtynjtWl|L*qXi-RS2#wUeiR z!iOLDv(Ff=6>x*tQ_OenhdtmgR;m0IFIGbTId#wdE27D^=X!a0YhtdO8A z3vX#-ZV6CCv7w>@Mp9a8aonZig6iq+eo3RLIZ4~37x*pbLO^PYQ^onj)HagEUKeA> za=?LQO1%0qh(S6b>^~Ilk=tG0+G=BOaUw0kSwAh#dctnymHp4?vu^}G3Bo60chv<0 zWwP6=(~NCerI1(C?Ru)g zOd-e(CK6oBGV+Qe->WFBa>(g45aL&5$z{I$UHZWQnx?bBgg7I9Yv!^OSS`yG;*f-y zw%J0%(#-)0>-72I1Pjv-7QiBZP3vYC7#L3S)Un>FKJlENFIwLd<0j2~aW@MZiHw0< zdOEfV8Mmjlp2j{Xf`8!xAt9K?S~6<{-~n3JetrV%;?IjO{99}KU%2RV>K!eEr?qtL zSHhmrbyVtfnixw-sk$93uXr>IL|3bt;&+e?zzhpU}-E4^)I3dC_8*b@Ee&y%9|{C%uY3gG!SZw0oong zZ!r}y?d}|}c7X{5OG84wY!zl|-iMGbMJ{6*szz-`Z}~hfY-Kk}rnUm5!$*zONi^?E zNzkY@lyXhFQ)T0_$7>)93p;YND!iAiwZ|-SVP9ZaQd)u5I8p(=>^qnPD^IlgM zTAbyt2E6A88 zPseAT?>&Z6Ldj6?XF8*>as{)GqfJq3@;gpD`nSC@9HX;}*Js1$ISoKo@>_Uh7eVhH zHX_T+k}*VoTa4*R80)a}3d_i9pC-f}8|`IJrkFiMTV9y0u8-ZsKR&Bvt*-Pro0xdd zjoN*XleF~Hhl7ISIi}2eWL?u|T#P#i+Ge~x^$v*w1ZQX~?v-BSJTHwZ{y{n!oG03< z4U4NOjyxxZ-2OOpt_jUmvZOe!c*sb`%2BcUw4`*D_c^yP1)}mYgJe%$82HftES)^j za^DH0a-*{n;}<7HiuLB`=QCN|YrL35*SNC$jI3p{8Zt*%8d?Ox(a9-gk2&OZGQV@| z((VGxXr}m%N#Kx>U`hPj^HBYrv{Q&{iJqEBezK^Gb57RG` zZP5eoT4CCi1|9Emsr{nTR;8q^P!0l}AXDk;)p<80@xKu;G?t11(aA|g;PyEMPf%Iy z%PRwb-n>mgNYF06h4B8>DVnO&DvB4#Q6p<-0snTYk{x5z2&aCX6Ki_Q#krxcc0{Nt zmRt6DI0C~sX6CyamHE3bf>^31Fd?$vqzKXHKp#s6g8M%N8_3} zyW+YhJ#!=k%XL#LFAg(mAhHTf;K{fBvbX)2t4_6Pkr~HX4;Y{k`7iap6pol;uj)TWvWa%Q7=`L6m-|e zTH(vpb-kVB-CfE zV-UcR7%<=OA%|fLe<|*-?o+W`E$opuk*TkecnJOYLGIN-!>Lf=Yi$#?KEeXz)N;zi zMpg>$dIaEF2F_R&!)K=qA!1!C&52#Cm^mw^1fr8N<1kx|zt^AHeNP4Ig25ZW%WQW=E)$|zrj@GA8ROqjaf zLG`L$-@%^~jilQvW!Y#XCJ$fh=pY4eL$TOPGNM{Qef*$b0;bi?#6?64piPFeCiwS+G7#4rh(5v>;|jEuyyJ5XFnGaJg+V~bjDs$ z(!#L*2!&SfvVMn74HzpBE;}10+vUS-j`tQ0S76h-$D){*wjWGhgen~;-b!ktWf<@V(h`XIA5)m zwnMzuf@cBgVQCpToqSs^>y+6>*Yj_-anf*J#Jr2*)J;J+<^v=6sLS*XP|sCu7zlU! z@!t_$j>a_Vi60Hjv=*X>;ZVSEP`FoM0cp`t&>d8;NqW_e__{g5Kk9!@yCvW#SonQl zd0_yBlAHb<#;f0iAezWK89{clt=8qjK*(4~p_G`IlpsP(9KC8PE>Zxzqt*{&OF?O> zI?s`{Vo8pa&q;3�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

    j6eS^uNp93{R1UwZG=o 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�$;Z}D*A1Mc^Iq?w!2iujWmQS2x%4fHcBqlJW2 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

  • ?IeAc7{DR$oU@v+^0C$C&_EHHtr{=fbkKAoL$$ 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

    Ok>D_w-B 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 literal 0 HcmV?d00001 diff --git a/docs/Img/XCMAkt.jpg b/docs/Img/XCMAkt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..027975a74f9a11a661a8b767037746024cfc9794 GIT binary patch literal 50023 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Ûz3&9_1Rg|J_% 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 F{{=kB3w;0p literal 0 HcmV?d00001 diff --git a/docs/Img/XCMDup.jpg b/docs/Img/XCMDup.jpg new file mode 100644 index 0000000000000000000000000000000000000000..da2036a5275b3785c60412d8837ced85cfb1fcaf GIT binary patch literal 18558 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 literal 0 HcmV?d00001 diff --git a/docs/Img/XCMGen.jpg b/docs/Img/XCMGen.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a35c50f4135df9f2d9be6227a479d9e32365782a GIT binary patch literal 67917 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 z zxZ!t$NAosb7b`0}43;L1lyg@aeWkJNw}Z;L;({I~`(s;eeX>|#{@sus`2p~3e0&ou zr?SjrG@?2_t0}FN=34p7&6#>9V8a-^_qmPOvXmYVBAkMhi0IH(w(a%bHevpC@a7P8 z+OZuW0y#HK4z;tT)`RC_G;G6e47Lh%K5cQR)geQW*WDm>vQ#bzM65LXT^XBWRRetB z=3l%aNVDmUwi`X_3S}EwKl+Igp;pLTYoTa|83FWdSOXCW;=ojoMP6-ezkfOo31 zWb|G?Wsgj%21<2R9lec;#fUcP?lRuc;{^A|pl)yWB#7sW%$4>%^^qPHgYah4F^Bah z-08l|({(L#*;&DG1@MFiQ8VQ-!HSyttXA}SECh^OU`iY>Q^%aA=wPd;7UzdNEH>!b$1`J29^{OJDu2DJLeaZ$eRV00B& zb@d06&W&dgOn}60wigH$MZqb@%t%*v%F!!GEEzOL$`s_fWCr^|%W33~9eX7r7vFQK zSPeO6g1BU=u6aW%S?!JGwD6pE557Xm`)tFeCDh((;eM#;~YR;$eGx3*=A_I31HrPoDsAs;evFx-c zU|bAnuBoba(-I=Qd**fvLX)R=UzWxhK$x^{#m)(}@jxF#CyKnpFNf4mf6k?=nF@Qj z6lx};=+ABS!0c9-9eHMf3oLE1U(;~EDsfKEO%)mvEAhBso3a2%3t+5U2~Ihz4dJuW z4Fn(SASacijdDRJXcY+k2%CcV+&1IL)a*f!{VkJWmqi@g+|;~F@1^C-_h}}pTt)?< z%z7wQQyK?9WY6?{Jw%a-{xZ78y+_@px0>FtH!HyZp9&kZ|*Afktj5Ijx_3MG~v0i#IHr1%-tX;LKbw0^k zY3nlW+oA<&v`Y@3_{RI}0Qu^@iN*E6<@_Hu9s2O5N(SflA$4ug^`hb>X*bJ-+d+Tm_l$&2L~T_;%jIu%xXbw?z;W^{6-v$sSF4W`gV`}vO2w)S9i@`Ihe zsCr7*&V4(6v0-det|$a93K!7O5qFGNJkd|OmXu!!=zrKFbP#oo7uM35Lw)cC7Hfl| zo1Miz+Hw=w4$mb>@j8mPbYU6J`*k#NjTh+nNKkq_Ot+dnOu9aA{)Y4JTR8nqd$JG# zgobz*>A1`?V^B10Ond*RuJ$WV6)RFa;NuWy@MkNvx_O&@Z+Wy?iREmg;4|{q_^Dej zf*(_Bi2{Rstv?dq#63JDWv{Zmz~R$ zS}0|Kr;U)NySCI__fU%cV8}6tLi!t32)OxUV~-10t>xR&p$~4FfqVwUuyJsfd*=#` zzAYdrOfs4M8RDxZAnx|Pf*-Jy6||d5+<8kW3_rF5Y`bzmBd0p<`$U;pG<2 zmfum1GI*LoX)@O$yqsHCG*Pq(H^O+nItPZ0#f$KWW5J^kt}zl zYbq5?ciMUjdN{SIc57ZOst$g$pQ^j{xLwzga;cE@sa53dI0C%vv=`3|oVD^kLA5ThPF)MDfJsARJ44j{IXD3Y| z2Bzwb53~K;@{-txD?o?(M(w+1B2SXK3Iriax-nl-=#AYgToRHf>xgyxCxRNhf|_z6 zu>o({&FdJY(c^rAg-X&vKG=Tz{F(JKg3&c{R zlsw{%-rSSNs16^BG%qwJ6au6zM-BUx_pP<^jV%g(I6M0U#M#JXEUQD~t&_P4#>zdP zZ}0@i>#!sbR=;>JAgD-EFYs}L4q|#$p(>Fa!v{!=_98&DR%8m7JT)@y_PdkpJ-nWL zxSguzSvuOc$7kg4P*Ua*SDwBh1lN&Nw(NTit{{TrO^B}&N2NLY(IRguo$L`~Qz}$u zzXTc@ASKxQV~WO=vSNmRFgQH52W0HPz_i0tIf(BHoT})Bl>Mace%@p2=|ZylipRVg zGC;nmD`BAQh{F3t&%;G(QLtMNn;S4JH{}N-5&%(NF|zz7-*y)*IE{Q!JmTT{WwILs znjT-x!O^U&$fBFvn?^h$Pc3HE>FO8wlZYx{ z>x$Inlg*z*iLF0w{%`3q#yESB9dvp)>*yjYCXB3Nc1P!UsMYe-)+i9S9}i~xTjmQO{r61s>Sq>Vzh$ys&{Ftb03jD#LwGLG z|A_i`Qy^P3CbF)3Sh%sv-f2ijxY4T%8r(y--LQVp`b4m<79L;&07n;Gykyy@%&AHs ziVukM&Ylp9ymTYm1e?TDV2UXLXG54E%y{rCAO7k^p1P;1u`KCZWiyDO^HA6?4f53w zHqtm#39zX-^fMoPU}9~(^4HlgE+^+3qd{)j19jZgo7aoYOcv{&_+GI+=M9bh-1Vaq z4KkC>qwG_oBg6WCQe=07)SWf91gH6g|Iy_u-7&g_OOd?6KQzu<_+qoIuLJ&YIJ$IW zM~3ka;UDGvv7CQ9@2K)2eKhEP#aT%uw5h{lSNlC8c?OL0i7164rggkf#^rE;vX2AM zFkgn`_Ugt>oqEq_3z8L24Sh2jtFOI~fArKlz&f-Rhhi$aI-<4>v-Lai*t3*bCFIpV z?gWX=4eVpoTi1LD%^4pXJ^?iTYlvu2?*B;ise?N67rNX9CF}QJj6O}2?ViGj$<;4Jko*?+<~Q(y zDf$0N5KZ0}fDQlJ`Fv&S_|^SPX?nFaG{KA)GW~bws?}O@{u7JgwiPZ89nwB}nf0dFMN;q+zWR7+`aWOxDi+_bQ zbXC;9yIs)K=Ve$+*m*_-T*-OR$_OOMoq5Rk=SlwPFr-%OWoj>v9|80!@IrSe7 C8MuD{ literal 0 HcmV?d00001 diff --git a/docs/Img/XCMIde.jpg b/docs/Img/XCMIde.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e3bec85c822303a0f0de711a0dc5e854a951a44d GIT binary patch literal 29646 zcmeFYby%FwvM@La0RjPnyZhko5*!8#?gV$Yph1HB3_eH#46cJa!QEkSlHeXJNJz++ z-%0K{d+vVs?(TDT_ql(Znfar--+HU7tE;Q3t80EP{rm*L2FWYQ10FpB03QAN0)DOn zWPY{&wa;Hf{xu4}-v0Rkfb$g4^w<&U5iQ^`&Lbq8M?d=kl)spK{21xibHIOmP@f{B zJVru$g8tWYU2FgV842(h0}bs7Dhe|4FC?TV$S98l$B&Uw(UJe^`b(6LkpNF{aFOve%+K&?z!3P%ED9~Rl%|$@X#N}> zZ%SdEW$HNrk93$PDj_}JTcV#U01TvG6T?Bm0Z0OVEQ*sDId%8FLS~&ZNpxMUe<vK;e|;@bXv7e<(W#}nSJWxmM#@s#=hEDqe&|g0 z>r0dTDTyxzP1%dBZG@5w#A-vi8B(@Z8P*o?PH7%z-;XPv|B_GRBln z>Y%5C@$LbBs?IaqGTMZ}7vpQ2^Q&s;@&#pw7iDd6$ z<^?02+vz#|;}<+6P{r*8iy=`F5oESXz~E;DPa?gY>1Rt8&juX%dL@x!l6da^1J+>_ z*@U#^uv*3$Kxt-;ItAXPrb==Jxi##I{H6eswEe zB*b5~R%LUtYQ7P(jZ|DTOhsf_bZD*}f2C9R-W!@!+jWqOoIW3qb6bhgUs>vcq;Wm% zolqh@v$30|BSAYkl%D_2 z&wh~4)=gH>w+ZwH(Y&TD3s)xRF6yY|ZcW_K&J#^=(pX(OAUQrFiT9~2AHVSt@Rt_S zLQR$lhMCPY4I3zh?xY)K7HMG27WOc-CTuvKP+@*7e$Sl8cL!?V9b1-Qh@|!dNjEd9 z3u%Ih$4>F4xC$xlMiKCx>0aaA+d-jWCFbm8mY4RUYjXrfagE}U#;{E^-cK`^AhE!S zf{G3Q@izSdo(@`Jp<(tZlAbqwM&T=3sjEE3)9aWV`0!4$*geG`_Zxii*VhZIMat+b zSNJ|Jy~`J7&C>`r^f&MogyXabC4bb0BsXb^9nrmpe1b$h_AWs!IM zJ~v~(XEa_Uyvg7ekcp((g1@5$+QWKaiA-T+S!Ug4EDu<7qVmr4cw-ZNeo7c+D#$o$ zo+$j_gK%lx{`vQB@flz1VPy{$LMm1WQcb?fALeH6etmrcQi096){PbD{sg3OuZf}Cs_4vB z>}v7g5$x0v{EE`IsiPP!hN3}o3&UB-Ky#92cxUb_j4I5c@mP=)&~z{fs6m>+$sFnt z@2N7o`hxa}rz6HgM(+AEW(d_QNgO1&rR-sYj9$x+1ZN!;kav;Ri{+G>Hd}<)Hb58tlo)z6_>3? zVg7x31_&ixfq#a_Sot{PNGQ&J47#rNj4Xo=T9(?J955S{FdN`#U+2JzNUJZIQwy=0 z78_d=ZA0@@Ovs&i<;zXNnQe4)tj0+J&Zj7?N^xh5J>8fWeO$w{c;SxBp*fe-nbE`1 z@E+NC#)vfT@i9J?_m$Cxp8uwCyMT5#-U0Hn>{ zGjnHRs>a=ye=H_HK`0W*5(6Tnm1pc-RLtxy?yx7|>mkZnQK%djW}Pr{)Esl_wqT~f z+FI{1#2iyuS;-eMe*xc3Tp@F2a8RiX#`VKRFhCCVY0^E)BA!4z=?pyvgtoFsPmPH4 zr4AfpP78cDBcv?yi#?JR*udX#A17N&rY1?Vv4a;aoYG(z7UH6|+A$arwdwXL_f8s) z5eUOH`cW;?1Topqk|1GM=z7kvYF|@sA9rq-M8AL3Fig7d?@Vfy_)$wJj}g%5ycup(F%5(zic)z z3qc~CLS99#E?TLEVn9NjsFXv)V4;xwDOM5R9T-xG7Dj@>pqNTM7MD3Zm26{dgdw)G zw?|+dqIJudx58w##Hckq?NqI`9e~czXrr!ZCGuv3GX~q;1{yzbhK8?G;AQS&6jRig z0}*+jK{v{mDo<%HziMSv@O)G+v;p3KdPg0%4qr_bVW7|3w!6G~6X;3LLHXhOIBYR? z`!zGZ0})fpZsgS$#~C?2Q5M^eAZ+G_qt#Skn>@*joCcQ;=u?-H$s!Eh`XR9y<65)l zOm@yCspF3lXyb>EOGgdTqUF&QA=}IOfSg6p46upV^0sF$lt1_jLKW9MPgeIz5m~60 ziWw_fM1Imf!R^6Hh9M_sw(PD=Xb~af4;lvJ9 zU~OwqQ7T?G^0J&WMl8AH8Hj?8YnPUj_}viOb1|yT^g_W2sh{z0IT4bSh6n1Z@Sj)Jgo0i^_2Ko77 zEKO-w2ov*H1OsExgowXgM&VdC5~0cXQ@ZCD`k!&H_YV~tP7P>P@im+|7?r5aBIUL@ zaRfvUnoH0@8oabko7&5Mh>bMWA`HAIu`>9fHtBYB1H{~U8;+$mA^9W-s{q!*a&H4t zW}O5^XSJs zCO>Hk_<0HFBGL|p8O)4j;$->^#{>=#H2Qf*qkQdU_14$N)4i&-y;!yNaa`>_p{NQ8 z8^Sn+5P@IbUo$Z=yn?O*Fgp4nQuEOh>=(4}E33=*NB0j&C={)&&136o>3M3Y!_c0P zOZA2T=rrF0keLCGKmdSd2mt?IYqU`XU%mQ~Tc{lueB(-WLA8gna;FOUa@Xb9nfJWB zku>L(WssO}Am0XG&5e%B5CW)v^ZcE8739GvusgY`AAr1&*ezVgOn$^P5xnv^)Ka!0 zhY8mPgD*6+tlm|RsPLpOaa4!vJzLv!AEH|@xhj{%Q4&`AwTZEawe46JYXYji{}Jk? zd?yBHq_+yxOXkW;hSCU5Wdakd$0N*2Q0Qj+wyQK-pTYc)o>{&iS15q5{=QFv%-|2;-tkxE}vN3rHBgv6YC_{<_q_#JDO zQ(H=EF7+pe?ap8p4_r?ex1W}+v#ncY2%R!RX+xwUJ+5@MN(H?F4_`2pe13<1rhSKC z_S!n*3ZAp?j5bwCoIgZtP2chuC-bu~hcIb$`iFCXgc8qC{ivMDX0`P@Qw~^#fh#?8 z!NN6_H?c#>?MXDZ3i|U40jcx;lb-;d%`|^EMcBEY_6B}6Hhi5mCGLAz8VBj&{A7Mv zzUbFj{Ca##5G{T|x%a`-0y+9uuMYwrPadzx71E()H8_34h(g9+Ti$2A{Zdu6Ynx~g zK2@G5p+P=^E2_@bVCl9`r0G%8>A_R=wF#22wTniukv#2br=~?ZNUKH8wFWwJPKkQJM> zmZqBIygIu|QC_5@%Cm`=X~6i=_8=KWQ>ylzLX${)0%j4Pb|MxAJx0_ z%I3g4J1k3Ya%+gAf;(ipZR9newe4>WctAWC28LXg zt%^&^cT;*lOoHoYzRM*_KG2S`c^F(-5(HMZ*>8^&9IaY#VLoy{9#rY5!_;<=7dlSd z)8icl$u*P1j&KS! za`9oM^n@w}$MB~d!QbwvzaI{{lFHdT+cNVEpu|iYGD=sK+iS`ADSF+HmZ0&=pD5L% z-R9){1YCGd+!5S;y%W8vo@rO2px+?{SqF|_=@bdLzT8V_2<+i+T?oj-=@~~6;&hE= z&~P*{aLS%geo?I_;HJ{m(6t&XFI84r7U10A{Ny>E(t~m!DqqA$);hsR2@PP^%aOx; z4V2>u+JxS$3$_`YxotNhFRUtFGU}r>+zz0nhoifzP;6#EtWmaB6<^Jw8`iUyO*>Nr zVN{CI{yux5--cqrPk`zilv7Q1kG4-#d}1;&?aMaNGk0&#AooC9WjU~Kc&c_J>{|%>Wcru-2l^Ipg)sf9{F!s35rT2`@HZHC6>o?p4CSV-LgMU? z_-Ai`gIDIz7nC54!g~RRq^2Gs5jsy<@ZBLW(JY?jBeo=!`^k8s9xFKAAWo$P0v1F> zDE|b|tx;q>A2Ck=5}LWl-is&h3=uUxg(OQK(8p*`x(tFX3(Ae`D|D73@Ei>-wX@#b zNGGspR+v9owib_m1U=Ylt)2B3V;vxb)YjKBV6d1)ZXBs^sNtA5N0_*rdhG$hR!`z8 zoC7+FwT=7~+}U0e5(!m|nHQ0PfPu%1X-<4TNzDq#XQt{XNjUN|+mAP-9v4{IGkmY# z1QPHz55vKHRQ>2M<%YU`;;;MP(<0ep$4GZ3O7-h^E(BY?y1H8{&VM?*q3pWa*H0Fz zaQEStoA8qJYu|?yC6Ji76@#=o6I{EZg$blgbMFhuoe%0=59(s^89w3?cf-UQ61S>vwqXgYECb5xDcNwJT|Xn| zR=pFK6%yxWCp}9unI&P!7f20=umkJ(;`S)NI&;cC2QGVU`q{I+iGS93uz~qw{+yq1 z5uSe?PnKdzjjiXahWu(o2{q)nkvt)2V?SiTQn=2b@L6Tz7e(W>S2V(M6KROV8AAE7 z9EoZp`zsZH`Pnm+h4n+(^h=`wK0!Sb;kMYP`qqR9c`_eV!pN_#F0M3PnvWs*99DHL zO+qop#cc_UVM+-7U|!-m5eo{O+QfG&zyk%Ul#*FipbZ5b6`ebhdqb~Ex020x<)Ze| z$qMn=0+pwIFwOKf{I`kd$CEc z!dVj@I#WReAKpq}WfS$v=XiPl%tlK3z;JD&wO|#!ZFO$hyBkJLxUzm>Y4NS&(vTxO zVNF67EcR~N-$>eSH-e|#Xd*>f$=ef{ZVj=c!IpD)4>jp#5qytn{2F}s(j$kW@ZD&= z%T2ZMljq1C>BG+Nhm$I7l&Tq=>YkHYR7FOtw6`j2;D<5}~ zwZA7bQq^eHhDGE!J9>xD&R);gWj}`Q*B3*+b6zMZ!n-h}%VmmD;?DdCc(9m*hb|dd z&u8_-mO85rWp5E>S!9+IbnrWd3(|&SPaU5bnjsOo*3Q;7NVf`rS&3(bObjjIeRINS z``{EqdgetOXytAu&G#frtgyANBa$g`S3f`2NO={_4{_<137Orv7JYd{CJ)&-_(4$u^Ro;SwT3VR2%ivG&YRG` z)>xMdAWUvlZspyiPttPFvnz_6L>!@VkMVa_CFa!z8MjC><@q+u4v$A8dX)`m1C*Rx z>Fd>>He}55Vtw$so#s?&m2E2Hv&^*H%GerT4(*JUqlw$NVP=lfMJal%Kx&dv=RKalBYG2{o2iid1B(G6FT4ypkCF29kB#&cL>YeG`|tSmOlB zte68=(tA?7)VceYRfKo>>b5W{4SNl0ycl%w+i?64@Rh==6(kX5eE&2>Wd&EPtlC&% z7;c5#1aA??RsXaxN0ny4aP_GM?h(Du7f1YLrNX7jS+?=YUZ-1|)+E`^v4Z!E_cE(X zhDK8;-YHtn^n}zCcHi!Vm8-@D-5NX48yvT{1~d2Y_Y)E=ZjSr)U+tHW{62}y8tWQ51_jh|Ud)@Mb)>k`ulnG-2+lSUn_TPJjB45B zVM3h%2}zPrR6$V@=DjNngODK~iNe}N-gvj35uqGHAn~WCPd=5Z0l+a=7;?%V=v)L< ze*(N~#QleE^9K*QPaF4Y^nU{IU+V^y2Afi~{-4ZXb$xSv%ugSZ(6TQ01JUvIh-x#6toSFOZ85LY^83q$cMepGQKzmaOZM-+ zdH!NXa`oeC?L6eMz?Rp?8^g=R%HUXXm+XflQ~$3?=Q981{+I0e1QrkO+dWWqzZ-W- zqw*;kW0!7OX;-b2&OX!3JQ@BvK(2eJ)by$~$G~Q}X(h`#W43ATJu(@fBlewuaBZ;B5{u2;Wl|cph3HbV; ztkHVh^wIDqKst}=`NWS6tYFu-*WddnJdx9?9F>8eAEv&Rg7oN%9AEAK1lUf&D{NOp zPGvxgKLP3sY9F62o4PQ$l0TZ!aJFpHZ5PdzY->2Cn&dFpbSyDTeH|fY_(S^y^Rqf( zw~nX+*X>o_gM>|cW|G0yclQLjHRJmJMYRu`J9&(4K4=QQS_3r;YSSC|=Z;^s8eTt7 zQrcQrZJ6VA77I>XFD^L!P1N0E3eQCJNnr8@kbVdzvYM_AI02y`5Rj3z?hh-*D-G5ADVw8V}5=h=HKoEwQ(*#ORpzPXA|6y^8= zyD<|f`*#M9paOZpJ!x1RR(1=8u48sDk|*LUmaPJD*YGg1s9Rdo1!8xFC@UWL#voZx zacp%@rvz-DWc{@3APzXX9&PE`{sLy?a4apaLzK53om2S%X@MI1Yz>P8v_E2{w!Vt% z@@tm1_bSl(`*Ht84To^8IU|OLwmR2tn?Jq zYj^3C>HBk^M`Lui%bOXSxz-8Y`X8%OWyozk2bvZrQbB3S=_H0BjM1KK(6U?SSSnKR z7)7DGEZVB>F@&AWBCgvrV=^q)ewAC$ zH(ZmYZq&tNdBkgRMs$nSrq<3O7_DEs86(mRBUn=CnZGh++Qe*-Fd$?|B3_xg5#u?` zDsjiWe^NI&BW;mDDHo?ZK1X{*9o=o2!sup@`G{Cr517hU+m7a;ScC1YM9{AZ_Yx_# z#GegS=C)DGwpw=Ki?x6a)7?&wv*L}^sAVOPjW4pArZ11@;qT#T=O@vgNzD>T(>0R~ z@oNh6*mxhLvcFvA2F@24wbD;{%ABVs@rtg{@_COXuVv9CGdAKiV#9RM2OwGPLGj^h z_a3Pum_AmrS-lIRISHK|TO-t0>Gn#t|MOFG?uXP#2IT7+4~p}w%Pebr_g!0Ma!>YkIrye+1wIL z;eAg&B8cD^KIX)jDv~cqgxE&+Dd2_Lm~JVJSmBFRy9vzM?Y|;<8fm2GZ4{NRRMa+*PjtrjS$EE)pkP7ZF@JO7 z0A#8r+M|prLp;C^Y_&F7d%wUhw#Ij#r{3ms0F2awbxGs|h+9W=otqEfMDa zIC41)T&;px&o!GbLn@Z1audn;M)#_ATWqR`&QGFw#641L)qZTyU?9I})(;mAhG zHXI}ErHCmYVn4C3iNiH?1?pvU(zKDGDbG`c%4cnA8jjlVw!-HVxrsfBeb?;020>R{ zB&3$^ngOXnvE*KUW#BP)4+q&8539YDuKks`)r6ONO^JT<@>yYPtBsRccIL6x-VlOB z60aA6<(Oktg{<=4a~-#zz<2yHDH5H7eoN)H3BMAqtMOmh6!^@GWar$59G-pn;x=19 zIMWZ8BNbCF5vIU6;5!xBPLl=6C%_>VZzxB7xr_bBH$SYL^g8R`bA2iERI03YFt(fw z;C!AiI_bhNKzeav;_*a#6@Bbt4GH!06ZOa!dc8dIqGJi?kqCJ|OECoV4(eN#J(cR} zIU~km+F+WKF0PKo=q!umJ>tWKQs)=nj)}6WUyK8O@`K4@#13vsu{5~fWwz7O^swsu+E@LY9+hWBD-*OsQ#3J52sXRPQ3WVI zkFAawzjeHI=p}S~F7UP#&Cv3C~nMZmo*_aaeuAFWW6dYa9N^7&e6$*qxr zyRGPZj5wPEkAd;iI$$ci)iKn0r-!t;gFWVWZd|2ySFT#%8Y;XAQebpvk#!t6ev4`` zcyawe@mCb$YwRFW%{)BOb?X>Ry`l0fjrucTBXe%*Y5RfUB_drjoBL#iXS2Ah67nV# zV=ZbqE+(oI8WWud&=So!h!pXS=vGPB$d-4 zS|COx*q9v;R&{5^4>R~xHkOy8Jyv)ujAQSr@XCcEro_!(cgrhu^aia{#Yb(GLw6eb zz-<>3w$*5$dt3M|wrYs;Hnu|?!V_5HYYF5xa`^Jpa!YLDV;uPYmZmFVUtdUIP+766 zGR?JN2VanmZ^jnG>KPh~DzP759QF2=TufF;D;6{O;W0GUE}f232|t~O5ehFV*rPa% zG}c;HD&IZQWHvD&XDJekwwz_PBi&G*9Rvb;s(RP`wD{{HpJ%0SU;^{2<{#%rj=lDUXIX8hb-}hEJht^ zZ{)UZMCLNrc^)U6_dwC%lNiSDgk+;%n4(S&S4E`6fT!>p)vbkRJ``{r=R=hl!VD+d zn8?|S2I7~MHKk$IV=L=Qc+U_q!d@L&w8_#NDe^eNpiijsbx0h^eqGGfOiAWXEip%E zzK{xYDcsSGj?FgmiSwk<4twkztwSX619AtFXA?>dJ+5pA(6%8!5&0}bWZW^B&2T1} zhs#Unp~*PwVeR)RqVM98Rpu-mUu}#SR^FhYaZA6$a@X|iG-f`u9&=Etb(R(S=}Mp}KBlX0b8i;F_>4m&iexk9ARIBlC635Bl~O>K#x71FkVx$I6c zo7s(yqDMwDjYU@`T;gk$*>ukt!HGPeJ%`eT(wfGi2?yk08vyY;2{Rk2Q{CK_v4zvJzZMhjwAIv8*V z9$A(HU!&isCT zY77&NdMW*>&KOo#`bZwvlNPB$|G$mW<8S|*04o1eP|wzcLfcz_l3`?Dr!^nm<}{nO zv?3{N0RL)KOIP*#SRh*%ezKxK?tE?q$$m2qM!fruzWcrKCjcxNo)!dWbn#5Yk-Us+ zgROKcl->ne)UY)`2&a_Lz=tjQg*)*?Y@J<;V=E3mKLL$-J3E9LFUbZ&n6yes5y;Op|^7kBXnv3PC zs8Bv`Tk(r1g2@0?yr70j6xtc-=@Z1nlox6|>N?JKY%>7o3CHJPi{ax|)^aQ$TPoko zhwRi1>1--Bc6t-T^z@7jg~x^CN6?xyWlN^sI%8HmGuvEBVsbaWL><`LrObZz8xW5S zn>B>7ZOKPCrBR*Xc0MxN(qf!dTsHz9(w?IUj1(iTnjUm*fM3x4kROv-Gu+6soqee+ z-md{uxqeJ(P!YPBZshDen5=Bi1UK>0;BQKrg`gEfR_vU+c$NIT_;ew2*BL&_1YJ?k z-e&|s_86Q1YAEYM=vW*z ztUQpFeqcdFgmA>F;}w-U%A1`c{8+E{VZ~r`_1b<3h=@4-QuDI)aDYUR(rU?h8ApeE zB`4?|eVZy6&#cmhKOjeHk9Vw)yX*Mu}xR7^YuPQ-EQBf4-v3J|#hW=S1k4L+U z6~;d4zD+-%J}AE@(=+@yZOGm>&ULxO%$e=n`JV5XJOudv9+IJr&_fM%a1S{6jE~Nf z^#9lzf1XO|d{JZRcP;Vi{hA)OwV1t-=?so<(r|tvdQrOh>! z%er3Xmic`bEp4=d@3C^vhaIl%4NuI$uFG2zs_n?**_ z3Vl3~au7H+-mS7;*q1hibc<|0x$G^PjRy#W&d;RT*;@-Td~K!By|Fub;N`+B>{GGW2y>@qOb8ZN3epe7;(L zFFU^Z&eeJ2`SL@T|FM?o;BeTUvK|~7-LK2kRnA-;sUMW_(b_>rOLuh6ldIyuyFEX3 zY1K(L!`I$$Hmz8woBK_0|6-y0o%&C}tL?^XXW*2H$=kcuZ{C5jBEe!j(yCnfoCEYU694;*=?+Q_> z?-#4RVfw&sewAO2$+fcTezWSl`0L2K3UqFWtA?X*;_vDX!22?}=q51SFPqHA{eBQH z<8UkGl$nDwkjE0)hTSh?<59GdB!s>_s!{d1_C@^om9*ZNBK_E?HnaPVd0D1NSzM{6 z1@-R`x}Rvk@K1o}2_jEZe7?K+M(D%o(CkEK9)Gt(Zhmw9VDpJqgI~$0z{>;8DNV=I zNB@9ERyP#x-?`+#0?LA2Pu)Y;lZvtf#2nu&h|0LyCb+JY*j=ipI_1w6<-r!$kp2Os zG=sT)Xw*f4(*09jxncbSQrozYT)X$$p<7qJ5B7}5Iu2r6UEVUfE?Xh{&8`A8u+SPS zjqNLA*C+CSK)IdU!L8Q^qY7;q*AIKYjNmteKl1p)ZW7;}{3r#B!J%r<2jPD}e*`+0 zn&i!S@?(-q6n<6zM<9RrrL@0DNEOkppNHOuc>DwMxdA`yt(E{O4_~d`=a{{=Jh1t_ zbkl$M6`R{3WA-YuE#tod`~%uP`9k+&s#)z{UcZFcRq2Lg z$^3$&E^480T-__+EtZhWrvx12VimQ+0O1m{R$QHQmndTM<`bX6S3zH^7ViCQ#ydIM zOKE?VQlN<;=VmHVV)Vy*XMR!=d$5)l?kxZ&s^}1?k#=wckfJvIMY{<0-`C7#`z&Jy zM_F2s;Qs`W=fp0L30NO^uS*eqPYxv9E?bUE6K>53-5D|Tior1K#M%ie!``TzFNfjpQW>+haW?j7CLmtQJMen<9N zogAs1j16*KrBh)(rl9;c}& zNL2FZzA@O^#~$5k@SBP5yZyV~E_8pKApdULC^PkDqI%G=ZxF@1BP%%r;yA|-KLPbW zKHm#BC*3#@Z+;)R`w74^jTqYQ{t*mWa23zXaQbyy_)hQU+UZiS@AFx__qf2Xt3P#x zux!brLtO6>_UfsyJWAKZ!Tdho<%#1HGS-RGp%CW_|BBNn!0Pr_y>(ol^ZM-N6|%ue zS6jPXB(wb@c`+o{l!aGbLMR`Z%DeVcniFz1CZ{(9JOe~!9@ToGYg>L0xD(g8k@-z0 zM)Yr#F}G|5>l?VpP+$C;!2ekWAyZSrZ+Nqe+`FXveRJzL`|p~R(#OqO5w0QuA(p-c z-nz{otFs|?vV0)BfaaNoO8j`j9Kj^ZJR_LJsd1U!x_@*DQTg^s!0V{mCUMsc`zwMs zpcsZvLms|{_)CE%JbP8^(vMT9*RZk%D?jb=g4@Y@jVxZ0IPl*vKn6`LyM%5FjaC_H^glH>Ik_2C zcruFqlg40&N3kDZFXkH79+_hIR;ykRANP6;u)czM9hBK8XF5TtC`^l1__F1OAY?@> zEr$p=xgR-ry|{hd-?GTs#Xd==i*{D;X(gkB`-R{x`qnNV#E;e>PjDnzfn|u?Sf{?J zYsj!T`I<<$LbgxKN?7Oj^kzeFKle9l-#W1;wrPWjfH_-zhBAGRBO?Vt8- z>_Jf;){8WXIv`mXs;0Rcu)nrRNaAI>f;pQ3PWh1H<$QtZ;v;y0FtNS~!F&vT8#vs$ z+|8a!xTTTS?ZXPFr0e>>(oCM=jC!D3? z(iLRKG~!iy9qW=b`F2N7cmz$Cr!?XViwd+UqMFcn$t-eur)?mTHKMi8_(NI}wtk2d ze?LaAK#ZvriyXb5MvU*C6g?Xe#*#7_s+y~?A{~yA`fuBW^{9E|u%?Y~Edhol8YZ>I zP_`hXNJJ7*v^>euyGWK+W5f{AKQlC;*-@9RugCntL}#pEo0-P`NefJ6-!o>|F0^c2 znz)|C9*xdFB>j$Fgz%o$dLZGhkdDxbmHQJ^+FTP=t}KgLR>GNLcos;J-rQFQsV1fw zX>?pTXT(dE#pP37%>}#lYn$-JlqrjaecmO7C9J5@;L-7h5EKLvz%)O#YKJKs(4;|Z z5(OcJBCBGS`W$OTT{T1qY&KA`9zm}b?8@T>_mtaW@*$zz#Et*`=-%G()M_ zP}+kNWfQ6M-3iK4iA9NOB`+CxVl(^ECy zfW>}9K(ChNp`|t+yeat9z3P)I2x(v-*4|IMGE#%u{G;mNDHA?0g=6wifvLL{u!- z@txIXdagAr?UUO{~`&rPqKjME-DZW>h3Y*n1jJO&u~g! z`fR6t9boae-pvSF)r_I9t8BJuXc}X0T94ICEg_?=wjo~*yDLZQ4-2yPtJONX`h1Qn zYfnY{IZ<;7PHl$%b|3ZKB$cUuWXnG-yW<`CkO_g+VS{7{d7@=?Y@N3u)dy@uAN*U~ z*6o>J^>*D!Qsu_;BvfeWZ$iH*>CW@r_S5!l9$NxRO|7WWw{wSnJSIS(OP`Ut=Rvx2(U#?v& zH0d9~^4wP5{t%ziL3BcBE1_)*lW(k=tB<4Y{?Mkh*)suZ?C0=~E7#rPoPS!x*1#Og$yc35;&O)QkZ z3ws+|?JBH|!OQYZhRVq4tF~3d)}w5iC!fcaB*KCm1k4Y}UTaJK*YTwCUjb)%A?0sJ z@JGp%R{s{Px{?WZ=H`bii6FCZ|C1}1&Fyg7z4nRxTVP9!`S!i$zf7PiB>sXOXo|XA zJayl<_v=0i*DU^m^E=f;{)4Pl+$GW8cU6DA|ES_ioZWD>d-$DD%*0IFUBoOBKB}k{ zNZqTh?iqia)@QHge|Y@6(-TnSwxX5S){gYIPVx^xx}s_bfsvw`ni0L`Tr1a4wOAOU|4nMrp#HDyo=g zyaCtjwN}vok(6IXLZ(AKR5HCwhTjRa*L@%N%-^3us)V*Jge_4%CM}u690QwBC}+&s z9Oh+((MO)YRX4kM?w7B#;?5R(G4N~%m@|ST4Lrzk(=pk;CwdWIDwnI10i<_^2JkDGi?513v< zY)(&k@w=bOv3jWaMXiN$D=uK?YaECjkKD4dZN+;+>U8xy6AgF2M11!36K%cw!nuQA zWxy}59oxpUn}t8dJh(L>RF1X4(8*SHNAJ&P&rwbc^+`W{v>M zy(#+jB?K+!c?7YOxVi={Z%^Q@VD@nZXjwpEVNAmiEr6JnyM~Jc0xqpKoM3>RugNZr;h(rg3Z{klpqOM^b&3EVu>t zLsb-vN+e}}2lgZam+>Ht>ylI-5qYO2pDr?Jqoss1CQ?=O&2Mi+seA>6>KktZfXqn2c zO-p8XG^>@~i~5R&paEI67ege&P!YinvoKyGFG--fM+XW+lI7EjR6+FeK1f-fqP6Q9 z9oD!qcqd1LD9}0NOGzmt5zX-Wi^Vb@FomakWR;+yZq!mcWshV~JXhSFA7Ovb zLcI}RapfeO{}G*Df98#>e?oOygW^+ePv8;NvpD?QPEf!P-bbQYD;I(WgFI^tOYP|b z+-$R^tIK_S@WD)v*D|)0?+3SsT+**qW{nK{(}u|)ndxg*Ve3w_8$==>z)NwkNa1H@ z^@C^YlNmU}k-{)&K)RGzE266BEHICoduH|pJn+pGah&{}8YMV6Mk``ecZ71PH?lx~ zP@@VsqS>q3vVIX&YU*imaadIz-b5yY(80|AW1-3OHkBheX^`WaQ^-*$gTDUQfV|sw zsj+32+>ChX$y{y`W1c{#;xRn!f+rD&A2w8OU={&+Lz@KzA7Z z+)yI!?Sr|8;Y(~{Kf#*|cs^d{;~pH_L9hN^`wc>h++L9{;vv*Z}0PH0v4eK#a&WvcQ}B z6>(>sjK~Ctn%n2(#CyxFXYlo@7iyK0E7PV}c0@=-TcrB&1Tc-0_@fnW-Wd{{s+VFn zS^9p{56E_Eayl&#`k{LZN3+CWXV$7?49Y%>>j9-2W(i=1jPKTwz^ZU#P)W~4;<>5g zL|lo|Fs z#&;L+%!VOH%G{!%s3KQGd$vL@cJ#TbKzvge`xB^v^ReqGp1jGry(Q)zqhRqGD4dUctElzlcL9&7A3kBIGJam z17Ahwa*8jRrJ8upexe3ONU8o>n#zZ-g={nrvNz10Z=mES)KIgSEpV#o zfW1wZ-R-BWNg8D~m`5X=Y!ueC&c^EMKIX)=YB0~O+hk%Z{3d={ID1kW!tR^dq*yXV zJP6X-qAN5Md@5FfgAI$eg5a8u$Hsv+-vzz%gxaHN%G-LViZ=#mj2{sR0@=SLC$Rbd zAQFJ77cP%$Zp48dG2SQ)c{|Z7Rh__iq64e!T`*H$<0-p8DL<<>il$|g{QAg3q>2-z z`v=DlA`|2!h9GXSE|U>QKR#8=^?9yd7qO_Z|JB}iMn$!4>DCb?9dgc+5sFyEB1$MS zqGTw75``j1Ng|-+R6vm=NGNiU3`J7OSqg~-NJgT91VKWhXB^Mz*SE)g?{)W&H{SiT z$NDknnsd$djXn2TGi>`?hYep8VO{`@m_|Ogv3zH^CQ1>cHNo7#`0m@DgEgztQ*fWE zd%KLgaX?_y{oqO3gaqO1&OahN_6d0$S_3QP&RX&Ij2To7Gk)|G+%;G#&$_a6%X=H- zR?~ZQU1i>^)hCW7t{iG}BtPQr=c{|(G>I3tqSRQJODULP%#=4ca{pDg2F2ue@0V{* z8TpTi3;5}k@1`7EJZFglMqjs&;w9z%OmWh1oa)3-8)*}37t9{XXlcc%1-l4)uEoI= z(`Y8(#xau6vs9P?g=&D+Wrjvw7#fbL4O3w3V#5UdUrhUwL~I?|>KN2tgL3t;l z&?R`U-%hz|D`47F&wddWdG$t`1OeVklb-|a8f7UzVx<29G@5{hzAf?5&FZ(-_< zOzQ84b3GCD6l=oe6dX%D!f zaIssGs%^ZVC6b#lvFfP_s@2fYsfxDd@k7(PTkH(&R&&k+$|)glAdjC<=aUn>(9{9> z?&FDW)zUOeV`TaJ_IEnsS!re270;e@t-;wNL;986wph=s)W17eQUdd9D4aeMw(QG} znLrH+IM;AT?v-buyl$ok_)0XST8k5A<=g~ueGU5F-}jmV$*r!FeEo3LN&a$u1Rqw{ zJ=O^UT-UQ2Ip2N@m)q~}YZs>1avft+Atkbmom1bWO~+^JBV%FXSu9_c=u9wT#Y(nL zlL%n}0{cLCv=n*5&%rY!waGfu2%SAWlHY}BGMUhsM-$V3yqec<%=Z45zQ_$8D*IAj z5?=xCUjbOz-_ovHe3QFSJdfz5UKbesmT_1q$8iPNK2OOP1YBRv|JQotgsw)a=R7KC z7T4ij+)^7AxOWq%R3G(DlVfFBzh52u;m*{m@Uob?v>adWn(I`*JNJ ztao61L!RlvkMAr3Y!dK^?PC?B;{l;7mLYYEd0n=wkko6~`thi~w6vwqqw0gY)AuSJ z=Fv~{hzxQhaZk3#Ts|n80w%imrYgANWA5$H{r{mb?YC^jG6DloPYo@f5L6^Ez2re; zY`A%5H{ozUJjc&}IF-z4btn=Id={g3$^^BwygAUo=^4v%CUqs!pc} zRk9}rY|5}N2W|Ao5lGakmr{V=-o+Z$z6&7!wsTvzh48v(-(NgnR2FMeliWm!hk`CG z&CEEbyHLYXq4{jh-Fo?x*~!KAly{Y7{Wj!UN4m~)Rj7lV!pTMeAmq6$Db@wZ+A3XesV68WQ~&BML*R{)|9|E|3h&k*kDb?Ec$6=3W3s!|%8 zbo3Pf=L%391pgH~L;Mjt`(O*evhl6^X9f21h2T{qVMWvZB~xTt*ONB7iDsh732*7D z@Z=C#y$Usf3f}LhGx(Q$#p=h`Ip(J9_4OvAs^~j>mJTnEhdIgjz$lG2d?| z7%pqG;UTP#884G%0UK1>moEpX(^73Z?(L!_2vV_kci#8B9%SE#)i)X=Yt??g)zsej zEDvE!H)TfPr|_hoh+%;OKv^DeiaQd(+5j<1~T zX?=iCtzIvcm^QBIu5=D4Fk`aR$K|hZ zR!zpG0}DYTIU8TQTTRYka%3m=>8O&BVPxWiPKb*ky{8!1HP0$DVVE1KT|<+s%D6mi@!Ac^}Ls~*@8 z5I(fDnbRLtjOa-kpkRmulh%GT83>X-p*m@_J;1XQ(y!!XXe$-H?pI_Mx!0!ak2U*_ zPe@p21$X}nz@d!PB5^Ds8JxM{ci>4xec-1BqQ3&%883_yX)Yff50B~KtY6DeSXdmr z?WAZ`Iyk~-kGnGTU|s)(X&l_(1z&Ueh-b9G2+ck}Yg)5ODKJySzsFO^9B~R#JpuQi zv$@%!f{@?}eq+K+E3k;OkDlt+%pT43-ANS`SiFs4+sfWKK||+6<8fS~=Gi?Nra~$* zNTP8$pU&an(5+fCd))k6inX1TL;HB-|#Dj(0gRh&o|)^ZC*ii`z^i7cgSN)7|3E zQ%QPbcI(6Vf>PBNg|(K%{OWZZNG?~zhbsV$nDh!SU*375xLiNNFu8i~sZDBq^QxME zro!=Yxl|IDTO9ve18I7~FbPOD>oA9Cn-Wdh0)iuNfx*>VuT4E)Xs+h1osZ83Wk^5& zdj!){f9}08g)rKc?zJ8_KLfU!S-U@%FXy)Q)yWyqV_|)hXbmD z@3h$m33CKjHEC<}p+Wh%}oha7p%QU&($n=Alwb;mPdt2J4Da{?t zDl;D+2oGu|pz0d*Pa7Uao~HK|^xi+l#JakQYDNmbd}oJJUNv~a=@k@r&n;Url}(O8 z+@1@pxsg;G@REiHoCl_Q#{=RR`%Y8cYA;VF8pW27JYkW*_)=T5xQNCyJYWkg82x(| z3pO9nh>(M=z)Cudo)W&|DyTWTLh~Z+j?o@hUHqsxjY>v0*jiFnXPa#EX2V23GmuO} zuo}c08%<%<@qxwhjTB98TRMWdVX}V<7#)QjcC{6pM1!=f z=SqhfY^c0#LUPeyx#YJA2tS=AWd#k_DsNkneg*xBmQkZXbKF>m>bkg`R8 zeYOQiou>8TxaIjpJrOlG-&acb$@49;QF=WycGcD3B{dyAdq(s7Qk;ChZ>?^75cv|u z-%zg6^ZLrE%DM{^!Rh%-V@5E@KCrNm4Wjk7<8Vi<=(}%Xl?Sgoq?_z`8-L0#Mabl; zSTo{Vk~cJ}j3Z4I_}I|y118RpG-xkiU`q032apfxWlNl8%cO<38^X0_N@e>{dIrP9V=c_Uz7|DBIom|OVr=2I6$ zFBg9Hp+QRb$Q7VFG=;%hoR&AFYtHtIO}x85X5cPCpOZ=q9A38M9X4 znAkDMluW|HssuR9!qR`iOWx7|Q!}A{IFvZAuu6dKud!W5i=XH_wlGl;lTdEuH4<@} ztWObQt)@qk$gZOj|2;~B!ku712!Fsd_qR0P=1>x40D#tEfWR@Z)Q-2_uLt3H=K-gu zrxQCe7C2el5;8~8xL_Zi`0W|$17=)r7V6+Hmhw?U%%!5mzedr!Q*MviWjWIBVrYkr zjUuLI>7`^PhoT3`>Q_NFbbb!exPd}6dou$Ws=*Np^fl}*5s&<#(0VUXkcwc1UDA2< zMnuQ_hTH^8|0U#Wm&M-KoGo}}hW&4GZmZ3g9Kt5`;n5OrT5EP$3>5tH*LvfVUXp6g zW-L?D9ky#$ua=QF*5uhp_X<dC1>!`+*;{|R)Hg-p?KC_ ze3Zp(T1-rynLX)-&;Ys7>hw-qTc;~!a0tGzK8u8?mRhR88-&c)U%mT=9k+UaeDFJ6Efrf} zM5{HnW>Fl|LpRI>CG$&Bt(EJV6*iKT2W1*h64^b$={1KoO!86XCUwzCDQ<>Y8hoIE zdE-WORK|juFeDbWtutXAE%V|2s0%HE^>J4cM4BH?HA%`7($qldFq&rq2}j(mm1yGr zeO|;va&}mztt*mzphntF%gHsKrzD2Pnk7QVLFPYMo#q3)a&hL@`G~v7>hxB#cSW-y zY9vn`5?@y~3r!V0a1al(fk8h^fY;LG4>=%5ceVw1hbxZfox~nx7@|T{!mI^{$?M!9 zym$<76ay{0N(@L69ts4=cag@4=F#j_vc~!Qs4XIH!nFuH2Puj>DW9yW(K6C_gz3mL zEKd0RCt4XjBUvNc)ka6ZZE3VG^W|k4d|KWvS$UqbY9S4|{0zP?fm8FbOdzhTgX@%flr*SiB&byJFZi-{0o)_Ki#8#P^Vi)h z65sALZVj%Ke*O#834hnA8o-ceR&w^>iTHJYiq+Ttd}lS^wptGULI+r`ul-5%#e&C$ z4)0x@JE;y&lg$a|TeQIc^Ew|fJXbFuU8mj?=|#I@fYA2CW&fzy?RToG(6*DOQsgbp zQVkoZJr3uWX6>uy7<5nr5cX}34Gwv(^e=}y#o9@Xe+w(GXm%pL>M9*&^rm?C#4`JW1H$P2%!8d$J)HXg=wMbu-Z}EoP?3v`r z4<6_2*dPG%{|PqzlM9OF1Fq(f7skJH6uz*g?NnCEv@8g-8t7z4d;9fjvL97xxXlg~ z$Kt;rRc8AjCcGNfB{s&`HTU|RS9*7Gj8c8zaRO|@Eq=l+E&c2<*nocCMCrsnWnXJsU)r>!zgzG( zy0!nsgyN3EmrLH4e?&SUKlTL6w#!AUIDI}suQ-peAY0$d5p)Li;tqhLzr(7{q9#+J zUO;V?=Z4~Ix6dQbt;=?UC>M>ZYy_cfWMfHsw8mb{7fO z+D=bu>jSL{@^CduL{mZ2GiG~>ih~Ma-|4dE`D|RB;h!PJD-5}jb#3^Jh(cYjSk)52h}k7e zGNVAT6*jKSYlMRq-v1hn9eO`Cv6s>ay#06*1v>bs3>}8qF&@>`;_mKc*z+%govk?d z?fm^CDM;8ddaxTw%FonXE}vcj`m$&PeUSp)>xgR9I5nN@*0IxVFUl6to=7vg43Hk@ ztU{G_hOFL;NXx;3s`?(C42e%y0CA>6^FAC&nfii=CRJ9^ehV)2aW~lv1$cOAfh(Ai zR-o@*B5>DDQ(?-MLTf^AQ{#SNyAo==Dwf$T7fA*Je^ilvE1J5&%>bd#_oHUW&1=_+ zBYU$Qr}iW}DU#j*&hKoeB`ePvmY>*AoDVw2UoGBun^H-^)*&`Pkb1X@`Em3pYfErl z+O*~VImr8P@L5a6jd8N{?OL3_e}YYzJteYHR-I%d-d(@GsPBTdQsPDr42}F9LvQ*c zt|j|EAbs~{>L%8wmRJ%4?uuogjoTHV4U0$GyR@&b-E8xDL9 z*e2nXoe%G6S_=3LjVuV{`&RBN-!9Rg0~*--^2L9k$qS$a7S5k`{AJKw^%20^eR$Fc z-W4F-<+0nZkxuP1!2oOPuOUI}&{>8*2NeHDQ+NG67$N=URQ^)S5sqyAe%snn02yX6 zHnz)p9LA70!I+~R5vlshKDNCG)w9A|_35Pv*KUECFP=cInz2Q>*kHEvy%G*8p2O?+ zeUM>-++ttHH#*YhXgr~L70IRYhUTf>G|Lysuen)oi>VeUKUs|pHc*xg!|zNvkc8H7 zztM&jC#8|YCsb|N8LH?@HR$6!;iS!9m_JE0GS)6@`VjY&6S;>MMp)5_iMR;c1MA+I z>^i_;x|ypW!)~6;tSsu{)(Q1^35?q7PKPXf>&I%E2@z*57mu2Pu$8U=ya0um|goHjXV;c9y%jFFrzHOUOoyS!{H%K%7bjED~vXpw6Vm zuoNvd6tm;{#&Sqa0suZOWB&w~r%(kI*swvmGAT(B%It}*_pz@ZT}ei-82x{Elb_zF zp?d27&co;<+OGiF^_AVyvP3~gNB1GdjF7s;*w}a+-0O0W>ncXkpjK4}ZDfm-==7n- z&ePGO#nbH}R%5geH560stnD5hk%x&z60oC;QTiObNEeBByBISKf$2hwZ40!cgTWNd zFZG@9I*;kvRUTa`)X^g_>QiUt3$y+>S_YU}3nG*uM*b^3ZHhttY`sB8P0s21mf`g^ zRO#h#Ed0QXI^A*VQQqg>kGnzV6*H5f>t^|dtvf`W?_pdWe`xw=qeCcvxWKE~H``|Na z6=XcRvqSik{?WHzGJnl3M6aS+s62DTc$D^2FxF3cny0^}`ZYU&@)(*M-Vmq~_%B8O zWzqkBjMBUygs+90=R$#!NbD)=&JSX_(ksB~>RR7IxYx;)Wpd&0ltBx{^zD)Vh)qV~ z;4U$o$BxABrwFXi^lr!DG@zak0k6~Hik$b}zHu{;dwnG3}h3&R2M+54-czKEFhS|B?!WE{L0+>@iYI5I^#x`rlm{ z-Q-E^l+5>V$iEi$Kd@s2iL4lU$ELzn)%Vna82>>fgd|j;!^+CZ>p7KKqgnML#sE>- z8)_X8@N4sb;X%Th{h=xRbpzY0tj;_XYiA}i&SQL_(BHg;;Q4>#VvCrSg!r&Ip2eLF zxom?kvVwmy5Xk+)$uH=Hu|3|T=)=h7x7X62jRe^}{7D~5{7Zws5cy+Lkl1MP=klJP ze(DeU&iy}u{uc@@#p2+av9()L+y6{cn%MjT-Jgoq#;MF}z^ZG%+aEdl1`4>J!x0MF#Xa$o=g0sw&U_ys)710)~M z{(GN4g#7m;JobM03cy7Jz!7bc5NH92xCltN2oK!=%14q&0Hi;p1OE0wK}AD;f{uWQ zgz^hE`~(F75fu$reH5RNh*(WaJ34j}j{p{zSviGH z!!>>+uH!^&?B@QVrh^{D%P(E~lZ1|ePr^06ZUO_yqiF{1VKn)eGxjK){1NnDpdXcn zgpBwE1@-ZwBrX8)k;D@u^e3oD$Vh)E6!DP=E}rode6{E!n#yAWE^&1Y6DQah3N0w+ zCmpxMhwRaDLP=Ae%&HC`y^Hh1902RFA0jRiEX-4^)0JtB4k#Qqtri9i9NSh7g{%d?`P;24Y`|Zx3i|lvGC?wENXw+mNEYT zp!x|>l~5}zEDM+|KT?D)_C~9$-uU5;!ANj7yLIrwOl>{=4ze#-dtG>UA%{x7sM!wy z0>V2@r`>Q;n_mqgekPwq4cJ~0Z`dfaqbz4Lsp4iJ^*Scw{Hok^B(}=RDujgH8Y*TV8o*>P-1u6s_qznqMk0nF_g|G-MbK`KXp7r*=amGA%fGtn!Q z|A_gIZvL}w{?NdGjN$)_j-s)g-@5KvnuVzulsg5ZpCAyfYLs;q^eMOuZDPUX;PfdU^c!yfh8mRxkT8M|WK zq^$zkk{B43u{8#0&^`nRn;Y3)$Ccp`0_zVA23MW1ht|3;HdCN2>%Z3DYcvj6MXP8C zv;tT5yW1S@Hw4H+(+M=VbM&9@e|&mf=$^aLQJp-4Gyc5iliiJ6P9!>ig_7BiUI&c% z8)2l|jocf{{M!i2G3ky~306m&l4Dl6YrZc-A#vMHbCDkqVr#GCOeq}6mQazn@cvk(`oiM6b%+}wLJqG# zfP_ec&*p8XXTEGvR8aSjo*qpEsYj3taP(Wv{)I#fmJq#GYtwr{qYmUsgEAYhA27oS zB%CdooR&j5&{<}i^EjS$8UENe_8*?*!0*B|*`Fnz*bwS1@LE5QJrDYQ!{0u z)e}o!GK#87I&>m!LpI>Vrq-H8%z?)`~1j4@XSnTf+y=LdGSP(g-V;DDoU4w!*P9%x~f6xYdl_2WBp# zeW(&>5w$O6g5U>6pInnh>`!)V#_fue<7HMT@S!@YC!?{A^7?aQP_`Uu+H34ITo7&P z@Z^vW$j7bDoW@+v?xHoV6CUVJ^L7MoM3~^O-lOR*7Gq@CpH^}t{^mwms5k8yH~3A8 z*^*@J$8q^g_U>-E<_k;I&vPCYrTkg#7A^rQGB8(bhd7b783p=TNw6NDl6wDcM2_>X z6kDfpN?Bz$=8m-efxY$ps@=V}9+GB8J#u;mI7X{lX!gEzXVc%VfgO$pnC!xqsrImB zah0_&+}W<|l0E{ zi^c5Ja{vwsH9_e#nig2iQgCS)s6tkRYcv<@kkt;qbnhB4a*C(t>#{$NPj(gE#?3yQ z6MtWYzY!TzctAV)ntE`)Dm@gRkeh-%%6M$Sfq_xqZsaK*BLh0nc%(B0h|RLR$n3PU z*AfZ`rYP#@h&L!3`t2Pa@l@rV;>HWGkm?s0Dn0;Wfc)Px5k<6(W-dZXkJUUkX1c!h?Ehl z@u#9-j_{5UY!=5JUgmIY_QLZ?JgxZ0FvAx)Cal;D8yC|upE;e@2N$PFY24aYQq$O8 z6sd8}ON*_!fMFa@$#C^Q8CnEGR7Pu2%rwiDrcynd^antBAv2}X+M+Hy>br94{f1F1 z%2oXODvdv2zqE2ru~TCPpae?f176TdhZn-*$?)ynPOr1D}<5z?#?K8sXZ~;~X1vCfjcGDs~LtJwAVec){SR>fM zArP5#t)*z0t-Ayqj(x5C9KD7Uao+^%vZ8UrdiADadF_lEzqC?x5WdbFI?<@YtNg&8 z@4i$o?2!V@!di))Du+MHDf;s@R!vwRsNWuaUMmR7GG8%L zJ+`pFj4{;D9H1}WyNG>ZLNv1RyxGOi{TCvf&#kT7{8>@+;-DJ^bw^aQ^A%mq$Eyr- ztN1hYXDGuwAX`heH-U#w;x58&jB#~aoaXzGWBP}Q+(YlQ-k*&4<+R0sTIutfXtuZz zN4Kl*m0zII^{ORrb}>qI&TA>@`h{5XDV?2L+s&HO>oI^0b?Yoo@DAQxAu$7m@& zBKGt6z7pK_nm~?wT$whA_M2{~JcBO@Hv^-Gv%7ofltF;zhh%jFkt@Uv|89bdg&$GB zy0YWS%s?FK#>(s`z%2o-+a4rkYD+FBH~NBFi5KZUK8uA8mHXv*gdD?m^mmITdQpw6 zPRRY`4#J=Tc7o`5Jw(B(j=1c?a|ppUoD=qrocGw)p;} zF;L#{#c@QuE~d;r6V3I@f=DY#$^q-j`8GVY=unRj@X8w3MupgS)_K;o>VoR{s+39S z4vOr!ZG?K$EZJW4_)__rR2CzO24bH-hH1OHjBb$O zKst#&coY~Q{n{2;j_n$)$$U2gSII;HM2-()CSSm23r~|8P8VMDD6SW6>KV}US@i*( z6BMGQ5oXe3WEXZk^GbLC06i;{-i-~dW?#rzw3$YWjx0nY>Zj;AW%m+y>6vTZMnWDQ<2nHIz}}eX+4-pn`g7RGYA6 z#)nMZK1$Fc)NGcYUKY9|A0{!Q&@?Wly8lK zv!PF}t&Tx=A4f&j>=U6ei=AKe+GIspx zV}ahWIZ-G(k0L9?k|*n>wsA0y^ysw=k%N22)+WbGt4}99*3M(KbKLZwUltqfHR5(J%xsNP zo9Q0x*w`eKho0|-HJlZSkW&m}e(f*+fY;&RLe3!|Osp#7f)plE6(6F>7EugzNEXBe z%BbnSfoM_}cd>S{P;kl72|RNI5<*#l_BlC~!p^=oCrkhYc>qBD zzjtz9u6Zy00O+haoS;^8eE@J4ls^FMMbqFg2O^}YV!QU&r&FWknh1l&Xk;W$n@s7?Ml>-i?vbl^x z{Gc`C;C+s2wu!48WrZw*4D4^ml)%0`q5k2Fui2!O_T$3t{uKU-mUXlycFIM0$h9R3 z9F9g-He)P;4RI{fj+E1Y1AeaeUsxHhp;P^qGv*QctPK_)rK9~KG(&dQX;LbG>IYAv z>E%8(9i$5uH_6j)P4G=Z*9qA*?Sm4=R#e=Kt}9>~vwVs-`LL$GP0koBpz~^&?aal} zyfez(q572Bn4~+{j!uxDdzHEI>Ku!7_)4-d{Hfv|HnCLB;of$9frEvY2CD-QP7vEu zXs>Ko5ZZjQ5&BZErv@IiZILBhEi+g?@GF2n_{4x!7TAbYgB=?zsHG3gqRfAuD=6o6zF^Xm`vH7f)Iad3rw-b29rGzZ;W*D!TBE4LE0^acd&$x$9or2!qr(BMC|(Z z_C~~24Gv-Gs%|FIPm>1m#IRXWi42>;R|?a}OPu6*Ekk2-HUngU%zJM<1=kBF#lwcn zKqwPT5z@v_L$M0$@Rc`}P`N=$%ob!CmQxARS53DAc%k5vHukYLc3P*I~>P#nuRGUvST?+c#-YFc}}CD&?5I*RmBdn|fsR6tNnvN!D0RkB7p z0|yq)77E5Ec(b^|4fK#o`6&}l<@iN~TnY!dUmmeaP88n(Hgl9W$4aQP0 z78U4zEyqp~g@?r`J#qaoI{cVc5_g}7nh$qdG&Ccl7pa2*-QVognVN4j5t%+L1$dO^Fq6BuF-^8|ynH z$@N27g|O2IDtMCSc~XST^>i14AzDqfpZgrENDs(VT_V^&adV7Cm{TJ;p-jOJeCEBJ z*U1wa+L{}JO>t{m#;d=MuD@zCud-au>8?kzQiueF@k`h`unjiYYlU<5Gzs+O+wL

    (*p>q%fij&rnJxO3h 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 W|7S9t|C9XZ|3CY`NyqU2E&dO6fQ4HC literal 0 HcmV?d00001 diff --git a/docs/Img/apikey.jpg b/docs/Img/apikey.jpg new file mode 100644 index 0000000000000000000000000000000000000000..12387a0864025bc02787c34614e1987d6ecd56a5 GIT binary patch literal 45799 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 K?HK-V{eJ+n%4Ev` literal 0 HcmV?d00001 diff --git a/docs/Img/XCMReg.jpg b/docs/Img/XCMReg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9f7a4553af9dad8db8415eaf7a02fa482d6bf762 GIT binary patch literal 77742 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 z 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 ChY|$< literal 0 HcmV?d00001 diff --git a/docs/Img/XCMUpda.jpg b/docs/Img/XCMUpda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..054f9bc1edba03bab2e27bde39edd5d904c2931e GIT binary patch literal 160490 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 z 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

  • {$form.selector.label} $profile) { + $profiles[$profile_id]['id'] = $profile_id; + $profiles[$profile_id]['name'] = $profile->getName(); + $profiles[$profile_id]['is_default'] = $profile->is_default(); + $profiles[$profile_id]['selectors'] = $profile->getProjectIds(); foreach (CRM_Twingle_Profile::allowedAttributes() as $attribute) { $profiles[$profile_name][$attribute] = $profile->getAttribute($attribute); } diff --git a/templates/CRM/Twingle/Page/Profiles.tpl b/templates/CRM/Twingle/Page/Profiles.tpl index b5b869e..992fe64 100644 --- a/templates/CRM/Twingle/Page/Profiles.tpl +++ b/templates/CRM/Twingle/Page/Profiles.tpl @@ -25,7 +25,7 @@
    {ts domain="de.systopia.twingle"}Profile name{/ts}{ts domain="de.systopia.twingle"}Properties{/ts}{ts domain="de.systopia.twingle"}Selectors{/ts} {ts domain="de.systopia.twingle"}Used{/ts} {ts domain="de.systopia.twingle"}Last Used{/ts} {ts domain="de.systopia.twingle"}Operations{/ts}
    {$profile.name} -
    {ts domain="de.systopia.twingle"}Selector{/ts}: {$profile.selector}
    + {if not $profile.is_default} +
      + {foreach from=$profile.selectors item=selector} +
    • {$selector}
    • + {/foreach} +
    + {/if}
    {ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.access_counter_txt}{/ts} {ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.last_access_txt}{/ts}
    {$profile.name} {if not $profile.is_default} From 89df7482a6be72bfbd0ead47ad3367cf9098c416 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 6 Sep 2023 16:45:13 +0200 Subject: [PATCH 105/221] throw error if no default project is found --- CRM/Twingle/Profile.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 0f9115e..80238be 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -350,6 +350,8 @@ class CRM_Twingle_Profile { * @param $project_id * * @return CRM_Twingle_Profile + * @throws \CRM\Twingle\Exceptions\ProfileException + * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileForProject($project_id) { $profiles = self::getProfiles(); @@ -361,7 +363,16 @@ class CRM_Twingle_Profile { } // If none matches, use the default profile. - return $profiles['default']; + $default_profile = $profiles['default']; + if (!empty($default_profile)) { + return $default_profile; + } + else { + throw new ProfileException( + 'Could not find default profile', + ProfileException::ERROR_CODE_DEFAULT_PROFILE_NOT_FOUND + ); + } } /** From e39a91e4770a71fa2533bfd95a8d85b29bd0ec61 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 26 Sep 2023 12:35:34 +0200 Subject: [PATCH 106/221] Add navigation menu items --- info.xml | 1 + .../Navigation__twingle_configuration.mgd.php | 93 +++++++++++++++++++ xml/Menu/twingle.xml | 2 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 managed/Navigation__twingle_configuration.mgd.php diff --git a/info.xml b/info.xml index abcb061..145475e 100644 --- a/info.xml +++ b/info.xml @@ -31,6 +31,7 @@ menu-xml@1.0.0 + mgd-php@1.0.0 diff --git a/managed/Navigation__twingle_configuration.mgd.php b/managed/Navigation__twingle_configuration.mgd.php new file mode 100644 index 0000000..be2d284 --- /dev/null +++ b/managed/Navigation__twingle_configuration.mgd.php @@ -0,0 +1,93 @@ +. + */ + +use CRM_Twingle_ExtensionUtil as E; + +return [ + [ + 'name' => 'Navigation__twingle_configuration', + 'entity' => 'Navigation', + 'cleanup' => 'unused', + 'update' => 'unmodified', + 'params' => [ + 'version' => 4, + 'values' => [ + 'domain_id' => 'current_domain', + 'label' => E::ts('Twingle API Configuration'), + 'name' => 'twingle_configuration', + 'url' => 'civicrm/admin/settings/twingle', + 'icon' => NULL, + 'permission' => [ + 'administer CiviCRM', + ], + 'permission_operator' => 'OR', + 'parent_id.name' => 'CiviContribute', + 'is_active' => TRUE, + 'has_separator' => 0, + ], + 'match' => ['name', 'parent_id'], + ], + ], + [ + 'name' => 'Navigation__twingle_settings', + 'entity' => 'Navigation', + 'cleanup' => 'unused', + 'update' => 'unmodified', + 'params' => [ + 'version' => 4, + 'values' => [ + 'domain_id' => 'current_domain', + 'label' => E::ts('Twingle API Settings'), + 'name' => 'twingle_settings', + 'url' => 'civicrm/admin/settings/twingle/settings', + 'icon' => NULL, + 'permission' => [ + 'administer CiviCRM', + ], + 'permission_operator' => 'OR', + 'parent_id.name' => 'twingle_configuration', + 'is_active' => TRUE, + 'has_separator' => 0, + ], + 'match' => ['name', 'parent_id'], + ], + ], + [ + 'name' => 'Navigation__twingle_profiles', + 'entity' => 'Navigation', + 'cleanup' => 'unused', + 'update' => 'unmodified', + 'params' => [ + 'version' => 4, + 'values' => [ + 'domain_id' => 'current_domain', + 'label' => E::ts('Twingle API Profiles'), + 'name' => 'twingle_profiles', + 'url' => 'civicrm/admin/settings/twingle/profiles', + 'icon' => NULL, + 'permission' => [ + 'administer CiviCRM', + ], + 'permission_operator' => 'OR', + 'parent_id.name' => 'twingle_configuration', + 'is_active' => TRUE, + 'has_separator' => 0, + ], + 'match' => ['name', 'parent_id'], + ], + ], +]; diff --git a/xml/Menu/twingle.xml b/xml/Menu/twingle.xml index 80529df..f1bc0a9 100644 --- a/xml/Menu/twingle.xml +++ b/xml/Menu/twingle.xml @@ -6,7 +6,7 @@ Twingle API Configuration administer CiviCRM Configure the Twingle API extension - System Settings + CiviContribute admin/option.png From dc1118dac9880b0da10af1a347b0621c1c8a1378 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 29 Sep 2023 10:53:17 +0200 Subject: [PATCH 107/221] Version 1.4-alpha4 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 3ac0141..2e2f816 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.4-dev - dev + 2023-09-29 + 1.4-alpha4 + alpha 5.19 From c149275e1543aa7037743aab48a0688dc6b9044d Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 29 Sep 2023 10:53:32 +0200 Subject: [PATCH 108/221] Back to dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 2e2f816..3ac0141 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2023-09-29 - 1.4-alpha4 - alpha + + 1.4-dev + dev 5.19 From c00314c75db8c3a62ac0d5279f7bbdba0c1cbb40 Mon Sep 17 00:00:00 2001 From: peth-systopia Date: Tue, 16 Jan 2024 12:57:03 +0100 Subject: [PATCH 109/221] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 0568a6b..b731fba 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,13 @@ This extension integrates [Twingle donation and membership forms](https://www.twingle.de/) with CiviCRM. You can read the full documentation, including installation and configuration instructions and API specification, [here](https://docs.civicrm.org/twingle/en/latest/). + +## We need your support +This CiviCRM extension is provided as Free and Open Source Software, +and we are happy if you find it useful. However, we have put a lot of work into it +(and continue to do so), much of it unpaid for. So if you benefit from our software, +please consider making a financial contribution so we can continue to maintain and develop it further. + +If you are willing to support us in developing this CiviCRM extension, +please send an email to info@systopia.de to get an invoice or agree a different payment method. +Thank you! From 75d9516da0926662b37333ed7809a9039967285c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 11 Mar 2024 14:52:24 +0100 Subject: [PATCH 110/221] Define permissions with label and description Fixes "User deprecated function: Permission 'access Twingle API' should be declared with 'label' and 'description' keys." deprecation warnings --- twingle.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/twingle.php b/twingle.php index 0e72d8e..062152e 100644 --- a/twingle.php +++ b/twingle.php @@ -81,7 +81,10 @@ function twingle_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_permission */ function twingle_civicrm_permission(&$permissions) { - $permissions['access Twingle API'] = 'Twingle API: Access Twingle API'; + $permissions['access Twingle API'] = [ + 'label' => E::ts('Twingle API: Access Twingle API'), + 'description' => E::ts('Allows access to the Twingle API actions.'), + ]; } /** From e7040c70d32b7f0c4e4e5f4104cd8eda4662ce04 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 13 Mar 2024 12:53:35 +0100 Subject: [PATCH 111/221] Version 1.4-beta1 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 3ac0141..0191e17 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.4-dev - dev + 2024-03-13 + 1.4-beta1 + beta 5.19 From fb25af415c116bbff1994bfbf834c5f641a7fb5c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 13 Mar 2024 12:53:51 +0100 Subject: [PATCH 112/221] Back to 1.4-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 0191e17..3ac0141 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2024-03-13 - 1.4-beta1 - beta + + 1.4-dev + dev 5.19 From b4c6581d4f3fb4f6a00ba19fdcd50cd5feddbebf Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 14:36:18 +0100 Subject: [PATCH 113/221] Set version to 1.5-dev --- info.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info.xml b/info.xml index 3ac0141..05ca281 100644 --- a/info.xml +++ b/info.xml @@ -15,7 +15,7 @@ http://www.gnu.org/licenses/agpl-3.0.html - 1.4-dev + 1.5-dev dev 5.19 From 8cd928caa92c10529d6155fb5ce1e8a86c75e3ac Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 14:51:55 +0100 Subject: [PATCH 114/221] Add extension template with PHPStan, PHPUnit and phpcs --- .editorconfig | 240 ++++++++++++++++++++++++++++++++ .github/workflows/phpcs.yml | 42 ++++++ .github/workflows/phpstan.yml | 52 +++++++ .github/workflows/phpunit.yml | 37 +++++ .gitignore | 10 ++ ci/README.md | 2 + ci/composer.json | 33 +++++ composer.json | 45 ++++++ info.xml | 2 +- phpcs.xml.dist | 77 ++++++++++ phpstan.ci.neon | 13 ++ phpstan.neon.dist | 42 ++++++ phpstan.neon.template | 13 ++ phpstanBootstrap.php | 43 ++++++ phpunit.xml.dist | 35 +++++ tests/docker-compose.yml | 33 +++++ tests/docker-phpunit.sh | 19 +++ tests/docker-prepare.sh | 45 ++++++ tests/ignored-deprecations.json | 1 + tools/phpcs/composer.json | 11 ++ tools/phpstan/composer.json | 18 +++ tools/phpunit/composer.json | 13 ++ 22 files changed, 825 insertions(+), 1 deletion(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/phpcs.yml create mode 100644 .github/workflows/phpstan.yml create mode 100644 .github/workflows/phpunit.yml create mode 100644 .gitignore create mode 100644 ci/README.md create mode 100644 ci/composer.json create mode 100644 composer.json create mode 100644 phpcs.xml.dist create mode 100644 phpstan.ci.neon create mode 100644 phpstan.neon.dist create mode 100644 phpstan.neon.template create mode 100644 phpstanBootstrap.php create mode 100644 phpunit.xml.dist create mode 100644 tests/docker-compose.yml create mode 100755 tests/docker-phpunit.sh create mode 100755 tests/docker-prepare.sh create mode 100644 tests/ignored-deprecations.json create mode 100644 tools/phpcs/composer.json create mode 100644 tools/phpstan/composer.json create mode 100644 tools/phpunit/composer.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f5f7003 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,240 @@ +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 120 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_visual_guides = 80,120 + +[{*.php}] +ij_php_align_assignments = false +ij_php_align_class_constants = false +ij_php_align_enum_cases = false +ij_php_align_group_field_declarations = false +ij_php_align_inline_comments = false +ij_php_align_key_value_pairs = false +ij_php_align_match_arm_bodies = false +ij_php_align_multiline_array_initializer_expression = false +ij_php_align_multiline_binary_operation = false +ij_php_align_multiline_chained_methods = false +ij_php_align_multiline_extends_list = false +ij_php_align_multiline_for = true +ij_php_align_multiline_parameters = false +ij_php_align_multiline_parameters_in_calls = false +ij_php_align_multiline_ternary_operation = false +ij_php_align_named_arguments = false +ij_php_align_phpdoc_comments = false +ij_php_align_phpdoc_param_names = false +ij_php_anonymous_brace_style = end_of_line +ij_php_api_weight = 28 +ij_php_array_initializer_new_line_after_left_brace = true +ij_php_array_initializer_right_brace_on_new_line = true +ij_php_array_initializer_wrap = on_every_item +ij_php_assignment_wrap = normal +ij_php_attributes_wrap = normal +ij_php_author_weight = 28 +ij_php_binary_operation_sign_on_next_line = false +ij_php_binary_operation_wrap = normal +ij_php_blank_lines_after_class_header = 1 +ij_php_blank_lines_after_function = 1 +ij_php_blank_lines_after_imports = 1 +ij_php_blank_lines_after_opening_tag = 0 +ij_php_blank_lines_after_package = 1 +ij_php_blank_lines_around_class = 1 +ij_php_blank_lines_around_constants = 1 +ij_php_blank_lines_around_enum_cases = 0 +ij_php_blank_lines_around_field = 1 +ij_php_blank_lines_around_method = 1 +ij_php_blank_lines_before_class_end = 1 +ij_php_blank_lines_before_imports = 1 +ij_php_blank_lines_before_method_body = 0 +ij_php_blank_lines_before_package = 1 +ij_php_blank_lines_before_return_statement = 1 +ij_php_blank_lines_between_imports = 0 +ij_php_block_brace_style = end_of_line +ij_php_call_parameters_new_line_after_left_paren = true +ij_php_call_parameters_right_paren_on_new_line = true +ij_php_call_parameters_wrap = on_every_item +ij_php_catch_on_new_line = true +ij_php_category_weight = 28 +ij_php_class_brace_style = end_of_line +ij_php_comma_after_last_argument = false +ij_php_comma_after_last_array_element = true +ij_php_comma_after_last_closure_use_var = false +ij_php_comma_after_last_match_arm = false +ij_php_comma_after_last_parameter = false +ij_php_concat_spaces = true +ij_php_copyright_weight = 28 +ij_php_deprecated_weight = 4 +ij_php_do_while_brace_force = always +ij_php_else_if_style = as_is +ij_php_else_on_new_line = true +ij_php_example_weight = 28 +ij_php_extends_keyword_wrap = off +ij_php_extends_list_wrap = off +ij_php_fields_default_visibility = private +ij_php_filesource_weight = 28 +ij_php_finally_on_new_line = true +ij_php_for_brace_force = always +ij_php_for_statement_new_line_after_left_paren = false +ij_php_for_statement_right_paren_on_new_line = false +ij_php_for_statement_wrap = off +ij_php_force_empty_methods_in_one_line = false +ij_php_force_short_declaration_array_style = true +ij_php_getters_setters_naming_style = camel_case +ij_php_getters_setters_order_style = getters_first +ij_php_global_weight = 28 +ij_php_group_use_wrap = on_every_item +ij_php_if_brace_force = always +ij_php_if_lparen_on_next_line = false +ij_php_if_rparen_on_next_line = false +ij_php_ignore_weight = 28 +ij_php_import_sorting = alphabetic +ij_php_indent_break_from_case = true +ij_php_indent_case_from_switch = true +ij_php_indent_code_in_php_tags = false +ij_php_internal_weight = 28 +ij_php_keep_blank_lines_after_lbrace = 1 +ij_php_keep_blank_lines_before_right_brace = 1 +ij_php_keep_blank_lines_in_code = 1 +ij_php_keep_blank_lines_in_declarations = 1 +ij_php_keep_control_statement_in_one_line = false +ij_php_keep_first_column_comment = false +ij_php_keep_indents_on_empty_lines = false +ij_php_keep_line_breaks = false +ij_php_keep_rparen_and_lbrace_on_one_line = true +ij_php_keep_simple_classes_in_one_line = false +ij_php_keep_simple_methods_in_one_line = false +ij_php_lambda_brace_style = end_of_line +ij_php_license_weight = 28 +ij_php_line_comment_add_space = false +ij_php_line_comment_at_first_column = true +ij_php_link_weight = 28 +ij_php_lower_case_boolean_const = false +ij_php_lower_case_keywords = true +ij_php_lower_case_null_const = false +ij_php_method_brace_style = end_of_line +ij_php_method_call_chain_wrap = on_every_item +ij_php_method_parameters_new_line_after_left_paren = true +ij_php_method_parameters_right_paren_on_new_line = true +ij_php_method_parameters_wrap = on_every_item +ij_php_method_weight = 28 +ij_php_modifier_list_wrap = false +ij_php_multiline_chained_calls_semicolon_on_new_line = true +ij_php_namespace_brace_style = 1 +ij_php_new_line_after_php_opening_tag = true +ij_php_null_type_position = in_the_end +ij_php_package_weight = 28 +ij_php_param_weight = 1 +ij_php_parameters_attributes_wrap = normal +ij_php_parentheses_expression_new_line_after_left_paren = false +ij_php_parentheses_expression_right_paren_on_new_line = false +ij_php_phpdoc_blank_line_before_tags = true +ij_php_phpdoc_blank_lines_around_parameters = true +ij_php_phpdoc_keep_blank_lines = true +ij_php_phpdoc_param_spaces_between_name_and_description = 1 +ij_php_phpdoc_param_spaces_between_tag_and_type = 1 +ij_php_phpdoc_param_spaces_between_type_and_name = 1 +ij_php_phpdoc_use_fqcn = true +ij_php_phpdoc_wrap_long_lines = true +ij_php_place_assignment_sign_on_next_line = false +ij_php_place_parens_for_constructor = 1 +ij_php_property_read_weight = 28 +ij_php_property_weight = 28 +ij_php_property_write_weight = 28 +ij_php_return_type_on_new_line = false +ij_php_return_weight = 2 +ij_php_see_weight = 5 +ij_php_since_weight = 28 +ij_php_sort_phpdoc_elements = true +ij_php_space_after_colon = true +ij_php_space_after_colon_in_enum_backed_type = true +ij_php_space_after_colon_in_named_argument = true +ij_php_space_after_colon_in_return_type = true +ij_php_space_after_comma = true +ij_php_space_after_for_semicolon = true +ij_php_space_after_quest = true +ij_php_space_after_type_cast = true +ij_php_space_after_unary_not = false +ij_php_space_before_array_initializer_left_brace = false +ij_php_space_before_catch_keyword = true +ij_php_space_before_catch_left_brace = true +ij_php_space_before_catch_parentheses = true +ij_php_space_before_class_left_brace = true +ij_php_space_before_closure_left_parenthesis = true +ij_php_space_before_colon = true +ij_php_space_before_colon_in_enum_backed_type = false +ij_php_space_before_colon_in_named_argument = false +ij_php_space_before_colon_in_return_type = false +ij_php_space_before_comma = false +ij_php_space_before_do_left_brace = true +ij_php_space_before_else_keyword = true +ij_php_space_before_else_left_brace = true +ij_php_space_before_finally_keyword = true +ij_php_space_before_finally_left_brace = true +ij_php_space_before_for_left_brace = true +ij_php_space_before_for_parentheses = true +ij_php_space_before_for_semicolon = false +ij_php_space_before_if_left_brace = true +ij_php_space_before_if_parentheses = true +ij_php_space_before_method_call_parentheses = false +ij_php_space_before_method_left_brace = true +ij_php_space_before_method_parentheses = false +ij_php_space_before_quest = true +ij_php_space_before_short_closure_left_parenthesis = false +ij_php_space_before_switch_left_brace = true +ij_php_space_before_switch_parentheses = true +ij_php_space_before_try_left_brace = true +ij_php_space_before_unary_not = false +ij_php_space_before_while_keyword = true +ij_php_space_before_while_left_brace = true +ij_php_space_before_while_parentheses = true +ij_php_space_between_ternary_quest_and_colon = false +ij_php_spaces_around_additive_operators = true +ij_php_spaces_around_arrow = false +ij_php_spaces_around_assignment_in_declare = true +ij_php_spaces_around_assignment_operators = true +ij_php_spaces_around_bitwise_operators = true +ij_php_spaces_around_equality_operators = true +ij_php_spaces_around_logical_operators = true +ij_php_spaces_around_multiplicative_operators = true +ij_php_spaces_around_null_coalesce_operator = true +ij_php_spaces_around_pipe_in_union_type = false +ij_php_spaces_around_relational_operators = true +ij_php_spaces_around_shift_operators = true +ij_php_spaces_around_unary_operator = false +ij_php_spaces_around_var_within_brackets = false +ij_php_spaces_within_array_initializer_braces = false +ij_php_spaces_within_brackets = false +ij_php_spaces_within_catch_parentheses = false +ij_php_spaces_within_for_parentheses = false +ij_php_spaces_within_if_parentheses = false +ij_php_spaces_within_method_call_parentheses = false +ij_php_spaces_within_method_parentheses = false +ij_php_spaces_within_parentheses = false +ij_php_spaces_within_short_echo_tags = true +ij_php_spaces_within_switch_parentheses = false +ij_php_spaces_within_while_parentheses = false +ij_php_special_else_if_treatment = false +ij_php_subpackage_weight = 28 +ij_php_ternary_operation_signs_on_next_line = true +ij_php_ternary_operation_wrap = on_every_item +ij_php_throws_weight = 3 +ij_php_todo_weight = 6 +ij_php_treat_multiline_arrays_and_lambdas_multiline = false +ij_php_unknown_tag_weight = 28 +ij_php_upper_case_boolean_const = true +ij_php_upper_case_null_const = true +ij_php_uses_weight = 28 +ij_php_var_weight = 0 +ij_php_variable_naming_style = camel_case +ij_php_version_weight = 28 +ij_php_while_brace_force = always +ij_php_while_on_new_line = false + +[{*.neon,*.neon.dist,*neon.template}] +indent_style = tab +tab_width = 4 diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml new file mode 100644 index 0000000..395cf22 --- /dev/null +++ b/.github/workflows/phpcs.yml @@ -0,0 +1,42 @@ +name: PHP_CodeSniffer + +on: + pull_request: + paths: + - '**.php' + - tools/phpcs/composer.json + - phpcs.xml.dist + +jobs: + phpcs: + runs-on: ubuntu-latest + name: PHP_CodeSniffer + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + coverage: none + tools: cs2pr + env: + fail-fast: true + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('tools/phpcs/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer composer-phpcs -- update --no-progress --prefer-dist + + - name: Run PHP_CodeSniffer + run: composer phpcs -- -q --report=checkstyle | cs2pr diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..33c30f5 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,52 @@ +name: PHPStan + +on: + pull_request: + paths: + - '**.php' + - composer.json + - tools/phpstan/composer.json + - ci/composer.json + - phpstan.ci.neon + - phpstan.neon.dist + +jobs: + phpstan: + runs-on: ubuntu-latest + strategy: + matrix: + php-versions: ['7.4', '8.0', '8.1'] + prefer: ['prefer-stable', 'prefer-lowest'] + name: PHPStan with PHP ${{ matrix.php-versions }} ${{ matrix.prefer }} + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + env: + fail-fast: true + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ matrix.prefer }}-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer-${{ matrix.prefer }}- + + - name: Install dependencies + run: | + composer update --no-progress --prefer-dist --${{ matrix.prefer }} && + composer composer-phpunit -- update --no-progress --prefer-dist && + composer composer-phpstan -- update --no-progress --prefer-dist --optimize-autoloader && + composer --working-dir=ci update --no-progress --prefer-dist --${{ matrix.prefer }} --optimize-autoloader --ignore-platform-req=ext-gd + + - name: Run PHPStan + run: composer phpstan -- analyse -c phpstan.ci.neon diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..a30e116 --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,37 @@ +name: PHPUnit + +on: + pull_request: + paths: + - '**.php' + - composer.json + - tools/phpunit/composer.json + - phpunit.xml.dist + - tests/docker-prepare.sh + +env: + # On github CI machine creating the "/vendor" volume fails otherwise with: read-only file system: unknown + BIND_VOLUME_PERMISSIONS: rw + +jobs: + phpunit: + runs-on: ubuntu-latest + strategy: + matrix: + civicrm-image-tags: [ '5-drupal-php8.1', '5-drupal-php7.4', '5.56-drupal-php7.4' ] + name: PHPUnit with Docker image michaelmcandrew/civicrm:${{ matrix.civicrm-image-tags }} + env: + CIVICRM_IMAGE_TAG: ${{ matrix.civicrm-image-tags }} + + steps: + - uses: actions/checkout@v3 + - name: Pull images + run: docker compose -f tests/docker-compose.yml pull --quiet + - name: Start containers + run: docker compose -f tests/docker-compose.yml up -d + - name: Prepare environment + run: docker compose -f tests/docker-compose.yml exec civicrm sites/default/files/civicrm/ext/de.systopia.twingle/tests/docker-prepare.sh + - name: Run PHPUnit + run: docker compose -f tests/docker-compose.yml exec civicrm sites/default/files/civicrm/ext/de.systopia.twingle/tests/docker-phpunit.sh + - name: Remove containers + run: docker compose -f tests/docker-compose.yml down -v diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62dffec --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +/.phpcs.cache +/.phpunit.result.cache +/.phpstan/ +/ci/composer.lock +/ci/vendor/ +/composer.lock +/phpstan.neon +/tools/*/vendor/ +/tools/*/composer.lock +/vendor/ diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 0000000..0bfc584 --- /dev/null +++ b/ci/README.md @@ -0,0 +1,2 @@ +The dependencies specified in composer.json of this directory are required to +run phpstan in CI. diff --git a/ci/composer.json b/ci/composer.json new file mode 100644 index 0000000..ab469d6 --- /dev/null +++ b/ci/composer.json @@ -0,0 +1,33 @@ +{ + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "allow-plugins": { + "civicrm/composer-compile-plugin": false, + "civicrm/composer-downloads-plugin": true, + "cweagans/composer-patches": true + } + }, + "require": { + "civicrm/civicrm-core": "^5" + }, + "scripts": { + "post-install-or-update": [ + "# The following statements are only necessary when the extension is inside a CiviCRM installation, actually not required in CI.", + "# Avoid redeclaration of function \\GuzzleHttp\\http_build_query()", + "if [ -e vendor/civicrm/civicrm-core/guzzle_php81_shim.php ]; then echo '' >vendor/civicrm/civicrm-core/guzzle_php81_shim.php; fi", + "# Avoid redeclaration of function \\GuzzleHttp\\Promise\\queue()", + "if [ -e vendor/guzzlehttp/promises/src/functions.php ]; then echo '' >vendor/guzzlehttp/promises/src/functions.php; fi", + "# Avoid CiviCRM load extensions in vendor", + "if [ -e vendor/civicrm ]; then find vendor/civicrm -name 'info.xml' -delete; fi", + "# Avoid Class 'CRM_AfformAdmin_ExtensionUtil' not found", + "find vendor -name '*.mgd.php' -delete" + ], + "post-install-cmd": [ + "@post-install-or-update" + ], + "post-update-cmd": [ + "@post-install-or-update" + ] + } +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..5489fbd --- /dev/null +++ b/composer.json @@ -0,0 +1,45 @@ +{ + "name": "systopia/de.systopia.twingle", + "type": "civicrm-ext", + "license": "AGPL-3.0-or-later", + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true + }, + "require": { + }, + "scripts": { + "composer-phpcs": [ + "@composer --working-dir=tools/phpcs" + ], + "composer-phpstan": [ + "@composer --working-dir=tools/phpstan" + ], + "composer-phpunit": [ + "@composer --working-dir=tools/phpunit" + ], + "composer-tools": [ + "@composer-phpcs", + "@composer-phpstan", + "@composer-phpunit" + ], + "phpcs": [ + "@php tools/phpcs/vendor/bin/phpcs" + ], + "phpcbf": [ + "@php tools/phpcs/vendor/bin/phpcbf" + ], + "phpstan": [ + "@php tools/phpstan/vendor/bin/phpstan" + ], + "phpunit": [ + "@php tools/phpunit/vendor/bin/simple-phpunit --coverage-text" + ], + "test": [ + "@phpcs", + "@phpstan", + "@phpunit" + ] + } +} diff --git a/info.xml b/info.xml index 05ca281..32c0ab7 100644 --- a/info.xml +++ b/info.xml @@ -18,7 +18,7 @@ 1.5-dev dev - 5.19 + 5.56 diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..ce14b44 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,77 @@ + + + CiviCRM coding standard with some additional changes + + api + Civi + CRM + tests + + /CRM/[^/]+/DAO/.*\.php$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpstan.ci.neon b/phpstan.ci.neon new file mode 100644 index 0000000..883179f --- /dev/null +++ b/phpstan.ci.neon @@ -0,0 +1,13 @@ +includes: + - phpstan.neon.dist + +parameters: + scanDirectories: + - ci/vendor/civicrm/civicrm-core/CRM/ + bootstrapFiles: + - ci/vendor/autoload.php + # Because we test with different versions in CI we have unmatched errors + reportUnmatchedIgnoredErrors: false + ignoreErrors: + # Errors we get when using "prefer-lowest" + - '#::getSubscribedEvents\(\) return type has no value type specified in iterable type array.$#' diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..0691f8e --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,42 @@ +parameters: + paths: + - api + - Civi + - CRM + - tests + excludePaths: + analyse: + - CRM/*/DAO/* + - tests/phpunit/bootstrap.php + scanFiles: + - twingle.civix.php + - tools/phpunit/vendor/bin/.phpunit/phpunit/src/Framework/TestCase.php + scanDirectories: + - tools/phpunit/vendor/bin/.phpunit/phpunit/src/Framework + bootstrapFiles: + - tools/phpunit/vendor/bin/.phpunit/phpunit/vendor/autoload.php + - vendor/autoload.php + - phpstanBootstrap.php + level: 9 + universalObjectCratesClasses: + - Civi\Core\Event\GenericHookEvent + checkTooWideReturnTypesInProtectedAndPublicMethods: true + checkUninitializedProperties: true + checkMissingCallableSignature: true + treatPhpDocTypesAsCertain: false + exceptions: + check: + missingCheckedExceptionInThrows: true + tooWideThrowType: true + checkedExceptionClasses: + - \Webmozart\Assert\InvalidArgumentException + implicitThrows: false + ignoreErrors: + # Note paths are prefixed with "*/" to work with inspections in PHPStorm because of: + # https://youtrack.jetbrains.com/issue/WI-63891/PHPStan-ignoreErrors-configuration-isnt-working-with-inspections + + # Example + #- # Accessing results of API requests + #message: "#^Offset '[^']+' does not exist on array[^\\|]+\\|null.$#" + #path: */tests/phpunit/**/*Test.php + tmpDir: .phpstan diff --git a/phpstan.neon.template b/phpstan.neon.template new file mode 100644 index 0000000..9f2f699 --- /dev/null +++ b/phpstan.neon.template @@ -0,0 +1,13 @@ +# Copy this file to phpstan.neon and replace {VENDOR_DIR} with the appropriate +# path. + +includes: + - phpstan.neon.dist + +parameters: + scanDirectories: + - {VENDOR_DIR}/civicrm/civicrm-core/Civi/ + - {VENDOR_DIR}/civicrm/civicrm-core/CRM/ + - {VENDOR_DIR}/civicrm/civicrm-core/api/ + bootstrapFiles: + - {VENDOR_DIR}/autoload.php diff --git a/phpstanBootstrap.php b/phpstanBootstrap.php new file mode 100644 index 0000000..08b3403 --- /dev/null +++ b/phpstanBootstrap.php @@ -0,0 +1,43 @@ +. + */ + +declare(strict_types = 1); + +// phpcs:disable Drupal.Commenting.DocComment.ContentAfterOpen +/** @var \PHPStan\DependencyInjection\Container $container */ +/** @phpstan-var array $bootstrapFiles */ +$bootstrapFiles = $container->getParameter('bootstrapFiles'); +foreach ($bootstrapFiles as $bootstrapFile) { + if (str_ends_with($bootstrapFile, 'vendor/autoload.php')) { + $vendorDir = dirname($bootstrapFile); + $civiCrmVendorDir = $vendorDir . '/civicrm'; + $civiCrmCoreDir = $civiCrmVendorDir . '/civicrm-core'; + if (file_exists($civiCrmCoreDir)) { + set_include_path(get_include_path() + . PATH_SEPARATOR . $civiCrmCoreDir + . PATH_SEPARATOR . $civiCrmVendorDir . '/civicrm-packages' + ); + // $bootstrapFile might not be included, yet. It is required for the + // following require_once, though. + require_once $bootstrapFile; + // Prevent error "Class 'CRM_Core_Exception' not found in file". + require_once $civiCrmCoreDir . '/CRM/Core/Exception.php'; + + break; + } + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..2df3e9e --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,35 @@ + + + + + + + + + + + ./tests/phpunit + + + + + api + CRM + Civi + + CRM/*/DAO + + + + + + + + + diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml new file mode 100644 index 0000000..840130d --- /dev/null +++ b/tests/docker-compose.yml @@ -0,0 +1,33 @@ +version: "3" +services: + civicrm: + image: michaelmcandrew/civicrm:${CIVICRM_IMAGE_TAG:-5-drupal-php8.1} + environment: + - PROJECT_NAME=test + - BASE_URL=http://localhost + - CIVICRM_DB_NAME=test + - CIVICRM_DB_USER=root + - CIVICRM_DB_PASS=secret + - CIVICRM_DB_HOST=mysql + - CIVICRM_DB_PORT=3306 + - DRUPAL_DB_NAME=test + - DRUPAL_DB_USER=root + - DRUPAL_DB_PASS=secret + - DRUPAL_DB_HOST=mysql + - DRUPAL_DB_PORT=3306 + - PHP_DATE_TIMEZONE=UTC + - DEBUG=ON + - SMTP_HOST=localhost + - SMTP_MAILDOMAIN=example.org + volumes: + - ../:/var/www/html/sites/default/files/civicrm/ext/de.systopia.twingle:${BIND_VOLUME_PERMISSIONS:-ro} + - /var/www/html/sites/default/files/civicrm/ext/de.systopia.twingle/vendor + - /var/www/html/sites/default/files/civicrm/ext/de.systopia.twingle/tools/phpunit/vendor + # Don't start Apache HTTP Server, but keep container running + command: ["tail", "-f", "/dev/null"] + stop_signal: SIGKILL + mysql: + image: mariadb + environment: + MARIADB_ROOT_PASSWORD: secret + MARIADB_DATABASE: test diff --git a/tests/docker-phpunit.sh b/tests/docker-phpunit.sh new file mode 100755 index 0000000..2b0fc69 --- /dev/null +++ b/tests/docker-phpunit.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -eu -o pipefail + +SCRIPT_DIR=$(realpath "$(dirname "$0")") +EXT_DIR=$(dirname "$SCRIPT_DIR") + +cd "$EXT_DIR" +if [ ! -e tools/phpunit/vendor/bin ]; then + "$SCRIPT_DIR/docker-prepare.sh" +fi + +export XDEBUG_MODE=coverage +# TODO: Remove when not needed, anymore. +# In Docker container with CiviCRM 5.5? all deprecations are reported as direct +# deprecations so "disabling" check of deprecation count is necessary for the +# tests to pass (if baselineFile does not contain all deprecations). +export SYMFONY_DEPRECATIONS_HELPER="max[total]=99999&baselineFile=./tests/ignored-deprecations.json" + +composer phpunit -- --cache-result-file=/tmp/.phpunit.result.cache "$@" diff --git a/tests/docker-prepare.sh b/tests/docker-prepare.sh new file mode 100755 index 0000000..a293c74 --- /dev/null +++ b/tests/docker-prepare.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -eu -o pipefail + +EXT_DIR=$(dirname "$(dirname "$(realpath "$0")")") +EXT_NAME=$(basename "$EXT_DIR") + +i=0 +while ! mysql -h "$CIVICRM_DB_HOST" -P "$CIVICRM_DB_PORT" -u "$CIVICRM_DB_USER" --password="$CIVICRM_DB_PASS" -e 'SELECT 1;' >/dev/null 2>&1; do + i=$((i+1)) + if [ $i -gt 10 ]; then + echo "Failed to connect to database" >&2 + exit 1 + fi + + echo -n . + sleep 1 +done + +echo + +export XDEBUG_MODE=off +if mysql -h "$CIVICRM_DB_HOST" -P "$CIVICRM_DB_PORT" -u "$CIVICRM_DB_USER" --password="$CIVICRM_DB_PASS" "$CIVICRM_DB_NAME" -e 'SELECT 1 FROM civicrm_setting LIMIT 1;' >/dev/null 2>&1; then + cv flush +else + # For headless tests it is required that CIVICRM_UF is defined using the corresponding env variable. + sed -E "s/define\('CIVICRM_UF', '([^']+)'\);/define('CIVICRM_UF', getenv('CIVICRM_UF') ?: '\1');/g" \ + -i /var/www/html/sites/default/civicrm.settings.php + civicrm-docker-install + + # Avoid this error: + # The autoloader expected class "Civi\ActionSchedule\Mapping" to be defined in + # file "[...]/Civi/ActionSchedule/Mapping.php". The file was found but the + # class was not in it, the class name or namespace probably has a typo. + rm -f /var/www/html/sites/all/modules/civicrm/Civi/ActionSchedule/Mapping.php + + # For headless tests these files need to exist. + touch /var/www/html/sites/all/modules/civicrm/sql/test_data.mysql + touch /var/www/html/sites/all/modules/civicrm/sql/test_data_second_domain.mysql + + cv ext:enable "$EXT_NAME" +fi + +cd "$EXT_DIR" +composer update --no-progress --prefer-dist --optimize-autoloader --no-dev +composer composer-phpunit -- update --no-progress --prefer-dist diff --git a/tests/ignored-deprecations.json b/tests/ignored-deprecations.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/ignored-deprecations.json @@ -0,0 +1 @@ +[] diff --git a/tools/phpcs/composer.json b/tools/phpcs/composer.json new file mode 100644 index 0000000..980e4b9 --- /dev/null +++ b/tools/phpcs/composer.json @@ -0,0 +1,11 @@ +{ + "repositories": [ + { + "type": "git", + "url": "https://github.com/civicrm/coder.git" + } + ], + "require": { + "drupal/coder": "dev-8.x-2.x-civi" + } +} diff --git a/tools/phpstan/composer.json b/tools/phpstan/composer.json new file mode 100644 index 0000000..218fa72 --- /dev/null +++ b/tools/phpstan/composer.json @@ -0,0 +1,18 @@ +{ + "require": { + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.7", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.2", + "phpstan/phpstan-webmozart-assert": "^1.2", + "thecodingmachine/phpstan-strict-rules": "^1.0", + "voku/phpstan-rules": "^3.0" + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + }, + "sort-packages": true + } +} diff --git a/tools/phpunit/composer.json b/tools/phpunit/composer.json new file mode 100644 index 0000000..ab13d43 --- /dev/null +++ b/tools/phpunit/composer.json @@ -0,0 +1,13 @@ +{ + "require": { + "symfony/phpunit-bridge": "^6.1" + }, + "scripts": { + "post-install-cmd": [ + "@php vendor/bin/simple-phpunit install" + ], + "post-update-cmd": [ + "@php vendor/bin/simple-phpunit install" + ] + } +} From fad228315d3952b66105ef4af5a57ecb8dcb287f Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 14:52:29 +0100 Subject: [PATCH 115/221] Remove invalid @throws --- CRM/Twingle/Profile.php | 1 - 1 file changed, 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 80238be..613e1e9 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -350,7 +350,6 @@ class CRM_Twingle_Profile { * @param $project_id * * @return CRM_Twingle_Profile - * @throws \CRM\Twingle\Exceptions\ProfileException * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileForProject($project_id) { From 69843bc98185612f431622a6b6dd6323f47d6618 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 14:58:51 +0100 Subject: [PATCH 116/221] PHP Code Beautifier fixes --- CRM/Twingle/Config.php | 7 +- CRM/Twingle/Form/Profile.php | 285 +++++++++++++++--------- CRM/Twingle/Form/Settings.php | 78 +++---- CRM/Twingle/Page/Profiles.php | 2 +- CRM/Twingle/Submission.php | 74 +++--- CRM/Twingle/Tools.php | 96 +++++--- CRM/Twingle/Upgrader.php | 15 +- CRM/Twingle/Upgrader/Base.php | 48 ++-- api/v3/TwingleDonation/Cancel.php | 39 ++-- api/v3/TwingleDonation/Endrecurring.php | 37 +-- 10 files changed, 389 insertions(+), 292 deletions(-) diff --git a/CRM/Twingle/Config.php b/CRM/Twingle/Config.php index 81f4647..557a572 100644 --- a/CRM/Twingle/Config.php +++ b/CRM/Twingle/Config.php @@ -29,9 +29,10 @@ class CRM_Twingle_Config { */ public static function getRecurringProtectionOptions() { return [ - self::RCUR_PROTECTION_OFF => E::ts("No"), - self::RCUR_PROTECTION_EXCEPTION => E::ts("Raise Exception"), - self::RCUR_PROTECTION_ACTIVITY => E::ts("Create Activity"), + self::RCUR_PROTECTION_OFF => E::ts('No'), + self::RCUR_PROTECTION_EXCEPTION => E::ts('Raise Exception'), + self::RCUR_PROTECTION_ACTIVITY => E::ts('Create Activity'), ]; } + } diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index ba542eb..e1fc67a 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -23,7 +23,7 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** - * @var CRM_Twingle_Profile $profile + * @var CRM_Twingle_Profile * * The profile object the form is acting on. */ @@ -151,25 +151,27 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { switch ($this->_op) { case 'delete': if ($profile_name) { - CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', array(1 => $profile_name))); - $this->addButtons(array( - array( + CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', [1 => $profile_name])); + $this->addButtons([ + [ 'type' => 'submit', 'name' => ($profile_name == 'default' ? E::ts('Reset') : E::ts('Delete')), 'isDefault' => TRUE, - ), - )); + ], + ]); } parent::buildQuickForm(); return; + case 'edit': // When editing without a valid profile name, edit the default profile. if (!$profile_name) { $profile_name = 'default'; $this->profile = CRM_Twingle_Profile::getProfile($profile_name); } - CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', array(1 => $this->profile->getName()))); + CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', [1 => $this->profile->getName()])); break; + case 'copy': // Retrieve the source profile name. $profile_name = CRM_Utils_Request::retrieve('source_name', 'String', $this); @@ -184,6 +186,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->profile->setName($profile_name); CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); break; + case 'create': // Load factory default profile values. $this->profile = CRM_Twingle_Profile::createDefaultProfile($profile_name); @@ -201,16 +204,20 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ($is_default ? 'static' : 'text'), 'name', E::ts('Profile name'), - array(), + [], !$is_default ); $this->add( - 'text', // field type - 'selector', // field name - E::ts('Project IDs'), // field label + // field type + 'text', + // field name + 'selector', + // field label + E::ts('Project IDs'), ['class' => 'huge'], - TRUE // is required + // is required + TRUE ); $this->add( @@ -238,18 +245,28 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ); $this->add( - 'select', // field type - 'financial_type_id', // field name - E::ts('Financial type'), // field label - static::getFinancialTypes(), // list of options - TRUE // is required + // field type + 'select', + // field name + 'financial_type_id', + // field label + E::ts('Financial type'), + // list of options + static::getFinancialTypes(), + // is required + TRUE ); $this->add( - 'select', // field type - 'financial_type_id_recur', // field name - E::ts('Financial type (recurring)'), // field label - static::getFinancialTypes(), // list of options - TRUE // is required + // field type + 'select', + // field name + 'financial_type_id_recur', + // field label + E::ts('Financial type (recurring)'), + // list of options + static::getFinancialTypes(), + // is required + TRUE ); $this->add( @@ -297,11 +314,16 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->assign('payment_instruments', $payment_instruments); foreach ($payment_instruments as $pi_name => $pi_label) { $this->add( - 'select', // field type - $pi_name, // field name - E::ts('Record %1 as', [1 => $pi_label]), // field label - static::getPaymentInstruments(), // list of options - TRUE // is required + // field type + 'select', + // field name + $pi_name, + // field label + E::ts('Record %1 as', [1 => $pi_label]), + // list of options + static::getPaymentInstruments(), + // is required + TRUE ); $this->add( @@ -324,46 +346,70 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { } $this->add( - 'checkbox', // field type - 'newsletter_double_opt_in', // field name - E::ts('Use Double-Opt-In for newsletter'), // field label - FALSE, // is not required + // field type + 'checkbox', + // field name + 'newsletter_double_opt_in', + // field label + E::ts('Use Double-Opt-In for newsletter'), + // is not required + FALSE, [] ); $this->add( - 'select', // field type - 'newsletter_groups', // field name - E::ts('Sign up for newsletter groups'), // field label - static::getNewsletterGroups(), // list of options - FALSE, // is not required + // field type + 'select', + // field name + 'newsletter_groups', + // field label + E::ts('Sign up for newsletter groups'), + // list of options + static::getNewsletterGroups(), + // is not required + FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - 'select', // field type - 'postinfo_groups', // field name - E::ts('Sign up for postal mail groups'), // field label - static::getPostinfoGroups(), // list of options - FALSE, // is not required + // field type + 'select', + // field name + 'postinfo_groups', + // field label + E::ts('Sign up for postal mail groups'), + // list of options + static::getPostinfoGroups(), + // is not required + FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - 'select', // field type - 'donation_receipt_groups', // field name - E::ts('Sign up for Donation receipt groups'), // field label - static::getDonationReceiptGroups(), // list of options - FALSE, // is not required + // field type + 'select', + // field name + 'donation_receipt_groups', + // field label + E::ts('Sign up for Donation receipt groups'), + // list of options + static::getDonationReceiptGroups(), + // is not required + FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - 'select', // field type - 'campaign', // field name - E::ts('Default Campaign'), // field label - ['' => E::ts('- none -')] + static::getCampaigns(), // list of options - FALSE, // is not required + // field type + 'select', + // field name + 'campaign', + // field label + E::ts('Default Campaign'), + // list of options + ['' => E::ts('- none -')] + static::getCampaigns(), + // is not required + FALSE, ['class' => 'crm-select2 huge'] ); @@ -372,30 +418,41 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'campaign_targets', E::ts('Set Campaign for'), [ - 'contribution' => E::ts("Contribution"), - 'recurring' => E::ts("Recurring Contribution"), - 'membership' => E::ts("Membership"), - 'mandate' => E::ts("SEPA Mandate"), - 'contact' => E::ts("Contacts (XCM)"), + 'contribution' => E::ts('Contribution'), + 'recurring' => E::ts('Recurring Contribution'), + 'membership' => E::ts('Membership'), + 'mandate' => E::ts('SEPA Mandate'), + 'contact' => E::ts('Contacts (XCM)'), ], - FALSE, // is not required + // is not required + FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - 'select', // field type - 'membership_type_id', // field name - E::ts('Create membership of type'), // field label - ['' => E::ts('- none -')] + static::getMembershipTypes(), // list of options - FALSE, // is not required + // field type + 'select', + // field name + 'membership_type_id', + // field label + E::ts('Create membership of type'), + // list of options + ['' => E::ts('- none -')] + static::getMembershipTypes(), + // is not required + FALSE, ['class' => 'crm-select2 huge'] ); $this->add( - 'select', // field type - 'membership_type_id_recur', // field name - E::ts('Create membership of type (recurring)'), // field label - ['' => E::ts('- none -')] + static::getMembershipTypes(), // list of options - FALSE, // is not required + // field type + 'select', + // field name + 'membership_type_id_recur', + // field label + E::ts('Create membership of type (recurring)'), + // list of options + ['' => E::ts('- none -')] + static::getMembershipTypes(), + // is not required + FALSE, ['class' => 'crm-select2 huge'] ); $this->add( @@ -407,9 +464,12 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->addRule('membership_postprocess_call', E::ts("The API call must have the form 'Entity.Action'."), 'regex', '/^[A-Za-z_]+[.][A-Za-z_]+$/'); $this->add( - 'text', // field type - 'contribution_source', // field name - E::ts('Contribution source'), // field label + // field type + 'text', + // field name + 'contribution_source', + // field label + E::ts('Contribution source'), [] ); @@ -418,19 +478,23 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'required_address_components', E::ts('Required address components'), [ - 'street_address' => E::ts("Street"), - 'postal_code' => E::ts("Postal Code"), - 'city' => E::ts("City"), - 'country' => E::ts("Country"), + 'street_address' => E::ts('Street'), + 'postal_code' => E::ts('Postal Code'), + 'city' => E::ts('City'), + 'country' => E::ts('Country'), ], - FALSE, // is not required + // is not required + FALSE, ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] ); $this->add( - 'textarea', // field type - 'custom_field_mapping', // field name - E::ts('Custom field mapping'), // field label + // field type + 'textarea', + // field name + 'custom_field_mapping', + // field label + E::ts('Custom field mapping'), [] ); @@ -469,7 +533,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { } // Restrict profile names to alphanumeric characters and the underscore. - if (isset($values['name']) && preg_match("/[^A-Za-z0-9\_]/", $values['name'])) { + if (isset($values['name']) && preg_match('/[^A-Za-z0-9\_]/', $values['name'])) { $this->_errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); } @@ -483,7 +547,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { ); } foreach ($custom_field_mapping as $custom_field_map) { - $custom_field_map = explode("=", $custom_field_map); + $custom_field_map = explode('=', $custom_field_map); if (count($custom_field_map) !== 2) { throw new Exception( E::ts('Could not parse custom field mapping.') @@ -494,40 +558,41 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Check for custom field existence try { - $custom_field = civicrm_api3('CustomField', 'getsingle', array( + $custom_field = civicrm_api3('CustomField', 'getsingle', [ 'id' => $custom_field_id, - )); + ]); } catch (CiviCRM_API3_Exception $exception) { throw new Exception( E::ts( 'Custom field custom_%1 does not exist.', - array(1 => $custom_field_id) + [1 => $custom_field_id] ) ); } // Only allow custom fields on relevant entities. try { - $custom_group = civicrm_api3('CustomGroup', 'getsingle', array( + $custom_group = civicrm_api3('CustomGroup', 'getsingle', [ 'id' => $custom_field['custom_group_id'], - 'extends' => array( - 'IN' => array( + 'extends' => [ + 'IN' => [ 'Contact', 'Individual', 'Organization', 'Contribution', 'ContributionRecur', - ), - ), - )); - } catch (CiviCRM_API3_Exception $exception) { + ], + ], + ]); + } + catch (CiviCRM_API3_Exception $exception) { throw new Exception( E::ts( 'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.', - array(1 => $custom_field['id']) + [1 => $custom_field['id']] ) - ); + ); } } } @@ -563,7 +628,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public function postProcess() { $values = $this->exportValues(); - if (in_array($this->_op, array('create', 'edit', 'copy'))) { + if (in_array($this->_op, ['create', 'edit', 'copy'])) { if (empty($values['name'])) { $values['name'] = 'default'; } @@ -614,9 +679,9 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { public static function getXCMProfiles() { if (!isset(static::$_xcm_profiles)) { if (method_exists('CRM_Xcm_Configuration', 'getProfileList')) { - static::$_xcm_profiles = array( - '' => E::ts("<select profile>"), - ); + static::$_xcm_profiles = [ + '' => E::ts('<select profile>'), + ]; $profiles = CRM_Xcm_Configuration::getProfileList(); foreach ($profiles as $profile_key => $profile_name) { static::$_xcm_profiles[$profile_key] = $profile_name; @@ -640,7 +705,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $query = civicrm_api3('FinancialType', 'get', [ 'option.limit' => 0, 'is_active' => 1, - 'return' => 'id,name' + 'return' => 'id,name', ]); foreach ($query['values'] as $type) { static::$_financialTypes[$type['id']] = $type['name']; @@ -663,7 +728,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $query = civicrm_api3('MembershipType', 'get', [ 'option.limit' => 0, 'is_active' => 1, - 'return' => 'id,name' + 'return' => 'id,name', ]); foreach ($query['values'] as $type) { static::$_membershipTypes[$type['id']] = $type['name']; @@ -711,13 +776,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { if (!isset(static::$_prefixOptions)) { static::$_prefixOptions = ['' => E::ts('none')]; $query = civicrm_api3('OptionValue', 'get', [ - 'option.limit' => 0, - 'option_group_id' => 'individual_prefix', - 'is_active' => 1, - 'return' => [ - 'value', - 'label', - ], + 'option.limit' => 0, + 'option_group_id' => 'individual_prefix', + 'is_active' => 1, + 'return' => [ + 'value', + 'label', + ], ]); foreach ($query['values'] as $prefix) { static::$_prefixOptions[$prefix['value']] = $prefix['label']; @@ -763,7 +828,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'option.limit' => 0, 'option_group_id' => 'payment_instrument', 'is_active' => 1, - 'return' => 'value,label' + 'return' => 'value,label', ]); foreach ($query['values'] as $payment_instrument) { // Do not include CiviSEPA payment instruments, but add a SEPA option if @@ -802,7 +867,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'return' => [ 'value', 'label', - ] + ], ] ); @@ -837,7 +902,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'is_active' => 1, 'group_type' => ['LIKE' => '%' . CRM_Utils_Array::implodePadded($group_type['value']) . '%'], 'option.limit' => 0, - 'return' => 'id,name' + 'return' => 'id,name', ]); foreach ($query['values'] as $group) { static::$_newsletterGroups[$group['id']] = $group['name']; @@ -863,7 +928,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $query = civicrm_api3('Group', 'get', [ 'option.limit' => 0, 'is_active' => 1, - 'return' => 'id,name' + 'return' => 'id,name', ]); foreach ($query['values'] as $group) { static::$_groups[$group['id']] = $group['name']; @@ -911,7 +976,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { 'return' => [ 'id', 'title', - ] + ], ]); foreach ($query['values'] as $campaign) { static::$_campaigns[$campaign['id']] = $campaign['title']; diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index 631fb05..a359588 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -23,69 +23,69 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Form_Settings extends CRM_Core_Form { /** - * @var array list of all settings options + * @var arraylistofallsettingsoptions */ public static $SETTINGS_LIST = [ - 'twingle_prefix', - 'twingle_use_sepa', - 'twingle_dont_use_reference', - 'twingle_protect_recurring', - 'twingle_protect_recurring_activity_type', - 'twingle_protect_recurring_activity_subject', - 'twingle_protect_recurring_activity_status', - 'twingle_protect_recurring_activity_assignee', + 'twingle_prefix', + 'twingle_use_sepa', + 'twingle_dont_use_reference', + 'twingle_protect_recurring', + 'twingle_protect_recurring_activity_type', + 'twingle_protect_recurring_activity_subject', + 'twingle_protect_recurring_activity_status', + 'twingle_protect_recurring_activity_assignee', ]; /** * @inheritdoc */ - function buildQuickForm() { + public function buildQuickForm() { // Set redirect destination. $this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle', 'reset=1'); $this->add( 'text', 'twingle_prefix', - E::ts("Twingle ID Prefix") + E::ts('Twingle ID Prefix') ); $this->add( 'checkbox', 'twingle_use_sepa', - E::ts("Use CiviSEPA") + E::ts('Use CiviSEPA') ); $this->add( 'checkbox', 'twingle_dont_use_reference', - E::ts("Use CiviSEPA generated reference") + E::ts('Use CiviSEPA generated reference') ); $this->add( 'select', 'twingle_protect_recurring', - E::ts("Protect Recurring Contributions"), + E::ts('Protect Recurring Contributions'), CRM_Twingle_Config::getRecurringProtectionOptions() ); $this->add( 'select', 'twingle_protect_recurring_activity_type', - E::ts("Activity Type"), + E::ts('Activity Type'), $this->getOptionValueList('activity_type', [0]) ); $this->add( 'text', 'twingle_protect_recurring_activity_subject', - E::ts("Subject"), + E::ts('Subject'), ['class' => 'huge'] ); $this->add( 'select', 'twingle_protect_recurring_activity_status', - E::ts("Status"), + E::ts('Status'), $this->getOptionValueList('activity_status') ); @@ -102,18 +102,18 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { ] ); - $this->addButtons(array( - array ( - 'type' => 'submit', - 'name' => E::ts('Save'), - 'isDefault' => TRUE, - ) - )); + $this->addButtons([ + [ + 'type' => 'submit', + 'name' => E::ts('Save'), + 'isDefault' => TRUE, + ], + ]); // set defaults foreach (self::$SETTINGS_LIST as $setting) { $this->setDefaults([ - $setting => Civi::settings()->get($setting) + $setting => Civi::settings()->get($setting), ]); } @@ -132,12 +132,13 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { $protection_mode = CRM_Utils_Array::value('twingle_protect_recurring', $this->_submitValues); if ($protection_mode == CRM_Twingle_Config::RCUR_PROTECTION_ACTIVITY) { foreach (['twingle_protect_recurring_activity_type', - 'twingle_protect_recurring_activity_subject', - 'twingle_protect_recurring_activity_status', - 'twingle_protect_recurring_activity_assignee',] as $activity_field) { + 'twingle_protect_recurring_activity_subject', + 'twingle_protect_recurring_activity_status', + 'twingle_protect_recurring_activity_assignee', + ] as $activity_field) { $current_value = CRM_Utils_Array::value($activity_field, $this->_submitValues); if (empty($current_value)) { - $this->_errors[$activity_field] = E::ts("This is required for activity creation"); + $this->_errors[$activity_field] = E::ts('This is required for activity creation'); } } } @@ -145,11 +146,10 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { return (0 == count($this->_errors)); } - /** * @inheritdoc */ - function postProcess() { + public function postProcess() { $values = $this->exportValues(); // store settings @@ -160,25 +160,25 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { parent::postProcess(); } - /** * Get a list of option group items * @param $group_id string group ID or name * @return array list of ID(value) => label * @throws CiviCRM_API3_Exception */ - protected function getOptionValueList($group_id, $reserved = [0,1]) { - $list = ['' => E::ts("-select-")]; + protected function getOptionValueList($group_id, $reserved = [0, 1]) { + $list = ['' => E::ts('-select-')]; $query = civicrm_api3('OptionValue', 'get', [ - 'option_group_id' => $group_id, - 'option.limit' => 0, - 'is_active' => 1, - 'is_reserved' => ['IN' => $reserved], - 'return' => 'value,label', + 'option_group_id' => $group_id, + 'option.limit' => 0, + 'is_active' => 1, + 'is_reserved' => ['IN' => $reserved], + 'return' => 'value,label', ]); foreach ($query['values'] as $value) { $list[$value['value']] = $value['label']; } return $list; } + } diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index eb5bf0c..f042e81 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -18,7 +18,7 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Page_Profiles extends CRM_Core_Page { public function run() { - CRM_Utils_System::setTitle(E::ts("Twingle API Profiles")); + CRM_Utils_System::setTitle(E::ts('Twingle API Profiles')); $profiles = []; foreach (CRM_Twingle_Profile::getProfiles() as $profile_name => $profile) { $profiles[$profile_name]['name'] = $profile_name; diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 2c2a282..342e2be 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -54,13 +54,13 @@ class CRM_Twingle_Submission { } // Validate donation rhythm. - if (!in_array($params['donation_rhythm'], array( + if (!in_array($params['donation_rhythm'], [ 'one_time', 'halfyearly', 'quarterly', 'yearly', 'monthly', - ))) { + ])) { throw new CiviCRM_API3_Exception( E::ts('Invalid donation rhythm.'), 'invalid_format' @@ -108,7 +108,7 @@ class CRM_Twingle_Submission { // Validate custom fields parameter, if given. if (!empty($params['custom_fields'])) { if (is_string($params['custom_fields'])) { - $params['custom_fields'] = json_decode($params['custom_fields'], TRUE); + $params['custom_fields'] = json_decode($params['custom_fields'], TRUE); } if (!is_array($params['custom_fields'])) { throw new CiviCRM_API3_Exception( @@ -137,7 +137,8 @@ class CRM_Twingle_Submission { 'getsingle', ['id' => $params['campaign_id']] ); - } catch (CiviCRM_API3_Exception $e) { + } + catch (CiviCRM_API3_Exception $e) { unset($params['campaign_id']); } } @@ -186,14 +187,14 @@ class CRM_Twingle_Submission { } else { // Look up the country depending on the given ISO code. - $country = civicrm_api3('Country', 'get', array('iso_code' => $contact_data['country'])); + $country = civicrm_api3('Country', 'get', ['iso_code' => $contact_data['country']]); if (!empty($country['id'])) { $contact_data['country_id'] = $country['id']; unset($contact_data['country']); } else { throw new \CiviCRM_API3_Exception( - E::ts('Unknown country %1.', array(1 => $contact_data['country'])), + E::ts('Unknown country %1.', [1 => $contact_data['country']]), 'invalid_format' ); } @@ -241,18 +242,20 @@ class CRM_Twingle_Submission { } // Check whether organisation has a WORK address. - $existing_org_addresses = civicrm_api3('Address', 'get', array( + $existing_org_addresses = civicrm_api3('Address', 'get', [ 'contact_id' => $organisation_id, - 'location_type_id' => $location_type_id)); + 'location_type_id' => $location_type_id, + ]); if ($existing_org_addresses['count'] <= 0) { // Organisation does not have a WORK address. return FALSE; } // Check whether contact already has a WORK address. - $existing_contact_addresses = civicrm_api3('Address', 'get', array( + $existing_contact_addresses = civicrm_api3('Address', 'get', [ 'contact_id' => $contact_id, - 'location_type_id' => $location_type_id)); + 'location_type_id' => $location_type_id, + ]); if ($existing_contact_addresses['count'] > 0) { // Contact already has a WORK address. return FALSE; @@ -284,21 +287,21 @@ class CRM_Twingle_Submission { } // see if there is already one - $existing_relationship = civicrm_api3('Relationship', 'get', array( + $existing_relationship = civicrm_api3('Relationship', 'get', [ 'relationship_type_id' => self::EMPLOYER_RELATIONSHIP_TYPE_ID, 'contact_id_a' => $contact_id, 'contact_id_b' => $organisation_id, 'is_active' => 1, - )); + ]); if ($existing_relationship['count'] == 0) { // There is currently no (active) relationship between these contacts. - $new_relationship_data = array( + $new_relationship_data = [ 'relationship_type_id' => self::EMPLOYER_RELATIONSHIP_TYPE_ID, 'contact_id_a' => $contact_id, 'contact_id_b' => $organisation_id, 'is_active' => 1, - ); + ]; civicrm_api3('Relationship', 'create', $new_relationship_data); } @@ -312,12 +315,11 @@ class CRM_Twingle_Submission { * @throws \CiviCRM_API3_Exception */ public static function civiSepaEnabled() { - $sepa_extension = civicrm_api3('Extension', 'get', array( + $sepa_extension = civicrm_api3('Extension', 'get', [ 'full_name' => 'org.project60.sepa', 'is_active' => 1, - )); - return - Civi::settings()->get('twingle_use_sepa') + ]); + return Civi::settings()->get('twingle_use_sepa') && $sepa_extension['count']; } @@ -334,25 +336,25 @@ class CRM_Twingle_Submission { * to contribution parameter arrays. */ public static function getFrequencyMapping($donation_rhythm) { - $mapping = array( - 'halfyearly' => array( + $mapping = [ + 'halfyearly' => [ 'frequency_unit' => 'month', 'frequency_interval' => 6, - ), - 'quarterly' => array( + ], + 'quarterly' => [ 'frequency_unit' => 'month', 'frequency_interval' => 3, - ), - 'yearly' => array( + ], + 'yearly' => [ 'frequency_unit' => 'month', 'frequency_interval' => 12, - ), - 'monthly' => array( + ], + 'monthly' => [ 'frequency_unit' => 'month', 'frequency_interval' => 1, - ), - 'one_time' => array(), - ); + ], + 'one_time' => [], + ]; return $mapping[$donation_rhythm]; } @@ -371,15 +373,15 @@ class CRM_Twingle_Submission { * The next possible day of this or the next month to start collecting. */ public static function getSEPACycleDay($start_date, $creditor_id) { - $buffer_days = (int) CRM_Sepa_Logic_Settings::getSetting("pp_buffer_days"); - $frst_notice_days = (int) CRM_Sepa_Logic_Settings::getSetting("batching.FRST.notice", $creditor_id); + $buffer_days = (int) CRM_Sepa_Logic_Settings::getSetting('pp_buffer_days'); + $frst_notice_days = (int) CRM_Sepa_Logic_Settings::getSetting('batching.FRST.notice', $creditor_id); $earliest_rcur_date = strtotime("$start_date + $frst_notice_days days + $buffer_days days"); // Find the next cycle day - $cycle_days = CRM_Sepa_Logic_Settings::getListSetting("cycledays", range(1, 28), $creditor_id); + $cycle_days = CRM_Sepa_Logic_Settings::getListSetting('cycledays', range(1, 28), $creditor_id); $earliest_cycle_day = $earliest_rcur_date; while (!in_array(date('j', $earliest_cycle_day), $cycle_days)) { - $earliest_cycle_day = strtotime("+ 1 day", $earliest_cycle_day); + $earliest_cycle_day = strtotime('+ 1 day', $earliest_cycle_day); } return date('j', $earliest_cycle_day); @@ -406,7 +408,7 @@ class CRM_Twingle_Submission { // then: check if campaign should be set it this context $enabled_contexts = $profile->getAttribute('campaign_targets'); - if ($enabled_contexts === null || !is_array($enabled_contexts)) { + if ($enabled_contexts === NULL || !is_array($enabled_contexts)) { // backward compatibility: $enabled_contexts = ['contribution', 'contact']; } @@ -414,10 +416,12 @@ class CRM_Twingle_Submission { // use the submitted campaign if set if (!empty($submission['campaign_id'])) { $entity_data['campaign_id'] = $submission['campaign_id']; - } // otherwise use the profile's + } + // otherwise use the profile's elseif (!empty($campaign = $profile->getAttribute('campaign'))) { $entity_data['campaign_id'] = $campaign; } } } + } diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php index 86cd828..52e9789 100644 --- a/CRM/Twingle/Tools.php +++ b/CRM/Twingle/Tools.php @@ -33,25 +33,36 @@ class CRM_Twingle_Tools { */ public static function checkRecurringContributionChange($recurring_contribution_id, $change) { // check if a change to the status is planned - if (empty($change['contribution_status_id'])) return; + if (empty($change['contribution_status_id'])) { + return; + } // check if the target status is not closed - if (in_array($change['contribution_status_id'], [2,5])) return; + if (in_array($change['contribution_status_id'], [2, 5])) { + return; + } // check if we're suspended - if (self::$protection_suspended) return; + if (self::$protection_suspended) { + return; + } // check if protection is turned on $protection_on = Civi::settings()->get('twingle_protect_recurring'); - if (empty($protection_on)) return; + if (empty($protection_on)) { + return; + } // load the recurring contribution $recurring_contribution = civicrm_api3('ContributionRecur', 'getsingle', [ - 'return' => 'trxn_id,contribution_status_id,payment_instrument_id,contact_id', - 'id' => $recurring_contribution_id]); + 'return' => 'trxn_id,contribution_status_id,payment_instrument_id,contact_id', + 'id' => $recurring_contribution_id, + ]); // check if this is a SEPA transaction (doesn't concern us) - if (self::isSDD($recurring_contribution['payment_instrument_id'])) return; + if (self::isSDD($recurring_contribution['payment_instrument_id'])) { + return; + } // see if this recurring contribution is from Twingle if (!self::isTwingleRecurringContribution($recurring_contribution_id, $recurring_contribution)) { @@ -59,7 +70,9 @@ class CRM_Twingle_Tools { } // check if it's really a termination (i.e. current status is 2 or 5) - if (!in_array($recurring_contribution['contribution_status_id'], [2,5])) return; + if (!in_array($recurring_contribution['contribution_status_id'], [2, 5])) { + return; + } // this _IS_ on of the cases where we should step in: CRM_Twingle_Tools::processRecurringContributionTermination($recurring_contribution_id, $recurring_contribution); @@ -74,7 +87,9 @@ class CRM_Twingle_Tools { public static function isTwingleRecurringContribution($recurring_contribution_id, $recurring_contribution = NULL) { // this currently only works with prefixes $prefix = Civi::settings()->get('twingle_prefix'); - if (empty($prefix)) return null; + if (empty($prefix)) { + return NULL; + } // load recurring contribution if necessary if (empty($recurring_contribution['trxn_id'])) { @@ -95,7 +110,9 @@ class CRM_Twingle_Tools { */ public static function processRecurringContributionTermination($recurring_contribution_id, $recurring_contribution) { // check if we're suspended - if (self::$protection_suspended) return; + if (self::$protection_suspended) { + return; + } $protection_mode = Civi::settings()->get('twingle_protect_recurring'); switch ($protection_mode) { @@ -104,39 +121,44 @@ class CRM_Twingle_Tools { break; case CRM_Twingle_Config::RCUR_PROTECTION_EXCEPTION: - throw new Exception(E::ts("This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.")); + throw new Exception(E::ts('This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.')); case CRM_Twingle_Config::RCUR_PROTECTION_ACTIVITY: // create contact source activity // first: get the contact ID if (!empty($recurring_contribution['contact_id'])) { $target_id = (int) $recurring_contribution['contact_id']; - } else { + } + else { $target_id = (int) civicrm_api3('ContributionRecur', 'getvalue', [ - 'id' => $recurring_contribution_id, - 'return' => 'contact_id']); + 'id' => $recurring_contribution_id, + 'return' => 'contact_id', + ]); } if (!empty($recurring_contribution['trxn_id'])) { $trxn_id = $recurring_contribution['trxn_id']; - } else { + } + else { $trxn_id = civicrm_api3('ContributionRecur', 'getvalue', [ - 'id' => $recurring_contribution_id, - 'return' => 'trxn_id']); + 'id' => $recurring_contribution_id, + 'return' => 'trxn_id', + ]); } try { civicrm_api3('Activity', 'create', [ - 'activity_type_id' => Civi::settings()->get('twingle_protect_recurring_activity_type'), - 'subject' => Civi::settings()->get('twingle_protect_recurring_activity_subject'), - 'activity_date_time' => date('YmdHis'), - 'target_id' => $target_id, - 'assignee_id' => Civi::settings()->get('twingle_protect_recurring_activity_assignee'), - 'status_id' => Civi::settings()->get('twingle_protect_recurring_activity_status'), - 'details' => E::ts("Recurring contribution [%1] (Transaction ID '%2') was terminated by a user. You need to end the corresponding record in Twingle as well, or it will still be collected.", + 'activity_type_id' => Civi::settings()->get('twingle_protect_recurring_activity_type'), + 'subject' => Civi::settings()->get('twingle_protect_recurring_activity_subject'), + 'activity_date_time' => date('YmdHis'), + 'target_id' => $target_id, + 'assignee_id' => Civi::settings()->get('twingle_protect_recurring_activity_assignee'), + 'status_id' => Civi::settings()->get('twingle_protect_recurring_activity_status'), + 'details' => E::ts("Recurring contribution [%1] (Transaction ID '%2') was terminated by a user. You need to end the corresponding record in Twingle as well, or it will still be collected.", [1 => $recurring_contribution_id, 2 => $trxn_id]), - 'source_contact_id' => CRM_Core_Session::getLoggedInContactID(), + 'source_contact_id' => CRM_Core_Session::getLoggedInContactID(), ]); - } catch (Exception $ex) { + } + catch (Exception $ex) { Civi::log()->warning("TwingleAPI: Couldn't create recurring protection activity: " . $ex->getMessage()); } break; @@ -161,9 +183,9 @@ class CRM_Twingle_Tools { // lookup and add instrument IDs $lookup = civicrm_api3('OptionValue', 'get', [ - 'option_group_id' => 'payment_instrument', - 'name' => ['IN' => $sepa_payment_instruments], - 'return' => 'value' + 'option_group_id' => 'payment_instrument', + 'name' => ['IN' => $sepa_payment_instruments], + 'return' => 'value', ]); foreach ($lookup['values'] as $payment_instrument) { $sepa_payment_instruments[] = $payment_instrument['value']; @@ -184,9 +206,9 @@ class CRM_Twingle_Tools { try { // try recurring mandate $rcur_mandate = civicrm_api3('SepaMandate', 'get', [ - 'entity_id' => $contribution_id, - 'entity_table' => 'civicrm_contribution_recur', - 'type' => 'RCUR', + 'entity_id' => $contribution_id, + 'entity_table' => 'civicrm_contribution_recur', + 'type' => 'RCUR', ]); if ($rcur_mandate['count'] == 1) { return reset($rcur_mandate['values']); @@ -195,17 +217,19 @@ class CRM_Twingle_Tools { // try OOFF mandate // try recurring mandate $ooff_mandate = civicrm_api3('SepaMandate', 'get', [ - 'entity_id' => $contribution_id, - 'entity_table' => 'civicrm_contribution', - 'type' => 'OOFF', + 'entity_id' => $contribution_id, + 'entity_table' => 'civicrm_contribution', + 'type' => 'OOFF', ]); if ($ooff_mandate['count'] == 1) { return reset($ooff_mandate['values']); } - } catch (Exception $ex) { + } + catch (Exception $ex) { Civi::log()->warning("CRM_Twingle_Tools::getMandate failed for [{$contribution_id}]: " . $ex->getMessage()); } } return NULL; } + } diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 9b3af0c..98d956b 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -20,11 +20,11 @@ class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base { /** * Example: Run an external SQL script when the module is uninstalled. * - public function uninstall() { - $this->executeSqlFile('sql/myuninstall.sql'); - } - - /** + * public function uninstall() { + * $this->executeSqlFile('sql/myuninstall.sql'); + * } + * + * /** * Copy financial_type_id setting to new setting financial_type_id_recur. */ public function upgrade_4000() { @@ -74,14 +74,15 @@ class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base { $profile = new CRM_Twingle_Profile($profile_name, $profile_data); $data = json_encode($profile->getData()); CRM_Core_DAO::executeQuery( - "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, NOW(), 0)", + 'INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, NOW(), 0)', [ 1 => [$profile_name, 'String'], - 2 => [$data, 'String'] + 2 => [$data, 'String'], ]); } } return TRUE; } + } diff --git a/CRM/Twingle/Upgrader/Base.php b/CRM/Twingle/Upgrader/Base.php index 07e9629..1ffe718 100644 --- a/CRM/Twingle/Upgrader/Base.php +++ b/CRM/Twingle/Upgrader/Base.php @@ -9,7 +9,7 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Upgrader_Base { /** - * @var varies, subclass of this + * @var variessubclassofthis */ static $instance; @@ -19,22 +19,22 @@ class CRM_Twingle_Upgrader_Base { protected $ctx; /** - * @var string, eg 'com.example.myextension' + * @var stringegcomexamplemyextension */ protected $extensionName; /** - * @var string, full path to the extension's source tree + * @var stringfullpathtotheextensionssourcetree */ protected $extensionDir; /** - * @var array(revisionNumber) sorted numerically + * @var arrayrevisionNumbersortednumerically */ private $revisions; /** - * @var boolean + * @var bool * Flag to clean up extension revision data in civicrm_setting */ private $revisionStorageIsDeprecated = FALSE; @@ -42,7 +42,7 @@ class CRM_Twingle_Upgrader_Base { /** * Obtain a reference to the active upgrade handler. */ - static public function instance() { + public static function instance() { if (!self::$instance) { // FIXME auto-generate self::$instance = new CRM_Twingle_Upgrader( @@ -63,13 +63,13 @@ class CRM_Twingle_Upgrader_Base { * CRM_Twingle_Upgrader_Base::_queueAdapter($ctx, 'methodName', 'arg1', 'arg2'); * @endcode */ - static public function _queueAdapter() { + public static function _queueAdapter() { $instance = self::instance(); $args = func_get_args(); $instance->ctx = array_shift($args); $instance->queue = $instance->ctx->queue; $method = array_shift($args); - return call_user_func_array(array($instance, $method), $args); + return call_user_func_array([$instance, $method], $args); } public function __construct($extensionName, $extensionDir) { @@ -144,7 +144,7 @@ class CRM_Twingle_Upgrader_Base { * provides syntatic sugar for queueing several tasks that * run different queries */ - public function executeSql($query, $params = array()) { + public function executeSql($query, $params = []) { // FIXME verify that we raise an exception on error CRM_Core_DAO::executeQuery($query, $params); return TRUE; @@ -163,11 +163,11 @@ class CRM_Twingle_Upgrader_Base { $args = func_get_args(); $title = array_shift($args); $task = new CRM_Queue_Task( - array(get_class($this), '_queueAdapter'), + [get_class($this), '_queueAdapter'], $args, $title ); - return $this->queue->createItem($task, array('weight' => -1)); + return $this->queue->createItem($task, ['weight' => -1]); } // ******** Revision-tracking helpers ******** @@ -200,23 +200,23 @@ class CRM_Twingle_Upgrader_Base { $currentRevision = $this->getCurrentRevision(); foreach ($this->getRevisions() as $revision) { if ($revision > $currentRevision) { - $title = ts('Upgrade %1 to revision %2', array( + $title = ts('Upgrade %1 to revision %2', [ 1 => $this->extensionName, 2 => $revision, - )); + ]); // note: don't use addTask() because it sets weight=-1 $task = new CRM_Queue_Task( - array(get_class($this), '_queueAdapter'), - array('upgrade_' . $revision), + [get_class($this), '_queueAdapter'], + ['upgrade_' . $revision], $title ); $this->queue->createItem($task); $task = new CRM_Queue_Task( - array(get_class($this), '_queueAdapter'), - array('setCurrentRevision', $revision), + [get_class($this), '_queueAdapter'], + ['setCurrentRevision', $revision], $title ); $this->queue->createItem($task); @@ -231,7 +231,7 @@ class CRM_Twingle_Upgrader_Base { */ public function getRevisions() { if (!is_array($this->revisions)) { - $this->revisions = array(); + $this->revisions = []; $clazz = new ReflectionClass(get_class($this)); $methods = $clazz->getMethods(); @@ -302,7 +302,7 @@ class CRM_Twingle_Upgrader_Base { $this->executeCustomDataFileByAbsPath($file); } } - if (is_callable(array($this, 'install'))) { + if (is_callable([$this, 'install'])) { $this->install(); } } @@ -315,7 +315,7 @@ class CRM_Twingle_Upgrader_Base { if (!empty($revisions)) { $this->setCurrentRevision(max($revisions)); } - if (is_callable(array($this, 'postInstall'))) { + if (is_callable([$this, 'postInstall'])) { $this->postInstall(); } } @@ -330,7 +330,7 @@ class CRM_Twingle_Upgrader_Base { $this->executeSqlTemplate($file); } } - if (is_callable(array($this, 'uninstall'))) { + if (is_callable([$this, 'uninstall'])) { $this->uninstall(); } $files = glob($this->extensionDir . '/sql/*_uninstall.sql'); @@ -346,7 +346,7 @@ class CRM_Twingle_Upgrader_Base { */ public function onEnable() { // stub for possible future use - if (is_callable(array($this, 'enable'))) { + if (is_callable([$this, 'enable'])) { $this->enable(); } } @@ -356,7 +356,7 @@ class CRM_Twingle_Upgrader_Base { */ public function onDisable() { // stub for possible future use - if (is_callable(array($this, 'disable'))) { + if (is_callable([$this, 'disable'])) { $this->disable(); } } @@ -364,7 +364,7 @@ class CRM_Twingle_Upgrader_Base { public function onUpgrade($op, CRM_Queue_Queue $queue = NULL) { switch ($op) { case 'check': - return array($this->hasPendingRevisions()); + return [$this->hasPendingRevisions()]; case 'enqueue': return $this->enqueuePendingRevisions($queue); diff --git a/api/v3/TwingleDonation/Cancel.php b/api/v3/TwingleDonation/Cancel.php index e007059..37ac700 100644 --- a/api/v3/TwingleDonation/Cancel.php +++ b/api/v3/TwingleDonation/Cancel.php @@ -26,34 +26,34 @@ use CRM_Twingle_ExtensionUtil as E; * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards */ function _civicrm_api3_twingle_donation_Cancel_spec(&$params) { - $params['project_id'] = array( + $params['project_id'] = [ 'name' => 'project_id', 'title' => E::ts('Project ID'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The Twingle project ID.'), - ); - $params['trx_id'] = array( + ]; + $params['trx_id'] = [ 'name' => 'trx_id', 'title' => E::ts('Transaction ID'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The unique transaction ID of the donation'), - ); - $params['cancelled_at'] = array( + ]; + $params['cancelled_at'] = [ 'name' => 'cancelled_at', 'title' => E::ts('Cancelled at'), 'type' => CRM_Utils_Type::T_INT, 'api.required' => 1, 'description' => E::ts('The date when the donation was cancelled, format: YmdHis.'), - ); - $params['cancel_reason'] = array( + ]; + $params['cancel_reason'] = [ 'name' => 'cancel_reason', 'title' => E::ts('Cancel reason'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The reason for the donation being cancelled.'), - ); + ]; } /** @@ -82,15 +82,15 @@ function civicrm_api3_twingle_donation_Cancel($params) { // Retrieve (recurring) contribution. $default_profile = CRM_Twingle_Profile::getProfile('default'); try { - $contribution = civicrm_api3('Contribution', 'getsingle', array( + $contribution = civicrm_api3('Contribution', 'getsingle', [ 'trxn_id' => $default_profile->getTransactionID($params['trx_id']), - )); + ]); $contribution_type = 'Contribution'; } catch (CiviCRM_API3_Exception $exception) { - $contribution = civicrm_api3('ContributionRecur', 'getsingle', array( - 'trxn_id' => $default_profile->getTransactionID($params['trx_id']), - )); + $contribution = civicrm_api3('ContributionRecur', 'getsingle', [ + 'trxn_id' => $default_profile->getTransactionID($params['trx_id']), + ]); $contribution_type = 'ContributionRecur'; } @@ -102,7 +102,7 @@ function civicrm_api3_twingle_donation_Cancel($params) { $mandate = CRM_Twingle_Tools::getMandateFor($contribution['id']); if (!$mandate) { throw new CiviCRM_API3_Exception( - E::ts("SEPA Mandate for contribution [%1 not found.", [1 => $contribution['id']]), + E::ts('SEPA Mandate for contribution [%1 not found.', [1 => $contribution['id']]), 'api_error' ); } @@ -115,7 +115,8 @@ function civicrm_api3_twingle_donation_Cancel($params) { $end_date = date('Ymd', max( time(), $end_date->getTimestamp())); - } else { + } + else { // end date couldn't be parsed, use 'now' $end_date = date('Ymd'); } @@ -132,19 +133,19 @@ function civicrm_api3_twingle_donation_Cancel($params) { } // Retrieve updated contribution for return value. - $contribution = civicrm_api3($contribution_type, 'getsingle', array( + $contribution = civicrm_api3($contribution_type, 'getsingle', [ 'id' => $contribution['id'], - )); + ]); } else { // regular contribution CRM_Twingle_Tools::$protection_suspended = TRUE; - $contribution = civicrm_api3($contribution_type, 'create', array( + $contribution = civicrm_api3($contribution_type, 'create', [ 'id' => $contribution['id'], 'cancel_date' => $params['cancelled_at'], 'contribution_status_id' => 'Cancelled', 'cancel_reason' => $params['cancel_reason'], - )); + ]); CRM_Twingle_Tools::$protection_suspended = FALSE; } diff --git a/api/v3/TwingleDonation/Endrecurring.php b/api/v3/TwingleDonation/Endrecurring.php index 9daa59b..95804ef 100644 --- a/api/v3/TwingleDonation/Endrecurring.php +++ b/api/v3/TwingleDonation/Endrecurring.php @@ -26,27 +26,27 @@ use CRM_Twingle_ExtensionUtil as E; * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards */ function _civicrm_api3_twingle_donation_endrecurring_spec(&$params) { - $params['project_id'] = array( + $params['project_id'] = [ 'name' => 'project_id', 'title' => E::ts('Project ID'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The Twingle project ID.'), - ); - $params['trx_id'] = array( + ]; + $params['trx_id'] = [ 'name' => 'trx_id', 'title' => E::ts('Transaction ID'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The unique transaction ID of the donation'), - ); - $params['ended_at'] = array( + ]; + $params['ended_at'] = [ 'name' => 'ended_at', 'title' => E::ts('Ended at'), 'type' => CRM_Utils_Type::T_INT, 'api.required' => 1, 'description' => E::ts('The date when the recurring donation was ended, format: YmdHis.'), - ); + ]; } /** @@ -73,9 +73,9 @@ function civicrm_api3_twingle_donation_endrecurring($params) { } $default_profile = CRM_Twingle_Profile::getProfile('default'); - $contribution = civicrm_api3('ContributionRecur', 'getsingle', array( + $contribution = civicrm_api3('ContributionRecur', 'getsingle', [ 'trxn_id' => $default_profile->getTransactionID($params['trx_id']), - )); + ]); // End SEPA mandate (which ends the associated recurring contribution) or // recurring contributions. @@ -87,7 +87,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) { $mandate = CRM_Twingle_Tools::getMandateFor($contribution['id']); if (!$mandate) { throw new CiviCRM_API3_Exception( - E::ts("SEPA Mandate for recurring contribution [%1 not found.", [1 => $contribution['id']]), + E::ts('SEPA Mandate for recurring contribution [%1 not found.', [1 => $contribution['id']]), 'api_error' ); } @@ -99,7 +99,8 @@ function civicrm_api3_twingle_donation_endrecurring($params) { $end_date = date('Ymd', max( time(), $end_date->getTimestamp())); - } else { + } + else { // end date couldn't be parsed, use 'now' $end_date = date('Ymd'); } @@ -107,7 +108,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) { // verify that the mandate has not been terminated in the past if ($mandate['status'] != 'FRST' && $mandate['status'] != 'RCUR') { throw new CiviCRM_API3_Exception( - E::ts("SEPA Mandate [%1] already terminated.", [1 => $mandate_id]), + E::ts('SEPA Mandate [%1] already terminated.', [1 => $mandate_id]), 'api_error' ); } @@ -122,18 +123,18 @@ function civicrm_api3_twingle_donation_endrecurring($params) { 'api_error' ); } - $contribution = civicrm_api3('ContributionRecur', 'getsingle', array( + $contribution = civicrm_api3('ContributionRecur', 'getsingle', [ 'id' => $contribution['id'], - )); + ]); } else { // END RECURRING CONTRIBUTION CRM_Twingle_Tools::$protection_suspended = TRUE; - $contribution = civicrm_api3('ContributionRecur', 'create', array( - 'id' => $contribution['id'], - 'end_date' => $params['ended_at'], - 'contribution_status_id' => CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED, - )); + $contribution = civicrm_api3('ContributionRecur', 'create', [ + 'id' => $contribution['id'], + 'end_date' => $params['ended_at'], + 'contribution_status_id' => CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED, + ]); CRM_Twingle_Tools::$protection_suspended = FALSE; } From 322c2d0dd3705511b5c44b415d091035da9e83ba Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 15:01:36 +0100 Subject: [PATCH 117/221] Run Civix upgrade to Civix version 23.02.1 --- CRM/Twingle/Upgrader.php | 2 +- CRM/Twingle/Upgrader/Base.php | 376 -------------------------------- info.xml | 9 +- mixin/menu-xml@1.0.0.mixin.php | 31 --- mixin/polyfill.php | 101 --------- mixin/smarty-v2@1.0.1.mixin.php | 51 +++++ twingle.civix.php | 120 +--------- twingle.php | 45 ---- 8 files changed, 64 insertions(+), 671 deletions(-) delete mode 100644 CRM/Twingle/Upgrader/Base.php delete mode 100644 mixin/menu-xml@1.0.0.mixin.php delete mode 100644 mixin/polyfill.php create mode 100644 mixin/smarty-v2@1.0.1.mixin.php diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 98d956b..6cf7d91 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -4,7 +4,7 @@ use CRM_Twingle_ExtensionUtil as E; /** * Collection of upgrade steps. */ -class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base { +class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { /** * Installer script diff --git a/CRM/Twingle/Upgrader/Base.php b/CRM/Twingle/Upgrader/Base.php deleted file mode 100644 index 1ffe718..0000000 --- a/CRM/Twingle/Upgrader/Base.php +++ /dev/null @@ -1,376 +0,0 @@ -ctx = array_shift($args); - $instance->queue = $instance->ctx->queue; - $method = array_shift($args); - return call_user_func_array([$instance, $method], $args); - } - - public function __construct($extensionName, $extensionDir) { - $this->extensionName = $extensionName; - $this->extensionDir = $extensionDir; - } - - // ******** Task helpers ******** - - /** - * Run a CustomData file. - * - * @param string $relativePath the CustomData XML file path (relative to this extension's dir) - * @return bool - */ - public function executeCustomDataFile($relativePath) { - $xml_file = $this->extensionDir . '/' . $relativePath; - return $this->executeCustomDataFileByAbsPath($xml_file); - } - - /** - * Run a CustomData file - * - * @param string $xml_file the CustomData XML file path (absolute path) - * - * @return bool - */ - protected static function executeCustomDataFileByAbsPath($xml_file) { - $import = new CRM_Utils_Migrate_Import(); - $import->run($xml_file); - return TRUE; - } - - /** - * Run a SQL file. - * - * @param string $relativePath the SQL file path (relative to this extension's dir) - * - * @return bool - */ - public function executeSqlFile($relativePath) { - CRM_Utils_File::sourceSQLFile( - CIVICRM_DSN, - $this->extensionDir . DIRECTORY_SEPARATOR . $relativePath - ); - return TRUE; - } - - /** - * @param string $tplFile - * The SQL file path (relative to this extension's dir). - * Ex: "sql/mydata.mysql.tpl". - * @return bool - */ - public function executeSqlTemplate($tplFile) { - // Assign multilingual variable to Smarty. - $upgrade = new CRM_Upgrade_Form(); - - $tplFile = CRM_Utils_File::isAbsolute($tplFile) ? $tplFile : $this->extensionDir . DIRECTORY_SEPARATOR . $tplFile; - $smarty = CRM_Core_Smarty::singleton(); - $smarty->assign('domainID', CRM_Core_Config::domainID()); - CRM_Utils_File::sourceSQLFile( - CIVICRM_DSN, $smarty->fetch($tplFile), NULL, TRUE - ); - return TRUE; - } - - /** - * Run one SQL query. - * - * This is just a wrapper for CRM_Core_DAO::executeSql, but it - * provides syntatic sugar for queueing several tasks that - * run different queries - */ - public function executeSql($query, $params = []) { - // FIXME verify that we raise an exception on error - CRM_Core_DAO::executeQuery($query, $params); - return TRUE; - } - - /** - * Syntatic sugar for enqueuing a task which calls a function in this class. - * - * The task is weighted so that it is processed - * as part of the currently-pending revision. - * - * After passing the $funcName, you can also pass parameters that will go to - * the function. Note that all params must be serializable. - */ - public function addTask($title) { - $args = func_get_args(); - $title = array_shift($args); - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - $args, - $title - ); - return $this->queue->createItem($task, ['weight' => -1]); - } - - // ******** Revision-tracking helpers ******** - - /** - * Determine if there are any pending revisions. - * - * @return bool - */ - public function hasPendingRevisions() { - $revisions = $this->getRevisions(); - $currentRevision = $this->getCurrentRevision(); - - if (empty($revisions)) { - return FALSE; - } - if (empty($currentRevision)) { - return TRUE; - } - - return ($currentRevision < max($revisions)); - } - - /** - * Add any pending revisions to the queue. - */ - public function enqueuePendingRevisions(CRM_Queue_Queue $queue) { - $this->queue = $queue; - - $currentRevision = $this->getCurrentRevision(); - foreach ($this->getRevisions() as $revision) { - if ($revision > $currentRevision) { - $title = ts('Upgrade %1 to revision %2', [ - 1 => $this->extensionName, - 2 => $revision, - ]); - - // note: don't use addTask() because it sets weight=-1 - - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - ['upgrade_' . $revision], - $title - ); - $this->queue->createItem($task); - - $task = new CRM_Queue_Task( - [get_class($this), '_queueAdapter'], - ['setCurrentRevision', $revision], - $title - ); - $this->queue->createItem($task); - } - } - } - - /** - * Get a list of revisions. - * - * @return array(revisionNumbers) sorted numerically - */ - public function getRevisions() { - if (!is_array($this->revisions)) { - $this->revisions = []; - - $clazz = new ReflectionClass(get_class($this)); - $methods = $clazz->getMethods(); - foreach ($methods as $method) { - if (preg_match('/^upgrade_(.*)/', $method->name, $matches)) { - $this->revisions[] = $matches[1]; - } - } - sort($this->revisions, SORT_NUMERIC); - } - - return $this->revisions; - } - - public function getCurrentRevision() { - $revision = CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName); - if (!$revision) { - $revision = $this->getCurrentRevisionDeprecated(); - } - return $revision; - } - - private function getCurrentRevisionDeprecated() { - $key = $this->extensionName . ':version'; - if ($revision = CRM_Core_BAO_Setting::getItem('Extension', $key)) { - $this->revisionStorageIsDeprecated = TRUE; - } - return $revision; - } - - public function setCurrentRevision($revision) { - CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision); - // clean up legacy schema version store (CRM-19252) - $this->deleteDeprecatedRevision(); - return TRUE; - } - - private function deleteDeprecatedRevision() { - if ($this->revisionStorageIsDeprecated) { - $setting = new CRM_Core_BAO_Setting(); - $setting->name = $this->extensionName . ':version'; - $setting->delete(); - Civi::log()->debug("Migrated extension schema revision ID for {$this->extensionName} from civicrm_setting (deprecated) to civicrm_extension.\n"); - } - } - - // ******** Hook delegates ******** - - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install - */ - public function onInstall() { - $files = glob($this->extensionDir . '/sql/*_install.sql'); - if (is_array($files)) { - foreach ($files as $file) { - CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); - } - } - $files = glob($this->extensionDir . '/sql/*_install.mysql.tpl'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeSqlTemplate($file); - } - } - $files = glob($this->extensionDir . '/xml/*_install.xml'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeCustomDataFileByAbsPath($file); - } - } - if (is_callable([$this, 'install'])) { - $this->install(); - } - } - - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall - */ - public function onPostInstall() { - $revisions = $this->getRevisions(); - if (!empty($revisions)) { - $this->setCurrentRevision(max($revisions)); - } - if (is_callable([$this, 'postInstall'])) { - $this->postInstall(); - } - } - - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall - */ - public function onUninstall() { - $files = glob($this->extensionDir . '/sql/*_uninstall.mysql.tpl'); - if (is_array($files)) { - foreach ($files as $file) { - $this->executeSqlTemplate($file); - } - } - if (is_callable([$this, 'uninstall'])) { - $this->uninstall(); - } - $files = glob($this->extensionDir . '/sql/*_uninstall.sql'); - if (is_array($files)) { - foreach ($files as $file) { - CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); - } - } - } - - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable - */ - public function onEnable() { - // stub for possible future use - if (is_callable([$this, 'enable'])) { - $this->enable(); - } - } - - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable - */ - public function onDisable() { - // stub for possible future use - if (is_callable([$this, 'disable'])) { - $this->disable(); - } - } - - public function onUpgrade($op, CRM_Queue_Queue $queue = NULL) { - switch ($op) { - case 'check': - return [$this->hasPendingRevisions()]; - - case 'enqueue': - return $this->enqueuePendingRevisions($queue); - - default: - } - } - -} diff --git a/info.xml b/info.xml index 32c0ab7..d6e896f 100644 --- a/info.xml +++ b/info.xml @@ -14,25 +14,28 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - + 1.5-dev dev 5.56 - + de.systopia.xcm CRM/Twingle - 22.10.0 + 23.02.1 menu-xml@1.0.0 mgd-php@1.0.0 + smarty-v2@1.0.1 + + CRM_Twingle_Upgrader diff --git a/mixin/menu-xml@1.0.0.mixin.php b/mixin/menu-xml@1.0.0.mixin.php deleted file mode 100644 index 4c0b227..0000000 --- a/mixin/menu-xml@1.0.0.mixin.php +++ /dev/null @@ -1,31 +0,0 @@ -addListener('hook_civicrm_xmlMenu', function ($e) use ($mixInfo) { - if (!$mixInfo->isActive()) { - return; - } - - $files = (array) glob($mixInfo->getPath('xml/Menu/*.xml')); - foreach ($files as $file) { - $e->files[] = $file; - } - }); - -}; diff --git a/mixin/polyfill.php b/mixin/polyfill.php deleted file mode 100644 index f57c5eb..0000000 --- a/mixin/polyfill.php +++ /dev/null @@ -1,101 +0,0 @@ -')) { - $mixinVers[$name] = $ver; - } - } - $mixins = []; - foreach ($mixinVers as $name => $ver) { - $mixins[] = "$name@$ver"; - } - - // Imitate CRM_Extension_MixInfo. - $mixInfo = new class() { - - /** - * @var string - */ - public $longName; - - /** - * @var string - */ - public $shortName; - - public $_basePath; - - public function getPath($file = NULL) { - return $this->_basePath . ($file === NULL ? '' : (DIRECTORY_SEPARATOR . $file)); - } - - public function isActive() { - return \CRM_Extension_System::singleton()->getMapper()->isActiveModule($this->shortName); - } - - }; - $mixInfo->longName = $longName; - $mixInfo->shortName = $shortName; - $mixInfo->_basePath = $basePath; - - // Imitate CRM_Extension_BootCache. - $bootCache = new class() { - - public function define($name, $callback) { - $envId = \CRM_Core_Config_Runtime::getId(); - $oldExtCachePath = \Civi::paths()->getPath("[civicrm.compile]/CachedExtLoader.{$envId}.php"); - $stat = stat($oldExtCachePath); - $file = Civi::paths()->getPath('[civicrm.compile]/CachedMixin.' . md5($name . ($stat['mtime'] ?? 0)) . '.php'); - if (file_exists($file)) { - return include $file; - } - else { - $data = $callback(); - file_put_contents($file, '<' . "?php\nreturn " . var_export($data, 1) . ';'); - return $data; - } - } - - }; - - // Imitate CRM_Extension_MixinLoader::run() - // Parse all live mixins before trying to scan any classes. - global $_CIVIX_MIXIN_POLYFILL; - foreach ($mixins as $mixin) { - // If the exact same mixin is defined by multiple exts, just use the first one. - if (!isset($_CIVIX_MIXIN_POLYFILL[$mixin])) { - $_CIVIX_MIXIN_POLYFILL[$mixin] = include_once $basePath . '/mixin/' . $mixin . '.mixin.php'; - } - } - foreach ($mixins as $mixin) { - // If there's trickery about installs/uninstalls/resets, then we may need to register a second time. - if (!isset(\Civi::$statics[__FUNCTION__][$mixin])) { - \Civi::$statics[__FUNCTION__][$mixin] = 1; - $func = $_CIVIX_MIXIN_POLYFILL[$mixin]; - $func($mixInfo, $bootCache); - } - } -}; diff --git a/mixin/smarty-v2@1.0.1.mixin.php b/mixin/smarty-v2@1.0.1.mixin.php new file mode 100644 index 0000000..5972dbd --- /dev/null +++ b/mixin/smarty-v2@1.0.1.mixin.php @@ -0,0 +1,51 @@ +getPath('templates'); + if (!file_exists($dir)) { + return; + } + + $register = function() use ($dir) { + // This implementation has a theoretical edge-case bug on older versions of CiviCRM where a template could + // be registered more than once. + CRM_Core_Smarty::singleton()->addTemplateDir($dir); + }; + + // Let's figure out what environment we're in -- so that we know the best way to call $register(). + + if (!empty($GLOBALS['_CIVIX_MIXIN_POLYFILL'])) { + // Polyfill Loader (v<=5.45): We're already in the middle of firing `hook_config`. + if ($mixInfo->isActive()) { + $register(); + } + return; + } + + if (CRM_Extension_System::singleton()->getManager()->extensionIsBeingInstalledOrEnabled($mixInfo->longName)) { + // New Install, Standard Loader: The extension has just been enabled, and we're now setting it up. + // System has already booted. New templates may be needed for upcoming installation steps. + $register(); + return; + } + + // Typical Pageview, Standard Loader: Defer the actual registration for a moment -- to ensure that Smarty is online. + \Civi::dispatcher()->addListener('hook_civicrm_config', function() use ($mixInfo, $register) { + if ($mixInfo->isActive()) { + $register(); + } + }); + +}; diff --git a/twingle.civix.php b/twingle.civix.php index 4cd74d1..c207adf 100644 --- a/twingle.civix.php +++ b/twingle.civix.php @@ -79,40 +79,22 @@ class CRM_Twingle_ExtensionUtil { use CRM_Twingle_ExtensionUtil as E; -function _twingle_civix_mixin_polyfill() { - if (!class_exists('CRM_Extension_MixInfo')) { - $polyfill = __DIR__ . '/mixin/polyfill.php'; - (require $polyfill)(E::LONG_NAME, E::SHORT_NAME, E::path()); - } -} - /** * (Delegated) Implements hook_civicrm_config(). * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _twingle_civix_civicrm_config(&$config = NULL) { +function _twingle_civix_civicrm_config($config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; - $template = CRM_Core_Smarty::singleton(); - $extRoot = __DIR__ . DIRECTORY_SEPARATOR; - $extDir = $extRoot . 'templates'; - - if (is_array($template->template_dir)) { - array_unshift($template->template_dir, $extDir); - } - else { - $template->template_dir = [$extDir, $template->template_dir]; - } - $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); - _twingle_civix_mixin_polyfill(); + // Based on , this does not currently require mixin/polyfill.php. } /** @@ -122,36 +104,7 @@ function _twingle_civix_civicrm_config(&$config = NULL) { */ function _twingle_civix_civicrm_install() { _twingle_civix_civicrm_config(); - if ($upgrader = _twingle_civix_upgrader()) { - $upgrader->onInstall(); - } - _twingle_civix_mixin_polyfill(); -} - -/** - * Implements hook_civicrm_postInstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall - */ -function _twingle_civix_civicrm_postInstall() { - _twingle_civix_civicrm_config(); - if ($upgrader = _twingle_civix_upgrader()) { - if (is_callable([$upgrader, 'onPostInstall'])) { - $upgrader->onPostInstall(); - } - } -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall - */ -function _twingle_civix_civicrm_uninstall(): void { - _twingle_civix_civicrm_config(); - if ($upgrader = _twingle_civix_upgrader()) { - $upgrader->onUninstall(); - } + // Based on , this does not currently require mixin/polyfill.php. } /** @@ -161,57 +114,7 @@ function _twingle_civix_civicrm_uninstall(): void { */ function _twingle_civix_civicrm_enable(): void { _twingle_civix_civicrm_config(); - if ($upgrader = _twingle_civix_upgrader()) { - if (is_callable([$upgrader, 'onEnable'])) { - $upgrader->onEnable(); - } - } - _twingle_civix_mixin_polyfill(); -} - -/** - * (Delegated) Implements hook_civicrm_disable(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable - * @return mixed - */ -function _twingle_civix_civicrm_disable(): void { - _twingle_civix_civicrm_config(); - if ($upgrader = _twingle_civix_upgrader()) { - if (is_callable([$upgrader, 'onDisable'])) { - $upgrader->onDisable(); - } - } -} - -/** - * (Delegated) Implements hook_civicrm_upgrade(). - * - * @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 - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade - */ -function _twingle_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - if ($upgrader = _twingle_civix_upgrader()) { - return $upgrader->onUpgrade($op, $queue); - } -} - -/** - * @return CRM_Twingle_Upgrader - */ -function _twingle_civix_upgrader() { - if (!file_exists(__DIR__ . '/CRM/Twingle/Upgrader.php')) { - return NULL; - } - else { - return CRM_Twingle_Upgrader_Base::instance(); - } + // Based on , this does not currently require mixin/polyfill.php. } /** @@ -230,8 +133,8 @@ function _twingle_civix_insert_navigation_menu(&$menu, $path, $item) { if (empty($path)) { $menu[] = [ 'attributes' => array_merge([ - 'label' => CRM_Utils_Array::value('name', $item), - 'active' => 1, + 'label' => $item['name'] ?? NULL, + 'active' => 1, ], $item), ]; return TRUE; @@ -295,14 +198,3 @@ function _twingle_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) { } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _twingle_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, []); -} diff --git a/twingle.php b/twingle.php index 062152e..f22eafc 100644 --- a/twingle.php +++ b/twingle.php @@ -30,24 +30,6 @@ function twingle_civicrm_install() { _twingle_civix_civicrm_install(); } -/** - * Implements hook_civicrm_postInstall(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall - */ -function twingle_civicrm_postInstall() { - _twingle_civix_civicrm_postInstall(); -} - -/** - * Implements hook_civicrm_uninstall(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall - */ -function twingle_civicrm_uninstall() { - _twingle_civix_civicrm_uninstall(); -} - /** * Implements hook_civicrm_enable(). * @@ -57,24 +39,6 @@ function twingle_civicrm_enable() { _twingle_civix_civicrm_enable(); } -/** - * Implements hook_civicrm_disable(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable - */ -function twingle_civicrm_disable() { - _twingle_civix_civicrm_disable(); -} - -/** - * Implements hook_civicrm_upgrade(). - * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade - */ -function twingle_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { - return _twingle_civix_civicrm_upgrade($op, $queue); -} - /** * Implements hook_civicrm_permission(). * @@ -137,12 +101,3 @@ function twingle_civicrm_navigationMenu(&$menu) { )); _twingle_civix_navigationMenu($menu); } // */ - -/** - * Implements hook_civicrm_entityTypes(). - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function twingle_civicrm_entityTypes(&$entityTypes) { - _twingle_civix_civicrm_entityTypes($entityTypes); -} From f42bc9b7ed2105c62c640876ad5ef5f54534745c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 15:26:15 +0100 Subject: [PATCH 118/221] PHP Code Sniffer fixes --- CRM/Twingle/Config.php | 8 +- CRM/Twingle/Form/Profile.php | 17 +- CRM/Twingle/Form/Settings.php | 2 + CRM/Twingle/Page/Configuration.php | 2 + CRM/Twingle/Page/Profiles.php | 2 + CRM/Twingle/Profile.php | 89 ++-- CRM/Twingle/Submission.php | 18 +- CRM/Twingle/Tools.php | 6 +- CRM/Twingle/Upgrader.php | 16 + api/v3/TwingleDonation/Cancel.php | 2 + api/v3/TwingleDonation/Endrecurring.php | 2 + api/v3/TwingleDonation/Submit.php | 544 ++++++++++++------------ 12 files changed, 392 insertions(+), 316 deletions(-) diff --git a/CRM/Twingle/Config.php b/CRM/Twingle/Config.php index 557a572..d75b7b4 100644 --- a/CRM/Twingle/Config.php +++ b/CRM/Twingle/Config.php @@ -13,13 +13,15 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Config { - const RCUR_PROTECTION_OFF = 0; - const RCUR_PROTECTION_EXCEPTION = 1; - const RCUR_PROTECTION_ACTIVITY = 2; + public const RCUR_PROTECTION_OFF = 0; + public const RCUR_PROTECTION_EXCEPTION = 1; + public const RCUR_PROTECTION_ACTIVITY = 2; /** * Get the options for protecting a recurring contribution linked Twingle diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index e1fc67a..c4a556b 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -13,6 +13,8 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; /** @@ -461,7 +463,12 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { E::ts('API Call for Membership Postprocessing'), FALSE ); - $this->addRule('membership_postprocess_call', E::ts("The API call must have the form 'Entity.Action'."), 'regex', '/^[A-Za-z_]+[.][A-Za-z_]+$/'); + $this->addRule( + 'membership_postprocess_call', + E::ts("The API call must have the form 'Entity.Action'."), + 'regex', + '/^[A-Za-z_]+[.][A-Za-z_]+$/' + ); $this->add( // field type @@ -513,10 +520,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { /** * Validates the profile form. * - * @param array $values - * The submitted form values, keyed by form element name. - * - * @return bool | array + * @return bool|array * TRUE when the form was successfully validated, or an array of error * messages, keyed by form element name. */ @@ -534,7 +538,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Restrict profile names to alphanumeric characters and the underscore. if (isset($values['name']) && preg_match('/[^A-Za-z0-9\_]/', $values['name'])) { - $this->_errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); + $this->_errors['name'] = + E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); } // Validate custom field mapping. diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index a359588..6303dc9 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -13,6 +13,8 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; /** diff --git a/CRM/Twingle/Page/Configuration.php b/CRM/Twingle/Page/Configuration.php index 2a56343..f30cf67 100644 --- a/CRM/Twingle/Page/Configuration.php +++ b/CRM/Twingle/Page/Configuration.php @@ -13,6 +13,8 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Page_Configuration extends CRM_Core_Page { diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index f042e81..e8f014b 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -13,6 +13,8 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Page_Profiles extends CRM_Core_Page { diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 613e1e9..d85c9f3 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -13,6 +13,8 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; /** @@ -22,13 +24,13 @@ use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Profile { /** - * @var string $name + * @var string * The name of the profile. */ protected $name = NULL; /** - * @var array $data + * @var array * The properties of the profile. */ protected $data = NULL; @@ -54,18 +56,18 @@ class CRM_Twingle_Profile { * Logs (production) access to this profile */ public function logAccess() { - CRM_Core_DAO::executeQuery(" + CRM_Core_DAO::executeQuery(' UPDATE civicrm_twingle_profile SET last_access = NOW(), access_counter = access_counter + 1 - WHERE name = %1", [1 => [$this->name, 'String']]); + WHERE name = %1', [1 => [$this->name, 'String']]); } /** * Checks whether the profile's selector matches the given project ID. * - * @param string | int $project_id + * @param string|int $project_id * * @return bool */ @@ -88,7 +90,7 @@ class CRM_Twingle_Profile { $custom_field_mapping = []; if (!empty($custom_field_definition = $this->getAttribute('custom_field_mapping'))) { foreach (preg_split('/\r\n|\r|\n/', $custom_field_definition, -1, PREG_SPLIT_NO_EMPTY) as $custom_field_map) { - [$twingle_field_name, $custom_field_name] = explode("=", $custom_field_map); + [$twingle_field_name, $custom_field_name] = explode('=', $custom_field_map); $custom_field_mapping[$twingle_field_name] = $custom_field_name; } } @@ -161,7 +163,8 @@ class CRM_Twingle_Profile { $prefix = Civi::settings()->get('twingle_prefix'); if (empty($prefix)) { return $twingle_id; - } else { + } + else { return $prefix . $twingle_id; } } @@ -188,22 +191,23 @@ class CRM_Twingle_Profile { // check if the profile exists $profile_id = CRM_Core_DAO::singleValueQuery( - "SELECT id FROM civicrm_twingle_profile WHERE name = %1", [1 => [$this->name, 'String']]); + 'SELECT id FROM civicrm_twingle_profile WHERE name = %1', [1 => [$this->name, 'String']]); if ($profile_id) { // existing profile -> just update the config CRM_Core_DAO::executeQuery( - "UPDATE civicrm_twingle_profile SET config = %2 WHERE name = %1", + 'UPDATE civicrm_twingle_profile SET config = %2 WHERE name = %1', [ 1 => [$this->name, 'String'], - 2 => [json_encode($this->data), 'String'] + 2 => [json_encode($this->data), 'String'], ]); - } else { + } + else { // new profile -> add new entry to the DB CRM_Core_DAO::executeQuery( - "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)", + 'INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)', [ 1 => [$this->name, 'String'], - 2 => [json_encode($this->data), 'String'] + 2 => [json_encode($this->data), 'String'], ]); } } @@ -212,7 +216,10 @@ class CRM_Twingle_Profile { * Deletes the profile from the database */ public function deleteProfile() { - CRM_Core_DAO::executeQuery("DELETE FROM civicrm_twingle_profile WHERE name = %1", [1 => [$this->name, 'String']]); + CRM_Core_DAO::executeQuery( + 'DELETE FROM civicrm_twingle_profile WHERE name = %1', + [1 => [$this->name, 'String']] + ); } /** @@ -275,7 +282,7 @@ class CRM_Twingle_Profile { 'pi_sofortueberweisung' => E::ts('SOFORT Überweisung'), 'pi_amazonpay' => E::ts('Amazon Pay'), 'pi_applepay' => E::ts('Apple Pay'), - 'pi_googlepay' => E::ts('Google Pay'), + 'pi_googlepay' => E::ts('Google Pay'), 'pi_paydirekt' => E::ts('Paydirekt'), 'pi_twint' => E::ts('Twint'), 'pi_ideal' => E::ts('iDEAL'), @@ -294,16 +301,21 @@ class CRM_Twingle_Profile { */ public static function createDefaultProfile($name = 'default') { return new CRM_Twingle_Profile($name, [ - 'selector' => '', - 'xcm_profile' => '', - 'location_type_id' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, + 'selector' => '', + 'xcm_profile' => '', + 'location_type_id' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, 'location_type_id_organisation' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, - 'financial_type_id' => 1, // "Donation" - 'financial_type_id_recur' => 1, // "Donation" - 'pi_banktransfer' => 5, // "EFT" + // "Donation" + 'financial_type_id' => 1, + // "Donation" + 'financial_type_id_recur' => 1, + // "EFT" + 'pi_banktransfer' => 5, 'pi_debit_manual' => NULL, - 'pi_debit_automatic' => 2, // Debit - 'pi_creditcard' => 1, // "Credit Card" + // Debit + 'pi_debit_automatic' => 2, + // "Credit Card" + 'pi_creditcard' => 1, 'pi_mobilephone_germany' => NULL, 'pi_paypal' => NULL, 'pi_sofortueberweisung' => NULL, @@ -336,10 +348,10 @@ class CRM_Twingle_Profile { 'country', ], ] - // Add contribution status for all payment methods. - + array_fill_keys(array_map(function($attribute) { - return $attribute . '_status'; - }, array_keys(static::paymentInstruments())), CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED)); + // Add contribution status for all payment methods. + + array_fill_keys(array_map(function($attribute) { + return $attribute . '_status'; + }, array_keys(static::paymentInstruments())), CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED)); } /** @@ -383,8 +395,10 @@ class CRM_Twingle_Profile { */ public static function getProfile($name) { if (!empty($name)) { - $profile_data = CRM_Core_DAO::singleValueQuery("SELECT config FROM civicrm_twingle_profile WHERE name = %1", [ - 1 => [$name, 'String']]); + $profile_data = CRM_Core_DAO::singleValueQuery( + 'SELECT config FROM civicrm_twingle_profile WHERE name = %1', + [1 => [$name, 'String']] + ); if ($profile_data) { return new CRM_Twingle_Profile($name, json_decode($profile_data, 1)); } @@ -402,9 +416,12 @@ class CRM_Twingle_Profile { public static function getProfiles() { // todo: cache? $profiles = []; - $profile_data = CRM_Core_DAO::executeQuery("SELECT name, config FROM civicrm_twingle_profile"); + $profile_data = CRM_Core_DAO::executeQuery('SELECT name, config FROM civicrm_twingle_profile'); while ($profile_data->fetch()) { - $profiles[$profile_data->name] = new CRM_Twingle_Profile($profile_data->name, json_decode($profile_data->config, 1)); + $profiles[$profile_data->name] = new CRM_Twingle_Profile( + $profile_data->name, + json_decode($profile_data->config, 1) + ); } return $profiles; } @@ -416,14 +433,18 @@ class CRM_Twingle_Profile { */ public static function getProfileStats() { $stats = []; - $profile_data = CRM_Core_DAO::executeQuery("SELECT name, last_access, access_counter FROM civicrm_twingle_profile"); + $profile_data = CRM_Core_DAO::executeQuery('SELECT name, last_access, access_counter FROM civicrm_twingle_profile'); while ($profile_data->fetch()) { $stats[$profile_data->name] = [ 'name' => $profile_data->name, 'last_access' => $profile_data->last_access, - 'last_access_txt' => $profile_data->last_access ? date('Y-m-d H:i:s', strtotime($profile_data->last_access)) : E::ts("never"), + 'last_access_txt' => $profile_data->last_access + ? date('Y-m-d H:i:s', strtotime($profile_data->last_access)) + : E::ts('never'), 'access_counter' => $profile_data->access_counter, - 'access_counter_txt' => $profile_data->access_counter ? ((int) $profile_data->access_counter) . 'x' : E::ts("never"), + 'access_counter_txt' => $profile_data->access_counter + ? ((int) $profile_data->access_counter) . 'x' + : E::ts('never'), ]; } return $stats; diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 342e2be..7c8ed9c 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -13,6 +13,8 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Submission { @@ -20,22 +22,22 @@ class CRM_Twingle_Submission { /** * The default ID of the "Work" location type. */ - const LOCATION_TYPE_ID_WORK = 2; + public const LOCATION_TYPE_ID_WORK = 2; /** * The option value name of the group type for newsletter subscribers. */ - const GROUP_TYPE_NEWSLETTER = 'Mailing List'; + public const GROUP_TYPE_NEWSLETTER = 'Mailing List'; /** * The option value for the contribution type for completed contributions. */ - const CONTRIBUTION_STATUS_COMPLETED = 'Completed'; + public const CONTRIBUTION_STATUS_COMPLETED = 'Completed'; /** * The default ID of the "Employer of" relationship type. */ - const EMPLOYER_RELATIONSHIP_TYPE_ID = 5; + public const EMPLOYER_RELATIONSHIP_TYPE_ID = 5; /** * @param array &$params @@ -157,7 +159,7 @@ class CRM_Twingle_Submission { * @param array $submission * Submission data * - * @return int | NULL + * @return int|NULL * The ID of the matching/created contact, or NULL if no matching contact * was found and no new contact could be created. * @throws \CiviCRM_API3_Exception @@ -235,7 +237,11 @@ class CRM_Twingle_Submission { * @throws \CiviCRM_API3_Exception * When looking up or creating the shared address failed. */ - public static function shareWorkAddress($contact_id, $organisation_id, $location_type_id = self::LOCATION_TYPE_ID_WORK) { + public static function shareWorkAddress( + $contact_id, + $organisation_id, + $location_type_id = self::LOCATION_TYPE_ID_WORK + ) { if (empty($organisation_id)) { // Only if organisation exists. return FALSE; diff --git a/CRM/Twingle/Tools.php b/CRM/Twingle/Tools.php index 52e9789..aa1bb1c 100644 --- a/CRM/Twingle/Tools.php +++ b/CRM/Twingle/Tools.php @@ -13,6 +13,8 @@ | written permission from the original author(s). | +-------------------------------------------------------------*/ +declare(strict_types = 1); + use CRM_Twingle_ExtensionUtil as E; class CRM_Twingle_Tools { @@ -121,7 +123,9 @@ class CRM_Twingle_Tools { break; case CRM_Twingle_Config::RCUR_PROTECTION_EXCEPTION: - throw new Exception(E::ts('This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.')); + throw new Exception(E::ts( + 'This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.' + )); case CRM_Twingle_Config::RCUR_PROTECTION_ACTIVITY: // create contact source activity diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 6cf7d91..abba9d8 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -1,4 +1,20 @@ 'project_id', 'title' => E::ts('Project ID'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The Twingle project ID.'), - ); - $params['trx_id'] = array( + ]; + $params['trx_id'] = [ 'name' => 'trx_id', 'title' => E::ts('Transaction ID'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The unique transaction ID of the donation'), - ); - $params['confirmed_at'] = array( + ]; + $params['confirmed_at'] = [ 'name' => 'confirmed_at', 'title' => E::ts('Confirmed at'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, 'description' => E::ts('The date when the donation was issued, format: YmdHis.'), - ); - $params['purpose'] = array( + ]; + $params['purpose'] = [ 'name' => 'purpose', 'title' => E::ts('Purpose'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, 'description' => E::ts('The purpose of the donation.'), - ); - $params['amount'] = array( + ]; + $params['amount'] = [ 'name' => 'amount', 'title' => E::ts('Amount'), 'type' => CRM_Utils_Type::T_INT, 'api.required' => 1, 'description' => E::ts('The donation amount in minor currency unit.'), - ); - $params['currency'] = array( - 'name' => 'currency', - 'title' => E::ts('Currency'), - 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['currency'] = [ + 'name' => 'currency', + 'title' => E::ts('Currency'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, - 'description' => E::ts('The ISO-4217 currency code of the donation.'), - ); - $params['newsletter'] = array( - 'name' => 'newsletter', - 'title' => E::ts('Newsletter'), - 'type' => CRM_Utils_Type::T_BOOLEAN, + 'description' => E::ts('The ISO-4217 currency code of the donation.'), + ]; + $params['newsletter'] = [ + 'name' => 'newsletter', + 'title' => E::ts('Newsletter'), + 'type' => CRM_Utils_Type::T_BOOLEAN, 'api.required' => 0, - 'description' => E::ts('Whether to subscribe the contact to the newsletter group defined in the profile.'), - ); - $params['postinfo'] = array( - 'name' => 'postinfo', - 'title' => E::ts('Postal mailing'), - 'type' => CRM_Utils_Type::T_BOOLEAN, + 'description' => E::ts('Whether to subscribe the contact to the newsletter group defined in the profile.'), + ]; + $params['postinfo'] = [ + 'name' => 'postinfo', + 'title' => E::ts('Postal mailing'), + 'type' => CRM_Utils_Type::T_BOOLEAN, 'api.required' => 0, - 'description' => E::ts('Whether to subscribe the contact to the postal mailing group defined in the profile.'), - ); - $params['donation_receipt'] = array( - 'name' => 'donation_receipt', - 'title' => E::ts('Donation receipt'), - 'type' => CRM_Utils_Type::T_BOOLEAN, + 'description' => E::ts('Whether to subscribe the contact to the postal mailing group defined in the profile.'), + ]; + $params['donation_receipt'] = [ + 'name' => 'donation_receipt', + 'title' => E::ts('Donation receipt'), + 'type' => CRM_Utils_Type::T_BOOLEAN, 'api.required' => 0, - 'description' => E::ts('Whether the contact requested a donation receipt.'), - ); - $params['payment_method'] = array( - 'name' => 'payment_method', - 'title' => E::ts('Payment method'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('Whether the contact requested a donation receipt.'), + ]; + $params['payment_method'] = [ + 'name' => 'payment_method', + 'title' => E::ts('Payment method'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, - 'description' => E::ts('The Twingle payment method used for the donation.'), - ); - $params['donation_rhythm'] = array( - 'name' => 'donation_rhythm', - 'title' => E::ts('Donation rhythm'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The Twingle payment method used for the donation.'), + ]; + $params['donation_rhythm'] = [ + 'name' => 'donation_rhythm', + 'title' => E::ts('Donation rhythm'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 1, - 'description' => E::ts('The interval which the donation is recurring in.'), - ); - $params['debit_iban'] = array( - 'name' => 'debit_iban', - 'title' => E::ts('SEPA IBAN'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The interval which the donation is recurring in.'), + ]; + $params['debit_iban'] = [ + 'name' => 'debit_iban', + 'title' => E::ts('SEPA IBAN'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The IBAN for SEPA Direct Debit payments, conforming with ISO 13616-1:2007.'), - ); - $params['debit_bic'] = array( - 'name' => 'debit_bic', - 'title' => E::ts('SEPA BIC'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The IBAN for SEPA Direct Debit payments, conforming with ISO 13616-1:2007.'), + ]; + $params['debit_bic'] = [ + 'name' => 'debit_bic', + 'title' => E::ts('SEPA BIC'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The BIC for SEPA Direct Debit payments, conforming with ISO 9362.'), - ); - $params['debit_mandate_reference'] = array( - 'name' => 'debit_mandate_reference', - 'title' => E::ts('SEPA Direct Debit Mandate reference'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The BIC for SEPA Direct Debit payments, conforming with ISO 9362.'), + ]; + $params['debit_mandate_reference'] = [ + 'name' => 'debit_mandate_reference', + 'title' => E::ts('SEPA Direct Debit Mandate reference'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The mandate reference for SEPA Direct Debit payments.'), - ); - $params['debit_account_holder'] = array( - 'name' => 'debit_account_holder', - 'title' => E::ts('SEPA Direct Debit Account holder'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The mandate reference for SEPA Direct Debit payments.'), + ]; + $params['debit_account_holder'] = [ + 'name' => 'debit_account_holder', + 'title' => E::ts('SEPA Direct Debit Account holder'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The account holder for SEPA Direct Debit payments.'), - ); - $params['is_anonymous'] = array( - 'name' => 'is_anonymous', - 'title' => E::ts('Anonymous donation'), - 'type' => CRM_Utils_Type::T_BOOLEAN, + 'description' => E::ts('The account holder for SEPA Direct Debit payments.'), + ]; + $params['is_anonymous'] = [ + 'name' => 'is_anonymous', + 'title' => E::ts('Anonymous donation'), + 'type' => CRM_Utils_Type::T_BOOLEAN, 'api.required' => 0, - 'api.default' => 0, - 'description' => E::ts('Whether the donation is submitted anonymously.'), - ); - $params['user_gender'] = array( - 'name' => 'user_gender', - 'title' => E::ts('Gender'), - 'type' => CRM_Utils_Type::T_STRING, + 'api.default' => 0, + 'description' => E::ts('Whether the donation is submitted anonymously.'), + ]; + $params['user_gender'] = [ + 'name' => 'user_gender', + 'title' => E::ts('Gender'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The gender of the contact.'), - ); - $params['user_birthdate'] = array( - 'name' => 'user_birthdate', - 'title' => E::ts('Date of birth'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The gender of the contact.'), + ]; + $params['user_birthdate'] = [ + 'name' => 'user_birthdate', + 'title' => E::ts('Date of birth'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The date of birth of the contact, format: Ymd.'), - ); - $params['user_title'] = array( - 'name' => 'user_title', - 'title' => E::ts('Formal title'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The date of birth of the contact, format: Ymd.'), + ]; + $params['user_title'] = [ + 'name' => 'user_title', + 'title' => E::ts('Formal title'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The formal title of the contact.'), - ); - $params['user_email'] = array( - 'name' => 'user_email', - 'title' => E::ts('Email address'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The formal title of the contact.'), + ]; + $params['user_email'] = [ + 'name' => 'user_email', + 'title' => E::ts('Email address'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The e-mail address of the contact.'), - ); - $params['user_firstname'] = array( - 'name' => 'user_firstname', - 'title' => E::ts('First name'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The e-mail address of the contact.'), + ]; + $params['user_firstname'] = [ + 'name' => 'user_firstname', + 'title' => E::ts('First name'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The first name of the contact.'), - ); - $params['user_lastname'] = array( - 'name' => 'user_lastname', - 'title' => E::ts('Last name'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The first name of the contact.'), + ]; + $params['user_lastname'] = [ + 'name' => 'user_lastname', + 'title' => E::ts('Last name'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The last name of the contact.'), - ); - $params['user_street'] = array( - 'name' => 'user_street', - 'title' => E::ts('Street address'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The last name of the contact.'), + ]; + $params['user_street'] = [ + 'name' => 'user_street', + 'title' => E::ts('Street address'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The street address of the contact.'), - ); - $params['user_postal_code'] = array( - 'name' => 'user_postal_code', - 'title' => E::ts('Postal code'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The street address of the contact.'), + ]; + $params['user_postal_code'] = [ + 'name' => 'user_postal_code', + 'title' => E::ts('Postal code'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The postal code of the contact.'), - ); - $params['user_city'] = array( - 'name' => 'user_city', - 'title' => E::ts('City'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The postal code of the contact.'), + ]; + $params['user_city'] = [ + 'name' => 'user_city', + 'title' => E::ts('City'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The city of the contact.'), - ); - $params['user_country'] = array( - 'name' => 'user_country', - 'title' => E::ts('Country'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The city of the contact.'), + ]; + $params['user_country'] = [ + 'name' => 'user_country', + 'title' => E::ts('Country'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The country of the contact.'), - ); - $params['user_telephone'] = array( - 'name' => 'user_telephone', - 'title' => E::ts('Telephone'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The country of the contact.'), + ]; + $params['user_telephone'] = [ + 'name' => 'user_telephone', + 'title' => E::ts('Telephone'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The telephone number of the contact.'), - ); - $params['user_company'] = array( - 'name' => 'user_company', - 'title' => E::ts('Company'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The telephone number of the contact.'), + ]; + $params['user_company'] = [ + 'name' => 'user_company', + 'title' => E::ts('Company'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The company of the contact.'), - ); - $params['user_language'] = array( - 'name' => 'user_language', - 'title' => E::ts('Language'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The company of the contact.'), + ]; + $params['user_language'] = [ + 'name' => 'user_language', + 'title' => E::ts('Language'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('The preferred language of the contact. A 2-digit ISO-639-1 language code.'), - ); - $params['user_extrafield'] = array( - 'name' => 'user_extrafield', - 'title' => E::ts('User extra field'), - 'type' => CRM_Utils_Type::T_STRING, + 'description' => E::ts('The preferred language of the contact. A 2-digit ISO-639-1 language code.'), + ]; + $params['user_extrafield'] = [ + 'name' => 'user_extrafield', + 'title' => E::ts('User extra field'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('Additional information of the contact.'), - ); - $params['campaign_id'] = array( + 'description' => E::ts('Additional information of the contact.'), + ]; + $params['campaign_id'] = [ 'name' => 'campaign_id', 'title' => E::ts('Campaign ID'), 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, 'description' => E::ts('The CiviCRM ID of a campaign to assign the contribution.'), - ); - $params['custom_fields'] = array( - 'name' => 'custom_fields', - 'title' => E::ts('Custom fields'), - 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['custom_fields'] = [ + 'name' => 'custom_fields', + 'title' => E::ts('Custom fields'), + 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, - 'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'), - ); + 'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'), + ]; } /** @@ -273,7 +275,7 @@ function civicrm_api3_twingle_donation_Submit($params) { $original_params = $params; // Prepare results array. - $result_values = array(); + $result_values = []; // Get the profile defined for the given form ID, or the default profile // if none matches. @@ -285,12 +287,12 @@ function civicrm_api3_twingle_donation_Submit($params) { // Do not process an already existing contribution with the given // transaction ID. - $existing_contribution = civicrm_api3('Contribution', 'get', array( - 'trxn_id' => $profile->getTransactionID($params['trx_id']) - )); - $existing_contribution_recur = civicrm_api3('ContributionRecur', 'get', array( - 'trxn_id' => $profile->getTransactionID($params['trx_id']) - )); + $existing_contribution = civicrm_api3('Contribution', 'get', [ + 'trxn_id' => $profile->getTransactionID($params['trx_id']), + ]); + $existing_contribution_recur = civicrm_api3('ContributionRecur', 'get', [ + 'trxn_id' => $profile->getTransactionID($params['trx_id']), + ]); if ($existing_contribution['count'] > 0 || $existing_contribution_recur['count'] > 0) { throw new CiviCRM_API3_Exception( E::ts('Contribution with the given transaction ID already exists.'), @@ -300,13 +302,13 @@ function civicrm_api3_twingle_donation_Submit($params) { // Extract custom field values using the profile's mapping of Twingle fields // to CiviCRM custom fields. - $custom_fields = array(); + $custom_fields = []; if (!empty($params['custom_fields'])) { $custom_field_mapping = $profile->getCustomFieldMapping(); // Include user_extrafield in custom_field_mapping if it is referenced there. // See issue #50. - if(!empty($params['user_extrafield']) && isset($custom_field_mapping['user_extrafield'])) { + if (!empty($params['user_extrafield']) && isset($custom_field_mapping['user_extrafield'])) { $params['custom_fields']['user_extrafield'] = $params['user_extrafield']; } @@ -315,11 +317,11 @@ function civicrm_api3_twingle_donation_Submit($params) { // Get custom field definition to store values by entity the field // extends. $custom_field_id = substr($custom_field_mapping[$twingle_field], strlen('custom_')); - $custom_field = civicrm_api3('CustomField', 'getsingle', array( + $custom_field = civicrm_api3('CustomField', 'getsingle', [ 'id' => $custom_field_id, // Chain a CustomGroup.getsingle API call. - 'api.CustomGroup.getsingle' => array(), - )); + 'api.CustomGroup.getsingle' => [], + ]); $custom_fields[$custom_field['api.CustomGroup.getsingle']['extends']][$custom_field_mapping[$twingle_field]] = $value; } } @@ -329,18 +331,18 @@ function civicrm_api3_twingle_donation_Submit($params) { if ($params['is_anonymous']) { // Retrieve the ID of the contact to use for anonymous donations defined // within the profile - $contact_id = civicrm_api3('Contact', 'getsingle', array( + $contact_id = civicrm_api3('Contact', 'getsingle', [ 'id' => $profile->getAttribute('anonymous_contact_id'), - ))['id']; + ])['id']; } else { // Prepare parameter mapping for address. - foreach (array( - 'user_street' => 'street_address', - 'user_postal_code' => 'postal_code', - 'user_city' => 'city', - 'user_country' => 'country', - ) as $address_param => $address_component) { + foreach ([ + 'user_street' => 'street_address', + 'user_postal_code' => 'postal_code', + 'user_city' => 'city', + 'user_country' => 'country', + ] as $address_param => $address_component) { if (!empty($params[$address_param])) { $params[$address_component] = $params[$address_param]; if ($address_param != $address_component) { @@ -355,11 +357,11 @@ function civicrm_api3_twingle_donation_Submit($params) { foreach ($profile->getAttribute('required_address_components', []) as $required_address_component) { if (empty($params[$required_address_component])) { foreach ([ - 'street_address', - 'postal_code', - 'city', - 'country', - ] as $address_param) { + 'street_address', + 'postal_code', + 'city', + 'country', + ] as $address_param) { unset($params[$address_param]); } break; @@ -383,14 +385,14 @@ function civicrm_api3_twingle_donation_Submit($params) { // Exclude address for now when retrieving/creating the individual contact // as we are checking organisation address first and share it with the // individual. - $submitted_address = array(); - foreach (array( - 'street_address', - 'postal_code', - 'city', - 'country', - 'location_type_id', - ) as $address_component) { + $submitted_address = []; + foreach ([ + 'street_address', + 'postal_code', + 'city', + 'country', + 'location_type_id', + ] as $address_component) { if (!empty($params[$address_component])) { $submitted_address[$address_component] = $params[$address_component]; unset($params[$address_component]); @@ -399,18 +401,18 @@ function civicrm_api3_twingle_donation_Submit($params) { // Get the ID of the contact matching the given contact data, or create a // new contact if none exists for the given contact data. - $contact_data = array(); - foreach (array( - 'user_firstname' => 'first_name', - 'user_lastname' => 'last_name', - 'gender_id' => 'gender_id', - 'user_birthdate' => 'birth_date', - 'user_email' => 'email', - 'user_telephone' => 'phone', - 'user_language' => 'preferred_language', - 'user_title' => 'formal_title', - 'debit_iban' => 'iban', - ) as $contact_param => $contact_component) { + $contact_data = []; + foreach ([ + 'user_firstname' => 'first_name', + 'user_lastname' => 'last_name', + 'gender_id' => 'gender_id', + 'user_birthdate' => 'birth_date', + 'user_email' => 'email', + 'user_telephone' => 'phone', + 'user_language' => 'preferred_language', + 'user_title' => 'formal_title', + 'debit_iban' => 'iban', + ] as $contact_param => $contact_component) { if (!empty($params[$contact_param])) { $contact_data[$contact_component] = $params[$contact_param]; } @@ -434,9 +436,9 @@ function civicrm_api3_twingle_donation_Submit($params) { // Organisation lookup. if (!empty($params['organization_name'])) { - $organisation_data = array( + $organisation_data = [ 'organization_name' => $params['organization_name'], - ); + ]; // Add custom field values. if (!empty($custom_fields['Organization'])) { @@ -478,11 +480,11 @@ function civicrm_api3_twingle_donation_Submit($params) { // Save user_extrafield as contact note. if (!empty($params['user_extrafield'])) { - civicrm_api3('Note', 'create', array( + civicrm_api3('Note', 'create', [ 'entity_table' => 'civicrm_contact', 'entity_id' => $contact_id, 'note' => $params['user_extrafield'], - )); + ]); } // Share organisation address with individual contact, using configured @@ -509,7 +511,10 @@ function civicrm_api3_twingle_donation_Submit($params) { // If usage of double opt-in is selected, use MailingEventSubscribe.create // to add contact to newsletter groups defined in the profile - $result_values['newsletter']['newsletter_double_opt_in'] = ($profile->getAttribute('newsletter_double_opt_in')) ? 'true' : 'false'; + $result_values['newsletter']['newsletter_double_opt_in'] + = ($profile->getAttribute('newsletter_double_opt_in')) + ? 'true' + : 'false'; if ( $profile->getAttribute('newsletter_double_opt_in') && !empty($params['newsletter']) && @@ -519,10 +524,10 @@ function civicrm_api3_twingle_donation_Submit($params) { civicrm_api3( 'GroupContact', 'get', - array( + [ 'sequential' => 1, 'contact_id' => $contact_id, - ) + ] )['values'], 'group_id' ); @@ -530,19 +535,19 @@ function civicrm_api3_twingle_donation_Submit($params) { $is_public_group = civicrm_api3( 'Group', 'getsingle', - array( + [ 'id' => (int) $group_id, - ) + ] )['visibility'] == 'Public Pages'; if (!in_array($group_id, $group_memberships) && $is_public_group) { $result_values['newsletter'][][$group_id] = civicrm_api3( 'MailingEventSubscribe', 'create', - array( + [ 'email' => $params['user_email'], 'group_id' => (int) $group_id, 'contact_id' => $contact_id, - ) + ] ); } elseif ($is_public_group) { @@ -559,10 +564,10 @@ function civicrm_api3_twingle_donation_Submit($params) { civicrm_api3( 'GroupContact', 'create', - array( + [ 'group_id' => $group_id, 'contact_id' => $contact_id, - ) + ] ); $result_values['newsletter'][] = $group_id; @@ -572,10 +577,10 @@ function civicrm_api3_twingle_donation_Submit($params) { // If requested, add contact to postinfo groups defined in the profile. if (!empty($params['postinfo']) && !empty($groups = $profile->getAttribute('postinfo_groups'))) { foreach ($groups as $group_id) { - civicrm_api3('GroupContact', 'create', array( + civicrm_api3('GroupContact', 'create', [ 'group_id' => $group_id, 'contact_id' => $contact_id, - )); + ]); $result_values['postinfo'][] = $group_id; } @@ -585,10 +590,10 @@ function civicrm_api3_twingle_donation_Submit($params) { // profile. if (!empty($params['donation_receipt']) && !empty($groups = $profile->getAttribute('donation_receipt_groups'))) { foreach ($groups as $group_id) { - civicrm_api3('GroupContact', 'create', array( + civicrm_api3('GroupContact', 'create', [ 'group_id' => $group_id, 'contact_id' => $contact_id, - )); + ]); $result_values['donation_receipt'][] = $group_id; } @@ -596,14 +601,14 @@ function civicrm_api3_twingle_donation_Submit($params) { // Create contribution or SEPA mandate. Those attributes are valid for both, // single and recurring contributions. - $contribution_data = array( + $contribution_data = [ 'contact_id' => (isset($organisation_id) ? $organisation_id : $contact_id), 'currency' => $params['currency'], 'trxn_id' => $profile->getTransactionID($params['trx_id']), 'payment_instrument_id' => $params['payment_instrument_id'], 'amount' => $params['amount'] / 100, 'total_amount' => $params['amount'] / 100, - ); + ]; // Add custom field values. if (!empty($custom_fields['Contribution'])) { @@ -628,15 +633,15 @@ function civicrm_api3_twingle_donation_Submit($params) { // If CiviSEPA is installed and the financial type is a CiviSEPA-one, // create SEPA mandate (and recurring contribution, using "createfull" API // action). - foreach (array( + foreach ([ 'debit_iban', 'debit_bic', - ) as $sepa_attribute) { + ] as $sepa_attribute) { if (empty($params[$sepa_attribute])) { throw new CiviCRM_API3_Exception( - E::ts('Missing attribute %1 for SEPA mandate', array( + E::ts('Missing attribute %1 for SEPA mandate', [ 1 => $sepa_attribute, - )), + ]), 'invalid_format' ); } @@ -648,23 +653,25 @@ function civicrm_api3_twingle_donation_Submit($params) { $mandate_data = $contribution_data // ... CiviSEPA mandate attributes, ... - + array( + + [ 'type' => ($params['donation_rhythm'] == 'one_time' ? 'OOFF' : 'RCUR'), 'iban' => $params['debit_iban'], 'bic' => $params['debit_bic'], 'reference' => $params['debit_mandate_reference'], - 'date' => $params['confirmed_at'], // Signature date - 'start_date' => $params['confirmed_at'], // Earliest collection date. + // Signature date + 'date' => $params['confirmed_at'], + // Earliest collection date. + 'start_date' => $params['confirmed_at'], 'creditor_id' => $creditor_id, - ) - // ... and frequency unit and interval from a static mapping. - + CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']); + ] + // ... and frequency unit and interval from a static mapping. + + CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']); // Add custom field values. if (!empty($custom_fields['ContributionRecur'])) { $mandate_data += $custom_fields['ContributionRecur']; } if (!empty($mandate_source = $profile->getAttribute('contribution_source'))) { - $mandate_data['source'] = $mandate_source; + $mandate_data['source'] = $mandate_source; } // Add cycle day for recurring contributions. @@ -714,10 +721,10 @@ function civicrm_api3_twingle_donation_Submit($params) { // Create recurring contribution first. $contribution_recur_data = $contribution_data - + array( + + [ 'contribution_status_id' => 'Pending', 'start_date' => $params['confirmed_at'], - ) + ] + CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']); // Add custom field values. @@ -741,17 +748,17 @@ function civicrm_api3_twingle_donation_Submit($params) { } // Create contribution. - $contribution_data += array( + $contribution_data += [ 'contribution_status_id' => $profile->getAttribute("pi_{$params['payment_method']}_status", CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED), 'receive_date' => $params['confirmed_at'], - ); + ]; // Assign to recurring contribution. if (!empty($params['parent_trx_id'])) { try { - $parent_contribution = civicrm_api3('ContributionRecur', 'getsingle', array( + $parent_contribution = civicrm_api3('ContributionRecur', 'getsingle', [ 'trxn_id' => $profile->getTransactionID($params['parent_trx_id']), - )); + ]); $contribution_data['contribution_recur_id'] = $parent_contribution['id']; } catch (Exception $exception) { @@ -778,15 +785,16 @@ function civicrm_api3_twingle_donation_Submit($params) { if ($params['donation_rhythm'] == 'one_time') { // membership creation based on one-off contributions $membership_type_id = $profile->getAttribute('membership_type_id'); - - } else { + } + else { // membership creation based on recurring contributions if (empty($params['parent_trx_id'])) { // this is the initial payment $membership_type_id = $profile->getAttribute('membership_type_id_recur'); - } else { + } + else { // this is a follow-up recurring payment - $membership_type_id = false; + $membership_type_id = FALSE; } } @@ -800,7 +808,7 @@ function civicrm_api3_twingle_donation_Submit($params) { CRM_Twingle_Submission::setCampaign($membership_data, 'membership', $params, $profile); // set source if (!empty($membership_source = $profile->getAttribute('contribution_source'))) { - $membership_data['source'] = $membership_source; + $membership_data['source'] = $membership_source; } $membership = civicrm_api3('Membership', 'create', $membership_data); @@ -809,13 +817,14 @@ function civicrm_api3_twingle_donation_Submit($params) { // call the postprocess API $postprocess_call = $profile->getAttribute('membership_postprocess_call'); if (!empty($postprocess_call)) { - list($pp_entity, $pp_action) = explode('.', $postprocess_call, 2); + [$pp_entity, $pp_action] = explode('.', $postprocess_call, 2); try { // gather the contribution IDs $recurring_contribution_id = $contribution_id = ''; if (isset($contribution_recur['id'])) { $recurring_contribution_id = $contribution_recur['id']; - } elseif (!empty($result_values['sepa_mandate'])) { + } + elseif (!empty($result_values['sepa_mandate'])) { $mandate = reset($result_values['sepa_mandate']); if ($mandate['entity_table'] == 'civicrm_contribution_recur') { $recurring_contribution_id = (int) $mandate['entity_id']; @@ -827,21 +836,24 @@ function civicrm_api3_twingle_donation_Submit($params) { // run the call civicrm_api3(trim($pp_entity), trim($pp_action), [ - 'membership_id' => $membership['id'], - 'contact_id' => $contact_id, - 'organization_id' => isset($organisation_id) ? $organisation_id : '', - 'contribution_id' => $contribution_id, - 'recurring_contribution_id' => $recurring_contribution_id, + 'membership_id' => $membership['id'], + 'contact_id' => $contact_id, + 'organization_id' => isset($organisation_id) ? $organisation_id : '', + 'contribution_id' => $contribution_id, + 'recurring_contribution_id' => $recurring_contribution_id, ]); // refresh membership data $result_values['membership'] = civicrm_api3('Membership', 'getsingle', ['id' => $membership['id']]); - - } catch (CiviCRM_API3_Exception $ex) { + } + catch (CiviCRM_API3_Exception $ex) { // TODO: more error handling? - Civi::log()->warning("Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()); + Civi::log() + ->warning( + "Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage() + ); throw new Exception( - E::ts("Twingle membership postprocessing call has failed, see log for more information") + E::ts('Twingle membership postprocessing call has failed, see log for more information') ); } } From 7a751e92bf7edc82c9457379e8cd0c7727b8e461 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 15:44:43 +0100 Subject: [PATCH 119/221] phpcs: Conflicts with PHPStan type hints --- phpcs.xml.dist | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index ce14b44..07d420f 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -19,6 +19,11 @@ + + + + + From 43be624bf6704e00075dbe45aab47118ccf4cdcf Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 14:52:30 +0200 Subject: [PATCH 120/221] create custom exceptions --- CRM/Twingle/Exceptions/BaseException.php | 43 +++++++++++++++++++ CRM/Twingle/Exceptions/ProfileException.php | 16 +++++++ .../Exceptions/ProfileValidationError.php | 34 +++++++++++++++ CRM/Twingle/Form/Profile.php | 40 +++++++++++------ CRM/Twingle/Profile.php | 10 ++++- 5 files changed, 127 insertions(+), 16 deletions(-) create mode 100644 CRM/Twingle/Exceptions/BaseException.php create mode 100644 CRM/Twingle/Exceptions/ProfileException.php create mode 100644 CRM/Twingle/Exceptions/ProfileValidationError.php diff --git a/CRM/Twingle/Exceptions/BaseException.php b/CRM/Twingle/Exceptions/BaseException.php new file mode 100644 index 0000000..f61a4fe --- /dev/null +++ b/CRM/Twingle/Exceptions/BaseException.php @@ -0,0 +1,43 @@ +log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : ''; + $this->error_code = $error_code; + } + + /** + * Returns the error message, but with the extension name prefixed. + * @return string + */ + public function getLogMessage() { + return $this->log_message; + } + + /** + * Returns the error code. + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } + +} diff --git a/CRM/Twingle/Exceptions/ProfileException.php b/CRM/Twingle/Exceptions/ProfileException.php new file mode 100644 index 0000000..1141d10 --- /dev/null +++ b/CRM/Twingle/Exceptions/ProfileException.php @@ -0,0 +1,16 @@ +affected_field_name = $affected_field_name; + } + + /** + * Returns the name of the profile field that caused the exception. + * @return string + */ + public function getAffectedFieldName() { + return $this->affected_field_name; + } + +} diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index c4a556b..3bc43e0 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -16,6 +16,8 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; +use CRM_Twingle_Exceptions_ProfileException as ProfileException; +use CRM_Twingle_Exceptions_ProfileValidationError as ProfileValidationError; /** * Form controller class @@ -633,23 +635,33 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ public function postProcess() { $values = $this->exportValues(); - if (in_array($this->_op, ['create', 'edit', 'copy'])) { - if (empty($values['name'])) { - $values['name'] = 'default'; - } - $this->profile->setName($values['name']); - foreach ($this->profile->getData() as $element_name => $value) { - if ($element_name == 'newsletter_double_opt_in') { - $values[$element_name] = (int) isset($values[$element_name]); + try { + if (in_array($this->_op, ['create', 'edit', 'copy'])) { + if (empty($values['name'])) { + $values['name'] = 'default'; } - if (isset($values[$element_name])) { - $this->profile->setAttribute($element_name, $values[$element_name]); + $this->profile->setName($values['name']); + foreach ($this->profile->getData() as $element_name => $value) { + if ($element_name == 'newsletter_double_opt_in') { + $values[$element_name] = (int) isset($values[$element_name]); + } + if (isset($values[$element_name])) { + $this->profile->setAttribute($element_name, $values[$element_name]); + } } + $this->profile->saveProfile(); } - $this->profile->saveProfile(); - } - elseif ($this->_op == 'delete') { - $this->profile->deleteProfile(); + elseif ($this->_op == 'delete') { + $this->profile->deleteProfile(); + } + } catch (ProfileException $e) { + Civi::log()->error($e->getLogMessage()); + CRM_Core_Session::setStatus( + E::ts('Error'), + $e->getMessage(), + 'error', + ['unique' => TRUE] + ); } parent::postProcess(); } diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index d85c9f3..437d4af 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -16,6 +16,8 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; +use CRM_Twingle_Exceptions_ProfileException as ProfileException; +use CRM_Twingle_Exceptions_ProfileValidationError as ProfileValidationError; /** * Profiles define how incoming submissions from the Twingle API are @@ -142,12 +144,15 @@ class CRM_Twingle_Profile { * @param string $attribute_name * @param mixed $value * - * @throws \Exception + * @throws \CRM_Twingle_Exceptions_ProfileException * When the attribute name is not known. */ public function setAttribute($attribute_name, $value) { if (!in_array($attribute_name, self::allowedAttributes())) { - throw new Exception(E::ts('Unknown attribute %1.', [1 => $attribute_name])); + throw new ProfileException( + E::ts('Unknown attribute %1.', [1 => $attribute_name]), + ProfileException::ERROR_CODE_UNKNOWN_PROFILE_ATTRIBUTE + ); } // TODO: Check if value is acceptable. $this->data[$attribute_name] = $value; @@ -430,6 +435,7 @@ class CRM_Twingle_Profile { * Get the stats (access_count, last_access) for all twingle profiles * * @return CRM_Twingle_Profile[] + * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfileStats() { $stats = []; From 27675b7219064497052be15e76650ea714beab80 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 16 Aug 2023 14:03:44 +0200 Subject: [PATCH 121/221] use new namespace style --- CRM/Twingle/Exceptions/BaseException.php | 4 +++- CRM/Twingle/Exceptions/ProfileException.php | 4 +++- CRM/Twingle/Exceptions/ProfileValidationError.php | 4 +++- CRM/Twingle/Form/Profile.php | 4 ++-- CRM/Twingle/Profile.php | 4 ++-- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CRM/Twingle/Exceptions/BaseException.php b/CRM/Twingle/Exceptions/BaseException.php index f61a4fe..eeb5354 100644 --- a/CRM/Twingle/Exceptions/BaseException.php +++ b/CRM/Twingle/Exceptions/BaseException.php @@ -1,12 +1,14 @@ Date: Wed, 16 Aug 2023 17:02:48 +0200 Subject: [PATCH 122/221] override the $code property inherited from Exception in BaseException --- CRM/Twingle/Exceptions/BaseException.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CRM/Twingle/Exceptions/BaseException.php b/CRM/Twingle/Exceptions/BaseException.php index eeb5354..cebf692 100644 --- a/CRM/Twingle/Exceptions/BaseException.php +++ b/CRM/Twingle/Exceptions/BaseException.php @@ -10,8 +10,11 @@ use CRM_Twingle_ExtensionUtil as E; */ class BaseException extends \Exception { - private string $error_code; - private string $log_message; + /** + * @var int|string + */ + protected $code; + protected string $log_message; /** * BaseException Constructor @@ -23,7 +26,7 @@ class BaseException extends \Exception { public function __construct(string $message = '', string $error_code = '') { parent::__construct($message, 1); $this->log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : ''; - $this->error_code = $error_code; + $this->code = $error_code; } /** @@ -39,7 +42,7 @@ class BaseException extends \Exception { * @return string */ public function getErrorCode() { - return $this->error_code; + return $this->code; } } From e83a898cb8f1445b927f47eb32d5118c9c1cbe6f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 17 Aug 2023 10:29:00 +0200 Subject: [PATCH 123/221] add error code for profile validation warning --- CRM/Twingle/Exceptions/ProfileValidationError.php | 1 + 1 file changed, 1 insertion(+) diff --git a/CRM/Twingle/Exceptions/ProfileValidationError.php b/CRM/Twingle/Exceptions/ProfileValidationError.php index e00c6c2..97a50ab 100644 --- a/CRM/Twingle/Exceptions/ProfileValidationError.php +++ b/CRM/Twingle/Exceptions/ProfileValidationError.php @@ -10,6 +10,7 @@ class ProfileValidationError extends BaseException { private string $affected_field_name; public const ERROR_CODE_PROFILE_VALIDATION_FAILED = 'profile_validation_failed'; + public const ERROR_CODE_PROFILE_VALIDATION_WARNING = 'profile_validation_warning'; /** * ProfileValidationError Constructor From 187586173548ba48aeb94e59b2a3157373e9f751 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 17 Aug 2023 12:51:28 +0200 Subject: [PATCH 124/221] pass $error_code to parent BaseException --- CRM/Twingle/Exceptions/ProfileValidationError.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Exceptions/ProfileValidationError.php b/CRM/Twingle/Exceptions/ProfileValidationError.php index 97a50ab..b7a8f52 100644 --- a/CRM/Twingle/Exceptions/ProfileValidationError.php +++ b/CRM/Twingle/Exceptions/ProfileValidationError.php @@ -22,7 +22,7 @@ class ProfileValidationError extends BaseException { * A meaningful error code */ public function __construct(string $affected_field_name, string $message = '', string $error_code = '') { - parent::__construct($message, 1); + parent::__construct($message, $error_code); $this->affected_field_name = $affected_field_name; } From b0d5bdefa5463bb9da860fff511394847be0b618 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Mon, 16 Oct 2023 15:00:47 +0200 Subject: [PATCH 125/221] use correct namespace --- CRM/Twingle/Form/Profile.php | 5 ++--- CRM/Twingle/Profile.php | 3 +-- {CRM/Twingle => Civi}/Exceptions/BaseException.php | 2 +- {CRM/Twingle => Civi}/Exceptions/ProfileException.php | 2 +- {CRM/Twingle => Civi}/Exceptions/ProfileValidationError.php | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) rename {CRM/Twingle => Civi}/Exceptions/BaseException.php (96%) rename {CRM/Twingle => Civi}/Exceptions/ProfileException.php (94%) rename {CRM/Twingle => Civi}/Exceptions/ProfileValidationError.php (96%) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 243af97..6d545fe 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -16,8 +16,7 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; -use CRM\Twingle\Exceptions\ProfileException as ProfileException; -use CRM\Twingle\Exceptions\ProfileValidationError as ProfileValidationError; +use Civi\Twingle\Exceptions\ProfileException as ProfileException; /** * Form controller class @@ -560,7 +559,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { E::ts('Could not parse custom field mapping.') ); } - list($twingle_field_name, $custom_field_name) = $custom_field_map; + [$twingle_field_name, $custom_field_name] = $custom_field_map; $custom_field_id = substr($custom_field_name, strlen('custom_')); // Check for custom field existence diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index aeeb880..9fd6dd1 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -16,8 +16,7 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; -use CRM\Twingle\Exceptions\ProfileException as ProfileException; -use CRM\Twingle\Exceptions\ProfileValidationError as ProfileValidationError; +use Civi\Twingle\Exceptions\ProfileException as ProfileException; /** * Profiles define how incoming submissions from the Twingle API are diff --git a/CRM/Twingle/Exceptions/BaseException.php b/Civi/Exceptions/BaseException.php similarity index 96% rename from CRM/Twingle/Exceptions/BaseException.php rename to Civi/Exceptions/BaseException.php index cebf692..57e4660 100644 --- a/CRM/Twingle/Exceptions/BaseException.php +++ b/Civi/Exceptions/BaseException.php @@ -1,6 +1,6 @@ Date: Mon, 25 Mar 2024 14:33:52 +0100 Subject: [PATCH 126/221] Move exception class files into correct directory according to namespace --- Civi/{ => Twingle}/Exceptions/BaseException.php | 0 Civi/{ => Twingle}/Exceptions/ProfileException.php | 0 Civi/{ => Twingle}/Exceptions/ProfileValidationError.php | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename Civi/{ => Twingle}/Exceptions/BaseException.php (100%) rename Civi/{ => Twingle}/Exceptions/ProfileException.php (100%) rename Civi/{ => Twingle}/Exceptions/ProfileValidationError.php (100%) diff --git a/Civi/Exceptions/BaseException.php b/Civi/Twingle/Exceptions/BaseException.php similarity index 100% rename from Civi/Exceptions/BaseException.php rename to Civi/Twingle/Exceptions/BaseException.php diff --git a/Civi/Exceptions/ProfileException.php b/Civi/Twingle/Exceptions/ProfileException.php similarity index 100% rename from Civi/Exceptions/ProfileException.php rename to Civi/Twingle/Exceptions/ProfileException.php diff --git a/Civi/Exceptions/ProfileValidationError.php b/Civi/Twingle/Exceptions/ProfileValidationError.php similarity index 100% rename from Civi/Exceptions/ProfileValidationError.php rename to Civi/Twingle/Exceptions/ProfileValidationError.php From 53745a3e076a24005c46a42f27903f5d4af990d5 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 15:49:01 +0100 Subject: [PATCH 127/221] PHP Code Sniffer fixes --- CRM/Twingle/Form/Profile.php | 3 ++- Civi/Twingle/Exceptions/BaseException.php | 17 +++++++++++++++++ Civi/Twingle/Exceptions/ProfileException.php | 17 +++++++++++++++++ .../Exceptions/ProfileValidationError.php | 17 +++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 6d545fe..efffdce 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -653,7 +653,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { elseif ($this->_op == 'delete') { $this->profile->deleteProfile(); } - } catch (ProfileException $e) { + } + catch (ProfileException $e) { Civi::log()->error($e->getLogMessage()); CRM_Core_Session::setStatus( E::ts('Error'), diff --git a/Civi/Twingle/Exceptions/BaseException.php b/Civi/Twingle/Exceptions/BaseException.php index 57e4660..f1ce9e3 100644 --- a/Civi/Twingle/Exceptions/BaseException.php +++ b/Civi/Twingle/Exceptions/BaseException.php @@ -1,4 +1,21 @@ . + */ + +declare(strict_types = 1); namespace Civi\Twingle\Exceptions; diff --git a/Civi/Twingle/Exceptions/ProfileException.php b/Civi/Twingle/Exceptions/ProfileException.php index b9e5954..7581381 100644 --- a/Civi/Twingle/Exceptions/ProfileException.php +++ b/Civi/Twingle/Exceptions/ProfileException.php @@ -1,4 +1,21 @@ . + */ + +declare(strict_types = 1); namespace Civi\Twingle\Exceptions; diff --git a/Civi/Twingle/Exceptions/ProfileValidationError.php b/Civi/Twingle/Exceptions/ProfileValidationError.php index a678ba7..da29705 100644 --- a/Civi/Twingle/Exceptions/ProfileValidationError.php +++ b/Civi/Twingle/Exceptions/ProfileValidationError.php @@ -1,4 +1,21 @@ . + */ + +declare(strict_types = 1); namespace Civi\Twingle\Exceptions; From fe0ce3f57db11367f08630e257413a1cab5a004e Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Mon, 25 Mar 2024 15:51:58 +0100 Subject: [PATCH 128/221] Fix @throws tag with wrong class name --- CRM/Twingle/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 9fd6dd1..a78f576 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -143,7 +143,7 @@ class CRM_Twingle_Profile { * @param string $attribute_name * @param mixed $value * - * @throws \CRM_Twingle_Exceptions_ProfileException + * @throws \Civi\Twingle\Exceptions\ProfileException * When the attribute name is not known. */ public function setAttribute($attribute_name, $value) { From d9e51c67f6f50aa8a3825bb9496e4e4fd04ee70c Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 3 Aug 2023 15:06:27 +0200 Subject: [PATCH 129/221] use the id instead of the name to look up profiles --- CRM/Twingle/Form/Profile.php | 54 ++++---- CRM/Twingle/Page/Profiles.php | 7 +- CRM/Twingle/Profile.php | 164 +++++++++++++++++------- templates/CRM/Twingle/Page/Profiles.tpl | 9 +- 4 files changed, 157 insertions(+), 77 deletions(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index efffdce..d7fe333 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -32,6 +32,12 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { */ protected $profile; + /** + * The ID of this profile. + * @var int|NULL + */ + protected $profile_id = NULL; + /** * @var string * @@ -142,10 +148,11 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { $this->_op = 'create'; } - // Verify that a profile with the given name exists. - $profile_name = CRM_Utils_Request::retrieve('name', 'String', $this); - if (!$this->profile = CRM_Twingle_Profile::getProfile($profile_name)) { - $profile_name = NULL; + // Verify that a profile with the given id exists. + + if ($this->_op != 'copy') { + $this->profile_id = CRM_Utils_Request::retrieve('id', 'Int', $this); + $this->profile = CRM_Twingle_Profile::getProfile($this->profile_id); } // Set redirect destination. @@ -153,12 +160,12 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { switch ($this->_op) { case 'delete': - if ($profile_name) { - CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', [1 => $profile_name])); + if ($this->profile_id) { + CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', [1 => $this->profile->getName()])); $this->addButtons([ [ 'type' => 'submit', - 'name' => ($profile_name == 'default' ? E::ts('Reset') : E::ts('Delete')), + 'name' => ($this->profile->getName() == 'default' ? E::ts('Reset') : E::ts('Delete')), 'isDefault' => TRUE, ], ]); @@ -166,40 +173,37 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { parent::buildQuickForm(); return; - case 'edit': - // When editing without a valid profile name, edit the default profile. - if (!$profile_name) { - $profile_name = 'default'; - $this->profile = CRM_Twingle_Profile::getProfile($profile_name); - } - CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', [1 => $this->profile->getName()])); - break; - case 'copy': // Retrieve the source profile name. - $profile_name = CRM_Utils_Request::retrieve('source_name', 'String', $this); - // When copying without a valid profile name, copy the default profile. - if (!$profile_name) { - $profile_name = 'default'; + $source_id = CRM_Utils_Request::retrieve('source_id', 'Int', $this); + // When copying without a valid profile id, copy the default profile. + if (!$source_id) { + $this->profile = CRM_Twingle_Profile::createDefaultProfile(); + } else { + $source_profile = CRM_Twingle_Profile::getProfile($source_id); + $this->profile = $source_profile->copy(); } - $this->profile = clone CRM_Twingle_Profile::getProfile($profile_name); - // Propose a new name for this profile. - $profile_name = $profile_name . '_copy'; + $profile_name = $this->profile->getName() . '_copy'; $this->profile->setName($profile_name); CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); break; + case 'edit': + CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', [1 => $this->profile->getName()])); + break; + case 'create': // Load factory default profile values. - $this->profile = CRM_Twingle_Profile::createDefaultProfile($profile_name); + $this->profile = CRM_Twingle_Profile::createDefaultProfile(E::ts('New Profile')); CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); break; } // Assign template variables. $this->assign('op', $this->_op); - $this->assign('profile_name', $profile_name); + $this->assign('profile_name', $this->profile->getName()); + $this->assign('is_default', $this->profile->is_default()); // Add form elements. $is_default = $profile_name == 'default'; diff --git a/CRM/Twingle/Page/Profiles.php b/CRM/Twingle/Page/Profiles.php index e8f014b..919965d 100644 --- a/CRM/Twingle/Page/Profiles.php +++ b/CRM/Twingle/Page/Profiles.php @@ -22,10 +22,11 @@ class CRM_Twingle_Page_Profiles extends CRM_Core_Page { public function run() { CRM_Utils_System::setTitle(E::ts('Twingle API Profiles')); $profiles = []; - foreach (CRM_Twingle_Profile::getProfiles() as $profile_name => $profile) { - $profiles[$profile_name]['name'] = $profile_name; + foreach (CRM_Twingle_Profile::getProfiles() as $profile_id => $profile) { + $profiles[$profile_id]['id'] = $profile_id; + $profiles[$profile_id]['name'] = $profile->getName(); foreach (CRM_Twingle_Profile::allowedAttributes() as $attribute) { - $profiles[$profile_name][$attribute] = $profile->getAttribute($attribute); + $profiles[$profile_id][$attribute] = $profile->getAttribute($attribute); } } $this->assign('profiles', $profiles); diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index a78f576..ae62782 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -25,7 +25,13 @@ use Civi\Twingle\Exceptions\ProfileException as ProfileException; class CRM_Twingle_Profile { /** - * @var string + * @var int $id + * The id of the profile. + */ + protected $id = NULL; + + /** + * @var string $name * The name of the profile. */ protected $name = NULL; @@ -43,8 +49,10 @@ class CRM_Twingle_Profile { * The name of the profile. * @param array $data * The properties of the profile + * @param int|NULL $id */ - public function __construct($name, $data) { + public function __construct($name, $data, $id = NULL) { + $this->id = $id; $this->name = $name; $allowed_attributes = self::allowedAttributes(); $this->data = $data + array_combine( @@ -65,6 +73,18 @@ class CRM_Twingle_Profile { WHERE name = %1', [1 => [$this->name, 'String']]); } + /** + * Copy this profile by returning a clone with all unique information removed. + * + * @return CRM_Twingle_Profile + */ + public function copy() { + $copy = clone $this; + $copy->id = NULL; + $copy->data['selector'] = NULL; + return $copy; + } + /** * Checks whether the profile's selector matches the given project ID. * @@ -107,6 +127,24 @@ class CRM_Twingle_Profile { return $this->data; } + /** + * Retrieves the profile id. + * + * @return int + */ + public function getId() { + return $this->id; + } + + /** + * Set the profile id. + * + * @param int $id + */ + public function setId(int $id) { + $this->id = $id; + } + /** * Retrieves the profile name. * @@ -119,9 +157,9 @@ class CRM_Twingle_Profile { /** * Sets the profile name. * - * @param $name + * @param string $name */ - public function setName($name) { + public function setName(string $name) { $this->name = $name; } @@ -193,37 +231,76 @@ class CRM_Twingle_Profile { // make sure it's valid $this->verifyProfile(); - // check if the profile exists - $profile_id = CRM_Core_DAO::singleValueQuery( - 'SELECT id FROM civicrm_twingle_profile WHERE name = %1', [1 => [$this->name, 'String']]); - if ($profile_id) { - // existing profile -> just update the config - CRM_Core_DAO::executeQuery( - 'UPDATE civicrm_twingle_profile SET config = %2 WHERE name = %1', - [ - 1 => [$this->name, 'String'], - 2 => [json_encode($this->data), 'String'], - ]); + try { + if ($this->id !== NULL) { + // existing profile -> just update the config + CRM_Core_DAO::executeQuery( + "UPDATE civicrm_twingle_profile SET config = %2 WHERE id = %1", + [ + 1 => [$this->id, 'String'], + 2 => [json_encode($this->data), 'String'], + ]); + } + else { + // new profile -> add new entry to the DB + CRM_Core_DAO::executeQuery( + "INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)", + [ + 1 => [$this->name, 'String'], + 2 => [json_encode($this->data), 'String'], + ]); + } } - else { - // new profile -> add new entry to the DB - CRM_Core_DAO::executeQuery( - 'INSERT IGNORE INTO civicrm_twingle_profile(name,config,last_access,access_counter) VALUES (%1, %2, null, 0)', - [ - 1 => [$this->name, 'String'], - 2 => [json_encode($this->data), 'String'], - ]); + catch (Exception $e) { + throw new ProfileException( + E::ts("Could not save/update profile: %1", [1 => $e->getMessage()]), + ProfileException::ERROR_CODE_COULD_NOT_SAVE_PROFILE + ); } } /** * Deletes the profile from the database + * + * @throws \CRM_Twingle_Exceptions_ProfileException */ public function deleteProfile() { - CRM_Core_DAO::executeQuery( - 'DELETE FROM civicrm_twingle_profile WHERE name = %1', - [1 => [$this->name, 'String']] - ); + // Do only reset default profile + if ($this->getName() == 'default') { + try { + $default_profile = CRM_Twingle_Profile::createDefaultProfile(); + $default_profile->setId($this->getId()); + $default_profile->saveProfile(); + + // Reset counter + CRM_Core_DAO::executeQuery("UPDATE civicrm_twingle_profile SET access_counter = 0, last_access = NULL WHERE id = %1", [ + 1 => [ + $this->id, + 'Integer' + ] + ]); + } catch (Exception $e) { + throw new ProfileException( + E::ts("Could not reset default profile: %1", [1 => $e->getMessage()]), + ProfileException::ERROR_CODE_COULD_NOT_RESET_PROFILE + ); + } + } + else { + try { + CRM_Core_DAO::executeQuery("DELETE FROM civicrm_twingle_profile WHERE id = %1", [ + 1 => [ + $this->id, + 'Integer' + ] + ]); + } catch (Exception $e) { + throw new ProfileException( + E::ts("Could not delete profile: %1", [1 => $e->getMessage()]), + ProfileException::ERROR_CODE_COULD_NOT_RESET_PROFILE + ); + } + } } /** @@ -305,9 +382,9 @@ class CRM_Twingle_Profile { */ public static function createDefaultProfile($name = 'default') { return new CRM_Twingle_Profile($name, [ - 'selector' => '', - 'xcm_profile' => '', - 'location_type_id' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, + 'selector' => NULL, + 'xcm_profile' => '', + 'location_type_id' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, 'location_type_id_organisation' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, // "Donation" 'financial_type_id' => 1, @@ -391,20 +468,19 @@ class CRM_Twingle_Profile { } /** - * Retrieves the profile with the given name. + * Retrieves the profile with the given ID. * - * @param string $name + * @param int|NULL $id * * @return CRM_Twingle_Profile | NULL + * @throws \Civi\Core\Exception\DBQueryException */ - public static function getProfile($name) { - if (!empty($name)) { - $profile_data = CRM_Core_DAO::singleValueQuery( - 'SELECT config FROM civicrm_twingle_profile WHERE name = %1', - [1 => [$name, 'String']] - ); - if ($profile_data) { - return new CRM_Twingle_Profile($name, json_decode($profile_data, 1)); + public static function getProfile(int $id = NULL) { + if (!empty($id)) { + $profile_data = CRM_Core_DAO::executeQuery("SELECT id, name, config FROM civicrm_twingle_profile WHERE id = %1", + [1 => [$id, 'Integer']]); + if ($profile_data->fetch()) { + return new CRM_Twingle_Profile($profile_data->name, json_decode($profile_data->config, 1), (int) $profile_data->id); } } return NULL; @@ -416,16 +492,14 @@ class CRM_Twingle_Profile { * * @return array * profile_name => CRM_Twingle_Profile + * @throws \Civi\Core\Exception\DBQueryException */ public static function getProfiles() { // todo: cache? $profiles = []; - $profile_data = CRM_Core_DAO::executeQuery('SELECT name, config FROM civicrm_twingle_profile'); + $profile_data = CRM_Core_DAO::executeQuery("SELECT id, name, config FROM civicrm_twingle_profile"); while ($profile_data->fetch()) { - $profiles[$profile_data->name] = new CRM_Twingle_Profile( - $profile_data->name, - json_decode($profile_data->config, 1) - ); + $profiles[$profile_data->id] = new CRM_Twingle_Profile($profile_data->name, json_decode($profile_data->config, 1), (int) $profile_data->id); } return $profiles; } diff --git a/templates/CRM/Twingle/Page/Profiles.tpl b/templates/CRM/Twingle/Page/Profiles.tpl index b5b869e..cf3351e 100644 --- a/templates/CRM/Twingle/Page/Profiles.tpl +++ b/templates/CRM/Twingle/Page/Profiles.tpl @@ -33,6 +33,7 @@
    {$profile.name}{ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.access_counter_txt}{/ts} {ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.last_access_txt}{/ts} - {ts domain="de.systopia.twingle"}Edit{/ts} - {ts domain="de.systopia.twingle"}Copy{/ts} + {ts domain="de.systopia.twingle"}Edit{/ts} + {ts domain="de.systopia.twingle"}Copy{/ts} {if $profile_name == 'default'} - {ts domain="de.systopia.twingle"}Reset{/ts} + {ts domain="de.systopia.twingle"}Reset{/ts} {else} - {ts domain="de.systopia.twingle"}Delete{/ts} + {ts domain="de.systopia.twingle"}Delete{/ts} {/if} {$form.contribution_source.html}
    + {$form.map_as_contribution_notes.label} + + {$form.map_as_contribution_notes.html}
    + {$form.map_as_contact_notes.label} + + {$form.map_as_contact_notes.html}
    {$form.custom_field_mapping.label} From df51d59ceaad75e8bbb6d435496e1b7a2fd96303 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 26 Apr 2024 18:19:54 +0200 Subject: [PATCH 154/221] add logic to create selected contact and contribution notes --- api/v3/TwingleDonation/Submit.php | 48 ++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index ecaeac8..2466575 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -255,6 +255,13 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { 'api.required' => 0, 'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'), ]; + $params['remarks'] = [ + 'name' => 'remarks', + 'title' => E::ts('Remarks'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('Additional remarks for the donation.'), + ]; } /** @@ -477,13 +484,20 @@ function civicrm_api3_twingle_donation_Submit($params) { ); } - // Save user_extrafield as contact note. - if (isset($params['user_extrafield']) && '' != $params['user_extrafield']) { - civicrm_api3('Note', 'create', [ - 'entity_table' => 'civicrm_contact', - 'entity_id' => $contact_id, - 'note' => $params['user_extrafield'], - ]); + // Create contact notes. + $contact_note_mappings = $profile->getAttribute('map_as_contact_notes', []); + foreach (['user_extrafield'] as $target) { + if ( + isset($params[$target]) + && '' != $params[$target] + && in_array($target, $contact_note_mappings) + ) { + civicrm_api3('Note', 'create', [ + 'entity_table' => 'civicrm_contact', + 'entity_id' => $contact_id, + 'note' => $params[$target], + ]); + } } // Share organisation address with individual contact, using configured @@ -620,10 +634,6 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution_data += $custom_fields['Contribution']; } - if (isset($params['purpose'])) { - $contribution_data['note'] = $params['purpose']; - } - // set campaign, subject to configuration CRM_Twingle_Submission::setCampaign($contribution_data, 'contribution', $params, $profile); @@ -794,6 +804,22 @@ function civicrm_api3_twingle_donation_Submit($params) { $result_values['contribution'] = $contribution['values']; } + // Add notes to the contribution. + $contribution_note_mappings = $profile->getAttribute("map_as_contribution_notes"); + foreach (['purpose', 'remarks'] as $target) { + if ( + in_array($target, $contribution_note_mappings) + && isset($params[$target]) + && '' != $params[$target] + ) { + civicrm_api3('Note', 'create', [ + 'entity_table' => 'civicrm_contribution', + 'entity_id' => CRM_Utils_Array::first($result_values['contribution'])['id'], + 'note' => $params[$target], + ]); + } + } + // MEMBERSHIP CREATION // CHECK whether a membership should be created (based on profile settings and data provided) From b3f82fbfba2d650128722300ebc0be22221d402f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 30 Apr 2024 16:51:39 +0200 Subject: [PATCH 155/221] add Upgrader to maintain profile behaviour --- CRM/Twingle/Upgrader.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 2af4667..4d00514 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -102,4 +102,40 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { return TRUE; } + /** + * Upgrade to 1.5.0 + * + * - Activate mapping of `purpose` and `user_extra_field` to notes in each existing profile to + * maintain default behavior after making the fields optional. + * + * @return bool + * @throws \Civi\Core\Exception\DBQueryException + * @throws \Civi\Twingle\Exceptions\ProfileException + */ + public function upgrade_5150(): bool { + $this->ctx->log->info('Activate mapping of `purpose` and `user_extra_field` to notes in each existing profile.'); + + $profiles = CRM_Twingle_Profile::getProfiles(); + if ($profiles) { + foreach ($profiles as $profile) { + $profile_changed = FALSE; + $contribution_notes = $profile->getAttribute('map_as_contribution_notes', []); + $contact_notes = $profile->getAttribute('map_as_contact_notes', []); + if (!in_array('purpose', $contribution_notes)) { + $profile->setAttribute('map_as_contribution_notes', array_merge($contribution_notes, ['purpose'])); + $profile_changed = TRUE; + } + if (!in_array('user_extrafield', $contact_notes)) { + $profile->setAttribute('map_as_contact_notes', array_merge($contact_notes, ['user_extrafield'])); + $profile_changed = TRUE; + } + if ($profile_changed) { + $profile->saveProfile(); + } + } + } + + return TRUE; + } + } From 63b7e4d3eed502569bef8c437168210e347f051c Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 30 Apr 2024 15:43:44 +0200 Subject: [PATCH 156/221] add German translations --- l10n/de_DE/LC_MESSAGES/twingle.mo | Bin 6167 -> 7350 bytes l10n/de_DE/LC_MESSAGES/twingle.po | 36 ++++++++++++++++++++++++++++++ l10n/pot/twingle.pot | 36 ++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/l10n/de_DE/LC_MESSAGES/twingle.mo b/l10n/de_DE/LC_MESSAGES/twingle.mo index eff6c7e6ef72276b0d8a65e60300db9c0c5cd6fc..9fd805479ba6759289b95892b87803fec1e57720 100644 GIT binary patch delta 2813 zcmcK4TWl0n9LMofD4@{N+F}7gI4F3*mP?J%9qlprufd@2xf3sVqMI#CEq-Q^8W@pa) z=l}n2Uz>M)Y5Yw^@gc)l$DGPMIKr52EE&ZIgxE{-RzR9r|&xzeQ7Z2iWJckPCXM7MR@w9SW ziJUSUQ4e|!wXwtbxD9pxk%FJ20{I22aWYZrg_^OH=bPtQEXH1(g>T~o`~sDM?~r@V zRlEy}$!{x8M+Fk1Qojoo(1*ARPoOe$4Y}2n@Rs-BWF+aP9%F6X#6lZwK+0;iqHahR zj<=)Q;YCyiVywhhQE&bhYQuL69>aS%K7}gPw>S-d$2)NaVSjt^15(>hP*D9{q_)^!tc5zat0;WMcH_M-xN16BL?P^J6?6~HBIz-yJ{ zU$t3AzUN^(T0DSiwvSMee~HuaGS0wqc2VYPu?ibdUEPLya2MW>+mUCP!>GVNK=slI zWGizqWPy#?6v?mpqgnn*5b#gruhN2(MTFYr5cYaO%*Ik=q3Pd*v?)o7?xYnWTMTcW!Vf_%QH`Li0 z>W>v#437G~hE<{Svd(%ol?k$5Dr2VNfYQt_1axv(!2In(M=nJ{f<&9`2}L9Z8fA1E$4U)~nE&^Eo0 z4L#ee;thONQa2)AIHz{36513-S=U2JoF6#bqMCPSYu0A6{!ZI*_H<~sxwMOHGdEV- zw3pNARXLK{s$F~;#tw!HCP*L_yQ9LBuu26{}$-5a+ z3UV>*>lT=~u W7v!=#U09QJQjPjy;9Av`qCWwjum7q5 delta 1624 zcmYk+Ur3Wt7{~E5o0>YE|E;O@W@&1soBwi|x=c+d3QTuq9%@EyFQFZP2i8(iAv-gmfz;L2c9~T+e+w>a2Qj4Gv)zPN61vgiH7W*|d4i_Uj$Syh0_AMz(rC z4{Naq)jJ1KiHy0azZRb44V~#-EXK#Eg+5~=I{0suJb+$2iWZKecKiUd@hPg=W>NEg z#f|t4m9WJkN~{`7uqloD>ukDtLuYpici}MV2;QI%UCdgEji|FeftqLt={qxuD)Cip z!t3b8xu}_}UdDYZR$?EjqBp`^uu1a-1Nah^aTZx=p@yjYkSd#A)E5Uah!dy^EMP1C zK=n+3@^#=&Wbbbvw>YaP2jm#jqnR#^6BfpV(!X}wdxwo?dyF9X)PzkjgJS|A!XQSV!pT z(5N6*5ZbYa&`?$W4Lz3pzL`yglGXb5XjsPHxh|ElcCDc@`3VxXcMf)Q$|_ng$)ktc}YC=u8 znow!g7aErRx_m6U+)U^wG}N301bt~gSuUNSMj;Vdia+g$d`cK_CI!0=_x5#Kg+41Z yGLSM8+3)tpIKAb*#7I)cEk~p(t0mUWhh2R~LjC<+$E{FL|H!y!F>)o>Create a contribution note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "

    Erstelle eine Zuwendungs-Notiz für jedes Feld, das in dieser Auswahl angegeben ist.

    \n

    Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder deaktivieren.

    " + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "

    Create a contact note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "

    Erstelle eine Kontakt-Notiz für jedes Feld, das in dieser Auswahl angegeben ist.

    \n

    Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder deaktivieren.

    " + #: templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to reset the default profile?" msgstr "Möchten Sie wirklich das Standard-Profil zurücksetzen?" diff --git a/l10n/pot/twingle.pot b/l10n/pot/twingle.pot index 868ab0a..7de3f72 100644 --- a/l10n/pot/twingle.pot +++ b/l10n/pot/twingle.pot @@ -74,6 +74,26 @@ msgstr "" msgid "Only alphanumeric characters and the underscore (_) are allowed for profile names." msgstr "" +#: ./CRM/Twingle/Form/Profile.php +msgid "Create contribution notes for" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "Purpose" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "Remarks" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Create contact notes for" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "User Extra Field" +msgstr "" + #: ./CRM/Twingle/Form/Profile.php msgid "CiviSEPA" msgstr "" @@ -206,6 +226,22 @@ msgstr "" msgid "Groups" msgstr "" +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Create contribution note for" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Create contact note for" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "

    Create a contribution note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "

    Create a contact note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "" + #: ./templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to reset the default profile?" msgstr "" From 2b8ab813dbe9a3297edfd875539348408f8bb150 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 10 May 2024 12:27:33 +0200 Subject: [PATCH 157/221] Fix ambiguous conditions replacing `empty()` --- CRM/Twingle/Profile.php | 3 ++- CRM/Twingle/Submission.php | 6 +++--- api/v3/TwingleDonation/Submit.php | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 15588b3..79c11ca 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -111,7 +111,8 @@ class CRM_Twingle_Profile { */ public function getCustomFieldMapping() { $custom_field_mapping = []; - if (is_string($custom_field_definition = $this->getAttribute('custom_field_mapping'))) { + if ('' !== ($custom_field_definition = $this->getAttribute('custom_field_mapping', ''))) { + /** @var string $custom_field_definition */ $custom_field_maps = preg_split( '/\r\n|\r|\n/', $custom_field_definition, diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index a6ce330..70540ca 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -72,8 +72,8 @@ class CRM_Twingle_Submission { // Get the payment instrument defined within the profile, or return an error // if none matches (i.e. an unknown payment method was submitted). - $payment_instrument_id = $profile->getAttribute('pi_' . $params['payment_method']); - if (!isset($payment_instrument_id)) { + $payment_instrument_id = $profile->getAttribute('pi_' . $params['payment_method'], ''); + if ('' !== $payment_instrument_id) { throw new CRM_Core_Exception( E::ts('Payment method could not be matched to existing payment instrument.'), 'invalid_format' @@ -101,7 +101,7 @@ class CRM_Twingle_Submission { // matches (i.e. an unknown gender was submitted). if (is_string($params['user_gender'])) { $gender_id = $profile->getAttribute('gender_' . $params['user_gender']); - if (!isset($gender_id)) { + if (!is_numeric($gender_id)) { throw new CRM_Core_Exception( E::ts('Gender could not be matched to existing gender.'), 'invalid_format' diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index ecaeac8..e24cb2f 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -420,7 +420,7 @@ function civicrm_api3_twingle_donation_Submit($params) { // Get the prefix ID defined within the profile if ( isset($params['user_gender']) - && NULL !== ($prefix_id = $profile->getAttribute('prefix_' . $params['user_gender'])) + && is_numeric($prefix_id = $profile->getAttribute('prefix_' . $params['user_gender'])) ) { $contact_data['prefix_id'] = $prefix_id; } @@ -830,8 +830,8 @@ function civicrm_api3_twingle_donation_Submit($params) { $result_values['membership'] = $membership; // call the postprocess API - $postprocess_call = $profile->getAttribute('membership_postprocess_call'); - if (is_string($postprocess_call)) { + if ('' !== ($postprocess_call = $profile->getAttribute('membership_postprocess_call', ''))) { + /** @var string $postprocess_call */ [$pp_entity, $pp_action] = explode('.', $postprocess_call, 2); try { // gather the contribution IDs From c7f1b7cb6e6a055d5574ed0b65b8a1bef0773275 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 6 Jun 2024 10:33:19 +0200 Subject: [PATCH 158/221] Do not require project IDs for default profile forms --- CRM/Twingle/Form/Profile.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index af1832a..2f7a750 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -571,7 +571,15 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { // Show warning when there is configuration missing for required fields. $requiredConfig = CRM_Twingle_Profile::allowedAttributes(TRUE); foreach ($requiredConfig as $key => $metadata) { - if (!isset($profile_data[$key]) && $metadata['required']) { + $required = $metadata['required'] ?? FALSE; + // Do not require twingle project IDs/selector for the default profile. + if ( + $this->profile->is_default() + && 'selector' === $key + ) { + $required = FALSE; + } + if (!isset($profile_data[$key]) && $required) { CRM_Core_Session::setStatus( E::ts( 'The required configuration option "%1" has no value. Saving the profile might set this option to a possibly unwanted default value.', From a0b2879b694c4eb7bdb4a3208c45e4ace97e5fad Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 6 Jun 2024 10:56:49 +0200 Subject: [PATCH 159/221] Prevent undefined index warnings for unchecked checkbpxes in the settings form --- CRM/Twingle/Form/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index c4627fb..0634dbc 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -157,7 +157,7 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { // store settings foreach (self::$SETTINGS_LIST as $setting) { - Civi::settings()->set($setting, $values[$setting]); + Civi::settings()->set($setting, $values[$setting] ?? NULL); } parent::postProcess(); From 75676d42ebbd5c301f03a18860ecb235ab16fa6c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 6 Jun 2024 11:01:56 +0200 Subject: [PATCH 160/221] Fix condition in profile form template for not showing selector field for default profile --- templates/CRM/Twingle/Form/Profile.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index df54418..a090abd 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -28,7 +28,7 @@
    {$form.selector.label} 'civicrm_contribution', - 'entity_id' => CRM_Utils_Array::first($result_values['contribution'])['id'], + 'entity_id' => $result_values['contribution']['id'], 'note' => $params[$target], ]); } From 8020491bf1721cc09dfdb5b5c199714d7a20165d Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 6 Jun 2024 12:01:05 +0200 Subject: [PATCH 162/221] Repair help links in settings form (and reformat) --- templates/CRM/Twingle/Form/Settings.tpl | 86 +++++++++---------------- 1 file changed, 32 insertions(+), 54 deletions(-) diff --git a/templates/CRM/Twingle/Form/Settings.tpl b/templates/CRM/Twingle/Form/Settings.tpl index e5fa54f..42953e2 100644 --- a/templates/CRM/Twingle/Form/Settings.tpl +++ b/templates/CRM/Twingle/Form/Settings.tpl @@ -18,47 +18,41 @@ - + - + - + - + @@ -66,10 +60,6 @@ @@ -77,10 +67,6 @@ @@ -88,10 +74,6 @@ @@ -99,16 +81,11 @@
    {$form.twingle_use_sepa.label}   + {$form.twingle_use_sepa.label} + {help id="id-twingle_use_sepa" title=$form.twingle_use_sepa.label} + {$form.twingle_use_sepa.html} -
    - - {$formElements.twingle_use_sepa.description} -
    {$form.twingle_dont_use_reference.label}   + {$form.twingle_dont_use_reference.label} + {help id="id-twingle_dont_use_reference" title=$form.twingle_dont_use_reference.label} + {$form.twingle_dont_use_reference.html} -
    - - {$formElements.twingle_dont_use_reference.description} -
    {$form.twingle_prefix.label}  {$form.twingle_prefix.label} + {help id="id-twingle_prefix" title=$form.twingle_prefix.label} + {$form.twingle_prefix.html} -
    - - {$formElements.twingle_prefix.description} -
    {$form.twingle_protect_recurring.label}  {$form.twingle_protect_recurring.label} + {help id="id-twingle_protect_recurring" title=$form.twingle_protect_recurring.label} + {$form.twingle_protect_recurring.html} -
    - - {$formElements.protect_recurring.description} -
    {$form.twingle_protect_recurring_activity_type.label} {$form.twingle_protect_recurring_activity_type.html} -
    - - {$formElements.twingle_protect_recurring_activity_type.description} -
    {$form.twingle_protect_recurring_activity_subject.label} {$form.twingle_protect_recurring_activity_subject.html} -
    - - {$formElements.twingle_protect_recurring_activity_subject.description} -
    {$form.twingle_protect_recurring_activity_status.label} {$form.twingle_protect_recurring_activity_status.html} -
    - - {$formElements.twingle_protect_recurring_activity_status.description} -
    {$form.twingle_protect_recurring_activity_assignee.label} {$form.twingle_protect_recurring_activity_assignee.html} -
    - - {$formElements.twingle_protect_recurring_activity_assignee.description} -
    -
    {include file="CRM/common/formButtons.tpl" location="bottom"}
    @@ -116,22 +93,23 @@ {literal} - -{/literal} \ No newline at end of file + cj(document).ready(function () { + cj('#twingle_protect_recurring').change(twingle_protect_recurring_change); + twingle_protect_recurring_change(); + }); + +{/literal} From 983616812284a758106272f431f6a447aacb7d04 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 26 Apr 2024 18:19:16 +0200 Subject: [PATCH 163/221] add profile settings for note mapping --- CRM/Twingle/Form/Profile.php | 25 +++++++++++++++ CRM/Twingle/Profile.php | 4 +++ templates/CRM/Twingle/Form/Profile.hlp | 12 ++++++- templates/CRM/Twingle/Form/Profile.tpl | 44 ++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 2f7a750..2159d3b 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -498,6 +498,31 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { [] ); + $this->add( + 'select', + 'map_as_contribution_notes', + E::ts('Create contribution notes for'), + [ + 'purpose' => E::ts('Purpose'), + 'remarks' => E::ts('Remarks'), + ], + // is not required + FALSE, + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] + ); + + $this->add( + 'select', + 'map_as_contact_notes', + E::ts('Create contact notes for'), + [ + 'user_extrafield' => E::ts('User Extra Field'), + ], + // is not required + FALSE, + ['class' => 'crm-select2 huge', 'multiple' => 'multiple'] + ); + $this->addButtons([ [ 'type' => 'submit', diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 79c11ca..94a8a2e 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -530,6 +530,8 @@ class CRM_Twingle_Profile { 'membership_postprocess_call' => ['required' => FALSE], 'newsletter_double_opt_in' => ['required' => FALSE], 'required_address_components' => ['required' => FALSE], + 'map_as_contribution_notes' => ['required' => FALSE], + 'map_as_contact_notes' => ['required' => FALSE], ], // Add payment methods. array_combine( @@ -646,6 +648,8 @@ class CRM_Twingle_Profile { 'city', 'country', ], + 'map_as_contribution_notes' => [], + 'map_as_contact_notes' => [], ] // Add contribution status for all payment methods. // phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index e3841d7..b8d67a4 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -75,4 +75,14 @@
  • ContributionRecur – Will be set on the recurring contribution and deriving single contributions
  • {/ts} {/htxt} -{/crmScope} \ No newline at end of file + +{htxt id='id-map_as_contribution_notes'} + {ts domain="de.systopia.twingle"}

    Create a contribution note for each field specified in this selection.

    +

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    {/ts} +{/htxt} + +{htxt id='id-map_as_contact_notes'} + {ts domain="de.systopia.twingle"}

    Create a contact note for each field specified in this selection.

    +

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    {/ts} +{/htxt} +{/crmScope} diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index a090abd..4557e0d 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -313,6 +313,50 @@
    {$form.contribution_source.html}
    + {$form.map_as_contribution_notes.label} + + {$form.map_as_contribution_notes.html}
    + {$form.map_as_contact_notes.label} + + {$form.map_as_contact_notes.html}
    {$form.custom_field_mapping.label} From 758b793c0d96b658d62dd5c6720561bd63f4b373 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 26 Apr 2024 18:19:54 +0200 Subject: [PATCH 164/221] add logic to create selected contact and contribution notes --- api/v3/TwingleDonation/Submit.php | 48 ++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index e24cb2f..6c252fb 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -255,6 +255,13 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { 'api.required' => 0, 'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'), ]; + $params['remarks'] = [ + 'name' => 'remarks', + 'title' => E::ts('Remarks'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + 'description' => E::ts('Additional remarks for the donation.'), + ]; } /** @@ -477,13 +484,20 @@ function civicrm_api3_twingle_donation_Submit($params) { ); } - // Save user_extrafield as contact note. - if (isset($params['user_extrafield']) && '' != $params['user_extrafield']) { - civicrm_api3('Note', 'create', [ - 'entity_table' => 'civicrm_contact', - 'entity_id' => $contact_id, - 'note' => $params['user_extrafield'], - ]); + // Create contact notes. + $contact_note_mappings = $profile->getAttribute('map_as_contact_notes', []); + foreach (['user_extrafield'] as $target) { + if ( + isset($params[$target]) + && '' != $params[$target] + && in_array($target, $contact_note_mappings) + ) { + civicrm_api3('Note', 'create', [ + 'entity_table' => 'civicrm_contact', + 'entity_id' => $contact_id, + 'note' => $params[$target], + ]); + } } // Share organisation address with individual contact, using configured @@ -620,10 +634,6 @@ function civicrm_api3_twingle_donation_Submit($params) { $contribution_data += $custom_fields['Contribution']; } - if (isset($params['purpose'])) { - $contribution_data['note'] = $params['purpose']; - } - // set campaign, subject to configuration CRM_Twingle_Submission::setCampaign($contribution_data, 'contribution', $params, $profile); @@ -794,6 +804,22 @@ function civicrm_api3_twingle_donation_Submit($params) { $result_values['contribution'] = $contribution['values']; } + // Add notes to the contribution. + $contribution_note_mappings = $profile->getAttribute("map_as_contribution_notes"); + foreach (['purpose', 'remarks'] as $target) { + if ( + in_array($target, $contribution_note_mappings) + && isset($params[$target]) + && '' != $params[$target] + ) { + civicrm_api3('Note', 'create', [ + 'entity_table' => 'civicrm_contribution', + 'entity_id' => CRM_Utils_Array::first($result_values['contribution'])['id'], + 'note' => $params[$target], + ]); + } + } + // MEMBERSHIP CREATION // CHECK whether a membership should be created (based on profile settings and data provided) From 547254158c614101f1b881e9c530eb50167b84f1 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 30 Apr 2024 16:51:39 +0200 Subject: [PATCH 165/221] add Upgrader to maintain profile behaviour --- CRM/Twingle/Upgrader.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 2af4667..4d00514 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -102,4 +102,40 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { return TRUE; } + /** + * Upgrade to 1.5.0 + * + * - Activate mapping of `purpose` and `user_extra_field` to notes in each existing profile to + * maintain default behavior after making the fields optional. + * + * @return bool + * @throws \Civi\Core\Exception\DBQueryException + * @throws \Civi\Twingle\Exceptions\ProfileException + */ + public function upgrade_5150(): bool { + $this->ctx->log->info('Activate mapping of `purpose` and `user_extra_field` to notes in each existing profile.'); + + $profiles = CRM_Twingle_Profile::getProfiles(); + if ($profiles) { + foreach ($profiles as $profile) { + $profile_changed = FALSE; + $contribution_notes = $profile->getAttribute('map_as_contribution_notes', []); + $contact_notes = $profile->getAttribute('map_as_contact_notes', []); + if (!in_array('purpose', $contribution_notes)) { + $profile->setAttribute('map_as_contribution_notes', array_merge($contribution_notes, ['purpose'])); + $profile_changed = TRUE; + } + if (!in_array('user_extrafield', $contact_notes)) { + $profile->setAttribute('map_as_contact_notes', array_merge($contact_notes, ['user_extrafield'])); + $profile_changed = TRUE; + } + if ($profile_changed) { + $profile->saveProfile(); + } + } + } + + return TRUE; + } + } From 87ca1797916d08d204dac1cfcc5fefcf31c32db5 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Tue, 30 Apr 2024 15:43:44 +0200 Subject: [PATCH 166/221] add German translations --- l10n/de_DE/LC_MESSAGES/twingle.mo | Bin 6167 -> 7350 bytes l10n/de_DE/LC_MESSAGES/twingle.po | 36 ++++++++++++++++++++++++++++++ l10n/pot/twingle.pot | 36 ++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/l10n/de_DE/LC_MESSAGES/twingle.mo b/l10n/de_DE/LC_MESSAGES/twingle.mo index eff6c7e6ef72276b0d8a65e60300db9c0c5cd6fc..9fd805479ba6759289b95892b87803fec1e57720 100644 GIT binary patch delta 2813 zcmcK4TWl0n9LMofD4@{N+F}7gI4F3*mP?J%9qlprufd@2xf3sVqMI#CEq-Q^8W@pa) z=l}n2Uz>M)Y5Yw^@gc)l$DGPMIKr52EE&ZIgxE{-RzR9r|&xzeQ7Z2iWJckPCXM7MR@w9SW ziJUSUQ4e|!wXwtbxD9pxk%FJ20{I22aWYZrg_^OH=bPtQEXH1(g>T~o`~sDM?~r@V zRlEy}$!{x8M+Fk1Qojoo(1*ARPoOe$4Y}2n@Rs-BWF+aP9%F6X#6lZwK+0;iqHahR zj<=)Q;YCyiVywhhQE&bhYQuL69>aS%K7}gPw>S-d$2)NaVSjt^15(>hP*D9{q_)^!tc5zat0;WMcH_M-xN16BL?P^J6?6~HBIz-yJ{ zU$t3AzUN^(T0DSiwvSMee~HuaGS0wqc2VYPu?ibdUEPLya2MW>+mUCP!>GVNK=slI zWGizqWPy#?6v?mpqgnn*5b#gruhN2(MTFYr5cYaO%*Ik=q3Pd*v?)o7?xYnWTMTcW!Vf_%QH`Li0 z>W>v#437G~hE<{Svd(%ol?k$5Dr2VNfYQt_1axv(!2In(M=nJ{f<&9`2}L9Z8fA1E$4U)~nE&^Eo0 z4L#ee;thONQa2)AIHz{36513-S=U2JoF6#bqMCPSYu0A6{!ZI*_H<~sxwMOHGdEV- zw3pNARXLK{s$F~;#tw!HCP*L_yQ9LBuu26{}$-5a+ z3UV>*>lT=~u W7v!=#U09QJQjPjy;9Av`qCWwjum7q5 delta 1624 zcmYk+Ur3Wt7{~E5o0>YE|E;O@W@&1soBwi|x=c+d3QTuq9%@EyFQFZP2i8(iAv-gmfz;L2c9~T+e+w>a2Qj4Gv)zPN61vgiH7W*|d4i_Uj$Syh0_AMz(rC z4{Naq)jJ1KiHy0azZRb44V~#-EXK#Eg+5~=I{0suJb+$2iWZKecKiUd@hPg=W>NEg z#f|t4m9WJkN~{`7uqloD>ukDtLuYpici}MV2;QI%UCdgEji|FeftqLt={qxuD)Cip z!t3b8xu}_}UdDYZR$?EjqBp`^uu1a-1Nah^aTZx=p@yjYkSd#A)E5Uah!dy^EMP1C zK=n+3@^#=&Wbbbvw>YaP2jm#jqnR#^6BfpV(!X}wdxwo?dyF9X)PzkjgJS|A!XQSV!pT z(5N6*5ZbYa&`?$W4Lz3pzL`yglGXb5XjsPHxh|ElcCDc@`3VxXcMf)Q$|_ng$)ktc}YC=u8 znow!g7aErRx_m6U+)U^wG}N301bt~gSuUNSMj;Vdia+g$d`cK_CI!0=_x5#Kg+41Z yGLSM8+3)tpIKAb*#7I)cEk~p(t0mUWhh2R~LjC<+$E{FL|H!y!F>)o>Create a contribution note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "

    Erstelle eine Zuwendungs-Notiz für jedes Feld, das in dieser Auswahl angegeben ist.

    \n

    Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder deaktivieren.

    " + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "

    Create a contact note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "

    Erstelle eine Kontakt-Notiz für jedes Feld, das in dieser Auswahl angegeben ist.

    \n

    Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder deaktivieren.

    " + #: templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to reset the default profile?" msgstr "Möchten Sie wirklich das Standard-Profil zurücksetzen?" diff --git a/l10n/pot/twingle.pot b/l10n/pot/twingle.pot index 868ab0a..7de3f72 100644 --- a/l10n/pot/twingle.pot +++ b/l10n/pot/twingle.pot @@ -74,6 +74,26 @@ msgstr "" msgid "Only alphanumeric characters and the underscore (_) are allowed for profile names." msgstr "" +#: ./CRM/Twingle/Form/Profile.php +msgid "Create contribution notes for" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "Purpose" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +msgid "Remarks" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "Create contact notes for" +msgstr "" + +#: ./CRM/Twingle/Form/Profile.php +msgid "User Extra Field" +msgstr "" + #: ./CRM/Twingle/Form/Profile.php msgid "CiviSEPA" msgstr "" @@ -206,6 +226,22 @@ msgstr "" msgid "Groups" msgstr "" +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Create contribution note for" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.tpl +msgid "Create contact note for" +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "

    Create a contribution note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "" + +#: ./templates/CRM/Twingle/Form/Profile.hlp +msgid "

    Create a contact note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " +msgstr "" + #: ./templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to reset the default profile?" msgstr "" From 1ddcc217e34bfd1bdee9ca52ab2f220f0e1e0416 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 11:57:32 +0200 Subject: [PATCH 167/221] fix obsolete use of CRM_Utils_Array::first() --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 6c252fb..984f95c 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -814,7 +814,7 @@ function civicrm_api3_twingle_donation_Submit($params) { ) { civicrm_api3('Note', 'create', [ 'entity_table' => 'civicrm_contribution', - 'entity_id' => CRM_Utils_Array::first($result_values['contribution'])['id'], + 'entity_id' => $result_values['contribution']['id'], 'note' => $params[$target], ]); } From 089bbdf934719262defe5dc18cfef996c6ee4700 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 12:29:17 +0200 Subject: [PATCH 168/221] use api4 instead of api3 --- api/v3/TwingleDonation/Submit.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 984f95c..fc30843 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -492,10 +492,12 @@ function civicrm_api3_twingle_donation_Submit($params) { && '' != $params[$target] && in_array($target, $contact_note_mappings) ) { - civicrm_api3('Note', 'create', [ - 'entity_table' => 'civicrm_contact', - 'entity_id' => $contact_id, - 'note' => $params[$target], + civicrm_api4('Note', 'create', [ + 'values' => [ + 'entity_table' => 'civicrm_contact', + 'entity_id' => $contact_id, + 'note' => $params[$target], + ], ]); } } @@ -812,10 +814,12 @@ function civicrm_api3_twingle_donation_Submit($params) { && isset($params[$target]) && '' != $params[$target] ) { - civicrm_api3('Note', 'create', [ - 'entity_table' => 'civicrm_contribution', - 'entity_id' => $result_values['contribution']['id'], - 'note' => $params[$target], + civicrm_api4('Note', 'create', [ + 'values' => [ + 'entity_table' => 'civicrm_contribution', + 'entity_id' => $result_values['contribution']['id'], + 'note' => $params[$target], + ], ]); } } From bea59b4365d6197333d7088743e3ae397d4c6fc6 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 12:29:43 +0200 Subject: [PATCH 169/221] use strict comparisons --- api/v3/TwingleDonation/Submit.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index fc30843..582627c 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -489,7 +489,7 @@ function civicrm_api3_twingle_donation_Submit($params) { foreach (['user_extrafield'] as $target) { if ( isset($params[$target]) - && '' != $params[$target] + && '' !== $params[$target] && in_array($target, $contact_note_mappings) ) { civicrm_api4('Note', 'create', [ @@ -812,7 +812,7 @@ function civicrm_api3_twingle_donation_Submit($params) { if ( in_array($target, $contribution_note_mappings) && isset($params[$target]) - && '' != $params[$target] + && '' !== $params[$target] ) { civicrm_api4('Note', 'create', [ 'values' => [ From 0caf9bf98e63eb7316f2b5b494af3d522106d6e0 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 6 Jun 2024 14:14:44 +0200 Subject: [PATCH 170/221] Revert "fix obsolete use of CRM_Utils_Array::first()" --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 582627c..74610aa 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -817,7 +817,7 @@ function civicrm_api3_twingle_donation_Submit($params) { civicrm_api4('Note', 'create', [ 'values' => [ 'entity_table' => 'civicrm_contribution', - 'entity_id' => $result_values['contribution']['id'], + 'entity_id' => CRM_Utils_Array::first($result_values['contribution'])['id'], 'note' => $params[$target], ], ]); From cf9483ca3e1f3d4c5a868fcf73afdeff149a2105 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 12 Jun 2024 10:55:52 +0200 Subject: [PATCH 171/221] fix: "in_array() expects parameter 2 to be array, null given" --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 74610aa..66a3c8d 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -807,7 +807,7 @@ function civicrm_api3_twingle_donation_Submit($params) { } // Add notes to the contribution. - $contribution_note_mappings = $profile->getAttribute("map_as_contribution_notes"); + $contribution_note_mappings = $profile->getAttribute("map_as_contribution_notes", []); foreach (['purpose', 'remarks'] as $target) { if ( in_array($target, $contribution_note_mappings) From ac1b08b77542f10d63f9ae455fd5208883d05525 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 12 Jun 2024 14:35:42 +0200 Subject: [PATCH 172/221] Code style --- CRM/Twingle/Profile.php | 5 ++- CRM/Twingle/Upgrader.php | 33 ++++++++--------- api/v3/TwingleDonation/Submit.php | 51 +++++++++++++------------- templates/CRM/Twingle/Form/Profile.tpl | 32 +--------------- 4 files changed, 47 insertions(+), 74 deletions(-) diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 94a8a2e..b6f6225 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -687,7 +687,10 @@ class CRM_Twingle_Profile { return $default_profile; } else { - throw new ProfileException('Could not find default profile', ProfileException::ERROR_CODE_DEFAULT_PROFILE_NOT_FOUND); + throw new ProfileException( + 'Could not find default profile', + ProfileException::ERROR_CODE_DEFAULT_PROFILE_NOT_FOUND + ); } } diff --git a/CRM/Twingle/Upgrader.php b/CRM/Twingle/Upgrader.php index 4d00514..70f0180 100644 --- a/CRM/Twingle/Upgrader.php +++ b/CRM/Twingle/Upgrader.php @@ -115,23 +115,22 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base { public function upgrade_5150(): bool { $this->ctx->log->info('Activate mapping of `purpose` and `user_extra_field` to notes in each existing profile.'); - $profiles = CRM_Twingle_Profile::getProfiles(); - if ($profiles) { - foreach ($profiles as $profile) { - $profile_changed = FALSE; - $contribution_notes = $profile->getAttribute('map_as_contribution_notes', []); - $contact_notes = $profile->getAttribute('map_as_contact_notes', []); - if (!in_array('purpose', $contribution_notes)) { - $profile->setAttribute('map_as_contribution_notes', array_merge($contribution_notes, ['purpose'])); - $profile_changed = TRUE; - } - if (!in_array('user_extrafield', $contact_notes)) { - $profile->setAttribute('map_as_contact_notes', array_merge($contact_notes, ['user_extrafield'])); - $profile_changed = TRUE; - } - if ($profile_changed) { - $profile->saveProfile(); - } + foreach (CRM_Twingle_Profile::getProfiles() as $profile) { + $profile_changed = FALSE; + /** @phpstan-var array $contribution_notes */ + $contribution_notes = $profile->getAttribute('map_as_contribution_notes', []); + /** @phpstan-var array $contact_notes */ + $contact_notes = $profile->getAttribute('map_as_contact_notes', []); + if (!in_array('purpose', $contribution_notes, TRUE)) { + $profile->setAttribute('map_as_contribution_notes', array_merge($contribution_notes, ['purpose'])); + $profile_changed = TRUE; + } + if (!in_array('user_extrafield', $contact_notes, TRUE)) { + $profile->setAttribute('map_as_contact_notes', array_merge($contact_notes, ['user_extrafield'])); + $profile_changed = TRUE; + } + if ($profile_changed) { + $profile->saveProfile(); } } diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 66a3c8d..bac1fd6 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -17,6 +17,7 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; use Civi\Twingle\Exceptions\BaseException; +use Civi\Api4\Note; /** * TwingleDonation.Submit API specification @@ -485,20 +486,19 @@ function civicrm_api3_twingle_donation_Submit($params) { } // Create contact notes. + /** @phpstan-var array $contact_note_mappings */ $contact_note_mappings = $profile->getAttribute('map_as_contact_notes', []); foreach (['user_extrafield'] as $target) { if ( isset($params[$target]) && '' !== $params[$target] - && in_array($target, $contact_note_mappings) + && in_array($target, $contact_note_mappings, TRUE) ) { - civicrm_api4('Note', 'create', [ - 'values' => [ - 'entity_table' => 'civicrm_contact', - 'entity_id' => $contact_id, - 'note' => $params[$target], - ], - ]); + Note::create(FALSE) + ->addValue('entity_table', 'civicrm_contact') + ->addValue('entity_id', $contact_id) + ->addValue('note', $params[$target]) + ->execute(); } } @@ -803,25 +803,24 @@ function civicrm_api3_twingle_donation_Submit($params) { ); } - $result_values['contribution'] = $contribution['values']; - } - - // Add notes to the contribution. - $contribution_note_mappings = $profile->getAttribute("map_as_contribution_notes", []); - foreach (['purpose', 'remarks'] as $target) { - if ( - in_array($target, $contribution_note_mappings) - && isset($params[$target]) - && '' !== $params[$target] - ) { - civicrm_api4('Note', 'create', [ - 'values' => [ - 'entity_table' => 'civicrm_contribution', - 'entity_id' => CRM_Utils_Array::first($result_values['contribution'])['id'], - 'note' => $params[$target], - ], - ]); + // Add notes to the contribution. + /** @phpstan-var array $contribution_note_mappings */ + $contribution_note_mappings = $profile->getAttribute('map_as_contribution_notes', []); + foreach (['purpose', 'remarks'] as $target) { + if ( + in_array($target, $contribution_note_mappings, TRUE) + && isset($params[$target]) + && '' !== $params[$target] + ) { + Note::create(FALSE) + ->addValue('entity_table', 'civicrm_contribution') + ->addValue('entity_id', reset($contribution['values'])['id']) + ->addValue('note', reset($params[$target])) + ->execute(); + } } + + $result_values['contribution'] = $contribution['values']; } // MEMBERSHIP CREATION diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl index 4557e0d..1577b5f 100644 --- a/templates/CRM/Twingle/Form/Profile.tpl +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -316,21 +316,7 @@
    {$form.map_as_contribution_notes.label} - + {help id="id-map_as_contribution_notes" title=$form.map_as_contribution_notes.label} {$form.map_as_contribution_notes.html}
    {$form.map_as_contact_notes.label} - + {help id="id-map_as_contact_notes" title=$form.map_as_contact_notes.label} {$form.map_as_contact_notes.html}
    {$form.selector.html}{$form.selector.html}
    + {if $twingle_use_shop eq 1} + + {ts domain="de.systopia.twingle"}Shop Integration{/ts} + + + + + + + + + + + + + + + + + + + + + +
    + {$form.enable_shop_integration.label} + + {$form.enable_shop_integration.html}
    {$form.shop_financial_type.label}{$form.shop_financial_type.html}
    {$form.shop_donation_financial_type.label}{$form.shop_donation_financial_type.html}
    {$form.shop_map_products.label} + {$form.shop_map_products.html} + +
    +
    +
    +
    + + {/if} + {elseif $op == 'delete'} @@ -389,11 +454,18 @@ } } - // register events and run once + // register events cj(document).ready(function (){ cj('#membership_type_id').change(twingle_membership_active_changed); cj('#membership_type_id_recur').change(twingle_membership_active_changed); + + // init Twingle Shop integration + if ({/literal}{if $twingle_use_shop eq 1}true{else}false{/if}{literal}) { + twingleShopInit(); + } }); + + // run once twingle_membership_active_changed(); {/literal} diff --git a/templates/CRM/Twingle/Form/Settings.hlp b/templates/CRM/Twingle/Form/Settings.hlp index 7b82e7b..bfd00e2 100644 --- a/templates/CRM/Twingle/Form/Settings.hlp +++ b/templates/CRM/Twingle/Form/Settings.hlp @@ -27,3 +27,7 @@ {htxt id='id-twingle_prefix'} {ts domain="de.systopia.twingle"}You can use this setting to add a prefix to the Twingle transaction ID, in order to avoid collisions with other transaction ids.{/ts} {/htxt} + +{htxt id='id-twingle_use_shop'} + {ts domain="de.systopia.twingle"}If you enable Twingle Shop integration, you can configure Twingle API profiles to include products ordered through Twingle Shop as line items in the created contribution.{/ts} +{/htxt} diff --git a/templates/CRM/Twingle/Form/Settings.tpl b/templates/CRM/Twingle/Form/Settings.tpl index 42953e2..906a91c 100644 --- a/templates/CRM/Twingle/Form/Settings.tpl +++ b/templates/CRM/Twingle/Form/Settings.tpl @@ -37,7 +37,6 @@ - {$form.twingle_prefix.label} {help id="id-twingle_prefix" title=$form.twingle_prefix.label} @@ -86,6 +85,31 @@ +

    Twingle Shop Integration

    + + + + + + + + + + +
    {$form.twingle_use_shop.label}   + {$form.twingle_use_shop.html} +
    + + {$formElements.twingle_use_shop.description} + +
    {$form.twingle_access_key.label}   + {$form.twingle_access_key.html} +
    + + {$formElements.twingle_access_key.description} + +
    +
    {include file="CRM/common/formButtons.tpl" location="bottom"}
    diff --git a/templates/CRM/Twingle/Page/Profiles.tpl b/templates/CRM/Twingle/Page/Profiles.tpl index 6d4bc90..1ef751b 100644 --- a/templates/CRM/Twingle/Page/Profiles.tpl +++ b/templates/CRM/Twingle/Page/Profiles.tpl @@ -26,6 +26,9 @@ {ts domain="de.systopia.twingle"}Profile name{/ts} {ts domain="de.systopia.twingle"}Selectors{/ts} + {if $twingle_use_shop eq 1} + {ts domain="de.systopia.twingle"}Shop Integration{/ts} + {/if} {ts domain="de.systopia.twingle"}Used{/ts} {ts domain="de.systopia.twingle"}Last Used{/ts} {ts domain="de.systopia.twingle"}Operations{/ts} @@ -46,6 +49,9 @@ {/if} + {if $twingle_use_shop eq 1} + {if $profile.enable_shop_integration}{ts domain="de.systopia.twingle"}enabled{/ts}{else}{ts domain="de.systopia.twingle"}disabled{/ts}{/if} + {/if} {ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.access_counter_txt}{/ts} {ts domain="de.systopia.twingle"}{$profile_stats.$profile_name.last_access_txt}{/ts} @@ -56,7 +62,6 @@ {else} {ts domain="de.systopia.twingle"}Delete{/ts} {/if} - {/foreach} diff --git a/tests/phpunit/api/v3/TwingleProduct/CreateTest.php b/tests/phpunit/api/v3/TwingleProduct/CreateTest.php new file mode 100644 index 0000000..7d489aa --- /dev/null +++ b/tests/phpunit/api/v3/TwingleProduct/CreateTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleProduct', 'create', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/api/v3/TwingleProduct/DeleteTest.php b/tests/phpunit/api/v3/TwingleProduct/DeleteTest.php new file mode 100644 index 0000000..7edac01 --- /dev/null +++ b/tests/phpunit/api/v3/TwingleProduct/DeleteTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleProduct', 'delete', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/api/v3/TwingleProduct/GetTest.php b/tests/phpunit/api/v3/TwingleProduct/GetTest.php new file mode 100644 index 0000000..670de99 --- /dev/null +++ b/tests/phpunit/api/v3/TwingleProduct/GetTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleProduct', 'get', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/api/v3/TwingleProduct/GetsingleTest.php b/tests/phpunit/api/v3/TwingleProduct/GetsingleTest.php new file mode 100644 index 0000000..1bf43da --- /dev/null +++ b/tests/phpunit/api/v3/TwingleProduct/GetsingleTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleProduct', 'getsingle', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/api/v3/TwingleShop/CreateTest.php b/tests/phpunit/api/v3/TwingleShop/CreateTest.php new file mode 100644 index 0000000..12ccac6 --- /dev/null +++ b/tests/phpunit/api/v3/TwingleShop/CreateTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleShop', 'create', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/api/v3/TwingleShop/DeleteTest.php b/tests/phpunit/api/v3/TwingleShop/DeleteTest.php new file mode 100644 index 0000000..8e1a9ca --- /dev/null +++ b/tests/phpunit/api/v3/TwingleShop/DeleteTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleShop', 'delete', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/api/v3/TwingleShop/GetTest.php b/tests/phpunit/api/v3/TwingleShop/GetTest.php new file mode 100644 index 0000000..e9fa453 --- /dev/null +++ b/tests/phpunit/api/v3/TwingleShop/GetTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleShop', 'get', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/api/v3/TwingleShop/GetsingleTest.php b/tests/phpunit/api/v3/TwingleShop/GetsingleTest.php new file mode 100644 index 0000000..96a4efa --- /dev/null +++ b/tests/phpunit/api/v3/TwingleShop/GetsingleTest.php @@ -0,0 +1,54 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * The setup() method is executed before the test is executed (optional). + */ + public function setUp() { + parent::setUp(); + } + + /** + * The tearDown() method is executed after the test was executed (optional) + * This can be used for cleanup. + */ + public function tearDown() { + parent::tearDown(); + } + + /** + * Simple example test case. + * + * Note how the function name begins with the word "test". + */ + public function testApiExample() { + $result = civicrm_api3('TwingleShop', 'getsingle', array('magicword' => 'sesame')); + $this->assertEquals('Twelve', $result['values'][12]['name']); + } + +} diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php new file mode 100644 index 0000000..eaa8379 --- /dev/null +++ b/tests/phpunit/bootstrap.php @@ -0,0 +1,65 @@ +add('CRM_', [__DIR__ . '/../..', __DIR__]); +$loader->addPsr4('Civi\\', [__DIR__ . '/../../Civi', __DIR__ . '/Civi']); +$loader->add('api_', [__DIR__ . '/../..', __DIR__]); +$loader->addPsr4('api\\', [__DIR__ . '/../../api', __DIR__ . '/api']); + +$loader->register(); + +/** + * Call the "cv" command. + * + * @param string $cmd + * The rest of the command to send. + * @param string $decode + * Ex: 'json' or 'phpcode'. + * @return mixed + * Response output (if the command executed normally). + * For 'raw' or 'phpcode', this will be a string. For 'json', it could be any JSON value. + * @throws \RuntimeException + * If the command terminates abnormally. + */ +function cv(string $cmd, string $decode = 'json') { + $cmd = 'cv ' . $cmd; + $descriptorSpec = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => STDERR]; + $oldOutput = getenv('CV_OUTPUT'); + putenv('CV_OUTPUT=json'); + + // Execute `cv` in the original folder. This is a work-around for + // phpunit/codeception, which seem to manipulate PWD. + $cmd = sprintf('cd %s; %s', escapeshellarg(getenv('PWD')), $cmd); + + $process = proc_open($cmd, $descriptorSpec, $pipes, __DIR__); + putenv("CV_OUTPUT=$oldOutput"); + fclose($pipes[0]); + $result = stream_get_contents($pipes[1]); + fclose($pipes[1]); + if (proc_close($process) !== 0) { + throw new RuntimeException("Command failed ($cmd):\n$result"); + } + switch ($decode) { + case 'raw': + return $result; + + case 'phpcode': + // If the last output is /*PHPCODE*/, then we managed to complete execution. + if (substr(trim($result), 0, 12) !== '/*BEGINPHP*/' || substr(trim($result), -10) !== '/*ENDPHP*/') { + throw new \RuntimeException("Command failed ($cmd):\n$result"); + } + return $result; + + case 'json': + return json_decode($result, 1); + + default: + throw new RuntimeException("Bad decoder format ($decode)"); + } +} diff --git a/twingle.civix.php b/twingle.civix.php index c207adf..6d84d1c 100644 --- a/twingle.civix.php +++ b/twingle.civix.php @@ -198,3 +198,25 @@ function _twingle_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) { } } } + +/** + * (Delegated) Implements hook_civicrm_entityTypes(). + * + * Find any *.entityType.php files, merge their content, and return. + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes + */ +function _twingle_civix_civicrm_entityTypes(&$entityTypes) { + $entityTypes = array_merge($entityTypes, [ + 'Civi\Twingle\Shop\DAO\TwingleProduct' => [ + 'name' => 'TwingleProduct', + 'class' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'table' => 'civicrm_twingle_product', + ], + 'Civi\Twingle\Shop\DAO\TwingleShop' => [ + 'name' => 'TwingleShop', + 'class' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'table' => 'civicrm_twingle_shop', + ], + ]); +} diff --git a/twingle.php b/twingle.php index 8a838ea..c00ac35 100644 --- a/twingle.php +++ b/twingle.php @@ -5,11 +5,36 @@ use CRM_Twingle_ExtensionUtil as E; /** * Implements hook_civicrm_pre(). + * + * @throws \Civi\Twingle\Shop\Exceptions\ProductException + * @throws \CRM_Core_Exception + * @throws \Civi\Twingle\Shop\Exceptions\ShopException */ function twingle_civicrm_pre($op, $objectName, $id, &$params) { if ($objectName == 'ContributionRecur' && $op == 'edit') { CRM_Twingle_Tools::checkRecurringContributionChange((int) $id, $params); } + + // Create/delete PriceField and PriceFieldValue for TwingleProduct + elseif ($objectName == 'TwingleProduct') { + $twingle_product = new \Civi\Twingle\Shop\BAO\TwingleProduct(); + $twingle_product->load($params); + if ($op == 'create' || $op == 'edit') { + $twingle_product->createPriceField(); + } + elseif ($op == 'delete') { + $twingle_product->deletePriceField(); + } + $params = $twingle_product->getAttributes(); + } + + // Create PriceSet for TwingleShop + elseif ($objectName == 'TwingleShop' && ($op == 'create' || $op == 'edit')) { + $twingle_shop = new \Civi\Twingle\Shop\BAO\TwingleShop(); + $twingle_shop->load($params); + $twingle_shop->createPriceSet(); + $params = $twingle_shop->getAttributes(); + } } /** diff --git a/xml/schema/CRM/Twingle/TwingleProduct.entityType.php b/xml/schema/CRM/Twingle/TwingleProduct.entityType.php new file mode 100644 index 0000000..5b8879b --- /dev/null +++ b/xml/schema/CRM/Twingle/TwingleProduct.entityType.php @@ -0,0 +1,10 @@ + 'TwingleProduct', + 'class' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'table' => 'civicrm_twingle_product', + ], +]; diff --git a/xml/schema/CRM/Twingle/TwingleProduct.xml b/xml/schema/CRM/Twingle/TwingleProduct.xml new file mode 100644 index 0000000..5787e69 --- /dev/null +++ b/xml/schema/CRM/Twingle/TwingleProduct.xml @@ -0,0 +1,75 @@ + + + + CRM/Twingle/Shop + TwingleProduct + civicrm_twingle_product + This table contains the Twingle Product data. + false + + + + id + int unsigned + true + true + Unique TwingleProduct ID + + Number + + + + id + true + + + + external_id + int unsigned + true + The ID of this product in the Twingle database + + Number + + + + + price_field_id + int unsigned + FK to Price Field + true + + + price_field_id +
    civicrm_contact
    + id + CASCADE + + + + twingle_shop_id + int unsigned + true + FK to Twingle Shop + + + twingle_shop_id + civicrm_twingle_shop
    + id + CASCADE +
    + + + created_at + datetime + true + Timestamp of when the product was created in the database + + + + updated_at + datetime + true + Timestamp of when the product was last updated in the database + + diff --git a/xml/schema/CRM/Twingle/TwingleShop.entityType.php b/xml/schema/CRM/Twingle/TwingleShop.entityType.php new file mode 100644 index 0000000..34e6ce2 --- /dev/null +++ b/xml/schema/CRM/Twingle/TwingleShop.entityType.php @@ -0,0 +1,10 @@ + 'TwingleShop', + 'class' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'table' => 'civicrm_twingle_shop', + ], +]; diff --git a/xml/schema/CRM/Twingle/TwingleShop.xml b/xml/schema/CRM/Twingle/TwingleShop.xml new file mode 100644 index 0000000..3d9d6ba --- /dev/null +++ b/xml/schema/CRM/Twingle/TwingleShop.xml @@ -0,0 +1,73 @@ + + + + CRM/Twingle/Shop + TwingleShop + civicrm_twingle_shop + This table contains the Twingle Shop data. Each Twingle Shop is linked to a corresponding Price Set. + false + + + + id + int unsigned + true + true + Unique TwingleShop ID + + Number + + + + id + true + + + + project_identifier + varchar + 32 + true + true + Twingle Project Identifier + + Text + + + + + numerical_project_id + int unsigned + true + true + Numerical Twingle Project Identifier + + Number + + + + + price_set_id + int unsigned + true + FK to Price Set + + + price_set_id +
    civicrm_price_set
    + id + CASCADE + + + + name + varchar + false + 64 + true + name of the shop + + Text + + + From 1fc6529064e2b6a5e39dc757c21b2120e8743e5f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Thu, 21 Mar 2024 12:04:02 +0100 Subject: [PATCH 201/221] set price_field to is_required = false --- Civi/Twingle/Shop/BAO/TwingleProduct.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Civi/Twingle/Shop/BAO/TwingleProduct.php b/Civi/Twingle/Shop/BAO/TwingleProduct.php index 3e2d120..d6448b2 100644 --- a/Civi/Twingle/Shop/BAO/TwingleProduct.php +++ b/Civi/Twingle/Shop/BAO/TwingleProduct.php @@ -306,6 +306,7 @@ class TwingleProduct extends TwingleProductDAO { 'is_active' => $this->is_active, 'weight' => $this->sort, 'html_type' => 'Text', + 'is_required' => false, ]; // Add id if in edit mode if ($mode == 'edit') { From ac892c9afc14e2cde17d90de6c103bd5dcdd0499 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 5 Apr 2024 16:08:44 +0200 Subject: [PATCH 202/221] fix messed up merge conflicts --- Civi/Twingle/Exceptions/BaseException.php | 17 +++++ .../remotes/origin/master | 67 ------------------- .../origin/master => ProfileException.php} | 0 ...tion.php~implement TwingleShop integration | 18 ----- .../master => ProfileValidationError.php} | 9 +-- ...rror.php~implement TwingleShop integration | 37 ---------- 6 files changed, 19 insertions(+), 129 deletions(-) delete mode 100644 Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master rename Civi/Twingle/Exceptions/{ProfileException.php~refs/remotes/origin/master => ProfileException.php} (100%) delete mode 100644 Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration rename Civi/Twingle/Exceptions/{ProfileValidationError.php~refs/remotes/origin/master => ProfileValidationError.php} (88%) delete mode 100644 Civi/Twingle/Exceptions/ProfileValidationError.php~implement TwingleShop integration diff --git a/Civi/Twingle/Exceptions/BaseException.php b/Civi/Twingle/Exceptions/BaseException.php index 57e4660..f1ce9e3 100644 --- a/Civi/Twingle/Exceptions/BaseException.php +++ b/Civi/Twingle/Exceptions/BaseException.php @@ -1,4 +1,21 @@ . + */ + +declare(strict_types = 1); namespace Civi\Twingle\Exceptions; diff --git a/Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master b/Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master deleted file mode 100644 index a5413d5..0000000 --- a/Civi/Twingle/Exceptions/BaseException.php~refs/remotes/origin/master +++ /dev/null @@ -1,67 +0,0 @@ -. - */ - -declare(strict_types = 1); - -namespace Civi\Twingle\Exceptions; - -use CRM_Twingle_ExtensionUtil as E; - -/** - * A simple custom exception class that indicates a problem within a class - * of the Twingle API extension. - */ -class BaseException extends \Exception { - - /** - * @var string - */ - protected $code; - protected string $log_message; - - /** - * BaseException Constructor - * @param string $message - * Error message - * @param string $error_code - * A meaningful error code - * @param \Throwable $previous - * A previously thrown exception to include. - */ - public function __construct(string $message = '', string $error_code = '', \Throwable $previous = NULL) { - parent::__construct($message, 1, $previous); - $this->log_message = '' !== $message ? E::LONG_NAME . ': ' . $message : ''; - $this->code = $error_code; - } - - /** - * Returns the error message, but with the extension name prefixed. - * @return string - */ - public function getLogMessage() { - return $this->log_message; - } - - /** - * Returns the error code. - * @return string - */ - public function getErrorCode() { - return $this->code; - } - -} diff --git a/Civi/Twingle/Exceptions/ProfileException.php~refs/remotes/origin/master b/Civi/Twingle/Exceptions/ProfileException.php similarity index 100% rename from Civi/Twingle/Exceptions/ProfileException.php~refs/remotes/origin/master rename to Civi/Twingle/Exceptions/ProfileException.php diff --git a/Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration b/Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration deleted file mode 100644 index b9e5954..0000000 --- a/Civi/Twingle/Exceptions/ProfileException.php~implement TwingleShop integration +++ /dev/null @@ -1,18 +0,0 @@ -affected_field_name = $affected_field_name; } diff --git a/Civi/Twingle/Exceptions/ProfileValidationError.php~implement TwingleShop integration b/Civi/Twingle/Exceptions/ProfileValidationError.php~implement TwingleShop integration deleted file mode 100644 index a678ba7..0000000 --- a/Civi/Twingle/Exceptions/ProfileValidationError.php~implement TwingleShop integration +++ /dev/null @@ -1,37 +0,0 @@ -affected_field_name = $affected_field_name; - } - - /** - * Returns the name of the profile field that caused the exception. - * @return string - */ - public function getAffectedFieldName() { - return $this->affected_field_name; - } - -} From 477c57ca53f2a485d6d72d3d84dc64d174052a2f Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 26 Apr 2024 16:24:23 +0200 Subject: [PATCH 203/221] fix another messed up merge --- api/v3/TwingleDonation/Submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 17cb107..013dc73 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -255,7 +255,7 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) { 'type' => CRM_Utils_Type::T_STRING, 'api.required' => 0, 'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'), - ); + ]; $params['products'] = [ 'name' => 'products', 'title' => E::ts('Products'), From d3ccb3b09264a27c87e15c8ffb53801908819cd1 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Wed, 8 May 2024 17:27:39 +0200 Subject: [PATCH 204/221] allow products with self-selected price --- CRM/Twingle/Submission.php | 5 ++- Civi/Twingle/Shop/BAO/TwingleProduct.php | 41 +++++++++++++++++--- Civi/Twingle/Shop/Utils/TwingleShopUtils.php | 15 ++++--- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 606a714..48c658a 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -46,6 +46,7 @@ class CRM_Twingle_Submission { * List of allowed product attributes. */ const ALLOWED_PRODUCT_ATTRIBUTES = [ + 'id', 'name', 'internal_id', 'price', @@ -513,8 +514,8 @@ class CRM_Twingle_Submission { // If found, use the financial type and price field id from the price field if ($price_field) { - // Log warning if price differs from the submission - if ($price_field->price != (int) $product['price']) { + // Log warning if price is not variable and differs from the submission + if ($price_field->price !== Null && $price_field->price != (int) $product['price']) { Civi::log()->warning(E::LONG_NAME . ": Price for product " . $product['name'] . " differs from the PriceField. " . "Using the price from the submission.", ['price_field' => $price_field->price, 'submission' => $product['price']]); diff --git a/Civi/Twingle/Shop/BAO/TwingleProduct.php b/Civi/Twingle/Shop/BAO/TwingleProduct.php index d6448b2..62f37c3 100644 --- a/Civi/Twingle/Shop/BAO/TwingleProduct.php +++ b/Civi/Twingle/Shop/BAO/TwingleProduct.php @@ -14,7 +14,7 @@ use CRM_Utils_Type; use function Civi\Twingle\Shop\Utils\convert_int_to_bool; use function Civi\Twingle\Shop\Utils\convert_str_to_date; use function Civi\Twingle\Shop\Utils\convert_str_to_int; -use function Civi\Twingle\Shop\Utils\convert_null_to_int; +use function Civi\Twingle\Shop\Utils\convert_empty_string_to_null; use function Civi\Twingle\Shop\Utils\filter_attributes; use function Civi\Twingle\Shop\Utils\validate_data_types; @@ -112,9 +112,9 @@ class TwingleProduct extends TwingleProductDAO { ]; /** - * Attributes that need to be converted from NULL to int. + * Empty string to null conversion. */ - protected const NULL_TO_INT_CONVERSION = [ + protected const EMPTY_STRING_TO_NULL = [ "price", ]; @@ -198,6 +198,28 @@ class TwingleProduct extends TwingleProductDAO { self::CAN_BE_ZERO, ); + // Does this product allow to enter a custom price? + $custom_price = array_key_exists('price', $product_data) && $product_data['price'] === Null; + if (!$custom_price && isset($product_data['price_field_id'])) { + try { + $price_field = civicrm_api3('PriceField', 'getsingle', [ + 'id' => $product_data['price_field_id'], + 'return' => 'is_enter_qty', + ]); + $custom_price = (bool) $price_field['is_enter_qty']; + } + catch (CRM_Core_Exception $e) { + throw new ProductException( + E::ts("Could not find PriceField for Twingle Product ['id': %1, 'external_id': %2]: %3", + [ + 1 => $product_data['id'], + 2 => $product_data['external_id'], + 3 => $e->getMessage(), + ]), + ProductException::ERROR_CODE_PRICE_FIELD_NOT_FOUND); + } + } + // Amend data from corresponding PriceFieldValue if (isset($product_data['price_field_id'])) { try { @@ -216,7 +238,7 @@ class TwingleProduct extends TwingleProductDAO { ProductException::ERROR_CODE_PRICE_FIELD_VALUE_NOT_FOUND); } $product_data['name'] = $product_data['name'] ?? $price_field_value['label']; - $product_data['price'] = $product_data['price'] ?? $price_field_value['amount']; + $product_data['price'] = $custom_price ? Null : $product_data['price'] ?? $price_field_value['amount']; $product_data['financial_type_id'] = $product_data['financial_type_id'] ?? $price_field_value['financial_type_id']; $product_data['is_active'] = $product_data['is_active'] ?? $price_field_value['is_active']; $product_data['sort'] = $product_data['sort'] ?? $price_field_value['weight']; @@ -228,7 +250,7 @@ class TwingleProduct extends TwingleProductDAO { convert_str_to_int($product_data, self::STR_TO_INT_CONVERSION); convert_int_to_bool($product_data, self::INT_TO_BOOL_CONVERSION); convert_str_to_date($product_data, self::STR_TO_DATE_CONVERSION); - convert_null_to_int($product_data, self::NULL_TO_INT_CONVERSION); + convert_empty_string_to_null($product_data, self::EMPTY_STRING_TO_NULL); } catch (\Exception $e) { throw new ProductException($e->getMessage(), ProductException::ERROR_CODE_ATTRIBUTE_WRONG_DATA_TYPE); @@ -308,6 +330,13 @@ class TwingleProduct extends TwingleProductDAO { 'html_type' => 'Text', 'is_required' => false, ]; + + // If the product has no fixed price, allow the user to enter a custom price + if ($this->price === Null) { + $price_field_data['is_enter_qty'] = true; + $price_field_data['is_display_amounts'] = false; + } + // Add id if in edit mode if ($mode == 'edit') { $price_field_data['id'] = $this->price_field_id; @@ -348,7 +377,7 @@ class TwingleProduct extends TwingleProductDAO { 'price_field_id' => $this->price_field_id, 'financial_type_id' => $this->financial_type_id, 'label' => $this->name, - 'amount' => $this->price, + 'amount' => $this->price === Null ? 1 : $this->price, 'is_active' => $this->is_active, 'description' => $this->description, ]; diff --git a/Civi/Twingle/Shop/Utils/TwingleShopUtils.php b/Civi/Twingle/Shop/Utils/TwingleShopUtils.php index 5ee45f7..0638615 100644 --- a/Civi/Twingle/Shop/Utils/TwingleShopUtils.php +++ b/Civi/Twingle/Shop/Utils/TwingleShopUtils.php @@ -45,7 +45,7 @@ function filter_attributes(array &$data, array $allowed_attributes, array $can_b function convert_str_to_int(array &$data, array $str_to_int_conversion): void { // Convert string to int foreach ($str_to_int_conversion as $attribute) { - if (isset($data[$attribute])) { + if (isset($data[$attribute]) && $data[$attribute] !== '') { try { $data[$attribute] = (int) $data[$attribute]; } catch (\Exception $e) { @@ -108,18 +108,17 @@ function convert_str_to_date(array &$data, array $str_to_date_conversion): void } /** - * Convert null to int + * Convert an empty string to null. * * @param array $data - * @param array $null_to_int_conversion + * @param array $empty_string_to_null * * @return void */ -function convert_null_to_int(array &$data, array $null_to_int_conversion): void { - // Convert null to int - foreach ($null_to_int_conversion as $attribute) { - if (array_key_exists($attribute, $data) && $data[$attribute] === NULL) { - $data[$attribute] = 0; +function convert_empty_string_to_null(array &$data, array $empty_string_to_null): void { + foreach ($empty_string_to_null as $attribute) { + if (isset($data[$attribute]) && $data[$attribute] === '') { + $data[$attribute] = NULL; } } } From 33cb076d42a51d2c40b7aae0cb6ba4aee8238637 Mon Sep 17 00:00:00 2001 From: Marc Michalsky Date: Fri, 10 May 2024 10:51:19 +0200 Subject: [PATCH 205/221] activate update button on financial type change --- js/twingle_shop.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/js/twingle_shop.js b/js/twingle_shop.js index fb7dd40..68c9d89 100644 --- a/js/twingle_shop.js +++ b/js/twingle_shop.js @@ -219,6 +219,11 @@ class Product { button.disabled = true; } + // Deactivate 'update' button if product is not outdated + if (action === 'update' && !this.isOutdated) { + button.disabled = true; + } + // Add icon const icon = document.createElement('i'); const iconClass = action === 'create' ? 'fa-plus-circle' : action === 'update' ? 'fa-refresh' : 'fa-trash'; @@ -357,13 +362,11 @@ class Product { // Determine actions; if product has price field id, it can be updated or // deleted, otherwise it can be created if (this.priceFieldId) { - if (this.isOutdated) { + if (!this.isOrphaned) { actionsAndHandlers.push(['update', this.createPriceFieldHandler()]); - } else if (!this.isOrphaned) { - actionsAndHandlers.push(['update', null]); } actionsAndHandlers.push(['delete', this.deletePriceFieldHandler()]); - } else { + } else if (!this.isOrphaned) { actionsAndHandlers.push(['create', this.createPriceFieldHandler()]); } @@ -410,10 +413,10 @@ class Product { let self = this; dropdown.onchange = function () { - // Enable 'create' button if financial type is selected - const createButton = document.getElementById('twingle_product_tw_' + self.externalId).getElementsByClassName('twingle-shop-cell-button')[0]; - if (createButton.textContent.includes('Create')) { - createButton.disabled = dropdown.value === '0'; + // Enable 'create' or 'update' button if financial type is selected + const button = document.getElementById('twingle_product_tw_' + self.externalId).getElementsByClassName('twingle-shop-cell-button')[0]; + if (button.textContent.includes('Create') || button.textContent.includes('Update')) { + button.disabled = dropdown.value === '0'; } // Update financial type From 8de34f7b2ab7733825a7bdc064c743535e880419 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 3 Sep 2024 13:19:27 +0200 Subject: [PATCH 206/221] Version 1.5-beta1 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index d715ec8..f58beb4 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.5-dev - dev + 2024-09-03 + 1.5-beta1 + beta 5.58 From 7cca29b458322b32065433dda2cd4e727e8e78ed Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 3 Sep 2024 13:19:48 +0200 Subject: [PATCH 207/221] Back to 1.5-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index f58beb4..d715ec8 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2024-09-03 - 1.5-beta1 - beta + + 1.5-dev + dev 5.58 From 64d6b48813338c1f210d1d9cc9adbd51aeb3afe2 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 11 Sep 2024 12:59:22 +0200 Subject: [PATCH 208/221] Fix DAO/BAO namespaces and definitions --- .../Twingle}/BAO/TwingleProduct.php | 24 +++++++------------ .../Shop => CRM/Twingle}/BAO/TwingleShop.php | 23 +++++++----------- .../Twingle}/DAO/TwingleProduct.php | 18 +++++++------- .../Shop => CRM/Twingle}/DAO/TwingleShop.php | 12 ++++------ info.xml | 11 +++++---- twingle.civix.php | 22 ----------------- .../CRM/Twingle/TwingleProduct.entityType.php | 2 +- xml/schema/CRM/Twingle/TwingleProduct.xml | 2 +- .../CRM/Twingle/TwingleShop.entityType.php | 2 +- xml/schema/CRM/Twingle/TwingleShop.xml | 2 +- 10 files changed, 41 insertions(+), 77 deletions(-) rename {Civi/Twingle/Shop => CRM/Twingle}/BAO/TwingleProduct.php (96%) rename {Civi/Twingle/Shop => CRM/Twingle}/BAO/TwingleShop.php (95%) rename {Civi/Twingle/Shop => CRM/Twingle}/DAO/TwingleProduct.php (94%) rename {Civi/Twingle/Shop => CRM/Twingle}/DAO/TwingleShop.php (96%) diff --git a/Civi/Twingle/Shop/BAO/TwingleProduct.php b/CRM/Twingle/BAO/TwingleProduct.php similarity index 96% rename from Civi/Twingle/Shop/BAO/TwingleProduct.php rename to CRM/Twingle/BAO/TwingleProduct.php index 62f37c3..f696807 100644 --- a/Civi/Twingle/Shop/BAO/TwingleProduct.php +++ b/CRM/Twingle/BAO/TwingleProduct.php @@ -1,16 +1,10 @@ [$external_id, 'String']]); if ($dao->fetch()) { $product = new self(); @@ -456,7 +450,7 @@ class TwingleProduct extends TwingleProductDAO { // Try to lookup object in database try { - $dao = TwingleShopDAO::executeQuery("SELECT * FROM civicrm_twingle_product WHERE external_id = %1", + $dao = CRM_Twingle_BAO_TwingleShop::executeQuery("SELECT * FROM civicrm_twingle_product WHERE external_id = %1", [1 => [$this->external_id, 'String']]); if ($dao->fetch()) { $this->copyValues(array_merge($dao->toArray(), $this->getAttributes())); @@ -514,7 +508,7 @@ class TwingleProduct extends TwingleProductDAO { /** * Delete TwingleProduct along with associated PriceField and PriceFieldValue. * - * @override \Civi\Twingle\Shop\DAO\TwingleProduct::delete + * @override \CRM_Twingle_DAO_TwingleProduct::delete * @throws \CRM_Core_Exception * @throws \Civi\Twingle\Shop\Exceptions\ProductException */ @@ -570,7 +564,7 @@ class TwingleProduct extends TwingleProductDAO { /** * Compare two products * - * @param TwingleProduct $product_to_compare_with + * @param CRM_Twingle_BAO_TwingleProduct $product_to_compare_with * Product from database * * @return bool @@ -592,7 +586,7 @@ class TwingleProduct extends TwingleProductDAO { */ public function getFinancialTypeId(): ?int { if (!empty($this->price_field_id)) { - $price_set = \Civi\Api4\PriceField::get() + $price_set = PriceField::get() ->addSelect('financial_type_id') ->addWhere('id', '=', $this->price_field_id) ->execute() @@ -610,7 +604,7 @@ class TwingleProduct extends TwingleProductDAO { */ public function getPriceFieldValueId() { if (!empty($this->price_field_id)) { - $price_field_value = \Civi\Api4\PriceFieldValue::get() + $price_field_value = PriceFieldValue::get() ->addSelect('id') ->addWhere('price_field_id', '=', $this->price_field_id) ->execute() diff --git a/Civi/Twingle/Shop/BAO/TwingleShop.php b/CRM/Twingle/BAO/TwingleShop.php similarity index 95% rename from Civi/Twingle/Shop/BAO/TwingleShop.php rename to CRM/Twingle/BAO/TwingleShop.php index c27853c..dd49596 100644 --- a/Civi/Twingle/Shop/BAO/TwingleShop.php +++ b/CRM/Twingle/BAO/TwingleShop.php @@ -1,15 +1,10 @@ \CRM_Utils_Type::T_INT, @@ -64,14 +59,14 @@ class TwingleShop extends TwingleShopDAO { * @param string $project_identifier * Twingle project identifier * - * @return TwingleShop + * @return CRM_Twingle_BAO_TwingleShop * * @throws ShopException * @throws \Civi\Twingle\Shop\Exceptions\ApiCallError * @throws \CRM_Core_Exception */ public static function findByProjectIdentifier(string $project_identifier) { - $shop = new TwingleShop(); + $shop = new CRM_Twingle_BAO_TwingleShop(); $shop->get('project_identifier', $project_identifier); if (!$shop->id) { $shop->fetchDataFromTwingle($project_identifier); @@ -147,7 +142,7 @@ class TwingleShop extends TwingleShopDAO { // Try to lookup object in database try { - $dao = TwingleShopDAO::executeQuery("SELECT * FROM civicrm_twingle_shop WHERE project_identifier = %1", + $dao = self::executeQuery("SELECT * FROM civicrm_twingle_shop WHERE project_identifier = %1", [1 => [$this->project_identifier, 'String']]); if ($dao->fetch()) { $this->load($dao->toArray()); @@ -259,7 +254,7 @@ class TwingleShop extends TwingleShopDAO { }, []); foreach ($products_from_db as $product) { - /* @var TwingleProductBAO $product */ + /* @var CRM_Twingle_BAO_TwingleProduct $product */ // Find orphaned products which are in the database but not in Twingle $found = array_key_exists($product->external_id, $products_from_twingle); @@ -286,8 +281,8 @@ class TwingleShop extends TwingleShopDAO { foreach ($products_from_twingle as $product_from_twingle) { $found = array_key_exists($product_from_twingle['id'], $products); if (!$found) { - $product = new TwingleProduct(); - $product->load(TwingleProduct::renameTwingleAttrs($product_from_twingle)); + $product = new CRM_Twingle_BAO_TwingleProduct(); + $product->load(CRM_Twingle_BAO_TwingleProduct::renameTwingleAttrs($product_from_twingle)); $product->twingle_shop_id = $this->id; $this->products[] = $product; } @@ -305,13 +300,13 @@ class TwingleShop extends TwingleShopDAO { public function getProducts() { $products = []; - $result = TwingleProductBAO::executeQuery( + $result = CRM_Twingle_BAO_TwingleProduct::executeQuery( "SELECT * FROM civicrm_twingle_product WHERE twingle_shop_id = %1", [1 => [$this->id, 'Integer']] ); while ($result->fetch()) { - $product = new TwingleProductBAO(); + $product = new CRM_Twingle_BAO_TwingleProduct(); $product->load($result->toArray()); $products[] = $product; } diff --git a/Civi/Twingle/Shop/DAO/TwingleProduct.php b/CRM/Twingle/DAO/TwingleProduct.php similarity index 94% rename from Civi/Twingle/Shop/DAO/TwingleProduct.php rename to CRM/Twingle/DAO/TwingleProduct.php index 9d4f075..3adeae7 100644 --- a/Civi/Twingle/Shop/DAO/TwingleProduct.php +++ b/CRM/Twingle/DAO/TwingleProduct.php @@ -1,7 +1,5 @@ 'civicrm_twingle_product.id', 'table_name' => 'civicrm_twingle_product', 'entity' => 'TwingleProduct', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'bao' => 'CRM_Twingle_DAO_TwingleProduct', 'localizable' => 0, 'html' => [ 'type' => 'Number', @@ -167,7 +165,7 @@ class TwingleProduct extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_product.external_id', 'table_name' => 'civicrm_twingle_product', 'entity' => 'TwingleProduct', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'bao' => 'CRM_Twingle_DAO_TwingleProduct', 'localizable' => 0, 'html' => [ 'type' => 'Number', @@ -189,7 +187,7 @@ class TwingleProduct extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_product.price_field_id', 'table_name' => 'civicrm_twingle_product', 'entity' => 'TwingleProduct', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'bao' => 'CRM_Twingle_DAO_TwingleProduct', 'localizable' => 0, 'FKClassName' => 'CRM_Contact_DAO_Contact', 'add' => NULL, @@ -208,9 +206,9 @@ class TwingleProduct extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_product.twingle_shop_id', 'table_name' => 'civicrm_twingle_product', 'entity' => 'TwingleProduct', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'bao' => 'CRM_Twingle_DAO_TwingleProduct', 'localizable' => 0, - 'FKClassName' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'FKClassName' => 'CRM_Twingle_DAO_TwingleShop', 'add' => NULL, ], 'created_at' => [ @@ -228,7 +226,7 @@ class TwingleProduct extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_product.created_at', 'table_name' => 'civicrm_twingle_product', 'entity' => 'TwingleProduct', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'bao' => 'CRM_Twingle_DAO_TwingleProduct', 'localizable' => 0, 'add' => NULL, ], @@ -247,7 +245,7 @@ class TwingleProduct extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_product.updated_at', 'table_name' => 'civicrm_twingle_product', 'entity' => 'TwingleProduct', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'bao' => 'CRM_Twingle_DAO_TwingleProduct', 'localizable' => 0, 'add' => NULL, ], diff --git a/Civi/Twingle/Shop/DAO/TwingleShop.php b/CRM/Twingle/DAO/TwingleShop.php similarity index 96% rename from Civi/Twingle/Shop/DAO/TwingleShop.php rename to CRM/Twingle/DAO/TwingleShop.php index bef6db7..4b6e704 100644 --- a/Civi/Twingle/Shop/DAO/TwingleShop.php +++ b/CRM/Twingle/DAO/TwingleShop.php @@ -1,7 +1,5 @@ 'civicrm_twingle_shop.id', 'table_name' => 'civicrm_twingle_shop', 'entity' => 'TwingleShop', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'bao' => 'CRM_Twingle_DAO_TwingleShop', 'localizable' => 0, 'html' => [ 'type' => 'Number', @@ -159,7 +157,7 @@ class TwingleShop extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_shop.project_identifier', 'table_name' => 'civicrm_twingle_shop', 'entity' => 'TwingleShop', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'bao' => 'CRM_Twingle_DAO_TwingleShop', 'localizable' => 0, 'html' => [ 'type' => 'Text', @@ -181,7 +179,7 @@ class TwingleShop extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_shop.numerical_project_id', 'table_name' => 'civicrm_twingle_shop', 'entity' => 'TwingleShop', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'bao' => 'CRM_Twingle_DAO_TwingleShop', 'localizable' => 0, 'html' => [ 'type' => 'Number', @@ -202,7 +200,7 @@ class TwingleShop extends \CRM_Core_DAO { 'where' => 'civicrm_twingle_shop.price_set_id', 'table_name' => 'civicrm_twingle_shop', 'entity' => 'TwingleShop', - 'bao' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'bao' => 'CRM_Twingle_DAO_TwingleShop', 'localizable' => 0, 'FKClassName' => 'CRM_Price_DAO_PriceSet', 'add' => NULL, diff --git a/info.xml b/info.xml index d715ec8..c019d80 100644 --- a/info.xml +++ b/info.xml @@ -20,7 +20,11 @@ 5.58 - + + + + + de.systopia.xcm @@ -32,10 +36,7 @@ menu-xml@1.0.0 mgd-php@1.0.0 smarty-v2@1.0.1 + entity-types-php@1.0.0 - - - - CRM_Twingle_Upgrader diff --git a/twingle.civix.php b/twingle.civix.php index 6d84d1c..c207adf 100644 --- a/twingle.civix.php +++ b/twingle.civix.php @@ -198,25 +198,3 @@ function _twingle_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) { } } } - -/** - * (Delegated) Implements hook_civicrm_entityTypes(). - * - * Find any *.entityType.php files, merge their content, and return. - * - * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes - */ -function _twingle_civix_civicrm_entityTypes(&$entityTypes) { - $entityTypes = array_merge($entityTypes, [ - 'Civi\Twingle\Shop\DAO\TwingleProduct' => [ - 'name' => 'TwingleProduct', - 'class' => 'Civi\Twingle\Shop\DAO\TwingleProduct', - 'table' => 'civicrm_twingle_product', - ], - 'Civi\Twingle\Shop\DAO\TwingleShop' => [ - 'name' => 'TwingleShop', - 'class' => 'Civi\Twingle\Shop\DAO\TwingleShop', - 'table' => 'civicrm_twingle_shop', - ], - ]); -} diff --git a/xml/schema/CRM/Twingle/TwingleProduct.entityType.php b/xml/schema/CRM/Twingle/TwingleProduct.entityType.php index 5b8879b..153d50b 100644 --- a/xml/schema/CRM/Twingle/TwingleProduct.entityType.php +++ b/xml/schema/CRM/Twingle/TwingleProduct.entityType.php @@ -4,7 +4,7 @@ return [ [ 'name' => 'TwingleProduct', - 'class' => 'Civi\Twingle\Shop\DAO\TwingleProduct', + 'class' => 'CRM_Twingle_DAO_TwingleProduct', 'table' => 'civicrm_twingle_product', ], ]; diff --git a/xml/schema/CRM/Twingle/TwingleProduct.xml b/xml/schema/CRM/Twingle/TwingleProduct.xml index 5787e69..4b6e48a 100644 --- a/xml/schema/CRM/Twingle/TwingleProduct.xml +++ b/xml/schema/CRM/Twingle/TwingleProduct.xml @@ -1,7 +1,7 @@ - CRM/Twingle/Shop + CRM/TwingleTwingleProductcivicrm_twingle_productThis table contains the Twingle Product data. diff --git a/xml/schema/CRM/Twingle/TwingleShop.entityType.php b/xml/schema/CRM/Twingle/TwingleShop.entityType.php index 34e6ce2..5fe53ea 100644 --- a/xml/schema/CRM/Twingle/TwingleShop.entityType.php +++ b/xml/schema/CRM/Twingle/TwingleShop.entityType.php @@ -4,7 +4,7 @@ return [ [ 'name' => 'TwingleShop', - 'class' => 'Civi\Twingle\Shop\DAO\TwingleShop', + 'class' => 'CRM_Twingle_DAO_TwingleShop', 'table' => 'civicrm_twingle_shop', ], ]; diff --git a/xml/schema/CRM/Twingle/TwingleShop.xml b/xml/schema/CRM/Twingle/TwingleShop.xml index 3d9d6ba..5b45a77 100644 --- a/xml/schema/CRM/Twingle/TwingleShop.xml +++ b/xml/schema/CRM/Twingle/TwingleShop.xml @@ -1,7 +1,7 @@
    - CRM/Twingle/Shop + CRM/TwingleTwingleShopcivicrm_twingle_shopThis table contains the Twingle Shop data. Each Twingle Shop is linked to a corresponding Price Set. From 4ae20a1b04f283c900b0866003050f1ca9d06d6c Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 11 Sep 2024 13:19:54 +0200 Subject: [PATCH 209/221] Fix form template issues (help texts, undefined template variables, etc.) --- CRM/Twingle/Form/Settings.php | 40 ++++++++++++------------- templates/CRM/Twingle/Form/Profile.hlp | 4 +-- templates/CRM/Twingle/Form/Settings.hlp | 4 +++ templates/CRM/Twingle/Form/Settings.tpl | 20 ++++--------- 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php index a92535e..450b52a 100644 --- a/CRM/Twingle/Form/Settings.php +++ b/CRM/Twingle/Form/Settings.php @@ -29,16 +29,16 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { * List of all settings options. */ public static $SETTINGS_LIST = [ - 'twingle_prefix', - 'twingle_use_sepa', - 'twingle_dont_use_reference', - 'twingle_protect_recurring', - 'twingle_protect_recurring_activity_type', - 'twingle_protect_recurring_activity_subject', - 'twingle_protect_recurring_activity_status', - 'twingle_protect_recurring_activity_assignee', - 'twingle_use_shop', - 'twingle_access_key', + 'twingle_prefix', + 'twingle_use_sepa', + 'twingle_dont_use_reference', + 'twingle_protect_recurring', + 'twingle_protect_recurring_activity_type', + 'twingle_protect_recurring_activity_subject', + 'twingle_protect_recurring_activity_status', + 'twingle_protect_recurring_activity_assignee', + 'twingle_use_shop', + 'twingle_access_key', ]; /** @@ -110,22 +110,22 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { $this->add( 'checkbox', 'twingle_use_shop', - E::ts("Use Twingle Shop Integration") + E::ts('Use Twingle Shop Integration') ); $this->add( 'text', 'twingle_access_key', - E::ts("Twingle Access Key") + E::ts('Twingle Access Key') ); - $this->addButtons(array( - array ( - 'type' => 'submit', - 'name' => E::ts('Save'), - 'isDefault' => TRUE, - ) - )); + $this->addButtons([ + [ + 'type' => 'submit', + 'name' => E::ts('Save'), + 'isDefault' => TRUE, + ], + ]); // set defaults foreach (self::$SETTINGS_LIST as $setting) { @@ -164,7 +164,7 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form { CRM_Utils_Array::value('twingle_use_shop', $this->_submitValues) && !CRM_Utils_Array::value('twingle_access_key', $this->_submitValues, FALSE) ) { - $this->_errors['twingle_access_key'] = E::ts("An Access Key is required to enable Twingle Shop Integration"); + $this->_errors['twingle_access_key'] = E::ts('An Access Key is required to enable Twingle Shop Integration'); } return (0 == count($this->_errors)); diff --git a/templates/CRM/Twingle/Form/Profile.hlp b/templates/CRM/Twingle/Form/Profile.hlp index 8098450..5e1a401 100644 --- a/templates/CRM/Twingle/Form/Profile.hlp +++ b/templates/CRM/Twingle/Form/Profile.hlp @@ -91,7 +91,7 @@ {/htxt} {htxt id='id-shop_map_products'} -

    {ts domain="de.systopia.twingle"}If this option is enabled, all Twingle Shop products corresponding to the specified project IDs will be retrieved from Twingle and mapped as price sets and price fields. Each Twingle Shop is mapped as a price set with its products as price fields.

    -

    This allows you to manually create contributions with the same line items for phone orders, for example, as would be the case for orders placed through the Twingle Shop.

    +

    {ts domain="de.systopia.twingle"}If this option is enabled, all Twingle Shop products corresponding to the specified project IDs will be retrieved from Twingle and mapped as price sets and price fields. Each Twingle Shop is mapped as a price set with its products as price fields.{/ts}

    +

    {ts domain="de.systopia.twingle"}This allows you to manually create contributions with the same line items for phone orders, for example, as would be the case for orders placed through the Twingle Shop.{/ts}

    {/htxt} {/crmScope} diff --git a/templates/CRM/Twingle/Form/Settings.hlp b/templates/CRM/Twingle/Form/Settings.hlp index bfd00e2..fe0d483 100644 --- a/templates/CRM/Twingle/Form/Settings.hlp +++ b/templates/CRM/Twingle/Form/Settings.hlp @@ -31,3 +31,7 @@ {htxt id='id-twingle_use_shop'} {ts domain="de.systopia.twingle"}If you enable Twingle Shop integration, you can configure Twingle API profiles to include products ordered through Twingle Shop as line items in the created contribution.{/ts} {/htxt} + +{htxt id='id-twingle_access_key'} + {ts domain="de.systopia.twingle"}Enter your twingle API access key.{/ts} +{/htxt} diff --git a/templates/CRM/Twingle/Form/Settings.tpl b/templates/CRM/Twingle/Form/Settings.tpl index 906a91c..b13760a 100644 --- a/templates/CRM/Twingle/Form/Settings.tpl +++ b/templates/CRM/Twingle/Form/Settings.tpl @@ -89,24 +89,16 @@
    - - + - - +
    {$form.twingle_use_shop.label}   - {$form.twingle_use_shop.html} -
    - - {$formElements.twingle_use_shop.description} - +
    {$form.twingle_use_shop.label} + {help id="id-twingle_use_shop" title=$form.twingle_use_shop.label} {$form.twingle_use_shop.html}
    {$form.twingle_access_key.label}   - {$form.twingle_access_key.html} -
    - - {$formElements.twingle_access_key.description} - +
    {$form.twingle_access_key.label} + {help id="id-twingle_access_key" title=$form.twingle_access_key.label} {$form.twingle_access_key.html}
    From fa301676e389ee9d8ebf448f7f5e2ba85cd594eb Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 11 Sep 2024 13:30:39 +0200 Subject: [PATCH 210/221] Update translation template and fix incorrect use of ts() --- CRM/Twingle/BAO/TwingleProduct.php | 21 +- CRM/Twingle/BAO/TwingleShop.php | 18 +- CRM/Twingle/Form/Profile.php | 3 +- CRM/Twingle/Submission.php | 2 +- l10n/de.systopia.twingle.pot | 1092 +++++++++++++++++++++------- 5 files changed, 862 insertions(+), 274 deletions(-) diff --git a/CRM/Twingle/BAO/TwingleProduct.php b/CRM/Twingle/BAO/TwingleProduct.php index f696807..c782314 100644 --- a/CRM/Twingle/BAO/TwingleProduct.php +++ b/CRM/Twingle/BAO/TwingleProduct.php @@ -458,7 +458,7 @@ class CRM_Twingle_BAO_TwingleProduct extends CRM_Twingle_DAO_TwingleProduct { } catch (\Civi\Core\Exception\DBQueryException $e) { throw new ProductException( - E::ts('Could not find TwingleProduct in database: ' . $e->getMessage()), + E::ts('Could not find TwingleProduct in database: %1', [1 => $e->getMessage()]), ShopException::ERROR_CODE_COULD_NOT_FIND_SHOP_IN_DB); } @@ -466,7 +466,8 @@ class CRM_Twingle_BAO_TwingleProduct extends CRM_Twingle_DAO_TwingleProduct { $twingle_product_values = $this->getAttributes(); try { \CRM_Utils_Hook::pre($mode, 'TwingleProduct', $this->id, $twingle_product_values); - } catch (\Exception $e) { + } + catch (\Exception $e) { $tx->rollback(); throw $e; } @@ -481,14 +482,15 @@ class CRM_Twingle_BAO_TwingleProduct extends CRM_Twingle_DAO_TwingleProduct { // Save object to database try { $this->save(); - } catch (\Exception $e) { + } + catch (\Exception $e) { $tx->rollback(); throw new ProductException( - E::ts('Could not save TwingleProduct to database: ' . $e->getMessage()), + E::ts('Could not save TwingleProduct to database: %1', [1 => $e->getMessage()]), ProductException::ERROR_CODE_COULD_NOT_CREATE_PRODUCT); } $result = self::findById($this->id); - /* @var self $result */ + /** @var self $result */ $this->load($result->getAttributes()); // Register post-hook @@ -629,7 +631,7 @@ class CRM_Twingle_BAO_TwingleProduct extends CRM_Twingle_DAO_TwingleProduct { } catch (CRM_Core_Exception $e) { throw new ProductException( - E::ts('An Error occurred while searching for the associated PriceFieldValue: ' . $e->getMessage()), + E::ts('An Error occurred while searching for the associated PriceFieldValue: %1', [1 => $e->getMessage()]), ProductException::ERROR_CODE_PRICE_FIELD_VALUE_NOT_FOUND); } try { @@ -637,7 +639,7 @@ class CRM_Twingle_BAO_TwingleProduct extends CRM_Twingle_DAO_TwingleProduct { } catch (CRM_Core_Exception $e) { throw new ProductException( - E::ts('Could not delete associated PriceFieldValue: ' . $e->getMessage()), + E::ts('Could not delete associated PriceFieldValue: %1', [1 => $e->getMessage()]), ProductException::ERROR_CODE_COULD_NOT_DELETE_PRICE_FIELD_VALUE); } @@ -661,13 +663,14 @@ class CRM_Twingle_BAO_TwingleProduct extends CRM_Twingle_DAO_TwingleProduct { } catch (CRM_Core_Exception $e) { throw new ProductException( - E::ts('An Error occurred while searching for the associated PriceField: ' . $e->getMessage()), + E::ts('An Error occurred while searching for the associated PriceField: %1', [1 => $e->getMessage()]), ProductException::ERROR_CODE_PRICE_FIELD_NOT_FOUND); } throw new ProductException( - E::ts('Could not delete associated PriceField: ' . $e->getMessage()), + E::ts('Could not delete associated PriceField: %1', [1 => $e->getMessage()]), ProductException::ERROR_CODE_COULD_NOT_DELETE_PRICE_FIELD); } $this->price_field_id = NULL; } + } diff --git a/CRM/Twingle/BAO/TwingleShop.php b/CRM/Twingle/BAO/TwingleShop.php index dd49596..a4b006c 100644 --- a/CRM/Twingle/BAO/TwingleShop.php +++ b/CRM/Twingle/BAO/TwingleShop.php @@ -147,9 +147,10 @@ class CRM_Twingle_BAO_TwingleShop extends CRM_Twingle_DAO_TwingleShop { if ($dao->fetch()) { $this->load($dao->toArray()); } - } catch (\Civi\Core\Exception\DBQueryException $e) { + } + catch (\Civi\Core\Exception\DBQueryException $e) { throw new ShopException( - E::ts('Could not find TwingleShop in database: ' . $e->getMessage()), + E::ts('Could not find TwingleShop in database: %1', [1 => $e->getMessage()]), ShopException::ERROR_CODE_COULD_NOT_FIND_SHOP_IN_DB); } @@ -191,7 +192,7 @@ class CRM_Twingle_BAO_TwingleShop extends CRM_Twingle_DAO_TwingleShop { catch (\CRM_Core_Exception $e) { if ($e->getMessage() != 'Expected one PriceSet but found 0') { throw new ShopException( - E::ts('Could not find associated PriceSet: ' . $e->getMessage()), + E::ts('Could not find associated PriceSet: %1', [1 => $e->getMessage()]), ShopException::ERROR_CODE_PRICE_SET_NOT_FOUND); } else { @@ -207,7 +208,7 @@ class CRM_Twingle_BAO_TwingleShop extends CRM_Twingle_DAO_TwingleShop { ['id' => $this->price_set_id]); } catch (\CRM_Core_Exception $e) { throw new ShopException( - E::ts('Could not delete associated PriceSet: ' . $e->getMessage()), + E::ts('Could not delete associated PriceSet: %1', [1 => $e->getMessage()]), ShopException::ERROR_CODE_COULD_NOT_DELETE_PRICE_SET); } @@ -451,9 +452,10 @@ class CRM_Twingle_BAO_TwingleShop extends CRM_Twingle_DAO_TwingleShop { public function deleteProducts() { try { $products = $this->getProducts(); - } catch (\Civi\Core\Exception\DBQueryException $e) { + } + catch (\Civi\Core\Exception\DBQueryException $e) { throw new ProductException( - E::ts('Could not retrieve associated products: ' . $e->getMessage()), + E::ts('Could not retrieve associated products: %1', [1 => $e->getMessage()]), ProductException::ERROR_CODE_COULD_NOT_GET_PRODUCTS ); } @@ -464,8 +466,8 @@ class CRM_Twingle_BAO_TwingleShop extends CRM_Twingle_DAO_TwingleShop { } catch (ProductException $e) { throw new ProductException( - E::ts('Could not delete associated products: ' . $e->getMessage()), - ProductException::ERROR_CODE_COULD_NOT_DELETE_PRICE_SET + E::ts('Could not delete associated products: %1', [1 => $e->getMessage()]), + ProductException::ERROR_CODE_COULD_NOT_DELETE_PRICE_SET, ); } } diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php index 73022cd..76c9cb4 100644 --- a/CRM/Twingle/Form/Profile.php +++ b/CRM/Twingle/Form/Profile.php @@ -648,8 +648,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form { if (!isset($profile_data[$key]) && $required) { CRM_Core_Session::setStatus( E::ts( - 'The required configuration option "%1" has no value.' - . ' Saving the profile might set this option to a possibly unwanted default value.', + 'The required configuration option "%1" has no value. Saving the profile might set this option to a possibly unwanted default value.', [1 => $metadata['label'] ?? $key] ), E::ts('Error'), diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 48c658a..2c3e85d 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -546,7 +546,7 @@ class CRM_Twingle_Submission { if (!empty($line_item['is_error'])) { $line_item_name = $line_item_data['name']; throw new CiviCRM_API3_Exception( - E::ts("Could not create line item for product '$line_item_name'"), + E::ts("Could not create line item for product '%1'", [1 => $line_item_name]), 'api_error' ); } diff --git a/l10n/de.systopia.twingle.pot b/l10n/de.systopia.twingle.pot index 439b9b5..2a38969 100644 --- a/l10n/de.systopia.twingle.pot +++ b/l10n/de.systopia.twingle.pot @@ -1,1016 +1,1600 @@ -#: ./CRM/Twingle/Config.php +#: CRM/Twingle/Config.php msgid "No" msgstr "" -#: ./CRM/Twingle/Config.php +#: CRM/Twingle/Config.php msgid "Raise Exception" msgstr "" -#: ./CRM/Twingle/Config.php +#: CRM/Twingle/Config.php msgid "Create Activity" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Profile with ID \"%1\" not found" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Delete Twingle API profile %1" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Page/Profiles.tpl msgid "Reset" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl +#: CRM/Twingle/Form/Profile.php js/twingle_shop.js templates/CRM/Twingle/Page/Profiles.tpl msgid "Delete" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "The profile is invalid and cannot be copied." msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Error" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "The profile to be copied could not be found." msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "A database error has occurred. See the log for details." msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "New Twingle API profile" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Edit Twingle API profile %1" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "New Profile" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Page/Profiles.tpl +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Page/Profiles.tpl msgid "Profile name" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php templates/CRM/Twingle/Form/Profile.tpl msgid "Project IDs" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Contact Matcher (XCM) Profile" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php templates/CRM/Twingle/Form/Profile.tpl msgid "Location type" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php templates/CRM/Twingle/Form/Profile.tpl msgid "Location type for organisations" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php templates/CRM/Twingle/Form/Profile.tpl msgid "Financial type" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php templates/CRM/Twingle/Form/Profile.tpl msgid "Financial type (recurring)" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Gender option for submitted value \"male\"" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Gender option for submitted value \"female\"" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Gender option for submitted value \"other\"" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Prefix option for submitted value \"male\"" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Prefix option for submitted value \"female\"" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "Prefix option for submitted value \"other\"" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Record %1 as" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Record %1 donations with contribution status" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Profile.php +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Profile.php msgid "CiviSEPA creditor" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Use Double-Opt-In for newsletter" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Sign up for newsletter groups" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Sign up for postal mail groups" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Sign up for Donation receipt groups" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Default Campaign" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "- none -" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Set Campaign for" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Contribution" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Recurring Contribution" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Membership" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "SEPA Mandate" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Contacts (XCM)" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Create membership of type" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Create membership of type (recurring)" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "API Call for Membership Postprocessing" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "The API call must have the form 'Entity.Action'." msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Contribution source" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl msgid "Required address components" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Street" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Postal Code" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php msgid "City" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php msgid "Country" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./templates/CRM/Twingle/Form/Profile.tpl +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl msgid "Custom field mapping" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Create contribution notes for" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php msgid "Purpose" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./api/v3/TwingleDonation/Submit.php +#: CRM/Twingle/Form/Profile.php api/v3/TwingleDonation/Submit.php msgid "Remarks" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Create contact notes for" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "User Extra Field" msgstr "" -#: ./CRM/Twingle/Form/Profile.php ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl +msgid "Enable Shop Integration" +msgstr "" + +#: CRM/Twingle/Form/Profile.php +msgid "Default Financial Type" +msgstr "" + +#: CRM/Twingle/Form/Profile.php +msgid "Financial Type for top up donations" +msgstr "" + +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl +msgid "Map Products as Price Fields" +msgstr "" + +#: CRM/Twingle/Form/Profile.php CRM/Twingle/Form/Settings.php msgid "Save" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "Warning" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php +msgid "The required configuration option \"%1\" has no value. Saving the profile might set this option to a possibly unwanted default value." +msgstr "" + +#: CRM/Twingle/Form/Profile.php msgid "No profile set." msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "<select profile>" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "none" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "CiviSEPA" msgstr "" -#: ./CRM/Twingle/Form/Profile.php +#: CRM/Twingle/Form/Profile.php msgid "No mailing lists available" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Twingle ID Prefix" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Use CiviSEPA" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Use CiviSEPA generated reference" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Protect Recurring Contributions" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Activity Type" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Subject" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Status" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php msgid "Assigned To" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php +msgid "Use Twingle Shop Integration" +msgstr "" + +#: CRM/Twingle/Form/Settings.php +msgid "Twingle Access Key" +msgstr "" + +#: CRM/Twingle/Form/Settings.php msgid "This is required for activity creation" msgstr "" -#: ./CRM/Twingle/Form/Settings.php +#: CRM/Twingle/Form/Settings.php +msgid "An Access Key is required to enable Twingle Shop Integration" +msgstr "" + +#: CRM/Twingle/Form/Settings.php msgid "-select-" msgstr "" -#: ./CRM/Twingle/Page/Profiles.php ./managed/Navigation__twingle_configuration.mgd.php +#: CRM/Twingle/Page/Profiles.php managed/Navigation__twingle_configuration.mgd.php msgid "Twingle API Profiles" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Unknown attribute %1." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Profile name cannot be empty." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Only alphanumeric characters, space and the underscore (_) are allowed for profile names." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "A profile with the name '%1' already exists." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Project ID(s) [%1] already used in profile '%2'." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Could not parse custom field mapping." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Custom field custom_%1 does not exist." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities." msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Could not save/update profile: %1" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Could not reset default profile: %1" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Could not delete profile: %1" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Contribution Status" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Bank transfer" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Debit manual" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Debit automatic" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Credit card" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Mobile phone Germany" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "PayPal" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "SOFORT Überweisung" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Amazon Pay" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Apple Pay" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Google Pay" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Paydirekt" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Twint" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "iDEAL" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Postfinance" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Bancontact" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "Generic Payment Method" msgstr "" -#: ./CRM/Twingle/Profile.php +#: CRM/Twingle/Profile.php msgid "never" msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Invalid donation rhythm." msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Payment method could not be matched to existing payment instrument." msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Invalid date for parameter \"confirmed_at\"." msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Invalid date for parameter \"user_birthdate\"." msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Gender could not be matched to existing gender." msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Invalid format for custom fields." msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php +msgid "Invalid format for products." +msgstr "" + +#: CRM/Twingle/Submission.php msgid "campaign_id must be a numeric string. " msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Unknown country %1." msgstr "" -#: ./CRM/Twingle/Submission.php +#: CRM/Twingle/Submission.php msgid "Could not calculate SEPA cycle day from configuration." msgstr "" -#: ./CRM/Twingle/Tools.php +#: CRM/Twingle/Submission.php +msgid "Could not create line item for product '%1'" +msgstr "" + +#: CRM/Twingle/Submission.php +msgid "Could not create line item for donation" +msgstr "" + +#: CRM/Twingle/Tools.php msgid "This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected." msgstr "" -#: ./CRM/Twingle/Tools.php +#: CRM/Twingle/Tools.php msgid "Recurring contribution [%1] (Transaction ID '%2') was terminated by a user. You need to end the corresponding record in Twingle as well, or it will still be collected." msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +#: Civi/Twingle/Shop/ApiCall.php +msgid "Could not find Twingle API token" +msgstr "" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "Call to Twingle API failed. Please check your api token." +msgstr "" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "GET curl failed" +msgstr "" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "http status code 404 (not found)" +msgstr "" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "https status code 500 (internal error)" +msgstr "" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "Connection not yet established. Use connect() method." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not find PriceField for Twingle Product ['id': %1, 'external_id': %2]: %3" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not find PriceFieldValue for Twingle Product ['id': %1, 'external_id': %2]: %3" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "PriceField for this Twingle Product already exists." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "PriceField for this Twingle Product does not exist and cannot be edited." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not check if PriceField for this Twingle Product already exists." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not find PriceSet for this Twingle Product." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not create PriceField for this Twingle Product: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not find PriceFieldValue for this Twingle Product: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not create PriceFieldValue for this Twingle Product: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not find TwingleProduct in database: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not save TwingleProduct to database: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "An Error occurred while searching for the associated PriceFieldValue: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not delete associated PriceFieldValue: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "PriceField for this Twingle Product still exists." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "An Error occurred while searching for the associated PriceField: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleProduct.php +msgid "Could not delete associated PriceField: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not find TwingleShop in database: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not find associated PriceSet: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not delete associated PriceSet: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "PriceSet for this Twingle Shop already exists." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "PriceSet for this Twingle Shop does not exist and cannot be edited." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not check if PriceSet for this TwingleShop already exists." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not create PriceSet for this TwingleShop." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "This Twingle Project is not a shop." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not retrieve Twingle projects from API.\n Please check your API credentials." +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not retrieve associated products: %1" +msgstr "" + +#: Civi/Twingle/Shop/BAO/TwingleShop.php +msgid "Could not delete associated products: %1" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "Twingle Products" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "Twingle Product" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "Unique TwingleProduct ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "External ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "The ID of this product in the Twingle database" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php api/v3/TwingleProduct/Get.php +msgid "Price Field ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "FK to Price Field" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php api/v3/TwingleProduct/Create.php +msgid "Twingle Shop ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "FK to Twingle Shop" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "Created At" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "Timestamp of when the product was created in the database" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "Updated At" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleProduct.php +msgid "Timestamp of when the product was last updated in the database" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "Twingle Shops" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "Twingle Shop" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "Unique TwingleShop ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Create.php api/v3/TwingleShop/Delete.php api/v3/TwingleShop/Get.php +msgid "Project Identifier" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "Twingle Project Identifier" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "Numerical Project ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "Numerical Twingle Project Identifier" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php api/v3/TwingleShop/Get.php +msgid "Price Set ID" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "FK to Price Set" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php api/v3/TwingleShop/Get.php +msgid "Name" +msgstr "" + +#: Civi/Twingle/Shop/DAO/TwingleShop.php +msgid "name of the shop" +msgstr "" + +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php api/v3/TwingleDonation/Submit.php msgid "Project ID" msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php api/v3/TwingleDonation/Submit.php msgid "The Twingle project ID." msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php api/v3/TwingleDonation/Submit.php msgid "Transaction ID" msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php api/v3/TwingleDonation/Submit.php msgid "The unique transaction ID of the donation" msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php +#: api/v3/TwingleDonation/Cancel.php msgid "Cancelled at" msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php +#: api/v3/TwingleDonation/Cancel.php msgid "The date when the donation was cancelled, format: YmdHis." msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php +#: api/v3/TwingleDonation/Cancel.php msgid "Cancel reason" msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php +#: api/v3/TwingleDonation/Cancel.php msgid "The reason for the donation being cancelled." msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php +#: api/v3/TwingleDonation/Cancel.php msgid "Invalid date for parameter \"cancelled_at\"." msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php +#: api/v3/TwingleDonation/Cancel.php msgid "SEPA Mandate for contribution [%1 not found." msgstr "" -#: ./api/v3/TwingleDonation/Cancel.php ./api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php msgid "Could not terminate SEPA mandate" msgstr "" -#: ./api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Endrecurring.php msgid "Ended at" msgstr "" -#: ./api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Endrecurring.php msgid "The date when the recurring donation was ended, format: YmdHis." msgstr "" -#: ./api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Endrecurring.php msgid "Invalid date for parameter \"ended_at\"." msgstr "" -#: ./api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Endrecurring.php msgid "SEPA Mandate for recurring contribution [%1 not found." msgstr "" -#: ./api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Endrecurring.php msgid "SEPA Mandate [%1] already terminated." msgstr "" -#: ./api/v3/TwingleDonation/Endrecurring.php +#: api/v3/TwingleDonation/Endrecurring.php msgid "Mandate closed by TwingleDonation.Endrecurring API call" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Confirmed at" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The date when the donation was issued, format: YmdHis." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The purpose of the donation." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Amount" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The donation amount in minor currency unit." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Currency" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The ISO-4217 currency code of the donation." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Newsletter" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Whether to subscribe the contact to the newsletter group defined in the profile." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Postal mailing" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Whether to subscribe the contact to the postal mailing group defined in the profile." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Donation receipt" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Whether the contact requested a donation receipt." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Payment method" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The Twingle payment method used for the donation." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Donation rhythm" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The interval which the donation is recurring in." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "SEPA IBAN" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The IBAN for SEPA Direct Debit payments, conforming with ISO 13616-1:2007." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "SEPA BIC" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The BIC for SEPA Direct Debit payments, conforming with ISO 9362." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "SEPA Direct Debit Mandate reference" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The mandate reference for SEPA Direct Debit payments." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "SEPA Direct Debit Account holder" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The account holder for SEPA Direct Debit payments." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Anonymous donation" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Whether the donation is submitted anonymously." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Gender" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The gender of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Date of birth" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The date of birth of the contact, format: Ymd." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Formal title" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The formal title of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Email address" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The e-mail address of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "First name" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The first name of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Last name" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The last name of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Street address" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The street address of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Postal code" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The postal code of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The city of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The country of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Telephone" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The telephone number of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Company" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The company of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Language" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The preferred language of the contact. A 2-digit ISO-639-1 language code." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "User extra field" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Additional information of the contact." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Campaign ID" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "The CiviCRM ID of a campaign to assign the contribution." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Custom fields" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Additional information for either the contact or the (recurring) contribution." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php +msgid "Products" +msgstr "" + +#: api/v3/TwingleDonation/Submit.php +msgid "Products ordered via TwingleShop" +msgstr "" + +#: api/v3/TwingleDonation/Submit.php msgid "Additional remarks for the donation." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Contribution with the given transaction ID already exists." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Organisation contact could not be found or created." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Individual contact could not be found or created." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Missing attribute %1 for SEPA mandate" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "SEPA creditor is not configured for profile \"%1\"." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Could not create recurring contribution." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Could not find recurring contribution with given parent transaction ID." msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Could not create contribution" msgstr "" -#: ./api/v3/TwingleDonation/Submit.php +#: api/v3/TwingleDonation/Submit.php msgid "Twingle membership postprocessing call has failed, see log for more information" msgstr "" -#: ./managed/Navigation__twingle_configuration.mgd.php +#: api/v3/TwingleProduct/Create.php api/v3/TwingleProduct/Delete.php api/v3/TwingleProduct/Get.php +msgid "TwingleProduct ID" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "The TwingleProduct ID in the database" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Twingle ID" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "External product ID in Twingle database" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "ID of the corresponding Twingle Shop" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Product Name" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Name of the product" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Is active?" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Is the product active?" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Product Description" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Short description of the product" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Product Price" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Price of the product" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Sort" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Sort order of the product" +msgstr "" + +#: api/v3/TwingleProduct/Create.php api/v3/TwingleShop/Create.php +msgid "Financial Type ID" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "ID of the financial type of the product" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "FK to TwingleShop" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Twingle timestamp" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "Timestamp of last update in Twingle db" +msgstr "" + +#: api/v3/TwingleProduct/Create.php +msgid "FK to PriceField" +msgstr "" + +#: api/v3/TwingleProduct/Delete.php api/v3/TwingleProduct/Get.php +msgid "The TwingleProduct ID in CiviCRM" +msgstr "" + +#: api/v3/TwingleProduct/Delete.php api/v3/TwingleProduct/Get.php +msgid "External TwingleProduct ID" +msgstr "" + +#: api/v3/TwingleProduct/Delete.php api/v3/TwingleProduct/Get.php +msgid "Twingle's ID of the product" +msgstr "" + +#: api/v3/TwingleProduct/Delete.php +msgid "TwingleProduct could not be deleted." +msgstr "" + +#: api/v3/TwingleProduct/Get.php +msgid "FK to civicrm_price_field" +msgstr "" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Delete.php api/v3/TwingleShop/Get.php +msgid "TwingleShop ID" +msgstr "" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Delete.php api/v3/TwingleShop/Get.php +msgid "The TwingleShop ID in CiviCRM" +msgstr "" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Create.php api/v3/TwingleShop/Delete.php api/v3/TwingleShop/Get.php +msgid "Twingle project identifier" +msgstr "" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Create.php api/v3/TwingleShop/Get.php +msgid "Numerical Project Identifier" +msgstr "" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Get.php +msgid "Twingle numerical project identifier" +msgstr "" + +#: api/v3/TwingleShop/Create.php +msgid "Numerical Twingle project identifier" +msgstr "" + +#: api/v3/TwingleShop/Create.php +msgid "Shop Name" +msgstr "" + +#: api/v3/TwingleShop/Create.php +msgid "Name of the shop" +msgstr "" + +#: api/v3/TwingleShop/Create.php +msgid "FK to civicrm_financial_type" +msgstr "" + +#: api/v3/TwingleShop/Delete.php +msgid "TwingleShop could not be found." +msgstr "" + +#: api/v3/TwingleShop/Delete.php +msgid "TwingleShop could not be deleted." +msgstr "" + +#: api/v3/TwingleShop/Fetch.php +msgid "Project Identifiers" +msgstr "" + +#: api/v3/TwingleShop/Fetch.php +msgid "Comma separated list of Twingle project identifiers." +msgstr "" + +#: api/v3/TwingleShop/Get.php +msgid "Name of the TwingleShop" +msgstr "" + +#: api/v3/TwingleShop/Get.php +msgid "FK to civicrm_price_set" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not fetch products" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not fetch products. Please check your Twingle API key." +msgstr "" + +#: js/twingle_shop.js +msgid "Create" +msgstr "" + +#: js/twingle_shop.js +msgid "Update" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not create Price Field for this product" +msgstr "" + +#: js/twingle_shop.js +msgid "Delete Price Field" +msgstr "" + +#: js/twingle_shop.js +msgid "Are you sure you want to delete the price field associated with this product?" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not delete Price Field" +msgstr "" + +#: js/twingle_shop.js +msgid "The Price Field was deleted successfully." +msgstr "" + +#: js/twingle_shop.js +msgid "Price Field deleted" +msgstr "" + +#: js/twingle_shop.js +msgid "select financial type" +msgstr "" + +#: js/twingle_shop.js +msgid "Product" +msgstr "" + +#: js/twingle_shop.js +msgid "Financial Type" +msgstr "" + +#: js/twingle_shop.js +msgid "Price Field" +msgstr "" + +#: js/twingle_shop.js +msgid "Create Price Set" +msgstr "" + +#: js/twingle_shop.js +msgid "Update Price Set" +msgstr "" + +#: js/twingle_shop.js +msgid "Delete Price Set" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not create Twingle Shop" +msgstr "" + +#: js/twingle_shop.js +msgid "The Price Set was created successfully." +msgstr "" + +#: js/twingle_shop.js +msgid "Price Field created" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not create TwingleShop" +msgstr "" + +#: js/twingle_shop.js +msgid "Are you sure you want to delete the price set associated with this Twingle Shop?" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not delete Twingle Shop" +msgstr "" + +#: js/twingle_shop.js +msgid "The Price Set was deleted successfully." +msgstr "" + +#: js/twingle_shop.js +msgid "Price Set deleted" +msgstr "" + +#: js/twingle_shop.js +msgid "Could not update Twingle Shop" +msgstr "" + +#: managed/Navigation__twingle_configuration.mgd.php msgid "Twingle API Configuration" msgstr "" -#: ./managed/Navigation__twingle_configuration.mgd.php +#: managed/Navigation__twingle_configuration.mgd.php msgid "Twingle API Settings" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Select which location type to use for addresses for individuals, either when no organisation name is specified, or an organisation address can not be shared with the individual contact." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Put your project's Twingle ID in here, to activate this profile for that project." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "You can also provide multiple project IDs separated by a comma." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "The Contact Matcher (XCM) manages the identification or creation of the related contact." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "We recommend creating a new XCM profile only to be used with the Twingle API." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Select which location type to use for addresses for organisations and shared organisation addresses for individual contacts." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Select which financial type to use for one-time contributions." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Select which financial type to use for recurring contributions." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Select whether to use CiviCRM's Double-Opt-In feature for subscribing to mailing lists. Note that this only works for public mailing lists. Any non-public mailing list selected above will be ignored when this setting is enabled." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Also, do not forget to disable Twingle's own Double Opt-In option in the Twingle Manager to avoid subscribers receiving multiple confirmation e-mails. Only one or the other option should be enabled." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Some organisations have specific conventions on how a membership should be created. Since the Twingle-API can only create a \"bare bone\" membership object, you can enter a API Call (as 'Entity.Action') to adjust any newly created membership to your organisation's needs." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "The API call would receive the following parameters:
      \n
    • membership_id: The ID of the newly created membership
    • \n
    • contact_id: The ID of the contact involved
    • \n
    • organization_id: The ID of the contact's organisation, potentially empty
    • \n
    • contribution_id: The ID contribution received, potentially empty
    • \n
    • recurring_contribution_id: The ID of the recurring contribution. If empty, this was only a one-off donation.
    • \n
    " msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Select the address components that must be present to create or update an address for the contact." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Depending on your XCM settings, the transferred address might replace an existing one." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "Since in some cases Twingle send the country of the user as the only address parameter, depending on your XCM configuration, not declaring other address components as required might lead to the current user address being overwritten with an address containing the country only." msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "

    Map Twingle custom fields to CiviCRM fields using the following format (each assignment in a separate line):

    \n
    twingle_field_1=custom_123
    twingle_field_2=custom_789
    \n

    Always use the custom_[id] notation for CiviCRM custom fields.

    \n

    This works for fields that Twingle themselves provide in the custom_fields parameter, and for any other parameter (e.g. user_extrafield)

    \n

    Only custom fields extending one of the following CiviCRM entities are allowed:

    \n
      \n
    • Contact – Will be set on the Individual contact
    • \n
    • Individual – Will be set on the Individual contact
    • \n
    • Organization – Will be set on the Organization contact, if an organisation name was submitted
    • \n
    • Contribution – Will be set on the contribution
    • \n
    • ContributionRecur – Will be set on the recurring contribution and deriving single contributions
    • \n
    " msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "

    Create a contribution note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.hlp +#: templates/CRM/Twingle/Form/Profile.hlp msgid "

    Create a contact note for each field specified in this selection.

    \n

    Tip: You can enable or disable this fields in the TwingleMANAGER.

    " msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "Enable the processing of orders via Twingle Shop for this profile. The ordered products will then appear as line items in the contribution." +msgstr "" + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "If this option is enabled, all Twingle Shop products corresponding to the specified project IDs will be retrieved from Twingle and mapped as price sets and price fields. Each Twingle Shop is mapped as a price set with its products as price fields." +msgstr "" + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "This allows you to manually create contributions with the same line items for phone orders, for example, as would be the case for orders placed through the Twingle Shop." +msgstr "" + +#: templates/CRM/Twingle/Form/Profile.tpl msgid "General settings" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Help" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "XCM Profile" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Gender/Prefix for value 'male'" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Gender/Prefix for value 'female'" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Gender/Prefix for value 'other'" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Payment methods" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Groups and Correlations" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Newsletter Double Opt-In" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Membership Postprocessing" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl templates/CRM/Twingle/Page/Profiles.tpl +msgid "Shop Integration" +msgstr "" + +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to reset the default profile?" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to delete the profile %1?" msgstr "" -#: ./templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Form/Profile.tpl msgid "Profile name not given or invalid." msgstr "" -#: ./templates/CRM/Twingle/Form/Settings.hlp +#: templates/CRM/Twingle/Form/Settings.hlp msgid "When the %1 is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the debit_manual payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data." msgstr "" -#: ./templates/CRM/Twingle/Form/Settings.hlp +#: templates/CRM/Twingle/Form/Settings.hlp msgid "When the %1 is enabled, you can activate this to use your own references instead of the ones submitted by Twingle." msgstr "" -#: ./templates/CRM/Twingle/Form/Settings.hlp +#: templates/CRM/Twingle/Form/Settings.hlp msgid "Will protect all recurring contributions created by Twingle from termination, since this does NOT terminate the Twingle collection process" msgstr "" -#: ./templates/CRM/Twingle/Form/Settings.hlp +#: templates/CRM/Twingle/Form/Settings.hlp msgid "You can use this setting to add a prefix to the Twingle transaction ID, in order to avoid collisions with other transaction ids." msgstr "" -#: ./templates/CRM/Twingle/Page/Configuration.tpl +#: templates/CRM/Twingle/Form/Settings.hlp +msgid "If you enable Twingle Shop integration, you can configure Twingle API profiles to include products ordered through Twingle Shop as line items in the created contribution." +msgstr "" + +#: templates/CRM/Twingle/Form/Settings.hlp +msgid "Enter your twingle API access key." +msgstr "" + +#: templates/CRM/Twingle/Page/Configuration.tpl msgid "Profiles" msgstr "" -#: ./templates/CRM/Twingle/Page/Configuration.tpl +#: templates/CRM/Twingle/Page/Configuration.tpl msgid "Configure profiles" msgstr "" -#: ./templates/CRM/Twingle/Page/Configuration.tpl +#: templates/CRM/Twingle/Page/Configuration.tpl msgid "Settings" msgstr "" -#: ./templates/CRM/Twingle/Page/Configuration.tpl +#: templates/CRM/Twingle/Page/Configuration.tpl msgid "Configure extension settings" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "New profile" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Selectors" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Used" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Last Used" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Operations" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "enabled" +msgstr "" + +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "disabled" +msgstr "" + +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Edit profile %1" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Edit" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Copy profile %1" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Copy" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Reset profile %1" msgstr "" -#: ./templates/CRM/Twingle/Page/Profiles.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Delete profile %1" msgstr "" -#: ./twingle.php +#: twingle.php msgid "Twingle API: Access Twingle API" msgstr "" -#: ./twingle.php +#: twingle.php msgid "Allows access to the Twingle API actions." msgstr "" From 612224901aa1dbf4b6969302f0133f1fe7cd606d Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 24 Sep 2024 14:28:34 +0200 Subject: [PATCH 211/221] Update translation template --- l10n/de.systopia.twingle.pot | 416 +++++++++++++++++------------------ 1 file changed, 208 insertions(+), 208 deletions(-) diff --git a/l10n/de.systopia.twingle.pot b/l10n/de.systopia.twingle.pot index 2a38969..e358b75 100644 --- a/l10n/de.systopia.twingle.pot +++ b/l10n/de.systopia.twingle.pot @@ -1,3 +1,111 @@ +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not find PriceField for Twingle Product ['id': %1, 'external_id': %2]: %3" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not find PriceFieldValue for Twingle Product ['id': %1, 'external_id': %2]: %3" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "PriceField for this Twingle Product already exists." +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "PriceField for this Twingle Product does not exist and cannot be edited." +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not check if PriceField for this Twingle Product already exists." +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not find PriceSet for this Twingle Product." +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not create PriceField for this Twingle Product: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not find PriceFieldValue for this Twingle Product: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not create PriceFieldValue for this Twingle Product: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not find TwingleProduct in database: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not save TwingleProduct to database: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "An Error occurred while searching for the associated PriceFieldValue: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not delete associated PriceFieldValue: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "PriceField for this Twingle Product still exists." +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "An Error occurred while searching for the associated PriceField: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleProduct.php +msgid "Could not delete associated PriceField: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not find TwingleShop in database: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not find associated PriceSet: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not delete associated PriceSet: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "PriceSet for this Twingle Shop already exists." +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "PriceSet for this Twingle Shop does not exist and cannot be edited." +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not check if PriceSet for this TwingleShop already exists." +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not create PriceSet for this TwingleShop." +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "This Twingle Project is not a shop." +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not retrieve Twingle projects from API.\n Please check your API credentials." +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not retrieve associated products: %1" +msgstr "" + +#: CRM/Twingle/BAO/TwingleShop.php +msgid "Could not delete associated products: %1" +msgstr "" + #: CRM/Twingle/Config.php msgid "No" msgstr "" @@ -10,6 +118,106 @@ msgstr "" msgid "Create Activity" msgstr "" +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "Twingle Products" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "Twingle Product" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php CRM/Twingle/DAO/TwingleShop.php +msgid "ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "Unique TwingleProduct ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "External ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "The ID of this product in the Twingle database" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php api/v3/TwingleProduct/Get.php +msgid "Price Field ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "FK to Price Field" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php api/v3/TwingleProduct/Create.php +msgid "Twingle Shop ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "FK to Twingle Shop" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "Created At" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "Timestamp of when the product was created in the database" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "Updated At" +msgstr "" + +#: CRM/Twingle/DAO/TwingleProduct.php +msgid "Timestamp of when the product was last updated in the database" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "Twingle Shops" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "Twingle Shop" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "Unique TwingleShop ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Create.php api/v3/TwingleShop/Delete.php api/v3/TwingleShop/Get.php +msgid "Project Identifier" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "Twingle Project Identifier" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "Numerical Project ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "Numerical Twingle Project Identifier" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php api/v3/TwingleShop/Get.php +msgid "Price Set ID" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "FK to Price Set" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php api/v3/TwingleShop/Get.php +msgid "Name" +msgstr "" + +#: CRM/Twingle/DAO/TwingleShop.php +msgid "name of the shop" +msgstr "" + #: CRM/Twingle/Form/Profile.php msgid "Profile with ID \"%1\" not found" msgstr "" @@ -530,214 +738,6 @@ msgstr "" msgid "Connection not yet established. Use connect() method." msgstr "" -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not find PriceField for Twingle Product ['id': %1, 'external_id': %2]: %3" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not find PriceFieldValue for Twingle Product ['id': %1, 'external_id': %2]: %3" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "PriceField for this Twingle Product already exists." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "PriceField for this Twingle Product does not exist and cannot be edited." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not check if PriceField for this Twingle Product already exists." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not find PriceSet for this Twingle Product." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not create PriceField for this Twingle Product: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not find PriceFieldValue for this Twingle Product: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not create PriceFieldValue for this Twingle Product: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not find TwingleProduct in database: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not save TwingleProduct to database: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "An Error occurred while searching for the associated PriceFieldValue: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not delete associated PriceFieldValue: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "PriceField for this Twingle Product still exists." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "An Error occurred while searching for the associated PriceField: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleProduct.php -msgid "Could not delete associated PriceField: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not find TwingleShop in database: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not find associated PriceSet: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not delete associated PriceSet: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "PriceSet for this Twingle Shop already exists." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "PriceSet for this Twingle Shop does not exist and cannot be edited." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not check if PriceSet for this TwingleShop already exists." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not create PriceSet for this TwingleShop." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "This Twingle Project is not a shop." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not retrieve Twingle projects from API.\n Please check your API credentials." -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not retrieve associated products: %1" -msgstr "" - -#: Civi/Twingle/Shop/BAO/TwingleShop.php -msgid "Could not delete associated products: %1" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "Twingle Products" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "Twingle Product" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "Unique TwingleProduct ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "External ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "The ID of this product in the Twingle database" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php api/v3/TwingleProduct/Get.php -msgid "Price Field ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "FK to Price Field" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php api/v3/TwingleProduct/Create.php -msgid "Twingle Shop ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "FK to Twingle Shop" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "Created At" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "Timestamp of when the product was created in the database" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "Updated At" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleProduct.php -msgid "Timestamp of when the product was last updated in the database" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "Twingle Shops" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "Twingle Shop" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "Unique TwingleShop ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Create.php api/v3/TwingleShop/Delete.php api/v3/TwingleShop/Get.php -msgid "Project Identifier" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "Twingle Project Identifier" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "Numerical Project ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "Numerical Twingle Project Identifier" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php api/v3/TwingleShop/Get.php -msgid "Price Set ID" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "FK to Price Set" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php api/v3/TwingleShop/Get.php -msgid "Name" -msgstr "" - -#: Civi/Twingle/Shop/DAO/TwingleShop.php -msgid "name of the shop" -msgstr "" - #: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php api/v3/TwingleDonation/Submit.php msgid "Project ID" msgstr "" From 30c34f72bea38791c0b9f57eed0aa567aa79eeae Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 24 Sep 2024 14:29:26 +0200 Subject: [PATCH 212/221] Version 1.5-beta2 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index c019d80..6e2d126 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.5-dev - dev + 2024-09-24 + 1.5-beta2 + beta 5.58 From 9c9fed20d7d698bac1eb4ffba15de79bae613ed9 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 24 Sep 2024 14:29:38 +0200 Subject: [PATCH 213/221] Back to 1.5-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 6e2d126..c019d80 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2024-09-24 - 1.5-beta2 - beta + + 1.5-dev + dev 5.58 From 82456d2ae43370915c56e9e0c43a73e4c27c2368 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 1 Oct 2024 14:24:23 +0200 Subject: [PATCH 214/221] Update German translation --- l10n/de_DE/LC_MESSAGES/twingle.mo | Bin 29888 -> 44836 bytes l10n/de_DE/LC_MESSAGES/twingle.po | 658 +++++++++++++++++++++++++++++- 2 files changed, 657 insertions(+), 1 deletion(-) diff --git a/l10n/de_DE/LC_MESSAGES/twingle.mo b/l10n/de_DE/LC_MESSAGES/twingle.mo index 78498f0172762c1ca981c4a566147748306906b4..b7c97292a885e91d1eba63ab908501a13fe7c5f9 100644 GIT binary patch literal 44836 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 löschen" msgid "Reset" msgstr "Zurücksetzen" -#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Page/Profiles.tpl +#: CRM/Twingle/Form/Profile.php js/twingle_shop.js +#: templates/CRM/Twingle/Page/Profiles.tpl msgid "Delete" msgstr "Löschen" @@ -254,6 +490,22 @@ msgstr "Kontakt-Notizen erstellen für" msgid "User Extra Field" msgstr "Benutzer-Extra-Feld" +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl +msgid "Enable Shop Integration" +msgstr "Shop-Integration aktivieren" + +#: CRM/Twingle/Form/Profile.php +msgid "Default Financial Type" +msgstr "Standard-Zuwendungsart" + +#: CRM/Twingle/Form/Profile.php +msgid "Financial Type for top up donations" +msgstr "Zuwendungsart für zusätzliche Spenden" + +#: CRM/Twingle/Form/Profile.php templates/CRM/Twingle/Form/Profile.tpl +msgid "Map Products as Price Fields" +msgstr "Produkte Preisfeldern zuordnen" + #: CRM/Twingle/Form/Profile.php CRM/Twingle/Form/Settings.php msgid "Save" msgstr "Speichern" @@ -262,6 +514,15 @@ msgstr "Speichern" msgid "Warning" msgstr "Warnung" +#: CRM/Twingle/Form/Profile.php +msgid "" +"The required configuration option \"%1\" has no value. Saving the profile " +"might set this option to a possibly unwanted default value." +msgstr "" +"Die erforderliche Konfigurationsoption \"%1\" hat keinen Wert. Das Speichern " +"des Profils könnte diese Option auf einen möglicherweise ungewollten " +"Standardwert setzen." + #: CRM/Twingle/Form/Profile.php msgid "No profile set." msgstr "Kein Profil eingestellt." @@ -314,10 +575,24 @@ msgstr "Status" msgid "Assigned To" msgstr "Zugewiesen an" +#: CRM/Twingle/Form/Settings.php +msgid "Use Twingle Shop Integration" +msgstr "Twingle-Shop-Integration verwenden" + +#: CRM/Twingle/Form/Settings.php +msgid "Twingle Access Key" +msgstr "Twingle-Zugriffsschlüssel" + #: CRM/Twingle/Form/Settings.php msgid "This is required for activity creation" msgstr "Diese Angaben sind erforderlich für das Erstellen von Aktivitäten" +#: CRM/Twingle/Form/Settings.php +msgid "An Access Key is required to enable Twingle Shop Integration" +msgstr "" +"Ein Zugriffsschlüssel ist für die Aktivierung der Twingle-Shop-Integration " +"erforderlich" + #: CRM/Twingle/Form/Settings.php msgid "-select-" msgstr "- auswählen -" @@ -478,6 +753,10 @@ msgstr "" msgid "Invalid format for custom fields." msgstr "Ungültiges Format für benutzerdefinierte Felder." +#: CRM/Twingle/Submission.php +msgid "Invalid format for products." +msgstr "Ungültiges Format für Produkte." + #: CRM/Twingle/Submission.php msgid "campaign_id must be a numeric string. " msgstr "campaign_id muss eine numerische Zeichenkette sein. " @@ -490,6 +769,14 @@ msgstr "Unbekanntes Land %1." msgid "Could not calculate SEPA cycle day from configuration." msgstr "SEPA-Einzugstag konnte nicht aus der Konfiguration berechnet werden." +#: CRM/Twingle/Submission.php +msgid "Could not create line item for product '%1'" +msgstr "Belegzeile für Produkt konnte nicht erstellt werden: %1" + +#: CRM/Twingle/Submission.php +msgid "Could not create line item for donation" +msgstr "Belegzeile für Spende konnte nicht erstellt werden" + #: CRM/Twingle/Tools.php msgid "" "This is a Twingle recurring contribution. It should be terminated through " @@ -508,6 +795,30 @@ msgstr "" "Benutzer beendet. Es ist erforderlich, den zugehörigen Datensatz auch in " "Twingle zu beenden, da die Zuwendung ansonsten weiter eingezogen wird." +#: Civi/Twingle/Shop/ApiCall.php +msgid "Could not find Twingle API token" +msgstr "Twingle-API-Token konnte nicht gefunden werden" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "Call to Twingle API failed. Please check your api token." +msgstr "Aufruf der Twingle-API fehlgeschlagen. Überprüfen Sie Ihren API-Token." + +#: Civi/Twingle/Shop/ApiCall.php +msgid "GET curl failed" +msgstr "GET cURL fehlgeschlagen" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "http status code 404 (not found)" +msgstr "HTTP-Statuscode 404 (not found)" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "https status code 500 (internal error)" +msgstr "HTTP-Statuscode 500 (internal error)" + +#: Civi/Twingle/Shop/ApiCall.php +msgid "Connection not yet established. Use connect() method." +msgstr "Verbindung nch nicht hergestellt. connect()-Methode verwenden." + #: api/v3/TwingleDonation/Cancel.php api/v3/TwingleDonation/Endrecurring.php #: api/v3/TwingleDonation/Submit.php msgid "Project ID" @@ -827,6 +1138,14 @@ msgstr "" "Zusätzliche Informationen für entweder den Kontakt oder die (wiederkehrende) " "Zuwendung." +#: api/v3/TwingleDonation/Submit.php +msgid "Products" +msgstr "Produkte" + +#: api/v3/TwingleDonation/Submit.php +msgid "Products ordered via TwingleShop" +msgstr "Über TwingleShop bestellte Produkte" + #: api/v3/TwingleDonation/Submit.php msgid "Additional remarks for the donation." msgstr "Zusätzliche Anmerkungen für die Zuwendung." @@ -873,6 +1192,285 @@ msgstr "" "Die Nachbearbeitung (postprocessing) der Twingle-Mitgliedschaft ist " "fehlgeschlagen, siehe Protokoll für weitere Informationen." +#: api/v3/TwingleProduct/Create.php api/v3/TwingleProduct/Delete.php +#: api/v3/TwingleProduct/Get.php +msgid "TwingleProduct ID" +msgstr "TwingleProduct-ID" + +#: api/v3/TwingleProduct/Create.php +msgid "The TwingleProduct ID in the database" +msgstr "Die TwingleProduct-ID in der Datenbank" + +#: api/v3/TwingleProduct/Create.php +msgid "Twingle ID" +msgstr "Twingle-ID" + +#: api/v3/TwingleProduct/Create.php +msgid "External product ID in Twingle database" +msgstr "Externe Produkt-ID in der Twingle-Datenbank" + +#: api/v3/TwingleProduct/Create.php +msgid "ID of the corresponding Twingle Shop" +msgstr "ID des zugehlrigen Twingle-Shops" + +#: api/v3/TwingleProduct/Create.php +msgid "Product Name" +msgstr "Produktname" + +#: api/v3/TwingleProduct/Create.php +msgid "Name of the product" +msgstr "Name des Produkts" + +#: api/v3/TwingleProduct/Create.php +msgid "Is active?" +msgstr "Status" + +#: api/v3/TwingleProduct/Create.php +msgid "Is the product active?" +msgstr "Ob das Produkt aktiviert ist" + +#: api/v3/TwingleProduct/Create.php +msgid "Product Description" +msgstr "Produktbeschreibung" + +#: api/v3/TwingleProduct/Create.php +msgid "Short description of the product" +msgstr "Kurzbeschreibung des Produkts" + +#: api/v3/TwingleProduct/Create.php +msgid "Product Price" +msgstr "Produkt-Preis" + +#: api/v3/TwingleProduct/Create.php +msgid "Price of the product" +msgstr "Preis des Produkts" + +#: api/v3/TwingleProduct/Create.php +msgid "Sort" +msgstr "Sortierung" + +#: api/v3/TwingleProduct/Create.php +msgid "Sort order of the product" +msgstr "Sortierungsreihenfolge des Produkts" + +#: api/v3/TwingleProduct/Create.php api/v3/TwingleShop/Create.php +msgid "Financial Type ID" +msgstr "Zuwendungsart" + +#: api/v3/TwingleProduct/Create.php +msgid "ID of the financial type of the product" +msgstr "ID der Zuwendungsart des Produkts" + +#: api/v3/TwingleProduct/Create.php +msgid "FK to TwingleShop" +msgstr "Fremdschlüssel zu TwingleShop" + +#: api/v3/TwingleProduct/Create.php +msgid "Twingle timestamp" +msgstr "Twingle-Zeitstempel" + +#: api/v3/TwingleProduct/Create.php +msgid "Timestamp of last update in Twingle db" +msgstr "Zeitstempel der letzten Aktualisierung in der Twingle-Datenbank" + +#: api/v3/TwingleProduct/Create.php +msgid "FK to PriceField" +msgstr "Fremdschlüssel zu PriceField" + +#: api/v3/TwingleProduct/Delete.php api/v3/TwingleProduct/Get.php +msgid "The TwingleProduct ID in CiviCRM" +msgstr "Die TwingleProduct-ID in CiviCRM" + +#: api/v3/TwingleProduct/Delete.php api/v3/TwingleProduct/Get.php +msgid "External TwingleProduct ID" +msgstr "Externe TwingleProduct-ID" + +#: api/v3/TwingleProduct/Delete.php api/v3/TwingleProduct/Get.php +msgid "Twingle's ID of the product" +msgstr "Twingles ID des Produkts" + +#: api/v3/TwingleProduct/Delete.php +msgid "TwingleProduct could not be deleted." +msgstr "TwingleProduct konnte nicht gelöscht werden." + +#: api/v3/TwingleProduct/Get.php +msgid "FK to civicrm_price_field" +msgstr "Fremdschlüssel zu civicrm_price_field" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Delete.php +#: api/v3/TwingleShop/Get.php +msgid "TwingleShop ID" +msgstr "TwingleShop-ID" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Delete.php +#: api/v3/TwingleShop/Get.php +msgid "The TwingleShop ID in CiviCRM" +msgstr "Die TwingleShop-ID in CiviCRM" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Create.php +#: api/v3/TwingleShop/Delete.php api/v3/TwingleShop/Get.php +msgid "Twingle project identifier" +msgstr "Twingle-Projekt-Identifikator" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Create.php +#: api/v3/TwingleShop/Get.php +msgid "Numerical Project Identifier" +msgstr "Numerischer Projekt-Identifikator" + +#: api/v3/TwingleProduct/Get.php api/v3/TwingleShop/Get.php +msgid "Twingle numerical project identifier" +msgstr "Twingles numerischer Projekt-Identifikator" + +#: api/v3/TwingleShop/Create.php +msgid "Numerical Twingle project identifier" +msgstr "Numerischer Twingle-Projekt-Identifikator" + +#: api/v3/TwingleShop/Create.php +msgid "Shop Name" +msgstr "Shop-Name" + +#: api/v3/TwingleShop/Create.php +msgid "Name of the shop" +msgstr "Name des Shops" + +#: api/v3/TwingleShop/Create.php +msgid "FK to civicrm_financial_type" +msgstr "ZuwendungsartFremdschlüssel zu civicrm_financial_type" + +#: api/v3/TwingleShop/Delete.php +msgid "TwingleShop could not be found." +msgstr "TwingleShop konnte nicht gefunden werden." + +#: api/v3/TwingleShop/Delete.php +msgid "TwingleShop could not be deleted." +msgstr "TwingleShop konnte nicht gelöscht werden." + +#: api/v3/TwingleShop/Fetch.php +msgid "Project Identifiers" +msgstr "Projekt-Identifikatoren" + +#: api/v3/TwingleShop/Fetch.php +msgid "Comma separated list of Twingle project identifiers." +msgstr "Kommaseparierte Liste von Twingle-Projekt-Identifikatoren." + +#: api/v3/TwingleShop/Get.php +msgid "Name of the TwingleShop" +msgstr "Name des TwingleShop" + +#: api/v3/TwingleShop/Get.php +msgid "FK to civicrm_price_set" +msgstr "Fremdschlüssel zu civicrm_price_set" + +#: js/twingle_shop.js +msgid "Could not fetch products" +msgstr "Produkte konnten nicht abgerufen werden" + +#: js/twingle_shop.js +msgid "Could not fetch products. Please check your Twingle API key." +msgstr "" +"Produkte konnten nicht abgerufen werden. Überprüfen Sie Ihren Twingle-API-" +"Schlüssel." + +#: js/twingle_shop.js +msgid "Create" +msgstr "Erstellen" + +#: js/twingle_shop.js +msgid "Update" +msgstr "Bearbeiten" + +#: js/twingle_shop.js +msgid "Could not create Price Field for this product" +msgstr "Preisfeld für dieses Produkt konnte nicht erstellt werden" + +#: js/twingle_shop.js +msgid "Delete Price Field" +msgstr "Preisfeld löschen" + +#: js/twingle_shop.js +msgid "" +"Are you sure you want to delete the price field associated with this product?" +msgstr "Möchten Sie wirklich das diesem Produkt zugehörige Preisfeld löschen?" + +#: js/twingle_shop.js +msgid "Could not delete Price Field" +msgstr "Preisfeld konnte nicht gelöscht werden" + +#: js/twingle_shop.js +msgid "The Price Field was deleted successfully." +msgstr "Das Preisfeld wurde erfolgreich gelöscht." + +#: js/twingle_shop.js +msgid "Price Field deleted" +msgstr "Preisfeld gelöscht" + +#: js/twingle_shop.js +msgid "select financial type" +msgstr "Zuwendungsart auswählen" + +#: js/twingle_shop.js +msgid "Product" +msgstr "Produkt" + +#: js/twingle_shop.js +msgid "Financial Type" +msgstr "Zuwendungsart" + +#: js/twingle_shop.js +msgid "Price Field" +msgstr "Preisfeld" + +#: js/twingle_shop.js +msgid "Create Price Set" +msgstr "Preisschema erstellen" + +#: js/twingle_shop.js +msgid "Update Price Set" +msgstr "Preisschema bearbeiten" + +#: js/twingle_shop.js +msgid "Delete Price Set" +msgstr "Preisschema löschen" + +#: js/twingle_shop.js +msgid "Could not create Twingle Shop" +msgstr "Twingle-Shop konnte nicht erstellt werden" + +#: js/twingle_shop.js +msgid "The Price Set was created successfully." +msgstr "Das Preisschema wurde erfolgreich erstellt." + +#: js/twingle_shop.js +msgid "Price Field created" +msgstr "Preisfeld erstellt" + +#: js/twingle_shop.js +msgid "Could not create TwingleShop" +msgstr "TwingleShop konnte nicht erstellt werden" + +#: js/twingle_shop.js +msgid "" +"Are you sure you want to delete the price set associated with this Twingle " +"Shop?" +msgstr "" +"Möchten Sie wirklich das diesem Twingle-Shop zugehörige Preisschema löschen?" + +#: js/twingle_shop.js +msgid "Could not delete Twingle Shop" +msgstr "Twingle-Shop konnte nicht gelöscht werden" + +#: js/twingle_shop.js +msgid "The Price Set was deleted successfully." +msgstr "Das Preisschema wurde erfolgreiche gelöscht." + +#: js/twingle_shop.js +msgid "Price Set deleted" +msgstr "Preisschema gelöscht" + +#: js/twingle_shop.js +msgid "Could not update Twingle Shop" +msgstr "Twingle-Shop konnte nicht aktualisiert werden" + #: managed/Navigation__twingle_configuration.mgd.php msgid "Twingle API Configuration" msgstr "Twingle-API-Konfiguration" @@ -1099,6 +1697,37 @@ msgstr "" "

    Tipp: Sie können diese Felder im TwingleMANAGER aktivieren oder " "deaktivieren.

    " +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"Enable the processing of orders via Twingle Shop for this profile. The " +"ordered products will then appear as line items in the contribution." +msgstr "" +"Aktiviert die Verarbeitung von Bestellungen über den Twingle-Shop für dieses " +"Profil. Die bestellten Produkte werden als Belegzeilen der Zuwendung " +"erscheinen." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"If this option is enabled, all Twingle Shop products corresponding to the " +"specified project IDs will be retrieved from Twingle and mapped as price " +"sets and price fields. Each Twingle Shop is mapped as a price set with its " +"products as price fields." +msgstr "" +"Wenn diese Option aktiviert ist, werden alle zur angegebenen Projekt-ID " +"gehörenden Twingle-Shop-Produkte von Twingle abgerufen und als Preisschemata " +"und Preisfelder zugeordnet. Jeder Twingle-Shop wird als ein Preisschema mit " +"seinen Produkten als Preisfelder zugeordnet." + +#: templates/CRM/Twingle/Form/Profile.hlp +msgid "" +"This allows you to manually create contributions with the same line items " +"for phone orders, for example, as would be the case for orders placed " +"through the Twingle Shop." +msgstr "" +"Dies ermöglicht das manuelle Erstellen von Zuwendungen mit den gleichen " +"Belegzeilen wie bei Bestellungen über den Twingle-Shop, z. B. für " +"telefonische Bestellungen." + #: templates/CRM/Twingle/Form/Profile.tpl msgid "General settings" msgstr "Allgemeine Einstellungen" @@ -1139,6 +1768,11 @@ msgstr "Double-Opt-In für Newsletter" msgid "Membership Postprocessing" msgstr "Mitgliedschafts--Nachbearbeitung (Postprocessing)" +#: templates/CRM/Twingle/Form/Profile.tpl +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "Shop Integration" +msgstr "Shop-Integration" + #: templates/CRM/Twingle/Form/Profile.tpl msgid "Are you sure you want to reset the default profile?" msgstr "Möchten Sie wirklich das Standard-Profil zurücksetzen?" @@ -1188,6 +1822,20 @@ msgstr "" "Transaktions-ID voranzustellen, um Kollisionen mit anderen Transaktions-IDs " "auszuschließen." +#: templates/CRM/Twingle/Form/Settings.hlp +msgid "" +"If you enable Twingle Shop integration, you can configure Twingle API " +"profiles to include products ordered through Twingle Shop as line items in " +"the created contribution." +msgstr "" +"Mit aktivierter Twingle-Shop-Integration können Twingle-API-Profile so " +"konfiguriert werden, dass über den Twingle-Shop bestellte Produkte als " +"Belegzeilen in der erstellten Zuwendung enthalten sind." + +#: templates/CRM/Twingle/Form/Settings.hlp +msgid "Enter your twingle API access key." +msgstr "Geben Sie ihren Zugriffsschlüssel für die Twingle-API ein." + #: templates/CRM/Twingle/Page/Configuration.tpl msgid "Profiles" msgstr "Profile" @@ -1224,6 +1872,14 @@ msgstr "Zuletzt verwendet" msgid "Operations" msgstr "Operationen" +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "enabled" +msgstr "aktiviert" + +#: templates/CRM/Twingle/Page/Profiles.tpl +msgid "disabled" +msgstr "deaktiviert" + #: templates/CRM/Twingle/Page/Profiles.tpl msgid "Edit profile %1" msgstr "Profil %1 bearbeiten" From eaf9d531696170ae3e28e339c360d3aeef98d01a Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 1 Oct 2024 14:27:53 +0200 Subject: [PATCH 215/221] Version 1.5-beta3 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index c019d80..099915c 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.5-dev - dev + 2024-010-01 + 1.5-beta3 + beta 5.58 From 82952a01623b1127c7268352a06cbc543487c402 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Tue, 1 Oct 2024 14:28:06 +0200 Subject: [PATCH 216/221] Back to 1.5-dev --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 099915c..c019d80 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2024-010-01 - 1.5-beta3 - beta + + 1.5-dev + dev 5.58 From c7c766d926bc3475b0e119a6ff9b9a283d2bc8a8 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 9 Oct 2024 12:39:57 +0200 Subject: [PATCH 217/221] Fix BAO class namespace issues --- CRM/Twingle/BAO/TwingleShop.php | 2 +- CRM/Twingle/Submission.php | 3 +-- api/v3/TwingleProduct/Create.php | 3 +-- api/v3/TwingleProduct/Delete.php | 3 +-- api/v3/TwingleProduct/Get.php | 5 ++--- api/v3/TwingleShop/Create.php | 3 +-- api/v3/TwingleShop/Delete.php | 6 +++--- api/v3/TwingleShop/Fetch.php | 5 ++--- api/v3/TwingleShop/Get.php | 4 ++-- twingle.php | 4 ++-- 10 files changed, 16 insertions(+), 22 deletions(-) diff --git a/CRM/Twingle/BAO/TwingleShop.php b/CRM/Twingle/BAO/TwingleShop.php index a4b006c..27ae3b8 100644 --- a/CRM/Twingle/BAO/TwingleShop.php +++ b/CRM/Twingle/BAO/TwingleShop.php @@ -294,7 +294,7 @@ class CRM_Twingle_BAO_TwingleShop extends CRM_Twingle_DAO_TwingleShop { /** * Get associated products. * - * @return array[Civi\Twingle\Shop\BAO\TwingleProduct] + * @return list * @throws \Civi\Core\Exception\DBQueryException * @throws \Civi\Twingle\Shop\Exceptions\ProductException */ diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 2c3e85d..1955d18 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -18,7 +18,6 @@ declare(strict_types = 1); use CRM_Twingle_ExtensionUtil as E; use Civi\Twingle\Exceptions\BaseException; use Civi\Twingle\Shop\Exceptions\LineItemException; -use Civi\Twingle\Shop\BAO\TwingleProduct; class CRM_Twingle_Submission { @@ -503,7 +502,7 @@ class CRM_Twingle_Submission { // Try to find the TwingleProduct with its corresponding PriceField // for this product try { - $price_field = TwingleProduct::findByExternalId($product['id']); + $price_field = CRM_Twingle_BAO_TwingleProduct::findByExternalId($product['id']); } catch (Exception $e) { Civi::log()->error(E::LONG_NAME . diff --git a/api/v3/TwingleProduct/Create.php b/api/v3/TwingleProduct/Create.php index 36bb48a..2490557 100644 --- a/api/v3/TwingleProduct/Create.php +++ b/api/v3/TwingleProduct/Create.php @@ -2,7 +2,6 @@ use Civi\Twingle\Shop\Exceptions\ProductException; use CRM_Twingle_ExtensionUtil as E; -use Civi\Twingle\Shop\BAO\TwingleProduct; /** * TwingleProduct.Create API specification (optional) @@ -121,7 +120,7 @@ function civicrm_api3_twingle_product_Create($params): array { try { // Create TwingleProduct and load params - $product = new TwingleProduct(); + $product = new CRM_Twingle_BAO_TwingleProduct(); $product->load($params); // Save TwingleProduct diff --git a/api/v3/TwingleProduct/Delete.php b/api/v3/TwingleProduct/Delete.php index 60c9591..7c675ab 100644 --- a/api/v3/TwingleProduct/Delete.php +++ b/api/v3/TwingleProduct/Delete.php @@ -1,7 +1,6 @@ delete(); diff --git a/api/v3/TwingleProduct/Get.php b/api/v3/TwingleProduct/Get.php index a7f64ca..9544678 100644 --- a/api/v3/TwingleProduct/Get.php +++ b/api/v3/TwingleProduct/Get.php @@ -1,7 +1,6 @@ getMessage(), [ diff --git a/api/v3/TwingleShop/Create.php b/api/v3/TwingleShop/Create.php index ebb34f4..ab858ff 100644 --- a/api/v3/TwingleShop/Create.php +++ b/api/v3/TwingleShop/Create.php @@ -1,6 +1,5 @@ load($params); // Save TwingleShop diff --git a/api/v3/TwingleShop/Delete.php b/api/v3/TwingleShop/Delete.php index d1f3323..cc851a7 100644 --- a/api/v3/TwingleShop/Delete.php +++ b/api/v3/TwingleShop/Delete.php @@ -1,6 +1,6 @@ deleteByConstraint(); if ($result) { return civicrm_api3_create_success(1, $params, 'TwingleShop', 'Delete'); diff --git a/api/v3/TwingleShop/Fetch.php b/api/v3/TwingleShop/Fetch.php index 961f42b..9c5d3e3 100644 --- a/api/v3/TwingleShop/Fetch.php +++ b/api/v3/TwingleShop/Fetch.php @@ -1,7 +1,6 @@ fetchProducts(); $returnValues[$projectId] = []; $returnValues[$projectId] += $shop->getAttributes(); @@ -63,7 +62,7 @@ function civicrm_api3_twingle_shop_Fetch($params) { return $product->getAttributes(); }, $products); } - catch (ShopException|ApiCallError|ProductException $e) { + catch (ShopException | ApiCallError | ProductException $e) { // If this project identifier doesn't belong to a project of type // 'shop', just skip it if ($e->getErrorCode() == ShopException::ERROR_CODE_NOT_A_SHOP) { diff --git a/api/v3/TwingleShop/Get.php b/api/v3/TwingleShop/Get.php index 2915212..9309e04 100644 --- a/api/v3/TwingleShop/Get.php +++ b/api/v3/TwingleShop/Get.php @@ -1,6 +1,6 @@ getMessage(), [ diff --git a/twingle.php b/twingle.php index c00ac35..9c20db1 100644 --- a/twingle.php +++ b/twingle.php @@ -17,7 +17,7 @@ function twingle_civicrm_pre($op, $objectName, $id, &$params) { // Create/delete PriceField and PriceFieldValue for TwingleProduct elseif ($objectName == 'TwingleProduct') { - $twingle_product = new \Civi\Twingle\Shop\BAO\TwingleProduct(); + $twingle_product = new CRM_Twingle_BAO_TwingleProduct(); $twingle_product->load($params); if ($op == 'create' || $op == 'edit') { $twingle_product->createPriceField(); @@ -30,7 +30,7 @@ function twingle_civicrm_pre($op, $objectName, $id, &$params) { // Create PriceSet for TwingleShop elseif ($objectName == 'TwingleShop' && ($op == 'create' || $op == 'edit')) { - $twingle_shop = new \Civi\Twingle\Shop\BAO\TwingleShop(); + $twingle_shop = new CRM_Twingle_BAO_TwingleShop(); $twingle_shop->load($params); $twingle_shop->createPriceSet(); $params = $twingle_shop->getAttributes(); From 2ee06faf34bb7ccdd40e066770d175ac0f7cbba5 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 23 Jan 2025 15:17:54 +0100 Subject: [PATCH 218/221] Version 1.5-beta4 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index c019d80..56b4ef3 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.5-dev - dev + 2025-01-23 + 1.5-beta4 + beta 5.58 From c8a577b6517807a7b273e2691454fa9f597dd366 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Thu, 23 Jan 2025 15:18:14 +0100 Subject: [PATCH 219/221] Back to dev (1.5-dev) --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 56b4ef3..c019d80 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2025-01-23 - 1.5-beta4 - beta + + 1.5-dev + dev 5.58 From 21f29ce169ffe00eebab2daf36dc68b9533fc1c7 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 21 Feb 2025 13:13:44 +0100 Subject: [PATCH 220/221] Version 1.5.0 --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index c019d80..1e7baa0 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - - 1.5-dev - dev + 2025-02-21 + 1.5.0 + stable 5.58 From b8f44d962de634a777bf85fe25300101c66788cd Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 21 Feb 2025 13:14:04 +0100 Subject: [PATCH 221/221] Back to dev (1.6-dev) --- info.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info.xml b/info.xml index 1e7baa0..edfa3fb 100644 --- a/info.xml +++ b/info.xml @@ -14,9 +14,9 @@ https://github.com/systopia/de.systopia.twingle/issues http://www.gnu.org/licenses/agpl-3.0.html - 2025-02-21 - 1.5.0 - stable + + 1.6-dev + dev 5.58