diff --git a/CRM/Twingle/Form/Profile.php b/CRM/Twingle/Form/Profile.php new file mode 100644 index 0000000..975a198 --- /dev/null +++ b/CRM/Twingle/Form/Profile.php @@ -0,0 +1,402 @@ +_op = CRM_Utils_Request::retrieve('op', 'String', $this)) { + $this->_op = 'create'; + } + + // Verify that profile with the given name exists. + $profile_name = CRM_Utils_Request::retrieve('name', 'String', $this); + if (!$this->profile = CRM_Twingle_Profile::getProfile($profile_name)) { + $profile_name = NULL; + } + + // Assign template variables. + $this->assign('op', $this->_op); + $this->assign('profile_name', $profile_name); + + // Set redirect destination. + $this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1'); + + switch ($this->_op) { + case 'delete': + if ($profile_name) { + CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile %1', array(1 => $profile_name))); + $this->addButtons(array( + array( + 'type' => 'submit', + 'name' => ($profile_name == 'default' ? E::ts('Reset') : E::ts('Delete')), + 'isDefault' => TRUE, + ), + )); + } + parent::buildQuickForm(); + return; + case 'edit': + // When editing without a valid profile name, edit the default profile. + if (!$profile_name) { + $profile_name = 'default'; + $this->profile = CRM_Twingle_Profile::getProfile($profile_name); + } + CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile %1', array(1 => $this->profile->getName()))); + break; + case 'create': + // Load factory default profile values. + $this->profile = CRM_twingle_Profile::createDefaultProfile($profile_name); + CRM_Utils_System::setTitle(E::ts('New Twingle API profile')); + break; + } + + // Add form elements. + $is_default = $profile_name == 'default'; + $this->add( + ($is_default ? 'static' : 'text'), + 'name', + E::ts('Profile name'), + array(), + !$is_default + ); + + $this->add( + 'text', // field type + 'selector', // field name + E::ts('Project IDs'), // field label + array(), + TRUE // is required + ); + + $this->add( + 'select', + 'location_type_id', + E::ts('Location type'), + $this->getLocationTypes(), + TRUE + ); + + $this->add( + 'select', // field type + 'financial_type_id', // field name + E::ts('Financial Type'), // field label + $this->getFinancialTypes(), // list of options + TRUE // is required + ); + + $payment_instruments = CRM_Twingle_Profile::paymentInstruments(); + $this->assign('payment_instruments', $payment_instruments); + foreach ($payment_instruments as $pi_name => $pi_label) { + $this->add( + 'select', // field type + $pi_name, // field name + E::ts('Record %1 as', array(1 => $pi_label)), // field label + $this->getPaymentInstruments(), // list of options + TRUE // is required + ); + } + + $this->add( + 'select', // field type + 'newsletter_groups', // field name + E::ts('Sign up for newsletter groups'), // field label + $this->getNewsletterGroups(), // list of options + FALSE, // is not required + array('class' => 'crm-select2 huge', 'multiple' => 'multiple') + ); + + $this->add( + 'select', // field type + 'postinfo_groups', // field name + E::ts('Sign up for postal mail groups'), // field label + $this->getPostinfoGroups(), // list of options + FALSE, // is not required + array('class' => 'crm-select2 huge', 'multiple' => 'multiple') + ); + + $this->add( + 'select', // field type + 'donation_receipt_groups', // field name + E::ts('Sign up for Donation receipt groups'), // field label + $this->getDonationReceiptGroups(), // list of options + FALSE, // is not required + array('class' => 'crm-select2 huge', 'multiple' => 'multiple') + ); + + $this->addButtons(array( + array( + 'type' => 'submit', + 'name' => E::ts('Save'), + 'isDefault' => TRUE, + ), + )); + + // Export form elements. + parent::buildQuickForm(); + } + + /** + * @inheritdoc + */ + public function addRules() { + $this->addFormRule(array('CRM_Twingle_Form_Profile', 'validateProfileForm')); + } + + /** + * Validates the profile form. + * + * @param array $values + * The submitted form values, keyed by form element name. + * + * @return bool | array + * TRUE when the form was successfully validated, or an array of error + * messages, keyed by form element name. + */ + public static function validateProfileForm($values) { + $errors = array(); + + // Restrict profile names to alphanumeric characters and the underscore. + if (isset($values['name']) && preg_match("/[^A-Za-z0-9\_]/", $values['name'])) { + $errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.'); + } + + return empty($errors) ? TRUE : $errors; + } + + /** + * Set the default values (i.e. the profile's current data) in the form. + */ + public function setDefaultValues() { + $defaults = parent::setDefaultValues(); + if (in_array($this->_op, array('create', 'edit'))) { + $defaults['name'] = $this->profile->getName(); + foreach ($this->profile->getData() as $element_name => $value) { + $defaults[$element_name] = $value; + } + } + return $defaults; + } + + /** + * Store the values submitted with the form in the profile. + */ + public function postProcess() { + $values = $this->exportValues(); + if (in_array($this->_op, array('create', 'edit'))) { + if (empty($values['name'])) { + $values['name'] = 'default'; + } + $this->profile->setName($values['name']); + foreach ($this->profile->getData() as $element_name => $value) { + if (isset($values[$element_name])) { + $this->profile->setAttribute($element_name, $values[$element_name]); + } + } + $this->profile->saveProfile(); + } + elseif ($this->_op == 'delete') { + $this->profile->deleteProfile(); + } + parent::postProcess(); + } + + /** + * Retrieves location types present within the system as options for select + * form elements. + */ + public function getLocationTypes() { + $location_types = array(); + $query = civicrm_api3('LocationType', 'get', array( + 'is_active' => 1, + )); + foreach ($query['values'] as $type) { + $location_types[$type['id']] = $type['name']; + } + + return $location_types; + } + + /** + * Retrieves financial types present within the system as options for select + * form elements. + */ + public function getFinancialTypes() { + $financial_types = array(); + $query = civicrm_api3('FinancialType', 'get', array( + 'is_active' => 1, + 'option.limit' => 0, + 'return' => 'id,name' + )); + foreach ($query['values'] as $type) { + $financial_types[$type['id']] = $type['name']; + } + return $financial_types; + } + + /** + * Retrieves campaigns present within the system as options for select form + * elements. + */ + public function getCampaigns() { + $campaigns = array('' => E::ts("no campaign")); + $query = civicrm_api3('Campaign', 'get', array( + 'is_active' => 1, + 'option.limit' => 0, + 'return' => 'id,title' + )); + foreach ($query['values'] as $campaign) { + $campaigns[$campaign['id']] = $campaign['title']; + } + return $campaigns; + } + + /** + * Retrieves payment instruments present within the system as options for + * select form elements. + */ + public function getPaymentInstruments() { + if (!isset(self::$_paymentInstruments)) { + self::$_paymentInstruments = array(); + $query = civicrm_api3('OptionValue', 'get', array( + 'option_group_id' => 'payment_instrument', + 'is_active' => 1, + 'option.limit' => 0, + 'return' => 'value,label' + )); + foreach ($query['values'] as $payment_instrument) { + self::$_paymentInstruments[$payment_instrument['value']] = $payment_instrument['label']; + } + } + return self::$_paymentInstruments; + } + + /** + * Retrieves active groups used as mailing lists within the system as options + * for select form elements. + */ + public function getNewsletterGroups() { + $groups = array(); + $group_types = civicrm_api3('OptionValue', 'get', array( + 'option_group_id' => 'group_type', + 'name' => CRM_Twingle_Submission::GROUP_TYPE_NEWSLETTER, + )); + if ($group_types['count'] > 0) { + $group_type = reset($group_types['values']); + $query = civicrm_api3('Group', 'get', array( + 'is_active' => 1, + 'group_type' => array('LIKE' => '%' . CRM_Utils_Array::implodePadded($group_type['value']) . '%'), + 'option.limit' => 0, + 'return' => 'id,name' + )); + foreach ($query['values'] as $group) { + $groups[$group['id']] = $group['name']; + } + } + else { + $groups[''] = E::ts('No newsletter groups available'); + } + return $groups; + } + + /** + * Retrieves active groups used as postal mailing lists within the system as + * options for select form elements. + */ + public function getPostinfoGroups() { + $groups = array(); + $group_types = civicrm_api3('OptionValue', 'get', array( + 'option_group_id' => 'group_type', + 'name' => CRM_Twingle_Submission::GROUP_TYPE_POSTINFO, + )); + if ($group_types['count'] > 0) { + $group_type = reset($group_types['values']); + $query = civicrm_api3('Group', 'get', array( + 'is_active' => 1, + 'group_type' => array('LIKE' => '%' . CRM_Utils_Array::implodePadded($group_type['value']) . '%'), + 'option.limit' => 0, + 'return' => 'id,name' + )); + foreach ($query['values'] as $group) { + $groups[$group['id']] = $group['name']; + } + } + else { + $groups[''] = E::ts('No postal mailing groups available'); + } + return $groups; + } + + /** + * Retrieves active groups used as donation receipt requester lists within the + * system as options for select form elements. + */ + public function getDonationReceiptGroups() { + $groups = array(); + $group_types = civicrm_api3('OptionValue', 'get', array( + 'option_group_id' => 'group_type', + 'name' => CRM_Twingle_Submission::GROUP_TYPE_DONATION_RECEIPT, + )); + if ($group_types['count'] > 0) { + $group_type = reset($group_types['values']); + $query = civicrm_api3('Group', 'get', array( + 'is_active' => 1, + 'group_type' => array('LIKE' => '%' . CRM_Utils_Array::implodePadded($group_type['value']) . '%'), + 'option.limit' => 0, + 'return' => 'id,name' + )); + foreach ($query['values'] as $group) { + $groups[$group['id']] = $group['name']; + } + } + else { + $groups[''] = E::ts('No donation receipt groups available'); + } + return $groups; + } + +} diff --git a/CRM/Twingle/Form/Settings.php b/CRM/Twingle/Form/Settings.php new file mode 100644 index 0000000..f2ee874 --- /dev/null +++ b/CRM/Twingle/Form/Settings.php @@ -0,0 +1,190 @@ + 'de.systopia.twingle'); + + //everything from this line down is generic & can be re-used for a setting form in another extension + //actually - I lied - I added a specific call in getFormSettings + private $_submittedValues = array(); + private $_settings = array(); + + /** + * @inheritdoc + */ + function buildQuickForm() { + // Set redirect destination. + $this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle', 'reset=1'); + + $settings = $this->getFormSettings(); + $form_elements = array(); + + foreach ($settings as $name => $setting) { + if (isset($setting['quick_form_type'])) { + $add = 'add' . $setting['quick_form_type']; + if ($add == 'addElement') { + $this->$add( + $setting['html_type'], + $name, + ts($setting['title']), + CRM_Utils_Array::value('html_attributes', $setting, array()) + ); + } + elseif ($setting['html_type'] == 'Select') { + $optionValues = array(); + if (!empty($setting['pseudoconstant']) && !empty($setting['pseudoconstant']['optionGroupName'])) { + $optionValues = CRM_Core_OptionGroup::values($setting['pseudoconstant']['optionGroupName'], FALSE, FALSE, FALSE, NULL, 'name'); + } + $this->add( + 'select', + $setting['name'], + $setting['title'], + $optionValues, + FALSE, + CRM_Utils_Array::value('html_attributes', $setting, array()) + ); + } + else { + $this->$add($name, ts($setting['title'])); + } + $form_elements[$setting['name']] = array('description' => ts($setting['description'])); + + // Disable CiviSEPA setting if the extension is not installed. + if ($name == 'twingle_use_sepa') { + $sepa_extension = civicrm_api3('Extension', 'get', array( + 'full_name' => 'org.project60.sepa', + 'is_active' => 1, + )); + if ($sepa_extension['count'] == 0) { + $element = $this->getElement('twingle_use_sepa'); + $element->freeze(); + $form_elements['twingle_use_sepa']['description'] .= ' The CiviSEPA (org.project60.sepa) extension is not installed.'; + } + } + } + } + + $this->assign('formElements', $form_elements); + + $this->addButtons(array( + array ( + 'type' => 'submit', + 'name' => ts('Save'), + 'isDefault' => TRUE, + ) + )); + + // Export form elements. + $this->assign('elementNames', $this->getRenderableElementNames()); + parent::buildQuickForm(); + } + + /** + * @inheritdoc + */ + function postProcess() { + $this->_submittedValues = $this->exportValues(); + $this->saveSettings(); + parent::postProcess(); + } + + /** + * Get the fields/elements defined in this form. + * + * @return array (string) + */ + function getRenderableElementNames() { + // The _elements list includes some items which should not be + // auto-rendered in the loop -- such as "qfKey" and "buttons". These + // items don't have labels. We'll identify renderable by filtering on + // the 'label'. + $elementNames = array(); + foreach ($this->_elements as $element) { + /* @var \HTML_QuickForm_element $element */ + $label = $element->getLabel(); + if (!empty($label)) { + $elementNames[] = $element->getName(); + } + } + return $elementNames; + } + /** + * Get the settings we are going to allow to be set on this form. + * + * @return array + */ + function getFormSettings() { + if (empty($this->_settings)) { + $settings = civicrm_api3('setting', 'getfields', array('filters' => $this->_settingFilter)); + $settings = $settings['values']; + } + else { + $settings = $this->_settings; + } + return $settings; + } + /** + * Save the settings set on this form. + */ + function saveSettings() { + $settings = $this->getFormSettings(); + $values = array_intersect_key($this->_submittedValues, $settings); + civicrm_api3('setting', 'create', $values); + } + /** + * @inheritdoc + */ + function setDefaultValues() { + $existing = civicrm_api3('setting', 'get', array('return' => array_keys($this->getFormSettings()))); + $defaults = array(); + $domainID = CRM_Core_Config::domainID(); + foreach ($existing['values'][$domainID] as $name => $value) { + $defaults[$name] = $value; + } + return $defaults; + } + + /** + * @inheritdoc + */ + public function addRules() { + $this->addFormRule(array('CRM_Twingle_Form_Settings', 'validateSettingsForm')); + } + + /** + * Validates the profile form. + * + * @param array $values + * The submitted form values, keyed by form element name. + * + * @return bool | array + * TRUE when the form was successfully validated, or an array of error + * messages, keyed by form element name. + */ + public static function validateSettingsForm($values) { + $errors = array(); + + return empty($errors) ? TRUE : $errors; + } + +} diff --git a/CRM/Twingle/Page/Configuration.php b/CRM/Twingle/Page/Configuration.php new file mode 100644 index 0000000..2a56343 --- /dev/null +++ b/CRM/Twingle/Page/Configuration.php @@ -0,0 +1,24 @@ + $profile) { + $profiles[$profile_name]['name'] = $profile_name; + foreach (CRM_Twingle_Profile::allowedAttributes() as $attribute) { + $profiles[$profile_name][$attribute] = $profile->getAttribute($attribute); + } + } + $this->assign('profiles', $profiles); + + parent::run(); + } + +} diff --git a/CRM/Twingle/Profile.php b/CRM/Twingle/Profile.php index 5d9c421..ff031e2 100644 --- a/CRM/Twingle/Profile.php +++ b/CRM/Twingle/Profile.php @@ -56,7 +56,6 @@ class CRM_Twingle_Profile { ); } - /** * Checks whether the profile's selector matches the given project ID. * @@ -166,16 +165,45 @@ class CRM_Twingle_Profile { * @return array */ public static function allowedAttributes() { - // TODO: Adjust attributes for Twingle. return array( 'selector', 'location_type_id', 'financial_type_id', - 'campaign_id', + 'pi_banktransfer', + 'pi_debit_manual', + 'pi_debit_automatic', 'pi_creditcard', - 'pi_sepa', + 'pi_mobilephone_germany', 'pi_paypal', - 'groups', + 'pi_sofortueberweisung', + 'pi_amazonpay', + 'pi_paydirekt', + 'pi_applepay', + 'pi_googlepay', + 'newsletter_groups', + 'postinfo_groups', + 'donation_receipt_groups' + ); + } + + /** + * Retrieves a list of supported payment methods. + * + * @return array + */ + public static function paymentInstruments() { + return array( + 'pi_banktransfer' => E::ts('Bank transfer'), + 'pi_debit_manual' => E::ts('Debit manual'), + 'pi_debit_automatic' => E::ts('Debit automatic'), + 'pi_creditcard' => E::ts('Credit card'), + 'pi_mobilephone_germany' => E::ts('Mobile phone Germany'), + 'pi_paypal' => E::ts('PayPal'), + 'pi_sofortueberweisung' => E::ts('SOFORT Überweisung'), + 'pi_amazonpay' => E::ts('Amazon Pay'), + 'pi_paydirekt' => E::ts('paydirekt'), + 'pi_applepay' => E::ts('Apple Pay'), + 'pi_googlepay' => E::ts('Google Pay'), ); } @@ -188,16 +216,24 @@ class CRM_Twingle_Profile { * @return CRM_Twingle_Profile */ public static function createDefaultProfile($name = 'default') { - // TODO: Adjust attributes for Twingle. return new CRM_Twingle_Profile($name, array( 'selector' => '', 'location_type_id' => CRM_Twingle_Submission::LOCATION_TYPE_ID_WORK, 'financial_type_id' => 1, // "Donation" - 'campaign_id' => '', - 'pi_creditcard' => 1, // "Credit Card" - 'pi_sepa' => 5, // "EFT" - 'pi_paypal' => 3, // "Debit" - 'groups' => '', + 'pi_banktransfer' => 5, // "EFT" + 'pi_debit_manual' => '', // TODO: SEPA + 'pi_debit_automatic' => 3, // Debit + 'pi_creditcard' => 1, // "Credit Card" + 'pi_mobilephone_germany' => '', + 'pi_paypal' => '', + 'pi_sofortueberweisung' => '', + 'pi_amazonpay' => '', + 'pi_paydirekt' => '', + 'pi_applepay' => '', + 'pi_googlepay' => '', + 'newsletter_groups' => '', + 'postinfo_groups' => '', + 'donation_receipt_groups' => '', )); } @@ -212,18 +248,21 @@ class CRM_Twingle_Profile { */ public static function getProfileForProject($project_id) { $profiles = self::getProfiles(); + + // If none matches, use the default profile. + $profile = $profiles['default']; + foreach ($profiles as $profile) { if ($profile->matches($project_id)) { - return $profile; + break; } } - // No profile matched, return default profile. - return $profiles['default']; + return $profile; } /** - * Retrieves the profil with the given name. + * Retrieves the profile with the given name. * * @param $name * diff --git a/CRM/Twingle/Submission.php b/CRM/Twingle/Submission.php index 8260d81..06db85f 100644 --- a/CRM/Twingle/Submission.php +++ b/CRM/Twingle/Submission.php @@ -22,6 +22,21 @@ class CRM_Twingle_Submission { */ const LOCATION_TYPE_ID_WORK = 2; + /** + * The option value name of the group type for newsletter subscribers. + */ + const GROUP_TYPE_NEWSLETTER = 'Mailing List'; + + /** + * The option value name of the group type for postal mailing subscribers. + */ + const GROUP_TYPE_POSTINFO = ''; // TODO. + + /** + * The option value name of the group type for donation receipt requesters. + */ + const GROUP_TYPE_DONATION_RECEIPT = ''; // TODO. + /** * The default ID of the "Employer of" relationship type. */ diff --git a/api/v3/TwingleDonation/Submit.php b/api/v3/TwingleDonation/Submit.php index 4d0fb40..76409eb 100644 --- a/api/v3/TwingleDonation/Submit.php +++ b/api/v3/TwingleDonation/Submit.php @@ -339,6 +339,15 @@ function civicrm_api3_twingle_donation_Submit($params) { ); } + // Save user_extrafield as contact note. + if (!empty($params['user_extrafield'])) { + civicrm_api3('Note', 'create', array( + 'entity_table' => 'civicrm_contact', + 'entity_id' => $contact_id, + 'note' => $params['user_extrafield'], + )); + } + // Organisation lookup. if (!empty($params['organization_name'])) { $organisation_data = array( @@ -378,6 +387,8 @@ function civicrm_api3_twingle_donation_Submit($params) { } } + // TODO: contact into newsletter, postinfo and donation_receipt groups. + // Create contribution or SEPA mandate. $contribution_data = array( 'contact_id' => (isset($organisation_id) ? $organisation_id : $contact_id), @@ -396,7 +407,14 @@ function civicrm_api3_twingle_donation_Submit($params) { 'full_name' => 'org.project60.sepa', 'is_active' => 1, )); - if ($sepa_extension['count'] && CRM_Sepa_Logic_Settings::isSDD($contribution_data)) { + if ( + CRM_Core_BAO_Setting::getItem( + 'de.systopia.twingle', + 'twingle_use_sepa' + ) + && $sepa_extension['count'] + && CRM_Sepa_Logic_Settings::isSDD($contribution_data) + ) { // If CiviSEPA is installed and the financial type is a CiviSEPA-one, // create SEPA mandate (and recurring contribution, using "createfull" API // action). diff --git a/settings/twingle.setting.php b/settings/twingle.setting.php new file mode 100644 index 0000000..164c97e --- /dev/null +++ b/settings/twingle.setting.php @@ -0,0 +1,34 @@ + array( + 'group_name' => 'de.systopia.twingle', + 'group' => 'de.systopia.twingle', + 'name' => 'twingle_use_sepa', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'html_type' => 'radio', + 'title' => 'Use CiviSEPA', + 'default' => 0, + 'add' => '4.6', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Whether to provide CiviSEPA functionality for manual debit payment method. This requires the CiviSEPA (org.project60.sepa) extension be installed.', + ), +); diff --git a/templates/CRM/Twingle/Form/Profile.tpl b/templates/CRM/Twingle/Form/Profile.tpl new file mode 100644 index 0000000..6931fe5 --- /dev/null +++ b/templates/CRM/Twingle/Form/Profile.tpl @@ -0,0 +1,106 @@ +{*------------------------------------------------------------+ +| SYSTOPIA Twingle Integration | +| Copyright (C) 2018 SYSTOPIA | +| Author: J. Schuppe (schuppe@systopia.de) | ++-------------------------------------------------------------+ +| This program is released as free software under the | +| Affero GPL license. You can redistribute it and/or | +| modify it under the terms of this license which you | +| can read by viewing the included agpl.txt or online | +| at www.gnu.org/licenses/agpl.html. Removal of this | +| copyright header is strictly prohibited without | +| written permission from the original author(s). | ++-------------------------------------------------------------*} + +
+ + {if $op == 'create' or $op == 'edit'} + +
+ + {ts domain="de.systopia.twingle"}General settings{/ts} + + + + + + + + + + + + + + + + + + + + + + + +
{$form.name.label}{$form.name.html}
{$form.selector.label}{$form.selector.html}
{$form.location_type_id.label}{$form.location_type_id.html}
{$form.financial_type_id.label}{$form.financial_type_id.html}
+ +
+ +
+ + {ts domain="de.systopia.twingle"}Payment methods{/ts} + + + {foreach key=pi_name item=pi_label from=$payment_instruments} + + + + + {/foreach} +
{$form.$pi_name.label}{$form.$pi_name.html}
+ +
+ +
+ + {ts domain="de.systopia.twingle"}Groups{/ts} + + + + + + + + + + + + + + + + + + +
{$form.newsletter_groups.label}{$form.newsletter_groups.html}
{$form.postinfo_groups.label}{$form.postinfo_groups.html}
{$form.donation_receipts_groups.label}{$form.donation_receipts_groups.html}
+ +
+ + {elseif $op == 'delete'} + {if $profile_name} + {if $profile_name == 'default'} +
{ts domain="de.systopia.twingle" 1=$profile_name}Are you sure you want to reset the default profile?{/ts}
+ {else} +
{ts domain="de.systopia.twingle" 1=$profile_name}Are you sure you want to delete the profile %1?{/ts}
+ {/if} + {else} +
{ts domain="de.systopia.twingle"}Profile name not given or invalid.{/ts}
+ {/if} + {/if} + + {* FOOTER *} +
+ {include file="CRM/common/formButtons.tpl" location="bottom"} +
+ +
diff --git a/templates/CRM/Twingle/Form/Settings.hlp b/templates/CRM/Twingle/Form/Settings.hlp new file mode 100644 index 0000000..3371972 --- /dev/null +++ b/templates/CRM/Twingle/Form/Settings.hlp @@ -0,0 +1,17 @@ +{*------------------------------------------------------------+ +| SYSTOPIA Twingle Integration | +| Copyright (C) 2018 SYSTOPIA | +| Author: J. Schuppe (schuppe@systopia.de) | ++-------------------------------------------------------------+ +| This program is released as free software under the | +| Affero GPL license. You can redistribute it and/or | +| modify it under the terms of this license which you | +| can read by viewing the included agpl.txt or online | +| at www.gnu.org/licenses/agpl.html. Removal of this | +| copyright header is strictly prohibited without | +| written permission from the original author(s). | ++-------------------------------------------------------------*} + +{htxt id='id-twingle_use_sepa'} + {ts domain="de.systopia.twingle"}When the CiviSEPA (org.project60.sepa) extension is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the debit_manual payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data.{/ts} +{/htxt} diff --git a/templates/CRM/Twingle/Form/Settings.tpl b/templates/CRM/Twingle/Form/Settings.tpl new file mode 100644 index 0000000..6f57d37 --- /dev/null +++ b/templates/CRM/Twingle/Form/Settings.tpl @@ -0,0 +1,42 @@ +{*------------------------------------------------------------+ +| SYSTOPIA Twingle Integration | +| Copyright (C) 2018 SYSTOPIA | +| Author: J. Schuppe (schuppe@systopia.de) | ++-------------------------------------------------------------+ +| This program is released as free software under the | +| Affero GPL license. You can redistribute it and/or | +| modify it under the terms of this license which you | +| can read by viewing the included agpl.txt or online | +| at www.gnu.org/licenses/agpl.html. Removal of this | +| copyright header is strictly prohibited without | +| written permission from the original author(s). | ++-------------------------------------------------------------*} + +
+ + {* HEADER *} +
+ {include file="CRM/common/formButtons.tpl" location="top"} +
+ + + {foreach from=$elementNames item=elementName} + + + + + {/foreach} +
{$form.$elementName.label}   + {$form.$elementName.html} +
+ + {$formElements.$elementName.description} + +
+ + {* FOOTER *} +
+ {include file="CRM/common/formButtons.tpl" location="bottom"} +
+ +
diff --git a/templates/CRM/Twingle/Page/Configuration.tpl b/templates/CRM/Twingle/Page/Configuration.tpl new file mode 100644 index 0000000..e538603 --- /dev/null +++ b/templates/CRM/Twingle/Page/Configuration.tpl @@ -0,0 +1,25 @@ +{*------------------------------------------------------------+ +| SYSTOPIA Twingle Integration | +| Copyright (C) 2018 SYSTOPIA | +| Author: J. Schuppe (schuppe@systopia.de) | ++-------------------------------------------------------------+ +| This program is released as free software under the | +| Affero GPL license. You can redistribute it and/or | +| modify it under the terms of this license which you | +| can read by viewing the included agpl.txt or online | +| at www.gnu.org/licenses/agpl.html. Removal of this | +| copyright header is strictly prohibited without | +| written permission from the original author(s). | ++-------------------------------------------------------------*} +
+
+ + + {ts domain="de.systopia.twingle"}Configure profiles{/ts} + + + {ts domain="de.systopia.twingle"}Configure extension settings{/ts} + + +
+
\ No newline at end of file diff --git a/templates/CRM/Twingle/Page/Profiles.tpl b/templates/CRM/Twingle/Page/Profiles.tpl new file mode 100644 index 0000000..3b935a7 --- /dev/null +++ b/templates/CRM/Twingle/Page/Profiles.tpl @@ -0,0 +1,55 @@ +{*------------------------------------------------------------+ +| SYSTOPIA Twingle Integration | +| Copyright (C) 2018 SYSTOPIA | +| Author: J. Schuppe (schuppe@systopia.de) | ++-------------------------------------------------------------+ +| This program is released as free software under the | +| Affero GPL license. You can redistribute it and/or | +| modify it under the terms of this license which you | +| can read by viewing the included agpl.txt or online | +| at www.gnu.org/licenses/agpl.html. Removal of this | +| copyright header is strictly prohibited without | +| written permission from the original author(s). | ++-------------------------------------------------------------*} + +
+ +
+ + {ts domain="de.systopia.twingle"}New profile{/ts} + +
+ + {if !empty($profiles)} + + + + + + + + + + {foreach from=$profiles item=profile} + {assign var="profile_name" value=$profile.name} + + + + + + {/foreach} + +
{ts domain="de.systopia.twingle"}Profile name{/ts}{ts domain="de.systopia.twingle"}Properties{/ts}{ts domain="de.systopia.twingle"}Operations{/ts}
{$profile.name} +
{ts domain="de.systopia.twingle"}Selector{/ts}: {$profile.selector}
+
+ {ts domain="de.systopia.twingle"}Edit{/ts} + {if $profile_name == 'default'} + {ts domain="de.systopia.twingle"}Reset{/ts} + {else} + {ts domain="de.systopia.twingle"}Delete{/ts} + {/if} + +
+ {/if} + +
diff --git a/xml/Menu/twingle.xml b/xml/Menu/twingle.xml new file mode 100644 index 0000000..80529df --- /dev/null +++ b/xml/Menu/twingle.xml @@ -0,0 +1,32 @@ + + + + civicrm/admin/settings/twingle + CRM_Twingle_Page_Configuration + Twingle API Configuration + administer CiviCRM + Configure the Twingle API extension + System Settings + admin/option.png + + + civicrm/admin/settings/twingle/settings + CRM_Twingle_Form_Settings + Twingle API Settings + administer CiviCRM + + + civicrm/admin/settings/twingle/profiles + CRM_Twingle_Page_Profiles + Twingle API profile settings + administer CiviCRM + Configure profiles for the Twingle API extension + admin/option.png + + + civicrm/admin/settings/twingle/profile + CRM_Twingle_Form_Profile + Twingle Profile + administer CiviCRM + +