From 0d9b312a9b86ad88872685489af4dcfc71f44ef6 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 09:47:42 +0200 Subject: [PATCH 01/12] =?UTF-8?q?=E2=9E=95=EF=B8=8F=20change=20json=20file?= =?UTF-8?q?s=20to=20php=20files=20and=20add=20custom=20fields=20for=20proj?= =?UTF-8?q?ects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changeing the file type is necessary to use the ts() function during custom field creation. Added new custom fields to map the donation form settings. --- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 2 +- CRM/TwingleCampaign/Utils/ExtensionCache.php | 67 +- CRM/TwingleCampaign/resources/campaigns.json | 469 ------- CRM/TwingleCampaign/resources/campaigns.php | 1082 +++++++++++++++++ CRM/TwingleCampaign/resources/dictionary.json | 13 - CRM/TwingleCampaign/resources/dictionary.php | 18 + .../resources/option_values.json | 8 - .../resources/option_values.php | 10 + .../resources/twingle_api_templates.json | 61 - .../resources/twingle_api_templates.php | 114 ++ api/v3/TwingleCampaign/Get.php | 2 +- twinglecampaign.php | 22 +- 12 files changed, 1262 insertions(+), 606 deletions(-) delete mode 100644 CRM/TwingleCampaign/resources/campaigns.json create mode 100644 CRM/TwingleCampaign/resources/campaigns.php delete mode 100644 CRM/TwingleCampaign/resources/dictionary.json create mode 100644 CRM/TwingleCampaign/resources/dictionary.php delete mode 100644 CRM/TwingleCampaign/resources/option_values.json create mode 100644 CRM/TwingleCampaign/resources/option_values.php delete mode 100644 CRM/TwingleCampaign/resources/twingle_api_templates.json create mode 100644 CRM/TwingleCampaign/resources/twingle_api_templates.php diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index c50118e..f7e8521 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -96,7 +96,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { // Get campaign type id for TwingleProject $twingle_project_campaign_type_id = ExtensionCache::getInstance() - ->getCampaigns()['campaign_types']['twingle_project']['id']; + ->getCampaignIds()['campaign_types']['twingle_project']['id']; // Determine the parent project id by looping through the campaign tree // until the parent campaign type is a TwingleProject diff --git a/CRM/TwingleCampaign/Utils/ExtensionCache.php b/CRM/TwingleCampaign/Utils/ExtensionCache.php index 365b50a..f813d9a 100644 --- a/CRM/TwingleCampaign/Utils/ExtensionCache.php +++ b/CRM/TwingleCampaign/Utils/ExtensionCache.php @@ -13,13 +13,7 @@ class CRM_TwingleCampaign_Utils_ExtensionCache { private $customFieldMapping; - private $translations; - - private $campaigns; - - private $templates; - - private $option_values; + private $campaignIds; /** * ## Get an instance (singleton) @@ -44,37 +38,11 @@ class CRM_TwingleCampaign_Utils_ExtensionCache { // Get a mapping of custom fields $this->customFieldMapping = CustomField::getMapping(); - // Initialize json files as arrays - $file_paths = [ - 'translations' => '/CRM/TwingleCampaign/resources/dictionary.json', - 'templates' => '/CRM/TwingleCampaign/resources/twingle_api_templates.json', - 'campaigns' => '/CRM/TwingleCampaign/resources/campaigns.json', - 'option_values' => '/CRM/TwingleCampaign/resources/option_values.json', - ]; - - foreach ($file_paths as $key => $file_path) { - - // Get array from json file - $file_path = E::path() . $file_path; - $json_file = file_get_contents($file_path); - $json_file_name = pathinfo($file_path)['filename']; - $array = json_decode($json_file, TRUE); - - // Throw and log an error if json file can't be read - if (!$array) { - $message = ($json_file_name) - ? "Could not read json file $json_file_name" - : "Could not locate json file in path: $file_path"; - Civi::log()->error($message); - throw new Exception($message); - } - - // Set attribute - $this->$key = $array; - } - // Get ids for Twingle related campaign types - foreach ($this->campaigns['campaign_types'] as $campaign_type) { + $this->campaignIds = require( + E::path() . '/CRM/TwingleCampaign/resources/campaigns.php' + ); + foreach ($this->campaignIds['campaign_types'] as $campaign_type) { $campaign_type_id = civicrm_api3( 'OptionValue', 'get', @@ -85,7 +53,7 @@ class CRM_TwingleCampaign_Utils_ExtensionCache { ] )['values']; if ($campaign_type_id) { - $this->campaigns['campaign_types'][$campaign_type['name']]['id'] = + $this->campaignIds['campaign_types'][$campaign_type['name']]['id'] = $campaign_type_id[0]['value']; } } @@ -114,28 +82,43 @@ class CRM_TwingleCampaign_Utils_ExtensionCache { * @return array */ public function getTranslations(): array { - return $this->translations; + return require( + E::path() . '/CRM/TwingleCampaign/resources/dictionary.php' + ); } /** * @return array */ public function getCampaigns(): array { - return $this->campaigns; + return require( + E::path() . '/CRM/TwingleCampaign/resources/campaigns.php' + ); + } + + /** + * @return array + */ + public function getCampaignIds(): array { + return $this->campaignIds; } /** * @return array */ public function getTemplates(): array { - return $this->templates; + return require( + E::path() . '/CRM/TwingleCampaign/resources/twingle_api_templates.php' + ); } /** * @return mixed */ public function getOptionValues() { - return $this->option_values; + return require( + E::path() . '/CRM/TwingleCampaign/resources/option_values.php' + ); } } \ No newline at end of file diff --git a/CRM/TwingleCampaign/resources/campaigns.json b/CRM/TwingleCampaign/resources/campaigns.json deleted file mode 100644 index aff49a7..0000000 --- a/CRM/TwingleCampaign/resources/campaigns.json +++ /dev/null @@ -1,469 +0,0 @@ -{ - "campaign_types": { - "twingle_project": { - "name": "twingle_project", - "label": "Twingle Project" - }, - "twingle_event": { - "name": "twingle_event", - "label": "Twingle Event" - }, - "twingle_campaign": { - "name": "twingle_campaign", - "label": "Twingle Campaign" - } - }, - "custom_groups": { - "twingle_project_information": { - "title": "Twingle Project Information", - "name": "Twingle_Project_Information", - "extends": "Campaign", - "campaign_type": "twingle_project", - "weight": "1" - }, - "twingle_project_embed_codes": { - "title": "Twingle Project Embed Codes", - "name": "Twingle_Project_Embed_Codes", - "extends": "Campaign", - "campaign_type": "twingle_project", - "collapse_display": "1", - "weight": "2" - }, - "twingle_event_information": { - "title": "Twingle Event Information", - "name": "Twingle_Event_Information", - "extends": "Campaign", - "campaign_type": "twingle_event" - }, - "twingle_campaign_information": { - "title": "Twingle Campaign Information", - "name": "Twingle_Campaign_Information", - "extends": "Campaign", - "campaign_type": "twingle_campaign" - } - }, - "custom_fields": { - "twingle_project_id": { - "custom_group_id": "Twingle_Project_Information", - "label": "Twingle Project ID", - "name": "twingle_project_id", - "is_required": 0, - "is_searchable": 1, - "data_type": "String", - "html_type": "Text", - "text_length": 16, - "is_active": 1, - "is_view": 1, - "weight": 1 - }, - "twingle_project_organisation_id": { - "custom_group_id": "Twingle_Project_Information", - "label": "Twingle Project organisation ID", - "name": "twingle_project_organisation_id", - "is_required": 0, - "is_searchable": 1, - "data_type": "String", - "html_type": "Text", - "text_length": 32, - "is_active": 1, - "is_view": 1, - "weight": 6 - }, - "twingle_project_identifier": { - "custom_group_id": "Twingle_Project_Information", - "label": "Twingle Project identifier", - "name": "twingle_project_identifier", - "is_required": 0, - "is_searchable": 1, - "data_type": "String", - "html_type": "Text", - "text_length": 15, - "is_active": 1, - "is_view": 1, - "weight": 3, - "help_post": "An unique identifier for a project (auto generated)" - }, - "twingle_project_type": { - "custom_group_id": "Twingle_Project_Information", - "label": "Twingle Project Type", - "name": "twingle_project_type", - "is_required": 0, - "is_searchable": 1, - "data_type": "String", - "html_type": "Select", - "option_values": { - "default": "Default", - "event": "Events", - "membership": "Membership" - }, - "text_length": 32, - "is_active": 1, - "is_view": 0, - "weight": 2, - "help_post": "Choose the project type. Allow users to create own events or to pay a membership fee.", - "default_value": "default" - }, - "twingle_project_allow_more": { - "custom_group_id": "Twingle_Project_Information", - "label": "Twingle Project allow more", - "name": "twingle_project_allow_more", - "is_required": 0, - "is_searchable": 1, - "data_type": "Boolean", - "html_type": "Radio", - "text_length": 4, - "is_active": 1, - "is_view": 0, - "weight": 4, - "help_post": "Allow to donate more than is defined in the target" - }, - "twingle_project_transaction_type": { - "custom_group_id": "Twingle_Project_Information", - "label": "Twingle Project transaction type", - "name": "twingle_project_transaction_type", - "is_required": 0, - "is_searchable": 1, - "data_type": "String", - "html_type": "Text", - "text_length": 32, - "is_active": 1, - "is_view": 0, - "weight": 5 - }, - "twingle_project_url": { - "custom_group_id": "Twingle_Project_Information", - "label": "Twingle Project URL", - "name": "twingle_project_url", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 600, - "is_active": 1, - "is_view": 0, - "weight": 6 - }, - "twingle_project_widget": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project Widget", - "name": "twingle_project_widget", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 600, - "is_active": 1, - "is_view": 1, - "weight": 1 - }, - "twingle_project_form": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project Form", - "name": "twingle_project_form", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 600, - "is_active": 1, - "is_view": 1, - "weight": 2 - }, - "twingle_project_widget-single": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project Widget Single", - "name": "twingle_project_widget-single", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 600, - "is_active": 1, - "is_view": 1, - "weight": 3 - }, - "twingle_project_form-single": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project Form Single", - "name": "twingle_project_form-single", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 600, - "is_active": 1, - "is_view": 1, - "weight": 4 - }, - "twingle_project_eventall": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project All Events", - "name": "twingle_project_eventall", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 1300, - "is_active": 1, - "is_view": 1, - "weight": 5 - }, - "twingle_project_eventlist": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project Event List", - "name": "twingle_project_eventlist", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 1300, - "is_active": 1, - "is_view": 1, - "weight": 6 - }, - "twingle_project_counter": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project Counter", - "name": "twingle_project_counter", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 120, - "is_active": 1, - "is_view": 1, - "weight": 7 - }, - "twingle_project_page": { - "custom_group_id": "Twingle_Project_Embed_Codes", - "label": "Twingle Project Page", - "name": "twingle_project_page", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 600, - "is_active": 1, - "is_view": 1, - "weight": 8 - }, - "twingle_event_id": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event ID", - "name": "twingle_event_id", - "is_required": 1, - "is_searchable": 1, - "data_type": "String", - "html_type": "Text", - "text_length": 16, - "is_active": 1, - "is_view": 1, - "weight": 1 - }, - "twingle_event_project_id": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Project ID", - "name": "twingle_event_project_id", - "is_required": 0, - "is_searchable": 1, - "data_type": "String", - "html_type": "Text", - "text_length": 16, - "is_active": 1, - "is_view": 1, - "weight": 2 - }, - "twingle_event_identifier": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Identifier", - "name": "twingle_event_identifier", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 16, - "is_active": 1, - "is_view": 1, - "weight": 3 - }, - "twingle_event_contact": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Initiator", - "name": "twingle_event_contact", - "is_required": 0, - "is_searchable": 1, - "data_type": "ContactReference", - "html_type": "Autocomplete-Select", - "is_active": 1, - "is_view": 0, - "weight": 5 - }, - "twingle_event_user_email": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Initiator Email", - "name": "twingle_event_user_email", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 128, - "is_active": 1, - "is_view": 1, - "weight": 6 - }, - "twingle_event_is_public": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event is public", - "name": "twingle_event_is_public", - "is_required": 0, - "is_searchable": 1, - "data_type": "Boolean", - "html_type": "Radio", - "is_active": 1, - "is_view": 1, - "weight": 7 - }, - "twingle_event_deleted": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Deleted", - "name": "twingle_event_deleted", - "is_required": 0, - "is_searchable": 1, - "data_type": "Boolean", - "html_type": "Radio", - "is_active": 1, - "is_view": 1, - "weight": 8 - }, - "twingle_event_confirmed_at": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Confirmed At", - "name": "twingle_event_confirmed_at", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 64, - "is_active": 1, - "is_view": 1, - "weight": 9 - }, - "twingle_event_created_at": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Created At", - "name": "twingle_event_created_at", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 64, - "is_active": 1, - "is_view": 1, - "weight": 10 - }, - "twingle_event_creation_url": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Creation URL", - "name": "twingle_event_creation_url", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 256, - "is_active": 1, - "is_view": 1, - "weight": 11 - }, - "twingle_event_url_internal": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Internal URL", - "name": "twingle_event_url_internal", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 256, - "is_active": 1, - "is_view": 1, - "weight": 12 - }, - "twingle_event_url_external": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event External URL", - "name": "twingle_event_url_external", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 256, - "is_active": 1, - "is_view": 1, - "weight": 13 - }, - "twingle_event_url_edit_internal": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Edit Internal URL", - "name": "twingle_event_url_edit_internal", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 256, - "is_active": 1, - "is_view": 1, - "weight": 14 - }, - "twingle_event_url_edit_external": { - "custom_group_id": "Twingle_Event_Information", - "label": "Twingle Event Edit External URL", - "name": "twingle_event_url_edit_external", - "is_required": 0, - "is_searchable": 0, - "data_type": "String", - "html_type": "Text", - "text_length": 256, - "is_active": 1, - "is_view": 1, - "weight": 15 - }, - "twingle_campaign_parent_project_id": { - "custom_group_id": "Twingle_Campaign_Information", - "label": "Parent TwingleProject ID", - "name": "twingle_campaign_parent_project_id", - "is_required": 0, - "is_searchable": 1, - "data_type": "String", - "html_type": "Text", - "text_length": 16, - "is_active": 1, - "is_view": 1, - "weight": 1 - }, - "twingle_campaign_cid": { - "custom_group_id": "Twingle_Campaign_Information", - "label": "Twingle Campaign CID", - "name": "twingle_campaign_cid", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "Text", - "text_length": 32, - "is_active": 1, - "is_view": 1, - "weight": 2 - }, - "twingle_campaign_url": { - "custom_group_id": "Twingle_Campaign_Information", - "label": "Twingle Campaign URL", - "name": "twingle_campaign_url", - "is_required": 0, - "is_searchable": 0, - "data_type": "Memo", - "html_type": "TextArea", - "text_length": 600, - "is_active": 1, - "is_view": 1, - "weight": 3 - } - } -} diff --git a/CRM/TwingleCampaign/resources/campaigns.php b/CRM/TwingleCampaign/resources/campaigns.php new file mode 100644 index 0000000..1dbeba8 --- /dev/null +++ b/CRM/TwingleCampaign/resources/campaigns.php @@ -0,0 +1,1082 @@ + [ + "twingle_project" => [ + "name" => "twingle_project", + "label" => "Twingle Project" + ], + "twingle_event" => [ + "name" => "twingle_event", + "label" => "Twingle Event" + ], + "twingle_campaign" => [ + "name" => "twingle_campaign", + "label" => "Twingle Campaign" + ] + ], + "custom_groups" => [ + "twingle_project_information" => [ + "title" => E::ts("Twingle Information"), + "name" => "Twingle_Project_Information", + "extends" => "Campaign", + "campaign_type" => "twingle_project", + "weight" => "1" + ], + "twingle_project_options" => [ + "title" => E::ts("Twingle Settings"), + "name" => "Twingle_Project_Options", + "extends" => "Campaign", + "campaign_type" => "twingle_project", + "weight" => "2" + ], + "twingle_project_payment_methods" => [ + "title" => E::ts("Twingle Payment Methods"), + "name" => "Twingle_Project_Payment_Methods", + "extends" => "Campaign", + "campaign_type" => "twingle_project", + "weight" => "3" + ], + "twingle_project_embed_codes" => [ + "title" => E::ts("Twingle Embed Codes"), + "name" => "Twingle_Project_Embed_Codes", + "extends" => "Campaign", + "campaign_type" => "twingle_project", + "collapse_display" => "1", + "weight" => "4" + ], + "twingle_event_information" => [ + "title" => E::ts("Twingle Event Information"), + "name" => "Twingle_Event_Information", + "extends" => "Campaign", + "campaign_type" => "twingle_event" + ], + "twingle_campaign_information" => [ + "title" => E::ts("Twingle Campaign Information"), + "name" => "Twingle_Campaign_Information", + "extends" => "Campaign", + "campaign_type" => "twingle_campaign" + ] + ], + "custom_fields" => [ + "twingle_project_id" => [ + "custom_group_id" => "Twingle_Project_Information", + "label" => E::ts("Twingle Project ID"), + "name" => "twingle_project_id", + "is_required" => FALSE, + "is_searchable" => 1, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 16, + "is_active" => 1, + "is_view" => 1, + "weight" => 1 + ], + "twingle_project_organisation_id" => [ + "custom_group_id" => "Twingle_Project_Information", + "label" => E::ts("Organisation ID"), + "name" => "twingle_project_organisation_id", + "is_required" => FALSE, + "is_searchable" => 1, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 32, + "is_active" => 1, + "is_view" => 1, + "weight" => 6 + ], + "twingle_project_identifier" => [ + "custom_group_id" => "Twingle_Project_Information", + "label" => E::ts("identifier"), + "name" => "twingle_project_identifier", + "is_required" => FALSE, + "is_searchable" => 1, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 15, + "is_active" => 1, + "is_view" => 1, + "weight" => 3, + "help_post" => E::ts("An unique identifier for a project (auto generated)") + ], + "twingle_project_type" => [ + "custom_group_id" => "Twingle_Project_Information", + "label" => E::ts("Type"), + "name" => "twingle_project_type", + "is_required" => FALSE, + "is_searchable" => 1, + "data_type" => "String", + "html_type" => "Select", + "option_values" => [ + "default" => E::ts("Default"), + "event" => E::ts("Events"), + "membership" => E::ts("Membership") + ], + "text_length" => 32, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 2, + "help_post" => E::ts("Choose the project type. Allow users to create own events or to pay a membership fee."), + "default_value" => "default" + ], + "twingle_project_allow_more" => [ + "custom_group_id" => "Twingle_Project_Information", + "label" => E::ts("allow more"), + "name" => "twingle_project_allow_more", + "is_required" => FALSE, + "is_searchable" => 1, + "data_type" => "Boolean", + "html_type" => "Radio", + "text_length" => 4, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 4, + "help_post" => E::ts("Allow to donate more than is defined in the target") + ], + "twingle_project_transaction_type" => [ + "custom_group_id" => "Twingle_Project_Information", + "label" => E::ts("transaction type"), + "name" => "twingle_project_transaction_type", + "is_required" => FALSE, + "is_searchable" => 1, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 32, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 5 + ], + "twingle_project_url" => [ + "custom_group_id" => "Twingle_Project_Information", + "label" => E::ts("URL"), + "name" => "twingle_project_url", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 600, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 6 + ], + "twingle_project_widget" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("Widget"), + "name" => "twingle_project_widget", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 600, + "is_active" => 1, + "is_view" => 1, + "weight" => 1 + ], + "twingle_project_form" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("Form"), + "name" => "twingle_project_form", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 600, + "is_active" => 1, + "is_view" => 1, + "weight" => 2 + ], + "twingle_project_widget-single" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("Widget Single"), + "name" => "twingle_project_widget-single", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 600, + "is_active" => 1, + "is_view" => 1, + "weight" => 3 + ], + "twingle_project_form-single" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("Form Single"), + "name" => "twingle_project_form-single", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 600, + "is_active" => 1, + "is_view" => 1, + "weight" => 4 + ], + "twingle_project_eventall" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("All Events"), + "name" => "twingle_project_eventall", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 1300, + "is_active" => 1, + "is_view" => 1, + "weight" => 5 + ], + "twingle_project_eventlist" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("Event List"), + "name" => "twingle_project_eventlist", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 1300, + "is_active" => 1, + "is_view" => 1, + "weight" => 6 + ], + "twingle_project_counter" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("Counter"), + "name" => "twingle_project_counter", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 120, + "is_active" => 1, + "is_view" => 1, + "weight" => 7 + ], + "twingle_project_page" => [ + "custom_group_id" => "Twingle_Project_Embed_Codes", + "label" => E::ts("Page"), + "name" => "twingle_project_page", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 600, + "is_active" => 1, + "is_view" => 1, + "weight" => 8 + ], + "twingle_project_has_confirmation_mail" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Confirmation Mail"), + "name" => "twingle_project_has_confirmation_mail", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 1, + "help_post" => E::ts("Send confirmation mail") + ], + "twingle_project_has_donation_receipt" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Donation Receipt"), + "name" => "twingle_project_has_donation_receipt", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 3, + "help_post" => E::ts("Offer donation receipts") + ], + "twingle_project_has_contact_data" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Contact Data"), + "name" => "twingle_project_has_contact_data", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 4 + ], + "twingle_project_donation_rhythm" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Donation Rhythm"), + "name" => "twingle_project_donation_rhythm", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Multi-Select", + "option_values" => [ + "yearly" => E::ts("yearly"), + "halfyearly" => E::ts("halfyearly"), + "quarterly" => E::ts("quarterly"), + "monthly" => E::ts("monthly"), + "one_time" => E::ts("one time") + ], + "text_length" => 64, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 5, + "help_post" => E::ts("The selected options are available for selection in the donation widget.") + ], + "twingle_project_default_rhythm" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Default Rhythm"), + "name" => "twingle_project_default_rhythm", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Radio", + "option_values" => [ + "yearly" => E::ts("yearly"), + "halfyearly" => E::ts("halfyearly"), + "quarterly" => E::ts("quarterly"), + "monthly" => E::ts("monthly"), + "one_time" => E::ts("one time") + ], + "text_length" => 64, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 6, + "help_post" => E::ts("Which donation rhythm should be displayed as selected by default?") + ], + "twingle_project_has_newsletter_registration" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Newsletter Registration"), + "name" => "twingle_project_has_newsletter_registration", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 7, + "help_post" => E::ts("Enable newsletter registration") + ], + "twingle_project_has_postinfo_registration" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Postinfo Registration"), + "name" => "twingle_project_has_postinfo_registration", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 8, + "help_post" => E::ts("Enable post info registration") + ], + "twingle_project_design_background_color" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Background Color"), + "name" => "twingle_project_design_background_color", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 9, + "help_post" => E::ts("Hex color code (e.g. ffffff for white)") + ], + "twingle_project_design_primary_color" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Primary Color"), + "name" => "twingle_project_design_primary_color", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 10, + "help_post" => E::ts("Hex color code (e.g. ffffff for white)") + ], + "twingle_project_design_font_color" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Font Color"), + "name" => "twingle_project_design_font_color", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 6, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 12, + "help_post" => E::ts("Hex color code (e.g. ffffff for white)") + ], + "twingle_project_bcc_email_address" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("BCC Email"), + "name" => "twingle_project_bcc_email_address", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 64, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 16, + "help_post" => E::ts("Email address used as bcc addresses for confirmation mail which is send to an user") + ], + "twingle_project_donation_value_min" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Donation Min"), + "name" => "twingle_project_donation_value_min", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 10, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 17, + "help_post" => E::ts("Minimum donation value"), + "default_value" => "5" + ], + "twingle_project_donation_value_max" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Donation Max"), + "name" => "twingle_project_donation_value_max", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 10, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 18, + "help_post" => E::ts("Maximum donation value"), + "default_value" => "500" + ], + "twingle_project_donation_value_default" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Donation Default"), + "name" => "twingle_project_donation_value_default", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 10, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 19, + "help_post" => E::ts("Default donation value"), + "default_value" => "50" + ], + "twingle_project_contact_fields" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Contact Fields"), + "name" => "twingle_project_contact_fields", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Multi-Select", + "option_values" => [ + "salutation" => E::ts("Salutation"), + "firstname" => E::ts("First name"), + "lastname" => E::ts("Last name"), + "company" => E::ts("Company"), + "birthday" => E::ts("Birthday"), + "street" => E::ts("Street"), + "postal_code" => E::ts("Postal Code"), + "city" => E::ts("City"), + "country" => E::ts("Country"), + "telephone" => E::ts("Telephone") + ], + "is_active" => 1, + "is_view" => FALSE, + "weight" => 20, + "help_post" => E::ts("Fields to include in contact form") + ], + "twingle_project_mandatory_contact_fields" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Mandatory Contact Fields"), + "name" => "twingle_project_mandatory_contact_fields", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Multi-Select", + "option_values" => [ + "salutation" => E::ts("Salutation"), + "firstname" => E::ts("First name"), + "lastname" => E::ts("Last name"), + "company" => E::ts("Company"), + "birthday" => E::ts("Birthday"), + "street" => E::ts("Street"), + "postal_code" => E::ts("Postal Code"), + "city" => E::ts("City"), + "country" => E::ts("Country"), + "telephone" => E::ts("Telephone") + ], + "is_active" => 1, + "is_view" => FALSE, + "weight" => 20, + "help_post" => E::ts("Fields that must get filled in the contact form.") + ], + "twingle_project_custom_css" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Custom CSS"), + "name" => "twingle_project_custom_css", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 120, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 21, + "help_post" => E::ts("URL to a custom CSS file that will be included in the frontend") + ], + "twingle_project_share_url" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Share URL"), + "name" => "twingle_project_share_url", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 120, + "is_active" => 1, + "is_view" => FALSE, + "weight" => 22, + "help_post" => E::ts("URL for the sharing component on the last page and doi page") + ], + "twingle_project_has_contact_mandatory" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Contact Mandatory"), + "name" => "twingle_project_has_contact_mandatory", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => 1, + "is_view" => FALSE, + "weight" => 23, + "help_post" => E::ts("If the contact data should be requested mandatory as second step") + ], + "twingle_project_has_doi" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Double Opt-In"), + "name" => "twingle_project_has_doi", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => 1, + "is_view" => FALSE, + "weight" => 24, + "help_post" => E::ts("Enable Twingle's double opt-in (Do not enable, if you use CiviCRM's double opt-in!)") + ], + "twingle_project_has_force_donation_target_buttons" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Force Donation Taget as Button"), + "name" => "twingle_project_has_force_donation_target_buttons", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => 1, + "is_view" => FALSE, + "weight" => 26, + "help_post" => E::ts("Force showing the donation targets as buttons") + ], + "twingle_project_slidericon" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Slider Icon"), + "name" => "twingle_project_slidericon", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Select", + "option_values" => [ + "heart" => E::ts("Heart"), + "asterisk" => E::ts("Asterisk"), + "animal" => E::ts("Animal"), + "Rettungsring" => E::ts("Lifebelt"), + "angellist" => E::ts("Angellist"), + "handshake" => E::ts("Handshake"), + "dollar" => E::ts("Dollar"), + "menue_burger_fine" => E::ts("Menue"), + "office" => E::ts("Office"), + "leaf" => E::ts("Leaf"), + "cog" => E::ts("Cog"), + "wvg" => E::ts("SVG"), + "euro" => E::ts("Euro"), + "stats-dots" => E::ts("Stats"), + "circle_fine" => E::ts("Circle"), + "waterdrop_outline" => E::ts("Water drop outline"), + "waterdrop" => E::ts("Water drop"), + "gift" => E::ts("Gift"), + "biene_b" => E::ts("Bee"), + "blume" => E::ts("Flower"), + "train" => E::ts("Train"), + "empty" => E::ts("No Icon") + ], + "is_active" => 1, + "is_view" => FALSE, + "weight" => 29 + ], + "twingle_project_has_hidden_logo" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Hidden Logo"), + "name" => "twingle_project_has_hidden_logo", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => 1, + "is_view" => FALSE, + "weight" => 35, + "help_post" => E::ts("Hide the Logo on the project page") + ], + "twingle_project_has_projecttarget_as_money" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Target Format"), + "name" => "twingle_project_has_projecttarget_as_money", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => 1, + "is_view" => FALSE, + "weight" => 36, + "help_post" => E::ts("Format of the reached portion of the donation target"), + "default_value" => "0" + ], + "twingle_project_has_donationtarget_textfield" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Donation Purpose as Textfield"), + "name" => "twingle_project_has_donationtarget_textfield", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => 1, + "is_view" => FALSE, + "weight" => 37, + "help_post" => E::ts("Let donors enter their own donation purpose") + ], + "twingle_project_has_civi_crm_activated" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Activate CiviCRM Support"), + "name" => "twingle_project_has_civi_crm_activated", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => 1, + "is_view" => FALSE, + "weight" => 38, + "help_post" => E::ts("Activate support for Twingle Extension (de.systopia.twingle)"), + "default_value" => TRUE, + ], + "twingle_project_has_step_index" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Show Step Index"), + "name" => "twingle_project_has_step_index", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 39, + "help_post" => E::ts("Show a step index during donation process") + ], + "twingle_project_languages" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Languages"), + "name" => "twingle_project_languages", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Multi-Select", + "option_values" => [ + "de" => E::ts("German"), + "en" => E::ts("English"), + "fr" => E::ts("French"), + "es" => E::ts("Spanish") + ], + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 43 + ], + "twingle_project_has_buttons" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Buttons"), + "name" => "twingle_project_has_buttons", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Up to four buttons can be configured. If you leave the amount blank, the button will not be displayed.") + ], + "twingle_project_has_no_slider" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Slider"), + "name" => "twingle_project_has_no_slider", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Show a slider that allows the donor to choose the donation amount.") + ], + "twingle_project_button1" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Button 1"), + "name" => "twingle_project_button1", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 10, + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Amount to be displayed on Button 1") + ], + "twingle_project_button2" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Button 2"), + "name" => "twingle_project_button2", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 10, + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Amount to be displayed on Button 2") + ], + "twingle_project_button3" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Button 3"), + "name" => "twingle_project_button3", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 10, + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Amount to be displayed on Button 3") + ], + "twingle_project_button4" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Button 4"), + "name" => "twingle_project_button4", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 10, + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Amount to be displayed on Button 4") + ], + "twingle_project_has_newsletter_namerequest" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Newsletter Name Requested"), + "name" => "twingle_project_has_newsletter_namerequest", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Must a donor give his name for newsletter sign-up?") + ], + "twingle_project_has_show_donator_data" => [ + "custom_group_id" => "Twingle_Project_Options", + "label" => E::ts("Show List of Donations"), + "name" => "twingle_project_has_show_donator_data", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 44, + "help_post" => E::ts("Display a list of public donations") + ], + "twingle_project_payment_methods" => [ + "custom_group_id" => "Twingle_Project_Payment_Methods", + "label" => E::ts("Payment Methods"), + "name" => "twingle_project_payment_methods", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Multi-Select", + "option_values" => [ + "has_paypal" => E::ts("PayPal"), + "has_banktransfer" => E::ts("Banktransfer"), + "has_debit" => E::ts("Debit"), + "has_sofortueberweisung" => E::ts("Sofortüberweisung") + ], + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 45, + "help_post" => E::ts("Chose which payment methods should be available. NOTE: You might have to activate them first in the Twingle-Manager configuration.") + ], + "twingle_project_payment_methods_recurring" => [ + "custom_group_id" => "Twingle_Project_Payment_Methods", + "label" => E::ts("Recurring Payment Methods"), + "name" => "twingle_project_payment_methods_recurring", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Multi-Select", + "option_values" => [ + "has_paypal_recurring" => E::ts("PayPal"), + "has_debit_recurring" => E::ts("Debit") + ], + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 45, + "help_post" => E::ts("Display a list of public donations") + ], + "twingle_event_id" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Twingle Event ID"), + "name" => "twingle_event_id", + "is_required" => TRUE, + "is_searchable" => TRUE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 16, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 1 + ], + "twingle_event_project_id" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Twingle Project ID"), + "name" => "twingle_event_project_id", + "is_required" => FALSE, + "is_searchable" => TRUE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 16, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 2 + ], + "twingle_event_identifier" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Identifier"), + "name" => "twingle_event_identifier", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 16, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 3 + ], + "twingle_event_contact" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Initiator"), + "name" => "twingle_event_contact", + "is_required" => FALSE, + "is_searchable" => TRUE, + "data_type" => "ContactReference", + "html_type" => "Autocomplete-Select", + "is_active" => TRUE, + "is_view" => FALSE, + "weight" => 5 + ], + "twingle_event_user_email" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Initiator Email"), + "name" => "twingle_event_user_email", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 128, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 6 + ], + "twingle_event_is_public" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Is public"), + "name" => "twingle_event_is_public", + "is_required" => FALSE, + "is_searchable" => TRUE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 7 + ], + "twingle_event_deleted" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Deleted"), + "name" => "twingle_event_deleted", + "is_required" => FALSE, + "is_searchable" => TRUE, + "data_type" => "Boolean", + "html_type" => "Radio", + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 8 + ], + "twingle_event_confirmed_at" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Confirmed At"), + "name" => "twingle_event_confirmed_at", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 64, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 9 + ], + "twingle_event_created_at" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Created At"), + "name" => "twingle_event_created_at", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 64, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 10 + ], + "twingle_event_creation_url" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Creation URL"), + "name" => "twingle_event_creation_url", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 256, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 11 + ], + "twingle_event_url_internal" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Internal URL"), + "name" => "twingle_event_url_internal", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 256, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 12 + ], + "twingle_event_url_external" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("External URL"), + "name" => "twingle_event_url_external", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 256, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 13 + ], + "twingle_event_url_edit_internal" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Edit Internal URL"), + "name" => "twingle_event_url_edit_internal", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 256, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 14 + ], + "twingle_event_url_edit_external" => [ + "custom_group_id" => "Twingle_Event_Information", + "label" => E::ts("Edit External URL"), + "name" => "twingle_event_url_edit_external", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 256, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 15 + ], + "twingle_campaign_parent_project_id" => [ + "custom_group_id" => "Twingle_Campaign_Information", + "label" => E::ts("Parent TwingleProject ID"), + "name" => "twingle_campaign_parent_project_id", + "is_required" => FALSE, + "is_searchable" => TRUE, + "data_type" => "String", + "html_type" => "Text", + "text_length" => 16, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 1 + ], + "twingle_campaign_cid" => [ + "custom_group_id" => "Twingle_Campaign_Information", + "label" => E::ts("CID"), + "name" => "twingle_campaign_cid", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "Text", + "text_length" => 32, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 2 + ], + "twingle_campaign_url" => [ + "custom_group_id" => "Twingle_Campaign_Information", + "label" => E::ts("URL"), + "name" => "twingle_campaign_url", + "is_required" => FALSE, + "is_searchable" => FALSE, + "data_type" => "Memo", + "html_type" => "TextArea", + "text_length" => 600, + "is_active" => TRUE, + "is_view" => TRUE, + "weight" => 3 + ] + ] +]; + diff --git a/CRM/TwingleCampaign/resources/dictionary.json b/CRM/TwingleCampaign/resources/dictionary.json deleted file mode 100644 index 150deff..0000000 --- a/CRM/TwingleCampaign/resources/dictionary.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "TwingleProject": { - "name": "title", - "last_update": "last_modified_date", - "project_target": "goal_revenue" - }, - "TwingleEvent": { - "description": "title", - "updated_at": "last_modified_date", - "created_at": "start_date", - "target": "goal_revenue" - } -} \ No newline at end of file diff --git a/CRM/TwingleCampaign/resources/dictionary.php b/CRM/TwingleCampaign/resources/dictionary.php new file mode 100644 index 0000000..e3a909c --- /dev/null +++ b/CRM/TwingleCampaign/resources/dictionary.php @@ -0,0 +1,18 @@ + [ + "name" => "title", + "last_update" => "last_modified_date", + "project_target" => "goal_revenue", + "counter-url" => "counter", + "embed" => "embed_codes" + ], + "TwingleEvent" => [ + "description" => "title", + "updated_at" => "last_modified_date", + "created_at" => "start_date", + "target" => "goal_revenue" + ] +]; + diff --git a/CRM/TwingleCampaign/resources/option_values.json b/CRM/TwingleCampaign/resources/option_values.json deleted file mode 100644 index 03b6564..0000000 --- a/CRM/TwingleCampaign/resources/option_values.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "twingle_event_donation": { - "name": "twingle_event_donation", - "label": "Twingle Event", - "description": "A soft credit type for TwingleEvent initiators.", - "option_group_id": "soft_credit_type" - } -} \ No newline at end of file diff --git a/CRM/TwingleCampaign/resources/option_values.php b/CRM/TwingleCampaign/resources/option_values.php new file mode 100644 index 0000000..c4a25d5 --- /dev/null +++ b/CRM/TwingleCampaign/resources/option_values.php @@ -0,0 +1,10 @@ + [ + "name" => "twingle_event_donation", + "label" => "Twingle Event", + "description" => "A soft credit type for TwingleEvent initiators.", + "option_group_id" => "soft_credit_type" + ] +]; diff --git a/CRM/TwingleCampaign/resources/twingle_api_templates.json b/CRM/TwingleCampaign/resources/twingle_api_templates.json deleted file mode 100644 index de6b202..0000000 --- a/CRM/TwingleCampaign/resources/twingle_api_templates.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "TwingleProject": [ - "id", - "identifier", - "allow_more", - "name", - "organisation_id", - "project_target", - "transaction_type", - "type", - "last_update", - "url" - ], - "project_embed_data": [ - "page", - "widget", - "form", - "form-single", - "widget-single", - "eventall", - "eventlist", - "counter" - ], - "TwingleEvent": [ - "id", - "project_id", - "identifier", - "description", - "user_name", - "user_email", - "is_public", - "deleted", - "confirmed_at", - "created_at", - "updated_at", - "target", - "creation_url", - "show_internal", - "show_external", - "edit_internal", - "edit_external", - "urls" - ], - "event_embed_data": [ - "page", - "eventpage", - "widget", - "form", - "widget-single", - "form-single", - "eventall", - "eventlist", - "eventeditcreate" - ], - "TwingleCampaign": [ - "id", - "parent_id", - "name", - "title" - ] -} \ No newline at end of file diff --git a/CRM/TwingleCampaign/resources/twingle_api_templates.php b/CRM/TwingleCampaign/resources/twingle_api_templates.php new file mode 100644 index 0000000..8e28c4f --- /dev/null +++ b/CRM/TwingleCampaign/resources/twingle_api_templates.php @@ -0,0 +1,114 @@ + [ + "project_data" => [ + "id", + "identifier", + "allow_more", + "name", + "organisation_id", + "project_target", + "transaction_type", + "type", + "last_update", + "url" + ], + "project_embed_data" => [ + "page", + "widget", + "form", + "form-single", + "widget-single", + "eventall", + "eventlist", + "counter" + ], + "project_options" => [ + "has_confirmation_mail", + "has_donation_receipt", + "has_contact_data", + "donation_rhythm", + "default_rhythm", + "has_newsletter_registration", + "has_postinfo_registration", + "design_background_color", + "design_primary_color", + "design_font_color", + "bcc_email_address", + "donation_value_min", + "donation_value_max", + "donation_value_default", + "contact_fields", + "exclude_contact_fields", + "mandatory_contact_fields", + "custom_css", + "share_url", + "has_contact_mandatory", + "has_doi", + "has_force_donation_target_buttons", + "slidericon", + "has_hidden_logo", + "has_projecttarget_as_money", + "has_donationtarget_textfield", + "has_civi_crm_activated", + "has_step_index", + "languages", + "has_buttons", + "has_no_slider", + "buttons", + "has_newsletter_namerequest", + "has_show_donator_data" + ], + "payment_methods" => [ + "has_paypal", + "has_banktransfer", + "has_debit", + "has_sofortueberweisung", + "has_paypal_recurring", + "has_debit_recurring" + ] + ], + "TwingleEvent" => [ + "event_data" => [ + "id", + "project_id", + "identifier", + "description", + "user_name", + "user_email", + "is_public", + "deleted", + "confirmed_at", + "created_at", + "updated_at", + "target", + "creation_url", + "show_internal", + "show_external", + "edit_internal", + "edit_external", + "urls" + ], + "event_embed_data" => [ + "page", + "eventpage", + "widget", + "form", + "widget-single", + "form-single", + "eventall", + "eventlist", + "eventeditcreate" + ] + ], + "TwingleCampaign" => [ + "campaign_data" => [ + "id", + "parent_id", + "name", + "title" + ] + ] +]; + diff --git a/api/v3/TwingleCampaign/Get.php b/api/v3/TwingleCampaign/Get.php index dce6b3a..6897ef0 100644 --- a/api/v3/TwingleCampaign/Get.php +++ b/api/v3/TwingleCampaign/Get.php @@ -105,7 +105,7 @@ function civicrm_api3_twingle_campaign_Get(array $params): array { // Get campaign type id for TwingleCampaign $twingle_campaign_campaign_type_id = Cache::getInstance() - ->getCampaigns()['campaign_types']['twingle_campaign']['id']; + ->getCampaignIds()['campaign_types']['twingle_campaign']['id']; // If no id but a project_id is provided, get all TwingleCampaign children of // this TwingleProject diff --git a/twinglecampaign.php b/twinglecampaign.php index 72558e1..ef73167 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -173,17 +173,17 @@ function twinglecampaign_postSave_campaign_callback ( try { civicrm_api3('TwingleProject', 'sync', ['id' => $campaign_id]); CRM_Utils_System::setUFMessage('TwingleProject was saved.'); - } catch (CiviCRM_API3_Exception $e) { - Civi::log()->error( - 'twinglecampaign_postSave_callback ' . $e->getMessage() - ); - } - } else { - try { - civicrm_api3('TwingleCampaign', 'create', ['id' => $campaign_id]); - CRM_Utils_System::setUFMessage('TwingleCampaign was saved.'); - } catch (CiviCRM_API3_Exception $e) { - Civi::log()->error( + +function _get_campaign_type_id_twingle_project() { + return ExtensionCache::getInstance() + ->getCampaignIds()['campaign_types']['twingle_project']['id']; +} + +function _get_campaign_type_id_twingle_campaign() { + return ExtensionCache::getInstance() + ->getCampaignIds()['campaign_types']['twingle_campaign']['id']; +} + 'twinglecampaign_postSave_callback ' . $e->getMessage() ); } From 0b1128fce54b1b1ca9fc7c0d5a563900f72cf276 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 11:44:11 +0200 Subject: [PATCH 02/12] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20implement=20formatti?= =?UTF-8?q?ng=20of=20settings=20values=20on=20import=20and=20export?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/Campaign.php | 101 +++-- CRM/TwingleCampaign/BAO/TwingleEvent.php | 2 +- CRM/TwingleCampaign/BAO/TwingleProject.php | 347 ++++++++++++++++-- .../Utils/StringOperations.php | 20 + api/v3/TwingleEvent/Get.php | 1 + api/v3/TwingleProject/Get.php | 24 +- 6 files changed, 436 insertions(+), 59 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/Campaign.php b/CRM/TwingleCampaign/BAO/Campaign.php index b8d8435..71f0245 100644 --- a/CRM/TwingleCampaign/BAO/Campaign.php +++ b/CRM/TwingleCampaign/BAO/Campaign.php @@ -10,6 +10,10 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { // OUT means: coming from the CiviCRM database public const OUT = 'OUT'; + public const PROJECT = 'TwingleProject'; + + public const EVENT = 'TwingleEvent'; + protected $className; protected $id; @@ -60,6 +64,7 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { ); $this->translateKeys( $values_prepared_for_import, + $this->className, self::IN ); $this->formattedValues = $values_prepared_for_import; @@ -76,6 +81,16 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { $_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] = TRUE; } + // Cast booleans to integers + foreach ($values_prepared_for_import as $key => $value) { + if ($value === false) { + $values_prepared_for_import[$key] = 0; + } + elseif ($value === true) { + $values_prepared_for_import[$key] = 1; + } + } + // Create campaign $result = civicrm_api3('Campaign', 'create', $values_prepared_for_import); @@ -156,17 +171,27 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { * * @param array $values * array of keys to translate - * + * @param string $campaignType + * const: Campaign::PROJECT or Campaign::EVENT * @param string $direction * const: Campaign::OUT or Campaign::OUT * - * @throws Exception + * @throws \Exception */ - public function translateKeys(array &$values, string $direction) { + public static function translateKeys( + array &$values, + string $campaignType, + string $direction) { + + if ($campaignType != self::PROJECT && $campaignType != self::EVENT) { + throw new Exception( + "Invalid Parameter $campaignType for translateKeys()" + ); + } // Get translations for fields $field_translations = Cache::getInstance() - ->getTranslations()[$this->className]; + ->getTranslations()[$campaignType]; // Set the direction of the translation if ($direction == self::OUT) { @@ -188,7 +213,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { } } - /** * ## Translate field names and custom field names * @@ -256,18 +280,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { } } - - /** - * ## Set counter url - * - * @param String $counterUrl - * URL of the counter - */ - public function setCounterUrl(string $counterUrl) { - $this->values['counter'] = $counterUrl; - } - - /** * ## Delete Campaign * Deletes this Campaign from CiviCRM @@ -287,7 +299,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { return ($result['is_error'] == 0); } - /** * ## Deactivate this campaign * @@ -300,7 +311,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { return self::deactivateByid($this->id); } - /** * ## Deactivate campaign by ID * @@ -335,10 +345,8 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { } } - public abstract function getResponse(string $status): array; - /** * ## Get timestamp * Validates **$input** to be either a *DateTime string* or an *Unix @@ -370,10 +378,8 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { } } - public abstract function lastUpdate(); - /** * ## Get DateTime * Validates **$input** to be either a *DateTime string* or an *Unix @@ -407,7 +413,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { } } - /** * ## Get id * Returns the **id** of this campaign. @@ -418,4 +423,52 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { return (int) $this->id; } + /** + * Helper function to search a value in a multidimensional array. + * + * @param $needle + * @param $haystack + * @param bool $strict + * + * @return bool + */ + protected function in_array_r($needle, $haystack, $strict = false): bool { + foreach ($haystack as $item) { + if (($strict ? $item === $needle : $item == $needle) || + (is_array($item) && $this->in_array_r($needle, $item, $strict))) { + return true; + } + } + return false; + } + + /** + * Helper function to check if the provided field is of type Boolean + * + * @param $fieldName + * @param string $campaignType Campaign::PROJECT or Campaign::EVENT + * + * @return bool + * @throws \Exception + */ + public static function isBoolean($fieldName, string $campaignType): bool { + $fields = Cache::getInstance()->getCampaigns()['custom_fields']; + if ($campaignType == self::PROJECT) { + if (isset($fields['twingle_project_' . $fieldName])) { + return $fields['twingle_project_' . $fieldName]['data_type'] == 'Boolean'; + } + else { + return FALSE; + } + } + elseif ($campaignType == self::EVENT) { + if (isset($fields['twingle_event_' . $fieldName])) { + return $fields['twingle_event_' . $fieldName]['data_type'] == 'Boolean'; + } + else { + return FALSE; + } + } + throw new Exception('Unknown campaign type'); + } } diff --git a/CRM/TwingleCampaign/BAO/TwingleEvent.php b/CRM/TwingleCampaign/BAO/TwingleEvent.php index 2adc38c..f1c4473 100644 --- a/CRM/TwingleCampaign/BAO/TwingleEvent.php +++ b/CRM/TwingleCampaign/BAO/TwingleEvent.php @@ -100,7 +100,7 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { * * @throws Exception */ - public function formatValues(array &$values, string $direction) { + public static function formatValues(array &$values, string $direction) { if ($direction == self::IN) { diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index 2473c3d..4035ecc 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -2,10 +2,35 @@ use CRM_TwingleCampaign_Utils_ExtensionCache as Cache; use CRM_TwingleCampaign_BAO_Campaign as Campaign; +use CRM_TwingleCampaign_Utils_StringOperations as StringOperations; +use CRM_TwingleCampaign_ExtensionUtil as E; class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { + // All available contact fields in Twingle project forms + const contactFields = [ + 'salutation', + 'firstname', + 'lastname', + 'company', + 'birthday', + 'street', + 'postal_code', + 'city', + 'country', + 'telephone', + ]; + + // All available donation rhythms in Twingle project forms + const donationRhythm = [ + 'yearly', + 'halfyearly', + 'quarterly', + 'monthly', + 'one_time', + ]; + /** * ## TwingleProject constructor * @@ -25,36 +50,91 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { } - /** * ## Export values - * Ensures that only those values will be exported which the Twingle API - * expects. These values are defined in - * *CRM/TwingleCampaign/resources/twingle_api_templates.json* + * Change all values to a format accepted by the Twingle API. * * @return array - * Array with all values to send to the Twingle API - * - * @throws Exception + * Array with all values ready to send to the Twingle API + * @throws \Exception */ public function export(): array { - + // copy project values $values = $this->values; - self::formatValues($values, self::OUT); - // Get template for project - $project = Cache::getInstance()->getTemplates()['TwingleProject']; + // Strings to booleans + $this->intToBool($values); - // Replace array items which the Twingle API does not expect - foreach ($values as $key => $value) { - if (!in_array($key, $project)) { - unset($values[$key]); - } + // Strings to integers + $this->strToInt($values); + + // Build counter-url array + if (isset($values['counter-url']) && is_string($values['counter-url'])) { + $url = $values['counter-url']; + unset($values['counter-url']); + $values['counter-url']['url'] = $url; } + // Remove campaign_type_id + unset($values['campaign_type_id']); + return $values; } + /** + * ## Int to bool + * Changes all project values that are defined as CiviCRM 'Boolean' types + * from strings to booleans. + * @param array $values + * @throws \Exception + */ + private function intToBool(array &$values) { + + $boolArrays = [ + 'payment_methods', + 'donation_rhythm', + ]; + + foreach ($values as $key => $value) { + if (CRM_TwingleCampaign_BAO_Campaign::isBoolean( + $key, + CRM_TwingleCampaign_BAO_Campaign::PROJECT + )) { + $values[$key] = (bool) $value; + } + elseif (in_array($key, $boolArrays)) { + foreach ($values[$key] as $_key => $_value) { + if (is_numeric($_value) && $_value < 2 || empty($_value)) { + $values[$key][$_key] = (bool) $_value; + } + else { + unset($values[$key][$_key]); + } + } + } + elseif (is_array($value)) { + $this->intToBool($values[$key]); + } + } + } + + /** + * ## Int to bool + * Changes all project values that are strings but originally came as integers + * back to integers. + * @param array $values + * @throws \Exception + */ + private function strToInt(array &$values) { + foreach ($values as $key => $value) { + if (ctype_digit($value)) { + $values[$key] = intval($value); + } + elseif (is_array($value)) { + $this->strToInt($values[$key]); + } + } + } /** * ## Create this TwingleProject as a campaign in CiviCRM @@ -80,6 +160,58 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { } } + /** + * ## Update instance values + * + * @param array $values + * + * @override CRM_TwingleCampaign_BAO_Campaign::update() + */ + public function update(array $values) { + + // Remove old values + unset($this->values); + + // Get allowed values + $projectOptionsKeys = Cache::getInstance() + ->getTemplates()['TwingleProject']['project_options']; + $projectEmbedDataKeys = Cache::getInstance() + ->getTemplates()['TwingleProject']['project_embed_data']; + $projectPaymentMethodsKeys = Cache::getInstance() + ->getTemplates()['TwingleProject']['payment_methods']; + + // Sort allowed values into arrays + foreach ($values as $key => $value) { + if ($key == 'project_options') { + foreach ($value as $optionKey => $optionValue) { + if (in_array($optionKey, $projectOptionsKeys)) { + $this->values['project_options'][$optionKey] = $optionValue; + } + } + } + elseif ($key == 'embed') { + foreach ($value as $embedKey => $embedValue) { + if (in_array($embedKey, $projectEmbedDataKeys)) { + $this->values['embed'][$embedKey] = $embedValue; + } + } + } + elseif ($key == 'payment_methods') { + foreach ($value as $paymentMethodKey => $paymentMethodValue) { + if (in_array($paymentMethodKey, $projectPaymentMethodsKeys)) { + $this->values['payment_methods'][$paymentMethodKey] = + $paymentMethodValue; + } + } + } + elseif ($key == 'counter-url' && is_array($value)) { + $this->values['counter-url'] = $value['url']; + } + else { + parent::update([$key => $value]); + } + } + } /** * ## Clone this TwingleProject @@ -114,23 +246,127 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * * @throws Exception */ - public function formatValues(array &$values, string $direction) { + public static function formatValues(array &$values, string $direction) { if ($direction == self::IN) { // Change timestamp into DateTime string - if ($values['last_update']) { + if (isset($values['last_update'])) { $values['last_update'] = self::getDateTime($values['last_update']); } // empty project_type to 'default' - if (!$values['type']) { + if (empty($values['type'])) { $values['type'] = 'default'; } + + // Flatten project options array + foreach ($values['project_options'] as $key => $value) { + $values[$key] = $value; + } + unset($values['project_options']); + + // Flatten embed codes array + foreach ($values['embed'] as $key => $value) { + $values[$key] = $value; + } + unset($values['embed']); + + // Flatten button array + if (isset($values['buttons'])) { + foreach ( + $values['buttons'] as $button_key => $button + ) { + $values[$button_key] = $button['amount']; + } + unset($values['buttons']); + } + + // Invert and explode exclude_contact_fields + if (isset($values['exclude_contact_fields'])) { + $values['contact_fields'] = + array_diff( + self::contactFields, + explode(',', $values['exclude_contact_fields']) + ); + unset($values['exclude_contact_fields']); + } + + // Explode mandatory_contact_fields + if (isset($values['mandatory_contact_fields'])) { + $values['mandatory_contact_fields'] = + explode( + ',', + $values['mandatory_contact_fields'] + ); + unset($values['mandatory_contact_fields']); + } + + // Explode languages + if (isset($values['languages'])) { + $values['languages'] = + explode(',', $values['languages']); + } + + // Divide payment methods array into one time and recurring payment + // methods arrays containing only TRUE payment methods + foreach ($values['payment_methods'] as $key => $value) { + if ($value) { + if (StringOperations::endsWith($key, 'recurring')) { + $values['payment_methods_recurring'][] = $key; + } + else { + $values['payment_methods'][] = $key; + } + } + unset($values['payment_methods'][$key]); + } + + // Transform donation rhythm array to contain only TRUE elements + foreach ($values['donation_rhythm'] as $key => $value) { + if ($value) { + $values['donation_rhythm'][] = $key; + } + unset($values['donation_rhythm'][$key]); + } } elseif ($direction == self::OUT) { + $projectOptionsKeys = Cache::getInstance() + ->getTemplates()['TwingleProject']['project_options']; + $projectEmbedDataKeys = Cache::getInstance() + ->getTemplates()['TwingleProject']['project_embed_data']; + + // Merge payment_methods and payment_methods_recurring arrays and change + // keys to values and values to TRUE + if (isset($values['payment_methods'])) { + foreach ($values['payment_methods'] as $key => $value) { + unset($values['payment_methods'][$key]); + $values['payment_methods'][$value] = TRUE; + } + } + if (isset($values['payment_methods_recurring'])) { + foreach ($values['payment_methods_recurring'] as $value) { + $values['payment_methods'][$value] = TRUE; + } + unset($values['payment_methods_recurring']); + } + + // Move options, embed data and payment methods into own arrays + foreach ($values as $key => $value) { + if (in_array($key, $projectOptionsKeys)) { + $values['project_options'][$key] + = $value; + unset($values[$key]); + } + elseif (in_array($key, $projectEmbedDataKeys)) { + $values['embed_data'][$key] + = $value; + unset($values[$key]); + } + } + // Change DateTime string into timestamp $values['last_update'] = self::getTimestamp($values['last_update']); @@ -141,19 +377,80 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { : $values['type']; // Cast project target to integer - $values['project_target'] = (int) $values['project_target']; + if (isset($values['project_target'])) { + $values['project_target'] = (int) $values['project_target']; + } // Set default for 'allow_more' - $values['allow_more'] = empty($values['allow_more']) - ? FALSE - : TRUE; + $values['allow_more'] = !empty($values['allow_more']); + + // Invert and concatenate contact fields + if (isset($values['project_options']['contact_fields'])) { + // Invert contact_fields to exclude_contact_fields + $values['project_options']['exclude_contact_fields'] = + array_diff( + self::contactFields, + $values['project_options']['contact_fields'] + ); + unset($values['project_options']['contact_fields']); + // Concatenate contact_fields array + $values['project_options']['exclude_contact_fields'] = + implode( + ',', + $values['project_options']['exclude_contact_fields'] + ); + } + + // Concatenate mandatory project contact fields + if (isset($values['project_options']['mandatory_contact_fields'])) { + $values['project_options']['mandatory_contact_fields'] = + implode( + ',', + $values['project_options']['mandatory_contact_fields'] + ); + } + + // Concatenate project languages + if (isset($values['project_options']['languages'])) { + $values['project_options']['languages'] = + implode(',', $values['project_options']['languages']); + } + + // Build donation_rhythm array + if (isset($values['project_options']['donation_rhythm'])) { + $tmp_array = []; + foreach (self::donationRhythm as $donationRhythm) { + $tmp_array[$donationRhythm] = + in_array( + $donationRhythm, + $values['project_options']['donation_rhythm'] + ); + } + $values['project_options']['donation_rhythm'] = $tmp_array; + } + + // Build payment_methods_array + if (isset($values['payment_methods'])) { + $payment_methods = array_fill_keys(Cache::getInstance() + ->getTemplates()['TwingleProject']['payment_methods'], + FALSE); + $values['payment_methods'] = + array_merge($payment_methods, $values['payment_methods']); + } + + // Build buttons array + for ($i = 1; $i <= 4; $i++) { + if (isset($values['button' . $i])) { + $values['project_options']['buttons']['button' . $i] = + ['amount' => $values['button' . $i]]; + unset($values['button' . $i]); + } + } } else { - throw new Exception( "Invalid Parameter $direction for formatValues()" ); - } } diff --git a/CRM/TwingleCampaign/Utils/StringOperations.php b/CRM/TwingleCampaign/Utils/StringOperations.php index 00014b7..19c0fd3 100644 --- a/CRM/TwingleCampaign/Utils/StringOperations.php +++ b/CRM/TwingleCampaign/Utils/StringOperations.php @@ -51,4 +51,24 @@ class CRM_TwingleCampaign_Utils_StringOperations { } return $string; } + + /** + * Checks if a string ands with another string. + * @param $haystack + * @param $needle + * @return bool + */ + public static function endsWith($haystack, $needle): bool { + return substr_compare($haystack, $needle, -strlen($needle)) === 0; + } + + /** + * Checks if a string starts with another string. + * @param $haystack + * @param $needle + * @return bool + */ + public static function startsWith($haystack, $needle): bool { + return substr_compare($haystack, $needle, 0, strlen($needle)) === 0; + } } \ No newline at end of file diff --git a/api/v3/TwingleEvent/Get.php b/api/v3/TwingleEvent/Get.php index 2398d66..02caaea 100644 --- a/api/v3/TwingleEvent/Get.php +++ b/api/v3/TwingleEvent/Get.php @@ -157,6 +157,7 @@ function civicrm_api3_twingle_event_Get(array $params): array { $tmp_event = new TwingleEvent([]); $tmp_event->translateKeys( $returnValues[$event['id']], + TwingleEvent::EVENT, TwingleEvent::OUT ); TwingleEvent::formatValues( diff --git a/api/v3/TwingleProject/Get.php b/api/v3/TwingleProject/Get.php index 5754ba3..da78501 100644 --- a/api/v3/TwingleProject/Get.php +++ b/api/v3/TwingleProject/Get.php @@ -156,22 +156,28 @@ function civicrm_api3_twingle_project_Get(array $params): array { $returnValues[$project['id']][$key] = $value; } } - foreach($returnValues[$project['id']] as $key => $value) { + foreach ($returnValues[$project['id']] as $key => $value) { if ($key != 'twingle_project_id' && strpos($key, 'twingle_project_') === 0) { - $returnValues[$project['id']][str_replace('twingle_project_', '', $key)] - = $value; + $key_short = str_replace('twingle_project_', '', $key); + $returnValues[$project['id']][$key_short] = $value; unset($returnValues[$project['id']][$key]); - } elseif($key == 'twingle_project_id'){ + } + elseif ($key == 'twingle_project_id') { $returnValues[$project['id']]['project_id'] = $value; unset($returnValues[$project['id']]['twingle_project_id']); } } try { - $tmp_project = new TwingleProject([]); - $tmp_project->translateKeys($returnValues[$project['id']], TwingleProject::OUT); - $tmp_project->formatValues($returnValues[$project['id']], TwingleProject::OUT); - } - catch (Exception $e) { + TwingleProject::translateKeys( + $returnValues[$project['id']], + TwingleProject::PROJECT, + TwingleProject::OUT + ); + TwingleProject::formatValues( + $returnValues[$project['id']], + TwingleProject::OUT + ); + } catch (Exception $e) { throw new API_Exception($e->getMessage()); } } From 4dc3644bb3ee81b0bba017238be151e281863d34 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 10:11:06 +0200 Subject: [PATCH 03/12] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20implement=20synchron?= =?UTF-8?q?isation=20of=20TwingleProject=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/Campaign.php | 47 +++----- CRM/TwingleCampaign/BAO/TwingleApiCall.php | 131 ++++++++++++++++++--- api/v3/TwingleProject/Sync.php | 38 +++--- 3 files changed, 149 insertions(+), 67 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/Campaign.php b/CRM/TwingleCampaign/BAO/Campaign.php index 71f0245..593a358 100644 --- a/CRM/TwingleCampaign/BAO/Campaign.php +++ b/CRM/TwingleCampaign/BAO/Campaign.php @@ -104,12 +104,11 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { return TRUE; } - /** * ## Update instance values * This method updates the **$values** array of this instance with the values * from the provided array if they are defined in - * *CRM/TwingleCampaign/resources/twingle_api_templates.json* + * *CRM/TwingleCampaign/resources/twingle_api_templates.php* * * @param array $values * Array with values to update @@ -118,47 +117,33 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { // Update campaign values $filter = Cache::getInstance()->getTemplates()[$this->className]; foreach ($values as $key => $value) { - if ($this->className == "TwingleProject" && $key == 'project_id') { - $this->values['id'] = $value; - } - elseif (in_array($key, $filter)) { + if ($this->in_array_r($key, $filter)) { $this->values[$key] = $value; } - elseif ($key == 'embed') { - self::setEmbedData($value); - } - elseif ($key == 'counter-url') { - self::setCounterUrl($value['url']); - } } } - /** - * ## Set embed data fields - * This method sets all embed data fields that are defined in - * *CRM/TwingleCampaign/resources/twingle_api_templates.json* - * - * @param array $embedData - * Array with embed data from Twingle API + * ## Complement campaign values + * Complement existing campaign values with new ones + * @param array $arrayToComplement */ - public function setEmbedData(array $embedData) { + public function complement(array $arrayToComplement) { + $this->complement_r($this->values, $arrayToComplement); + $this->values = $arrayToComplement; + } - // Get all embed_data keys from template - $embed_data_keys = Cache::getInstance() - ->getTemplates()['project_embed_data']; - - // Transfer all embed_data values - foreach ($embed_data_keys as $key) { - if (array_key_exists($key, $embedData)) { - $this->values[$key] = $embedData[$key]; + private function complement_r($orig, &$fill) { + foreach ($orig as $key => $value) { + if (is_array($value)) { + $this->complement_r($orig[$key], $fill[$key]); + } else { + $fill[$key] = $value; } } } - - public abstract function formatValues(array &$values, string $direction); - + public static abstract function formatValues(array &$values, string $direction); /** * ## Translate array keys between CiviCRM Campaigns and Twingle diff --git a/CRM/TwingleCampaign/BAO/TwingleApiCall.php b/CRM/TwingleCampaign/BAO/TwingleApiCall.php index 5d6d037..cb3999d 100644 --- a/CRM/TwingleCampaign/BAO/TwingleApiCall.php +++ b/CRM/TwingleCampaign/BAO/TwingleApiCall.php @@ -1,6 +1,5 @@ protocol . 'project' . $this->baseUrl . 'by-organisation/' . $this->organisationId - : $this->protocol . 'project' . $this->baseUrl . $projectId; + // If no project id is provided, return all projects + if (empty($projectId)) { + $response = []; + $projects = $this->curlGet($this->protocol . 'project' . + $this->baseUrl . 'by-organisation/' . $this->organisationId); + foreach ($projects as $project) { + $response[] = $this->getProject($project['id']); + } + return $response; + } + // If a project id is provided, return only one project + else { - return $this->curlGet($url); + // Get all general project information + $project = $this->curlGet($this->protocol . 'project' . + $this->baseUrl . $projectId); + + // Get project options + $project['project_options'] = $this->getProjectOptions($projectId); + + // Get project payment methods + $project['payment_methods'] = + $this->getProjectPaymentMethods($projectId); + + // Set last update time + $project['last_update'] = max( + $project['last_update'], + $project['project_options']['last_update'], + $project['payment_methods']['updated_at'] + ); + unset($project['project_options']['last_update']); + unset($project['payment_methods']['updated_at']); + + return $project; + } } /** @@ -92,30 +121,67 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { * * Returns an array with all project values. * - * @param TwingleProject $project - * The TwingleProject object that should get pushed to Twingle + * @param array $project + * The project values array that should get pushed to Twingle * * @return array * @throws \Exception */ - public function pushProject(TwingleProject &$project): array { + public function pushProject(array $project): array { - // Get only those values from the TwingleProject object which Twingle expects - $values = $project->export(); + $projectOptions = $project['project_options']; + unset($project['project_options']); + $paymentMethods = $project['payment_methods']; + unset($project['payment_methods']); - // Prepare url for curl - if ($values['id']) { - $url = $this->protocol . 'project' . $this->baseUrl . $values['id']; - } - else { - $url = $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' . - $this->organisationId; + try { + if (!isset($project['id'])) { + $url = $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' . + $this->organisationId; + + // Post project values + $updatedProject = $this->curlPost($url, $project); + + $url = $this->protocol . 'project' . $this->baseUrl . + $updatedProject['id']; + } + else { + $url = $this->protocol . 'project' . $this->baseUrl . $project['id']; + + // Post project values + $updatedProject = $this->curlPost($url, $project); + } + + // Post project_options + $updatedProject['project_options'] = + $this->curlPost($url . '/options', $projectOptions); + + // Post payment_methods + $this->curlPost($url . '/payment-methods', $paymentMethods); + $updatedProject['payment_methods'] = + $this->getProjectPaymentMethods($updatedProject['id']); + + // Set last update time + $updatedProject['last_update'] = max( + $updatedProject['last_update'], + $updatedProject['project_options']['last_update'], + $updatedProject['payment_methods']['updated_at'] + ); + unset($updatedProject['project_options']['last_update']); + unset($updatedProject['payment_methods']['updated_at']); + + return $updatedProject; + } catch (Exception $e) { + throw new Exception( + E::SHORT_NAME . 'Call to Twingle API failed: ' . + $e->getMessage() + ); } - // Send curl and return result - return $this->curlPost($url, $values); + } + /** * ## Get event from Twingle * Returns all events for the provided **$projectId** or a single event if an @@ -197,6 +263,33 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } } + /** + * ## Get project options + * Gets all project options from the Twingle API + * @param $projectId + * + * @return array + * @throws \Exception + */ + public function getProjectOptions($projectId): array { + $url = $this->protocol . 'project' . $this->baseUrl . $projectId . '/options'; + return $this->curlGet($url); + } + + /** + * ## Get project payment methods + * Gets all project payment methods from the Twingle API + * @param $projectId + * + * @return array + * @throws \Exception + */ + public function getProjectPaymentMethods($projectId): array { + $url = $this->protocol . 'project' . $this->baseUrl . $projectId + . '/payment-methods'; + return $this->curlGet($url); + } + /** * ## Delete Project diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index db1ebb2..b55f8a3 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -189,11 +189,6 @@ function civicrm_api3_twingle_project_Sync(array $params): array { $project = new TwingleProject($project_from_twingle); try { - // Get embed data - $project->setEmbedData( - $twingleApi->getProjectEmbedData($project->getProjectId()) - ); - // If this is a test, do not make db changes if (isset($params['is_test']) && $params['is_test']) { $returnValues[$project->getId()] = @@ -231,14 +226,18 @@ function civicrm_api3_twingle_project_Sync(array $params): array { $project = new TwingleProject($project_from_civicrm, $id); // sync project - $result = _projectSync($project, $project_from_twingle, $twingleApi, $params); - if ($result['is_error'] != 0) { - $errors_occurred++; + $result = _projectSync( + $project, + $project_from_twingle, + $twingleApi, + $params); + if (!$result['is_error'] == 0) { + $errors[$result['id']] = $result['error_message']; $returnValues[$project->getId()] = $project->getResponse($result['error_message']); } else { - $returnValues[$project->getId()] = $result['values']; + $returnValues[$result['id']] = $result['values'][$result['id']]; } break; } @@ -284,9 +283,7 @@ function _updateProjectLocally(array $project_from_twingle, try { $project->update($project_from_twingle); - $project->setEmbedData( - $twingleApi->getProjectEmbedData($project->getProjectId()) - ); + // If this is a test, do not make db changes if (array_key_exists('is_test', $params) && $params['is_test']) { return civicrm_api3_create_success( @@ -346,7 +343,7 @@ function _pushProjectToTwingle(TwingleProject $project, // Push project to Twingle try { - $result = $twingleApi->pushProject($project); + $result = $twingleApi->pushProject($project->export()); } catch (Exception $e) { Civi::log()->error( E::LONG_NAME . @@ -363,11 +360,7 @@ function _pushProjectToTwingle(TwingleProject $project, // Update local campaign with data returning from Twingle if ($result) { $project->update($result); - // Get embed data try { - $project->setEmbedData( - $twingleApi->getProjectEmbedData($project->getProjectId()) - ); // Create updated campaign $project->create(TRUE); $response = $project->getResponse('TwingleProject pushed to Twingle'); @@ -432,6 +425,17 @@ function _projectSync(TwingleProject $project, // If the CiviCRM TwingleProject campaign was changed, update the project // on Twingle's side elseif ($project_from_twingle['last_update'] < $project->lastUpdate()) { + // Make sure that the project hast a correct project_id. This is important + // to avoid an accidental cloning of project. + if (empty($project->getProjectId())) { + throw new \CiviCRM_API3_Exception( + 'Missing project_id for project that is meant to get updated on Twingle side.'); + } + + // By merging the project values with the values coming from Twingle, we + // make sure that the project contains all values needed to get pushed + $project->complement($project_from_twingle); + return _pushProjectToTwingle($project, $twingleApi, $params); } From ab8c16fac2ff52892a6b3ec1e18b9504fc473332 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 10:49:56 +0200 Subject: [PATCH 04/12] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20implement=20upgrade?= =?UTF-8?q?=20function=20to=20create=20new=20custom=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/CampaignType.php | 7 ++-- CRM/TwingleCampaign/BAO/CustomField.php | 15 ++++---- CRM/TwingleCampaign/BAO/CustomGroup.php | 10 +++++- CRM/TwingleCampaign/Upgrader.php | 44 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/CampaignType.php b/CRM/TwingleCampaign/BAO/CampaignType.php index 486c970..8e9f686 100644 --- a/CRM/TwingleCampaign/BAO/CampaignType.php +++ b/CRM/TwingleCampaign/BAO/CampaignType.php @@ -29,7 +29,7 @@ class CRM_TwingleCampaign_BAO_CampaignType { /** * @throws \CiviCRM_API3_Exception */ - public function create() { + public function create(bool $upgrade = false) { $field = civicrm_api3( 'OptionValue', @@ -59,7 +59,7 @@ class CRM_TwingleCampaign_BAO_CampaignType { for \"$this->label\": $error_message"); } } - else { + elseif (!$upgrade) { $campaignType = self::fetch($this->name); foreach ($this as $var => $value) { if (array_key_exists($var, $campaignType->getSetAttributes())) { @@ -67,6 +67,9 @@ class CRM_TwingleCampaign_BAO_CampaignType { } } } + else { + $this->value = $field['values'][0]['value']; + } } /** diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index b393e24..2145b67 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -65,9 +65,12 @@ class CRM_TwingleCampaign_BAO_CustomField { /** * Creates a CustomField by calling CiviCRM API v.3 * + * @param bool $upgrade + * If true: Does not show UF message if custom field already exists + * * @throws \CiviCRM_API3_Exception */ - public function create() { + public function create(bool $upgrade = false) { // Check if the field already exists $field = civicrm_api3( @@ -118,14 +121,10 @@ class CRM_TwingleCampaign_BAO_CustomField { } } } - else { - CRM_Utils_System::setUFMessage("Creation of custom field '$this->name' - failed, because a custom field with that name already exists. - Find more information in the logs."); + elseif (!$upgrade) { + CRM_Utils_System::setUFMessage(E::ts('Creation of custom field \'%1\' failed, because a custom field with that name already exists. Find more information in the logs.', [1 => $this->name])); Civi::log() - ->error("$this->extensionName could not create new custom field - \"$this->name\" for group \"$this->custom_group_id\" because a - field with that name already exists."); + ->error("$this->extensionName could not create new custom field \"$this->name\" for group \"$this->custom_group_id\" because a field with that name already exists."); } } diff --git a/CRM/TwingleCampaign/BAO/CustomGroup.php b/CRM/TwingleCampaign/BAO/CustomGroup.php index 3b92099..20fa1e5 100644 --- a/CRM/TwingleCampaign/BAO/CustomGroup.php +++ b/CRM/TwingleCampaign/BAO/CustomGroup.php @@ -41,9 +41,12 @@ class CRM_TwingleCampaign_BAO_CustomGroup { } /** + * @param bool $upgrade + * If true: Does not show UF message if custom group already exists + * * @throws \CiviCRM_API3_Exception */ - public function create() { + public function create(bool $upgrade = false) { $field = civicrm_api3( 'CustomGroup', @@ -86,6 +89,11 @@ class CRM_TwingleCampaign_BAO_CustomGroup { } } + elseif (!$upgrade) { + CRM_Utils_System::setUFMessage(E::ts('Creation of custom group \'%1\' failed, because a custom group with that name already exists. Find more information in the logs.', [1 => $this->name])); + Civi::log() + ->error("$this->extensionName could not create new custom group \"$this->name\" because a group with that name already exists."); + } } /** diff --git a/CRM/TwingleCampaign/Upgrader.php b/CRM/TwingleCampaign/Upgrader.php index dea29ab..b87e152 100644 --- a/CRM/TwingleCampaign/Upgrader.php +++ b/CRM/TwingleCampaign/Upgrader.php @@ -16,6 +16,50 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base { // By convention, functions that look like "function upgrade_NNNN()" are // upgrade tasks. They are executed in order (like Drupal's hook_update_N). + /** + * @throws \CiviCRM_API3_Exception + */ + public function upgrade_01() { + + $campaign_info = require E::path() . + '/CRM/TwingleCampaign/resources/campaigns.php'; + $option_values = require E::path() . + '/CRM/TwingleCampaign/resources/option_values.php'; + + // Create campaign types + foreach ($campaign_info['campaign_types'] as $campaign_type) { + new CampaignType($campaign_type); + } + foreach (CampaignType::getCampaignTypes() as $campaign_type) { + $campaign_type->create(true); + } + + // Create custom groups + foreach ($campaign_info['custom_groups'] as $custom_group) { + foreach (CampaignType::getCampaignTypes() as $campaign_type) { + if ($campaign_type->getName() == $custom_group['campaign_type']) { + $custom_group['extends_entity_column_value'] = $campaign_type->getValue(); + } + } + $cg = new CustomGroup($custom_group); + $cg->create(true); + } + + // Create custom fields + foreach ($campaign_info['custom_fields'] as $custom_field) { + $cf = new CustomField($custom_field); + $cf->create(true); + } + + // Create option values + foreach ($option_values as $option_value) { + $ov = new OptionValue($option_value); + $ov->create(); + } + + return TRUE; + } + /** * @throws \Exception */ From 060f7ec2dc36249a7c7bf63e6fa7918a9011c112 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 10:29:52 +0200 Subject: [PATCH 05/12] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20improve=20exception?= =?UTF-8?q?=20handling=20and=20API=20response?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleApiCall.php | 3 ++ api/v3/TwingleProject/Sync.php | 47 ++++++++++++++++------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleApiCall.php b/CRM/TwingleCampaign/BAO/TwingleApiCall.php index cb3999d..20d8c68 100644 --- a/CRM/TwingleCampaign/BAO/TwingleApiCall.php +++ b/CRM/TwingleCampaign/BAO/TwingleApiCall.php @@ -405,6 +405,9 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } elseif ($curl_status_code == 500) { throw new Exception('https status code 500 (internal error)'); } + if (sizeof($response) == 1 && isset($response['message'])){ + throw new Exception($response['message']); + } return $response; } diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index b55f8a3..aae2b47 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -140,7 +140,7 @@ function civicrm_api3_twingle_project_Sync(array $params): array { else { // Counter for sync errors - $errors_occurred = 0; + $errors = []; // Get all projects from Twingle $projects_from_twingle = $twingleApi->getProject(); @@ -172,7 +172,7 @@ function civicrm_api3_twingle_project_Sync(array $params): array { // push project to Twingle $result = _pushProjectToTwingle($project, $twingleApi, $params); if ($result['is_error'] != 0) { - $errors_occurred++; + $errors[$result['id']] = $result['error_message']; $returnValues[$project->getId()] = $project->getResponse($result['error_message']); } @@ -199,7 +199,7 @@ function civicrm_api3_twingle_project_Sync(array $params): array { $returnValues[$project->getId()] = $project->getResponse('TwingleProject created'); } catch (Exception $e) { - $errors_occurred++; + $errors[$result['id']] = $result['error_message']; Civi::log()->error( E::LONG_NAME . ' could not create TwingleProject: ' . @@ -245,13 +245,29 @@ function civicrm_api3_twingle_project_Sync(array $params): array { } // Return results - if ($errors_occurred > 0) { - $errorMessage = ($errors_occurred > 1) - ? "$errors_occurred synchronisation processes resulted with an error" + if (sizeof($errors) > 0) { + + $errorCount = sizeof($errors); + $errorMessage = ($errorCount > 1) + ? "$errorCount synchronisation processes resulted with an error" : "1 synchronisation process resulted with an error"; + + // Log errors + Civi::log()->error(E::LONG_NAME . ': ' . $errorMessage, $errors); + + // Return API Error + $errorMessage = $errorMessage . ': ['; + foreach ($errors as $key => $value) { + $errorMessage = + $errorMessage . + " ['project_id' => '$key', 'error_message' => '$value'],"; + } + $errorMessage = + substr($errorMessage, 0, strlen($errorMessage) - 1) . ' ]'; + return civicrm_api3_create_error( $errorMessage, - $returnValues + $errors ); } else { @@ -286,8 +302,10 @@ function _updateProjectLocally(array $project_from_twingle, // If this is a test, do not make db changes if (array_key_exists('is_test', $params) && $params['is_test']) { + $response[$project->getId()] = + $project->getResponse('TwingleProject ready to update'); return civicrm_api3_create_success( - $project->getResponse('TwingleProject ready to update'), + $response, $params, 'TwingleProject', 'Sync' @@ -295,7 +313,8 @@ function _updateProjectLocally(array $project_from_twingle, } // ... else, update local TwingleProject campaign $project->create(TRUE); - $response = $project->getResponse('TwingleProject updated successfully'); + $response[$project->getId()] = + $project->getResponse('TwingleProject updated successfully'); return civicrm_api3_create_success( $response, $params, @@ -333,8 +352,10 @@ function _pushProjectToTwingle(TwingleProject $project, // If this is a test, do not make db changes if ($params['is_test']) { + $response[$project->getId] = + $project->getResponse('TwingleProject ready to push to Twingle'); return civicrm_api3_create_success( - $project->getResponse('TwingleProject ready to push to Twingle'), + $response, $params, 'TwingleProject', 'Sync' @@ -363,7 +384,8 @@ function _pushProjectToTwingle(TwingleProject $project, try { // Create updated campaign $project->create(TRUE); - $response = $project->getResponse('TwingleProject pushed to Twingle'); + $response[$project->getId()] = + $project->getResponse('TwingleProject pushed to Twingle'); return civicrm_api3_create_success( $response, $params, @@ -441,7 +463,8 @@ function _projectSync(TwingleProject $project, // If both versions are still synchronized else { - $response = $project->getResponse('TwingleProject up to date'); + $response[$project->getId()] = + $project->getResponse('TwingleProject up to date'); return civicrm_api3_create_success( $response, $params, From 34e2e77d83d39804cc070e5bfe6978d458529646 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Tue, 13 Apr 2021 01:05:57 +0200 Subject: [PATCH 06/12] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20implement=20validati?= =?UTF-8?q?on=20of=20TwingleProject=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/Campaign.php | 2 +- CRM/TwingleCampaign/BAO/TwingleApiCall.php | 197 +++++++------- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 2 +- CRM/TwingleCampaign/BAO/TwingleEvent.php | 2 +- CRM/TwingleCampaign/BAO/TwingleProject.php | 269 ++++++++++++++++++- api/v3/TwingleProject/Sync.php | 88 ++++--- twinglecampaign.php | 275 ++++++++++++++++---- 7 files changed, 652 insertions(+), 183 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/Campaign.php b/CRM/TwingleCampaign/BAO/Campaign.php index 593a358..316aa3f 100644 --- a/CRM/TwingleCampaign/BAO/Campaign.php +++ b/CRM/TwingleCampaign/BAO/Campaign.php @@ -33,7 +33,7 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { * @param array $values * @param int|null $id */ - protected function __construct(array $values, int $id = NULL) { + protected function __construct(array $values = [], int $id = NULL) { $this->id = $id; $tmpClassName = explode('_', get_class($this)); diff --git a/CRM/TwingleCampaign/BAO/TwingleApiCall.php b/CRM/TwingleCampaign/BAO/TwingleApiCall.php index 20d8c68..4ae2536 100644 --- a/CRM/TwingleCampaign/BAO/TwingleApiCall.php +++ b/CRM/TwingleCampaign/BAO/TwingleApiCall.php @@ -129,10 +129,14 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { */ public function pushProject(array $project): array { - $projectOptions = $project['project_options']; - unset($project['project_options']); - $paymentMethods = $project['payment_methods']; - unset($project['payment_methods']); + if (isset($project['project_options'])) { + $projectOptions = $project['project_options']; + unset($project['project_options']); + } + if (isset($project['payment_methods'])) { + $paymentMethods = $project['payment_methods']; + unset($project['payment_methods']); + } try { if (!isset($project['id'])) { @@ -153,32 +157,40 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } // Post project_options - $updatedProject['project_options'] = - $this->curlPost($url . '/options', $projectOptions); + if (isset($projectOptions)) { + $updatedProject['project_options'] = + $this->curlPost($url . '/options', $projectOptions); + } + else { + $updatedProject['project_options'] = $this->getProjectOptions($updatedProject['id']); + } // Post payment_methods - $this->curlPost($url . '/payment-methods', $paymentMethods); - $updatedProject['payment_methods'] = - $this->getProjectPaymentMethods($updatedProject['id']); - - // Set last update time - $updatedProject['last_update'] = max( - $updatedProject['last_update'], - $updatedProject['project_options']['last_update'], - $updatedProject['payment_methods']['updated_at'] - ); - unset($updatedProject['project_options']['last_update']); - unset($updatedProject['payment_methods']['updated_at']); - - return $updatedProject; - } catch (Exception $e) { - throw new Exception( - E::SHORT_NAME . 'Call to Twingle API failed: ' . - $e->getMessage() - ); - } + if (isset ($paymentMethods)) { + $this->curlPost($url . '/payment-methods', $paymentMethods); + } + $updatedProject['payment_methods'] = + $this->getProjectPaymentMethods($updatedProject['id']); + // Set last update time + $updatedProject['last_update'] = max( + $updatedProject['last_update'], + $updatedProject['project_options']['last_update'], + $updatedProject['payment_methods']['updated_at'] + ); + unset($updatedProject['project_options']['last_update']); + unset($updatedProject['payment_methods']['updated_at']); + + return $updatedProject; + } + catch + (Exception $e) { + throw new Exception( + E::SHORT_NAME . 'Call to Twingle API failed: ' . + $e->getMessage() + ); + } } @@ -194,48 +206,48 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { * @throws Exception */ public function getEvent(int $projectId, int $eventId = NULL): array { - $result = []; + $result = []; - // Construct url for curl - $url = empty($eventId) - ? $this->protocol . 'project' . $this->baseUrl . $projectId . '/event' - : $this->protocol . 'project' . $this->baseUrl . $projectId . '/event/' - . $eventId; + // Construct url for curl + $url = empty($eventId) + ? $this->protocol . 'project' . $this->baseUrl . $projectId . '/event' + : $this->protocol . 'project' . $this->baseUrl . $projectId . '/event/' + . $eventId; - $offset = 0; - $finished = FALSE; + $offset = 0; + $finished = FALSE; - // Get only as much results per call as configured in $this->limit - while (!$finished) { - $params = [ - 'orderby' => 'id', - 'direction' => 'desc', - 'limit' => $this->limit, - 'offset' => $offset, - 'image' => 'as-boolean', - 'public' => 0, - ]; - $response = $this->curlGet($url, $params); + // Get only as much results per call as configured in $this->limit + while (!$finished) { + $params = [ + 'orderby' => 'id', + 'direction' => 'desc', + 'limit' => $this->limit, + 'offset' => $offset, + 'image' => 'as-boolean', + 'public' => 0, + ]; + $response = $this->curlGet($url, $params); - // If no $eventId was given, expect one or more events. - // Store the events, increase the offset and ask again until there - // are no more events incoming. - if (!$eventId) { - $result = array_merge($result, $response['data']); - $offset = $offset + $this->limit; - $finished = count($response['data']) < $this->limit; - } - // If $eventId was given, expect only one event - else { - // If the response array contains 'message', the $eventId does not exist - if (!$response['message']) { - $result = $response; + // If no $eventId was given, expect one or more events. + // Store the events, increase the offset and ask again until there + // are no more events incoming. + if (!$eventId) { + $result = array_merge($result, $response['data']); + $offset = $offset + $this->limit; + $finished = count($response['data']) < $this->limit; + } + // If $eventId was given, expect only one event + else { + // If the response array contains 'message', the $eventId does not exist + if (!$response['message']) { + $result = $response; + } + $finished = TRUE; } - $finished = TRUE; } + return $result; } - return $result; - } /** * ## Get project embed data @@ -248,47 +260,49 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { */ public function getProjectEmbedData($projectId): array { - $result = $this->getProject($projectId); + $result = $this->getProject($projectId); - if ($result['embed']) { - // Include counter url into embed data - $result['embed']['counter'] = $result['counter-url']['url']; + if ($result['embed']) { + // Include counter url into embed data + $result['embed']['counter'] = $result['counter-url']['url']; - return $result['embed']; + return $result['embed']; + } + else { + throw new Exception( + "Could not get embed data for project $projectId." + ); + } } - else { - throw new Exception( - "Could not get embed data for project $projectId." - ); - } - } /** * ## Get project options * Gets all project options from the Twingle API + * * @param $projectId * * @return array * @throws \Exception */ public function getProjectOptions($projectId): array { - $url = $this->protocol . 'project' . $this->baseUrl . $projectId . '/options'; - return $this->curlGet($url); - } + $url = $this->protocol . 'project' . $this->baseUrl . $projectId . '/options'; + return $this->curlGet($url); + } /** * ## Get project payment methods * Gets all project payment methods from the Twingle API + * * @param $projectId * * @return array * @throws \Exception */ public function getProjectPaymentMethods($projectId): array { - $url = $this->protocol . 'project' . $this->baseUrl . $projectId - . '/payment-methods'; - return $this->curlGet($url); - } + $url = $this->protocol . 'project' . $this->baseUrl . $projectId + . '/payment-methods'; + return $this->curlGet($url); + } /** @@ -301,9 +315,9 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { * @throws Exception */ public function deleteProject(int $projectId): bool { - $url = $this->protocol . 'project' . $this->baseUrl . $projectId; - return $this->curlDelete($url); - } + $url = $this->protocol . 'project' . $this->baseUrl . $projectId; + return $this->curlDelete($url); + } /** @@ -319,10 +333,10 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { * @throws Exception */ public function deleteEvent(int $projectId, int $eventId): bool { - $url = $this->protocol . 'project' . $this->baseUrl . $projectId . - '/event/' . $eventId; - return $this->curlDelete($url); - } + $url = $this->protocol . 'project' . $this->baseUrl . $projectId . + '/event/' . $eventId; + return $this->curlDelete($url); + } /** @@ -360,7 +374,8 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } if ($curl_status_code == 404) { throw new Exception('http status code 404 (not found)'); - } elseif ($curl_status_code == 500) { + } + elseif ($curl_status_code == 500) { throw new Exception('https status code 500 (internal error)'); } return $response; @@ -402,10 +417,11 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } if ($curl_status_code == 404) { throw new Exception('http status code 404 (not found)'); - } elseif ($curl_status_code == 500) { + } + elseif ($curl_status_code == 500) { throw new Exception('https status code 500 (internal error)'); } - if (sizeof($response) == 1 && isset($response['message'])){ + if (sizeof($response) == 1 && isset($response['message'])) { throw new Exception($response['message']); } return $response; @@ -448,7 +464,8 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } if ($curl_status_code == 404) { throw new Exception('http status code 404 (not found)'); - } elseif ($curl_status_code == 500) { + } + elseif ($curl_status_code == 500) { throw new Exception('https status code 500 (internal error)'); } return ($curl_status_code == 200); diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index f7e8521..58433ed 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -26,7 +26,7 @@ class CRM_TwingleCampaign_BAO_TwingleCampaign { * * @throws \CiviCRM_API3_Exception */ - public function __construct(array $values, int $id = NULL) { + public function __construct(array $values = [], int $id = NULL) { $this->prefix = 'twingle_campaign_'; $this->id = $id ?? NULL; diff --git a/CRM/TwingleCampaign/BAO/TwingleEvent.php b/CRM/TwingleCampaign/BAO/TwingleEvent.php index f1c4473..19de97b 100644 --- a/CRM/TwingleCampaign/BAO/TwingleEvent.php +++ b/CRM/TwingleCampaign/BAO/TwingleEvent.php @@ -19,7 +19,7 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { * * @throws \Exception */ - public function __construct(array $event, int $id = NULL) { + public function __construct(array $event = [], int $id = NULL) { parent::__construct($event, $id); $this->prefix = 'twingle_event_'; diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index 4035ecc..7e24868 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -40,7 +40,7 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * @param int|null $id * CiviCRM Campaign id */ - public function __construct(array $values, int $id = NULL) { + public function __construct(array $values = [], int $id = NULL) { parent::__construct($values, $id); $this->prefix = 'twingle_project_'; @@ -85,7 +85,9 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * ## Int to bool * Changes all project values that are defined as CiviCRM 'Boolean' types * from strings to booleans. + * * @param array $values + * * @throws \Exception */ private function intToBool(array &$values) { @@ -104,7 +106,10 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { } elseif (in_array($key, $boolArrays)) { foreach ($values[$key] as $_key => $_value) { - if (is_numeric($_value) && $_value < 2 || empty($_value)) { + if (is_bool($_value)) { + // nothing to do here + } + elseif (is_numeric($_value) && $_value < 2 || empty($_value)) { $values[$key][$_key] = (bool) $_value; } else { @@ -122,7 +127,9 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * ## Int to bool * Changes all project values that are strings but originally came as integers * back to integers. + * * @param array $values + * * @throws \Exception */ private function strToInt(array &$values) { @@ -214,8 +221,33 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { } /** - * ## Clone this TwingleProject + * ## Complement campaign values + * Complement existing campaign values with new ones * + * @param array $arrayToComplement + * + * @overrides CRM_TwingleCampaign_BAO_Campaign + */ + public function complement(array $arrayToComplement) { + + // Set all contact fields to false + if ( + isset($arrayToComplement['values']['project_options']['contact_fields']) + ) { + foreach ( + $arrayToComplement['values']['project_options']['contact_fields'] + as $key => $value + ) { + $arrayToComplement['values']['project_options']['contact_fields'][$key] + = FALSE; + } + } + + parent::complement($arrayToComplement); + } + + /** + * ## Clone this TwingleProject * This method removes the id and the identifier from this instance and in * the next step it pushes the clone as a new project with the same values to * Twingle. @@ -223,11 +255,163 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * @throws \Exception */ public function clone() { - $this->values['id'] = 0; - $this->values['identifier'] = 0; + $this->values['id'] = ''; + $this->values['identifier'] = ''; $this->create(); // this will also trigger the postSave hook } + /** + * ## Validate + * Validates project values and returns an array containing the result and + * another array with eventual error messages. + * + * @return array ['valid' => bool, 'messages' => array] + */ + public function validate(): array { + $valid = TRUE; + $messages = []; + + // Validate email address + if ( + !filter_var( + $this->values['project_options']['bcc_email_address'], + FILTER_VALIDATE_EMAIL + ) + && !empty($this->values['project_options']['bcc_email_address']) + ) { + $valid = FALSE; + $messages[] = E::ts("BCC email invalid"); + } + + // Validate hexadecimal color fields + $colorFields = + [ + 'design_background_color', + 'design_primary_color', + 'design_font_color', + ]; + foreach ($colorFields as $colorField) { + if ( + !empty($this->values['project_options'][$colorField]) && + ( + !( + ctype_xdigit($this->values['project_options'][$colorField]) || + is_integer($this->values['project_options'][$colorField]) + ) || + strlen((string) $this->values['project_options'][$colorField]) > 6 + ) + ) { + $valid = FALSE; + $messages[] = + E::ts("Invalid hexadecimal value in color field: %1", + [1 => $colorField]); + } + } + + // Check if donation values are integers and if proposed donation value + // lies between max and min values + if ( + // Is integer and >= 0 or empty + ( + empty($this->values['project_options']['donation_value_default']) || + ( + is_integer($this->values['project_options']['donation_value_default']) || + ctype_digit($this->values['project_options']['donation_value_default']) + ) && ( + $this->values['project_options']['donation_value_default'] >= 0 + ) + ) && ( + empty($this->values['project_options']['donation_value_min']) || + ( + is_integer($this->values['project_options']['donation_value_min']) || + ctype_digit($this->values['project_options']['donation_value_min']) + ) && ( + $this->values['project_options']['donation_value_max'] >= 0 + ) + ) && ( + empty($this->values['project_options']['donation_value_max']) || + ( + is_integer($this->values['project_options']['donation_value_max']) || + ctype_digit($this->values['project_options']['donation_value_max']) + ) && ( + $this->values['project_options']['donation_value_max'] >= 0 + ) + ) + ) { + if ( + // all empty + empty($this->values['project_options']['donation_value_default']) && + empty($this->values['project_options']['donation_value_min']) && + empty($this->values['project_options']['donation_value_max']) + ) { + // nothing to validate + } + elseif ( + // Max empty, min not empty + (!empty($this->values['project_options']['donation_value_min']) && + empty($this->values['project_options']['donation_value_max'])) || + // Max empty, default not empty + (!empty($this->values['project_options']['donation_value_default']) && + empty($this->values['project_options']['donation_value_max'])) + ) { + $valid = FALSE; + $messages[] = + E::ts("Missing maximum donation value"); + } + else { + if ( + // Min >= Max + $this->values['project_options']['donation_value_min'] >= + $this->values['project_options']['donation_value_max'] + ) { + $valid = FALSE; + $messages[] = + E::ts("Maximum donation value must be higher than the minimum"); + } + elseif ( + // Default < min or default > max + $this->values['project_options']['donation_value_default'] < + $this->values['project_options']['donation_value_min'] || + $this->values['project_options']['donation_value_default'] > + $this->values['project_options']['donation_value_max'] + ) { + $valid = FALSE; + $messages[] = + E::ts("Default donation value must lie in between maximum and minimum values"); + } + } + } + else { + $valid = FALSE; + $messages[] = + E::ts("Donation values (Min, Max, Default) must be positive integers"); + } + + // Validate sharing url + $urlFields = + [ + 'custom_css', + 'share_url', + ]; + + foreach ($urlFields as $urlField) { + if (!empty($this->values['project_options'][$urlField])) { + if ( + !filter_var( + $this->values['project_options'][$urlField], + FILTER_VALIDATE_URL + ) || empty($this->values['project_options'][$urlField]) + ) { + $valid = FALSE; + $messages[] = + E::ts("Invalid URL: %1", [1 => $urlField]); + } + } + } + + return ['valid' => $valid, 'messages' => $messages]; + } + /** * ## Translate values between CiviCRM Campaigns and Twingle formats @@ -246,7 +430,8 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * * @throws Exception */ - public static function formatValues(array &$values, string $direction) { + public + static function formatValues(array &$values, string $direction) { if ($direction == self::IN) { @@ -467,7 +652,8 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * @return array * */ - public function getResponse(string $status = NULL): array { + public + function getResponse(string $status = NULL): array { $project_type = empty($this->values['type']) ? 'default' : $this->values['type']; $response = [ @@ -489,7 +675,8 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * * @return int|string|null */ - public function lastUpdate() { + public + function lastUpdate(): ?int { return self::getTimestamp($this->values['last_update']); } @@ -500,8 +687,72 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * * @return int */ - public function getProjectId(): int { + public + function getProjectId(): int { return (int) $this->values['id']; } + /** + * ## Get the payment methods array of this project + * + * @return array + */ + public function getValues(): array { + if (isset($this->values)) { + return $this->values; + } + else { + return []; + } + } + + /** + * ## Get the project options array of this project + * + * @return array + */ + public function getOptions(): array { + if (isset($this->values['project_options'])) { + return $this->values['project_options']; + } + else { + return []; + } + } + + /** + * ## Get the payment methods array of this project + * + * @return array + */ + public function getPaymentMethods(): array { + if (isset($this->values['payment_methods'])) { + return $this->values['payment_methods']; + } + else { + return []; + } + } + + /** + * ## Get the payment methods array of this project + */ + public function deleteValues(): void { + unset ($this->values); + } + + /** + * ## Get the project options array of this project + */ + public function deleteOptions(): void { + unset($this->values['project_options']); + } + + /** + * ## Get the payment methods array of this project + */ + public function deletePaymentMethods(): void { + unset($this->values['payment_methods']); + } + } diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index aae2b47..5792a5b 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -131,6 +131,20 @@ function civicrm_api3_twingle_project_Sync(array $params): array { // instantiate project $project = new TwingleProject($result, $id); + // Send project information to Tingle and update project with the + // answer + $projectOptions = $project->getOptions(); + $project->deleteOptions(); + $paymentMethods = $project->getPaymentMethods(); + $project->deletePaymentMethods(); + $projectFromTwingle = $twingleApi->pushProject($project->export()); + $project = new TwingleProject($projectFromTwingle, $project->getId()); + $projectValues = $project->getValues(); + $projectValues['project_options'] = $projectOptions; + $projectValues['payment_methods'] = $paymentMethods; + $project->update($projectValues); + $project->complement($projectFromTwingle); + // Push project to Twingle return _pushProjectToTwingle($project, $twingleApi, $params); } @@ -342,17 +356,19 @@ function _updateProjectLocally(array $project_from_twingle, * @param \CRM_TwingleCampaign_BAO_TwingleProject $project * @param \CRM_TwingleCampaign_BAO_TwingleApiCall $twingleApi * @param array $params + * @param bool $update Update project after push? * * @return array * @throws \CiviCRM_API3_Exception */ function _pushProjectToTwingle(TwingleProject $project, TwingleApiCall $twingleApi, - array $params): array { + array $params = [], + bool $update = TRUE): array { // If this is a test, do not make db changes - if ($params['is_test']) { - $response[$project->getId] = + if (isset($params['is_test']) && $params['is_test']) { + $response[$project->getId()] = $project->getResponse('TwingleProject ready to push to Twingle'); return civicrm_api3_create_success( $response, @@ -379,43 +395,55 @@ function _pushProjectToTwingle(TwingleProject $project, } // Update local campaign with data returning from Twingle - if ($result) { - $project->update($result); - try { - // Create updated campaign - $project->create(TRUE); - $response[$project->getId()] = - $project->getResponse('TwingleProject pushed to Twingle'); - return civicrm_api3_create_success( - $response, - $params, - 'TwingleProject', - 'Sync' - ); - } catch (Exception $e) { + if ($update) { + if ($result) { + $project->update($result); + try { + // Create updated campaign + $project->create(TRUE); + $response[$project->getId()] = + $project->getResponse('TwingleProject pushed to Twingle'); + return civicrm_api3_create_success( + $response, + $params, + 'TwingleProject', + 'Sync' + ); + } catch (Exception $e) { + Civi::log()->error( + E::LONG_NAME . + ' pushed TwingleProject to Twingle but local update failed: ' . + $e->getMessage(), + $project->getResponse() + ); + return civicrm_api3_create_error( + 'TwingleProject was pushed to Twingle but local update failed: ' . + $e->getMessage(), + $project->getResponse() + ); + } + } + // If the curl fails, the $result may be empty + else { Civi::log()->error( E::LONG_NAME . - ' pushed TwingleProject to Twingle but local update failed: ' . - $e->getMessage(), + ' could not push TwingleProject campaign', $project->getResponse() ); return civicrm_api3_create_error( - 'TwingleProject was pushed to Twingle but local update failed: ' . - $e->getMessage(), + "Could not push TwingleProject campaign", $project->getResponse() ); } } - // If the curl fails, the $result may be empty else { - Civi::log()->error( - E::LONG_NAME . - ' could not push TwingleProject campaign', - $project->getResponse() - ); - return civicrm_api3_create_error( - "Could not push TwingleProject campaign", - $project->getResponse() + $response[$project->getId()] = + $project->getResponse('TwingleProject pushed to Twingle'); + return civicrm_api3_create_success( + $response, + $params, + 'TwingleProject', + 'Sync' ); } } diff --git a/twinglecampaign.php b/twinglecampaign.php index ef73167..e210c34 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -1,6 +1,8 @@ id, $dao->campaign_type_id] - ); + + if (_validateAndSendInput($dao->id, $dao->campaign_type_id)) { + + CRM_Core_Transaction::addCallback( + CRM_Core_Transaction::PHASE_POST_COMMIT, + 'twinglecampaign_postSave_campaign_update_callback', + [$dao->id, $dao->campaign_type_id] + ); + } } + // If the transaction is already finished, call the function directly else { - twinglecampaign_postSave_campaign_callback($dao->id, $dao->campaign_type_id); + twinglecampaign_postSave_campaign_update_callback($dao->id, $dao->campaign_type_id); } } @@ -89,21 +97,13 @@ function twinglecampaign_civicrm_postSave_civicrm_campaign($dao) { * * @throws \CiviCRM_API3_Exception */ -function twinglecampaign_postSave_campaign_callback ( +function twinglecampaign_postSave_campaign_update_callback( int $campaign_id, int $campaign_type_id ) { - // Get campaign type id for TwingleProject - $twingle_project_campaign_type_id = - ExtensionCache::getInstance() - ->getCampaigns()['campaign_types']['twingle_project']['id']; - - // Get campaign type id for TwingleCampaign - $twingle_campaign_campaign_type_id = - ExtensionCache::getInstance() - ->getCampaigns()['campaign_types']['twingle_campaign']['id']; - + $twingle_project_campaign_type_id = _get_campaign_type_id_twingle_project(); + $twingle_campaign_campaign_type_id = _get_campaign_type_id_twingle_campaign(); // If $campaign_type_id is a TwingleProject or TwingleCampaign campaign, // synchronize it @@ -121,15 +121,14 @@ function twinglecampaign_postSave_campaign_callback ( } if (isset($_POST['action'])) { - if ($_POST['action'] == 'clone') { + if ($_POST['action'] == 'clone' && $entity == 'TwingleProject') { unset($_POST['action']); - $result = civicrm_api3($entity, 'getsingle', + $result = civicrm_api3('TwingleProject', 'getsingle', ['id' => $campaign_id] - )['values'][$campaign_id]; - $className = 'CRM_TwingleCampaign_BAO_' . $entity; + ); $id = $result['id']; unset($result['id']); - $project = new $className($result, $id); + $project = new TwingleProject($result, $id); try { $project->clone(); } catch (Exception $e) { @@ -137,58 +136,232 @@ function twinglecampaign_postSave_campaign_callback ( E::LONG_NAME . ' could not clone ' . $entity . ': ' . $e->getMessage() ); - CRM_Utils_System::setUFMessage($entity . ' could not get cloned.'); - } - } - elseif ($entity == 'TwingleProject') { - try { - civicrm_api3('TwingleProject', 'sync', ['id' => $campaign_id]); - CRM_Utils_System::setUFMessage('TwingleProject was saved.'); - } catch (CiviCRM_API3_Exception $e) { - Civi::log()->error( - 'twinglecampaign_postSave_callback ' . $e->getMessage() - ); - } - } - else { - try { - civicrm_api3('TwingleCampaign', 'create', ['id' => $campaign_id]); - CRM_Utils_System::setUFMessage('TwingleCampaign was saved.'); - } catch (CiviCRM_API3_Exception $e) { - Civi::log()->error( - 'twinglecampaign_postSave_callback ' . $e->getMessage() + CRM_Core_Session::setStatus( + $e->getMessage(), + E::ts("Campaign cloning failed"), + error, + [unique => TRUE] ); } } } + + // If a TwingleProject is getting saved elseif ($entity == 'TwingleProject') { - // Also synchronize all child TwingleCampaign campaigns + + // Synchronize all child TwingleCampaign campaigns try { - civicrm_api3('TwingleCampaign', 'sync', ['project_id' => $campaign_id]); + civicrm_api3( + 'TwingleCampaign', + 'sync', + ['parent_id' => $campaign_id]); + } catch (CiviCRM_API3_Exception $e) { + CRM_Core_Session::setStatus( + $e->getMessage(), + E::ts("TwingleCampaign update failed"), + error, [unique => TRUE] + ); + Civi::log()->error( + E::SHORT_NAME . + ' Update of TwingleCampaigns failed: ' . $e->getMessage() + ); + } + } + else { + try { + civicrm_api3('TwingleCampaign', 'create', + ['id' => $campaign_id, 'parent_id' => $_POST['parent_id']]); + CRM_Utils_System::setUFMessage(E::ts('TwingleCampaign was saved.')); } catch (CiviCRM_API3_Exception $e) { Civi::log()->error( 'twinglecampaign_postSave_callback ' . $e->getMessage() ); } - try { - civicrm_api3('TwingleProject', 'sync', ['id' => $campaign_id]); - CRM_Utils_System::setUFMessage('TwingleProject was saved.'); + } + } +} function _get_campaign_type_id_twingle_project() { return ExtensionCache::getInstance() - ->getCampaignIds()['campaign_types']['twingle_project']['id']; + ->getCampaignIds()['campaign_types']['twingle_project']['id']; } function _get_campaign_type_id_twingle_campaign() { return ExtensionCache::getInstance() - ->getCampaignIds()['campaign_types']['twingle_campaign']['id']; + ->getCampaignIds()['campaign_types']['twingle_campaign']['id']; } - 'twinglecampaign_postSave_callback ' . $e->getMessage() - ); +/** + * Callback to sync a project after its creation. + * @param int $campaign_id + */ +function twinglecampaign_postSave_project_create_callback( + int $campaign_id +) { + try { + civicrm_api3( + 'TwingleProject', + 'sync', + ['id' => $campaign_id]); + } catch (Exception $e) { + CRM_Core_Session::setStatus( + $e->getMessage(), + E::ts("TwingleProject creation failed"), + error, [unique => TRUE] + ); + Civi::log()->error( + E::SHORT_NAME . + ' Update of TwingleProject creation failed: ' . $e->getMessage() + ); + } +} + +/** + * First validate and then sends the input of this transaction to Twinge. + * If the call to the Twingle API succeeded, this function returns TRUE; + * + * @param $id + * @param $campaign_type_id + * + * @return bool + * @throws \CiviCRM_API3_Exception + */ +function _validateAndSendInput($id, $campaign_type_id): bool { + + // Set callback for cloning + if (isset($_POST['action'])) { + CRM_Core_Transaction::addCallback( + CRM_Core_Transaction::PHASE_POST_COMMIT, + 'twinglecampaign_postSave_campaign_update_callback', + [$id, $campaign_type_id] + ); + return FALSE; + } + + if ($campaign_type_id == _get_campaign_type_id_twingle_project()) { + + // Instantiate project + $project = new TwingleProject(); + + // Translate custom fields from $_POST + $customFields = []; + $customFieldsKeys = preg_grep('/^custom_/', array_keys($_POST)); + foreach ($customFieldsKeys as $key) { + $customFields[preg_replace('/_-?\d*$/', '', $key)] = + $_POST[$key]; + } + $project->translateCustomFields( + $customFields, + TwingleProject::OUT + ); + TwingleProject::formatValues($customFields, TwingleProject::OUT); + + // Update project + $project->update($customFields); + + // Validate project values + $validation = $project->validate(); + + // If the input is valid, send it to Twingle + if ($validation['valid']) { + + // Try to retrieve twingleApi from cache or create a new + $twingleApi = Civi::cache()->get('twinglecampaign_twingle_api'); + if (NULL === $twingleApi) { + try { + $twingleApi = + new TwingleApiCall(Civi::settings()->get('twingle_api_key')); + } catch (Exception $e) { + + // Roll back transaction if input validation failed + CRM_Core_Transaction::rollbackIfFalse(FALSE); + + CRM_Core_Session::setStatus( + $e->getMessage(), + E::ts("Could not retrieve Twingle API key"), + error, + [unique => TRUE] + ); + Civi::log()->error( + E::SHORT_NAME . + ' Could not retrieve Twingle API key: ' . $e->getMessage() + ); + } + Civi::cache('long')->set('twinglecampaign_twingle_api', $twingleApi); } + + try { + // Complement project values with values from Twingle if it has a + // project_id + if ($project->getProjectId()) { + $project_from_twingle = $twingleApi->getProject($project->getProjectId()); + $project->complement($project_from_twingle); + } + // If this campaign is just about to become created, add a callback to + // sync it after the transaction has finished + else { + CRM_Core_Transaction::addCallback( + CRM_Core_Transaction::PHASE_POST_COMMIT, + 'twinglecampaign_postSave_project_create_callback', [$id] + ); + return FALSE; + } + + // Push project + require E::path() . '/api/v3/TwingleProject/Sync.php'; + $result = _pushProjectToTwingle($project, $twingleApi, [], FALSE); + if ($result['is_error'] != 0) { + throw new \CiviCRM_API3_Exception($result['error_message']); + } + } catch (Exception $e) { + + // Roll back transaction if input validation failed + CRM_Core_Transaction::rollbackIfFalse(FALSE); + + // Display and log error message + CRM_Core_Session::setStatus( + $e->getMessage(), + E::ts("TwingleProject synchronization failed: %1", + [1 => $e->getMessage()]), + error, + [unique => TRUE] + ); + Civi::log()->error( + E::SHORT_NAME . + ' TwingleProject synchronization failed: ' . $e->getMessage() + ); + // Push failed + return FALSE; + } + // Push succeeded + return TRUE; + } + // Display error message if validation failed + else { + + // Roll back transaction if input validation failed + CRM_Core_Transaction::rollbackIfFalse(FALSE); + + // Build error message + $errorMessage = '
    '; + foreach ($validation['messages'] as $message) { + $errorMessage = $errorMessage . '
  • ' . $message . '
  • '; + } + $errorMessage = $errorMessage . '
'; + + CRM_Core_Session::setStatus( + $errorMessage, + E::ts("Input validation failed"), + error, + [unique => TRUE] + ); + // Validation failed + return FALSE; } } + + // TwingleCampaigns always return TRUE; + return TRUE; } From 7b30a75014699215bf7ea3a365c26d41b2e3d808 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Tue, 13 Apr 2021 00:19:15 +0200 Subject: [PATCH 07/12] =?UTF-8?q?=F0=9F=87=A9=F0=9F=87=AA=20add=20German?= =?UTF-8?q?=20translation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/CustomField.php | 6 +- CRM/TwingleCampaign/BAO/CustomGroup.php | 6 +- CRM/TwingleCampaign/BAO/OptionValue.php | 7 +- l10n/de_DE/LC_MESSAGES/twinglecampaign.mo | Bin 7520 -> 20445 bytes l10n/de_DE/LC_MESSAGES/twinglecampaign.po | 779 +++++++++++++++++++++- l10n/pot/twinglecampaign.pot | 720 +++++++++++++++++++- 6 files changed, 1475 insertions(+), 43 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index 2145b67..b28642f 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -108,16 +108,14 @@ class CRM_TwingleCampaign_BAO_CustomField { ->error("$this->extensionName could not create new custom field \"$this->name\" for group \"$this->custom_group_id\": $this->result['error_message']"); - CRM_Utils_System::setUFMessage("Creation of custom field '$this->name' - failed. Find more information in the logs."); + CRM_Utils_System::setUFMessage(E::ts('Creation of custom field \'%1\' failed. Find more information in the logs.', [1 => $this->name])); } // If there is not enough information: log simple error message else { Civi::log() ->error("$this->extensionName could not create new custom field: $this->result['error_message']"); - CRM_Utils_System::setUFMessage("Creation of custom field - failed. Find more information in the logs."); + CRM_Utils_System::setUFMessage(E::ts("Creation of custom field failed. Find more information in the logs.")); } } } diff --git a/CRM/TwingleCampaign/BAO/CustomGroup.php b/CRM/TwingleCampaign/BAO/CustomGroup.php index 20fa1e5..134b27d 100644 --- a/CRM/TwingleCampaign/BAO/CustomGroup.php +++ b/CRM/TwingleCampaign/BAO/CustomGroup.php @@ -77,14 +77,12 @@ class CRM_TwingleCampaign_BAO_CustomGroup { Civi::log()->error("$this->extensionName could not create new custom group for \"$this->name\": $this->results['error_message']" ); - CRM_Utils_System::setUFMessage("Creation of custom group '$this->name' - failed. Find more information in the logs."); + CRM_Utils_System::setUFMessage(E::ts('Creation of custom group \'%1\' failed. Find more information in the logs.', [1 => $this->name])); } else { Civi::log()->error("$this->extensionName could not create new custom group: $this->results['error_message']"); - CRM_Utils_System::setUFMessage("Creation of custom group - failed. Find more information in the logs."); + CRM_Utils_System::setUFMessage(E::ts('Creation of custom group failed. Find more information in the logs.')); } } diff --git a/CRM/TwingleCampaign/BAO/OptionValue.php b/CRM/TwingleCampaign/BAO/OptionValue.php index e5144d3..38251f7 100644 --- a/CRM/TwingleCampaign/BAO/OptionValue.php +++ b/CRM/TwingleCampaign/BAO/OptionValue.php @@ -144,10 +144,9 @@ class CRM_TwingleCampaign_BAO_OptionValue { if (!$name) { $result = []; - // Get json file with all custom fields for this extension - $json_file = file_get_contents(E::path() . - '/CRM/TwingleCampaign/resources/option_values.json'); - $option_values = json_decode($json_file, TRUE); + // Get all custom fields for this extension from option_values.php + $option_values = + include(E::path() . '/CRM/TwingleCampaign/resources/option_values.php'); // Log an error and throw an exception if the file cannot get read if (!$option_values) { diff --git a/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo b/l10n/de_DE/LC_MESSAGES/twinglecampaign.mo index f491d04cbd9ddea0d621c940e3ddfb9f420184fa..e4a39ee1fe73b329e902527919b8bfda35ef13d4 100644 GIT binary patch literal 20445 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 diff --git a/l10n/de_DE/LC_MESSAGES/twinglecampaign.po b/l10n/de_DE/LC_MESSAGES/twinglecampaign.po index 086ae7b..7bfae67 100644 --- a/l10n/de_DE/LC_MESSAGES/twinglecampaign.po +++ b/l10n/de_DE/LC_MESSAGES/twinglecampaign.po @@ -12,6 +12,48 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Language: de_DE\n" +#: CRM/TwingleCampaign/BAO/CustomField.php +msgid "" +"Creation of custom field '%1' failed. Find more information in the logs." +msgstr "" +"Erstellung von Custom Field '%1' fehlgeschlagen. Mehr Informationen in den " +"Logs." + +#: CRM/TwingleCampaign/BAO/CustomField.php +msgid "Creation of custom field failed. Find more information in the logs." +msgstr "" +"Erstellung von Custom Field '%1' fehlgeschlagen. Mehr Informationen in den " +"Logs." + +#: CRM/TwingleCampaign/BAO/CustomField.php +msgid "" +"Creation of custom field '%1' failed, because a custom field with that name " +"already exists. Find more information in the logs." +msgstr "" +"Erstellung der Custom Field '%1' fehlgeschlagen, weil bereits eine Custom " +"Field mit selbem Namen existiert. Mehr Informationen in den Logs." + +#: CRM/TwingleCampaign/BAO/CustomGroup.php +msgid "" +"Creation of custom group '%1' failed. Find more information in the logs." +msgstr "" +"Erstellung von Custom Field '%1' fehlgeschlagen. Mehr Informationen in den " +"Logs." + +#: CRM/TwingleCampaign/BAO/CustomGroup.php +msgid "Creation of custom group failed. Find more information in the logs." +msgstr "" +"Erstellung von Custom Field '%1' fehlgeschlagen. Mehr Informationen in den " +"Logs." + +#: CRM/TwingleCampaign/BAO/CustomGroup.php +msgid "" +"Creation of custom group '%1' failed, because a custom group with that name " +"already exists. Find more information in the logs." +msgstr "" +"Erstellung der Custom Group '%1' fehlgeschlagen, weil bereits eine Custom " +"Group mit selbem Namen existiert. Mehr Informationen in den Logs." + #: CRM/TwingleCampaign/BAO/TwingleCampaign.php msgid "" "Could not determine parent TwingleProject URL. This URL is needed to create " @@ -36,6 +78,37 @@ msgstr "" msgid "No parent TwingleProject found" msgstr "Kein übergeordnetes TwingleProjekt gefunden" +#: CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "BCC email invalid" +msgstr "BCC-Email-Adresse ungültig" + +#: CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Invalid hexadecimal value in color field: %1" +msgstr "Ungültige Hexadezimalzahl in Farbfeld: %1" + +#: CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Missing maximum donation value" +msgstr "Maximale Spendenhöhe fehlt" + +#: CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Maximum donation value must be higher than the minimum" +msgstr "Die maximale Spendenhöhe muss höher als die minimale sein" + +#: CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Default donation value must lie in between maximum and minimum values" +msgstr "" +"Die voreingestellte Spendenhöhe muss zwischen Minimum und Maximum liegen" + +#: CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Donation values (Min, Max, Default) must be positive integers" +msgstr "" +"Die minimale, maximale und die voreingestellte Spendenhöhe müssen positive " +"Ganzzahlen sein" + +#: CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Invalid URL: %1" +msgstr "Ungültige URL: %1" + #: CRM/TwingleCampaign/Form/Settings.php api/v3/TwingleEvent/Delete.php #: api/v3/TwingleEvent/Sync.php api/v3/TwingleProject/Delete.php #: api/v3/TwingleProject/Sync.php api/v3/TwingleSync/Sync.php @@ -109,6 +182,664 @@ msgstr "" msgid "Could not disable scheduled job \"TwingleSync\"." msgstr "Geplante Aufgabe \"TwingleSync\" konnte nicht deaktiviert werden." +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Information" +msgstr "Twingle Informationen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Settings" +msgstr "Twingle Einstellungen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Payment Methods" +msgstr "Twingle Zahlungsarten" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Embed Codes" +msgstr "Twingle Embed Codes" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Event Information" +msgstr "Twingle Event Informationen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Campaign Information" +msgstr "Twingle Campaign Informationen" + +#: CRM/TwingleCampaign/resources/campaigns.php api/v3/TwingleEvent/Delete.php +#: api/v3/TwingleEvent/Get.php api/v3/TwingleEvent/Getsingle.php +#: api/v3/TwingleEvent/Sync.php api/v3/TwingleProject/Create.php +#: api/v3/TwingleProject/Delete.php api/v3/TwingleProject/Get.php +#: api/v3/TwingleProject/Getsingle.php api/v3/TwingleProject/Sync.php +msgid "Twingle Project ID" +msgstr "Twingle Project ID" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Organisation ID" +msgstr "Organisations ID" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "identifier" +msgstr "Kennung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "An unique identifier for a project (auto generated)" +msgstr "Eindeutige Kennung eines Projekts (automatisch generiert)" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Type" +msgstr "Typ" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Default" +msgstr "Default" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Events" +msgstr "Events" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Membership" +msgstr "Mitgliedschaft" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "" +"Choose the project type. Allow users to create own events or to pay a " +"membership fee." +msgstr "" +"Wähle den Projekt-Typ: erlaube Benutzern ihre eigenen Spenden-Events " +"anzulegen oder eine Mitgliedschaft zu bezahlen." + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "allow more" +msgstr "Mehr zulassen" + +#: CRM/TwingleCampaign/resources/campaigns.php api/v3/TwingleProject/Create.php +#: api/v3/TwingleProject/Get.php api/v3/TwingleProject/Getsingle.php +msgid "Allow to donate more than is defined in the target" +msgstr "Zulassen, dass mehr gespendet wird als im Spendenziel angegeben ist" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "transaction type" +msgstr "Transaktionstyp" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "URL" +msgstr "URL" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Widget" +msgstr "Widget" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Form" +msgstr "Formular" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Widget Single" +msgstr "Einzelnes Widget" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Form Single" +msgstr "Formular Widget" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "All Events" +msgstr "Alle Events" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Event List" +msgstr "Event-Liste" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Counter" +msgstr "Zähler" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Page" +msgstr "Seite" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Confirmation Mail" +msgstr "Bestätigungsmail" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Send confirmation mail" +msgstr "Sende Bestätigungs-E-Mail" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Receipt" +msgstr "Spendenbescheinigung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Offer donation receipts" +msgstr "Biete Spendenbescheinigungen an" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Contact Data" +msgstr "Kontaktdaten" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Rhythm" +msgstr "Spendenrhythmus" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "yearly" +msgstr "jährlich" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "halfyearly" +msgstr "halbjährlich" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "quarterly" +msgstr "vierteljährlich" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "monthly" +msgstr "monatlich" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "one time" +msgstr "einmalig" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "" +"The selected options are available for selection in the donation widget." +msgstr "Die ausgewählten Optionen stehen im Spenden-Widget zur Verfügung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Default Rhythm" +msgstr "Standard Spendenrhythmus" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Which donation rhythm should be displayed as selected by default?" +msgstr "Welcher Spendenrhythmus soll standardmäßig ausgewählt sein?" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Newsletter Registration" +msgstr "Newsletter-Registrierung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Enable newsletter registration" +msgstr "Registrierung für Newsletter aktivieren" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Postinfo Registration" +msgstr "Postinfo-Registrierung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Enable post info registration" +msgstr "Registrierung für Postinfos aktivieren" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Background Color" +msgstr "Hintergrundfarbe" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Hex color code (e.g. ffffff for white)" +msgstr "Hex-Farbcode (z.B. ffffff für weiß)" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Primary Color" +msgstr "Primärfarbe" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Font Color" +msgstr "Schriftfarbe" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "BCC Email" +msgstr "BCC-E-Mail" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "" +"Email address used as bcc addresses for confirmation mail which is send to " +"an user" +msgstr "E-Mail-Adresse für den BBC beim Versenden der Bestätigungs-E-Mail" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Min" +msgstr "Spendenminimum" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Minimum donation value" +msgstr "Mindestspendenbetrag" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Max" +msgstr "Spendenmaximum" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Maximum donation value" +msgstr "Höchstspendenbetrag" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Default" +msgstr "Standardspendenhöhe" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Default donation value" +msgstr "Standardspendenbetrag" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Contact Fields" +msgstr "Kontaktfelder" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Salutation" +msgstr "Anrede" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "First name" +msgstr "Vorname" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Last name" +msgstr "Nachname" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Company" +msgstr "Firma" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Birthday" +msgstr "Geburtsdatum" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Street" +msgstr "Straße" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Postal Code" +msgstr "Postleitzahl" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "City" +msgstr "Stadt" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Country" +msgstr "Land" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Telephone" +msgstr "Telefon" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Fields to include in contact form" +msgstr "Felder für Kontaktformular" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Mandatory Contact Fields" +msgstr "Pflicht-Kontaktfelder" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Fields that must get filled in the contact form." +msgstr "Pflichtfelder für Kontaktformular" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Custom CSS" +msgstr "Benutzerdefiniertes CSS" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "URL to a custom CSS file that will be included in the frontend" +msgstr "" +"URL einer benutzerdefinierten CSS-Datei, die im Frontend eingebunden wird" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Share URL" +msgstr "Teilen-URL" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "URL for the sharing component on the last page and doi page" +msgstr "URL für Teilen-Elemente auf der letzten Seite und auf der DOI-Seite" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Contact Mandatory" +msgstr "Kontaktdaten sind Pflicht" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "If the contact data should be requested mandatory as second step" +msgstr "Die Kontaktdaten als Pflichtangaben im zweiten Schritt abfragen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Double Opt-In" +msgstr "Doppeltes Opt-In" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "" +"Enable Twingle's double opt-in (Do not enable, if you use CiviCRM's double " +"opt-in!)" +msgstr "" +"Tingles doppelten Opt-In aktivieren (Nicht aktivieren, wenn der doppelte Opt-" +"In von CiviCRM verwendet wird!)" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Force Donation Taget as Button" +msgstr "Spendenziel-Knopf erzwingen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Force showing the donation targets as buttons" +msgstr "Erzwingen der Anzeige der Spendenziele als Knöpfe" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Slider Icon" +msgstr "Icon für Schieberegler" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Heart" +msgstr "Herz" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Asterisk" +msgstr "Sternchen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Animal" +msgstr "Pfote" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Lifebelt" +msgstr "Rettungsring" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Angellist" +msgstr "Peace-Hand" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Handshake" +msgstr "Handschütteln" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Dollar" +msgstr "Dollar" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Menue" +msgstr "Menübalken" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Office" +msgstr "Büro" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Leaf" +msgstr "Blatt" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Cog" +msgstr "Zahnrad" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "SVG" +msgstr "SVG" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Euro" +msgstr "Euro" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Stats" +msgstr "Statistik" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Circle" +msgstr "Kreis" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Water drop outline" +msgstr "Wassertropfen (Umriss)" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Water drop" +msgstr "Wassertropfen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Gift" +msgstr "Geschenk" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Bee" +msgstr "Biene" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Flower" +msgstr "Blume" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Train" +msgstr "Zug" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "No Icon" +msgstr "Kein Icon" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Hidden Logo" +msgstr "Verstecktes Logo" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Hide the Logo on the project page" +msgstr "Verstecke das Logo auf der Projektseite" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Target Format" +msgstr "Spendenzielformat in Euro" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Format of the reached portion of the donation target" +msgstr "Format des Spendenstands" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Purpose as Textfield" +msgstr "Spendenzweck als Textfeld" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Let donors enter their own donation purpose" +msgstr "Erlaubt Spendern, ihre eigenen Spendenzwecke einzutragen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Activate CiviCRM Support" +msgstr "CiviCRM-Unterstützung aktivieren" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Activate support for Twingle Extension (de.systopia.twingle)" +msgstr "" +"Aktiviert die Unterstützung für die Twingle-Erweiterung (de.systopia.twingle)" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Show Step Index" +msgstr "Zeige Fortschrittsanzeige" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Show a step index during donation process" +msgstr "Fortschrittsanzeige beim Spendenprozess anzeigen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Languages" +msgstr "Sprachen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "German" +msgstr "Deutsch" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "English" +msgstr "Englisch" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "French" +msgstr "Französisch" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Spanish" +msgstr "Spanisch" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Buttons" +msgstr "Knöpfe" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "" +"Up to four buttons can be configured. If you leave the amount blank, the " +"button will not be displayed." +msgstr "" +"Bis zu vier Knöpfe können konfiguriert werden. Wenn Sie den Wert frei " +"lassen, wird der Knopf nicht angezeigt." + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Slider" +msgstr "Schieberegler" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Show a slider that allows the donor to choose the donation amount." +msgstr "" +"Zeige einen Schieberegler, der es dem Spender erlaubt, einen Betrag zu wählen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 1" +msgstr "Knopf 1" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 1" +msgstr "Betrag der auf Knopf 1 angezeigt wird" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 2" +msgstr "Knopf 2" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 2" +msgstr "Betrag der auf Knopf 2 angezeigt wird" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 3" +msgstr "Knopf 3" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 3" +msgstr "Betrag der auf Knopf 3 angezeigt wird" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 4" +msgstr "Knopf 4" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 4" +msgstr "Betrag der auf Knopf 4 angezeigt wird" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Newsletter Name Requested" +msgstr "Name für Newsletter abfragen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Must a donor give his name for newsletter sign-up?" +msgstr "" +"Muss ein Spender seinen Namen für die Newsletter-Registrierung angeben?" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Show List of Donations" +msgstr "Spendenliste anzeigen" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Display a list of public donations" +msgstr "Zeigt eine liste öffentlicher Spenden an" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Payment Methods" +msgstr "Zahlungsarten" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "PayPal" +msgstr "PayPal" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Banktransfer" +msgstr "Banküberweisung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Debit" +msgstr "Bankeinzug" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Sofortüberweisung" +msgstr "Sofortüberweisung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "" +"Chose which payment methods should be available. NOTE: You might have to " +"activate them first in the Twingle-Manager configuration." +msgstr "" +"Wählen Sie aus, welche Zahlungsarten verfügbar sein sollen. WICHTIG: Sie " +"müssen die Zahlungsarten eventuell erst im Twingle-Manager konfigurieren." + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Recurring Payment Methods" +msgstr "Wiederkehrende Zahlungsarten" + +#: CRM/TwingleCampaign/resources/campaigns.php api/v3/TwingleEvent/Delete.php +#: api/v3/TwingleEvent/Get.php api/v3/TwingleEvent/Getsingle.php +#: api/v3/TwingleEvent/Sync.php +msgid "Twingle Event ID" +msgstr "Twingle Event ID" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Identifier" +msgstr "Kennung" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Initiator" +msgstr "Initiator" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Initiator Email" +msgstr "Initiator E-Mail" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Is public" +msgstr "Ist öffentlich" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Deleted" +msgstr "Gelöscht" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Confirmed At" +msgstr "Bestätigt am" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Created At" +msgstr "Erstellt am" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Creation URL" +msgstr "Erstell-URL" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Internal URL" +msgstr "Interne URL" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "External URL" +msgstr "Externe URL" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Edit Internal URL" +msgstr "Interne Bearbeitungs-URL" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Edit External URL" +msgstr "Externe Bearbeitungs-URL" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "Parent TwingleProject ID" +msgstr "Twingle ID des Eltern-TwingleProject" + +#: CRM/TwingleCampaign/resources/campaigns.php +msgid "CID" +msgstr "CID" + #: api/v3/TwingleCampaign/Create.php api/v3/TwingleCampaign/Delete.php #: api/v3/TwingleCampaign/Get.php api/v3/TwingleCampaign/Getsingle.php #: api/v3/TwingleCampaign/Sync.php @@ -231,7 +962,7 @@ msgstr "Ist diese Kampagne aktiviert oder deaktiviert/abgesagt?" msgid "" "A unique identifier for a TwingleCampaign generated by a hashing its id + " "name" -msgstr "" +msgstr "Einmalige Kennung einer TwingleCampaign" #: api/v3/TwingleEvent/Delete.php api/v3/TwingleEvent/Get.php #: api/v3/TwingleEvent/Getsingle.php api/v3/TwingleEvent/Sync.php @@ -247,25 +978,12 @@ msgstr "Kampagnen ID" msgid "Unique Campaign ID" msgstr "Einzigartige Kampagnen ID" -#: api/v3/TwingleEvent/Delete.php api/v3/TwingleEvent/Get.php -#: api/v3/TwingleEvent/Getsingle.php api/v3/TwingleEvent/Sync.php -#: api/v3/TwingleProject/Create.php api/v3/TwingleProject/Delete.php -#: api/v3/TwingleProject/Get.php api/v3/TwingleProject/Getsingle.php -#: api/v3/TwingleProject/Sync.php -msgid "Twingle Project ID" -msgstr "Twingle Project ID" - #: api/v3/TwingleEvent/Delete.php api/v3/TwingleEvent/Sync.php #: api/v3/TwingleProject/Delete.php api/v3/TwingleProject/Get.php #: api/v3/TwingleProject/Getsingle.php api/v3/TwingleProject/Sync.php msgid "Twingle ID for this project" msgstr "Twingle ID dieses Projekts" -#: api/v3/TwingleEvent/Delete.php api/v3/TwingleEvent/Get.php -#: api/v3/TwingleEvent/Getsingle.php api/v3/TwingleEvent/Sync.php -msgid "Twingle Event ID" -msgstr "Twingle Event ID" - #: api/v3/TwingleEvent/Delete.php api/v3/TwingleEvent/Get.php #: api/v3/TwingleEvent/Getsingle.php api/v3/TwingleEvent/Sync.php msgid "Twingle ID for this Event" @@ -380,11 +1098,6 @@ msgstr "Typ des Twingle Projects" msgid "Allow more" msgstr "Mehr zulassen" -#: api/v3/TwingleProject/Create.php api/v3/TwingleProject/Get.php -#: api/v3/TwingleProject/Getsingle.php -msgid "Allow to donate more than is defined in the target" -msgstr "Zulassen, dass mehr gespendet wird als im Spendenziel angegeben ist" - #: api/v3/TwingleProject/Create.php msgid "Project Target" msgstr "Spendenziel" @@ -416,3 +1129,31 @@ msgstr "Allgemeine Einstellungen" #: templates/CRM/TwingleCampaign/Form/Settings.tpl msgid "Twingle Event Settings" msgstr "Twingle Event Einstellungen" + +#: twinglecampaign.php +msgid "Campaign cloning failed" +msgstr "Klonen der Kampagne fehlgeschlagen" + +#: twinglecampaign.php +msgid "TwingleCampaign update failed" +msgstr "TwingleCampaign-Update fehlgeschlagen" + +#: twinglecampaign.php +msgid "TwingleCampaign was saved." +msgstr "TwingleCampaign wurde gespeichert" + +#: twinglecampaign.php +msgid "TwingleProject creation failed" +msgstr "Erstellung des TwingleProjects fehlgeschlagen" + +#: twinglecampaign.php +msgid "Could not retrieve Twingle API key" +msgstr "Twingle-API-Schlüssel nicht gefunden" + +#: twinglecampaign.php +msgid "TwingleProject synchronization failed: %1" +msgstr "Synchronisation des TwingleProjects fehlgeschlagen: %1" + +#: twinglecampaign.php +msgid "Input validation failed" +msgstr "Eingabeüberprüfung fehlgeschlagen" diff --git a/l10n/pot/twinglecampaign.pot b/l10n/pot/twinglecampaign.pot index 6e8e0c0..0516610 100644 --- a/l10n/pot/twinglecampaign.pot +++ b/l10n/pot/twinglecampaign.pot @@ -1,3 +1,27 @@ +#: ./CRM/TwingleCampaign/BAO/CustomField.php +msgid "Creation of custom field '%1' failed. Find more information in the logs." +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/CustomField.php +msgid "Creation of custom field failed. Find more information in the logs." +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/CustomField.php +msgid "Creation of custom field '%1' failed, because a custom field with that name already exists. Find more information in the logs." +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/CustomGroup.php +msgid "Creation of custom group '%1' failed. Find more information in the logs." +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/CustomGroup.php +msgid "Creation of custom group failed. Find more information in the logs." +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/CustomGroup.php +msgid "Creation of custom group '%1' failed, because a custom group with that name already exists. Find more information in the logs." +msgstr "" + #: ./CRM/TwingleCampaign/BAO/TwingleCampaign.php msgid "Could not determine parent TwingleProject URL. This URL is needed to create the TwingleEvent URL. Please check the logs." msgstr "" @@ -14,6 +38,34 @@ msgstr "" msgid "No parent TwingleProject found" msgstr "" +#: ./CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "BCC email invalid" +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Invalid hexadecimal value in color field: %1" +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Missing maximum donation value" +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Maximum donation value must be higher than the minimum" +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Default donation value must lie in between maximum and minimum values" +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Donation values (Min, Max, Default) must be positive integers" +msgstr "" + +#: ./CRM/TwingleCampaign/BAO/TwingleProject.php +msgid "Invalid URL: %1" +msgstr "" + #: ./CRM/TwingleCampaign/Form/Settings.php ./api/v3/TwingleEvent/Delete.php ./api/v3/TwingleEvent/Sync.php ./api/v3/TwingleProject/Delete.php ./api/v3/TwingleProject/Sync.php ./api/v3/TwingleSync/Sync.php msgid "Twingle API key" msgstr "" @@ -74,6 +126,634 @@ msgstr "" msgid "Could not disable scheduled job \"TwingleSync\"." msgstr "" +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Information" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Settings" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Payment Methods" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Embed Codes" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Event Information" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Twingle Campaign Information" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php ./api/v3/TwingleEvent/Delete.php ./api/v3/TwingleEvent/Get.php ./api/v3/TwingleEvent/Getsingle.php ./api/v3/TwingleEvent/Sync.php ./api/v3/TwingleProject/Create.php ./api/v3/TwingleProject/Delete.php ./api/v3/TwingleProject/Get.php ./api/v3/TwingleProject/Getsingle.php ./api/v3/TwingleProject/Sync.php +msgid "Twingle Project ID" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Organisation ID" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "identifier" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "An unique identifier for a project (auto generated)" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Type" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Default" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Events" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Membership" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Choose the project type. Allow users to create own events or to pay a membership fee." +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "allow more" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php ./api/v3/TwingleProject/Create.php ./api/v3/TwingleProject/Get.php ./api/v3/TwingleProject/Getsingle.php +msgid "Allow to donate more than is defined in the target" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "transaction type" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "URL" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Widget" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Form" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Widget Single" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Form Single" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "All Events" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Event List" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Counter" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Page" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Confirmation Mail" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Send confirmation mail" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Receipt" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Offer donation receipts" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Contact Data" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Rhythm" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "yearly" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "halfyearly" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "quarterly" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "monthly" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "one time" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "The selected options are available for selection in the donation widget." +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Default Rhythm" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Which donation rhythm should be displayed as selected by default?" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Newsletter Registration" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Enable newsletter registration" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Postinfo Registration" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Enable post info registration" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Background Color" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Hex color code (e.g. ffffff for white)" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Primary Color" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Font Color" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "BCC Email" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Email address used as bcc addresses for confirmation mail which is send to an user" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Min" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Minimum donation value" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Max" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Maximum donation value" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Default" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Default donation value" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Contact Fields" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Salutation" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "First name" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Last name" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Company" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Birthday" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Street" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Postal Code" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "City" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Country" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Telephone" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Fields to include in contact form" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Mandatory Contact Fields" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Fields that must get filled in the contact form." +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Custom CSS" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "URL to a custom CSS file that will be included in the frontend" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Share URL" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "URL for the sharing component on the last page and doi page" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Contact Mandatory" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "If the contact data should be requested mandatory as second step" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Double Opt-In" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Enable Twingle's double opt-in (Do not enable, if you use CiviCRM's double opt-in!)" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Force Donation Taget as Button" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Force showing the donation targets as buttons" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Slider Icon" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Heart" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Asterisk" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Animal" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Lifebelt" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Angellist" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Handshake" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Dollar" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Menue" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Office" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Leaf" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Cog" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "SVG" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Euro" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Stats" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Circle" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Water drop outline" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Water drop" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Gift" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Bee" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Flower" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Train" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "No Icon" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Hidden Logo" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Hide the Logo on the project page" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Target Format" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Format of the reached portion of the donation target" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Donation Purpose as Textfield" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Let donors enter their own donation purpose" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Activate CiviCRM Support" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Activate support for Twingle Extension (de.systopia.twingle)" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Show Step Index" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Show a step index during donation process" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Languages" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "German" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "English" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "French" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Spanish" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Buttons" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Up to four buttons can be configured. If you leave the amount blank, the button will not be displayed." +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Slider" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Show a slider that allows the donor to choose the donation amount." +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 1" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 1" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 2" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 2" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 3" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 3" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Button 4" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Amount to be displayed on Button 4" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Newsletter Name Requested" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Must a donor give his name for newsletter sign-up?" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Show List of Donations" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Display a list of public donations" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Payment Methods" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "PayPal" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Banktransfer" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Debit" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Sofortüberweisung" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Chose which payment methods should be available. NOTE: You might have to activate them first in the Twingle-Manager configuration." +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Recurring Payment Methods" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php ./api/v3/TwingleEvent/Delete.php ./api/v3/TwingleEvent/Get.php ./api/v3/TwingleEvent/Getsingle.php ./api/v3/TwingleEvent/Sync.php +msgid "Twingle Event ID" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Identifier" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Initiator" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Initiator Email" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Is public" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Deleted" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Confirmed At" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Created At" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Creation URL" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Internal URL" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "External URL" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Edit Internal URL" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Edit External URL" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "Parent TwingleProject ID" +msgstr "" + +#: ./CRM/TwingleCampaign/resources/campaigns.php +msgid "CID" +msgstr "" + #: ./api/v3/TwingleCampaign/Create.php ./api/v3/TwingleCampaign/Delete.php ./api/v3/TwingleCampaign/Get.php ./api/v3/TwingleCampaign/Getsingle.php ./api/v3/TwingleCampaign/Sync.php msgid "Twingle Campaign ID" msgstr "" @@ -178,18 +858,10 @@ msgstr "" msgid "Unique Campaign ID" msgstr "" -#: ./api/v3/TwingleEvent/Delete.php ./api/v3/TwingleEvent/Get.php ./api/v3/TwingleEvent/Getsingle.php ./api/v3/TwingleEvent/Sync.php ./api/v3/TwingleProject/Create.php ./api/v3/TwingleProject/Delete.php ./api/v3/TwingleProject/Get.php ./api/v3/TwingleProject/Getsingle.php ./api/v3/TwingleProject/Sync.php -msgid "Twingle Project ID" -msgstr "" - #: ./api/v3/TwingleEvent/Delete.php ./api/v3/TwingleEvent/Sync.php ./api/v3/TwingleProject/Delete.php ./api/v3/TwingleProject/Get.php ./api/v3/TwingleProject/Getsingle.php ./api/v3/TwingleProject/Sync.php msgid "Twingle ID for this project" msgstr "" -#: ./api/v3/TwingleEvent/Delete.php ./api/v3/TwingleEvent/Get.php ./api/v3/TwingleEvent/Getsingle.php ./api/v3/TwingleEvent/Sync.php -msgid "Twingle Event ID" -msgstr "" - #: ./api/v3/TwingleEvent/Delete.php ./api/v3/TwingleEvent/Get.php ./api/v3/TwingleEvent/Getsingle.php ./api/v3/TwingleEvent/Sync.php msgid "Twingle ID for this Event" msgstr "" @@ -286,10 +958,6 @@ msgstr "" msgid "Allow more" msgstr "" -#: ./api/v3/TwingleProject/Create.php ./api/v3/TwingleProject/Get.php ./api/v3/TwingleProject/Getsingle.php -msgid "Allow to donate more than is defined in the target" -msgstr "" - #: ./api/v3/TwingleProject/Create.php msgid "Project Target" msgstr "" @@ -322,3 +990,31 @@ msgstr "" msgid "Twingle Event Settings" msgstr "" +#: ./twinglecampaign.php +msgid "Campaign cloning failed" +msgstr "" + +#: ./twinglecampaign.php +msgid "TwingleCampaign update failed" +msgstr "" + +#: ./twinglecampaign.php +msgid "TwingleCampaign was saved." +msgstr "" + +#: ./twinglecampaign.php +msgid "TwingleProject creation failed" +msgstr "" + +#: ./twinglecampaign.php +msgid "Could not retrieve Twingle API key" +msgstr "" + +#: ./twinglecampaign.php +msgid "TwingleProject synchronization failed: %1" +msgstr "" + +#: ./twinglecampaign.php +msgid "Input validation failed" +msgstr "" + From 1954f90f794d4174f7a0e2aa75021e23bddc3217 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Tue, 13 Apr 2021 00:20:13 +0200 Subject: [PATCH 08/12] =?UTF-8?q?=E2=9C=94=EF=B8=8F=20add=20UnitTests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- phpunit.xml.dist | 4 +- .../BAO/TwingleProjectTest.php | 142 ++++++++++++++++++ tests/resources/twingle_project_bad_dummy.php | 136 +++++++++++++++++ tests/resources/twingle_project_dummy.php | 137 +++++++++++++++++ 4 files changed, 417 insertions(+), 2 deletions(-) create mode 100644 tests/phpunit/CRM/TwingleCampaign/BAO/TwingleProjectTest.php create mode 100644 tests/resources/twingle_project_bad_dummy.php create mode 100644 tests/resources/twingle_project_dummy.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0f9f25d..af5fa8c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ - + - + ./tests/phpunit diff --git a/tests/phpunit/CRM/TwingleCampaign/BAO/TwingleProjectTest.php b/tests/phpunit/CRM/TwingleCampaign/BAO/TwingleProjectTest.php new file mode 100644 index 0000000..bf82a4b --- /dev/null +++ b/tests/phpunit/CRM/TwingleCampaign/BAO/TwingleProjectTest.php @@ -0,0 +1,142 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * @throws \Exception + */ + public function setUp() { + + // Create project from dummy values + $this->dummyProject = + require(E::path() . '/tests/resources/twingle_project_dummy.php'); + $this->badDummyProject = + require(E::path() . '/tests/resources/twingle_project_bad_dummy.php'); + $this->project = new TwingleProject($this->dummyProject); + $this->project->create(TRUE); + + parent::setUp(); + } + + /** + * @throws \CiviCRM_API3_Exception + */ + public function tearDown() { + + // Delete project + $this->project->delete(); + unset($this->project); + + parent::tearDown(); + } + + /** + * ## The full TwingleProject circle + * This test simulates a TwingleProject that is fetched from the database and + * than gets instantiated and sent back to Twingle. + * + * It is important that all project values sent to the Twingle API have the + * same data types like when they were retrieved from Twingle. To test this, + * the export array will be compared to the original dummy array. + * + * dummy:array -> project:object -> database -> project:object -> export:array + * + * @throws \CiviCRM_API3_Exception + * @throws \Exception + */ + public function testFullTwingleProjectCircle() { + + // Get project via API from database + $project = civicrm_api3( + 'TwingleProject', + 'getsingle', + ['id' => $this->project->getId()]); + $project = new TwingleProject($project, $project['id']); + + // Complement project values with dummy values. This is important because + // not all values coming from the Twingle API are stored in the database, + // but the Twingle API requires that all parameters are set. + $project->complement($this->dummyProject); + + // Export project + $export = $project->export(); + + // Check if the project is sent to Twingle in the same state it arrived + $this->assertEquals( + $this->dummyProject, + $export, + 'Export values differ from import values.' + ); + } + + /** + * ## Input validation + * Checks if the input validation works properly. + * + * @throws \CiviCRM_API3_Exception + * @throws \Exception + */ + public function testInputValidation() { + + // Get project via API from database + $project = civicrm_api3( + 'TwingleProject', + 'getsingle', + ['id' => $this->project->getId()]); + $project = new TwingleProject($project, $project['id']); + + // Check if validation successes with healthy input + $validation_success = $project->validate(); + $this->assertTrue( + $validation_success['valid'], + 'Validation failed with healthy inputs.' + ); + + // Update project with values which simulate incorrect user input + $project->update($this->badDummyProject); + + // Run validation again + $validation_fail = $project->validate(); + + // Check if validation failed (as it should) + $this->assertFalse( + $validation_fail['valid'], + 'Validation did not fail as expected.' + ); + + // Check if all 6 wrong inputs were found + $this->assertCount( + 6, $validation_fail['messages'], + 'Did not find all 6 wrong inputs.' + ); + } +} + diff --git a/tests/resources/twingle_project_bad_dummy.php b/tests/resources/twingle_project_bad_dummy.php new file mode 100644 index 0000000..a6aeda6 --- /dev/null +++ b/tests/resources/twingle_project_bad_dummy.php @@ -0,0 +1,136 @@ + 2243, + "internal_id" => NULL, + "name" => "TestProject", + "organisation_id" => 555, + "slug" => "test_project", + "identifier" => "tw5555555555555", + "type" => "event", + "transaction_type" => NULL, + "project_target" => 1000, + "image_directory" => NULL, + "allow_more" => FALSE, + "last_update" => 1614166801, + "embed" => [ + "page" => "https://spenden.twingle.de/my-awesome-ngo/testprojekt/tw555555a555555c/page", + "eventpage" => "https://my-awesome-ngo/event/testprojekt/tw555555a555555c/edit", + "widget" => "", + "form" => "", + "widget-single" => "", + "form-single" => "", + "eventall" => "", + "eventlist" => "", + "eventeditcreate" => "", + "giftdonationexample" => "https://spenden.twingle.de/gift/my-awesome-ngo/tw555555a555555c/example", + "letterexample" => "https://spenden.twingle.de/letter/my-awesome-ngo/tw555555a555555c/example", + ], + "counter-url" => [ + "url" => "https://donationstatus.twingle.de/donation-status/555aaa", + ], + "host" => "https://spenden.twingle.de/", + "project_options" => [ + "id" => 2237, + "has_confirmation_mail" => FALSE, + "has_confirmation_mail_api" => FALSE, + "has_donation_receipt" => TRUE, + "has_contact_data" => FALSE, + "donation_rhythm" => [ + "yearly" => TRUE, + "halfyearly" => FALSE, + "quarterly" => TRUE, + "monthly" => TRUE, + "one_time" => TRUE, + ], + "default_rhythm" => "", + "has_newsletter_registration" => FALSE, + "has_postinfo_registration" => FALSE, + "design_background_color" => "not_a_hex", // not a hex + "design_primary_color" => "green", // no hex either + "design_font" => "", + "design_font_color" => "true", // no hex either + "design_button_font_color" => "", + "design_button_font_color_light" => "", + "image" => "", + "bcc_email_address" => "mustermann@awesome", // no valid email + "donation_value_min" => 50, // higher than max + "donation_value_max" => 10, + "donation_value_default" => 30, // higher than max, lower than min + "exclude_contact_fields" => "company,birthday,telephone", + "mandatory_contact_fields" => "firstname,lastname", + "custom_js" => NULL, + "custom_css" => "", + "share_url" => "not_a_url", // no valid url + "has_contact_mandatory" => FALSE, + "has_doi" => TRUE, + "doi_redirect" => NULL, + "has_force_donation_target_buttons" => FALSE, + "has_show_single_target" => FALSE, + "betterpayment_credit_card_theme" => NULL, + "app_js" => NULL, + "slidericon" => "handshake", + "extra_field" => [], + "has_hidden_logo" => FALSE, + "has_projecttarget_as_money" => FALSE, + "rapidmail_recipient_list" => NULL, + "mailchimp_recipient_list" => NULL, + "has_mailchimp_add_all_user" => NULL, + "has_mail_hide_paymentblock" => FALSE, + "has_mail_hide_paymentblock_api" => FALSE, + "cleverreach_group_id" => NULL, + "cleverreach_form_id" => NULL, + "has_donationtarget_textfield" => FALSE, + "has_civi_crm_activated" => FALSE, + "has_step_index" => FALSE, + "gift_donation" => "", + "gift_donation_icon" => NULL, + "gift_donation_image" => NULL, + "languages" => "de", + "has_buttons" => FALSE, + "has_no_slider" => FALSE, + "buttons" => [ + "button1" => [ + "amount" => "5", + ], + "button2" => [ + "amount" => "50", + ], + "button3" => [ + "amount" => "100", + ], + "button4" => [ + "amount" => "", + ], + ], + "has_newsletter_namerequest" => FALSE, + "has_show_donator_data" => FALSE, + "has_donation_letter" => FALSE, + "has_donation_letter_api" => FALSE, + "amount_images" => [], + "video_url" => NULL, + ], + "payment_methods" => [ + "has_paypal" => TRUE, + "has_betterpayment" => FALSE, + "has_sixpay" => FALSE, + "has_banktransfer" => TRUE, + "has_debit" => TRUE, + "has_sofortueberweisung" => FALSE, + "has_betterpayment_creditcard" => FALSE, + "has_mbe4" => FALSE, + "has_generic" => FALSE, + "has_konfipay" => FALSE, + "has_konfipay_recurring" => FALSE, + "has_betterpayment_creditcard_recurring" => FALSE, + "has_paypal_recurring" => FALSE, + "has_debit_recurring" => TRUE, + "has_generic_recurring" => FALSE, + "has_sixpay_recurring" => FALSE, + "has_apple_pay" => FALSE, + "has_apple_pay_recurring" => FALSE, + "has_paydirekt" => FALSE, + "has_paydirekt_recurring" => FALSE, + ], +]; + diff --git a/tests/resources/twingle_project_dummy.php b/tests/resources/twingle_project_dummy.php new file mode 100644 index 0000000..760f52b --- /dev/null +++ b/tests/resources/twingle_project_dummy.php @@ -0,0 +1,137 @@ + 2243, + "internal_id" => NULL, + "name" => "TestProject", + "organisation_id" => 555, + "slug" => "test_project", + "identifier" => "tw5555555555555", + "type" => "event", + "transaction_type" => NULL, + "project_target" => 1000, + "image_directory" => NULL, + "allow_more" => FALSE, + "last_update" => 1614166801, + "embed" => [ + "page" => "https://spenden.twingle.de/my-awesome-ngo/testprojekt/tw555555a555555c/page", + "eventpage" => "https://my-awesome-ngo/event/testprojekt/tw555555a555555c/edit", + "widget" => "", + "form" => "", + "widget-single" => "", + "form-single" => "", + "eventall" => "", + "eventlist" => "", + "eventeditcreate" => "", + "giftdonationexample" => "https://spenden.twingle.de/gift/my-awesome-ngo/tw555555a555555c/example", + "letterexample" => "https://spenden.twingle.de/letter/my-awesome-ngo/tw555555a555555c/example", + ], + "counter-url" => [ + "url" => "https://donationstatus.twingle.de/donation-status/555aaa", + ], + "host" => "https://spenden.twingle.de/", + "project_options" => [ + "id" => 2237, + "has_confirmation_mail" => FALSE, + "has_confirmation_mail_api" => FALSE, + "has_donation_receipt" => TRUE, + "has_contact_data" => FALSE, + "donation_rhythm" => [ + "yearly" => TRUE, + "halfyearly" => FALSE, + "quarterly" => TRUE, + "monthly" => TRUE, + "one_time" => TRUE, + ], + "default_rhythm" => "", + "has_newsletter_registration" => FALSE, + "has_postinfo_registration" => FALSE, + "design_background_color" => "ffffff", + "design_primary_color" => "102045", + "design_font" => "", + "design_font_color" => "102045", + "design_button_font_color" => "", + "design_button_font_color_light" => "", + "image" => "", + "bcc_email_address" => "mustermann@awesome-ngo.org", + "donation_value_min" => 5, + "donation_value_max" => 1000, + "donation_value_default" => 50, + "exclude_contact_fields" => "company,birthday,telephone", + "mandatory_contact_fields" => "firstname,lastname", + "custom_js" => NULL, + "custom_css" => "https://awesome-ngo.org/css", + "share_url" => "https://awesome-ngo.org/donate", + "has_contact_mandatory" => FALSE, + "has_doi" => TRUE, + "doi_redirect" => NULL, + "has_force_donation_target_buttons" => FALSE, + "has_show_single_target" => FALSE, + "betterpayment_credit_card_theme" => NULL, + "app_js" => NULL, + "slidericon" => "handshake", + "extra_field" => [ + ], + "has_hidden_logo" => FALSE, + "has_projecttarget_as_money" => FALSE, + "rapidmail_recipient_list" => NULL, + "mailchimp_recipient_list" => NULL, + "has_mailchimp_add_all_user" => NULL, + "has_mail_hide_paymentblock" => FALSE, + "has_mail_hide_paymentblock_api" => FALSE, + "cleverreach_group_id" => NULL, + "cleverreach_form_id" => NULL, + "has_donationtarget_textfield" => FALSE, + "has_civi_crm_activated" => FALSE, + "has_step_index" => FALSE, + "gift_donation" => "", + "gift_donation_icon" => NULL, + "gift_donation_image" => NULL, + "languages" => "de", + "has_buttons" => FALSE, + "has_no_slider" => FALSE, + "buttons" => [ + "button1" => [ + "amount" => "5", + ], + "button2" => [ + "amount" => "50", + ], + "button3" => [ + "amount" => "100", + ], + "button4" => [ + "amount" => "", + ], + ], + "has_newsletter_namerequest" => FALSE, + "has_show_donator_data" => FALSE, + "has_donation_letter" => FALSE, + "has_donation_letter_api" => FALSE, + "amount_images" => [], + "video_url" => NULL, + ], + "payment_methods" => [ + "has_paypal" => TRUE, + "has_betterpayment" => FALSE, + "has_sixpay" => FALSE, + "has_banktransfer" => TRUE, + "has_debit" => TRUE, + "has_sofortueberweisung" => FALSE, + "has_betterpayment_creditcard" => FALSE, + "has_mbe4" => FALSE, + "has_generic" => FALSE, + "has_konfipay" => FALSE, + "has_konfipay_recurring" => FALSE, + "has_betterpayment_creditcard_recurring" => FALSE, + "has_paypal_recurring" => FALSE, + "has_debit_recurring" => TRUE, + "has_generic_recurring" => FALSE, + "has_sixpay_recurring" => FALSE, + "has_apple_pay" => FALSE, + "has_apple_pay_recurring" => FALSE, + "has_paydirekt" => FALSE, + "has_paydirekt_recurring" => FALSE, + ], +]; + From 4bcc4cf1fba7d29cbbd6d6cecd2fee04fd7604a4 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 11:47:43 +0200 Subject: [PATCH 09/12] =?UTF-8?q?=F0=9F=91=BE=20bug=20fix:=20project=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/TwingleProject.php | 9 +++++++++ api/v3/TwingleProject/Sync.php | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index 7e24868..dd82cef 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -41,6 +41,15 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { * CiviCRM Campaign id */ public function __construct(array $values = [], int $id = NULL) { + + // If the $values originally come from the TwingleProject.get API, they + // contain the internal CiviCRM id as 'id' and the external Twingle id as + // 'project_id'. In this case 'id' gets replaced with 'project_id' + if (isset($values['project_id'])) { + $values['id'] = $values['project_id']; + unset($values['project_id']); + } + parent::__construct($values, $id); $this->prefix = 'twingle_project_'; diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index 5792a5b..7768997 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -104,7 +104,6 @@ function civicrm_api3_twingle_project_Sync(array $params): array { // instantiate project from CiviCRM $id = $result['id']; - unset($result['id']); $project = new TwingleProject($result, $id); // Synchronize projects @@ -232,9 +231,10 @@ function civicrm_api3_twingle_project_Sync(array $params): array { foreach ($projects_from_twingle as $project_from_twingle) { if ($project_from_twingle['id'] == $project_from_civicrm['project_id']) { - // store campaign id in $id + // store campaign id in $id and replace it with project_id $id = $project_from_civicrm['id']; - unset($project_from_civicrm['id']); + $project_from_civicrm['id'] = $project_from_civicrm['project_id']; + unset($project_from_civicrm['project_id']); // instantiate project with values from TwingleProject.Get $project = new TwingleProject($project_from_civicrm, $id); From 9b45d4a1faf75a1a0591e1e748c7385ecc552bab Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 11:39:59 +0200 Subject: [PATCH 10/12] =?UTF-8?q?=E2=9C=A8=EF=B8=8F=20avoid=20"missing=20i?= =?UTF-8?q?ndex"=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/Campaign.php | 4 +++- api/v3/TwingleCampaign/Get.php | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/Campaign.php b/CRM/TwingleCampaign/BAO/Campaign.php index 316aa3f..6a5e9cc 100644 --- a/CRM/TwingleCampaign/BAO/Campaign.php +++ b/CRM/TwingleCampaign/BAO/Campaign.php @@ -74,7 +74,9 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { ); // Set id - $values_prepared_for_import['id'] = $this->id; + if (isset($this->id)) { + $values_prepared_for_import['id'] = $this->id; + } // Set a flag to not trigger the hook if ($no_hook) { diff --git a/api/v3/TwingleCampaign/Get.php b/api/v3/TwingleCampaign/Get.php index 6897ef0..b0670e1 100644 --- a/api/v3/TwingleCampaign/Get.php +++ b/api/v3/TwingleCampaign/Get.php @@ -107,9 +107,9 @@ function civicrm_api3_twingle_campaign_Get(array $params): array { Cache::getInstance() ->getCampaignIds()['campaign_types']['twingle_campaign']['id']; - // If no id but a project_id is provided, get all TwingleCampaign children of - // this TwingleProject - if (array_key_exists('project_id', $params) && $params['project_id']) { + // If no id but a parent_id or a project_id is provided, get all + // TwingleCampaign children of this TwingleProject + if (isset($params['project_id']) && !isset($params['parent_id'])) { // Get TwingleProject $project = civicrm_api3('TwingleProject', From 2f1e5721c140af46e32ffd1b8bdc154e96d9256b Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 11:26:29 +0200 Subject: [PATCH 11/12] =?UTF-8?q?=F0=9F=A7=B9=20code=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CRM/TwingleCampaign/BAO/Campaign.php | 2 -- CRM/TwingleCampaign/BAO/CampaignType.php | 9 +++++---- CRM/TwingleCampaign/BAO/CustomField.php | 18 +++--------------- CRM/TwingleCampaign/BAO/OptionValue.php | 5 ----- CRM/TwingleCampaign/BAO/TwingleProject.php | 7 ++----- CRM/TwingleCampaign/Upgrader.php | 11 +++++++---- api/v3/TwingleProject/Get.php | 2 +- 7 files changed, 18 insertions(+), 36 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/Campaign.php b/CRM/TwingleCampaign/BAO/Campaign.php index 6a5e9cc..86b0bdc 100644 --- a/CRM/TwingleCampaign/BAO/Campaign.php +++ b/CRM/TwingleCampaign/BAO/Campaign.php @@ -26,7 +26,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { protected $formattedValues; - /** * ## Campaign constructor. * @@ -55,7 +54,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { * @throws \Exception */ public function create(bool $no_hook = FALSE): bool { - // Prepare project values for import into database $values_prepared_for_import = $this->values; $this->formatValues( diff --git a/CRM/TwingleCampaign/BAO/CampaignType.php b/CRM/TwingleCampaign/BAO/CampaignType.php index 8e9f686..5957f86 100644 --- a/CRM/TwingleCampaign/BAO/CampaignType.php +++ b/CRM/TwingleCampaign/BAO/CampaignType.php @@ -27,6 +27,9 @@ class CRM_TwingleCampaign_BAO_CampaignType { } /** + * @param bool $upgrade + * If true: Does not show UF message if campaign type already exists + * * @throws \CiviCRM_API3_Exception */ public function create(bool $upgrade = false) { @@ -41,8 +44,7 @@ class CRM_TwingleCampaign_BAO_CampaignType { ] ); - if ($field['count'] == 0) - { + if ($field['count'] == 0) { $this->results = civicrm_api3('OptionValue', 'create', $this->getSetAttributes()); $this->value = array_column($this->results['values'], 'value')[0]; @@ -55,8 +57,7 @@ class CRM_TwingleCampaign_BAO_CampaignType { } else { $error_message = $this->results['error_message']; - Civi::log()->error("Twingle Extension could not create new campaign type - for \"$this->label\": $error_message"); + Civi::log()->error("Twingle Extension could not create new campaign type for \"$this->label\": $error_message"); } } elseif (!$upgrade) { diff --git a/CRM/TwingleCampaign/BAO/CustomField.php b/CRM/TwingleCampaign/BAO/CustomField.php index b28642f..dea24f9 100644 --- a/CRM/TwingleCampaign/BAO/CustomField.php +++ b/CRM/TwingleCampaign/BAO/CustomField.php @@ -53,11 +53,6 @@ class CRM_TwingleCampaign_BAO_CustomField { if (array_key_exists($var, $attributes)) { $this->$var = $attributes[$var]; } - - // translate help_post - if ($this->help_post) { - $this->help_post = E::ts($this->help_post); - } } } @@ -162,16 +157,9 @@ class CRM_TwingleCampaign_BAO_CustomField { if (!$name) { $result = []; - // Get json file with all custom fields for this extension - $json_file = file_get_contents(E::path() . - '/CRM/TwingleCampaign/resources/campaigns.json'); - $campaign_info = json_decode($json_file, TRUE); - - // Log an error and throw an exception if the file cannot get read - if (!$campaign_info) { - Civi::log()->error("Could not read json file"); - throw new Exception('Could not read json file'); - } + // Get array with all custom fields for this extension + $campaign_info = + require E::path() . '/CRM/TwingleCampaign/resources/campaigns.php'; // Recursive method call with all custom field names from the json file foreach ($campaign_info['custom_fields'] as $customField) { diff --git a/CRM/TwingleCampaign/BAO/OptionValue.php b/CRM/TwingleCampaign/BAO/OptionValue.php index 38251f7..9de6594 100644 --- a/CRM/TwingleCampaign/BAO/OptionValue.php +++ b/CRM/TwingleCampaign/BAO/OptionValue.php @@ -33,11 +33,6 @@ class CRM_TwingleCampaign_BAO_OptionValue { if (array_key_exists($var, $attributes)) { $this->$var = $attributes[$var]; } - - // translate description - if ($this->description) { - $this->description = E::ts($this->description); - } } } diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index dd82cef..b92313e 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -677,19 +677,16 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { return $response; } - /** * ## Last update * Returns a timestamp of the last update of the TwingleProject campaign. * - * @return int|string|null + * @return int|null */ - public - function lastUpdate(): ?int { + public function lastUpdate(): ?int { return self::getTimestamp($this->values['last_update']); } - /** * ## Get project id * Returns the **project_id** of this TwingleProject. diff --git a/CRM/TwingleCampaign/Upgrader.php b/CRM/TwingleCampaign/Upgrader.php index b87e152..6cecff9 100644 --- a/CRM/TwingleCampaign/Upgrader.php +++ b/CRM/TwingleCampaign/Upgrader.php @@ -65,10 +65,12 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base { */ public function install() { // Create campaign types, custom fields and custom groups by the contents - // of the json file "campaigns.json" + // of the campaigns.php file - $campaign_info = Cache::getInstance()->getCampaigns(); - $option_values = Cache::getInstance()->getOptionValues(); + $campaign_info = require E::path() . + '/CRM/TwingleCampaign/resources/campaigns.php'; + $option_values = require E::path() . + '/CRM/TwingleCampaign/resources/option_values.php'; // Create campaign types foreach ($campaign_info['campaign_types'] as $campaign_type) { @@ -132,7 +134,8 @@ class CRM_TwingleCampaign_Upgrader extends CRM_TwingleCampaign_Upgrader_Base { */ public function uninstall() { - $campaign_info = Cache::getInstance()->getCampaigns(); + $campaign_info = require E::path() . + '/CRM/TwingleCampaign/resources/campaigns.php'; $option_values = Cache::getInstance()->getOptionValues(); // Delete campaign types diff --git a/api/v3/TwingleProject/Get.php b/api/v3/TwingleProject/Get.php index da78501..012150a 100644 --- a/api/v3/TwingleProject/Get.php +++ b/api/v3/TwingleProject/Get.php @@ -127,7 +127,7 @@ function civicrm_api3_twingle_project_Get(array $params): array { $query = ['options' => ['limit' => 0]]; foreach ($params as $key => $value) { - if ( $key != 'id' && + if ($key != 'id' && array_key_exists('twingle_project_' . $key, $custom_field_mapping) ) { $query[$custom_field_mapping['twingle_project_' . $key]] = $value; From 2be0a5ba49761d16df9010c26695448c3d583d9d Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 12 Apr 2021 11:28:25 +0200 Subject: [PATCH 12/12] =?UTF-8?q?=F0=9F=93=9A=20add=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Twingle_Project.md | 34 +++++++++++++++++++++++++++++ images/TwingleProject_settings.png | Bin 0 -> 235772 bytes 2 files changed, 34 insertions(+) create mode 100644 docs/Twingle_Project.md create mode 100644 images/TwingleProject_settings.png diff --git a/docs/Twingle_Project.md b/docs/Twingle_Project.md new file mode 100644 index 0000000..c3a24ce --- /dev/null +++ b/docs/Twingle_Project.md @@ -0,0 +1,34 @@ +# Twingle Project + +This campaign type represents Twingle donation forms. *Twingle Projects* are campaigns which get synchronized between +Twingle and your CiviCRM instance in both directions. A *Twingle Project* has three extra sections: + +## Twingle Information + +This section shows the external Twingle id, the identifier and the project type (default, event or membership). You can +change the project type at any time, but please be aware that your Twingle donation forms will change their appearance +depending on what project type is selevted. + +## Twingle Settings + +Here you can find almost all settings to configure a donation form. Each setting has a help text. + +Currently, there is no front end input validation but all settings get validated on server side when the form gets +saved. If the validation fails, an error message will be displayed that contains further information. In this case, the +form won't get saved. + +## Twingle Payment Methods + +These settings allow you to specify the payment methods that you want to offer to users for one time and recurring +donations. + +Currently, the extension only supports to configure *PayPal*, *bank transfer*, *debit* and *Sofortüberweisung* as one +time payment methods and *PayPal* and *debit* as recurring payment methods. This may be enhanced in future versions. +Nevertheless, you can configure additional payment methods in the *[TwingleMANAGER](https://twinglemanager.de)* – they +won't get overwritten by the *Twingle Campaign* extension. + +Please make sure to establish all payment methods in your general *[TwingleMANAGER](https://twinglemanager.de)* settings +before you try to configure them for *Twingle Projects*. + +## Twingle Project Preview +![TwingleProject](../images/TwingleProject_settings.png) \ No newline at end of file diff --git a/images/TwingleProject_settings.png b/images/TwingleProject_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..4f97e50de5d8b2e5a45f8550e6f6e53bd4c7ed8a GIT binary patch literal 235772 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 z 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 literal 0 HcmV?d00001