Merge branch 'master' into dev_5
This commit is contained in:
commit
cd7c7e7d12
16 changed files with 772 additions and 186 deletions
|
@ -44,6 +44,76 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
*/
|
*/
|
||||||
protected static $_paymentInstruments = NULL;
|
protected static $_paymentInstruments = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved contribution statuses found within
|
||||||
|
* static::getContributionStatusOptions().
|
||||||
|
*/
|
||||||
|
protected static $_contributionStatusOptions = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved groups found within static::getGroups().
|
||||||
|
*/
|
||||||
|
protected static $_groups = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved newsletter groups found within
|
||||||
|
* static::getNewsletterGroups().
|
||||||
|
*/
|
||||||
|
protected static $_newsletterGroups = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved campaigns found within static::getCampaigns().
|
||||||
|
*/
|
||||||
|
protected static $_campaigns = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved financial types found within
|
||||||
|
* static::getFinancialTypes().
|
||||||
|
*/
|
||||||
|
protected static $_financialTypes = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved genders found within
|
||||||
|
* static::getGenderOptions().
|
||||||
|
*/
|
||||||
|
protected static $_genderOptions = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved location types found within
|
||||||
|
* static::getLocationTypes().
|
||||||
|
*/
|
||||||
|
protected static $_locationTypes = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved membership types found within
|
||||||
|
* static::getMembershipTypes().
|
||||||
|
*/
|
||||||
|
protected static $_membershipTypes = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* A static cache of retrieved CiviSEPA creditors found within
|
||||||
|
* static::getSepaCreditors().
|
||||||
|
*/
|
||||||
|
protected static $_sepaCreditors = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the form structure.
|
* Builds the form structure.
|
||||||
*/
|
*/
|
||||||
|
@ -59,10 +129,6 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
$profile_name = NULL;
|
$profile_name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign template variables.
|
|
||||||
$this->assign('op', $this->_op);
|
|
||||||
$this->assign('profile_name', $profile_name);
|
|
||||||
|
|
||||||
// Set redirect destination.
|
// Set redirect destination.
|
||||||
$this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1');
|
$this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1');
|
||||||
|
|
||||||
|
@ -88,6 +154,21 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
}
|
}
|
||||||
CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile <em>%1</em>', array(1 => $this->profile->getName())));
|
CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile <em>%1</em>', array(1 => $this->profile->getName())));
|
||||||
break;
|
break;
|
||||||
|
case 'copy':
|
||||||
|
// This will be a 'create' actually.
|
||||||
|
$this->_op = 'create';
|
||||||
|
|
||||||
|
// When copying without a valid profile name, copy the default profile.
|
||||||
|
if (!$profile_name) {
|
||||||
|
$profile_name = 'default';
|
||||||
|
$this->profile = CRM_Twingle_Profile::getProfile($profile_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a new name for this profile.
|
||||||
|
$profile_name = $profile_name . '_copy';
|
||||||
|
$this->profile->setName($profile_name);
|
||||||
|
CRM_Utils_System::setTitle(E::ts('New Twingle API profile'));
|
||||||
|
break;
|
||||||
case 'create':
|
case 'create':
|
||||||
// Load factory default profile values.
|
// Load factory default profile values.
|
||||||
$this->profile = CRM_twingle_Profile::createDefaultProfile($profile_name);
|
$this->profile = CRM_twingle_Profile::createDefaultProfile($profile_name);
|
||||||
|
@ -95,6 +176,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assign template variables.
|
||||||
|
$this->assign('op', $this->_op);
|
||||||
|
$this->assign('profile_name', $profile_name);
|
||||||
|
|
||||||
// Add form elements.
|
// Add form elements.
|
||||||
$is_default = $profile_name == 'default';
|
$is_default = $profile_name == 'default';
|
||||||
$this->add(
|
$this->add(
|
||||||
|
@ -109,7 +194,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'text', // field type
|
'text', // field type
|
||||||
'selector', // field name
|
'selector', // field name
|
||||||
E::ts('Project IDs'), // field label
|
E::ts('Project IDs'), // field label
|
||||||
array(),
|
['class' => 'huge'],
|
||||||
TRUE // is required
|
TRUE // is required
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -117,7 +202,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select',
|
'select',
|
||||||
'location_type_id',
|
'location_type_id',
|
||||||
E::ts('Location type'),
|
E::ts('Location type'),
|
||||||
$this->getLocationTypes(),
|
static::getLocationTypes(),
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -125,7 +210,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select',
|
'select',
|
||||||
'location_type_id_organisation',
|
'location_type_id_organisation',
|
||||||
E::ts('Location type for organisations'),
|
E::ts('Location type for organisations'),
|
||||||
$this->getLocationTypes(),
|
static::getLocationTypes(),
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -133,14 +218,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select', // field type
|
'select', // field type
|
||||||
'financial_type_id', // field name
|
'financial_type_id', // field name
|
||||||
E::ts('Financial type'), // field label
|
E::ts('Financial type'), // field label
|
||||||
$this->getFinancialTypes(), // list of options
|
static::getFinancialTypes(), // list of options
|
||||||
TRUE // is required
|
TRUE // is required
|
||||||
);
|
);
|
||||||
$this->add(
|
$this->add(
|
||||||
'select', // field type
|
'select', // field type
|
||||||
'financial_type_id_recur', // field name
|
'financial_type_id_recur', // field name
|
||||||
E::ts('Financial type (recurring)'), // field label
|
E::ts('Financial type (recurring)'), // field label
|
||||||
$this->getFinancialTypes(), // list of options
|
static::getFinancialTypes(), // list of options
|
||||||
TRUE // is required
|
TRUE // is required
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -148,21 +233,21 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select',
|
'select',
|
||||||
'gender_male',
|
'gender_male',
|
||||||
E::ts('Gender option for submitted value "male"'),
|
E::ts('Gender option for submitted value "male"'),
|
||||||
$this->getGenderOptions(),
|
static::getGenderOptions(),
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
$this->add(
|
$this->add(
|
||||||
'select',
|
'select',
|
||||||
'gender_female',
|
'gender_female',
|
||||||
E::ts('Gender option for submitted value "female"'),
|
E::ts('Gender option for submitted value "female"'),
|
||||||
$this->getGenderOptions(),
|
static::getGenderOptions(),
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
$this->add(
|
$this->add(
|
||||||
'select',
|
'select',
|
||||||
'gender_other',
|
'gender_other',
|
||||||
E::ts('Gender option for submitted value "other"'),
|
E::ts('Gender option for submitted value "other"'),
|
||||||
$this->getGenderOptions(),
|
static::getGenderOptions(),
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -173,9 +258,17 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select', // field type
|
'select', // field type
|
||||||
$pi_name, // field name
|
$pi_name, // field name
|
||||||
E::ts('Record %1 as', array(1 => $pi_label)), // field label
|
E::ts('Record %1 as', array(1 => $pi_label)), // field label
|
||||||
$this->getPaymentInstruments(), // list of options
|
static::getPaymentInstruments(), // list of options
|
||||||
TRUE // is required
|
TRUE // is required
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->add(
|
||||||
|
'select',
|
||||||
|
$pi_name . '_status',
|
||||||
|
E::ts('Record %1 donations with contribution status', array(1 => $pi_label)),
|
||||||
|
static::getContributionStatusOptions(),
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CRM_Twingle_Submission::civiSepaEnabled()) {
|
if (CRM_Twingle_Submission::civiSepaEnabled()) {
|
||||||
|
@ -183,7 +276,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select',
|
'select',
|
||||||
'sepa_creditor_id',
|
'sepa_creditor_id',
|
||||||
E::ts('CiviSEPA creditor'),
|
E::ts('CiviSEPA creditor'),
|
||||||
$this->getSepaCreditors(),
|
static::getSepaCreditors(),
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -192,7 +285,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select', // field type
|
'select', // field type
|
||||||
'newsletter_groups', // field name
|
'newsletter_groups', // field name
|
||||||
E::ts('Sign up for newsletter groups'), // field label
|
E::ts('Sign up for newsletter groups'), // field label
|
||||||
$this->getNewsletterGroups(), // list of options
|
static::getNewsletterGroups(), // list of options
|
||||||
FALSE, // is not required
|
FALSE, // is not required
|
||||||
array('class' => 'crm-select2 huge', 'multiple' => 'multiple')
|
array('class' => 'crm-select2 huge', 'multiple' => 'multiple')
|
||||||
);
|
);
|
||||||
|
@ -201,7 +294,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select', // field type
|
'select', // field type
|
||||||
'postinfo_groups', // field name
|
'postinfo_groups', // field name
|
||||||
E::ts('Sign up for postal mail groups'), // field label
|
E::ts('Sign up for postal mail groups'), // field label
|
||||||
$this->getPostinfoGroups(), // list of options
|
static::getPostinfoGroups(), // list of options
|
||||||
FALSE, // is not required
|
FALSE, // is not required
|
||||||
array('class' => 'crm-select2 huge', 'multiple' => 'multiple')
|
array('class' => 'crm-select2 huge', 'multiple' => 'multiple')
|
||||||
);
|
);
|
||||||
|
@ -210,7 +303,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select', // field type
|
'select', // field type
|
||||||
'donation_receipt_groups', // field name
|
'donation_receipt_groups', // field name
|
||||||
E::ts('Sign up for Donation receipt groups'), // field label
|
E::ts('Sign up for Donation receipt groups'), // field label
|
||||||
$this->getDonationReceiptGroups(), // list of options
|
static::getDonationReceiptGroups(), // list of options
|
||||||
FALSE, // is not required
|
FALSE, // is not required
|
||||||
array('class' => 'crm-select2 huge', 'multiple' => 'multiple')
|
array('class' => 'crm-select2 huge', 'multiple' => 'multiple')
|
||||||
);
|
);
|
||||||
|
@ -219,7 +312,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select', // field type
|
'select', // field type
|
||||||
'campaign', // field name
|
'campaign', // field name
|
||||||
E::ts('Assign donation to campaign'), // field label
|
E::ts('Assign donation to campaign'), // field label
|
||||||
array('' => E::ts('- none -')) + $this->getCampaigns(), // list of options
|
array('' => E::ts('- none -')) + static::getCampaigns(), // list of options
|
||||||
FALSE, // is not required
|
FALSE, // is not required
|
||||||
array('class' => 'crm-select2 huge')
|
array('class' => 'crm-select2 huge')
|
||||||
);
|
);
|
||||||
|
@ -228,7 +321,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'select', // field type
|
'select', // field type
|
||||||
'membership_type_id', // field name
|
'membership_type_id', // field name
|
||||||
E::ts('Create membership of type'), // field label
|
E::ts('Create membership of type'), // field label
|
||||||
array('' => E::ts('- none -')) + $this->getMembershipTypes(), // list of options
|
array('' => E::ts('- none -')) + static::getMembershipTypes(), // list of options
|
||||||
FALSE, // is not required
|
FALSE, // is not required
|
||||||
array('class' => 'crm-select2 huge')
|
array('class' => 'crm-select2 huge')
|
||||||
);
|
);
|
||||||
|
@ -240,6 +333,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
array()
|
array()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->add(
|
||||||
|
'textarea', // field type
|
||||||
|
'custom_field_mapping', // field name
|
||||||
|
E::ts('Custom field mapping'), // field label
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
|
||||||
$this->addButtons(array(
|
$this->addButtons(array(
|
||||||
array(
|
array(
|
||||||
'type' => 'submit',
|
'type' => 'submit',
|
||||||
|
@ -277,6 +377,69 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
$errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.');
|
$errors['name'] = E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate custom field mapping.
|
||||||
|
try {
|
||||||
|
if (isset($values['custom_field_mapping'])) {
|
||||||
|
$custom_field_mapping = preg_split('/\r\n|\r|\n/', $values['custom_field_mapping'], -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
if (!is_array($custom_field_mapping)) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts('Could not parse custom field mapping.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
foreach ($custom_field_mapping as $custom_field_map) {
|
||||||
|
$custom_field_map = explode("=", $custom_field_map);
|
||||||
|
if (count($custom_field_map) !== 2) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts('Could not parse custom field mapping.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
list($twingle_field_name, $custom_field_name) = $custom_field_map;
|
||||||
|
$custom_field_id = substr($custom_field_name, strlen('custom_'));
|
||||||
|
|
||||||
|
// Check for custom field existence
|
||||||
|
try {
|
||||||
|
$custom_field = civicrm_api3('CustomField', 'getsingle', array(
|
||||||
|
'id' => $custom_field_id,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (CiviCRM_API3_Exception $exception) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts(
|
||||||
|
'Custom field custom_%1 does not exist.',
|
||||||
|
array(1 => $custom_field_id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only allow custom fields on relevant entities.
|
||||||
|
try {
|
||||||
|
$custom_group = civicrm_api3('CustomGroup', 'getsingle', array(
|
||||||
|
'id' => $custom_field['custom_group_id'],
|
||||||
|
'extends' => array(
|
||||||
|
'IN' => array(
|
||||||
|
'Contact',
|
||||||
|
'Individual',
|
||||||
|
'Organization',
|
||||||
|
'Contribution',
|
||||||
|
'ContributionRecur',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
} catch (CiviCRM_API3_Exception $exception) {
|
||||||
|
throw new Exception(
|
||||||
|
E::ts(
|
||||||
|
'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.',
|
||||||
|
array(1 => $custom_field['id'])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $exception) {
|
||||||
|
$errors['custom_field_mapping'] = $exception->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return empty($errors) ? TRUE : $errors;
|
return empty($errors) ? TRUE : $errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,16 +488,18 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
*
|
*
|
||||||
* @throws \CiviCRM_API3_Exception
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getLocationTypes() {
|
public static function getLocationTypes() {
|
||||||
$location_types = array();
|
if (!isset(static::$_locationTypes)) {
|
||||||
|
static::$_locationTypes = array();
|
||||||
$query = civicrm_api3('LocationType', 'get', array(
|
$query = civicrm_api3('LocationType', 'get', array(
|
||||||
|
'option.limit' => 0,
|
||||||
'is_active' => 1,
|
'is_active' => 1,
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $type) {
|
foreach ($query['values'] as $type) {
|
||||||
$location_types[$type['id']] = $type['name'];
|
static::$_locationTypes[$type['id']] = $type['name'];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return $location_types;
|
return static::$_locationTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -345,17 +510,19 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
*
|
*
|
||||||
* @throws \CiviCRM_API3_Exception
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getFinancialTypes() {
|
public static function getFinancialTypes() {
|
||||||
$financial_types = array();
|
if (!isset(static::$_financialTypes)) {
|
||||||
|
static::$_financialTypes = array();
|
||||||
$query = civicrm_api3('FinancialType', 'get', array(
|
$query = civicrm_api3('FinancialType', 'get', array(
|
||||||
'is_active' => 1,
|
|
||||||
'option.limit' => 0,
|
'option.limit' => 0,
|
||||||
|
'is_active' => 1,
|
||||||
'return' => 'id,name'
|
'return' => 'id,name'
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $type) {
|
foreach ($query['values'] as $type) {
|
||||||
$financial_types[$type['id']] = $type['name'];
|
static::$_financialTypes[$type['id']] = $type['name'];
|
||||||
}
|
}
|
||||||
return $financial_types;
|
}
|
||||||
|
return static::$_financialTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -366,17 +533,19 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
*
|
*
|
||||||
* @throws \CiviCRM_API3_Exception
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getMembershipTypes() {
|
public static function getMembershipTypes() {
|
||||||
$membership_types = array();
|
if (!isset(static::$_membershipTypes)) {
|
||||||
|
static::$_membershipTypes = array();
|
||||||
$query = civicrm_api3('MembershipType', 'get', array(
|
$query = civicrm_api3('MembershipType', 'get', array(
|
||||||
'is_active' => 1,
|
|
||||||
'option.limit' => 0,
|
'option.limit' => 0,
|
||||||
|
'is_active' => 1,
|
||||||
'return' => 'id,name'
|
'return' => 'id,name'
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $type) {
|
foreach ($query['values'] as $type) {
|
||||||
$membership_types[$type['id']] = $type['name'];
|
static::$_membershipTypes[$type['id']] = $type['name'];
|
||||||
}
|
}
|
||||||
return $membership_types;
|
}
|
||||||
|
return static::$_membershipTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -387,21 +556,23 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
*
|
*
|
||||||
* @throws \CiviCRM_API3_Exception
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getGenderOptions() {
|
public static function getGenderOptions() {
|
||||||
$genders = array();
|
if (!isset(static::$_genderOptions)) {
|
||||||
|
static::$_genderOptions = array();
|
||||||
$query = civicrm_api3('OptionValue', 'get', array(
|
$query = civicrm_api3('OptionValue', 'get', array(
|
||||||
|
'option.limit' => 0,
|
||||||
'option_group_id' => 'gender',
|
'option_group_id' => 'gender',
|
||||||
'is_active' => 1,
|
'is_active' => 1,
|
||||||
'option.limit' => 0,
|
|
||||||
'return' => array(
|
'return' => array(
|
||||||
'value',
|
'value',
|
||||||
'label',
|
'label',
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $gender) {
|
foreach ($query['values'] as $gender) {
|
||||||
$genders[$gender['value']] = $gender['label'];
|
static::$_genderOptions[$gender['value']] = $gender['label'];
|
||||||
}
|
}
|
||||||
return $genders;
|
}
|
||||||
|
return static::$_genderOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -411,32 +582,36 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
*
|
*
|
||||||
* @throws \CiviCRM_API3_Exception
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getSepaCreditors() {
|
public static function getSepaCreditors() {
|
||||||
$creditors = array();
|
if (!isset(static::$_sepaCreditors)) {
|
||||||
|
static::$_sepaCreditors = array();
|
||||||
if (CRM_Twingle_Submission::civiSepaEnabled()) {
|
if (CRM_Twingle_Submission::civiSepaEnabled()) {
|
||||||
$result = civicrm_api3('SepaCreditor', 'get', array(
|
$result = civicrm_api3('SepaCreditor', 'get', array(
|
||||||
'option.limit' => 0,
|
'option.limit' => 0,
|
||||||
));
|
));
|
||||||
foreach ($result['values'] as $sepa_creditor) {
|
foreach ($result['values'] as $sepa_creditor) {
|
||||||
$creditors[$sepa_creditor['id']] = $sepa_creditor['name'];
|
static::$_sepaCreditors[$sepa_creditor['id']] = $sepa_creditor['name'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return $creditors;
|
return static::$_sepaCreditors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves payment instruments present within the system as options for
|
* Retrieves payment instruments present within the system as options for
|
||||||
* select form elements.
|
* select form elements.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getPaymentInstruments() {
|
public static function getPaymentInstruments() {
|
||||||
if (!isset(self::$_paymentInstruments)) {
|
if (!isset(self::$_paymentInstruments)) {
|
||||||
self::$_paymentInstruments = array();
|
self::$_paymentInstruments = array();
|
||||||
$query = civicrm_api3('OptionValue', 'get', array(
|
$query = civicrm_api3('OptionValue', 'get', array(
|
||||||
|
'option.limit' => 0,
|
||||||
'option_group_id' => 'payment_instrument',
|
'option_group_id' => 'payment_instrument',
|
||||||
'is_active' => 1,
|
'is_active' => 1,
|
||||||
'option.limit' => 0,
|
|
||||||
'return' => 'value,label'
|
'return' => 'value,label'
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $payment_instrument) {
|
foreach ($query['values'] as $payment_instrument) {
|
||||||
|
@ -471,13 +646,49 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
return self::$_paymentInstruments;
|
return self::$_paymentInstruments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves contribution statuses as options for select form elements.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \CiviCRM_API3_Exception
|
||||||
|
*/
|
||||||
|
public static function getContributionStatusOptions() {
|
||||||
|
if (!isset(self::$_contributionStatusOptions)) {
|
||||||
|
$query = civicrm_api3(
|
||||||
|
'OptionValue',
|
||||||
|
'get',
|
||||||
|
array(
|
||||||
|
'option.limit' => 0,
|
||||||
|
'option_group_id' => 'contribution_status',
|
||||||
|
'return' => array(
|
||||||
|
'value',
|
||||||
|
'label',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($query['values'] as $contribution_status) {
|
||||||
|
self::$_contributionStatusOptions[$contribution_status['value']] = $contribution_status['label'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$_contributionStatusOptions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves active groups used as mailing lists within the system as options
|
* Retrieves active groups used as mailing lists within the system as options
|
||||||
* for select form elements.
|
* for select form elements.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getNewsletterGroups() {
|
public static function getNewsletterGroups() {
|
||||||
$groups = array();
|
if (!isset(static::$_newsletterGroups)) {
|
||||||
|
static::$_newsletterGroups = array();
|
||||||
$group_types = civicrm_api3('OptionValue', 'get', array(
|
$group_types = civicrm_api3('OptionValue', 'get', array(
|
||||||
|
'option.limit' => 0,
|
||||||
'option_group_id' => 'group_type',
|
'option_group_id' => 'group_type',
|
||||||
'name' => CRM_Twingle_Submission::GROUP_TYPE_NEWSLETTER,
|
'name' => CRM_Twingle_Submission::GROUP_TYPE_NEWSLETTER,
|
||||||
));
|
));
|
||||||
|
@ -490,52 +701,72 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
'return' => 'id,name'
|
'return' => 'id,name'
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $group) {
|
foreach ($query['values'] as $group) {
|
||||||
$groups[$group['id']] = $group['name'];
|
static::$_newsletterGroups[$group['id']] = $group['name'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$groups[''] = E::ts('No mailing lists available');
|
static::$_newsletterGroups[''] = E::ts('No mailing lists available');
|
||||||
}
|
}
|
||||||
return $groups;
|
}
|
||||||
|
return static::$_newsletterGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves active groups as options for select form elements.
|
* Retrieves active groups as options for select form elements.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getGroups() {
|
public static function getGroups() {
|
||||||
$groups = array();
|
if (!isset(static::$_groups)) {
|
||||||
|
static::$_groups = array();
|
||||||
$query = civicrm_api3('Group', 'get', array(
|
$query = civicrm_api3('Group', 'get', array(
|
||||||
'is_active' => 1,
|
|
||||||
'option.limit' => 0,
|
'option.limit' => 0,
|
||||||
|
'is_active' => 1,
|
||||||
'return' => 'id,name'
|
'return' => 'id,name'
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $group) {
|
foreach ($query['values'] as $group) {
|
||||||
$groups[$group['id']] = $group['name'];
|
static::$_groups[$group['id']] = $group['name'];
|
||||||
}
|
}
|
||||||
return $groups;
|
}
|
||||||
|
return static::$_groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves active groups used as postal mailing lists within the system as
|
* Retrieves active groups used as postal mailing lists within the system as
|
||||||
* options for select form elements.
|
* options for select form elements.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getPostinfoGroups() {
|
public static function getPostinfoGroups() {
|
||||||
return $this->getGroups();
|
return static::getGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves active groups used as donation receipt requester lists within the
|
* Retrieves active groups used as donation receipt requester lists within the
|
||||||
* system as options for select form elements.
|
* system as options for select form elements.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getDonationReceiptGroups() {
|
public static function getDonationReceiptGroups() {
|
||||||
return $this->getGroups();
|
return static::getGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves campaigns as options for select elements.
|
* Retrieves campaigns as options for select elements.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \CiviCRM_API3_Exception
|
||||||
*/
|
*/
|
||||||
public function getCampaigns() {
|
public static function getCampaigns() {
|
||||||
$campaigns = array();
|
if (!isset(static::$_campaigns)) {
|
||||||
|
static::$_campaigns = array();
|
||||||
$query = civicrm_api3('Campaign', 'get', array(
|
$query = civicrm_api3('Campaign', 'get', array(
|
||||||
'option.limit' => 0,
|
'option.limit' => 0,
|
||||||
'return' => array(
|
'return' => array(
|
||||||
|
@ -544,9 +775,10 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
foreach ($query['values'] as $campaign) {
|
foreach ($query['values'] as $campaign) {
|
||||||
$campaigns[$campaign['id']] = $campaign['title'];
|
static::$_campaigns[$campaign['id']] = $campaign['title'];
|
||||||
}
|
}
|
||||||
return $campaigns;
|
}
|
||||||
|
return static::$_campaigns;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,21 @@ class CRM_Twingle_Profile {
|
||||||
return in_array($project_id, $project_ids);
|
return in_array($project_id, $project_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* The profile's configured custom field mapping
|
||||||
|
*/
|
||||||
|
public function getCustomFieldMapping() {
|
||||||
|
$custom_field_mapping = array();
|
||||||
|
if (!empty($custom_field_definition = $this->getAttribute('custom_field_mapping'))) {
|
||||||
|
foreach (preg_split('/\r\n|\r|\n/', $custom_field_definition, -1, PREG_SPLIT_NO_EMPTY) as $custom_field_map) {
|
||||||
|
list($twingle_field_name, $custom_field_name) = explode("=", $custom_field_map);
|
||||||
|
$custom_field_mapping[$twingle_field_name] = $custom_field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $custom_field_mapping;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all data attributes of the profile.
|
* Retrieves all data attributes of the profile.
|
||||||
*
|
*
|
||||||
|
@ -100,15 +115,16 @@ class CRM_Twingle_Profile {
|
||||||
* Retrieves an attribute of the profile.
|
* Retrieves an attribute of the profile.
|
||||||
*
|
*
|
||||||
* @param string $attribute_name
|
* @param string $attribute_name
|
||||||
|
* @param mixed $default
|
||||||
*
|
*
|
||||||
* @return mixed | NULL
|
* @return mixed | NULL
|
||||||
*/
|
*/
|
||||||
public function getAttribute($attribute_name) {
|
public function getAttribute($attribute_name, $default = NULL) {
|
||||||
if (isset($this->data[$attribute_name])) {
|
if (isset($this->data[$attribute_name])) {
|
||||||
return $this->data[$attribute_name];
|
return $this->data[$attribute_name];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return NULL;
|
return $default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +145,21 @@ class CRM_Twingle_Profile {
|
||||||
$this->data[$attribute_name] = $value;
|
$this->data[$attribute_name] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the CiviCRM transaction ID (to be used in contributions and recurring contributions)
|
||||||
|
*
|
||||||
|
* @param $twingle_id string Twingle ID
|
||||||
|
* @return string CiviCRM transaction ID
|
||||||
|
*/
|
||||||
|
public function getTransactionID($twingle_id) {
|
||||||
|
$prefix = Civi::settings()->get('twingle_prefix');
|
||||||
|
if (empty($prefix)) {
|
||||||
|
return $twingle_id;
|
||||||
|
} else {
|
||||||
|
return $prefix . $twingle_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies whether the profile is valid (i.e. consistent and not colliding
|
* Verifies whether the profile is valid (i.e. consistent and not colliding
|
||||||
* with other profiles).
|
* with other profiles).
|
||||||
|
@ -165,23 +196,13 @@ class CRM_Twingle_Profile {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function allowedAttributes() {
|
public static function allowedAttributes() {
|
||||||
return array(
|
return array_merge(
|
||||||
|
array(
|
||||||
'selector',
|
'selector',
|
||||||
'location_type_id',
|
'location_type_id',
|
||||||
'location_type_id_organisation',
|
'location_type_id_organisation',
|
||||||
'financial_type_id',
|
'financial_type_id',
|
||||||
'financial_type_id_recur',
|
'financial_type_id_recur',
|
||||||
'pi_banktransfer',
|
|
||||||
'pi_debit_manual',
|
|
||||||
'pi_debit_automatic',
|
|
||||||
'pi_creditcard',
|
|
||||||
'pi_mobilephone_germany',
|
|
||||||
'pi_paypal',
|
|
||||||
'pi_sofortueberweisung',
|
|
||||||
'pi_amazonpay',
|
|
||||||
'pi_paydirekt',
|
|
||||||
'pi_applepay',
|
|
||||||
'pi_googlepay',
|
|
||||||
'sepa_creditor_id',
|
'sepa_creditor_id',
|
||||||
'gender_male',
|
'gender_male',
|
||||||
'gender_female',
|
'gender_female',
|
||||||
|
@ -191,7 +212,16 @@ class CRM_Twingle_Profile {
|
||||||
'donation_receipt_groups',
|
'donation_receipt_groups',
|
||||||
'campaign',
|
'campaign',
|
||||||
'contribution_source',
|
'contribution_source',
|
||||||
|
'custom_field_mapping',
|
||||||
'membership_type_id',
|
'membership_type_id',
|
||||||
|
),
|
||||||
|
// Add payment methods.
|
||||||
|
array_keys(static::paymentInstruments()),
|
||||||
|
|
||||||
|
// Add contribution status for all payment methods.
|
||||||
|
array_map(function ($attribute) {
|
||||||
|
return $attribute . '_status';
|
||||||
|
}, array_keys(static::paymentInstruments()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +281,13 @@ class CRM_Twingle_Profile {
|
||||||
'donation_receipt_groups' => NULL,
|
'donation_receipt_groups' => NULL,
|
||||||
'campaign' => NULL,
|
'campaign' => NULL,
|
||||||
'contribution_source' => NULL,
|
'contribution_source' => NULL,
|
||||||
|
'custom_field_mapping' => NULL,
|
||||||
'membership_type_id' => NULL,
|
'membership_type_id' => NULL,
|
||||||
));
|
)
|
||||||
|
// Add contribution status for all payment methods.
|
||||||
|
+ array_fill_keys(array_map(function($attribute) {
|
||||||
|
return $attribute . '_status';
|
||||||
|
}, array_keys(static::paymentInstruments())), CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,16 +302,14 @@ class CRM_Twingle_Profile {
|
||||||
public static function getProfileForProject($project_id) {
|
public static function getProfileForProject($project_id) {
|
||||||
$profiles = self::getProfiles();
|
$profiles = self::getProfiles();
|
||||||
|
|
||||||
// If none matches, use the default profile.
|
|
||||||
$profile = $profiles['default'];
|
|
||||||
|
|
||||||
foreach ($profiles as $profile) {
|
foreach ($profiles as $profile) {
|
||||||
if ($profile->matches($project_id)) {
|
if ($profile->matches($project_id)) {
|
||||||
break;
|
return $profile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $profile;
|
// If none matches, use the default profile.
|
||||||
|
return $profiles['default'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -305,7 +338,7 @@ class CRM_Twingle_Profile {
|
||||||
public static function getProfiles() {
|
public static function getProfiles() {
|
||||||
if (self::$_profiles === NULL) {
|
if (self::$_profiles === NULL) {
|
||||||
self::$_profiles = array();
|
self::$_profiles = array();
|
||||||
if ($profiles_data = CRM_Core_BAO_Setting::getItem('de.systopia.twingle', 'twingle_profiles')) {
|
if ($profiles_data = Civi::settings()->get('twingle_profiles')) {
|
||||||
foreach ($profiles_data as $profile_name => $profile_data) {
|
foreach ($profiles_data as $profile_name => $profile_data) {
|
||||||
self::$_profiles[$profile_name] = new CRM_Twingle_Profile($profile_name, $profile_data);
|
self::$_profiles[$profile_name] = new CRM_Twingle_Profile($profile_name, $profile_data);
|
||||||
}
|
}
|
||||||
|
@ -330,6 +363,6 @@ class CRM_Twingle_Profile {
|
||||||
foreach (self::$_profiles as $profile_name => $profile) {
|
foreach (self::$_profiles as $profile_name => $profile) {
|
||||||
$profile_data[$profile_name] = $profile->data;
|
$profile_data[$profile_name] = $profile->data;
|
||||||
}
|
}
|
||||||
CRM_Core_BAO_Setting::setItem((object) $profile_data, 'de.systopia.twingle', 'twingle_profiles');
|
Civi::settings()->set('twingle_profiles', $profile_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@ class CRM_Twingle_Submission {
|
||||||
*/
|
*/
|
||||||
const GROUP_TYPE_NEWSLETTER = 'Mailing List';
|
const GROUP_TYPE_NEWSLETTER = 'Mailing List';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The option value for the contribution type for completed contributions.
|
||||||
|
*/
|
||||||
|
const CONTRIBUTION_STATUS_COMPLETED = 'Completed';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default ID of the "Employer of" relationship type.
|
* The default ID of the "Employer of" relationship type.
|
||||||
*/
|
*/
|
||||||
|
@ -99,6 +104,16 @@ class CRM_Twingle_Submission {
|
||||||
}
|
}
|
||||||
$params['gender_id'] = $gender_id;
|
$params['gender_id'] = $gender_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate custom fields parameter, if given.
|
||||||
|
if (!empty($params['custom_fields'])) {
|
||||||
|
if (!is_array($custom_fields = json_decode($params['custom_fields'], TRUE))) {
|
||||||
|
throw new CiviCRM_API3_Exception(
|
||||||
|
E::ts('Invalid format for custom fields.'),
|
||||||
|
'invalid_format'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,10 +269,7 @@ class CRM_Twingle_Submission {
|
||||||
'is_active' => 1,
|
'is_active' => 1,
|
||||||
));
|
));
|
||||||
return
|
return
|
||||||
CRM_Core_BAO_Setting::getItem(
|
Civi::settings()->get('twingle_use_sepa')
|
||||||
'de.systopia.twingle',
|
|
||||||
'twingle_use_sepa'
|
|
||||||
)
|
|
||||||
&& $sepa_extension['count'];
|
&& $sepa_extension['count'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
94
CRM/Twingle/Tools.php
Normal file
94
CRM/Twingle/Tools.php
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
/*------------------------------------------------------------+
|
||||||
|
| SYSTOPIA Twingle Integration |
|
||||||
|
| Copyright (C) 2019 SYSTOPIA |
|
||||||
|
| Author: B. Endres (endres@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). |
|
||||||
|
+-------------------------------------------------------------*/
|
||||||
|
|
||||||
|
use CRM_Twingle_ExtensionUtil as E;
|
||||||
|
|
||||||
|
class CRM_Twingle_Tools {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This flag can be used to temporarily suspend twingle protection
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public static $protection_suspended = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the attempted modification of the recurring contribution is allowed.
|
||||||
|
* If not, an exception will be raised
|
||||||
|
*
|
||||||
|
* @param $recurring_contribution_id int
|
||||||
|
* @param $change array
|
||||||
|
* @throws Exception if the change is not allowed
|
||||||
|
*/
|
||||||
|
public static function checkRecurringContributionChange($recurring_contribution_id, $change) {
|
||||||
|
// check if a change to the status is planned
|
||||||
|
if (empty($change['contribution_status_id'])) return;
|
||||||
|
|
||||||
|
// check if the target status is not closed
|
||||||
|
if (in_array($change['contribution_status_id'], [2,5])) return;
|
||||||
|
|
||||||
|
// check if we're suspended
|
||||||
|
if (self::$protection_suspended) return;
|
||||||
|
|
||||||
|
// currently only works with prefixes
|
||||||
|
$prefix = Civi::settings()->get('twingle_prefix');
|
||||||
|
if (empty($prefix)) return;
|
||||||
|
|
||||||
|
// check if protection is turned on
|
||||||
|
$protection_on = Civi::settings()->get('twingle_protect_recurring');
|
||||||
|
if (empty($protection_on)) return;
|
||||||
|
|
||||||
|
// load the recurring contribution
|
||||||
|
$recurring_contribution = civicrm_api3('ContributionRecur', 'getsingle', [
|
||||||
|
'return' => 'trxn_id,contribution_status_id,payment_instrument_id',
|
||||||
|
'id' => $recurring_contribution_id]);
|
||||||
|
|
||||||
|
// check if this is a SEPA transaction
|
||||||
|
//if (self::isSDD($recurring_contribution['payment_instrument_id'])) return;
|
||||||
|
|
||||||
|
// check if it's really a termination (i.e. current status is 2 or 5)
|
||||||
|
if (!in_array($recurring_contribution['contribution_status_id'], [2,5])) return;
|
||||||
|
|
||||||
|
// check if it's a Twingle contribution
|
||||||
|
if (substr($recurring_contribution['trxn_id'], 0, strlen($prefix)) == $prefix) {
|
||||||
|
// this is a Twingle contribution that is about to be terminated
|
||||||
|
throw new Exception(E::ts("This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given payment instrument is SEPA
|
||||||
|
*
|
||||||
|
* @param $payment_instrument_id string payment instrument
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function isSDD($payment_instrument_id) {
|
||||||
|
static $sepa_payment_instruments = NULL;
|
||||||
|
if ($sepa_payment_instruments === NULL) {
|
||||||
|
// init with instrument names
|
||||||
|
$sepa_payment_instruments = ['FRST', 'RCUR', 'OOFF'];
|
||||||
|
|
||||||
|
// lookup and add instrument IDs
|
||||||
|
$lookup = civicrm_api3('OptionValue', 'get', [
|
||||||
|
'option_group_id' => 'payment_instrument',
|
||||||
|
'name' => ['IN' => $sepa_payment_instruments],
|
||||||
|
'return' => 'value'
|
||||||
|
]);
|
||||||
|
foreach ($lookup['values'] as $payment_instrument) {
|
||||||
|
$sepa_payment_instruments[] = $payment_instrument['value'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return in_array($payment_instrument_id, $sepa_payment_instruments);
|
||||||
|
}
|
||||||
|
}
|
|
@ -143,4 +143,24 @@ class CRM_Twingle_Upgrader extends CRM_Twingle_Upgrader_Base {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert serialized settings from objects to arrays.
|
||||||
|
*
|
||||||
|
* @link https://civicrm.org/advisory/civi-sa-2019-21-poi-saved-search-and-report-instance-apis
|
||||||
|
*/
|
||||||
|
public function upgrade_5011() {
|
||||||
|
// Do not use CRM_Core_BAO::getItem() or Civi::settings()->get().
|
||||||
|
// Extract and unserialize directly from the database.
|
||||||
|
$twingle_profiles_query = CRM_Core_DAO::executeQuery("
|
||||||
|
SELECT `value`
|
||||||
|
FROM `civicrm_setting`
|
||||||
|
WHERE `name` = 'twingle_profiles';");
|
||||||
|
if ($twingle_profiles_query->fetch()) {
|
||||||
|
$profiles = unserialize($twingle_profiles_query->value);
|
||||||
|
Civi::settings()->set('twingle_profiles', (array) $profiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
13
README.md
13
README.md
|
@ -13,6 +13,11 @@ The extension is licensed under
|
||||||
|
|
||||||
*This section is yet to be completed.*
|
*This section is yet to be completed.*
|
||||||
|
|
||||||
|
### Configure Extended Contact Matcher (XCM)
|
||||||
|
|
||||||
|
Make sure you use an XCM profile with the option *Match contacts by contact ID*
|
||||||
|
enabled.
|
||||||
|
|
||||||
### Configure CiviCRM
|
### Configure CiviCRM
|
||||||
|
|
||||||
- Go to the Administration console `/civicrm/admin`
|
- Go to the Administration console `/civicrm/admin`
|
||||||
|
@ -37,17 +42,21 @@ project ID from any other profile. Therefore the default profile will be used
|
||||||
for all newly created Twingle projects.
|
for all newly created Twingle projects.
|
||||||
|
|
||||||
| Label | Description |
|
| Label | Description |
|
||||||
|---------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Profile name | Internal name, used inside the extension. |
|
| Profile name | Internal name, used inside the extension. |
|
||||||
| Project IDs | Twingle project IDs. Separate multiple IDs with commas. |
|
| Project IDs | Twingle project IDs. Separate multiple IDs with commas. |
|
||||||
| Location type | Specify how the address data sent by the form should be categorised in CiviCRM. The list is based on your CiviCRM configuration. |
|
| Location type | Specify how the address data sent by the form should be categorised in CiviCRM. The list is based on your CiviCRM configuration. |
|
||||||
| Location type for organisations | Specify how the address data sent by the form should be categorised in CiviCRM for organisational donations. The list is based on your CiviCRM configuration. |
|
| Location type for organisations | Specify how the address data sent by the form should be categorised in CiviCRM for organisational donations. The list is based on your CiviCRM configuration. |
|
||||||
| Financial type | Specify which financial type incoming one-time donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. |
|
| Financial type | Specify which financial type incoming one-time donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. |
|
||||||
| Financial type (recurring) | Specify which financial type incoming recurring donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. |
|
| Financial type (recurring) | Specify which financial type incoming recurring donations should be recorded with in CiviCRM. The list is based on your CiviCRM configuration. |
|
||||||
|
| CiviSEPA creditor | When enabled to integrate with CiviSEPA, specify the CiviSEPA creditor to use. |
|
||||||
| Gender options | Specify which CiviCRM gender option the incoming Twingle gender value should be mapped to. The list is based on your CiviCRM configuration. |
|
| Gender options | Specify which CiviCRM gender option the incoming Twingle gender value should be mapped to. The list is based on your CiviCRM configuration. |
|
||||||
| Record *Payment method* as | Specifiy the payment methods mapping for incoming donations for each Twingle payment method. |
|
| Record *Payment method* as | Specifiy the payment methods mapping for incoming donations for each Twingle payment method. |
|
||||||
| CiviSEPA creditor | When enabled to integrate with CiviSEPA, specify the CiviSEPA creditor to use. |
|
|
||||||
| Sign up for groups | Whenever the donor checked the newsletter/postal mailing/donation receipt checkbox on the Twingle form, the contact will be added to the groups listed here. |
|
| Sign up for groups | Whenever the donor checked the newsletter/postal mailing/donation receipt checkbox on the Twingle form, the contact will be added to the groups listed here. |
|
||||||
|
| Assign donation to campaign | The donation will be assigned to the selected campaign. If a campaign ID is being submitted using the `campaign_id` parameter, this setting will be overridden with the submitted value. |
|
||||||
|
| Create membership of type | A membership of the selected type will be created for the Individual contact. If no membership type is selected, no membership will be created. |
|
||||||
|
| Contribution source | The configured value will be set as the "Source" field for the contribution. |
|
||||||
|
| Custom field mapping | Additional field values may be set to CiviCRM custom fields using a mapping. See the option's help text for the exact format. |
|
||||||
|
|
||||||
|
|
||||||
## API documentation
|
## API documentation
|
||||||
|
|
|
@ -80,15 +80,16 @@ function civicrm_api3_twingle_donation_Cancel($params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve (recurring) contribution.
|
// Retrieve (recurring) contribution.
|
||||||
|
$default_profile = CRM_Twingle_Profile::getProfile('default');
|
||||||
try {
|
try {
|
||||||
$contribution = civicrm_api3('Contribution', 'getsingle', array(
|
$contribution = civicrm_api3('Contribution', 'getsingle', array(
|
||||||
'trxn_id' => $params['trx_id'],
|
'trxn_id' => $default_profile->getTransactionID($params['trx_id']),
|
||||||
));
|
));
|
||||||
$contribution_type = 'Contribution';
|
$contribution_type = 'Contribution';
|
||||||
}
|
}
|
||||||
catch (CiviCRM_API3_Exception $exception) {
|
catch (CiviCRM_API3_Exception $exception) {
|
||||||
$contribution = civicrm_api3('ContributionRecur', 'getsingle', array(
|
$contribution = civicrm_api3('ContributionRecur', 'getsingle', array(
|
||||||
'trxn_id' => $params['trx_id'],
|
'trxn_id' => $default_profile->getTransactionID($params['trx_id']),
|
||||||
));
|
));
|
||||||
$contribution_type = 'ContributionRecur';
|
$contribution_type = 'ContributionRecur';
|
||||||
}
|
}
|
||||||
|
@ -121,12 +122,14 @@ function civicrm_api3_twingle_donation_Cancel($params) {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
CRM_Twingle_Tools::$protection_suspended = TRUE;
|
||||||
$contribution = civicrm_api3($contribution_type, 'create', array(
|
$contribution = civicrm_api3($contribution_type, 'create', array(
|
||||||
'id' => $contribution['id'],
|
'id' => $contribution['id'],
|
||||||
'cancel_date' => $params['cancelled_at'],
|
'cancel_date' => $params['cancelled_at'],
|
||||||
'contribution_status_id' => 'Cancelled',
|
'contribution_status_id' => 'Cancelled',
|
||||||
'cancel_reason' => $params['cancel_reason'],
|
'cancel_reason' => $params['cancel_reason'],
|
||||||
));
|
));
|
||||||
|
CRM_Twingle_Tools::$protection_suspended = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = civicrm_api3_create_success($contribution);
|
$result = civicrm_api3_create_success($contribution);
|
||||||
|
|
|
@ -72,8 +72,9 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$default_profile = CRM_Twingle_Profile::getProfile('default');
|
||||||
$contribution = civicrm_api3('ContributionRecur', 'getsingle', array(
|
$contribution = civicrm_api3('ContributionRecur', 'getsingle', array(
|
||||||
'trxn_id' => $params['trx_id'],
|
'trxn_id' => $default_profile->getTransactionID($params['trx_id']),
|
||||||
));
|
));
|
||||||
// End SEPA mandate (which ends the associated recurring contribution) or
|
// End SEPA mandate (which ends the associated recurring contribution) or
|
||||||
// recurring contributions.
|
// recurring contributions.
|
||||||
|
@ -87,6 +88,16 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
||||||
time(),
|
time(),
|
||||||
date_create_from_format('Ymd', $params['cancelled_at'])->getTimestamp()
|
date_create_from_format('Ymd', $params['cancelled_at'])->getTimestamp()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// verify that the mandate has not been terminated in the past
|
||||||
|
$mandate_status = civicrm_api3('SepaMandate', 'getvalue', ['return' => 'status', 'id' => $mandate_id]);
|
||||||
|
if ($mandate_status != 'FRST' && $mandate_status != 'RCUR') {
|
||||||
|
throw new CiviCRM_API3_Exception(
|
||||||
|
E::ts("SEPA Mandate [%1] already terminated.", [1 => $mandate_id]),
|
||||||
|
'api_error'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!CRM_Sepa_BAO_SEPAMandate::terminateMandate(
|
if (!CRM_Sepa_BAO_SEPAMandate::terminateMandate(
|
||||||
$mandate_id,
|
$mandate_id,
|
||||||
$end_date,
|
$end_date,
|
||||||
|
@ -102,11 +113,13 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
CRM_Twingle_Tools::$protection_suspended = TRUE;
|
||||||
$contribution = civicrm_api3('ContributionRecur', 'create', array(
|
$contribution = civicrm_api3('ContributionRecur', 'create', array(
|
||||||
'id' => $contribution['id'],
|
'id' => $contribution['id'],
|
||||||
'end_date' => $params['ended_at'],
|
'end_date' => $params['ended_at'],
|
||||||
'contribution_status_id' => 'Completed',
|
'contribution_status_id' => CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED,
|
||||||
));
|
));
|
||||||
|
CRM_Twingle_Tools::$protection_suspended = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = civicrm_api3_create_success($contribution);
|
$result = civicrm_api3_create_success($contribution);
|
||||||
|
|
|
@ -238,6 +238,13 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) {
|
||||||
'api.required' => 0,
|
'api.required' => 0,
|
||||||
'description' => E::ts('The CiviCRM ID of a campaign to assign the contribution.'),
|
'description' => E::ts('The CiviCRM ID of a campaign to assign the contribution.'),
|
||||||
);
|
);
|
||||||
|
$params['custom_fields'] = array(
|
||||||
|
'name' => 'custom_fields',
|
||||||
|
'title' => E::ts('Custom fields'),
|
||||||
|
'type' => CRM_Utils_Type::T_STRING,
|
||||||
|
'api.required' => 0,
|
||||||
|
'description' => E::ts('Additional information for either the contact or the (recurring) contribution.'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -271,10 +278,10 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
// Do not process an already existing contribution with the given
|
// Do not process an already existing contribution with the given
|
||||||
// transaction ID.
|
// transaction ID.
|
||||||
$existing_contribution = civicrm_api3('Contribution', 'get', array(
|
$existing_contribution = civicrm_api3('Contribution', 'get', array(
|
||||||
'trxn_id' => $params['trx_id']
|
'trxn_id' => $profile->getTransactionID($params['trx_id'])
|
||||||
));
|
));
|
||||||
$existing_contribution_recur = civicrm_api3('ContributionRecur', 'get', array(
|
$existing_contribution_recur = civicrm_api3('ContributionRecur', 'get', array(
|
||||||
'trxn_id' => $params['trx_id']
|
'trxn_id' => $profile->getTransactionID($params['trx_id'])
|
||||||
));
|
));
|
||||||
if ($existing_contribution['count'] > 0 || $existing_contribution_recur['count'] > 0) {
|
if ($existing_contribution['count'] > 0 || $existing_contribution_recur['count'] > 0) {
|
||||||
throw new CiviCRM_API3_Exception(
|
throw new CiviCRM_API3_Exception(
|
||||||
|
@ -283,6 +290,27 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract custom field values using the profile's mapping of Twingle fields
|
||||||
|
// to CiviCRM custom fields.
|
||||||
|
$custom_fields = array();
|
||||||
|
if (!empty($params['custom_fields'])) {
|
||||||
|
$custom_field_mapping = $profile->getCustomFieldMapping();
|
||||||
|
|
||||||
|
foreach (json_decode($params['custom_fields']) as $twingle_field => $value) {
|
||||||
|
if (isset($custom_field_mapping[$twingle_field])) {
|
||||||
|
// Get custom field definition to store values by entity the field
|
||||||
|
// extends.
|
||||||
|
$custom_field_id = substr($custom_field_mapping[$twingle_field], strlen('custom_'));
|
||||||
|
$custom_field = civicrm_api3('CustomField', 'getsingle', array(
|
||||||
|
'id' => $custom_field_id,
|
||||||
|
// Chain a CustomGroup.getsingle API call.
|
||||||
|
'api.CustomGroup.getsingle' => array(),
|
||||||
|
));
|
||||||
|
$custom_fields[$custom_field['api.CustomGroup.getsingle']['extends']][$custom_field_mapping[$twingle_field]] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create contact(s).
|
// Create contact(s).
|
||||||
if ($params['is_anonymous']) {
|
if ($params['is_anonymous']) {
|
||||||
// Retrieve the ID of the contact to use for anonymous donations defined
|
// Retrieve the ID of the contact to use for anonymous donations defined
|
||||||
|
@ -349,11 +377,21 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
'user_email' => 'email',
|
'user_email' => 'email',
|
||||||
'user_telephone' => 'phone',
|
'user_telephone' => 'phone',
|
||||||
'user_title' => 'formal_title',
|
'user_title' => 'formal_title',
|
||||||
|
'debit_iban' => 'iban',
|
||||||
) as $contact_param => $contact_component) {
|
) as $contact_param => $contact_component) {
|
||||||
if (!empty($params[$contact_param])) {
|
if (!empty($params[$contact_param])) {
|
||||||
$contact_data[$contact_component] = $params[$contact_param];
|
$contact_data[$contact_component] = $params[$contact_param];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['Contact'])) {
|
||||||
|
$contact_data += $custom_fields['Contact'];
|
||||||
|
}
|
||||||
|
if (!empty($custom_fields['Individual'])) {
|
||||||
|
$contact_data += $custom_fields['Individual'];
|
||||||
|
}
|
||||||
|
|
||||||
if (!$contact_id = CRM_Twingle_Submission::getContact(
|
if (!$contact_id = CRM_Twingle_Submission::getContact(
|
||||||
'Individual',
|
'Individual',
|
||||||
$contact_data
|
$contact_data
|
||||||
|
@ -378,6 +416,12 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
$organisation_data = array(
|
$organisation_data = array(
|
||||||
'organization_name' => $params['organization_name'],
|
'organization_name' => $params['organization_name'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['Organization'])) {
|
||||||
|
$organisation_data += $custom_fields['Organization'];
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($submitted_address)) {
|
if (!empty($submitted_address)) {
|
||||||
$organisation_data += $submitted_address;
|
$organisation_data += $submitted_address;
|
||||||
// Use configured location type for organisation address.
|
// Use configured location type for organisation address.
|
||||||
|
@ -467,12 +511,17 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
$contribution_data = array(
|
$contribution_data = array(
|
||||||
'contact_id' => (isset($organisation_id) ? $organisation_id : $contact_id),
|
'contact_id' => (isset($organisation_id) ? $organisation_id : $contact_id),
|
||||||
'currency' => $params['currency'],
|
'currency' => $params['currency'],
|
||||||
'trxn_id' => $params['trx_id'],
|
'trxn_id' => $profile->getTransactionID($params['trx_id']),
|
||||||
'payment_instrument_id' => $params['payment_instrument_id'],
|
'payment_instrument_id' => $params['payment_instrument_id'],
|
||||||
'amount' => $params['amount'] / 100,
|
'amount' => $params['amount'] / 100,
|
||||||
'total_amount' => $params['amount'] / 100,
|
'total_amount' => $params['amount'] / 100,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['Contribution'])) {
|
||||||
|
$contribution_data += $custom_fields['Contribution'];
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($params['purpose'])) {
|
if (!empty($params['purpose'])) {
|
||||||
$contribution_data['note'] = $params['purpose'];
|
$contribution_data['note'] = $params['purpose'];
|
||||||
}
|
}
|
||||||
|
@ -526,6 +575,10 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
)
|
)
|
||||||
// ... and frequency unit and interval from a static mapping.
|
// ... and frequency unit and interval from a static mapping.
|
||||||
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['ContributionRecur'])) {
|
||||||
|
$mandate_data += $custom_fields['ContributionRecur'];
|
||||||
|
}
|
||||||
|
|
||||||
// Add cycle day for recurring contributions.
|
// Add cycle day for recurring contributions.
|
||||||
if ($params['donation_rhythm'] != 'one_time') {
|
if ($params['donation_rhythm'] != 'one_time') {
|
||||||
|
@ -557,6 +610,13 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
'financial_type_id' => $profile->getAttribute('financial_type_id_recur'),
|
'financial_type_id' => $profile->getAttribute('financial_type_id_recur'),
|
||||||
)
|
)
|
||||||
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
||||||
|
|
||||||
|
// Add custom field values.
|
||||||
|
if (!empty($custom_fields['ContributionRecur'])) {
|
||||||
|
$contribution_recur_data += $custom_fields['ContributionRecur'];
|
||||||
|
$contribution_data += $custom_fields['ContributionRecur'];
|
||||||
|
}
|
||||||
|
|
||||||
$contribution_recur = civicrm_api3('contributionRecur', 'create', $contribution_recur_data);
|
$contribution_recur = civicrm_api3('contributionRecur', 'create', $contribution_recur_data);
|
||||||
if ($contribution_recur['is_error']) {
|
if ($contribution_recur['is_error']) {
|
||||||
throw new CiviCRM_API3_Exception(
|
throw new CiviCRM_API3_Exception(
|
||||||
|
@ -573,7 +633,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
||||||
|
|
||||||
// Create contribution.
|
// Create contribution.
|
||||||
$contribution_data += array(
|
$contribution_data += array(
|
||||||
'contribution_status_id' => 'Completed',
|
'contribution_status_id' => $profile->getAttribute("pi_{$params['payment_method']}_status", CRM_Twingle_Submission::CONTRIBUTION_STATUS_COMPLETED),
|
||||||
'receive_date' => $params['confirmed_at'],
|
'receive_date' => $params['confirmed_at'],
|
||||||
);
|
);
|
||||||
$contribution = civicrm_api3('Contribution', 'create', $contribution_data);
|
$contribution = civicrm_api3('Contribution', 'create', $contribution_data);
|
||||||
|
|
1
info.xml
1
info.xml
|
@ -19,6 +19,7 @@
|
||||||
<develStage>dev</develStage>
|
<develStage>dev</develStage>
|
||||||
<compatibility>
|
<compatibility>
|
||||||
<ver>4.7</ver>
|
<ver>4.7</ver>
|
||||||
|
<ver>5.0</ver>
|
||||||
</compatibility>
|
</compatibility>
|
||||||
<comments></comments>
|
<comments></comments>
|
||||||
<requires>
|
<requires>
|
||||||
|
|
|
@ -31,4 +31,32 @@ return array(
|
||||||
'is_contact' => 0,
|
'is_contact' => 0,
|
||||||
'description' => 'Whether to provide CiviSEPA functionality for manual debit payment method. This requires the CiviSEPA (org.project60.sepa) extension be installed.',
|
'description' => 'Whether to provide CiviSEPA functionality for manual debit payment method. This requires the CiviSEPA (org.project60.sepa) extension be installed.',
|
||||||
),
|
),
|
||||||
|
'twingle_protect_recurring' => array(
|
||||||
|
'group_name' => 'de.systopia.twingle',
|
||||||
|
'group' => 'de.systopia.twingle',
|
||||||
|
'name' => 'twingle_protect_recurring',
|
||||||
|
'type' => 'Boolean',
|
||||||
|
'quick_form_type' => 'YesNo',
|
||||||
|
'html_type' => 'radio',
|
||||||
|
'title' => 'Protect Recurring Contributions',
|
||||||
|
'default' => 0,
|
||||||
|
'add' => '4.6',
|
||||||
|
'is_domain' => 1,
|
||||||
|
'is_contact' => 0,
|
||||||
|
'description' => 'Will protect all recurring contributions created by Twingle from termination, since this does NOT terminate the Twingle collection process. Currently only works with a prefix',
|
||||||
|
),
|
||||||
|
'twingle_prefix' => array(
|
||||||
|
'group_name' => 'de.systopia.twingle',
|
||||||
|
'group' => 'de.systopia.twingle',
|
||||||
|
'name' => 'twingle_prefix',
|
||||||
|
'type' => CRM_Utils_Type::T_STRING,
|
||||||
|
'quick_form_type' => 'Element',
|
||||||
|
'html_type' => 'text',
|
||||||
|
'title' => 'Twingle ID Prefix',
|
||||||
|
'default' => '',
|
||||||
|
'add' => '4.6',
|
||||||
|
'is_domain' => 1,
|
||||||
|
'is_contact' => 0,
|
||||||
|
'description' => 'You can use this setting to add a prefix to the Twingle transaction ID, in order to avoid collisions with other transaction ids.',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
{ts domain="de.systopia.twingle"}Select which location type to use for addresses for individuals, either when no organisation name is specified, or an organisation address can not be shared with the individual contact.{/ts}
|
{ts domain="de.systopia.twingle"}Select which location type to use for addresses for individuals, either when no organisation name is specified, or an organisation address can not be shared with the individual contact.{/ts}
|
||||||
{/htxt}
|
{/htxt}
|
||||||
|
|
||||||
|
{htxt id='id-project_ids'}
|
||||||
|
{ts domain="de.systopia.twingle"}Put your project's Twingle ID in here, to activate this profile for that project.{/ts}
|
||||||
|
{ts domain="de.systopia.twingle"}You can also provide multiple project IDs separated by a comma.{/ts}
|
||||||
|
{/htxt}
|
||||||
|
|
||||||
{htxt id='id-location_type_id_organisation'}
|
{htxt id='id-location_type_id_organisation'}
|
||||||
{ts domain="de.systopia.twingle"}Select which location type to use for addresses for organisations and shared organisation addresses for individual contacts.{/ts}
|
{ts domain="de.systopia.twingle"}Select which location type to use for addresses for organisations and shared organisation addresses for individual contacts.{/ts}
|
||||||
{/htxt}
|
{/htxt}
|
||||||
|
@ -27,3 +32,17 @@
|
||||||
{htxt id='id-financial_type_id_recur'}
|
{htxt id='id-financial_type_id_recur'}
|
||||||
{ts domain="de.systopia.twingle"}Select which financial type to use for recurring contributions.{/ts}
|
{ts domain="de.systopia.twingle"}Select which financial type to use for recurring contributions.{/ts}
|
||||||
{/htxt}
|
{/htxt}
|
||||||
|
|
||||||
|
{htxt id='id-custom_field_mapping'}
|
||||||
|
{ts domain="de.systopia.twingle"}<p>Map Twingle custom fields to CiviCRM custom fields using the following format (each assignment in a separate line):</p>
|
||||||
|
<pre>twingle_field_1=custom_123<br />twingle_field_2=custom_789</pre>
|
||||||
|
<p>Always use the <code>custom_[id]</code> notation for CiviCRM custom fields.</p>
|
||||||
|
<p>Only custom fields extending one of the following CiviCRM entities are allowed:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Contact</strong> – Will be set on the Individual contact</li>
|
||||||
|
<li><strong>Individual</strong> – Will be set on the Individual contact</li>
|
||||||
|
<li><strong>Organization</strong> – Will be set on the Organization contact, if an organisation name was submitted</li>
|
||||||
|
<li><strong>Contribution</strong> – Will be set on the contribution</li>
|
||||||
|
<li><strong>ContributionRecur</strong> – Will be set on the recurring contribution and deriving single contributions</li>
|
||||||
|
</ul>{/ts}
|
||||||
|
{/htxt}
|
||||||
|
|
|
@ -28,7 +28,23 @@
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class="crm-section">
|
<tr class="crm-section">
|
||||||
<td class="label">{$form.selector.label}</td>
|
<td class="label">{$form.selector.label}
|
||||||
|
<a
|
||||||
|
onclick='
|
||||||
|
CRM.help(
|
||||||
|
"{ts domain="de.systopia.twingle"}Project IDs{/ts}",
|
||||||
|
{literal}{
|
||||||
|
"id": "id-project_ids",
|
||||||
|
"file": "CRM\/Twingle\/Form\/Profile"
|
||||||
|
}{/literal}
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
'
|
||||||
|
href="#"
|
||||||
|
title="{ts domain="de.systopia.twingle"}Help{/ts}"
|
||||||
|
class="helpicon"
|
||||||
|
></a>
|
||||||
|
</td>
|
||||||
<td class="content">{$form.selector.html}</td>
|
<td class="content">{$form.selector.html}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@ -151,8 +167,14 @@
|
||||||
<table class="form-layout-compressed">
|
<table class="form-layout-compressed">
|
||||||
{foreach key=pi_name item=pi_label from=$payment_instruments}
|
{foreach key=pi_name item=pi_label from=$payment_instruments}
|
||||||
<tr class="crm-section {cycle values="odd,even"}">
|
<tr class="crm-section {cycle values="odd,even"}">
|
||||||
|
|
||||||
<td class="label">{$form.$pi_name.label}</td>
|
<td class="label">{$form.$pi_name.label}</td>
|
||||||
<td class="content">{$form.$pi_name.html}</td>
|
<td class="content">{$form.$pi_name.html}</td>
|
||||||
|
|
||||||
|
{capture assign="pi_contribution_status"}{$pi_name}_status{/capture}
|
||||||
|
<td class="label">{$form.$pi_contribution_status.label}</td>
|
||||||
|
<td class="content">{$form.$pi_contribution_status.html}</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</table>
|
</table>
|
||||||
|
@ -161,7 +183,7 @@
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|
||||||
<legend>{ts domain="de.systopia.twingle"}Groups{/ts}</legend>
|
<legend>{ts domain="de.systopia.twingle"}Groups and Correlations{/ts}</legend>
|
||||||
|
|
||||||
<table class="form-layout-compressed">
|
<table class="form-layout-compressed">
|
||||||
|
|
||||||
|
@ -195,6 +217,28 @@
|
||||||
<td class="content">{$form.contribution_source.html}</td>
|
<td class="content">{$form.contribution_source.html}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr class="crm-section">
|
||||||
|
<td class="label">
|
||||||
|
{$form.custom_field_mapping.label}
|
||||||
|
<a
|
||||||
|
onclick='
|
||||||
|
CRM.help(
|
||||||
|
"{ts domain="de.systopia.twingle"}Custom field mapping{/ts}",
|
||||||
|
{literal}{
|
||||||
|
"id": "id-custom_field_mapping",
|
||||||
|
"file": "CRM\/Twingle\/Form\/Profile"
|
||||||
|
}{/literal}
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
'
|
||||||
|
href="#"
|
||||||
|
title="{ts domain="de.systopia.twingle"}Help{/ts}"
|
||||||
|
class="helpicon"
|
||||||
|
></a>
|
||||||
|
</td>
|
||||||
|
<td class="content">{$form.custom_field_mapping.html}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
@ -15,3 +15,11 @@
|
||||||
{htxt id='id-twingle_use_sepa'}
|
{htxt id='id-twingle_use_sepa'}
|
||||||
{ts domain="de.systopia.twingle" 1="<a href=\"https://github.com/project60/org.project60.sepa\" target=\"_blank\">CiviSEPA (<kbd>org.project60.sepa</kbd>) extension</a>"}When the %1 is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the <em>debit_manual</em> payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data.{/ts}
|
{ts domain="de.systopia.twingle" 1="<a href=\"https://github.com/project60/org.project60.sepa\" target=\"_blank\">CiviSEPA (<kbd>org.project60.sepa</kbd>) extension</a>"}When the %1 is enabled and one of its payment instruments is assigned to a Twingle payment method (practically the <em>debit_manual</em> payment method), submitting a Twingle donation through the API will create a SEPA mandate with the given data.{/ts}
|
||||||
{/htxt}
|
{/htxt}
|
||||||
|
|
||||||
|
{htxt id='id-twingle_protect_recurring'}
|
||||||
|
{ts domain="de.systopia.twingle"}Will protect all recurring contributions created by Twingle from termination, since this does NOT terminate the Twingle collection process{/ts}
|
||||||
|
{/htxt}
|
||||||
|
|
||||||
|
{htxt id='id-twingle_prefix'}
|
||||||
|
{ts domain="de.systopia.twingle"}You can use this setting to add a prefix to the Twingle transaction ID, in order to avoid collisions with other transaction ids.{/ts}
|
||||||
|
{/htxt}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{crmURL p="civicrm/admin/settings/twingle/profile" q="op=edit&name=$profile_name"}" title="{ts domain="de.systopia.twingle" 1=$profile.name}Edit profile %1{/ts}" class="action-item crm-hover-button">{ts domain="de.systopia.twingle"}Edit{/ts}</a>
|
<a href="{crmURL p="civicrm/admin/settings/twingle/profile" q="op=edit&name=$profile_name"}" title="{ts domain="de.systopia.twingle" 1=$profile.name}Edit profile %1{/ts}" class="action-item crm-hover-button">{ts domain="de.systopia.twingle"}Edit{/ts}</a>
|
||||||
|
<a href="{crmURL p="civicrm/admin/settings/twingle/profile" q="op=copy&name=$profile_name"}" title="{ts domain="de.systopia.twingle" 1=$profile.name}Copy profile %1{/ts}" class="action-item crm-hover-button">{ts domain="de.systopia.twingle"}Copy{/ts}</a>
|
||||||
{if $profile_name == 'default'}
|
{if $profile_name == 'default'}
|
||||||
<a href="{crmURL p="civicrm/admin/settings/twingle/profile" q="op=delete&name=$profile_name"}" title="{ts domain="de.systopia.twingle" 1=$profile.name}Reset profile %1{/ts}" class="action-item crm-hover-button">{ts domain="de.systopia.twingle"}Reset{/ts}</a>
|
<a href="{crmURL p="civicrm/admin/settings/twingle/profile" q="op=delete&name=$profile_name"}" title="{ts domain="de.systopia.twingle" 1=$profile.name}Reset profile %1{/ts}" class="action-item crm-hover-button">{ts domain="de.systopia.twingle"}Reset{/ts}</a>
|
||||||
{else}
|
{else}
|
||||||
|
|
|
@ -3,6 +3,15 @@
|
||||||
require_once 'twingle.civix.php';
|
require_once 'twingle.civix.php';
|
||||||
use CRM_Twingle_ExtensionUtil as E;
|
use CRM_Twingle_ExtensionUtil as E;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_civicrm_pre().
|
||||||
|
*/
|
||||||
|
function twingle_civicrm_pre($op, $objectName, $id, &$params) {
|
||||||
|
if ($objectName == 'ContributionRecur' && $op == 'edit') {
|
||||||
|
CRM_Twingle_Tools::checkRecurringContributionChange($id, $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_civicrm_config().
|
* Implements hook_civicrm_config().
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue