Fix PHPStan issues
This commit is contained in:
parent
d7b066751a
commit
8bcdff4a85
16 changed files with 385 additions and 364 deletions
|
@ -27,7 +27,7 @@ class CRM_Twingle_Config {
|
|||
* Get the options for protecting a recurring contribution linked Twingle
|
||||
* against ending or cancellation (because Twingle would keep on collecting them)
|
||||
*
|
||||
* @return array
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getRecurringProtectionOptions() {
|
||||
return [
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
declare(strict_types = 1);
|
||||
|
||||
use CRM_Twingle_ExtensionUtil as E;
|
||||
use Civi\Twingle\Exceptions\ProfileException as ProfileException;
|
||||
use Civi\Twingle\Exceptions\ProfileException;
|
||||
use Civi\Twingle\Exceptions\BaseException;
|
||||
|
||||
/**
|
||||
* Form controller class
|
||||
|
@ -30,7 +31,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
*
|
||||
* The profile object the form is acting on.
|
||||
*/
|
||||
protected $profile;
|
||||
protected ?CRM_Twingle_Profile $profile = NULL;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
|
@ -40,120 +41,128 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
protected $_op;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*
|
||||
* A static cache of retrieved payment instruments found within
|
||||
* self::getPaymentInstruments().
|
||||
*/
|
||||
protected static $_paymentInstruments = NULL;
|
||||
protected static $_paymentInstruments;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved contribution statuses found within
|
||||
* static::getContributionStatusOptions().
|
||||
*/
|
||||
protected static $_contributionStatusOptions = NULL;
|
||||
protected static array $_contributionStatusOptions;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved groups found within static::getGroups().
|
||||
*/
|
||||
protected static $_groups = NULL;
|
||||
protected static array $_groups;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*
|
||||
* A static cache of retrieved newsletter groups found within
|
||||
* static::getNewsletterGroups().
|
||||
*/
|
||||
protected static $_newsletterGroups = NULL;
|
||||
protected static array $_newsletterGroups;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved campaigns found within static::getCampaigns().
|
||||
*/
|
||||
protected static $_campaigns = NULL;
|
||||
protected static array $_campaigns;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved financial types found within
|
||||
* static::getFinancialTypes().
|
||||
*/
|
||||
protected static $_financialTypes = NULL;
|
||||
protected static array $_financialTypes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved genders found within
|
||||
* static::getGenderOptions().
|
||||
*/
|
||||
protected static $_genderOptions = NULL;
|
||||
protected static array $_genderOptions;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved prefixes found within
|
||||
* static::getGenderOptions().
|
||||
*/
|
||||
protected static $_prefixOptions = NULL;
|
||||
protected static array $_prefixOptions;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved location types found within
|
||||
* static::getLocationTypes().
|
||||
*/
|
||||
protected static $_locationTypes = NULL;
|
||||
protected static array $_locationTypes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*
|
||||
* A static cache of retrieved location types found within
|
||||
* static::getXCMProfiles().
|
||||
*/
|
||||
protected static $_xcm_profiles = NULL;
|
||||
protected static array $_xcm_profiles;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved membership types found within
|
||||
* static::getMembershipTypes().
|
||||
*/
|
||||
protected static $_membershipTypes = NULL;
|
||||
protected static array $_membershipTypes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*
|
||||
* A static cache of retrieved CiviSEPA creditors found within
|
||||
* static::getSepaCreditors().
|
||||
*/
|
||||
protected static $_sepaCreditors = NULL;
|
||||
protected static array $_sepaCreditors;
|
||||
|
||||
public function preProcess(): void {
|
||||
// "Create" is the default operation.
|
||||
$op = CRM_Utils_Request::retrieve('op', 'String', $this);
|
||||
$this->_op = is_string($op) ? $op : 'create';
|
||||
|
||||
// Verify that a profile with the given name exists.
|
||||
$profile_name = CRM_Utils_Request::retrieve('name', 'String', $this);
|
||||
if (is_string($profile_name)) {
|
||||
$this->profile = CRM_Twingle_Profile::getProfile($profile_name);
|
||||
}
|
||||
|
||||
// Set redirect destination.
|
||||
$this->controller->_destination = CRM_Utils_System::url(
|
||||
'civicrm/admin/settings/twingle/profiles',
|
||||
'reset=1'
|
||||
);
|
||||
|
||||
parent::preProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the form structure.
|
||||
*/
|
||||
public function buildQuickForm() {
|
||||
// "Create" is the default operation.
|
||||
if (!$this->_op = CRM_Utils_Request::retrieve('op', 'String', $this)) {
|
||||
$this->_op = 'create';
|
||||
}
|
||||
|
||||
// Verify that a profile with the given name exists.
|
||||
$profile_name = CRM_Utils_Request::retrieve('name', 'String', $this);
|
||||
if (!$this->profile = CRM_Twingle_Profile::getProfile($profile_name)) {
|
||||
$profile_name = NULL;
|
||||
}
|
||||
|
||||
// Set redirect destination.
|
||||
$this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle/profiles', 'reset=1');
|
||||
public function buildQuickForm(): void {
|
||||
$profile_name = (isset($this->profile) ? $this->profile->getName() : NULL);
|
||||
|
||||
switch ($this->_op) {
|
||||
case 'delete':
|
||||
if ($profile_name) {
|
||||
if (isset($profile_name)) {
|
||||
CRM_Utils_System::setTitle(E::ts('Delete Twingle API profile <em>%1</em>', [1 => $profile_name]));
|
||||
$this->addButtons([
|
||||
[
|
||||
|
@ -168,10 +177,13 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
|
||||
case 'edit':
|
||||
// When editing without a valid profile name, edit the default profile.
|
||||
if (!$profile_name) {
|
||||
if (!isset($profile_name)) {
|
||||
$profile_name = 'default';
|
||||
$this->profile = CRM_Twingle_Profile::getProfile($profile_name);
|
||||
}
|
||||
if (!isset($this->profile)) {
|
||||
throw new BaseException(E::ts('Could not retrieve profile with name "%1"', [1 => $profile_name]));
|
||||
}
|
||||
CRM_Utils_System::setTitle(E::ts('Edit Twingle API profile <em>%1</em>', [1 => $this->profile->getName()]));
|
||||
break;
|
||||
|
||||
|
@ -179,10 +191,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
// Retrieve the source profile name.
|
||||
$profile_name = CRM_Utils_Request::retrieve('source_name', 'String', $this);
|
||||
// When copying without a valid profile name, copy the default profile.
|
||||
if (!$profile_name) {
|
||||
if (!is_string($profile_name)) {
|
||||
$profile_name = 'default';
|
||||
}
|
||||
$this->profile = clone CRM_Twingle_Profile::getProfile($profile_name);
|
||||
$originalProfile = CRM_Twingle_Profile::getProfile($profile_name);
|
||||
if (!isset($originalProfile)) {
|
||||
throw new BaseException(E::ts('Could not retrieve profile with name "%1"', [1 => $profile_name]));
|
||||
}
|
||||
$this->profile = clone $originalProfile;
|
||||
|
||||
// Propose a new name for this profile.
|
||||
$profile_name = $profile_name . '_copy';
|
||||
|
@ -192,7 +208,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
|
||||
case 'create':
|
||||
// Load factory default profile values.
|
||||
$this->profile = CRM_Twingle_Profile::createDefaultProfile($profile_name);
|
||||
$this->profile = CRM_Twingle_Profile::createDefaultProfile($profile_name ?? 'default');
|
||||
CRM_Utils_System::setTitle(E::ts('New Twingle API profile'));
|
||||
break;
|
||||
}
|
||||
|
@ -354,10 +370,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
// field name
|
||||
'newsletter_double_opt_in',
|
||||
// field label
|
||||
E::ts('Use Double-Opt-In for newsletter'),
|
||||
// is not required
|
||||
FALSE,
|
||||
[]
|
||||
E::ts('Use Double-Opt-In for newsletter')
|
||||
);
|
||||
|
||||
$this->add(
|
||||
|
@ -461,8 +474,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
$this->add(
|
||||
'text',
|
||||
'membership_postprocess_call',
|
||||
E::ts('API Call for Membership Postprocessing'),
|
||||
FALSE
|
||||
E::ts('API Call for Membership Postprocessing')
|
||||
);
|
||||
$this->addRule(
|
||||
'membership_postprocess_call',
|
||||
|
@ -521,9 +533,8 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
/**
|
||||
* Validates the profile form.
|
||||
*
|
||||
* @return bool|array
|
||||
* TRUE when the form was successfully validated, or an array of error
|
||||
* messages, keyed by form element name.
|
||||
* @return bool
|
||||
* TRUE when the form was successfully validated.
|
||||
*/
|
||||
public function validate() {
|
||||
$values = $this->exportValues();
|
||||
|
@ -531,14 +542,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
// Validate new profile names.
|
||||
if (
|
||||
isset($values['name'])
|
||||
&& ($values['name'] != $this->profile->getName() || $this->_op != 'edit')
|
||||
&& !empty(CRM_Twingle_Profile::getProfile($values['name']))
|
||||
&& (!isset($this->profile) || $values['name'] != $this->profile->getName() || $this->_op != 'edit')
|
||||
&& NULL !== CRM_Twingle_Profile::getProfile($values['name'])
|
||||
) {
|
||||
$this->_errors['name'] = E::ts('A profile with this name already exists.');
|
||||
}
|
||||
|
||||
// Restrict profile names to alphanumeric characters and the underscore.
|
||||
if (isset($values['name']) && preg_match('/[^A-Za-z0-9\_]/', $values['name'])) {
|
||||
if (isset($values['name']) && 1 === preg_match('/[^A-Za-z0-9\_]/', $values['name'])) {
|
||||
$this->_errors['name'] =
|
||||
E::ts('Only alphanumeric characters and the underscore (_) are allowed for profile names.');
|
||||
}
|
||||
|
@ -548,14 +559,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
if (isset($values['custom_field_mapping'])) {
|
||||
$custom_field_mapping = preg_split('/\r\n|\r|\n/', $values['custom_field_mapping'], -1, PREG_SPLIT_NO_EMPTY);
|
||||
if (!is_array($custom_field_mapping)) {
|
||||
throw new Exception(
|
||||
throw new BaseException(
|
||||
E::ts('Could not parse custom field mapping.')
|
||||
);
|
||||
}
|
||||
foreach ($custom_field_mapping as $custom_field_map) {
|
||||
$custom_field_map = explode('=', $custom_field_map);
|
||||
if (count($custom_field_map) !== 2) {
|
||||
throw new Exception(
|
||||
throw new BaseException(
|
||||
E::ts('Could not parse custom field mapping.')
|
||||
);
|
||||
}
|
||||
|
@ -568,12 +579,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
'id' => $custom_field_id,
|
||||
]);
|
||||
}
|
||||
catch (CiviCRM_API3_Exception $exception) {
|
||||
throw new Exception(
|
||||
catch (CRM_Core_Exception $exception) {
|
||||
throw new BaseException(
|
||||
E::ts(
|
||||
'Custom field custom_%1 does not exist.',
|
||||
[1 => $custom_field_id]
|
||||
)
|
||||
),
|
||||
NULL,
|
||||
$exception
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -592,18 +605,20 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
],
|
||||
]);
|
||||
}
|
||||
catch (CiviCRM_API3_Exception $exception) {
|
||||
throw new Exception(
|
||||
catch (CRM_Core_Exception $exception) {
|
||||
throw new BaseException(
|
||||
E::ts(
|
||||
'Custom field custom_%1 is not in a CustomGroup that extends one of the supported CiviCRM entities.',
|
||||
[1 => $custom_field['id']]
|
||||
)
|
||||
);
|
||||
),
|
||||
NULL,
|
||||
$exception
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
catch (BaseException $exception) {
|
||||
$this->_errors['custom_field_mapping'] = $exception->getMessage();
|
||||
}
|
||||
|
||||
|
@ -612,12 +627,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
|
||||
/**
|
||||
* Set the default values (i.e. the profile's current data) in the form.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function setDefaultValues() {
|
||||
$defaults = parent::setDefaultValues();
|
||||
if (in_array($this->_op, ['create', 'edit', 'copy'])) {
|
||||
$defaults['name'] = $this->profile->getName();
|
||||
$profile_data = $this->profile->getData();
|
||||
if (in_array($this->_op, ['create', 'edit', 'copy'], TRUE)) {
|
||||
$defaults['name'] = isset($this->profile) ? $this->profile->getName() : NULL;
|
||||
$profile_data = isset($this->profile) ? $this->profile->getData() : [];
|
||||
foreach ($profile_data as $element_name => $value) {
|
||||
$defaults[$element_name] = $value;
|
||||
}
|
||||
|
@ -632,11 +649,14 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
/**
|
||||
* Store the values submitted with the form in the profile.
|
||||
*/
|
||||
public function postProcess() {
|
||||
public function postProcess(): void {
|
||||
$values = $this->exportValues();
|
||||
try {
|
||||
if (in_array($this->_op, ['create', 'edit', 'copy'])) {
|
||||
if (empty($values['name'])) {
|
||||
if (!isset($this->profile)) {
|
||||
throw new BaseException(E::ts('No profile set.'));
|
||||
}
|
||||
if (in_array($this->_op, ['create', 'edit', 'copy'], TRUE)) {
|
||||
if (!is_string($values['name'])) {
|
||||
$values['name'] = 'default';
|
||||
}
|
||||
$this->profile->setName($values['name']);
|
||||
|
@ -670,9 +690,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves location types present within the system as options for select
|
||||
* form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getLocationTypes() {
|
||||
if (!isset(static::$_locationTypes)) {
|
||||
|
@ -682,7 +700,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
'is_active' => 1,
|
||||
]);
|
||||
foreach ($query['values'] as $type) {
|
||||
static::$_locationTypes[$type['id']] = $type['name'];
|
||||
static::$_locationTypes[(int) $type['id']] = $type['name'];
|
||||
}
|
||||
}
|
||||
return static::$_locationTypes;
|
||||
|
@ -691,11 +709,11 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
/**
|
||||
* Retrieves XCM profiles (if supported). 'default' profile is always available
|
||||
*
|
||||
* @return array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getXCMProfiles() {
|
||||
if (!isset(static::$_xcm_profiles)) {
|
||||
if (method_exists('CRM_Xcm_Configuration', 'getProfileList')) {
|
||||
if (class_exists('CRM_Xcm_Configuration')) {
|
||||
static::$_xcm_profiles = [
|
||||
'' => E::ts('<select profile>'),
|
||||
];
|
||||
|
@ -712,9 +730,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves financial types present within the system as options for select
|
||||
* form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getFinancialTypes() {
|
||||
if (!isset(static::$_financialTypes)) {
|
||||
|
@ -725,7 +741,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
'return' => 'id,name',
|
||||
]);
|
||||
foreach ($query['values'] as $type) {
|
||||
static::$_financialTypes[$type['id']] = $type['name'];
|
||||
static::$_financialTypes[(int) $type['id']] = $type['name'];
|
||||
}
|
||||
}
|
||||
return static::$_financialTypes;
|
||||
|
@ -735,9 +751,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves membership types present within the system as options for select
|
||||
* form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getMembershipTypes() {
|
||||
if (!isset(static::$_membershipTypes)) {
|
||||
|
@ -758,9 +772,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves genders present within the system as options for select form
|
||||
* elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getGenderOptions() {
|
||||
if (!isset(static::$_genderOptions)) {
|
||||
|
@ -775,7 +787,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
],
|
||||
]);
|
||||
foreach ($query['values'] as $gender) {
|
||||
static::$_genderOptions[$gender['value']] = $gender['label'];
|
||||
static::$_genderOptions[(int) $gender['value']] = $gender['label'];
|
||||
}
|
||||
}
|
||||
return static::$_genderOptions;
|
||||
|
@ -785,9 +797,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves prefixes present within the system as options for select form
|
||||
* elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getPrefixOptions() {
|
||||
if (!isset(static::$_prefixOptions)) {
|
||||
|
@ -802,7 +812,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
],
|
||||
]);
|
||||
foreach ($query['values'] as $prefix) {
|
||||
static::$_prefixOptions[$prefix['value']] = $prefix['label'];
|
||||
static::$_prefixOptions[(int) $prefix['value']] = $prefix['label'];
|
||||
}
|
||||
}
|
||||
return static::$_prefixOptions;
|
||||
|
@ -811,9 +821,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
/**
|
||||
* Retrieves CiviSEPA creditors as options for select form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getSepaCreditors() {
|
||||
if (!isset(static::$_sepaCreditors)) {
|
||||
|
@ -823,7 +831,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
'option.limit' => 0,
|
||||
]);
|
||||
foreach ($result['values'] as $sepa_creditor) {
|
||||
static::$_sepaCreditors[$sepa_creditor['id']] = $sepa_creditor['name'];
|
||||
static::$_sepaCreditors[(int) $sepa_creditor['id']] = $sepa_creditor['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -834,9 +842,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves payment instruments present within the system as options for
|
||||
* select form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getPaymentInstruments() {
|
||||
if (!isset(self::$_paymentInstruments)) {
|
||||
|
@ -869,9 +875,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
/**
|
||||
* Retrieves contribution statuses as options for select form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getContributionStatusOptions() {
|
||||
if (!isset(self::$_contributionStatusOptions)) {
|
||||
|
@ -889,7 +893,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
);
|
||||
|
||||
foreach ($query['values'] as $contribution_status) {
|
||||
self::$_contributionStatusOptions[$contribution_status['value']] = $contribution_status['label'];
|
||||
self::$_contributionStatusOptions[(int) $contribution_status['value']] = $contribution_status['label'];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -900,9 +904,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves active groups used as mailing lists within the system as options
|
||||
* for select form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<string, string>
|
||||
*
|
||||
*/
|
||||
public static function getNewsletterGroups() {
|
||||
|
@ -935,9 +937,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
/**
|
||||
* Retrieves active groups as options for select form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getGroups() {
|
||||
if (!isset(static::$_groups)) {
|
||||
|
@ -948,7 +948,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
'return' => 'id,name',
|
||||
]);
|
||||
foreach ($query['values'] as $group) {
|
||||
static::$_groups[$group['id']] = $group['name'];
|
||||
static::$_groups[(int) $group['id']] = $group['name'];
|
||||
}
|
||||
}
|
||||
return static::$_groups;
|
||||
|
@ -958,9 +958,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves active groups used as postal mailing lists within the system as
|
||||
* options for select form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getPostinfoGroups() {
|
||||
return static::getGroups();
|
||||
|
@ -970,9 +968,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
* Retrieves active groups used as donation receipt requester lists within the
|
||||
* system as options for select form elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getDonationReceiptGroups() {
|
||||
return static::getGroups();
|
||||
|
@ -981,9 +977,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
/**
|
||||
* Retrieves campaigns as options for select elements.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function getCampaigns() {
|
||||
if (!isset(static::$_campaigns)) {
|
||||
|
@ -996,7 +990,7 @@ class CRM_Twingle_Form_Profile extends CRM_Core_Form {
|
|||
],
|
||||
]);
|
||||
foreach ($query['values'] as $campaign) {
|
||||
static::$_campaigns[$campaign['id']] = $campaign['title'];
|
||||
static::$_campaigns[(int) $campaign['id']] = $campaign['title'];
|
||||
}
|
||||
}
|
||||
return static::$_campaigns;
|
||||
|
|
|
@ -25,7 +25,8 @@ use CRM_Twingle_ExtensionUtil as E;
|
|||
class CRM_Twingle_Form_Settings extends CRM_Core_Form {
|
||||
|
||||
/**
|
||||
* @var arraylistofallsettingsoptions
|
||||
* @var array<string>
|
||||
* List of all settings options.
|
||||
*/
|
||||
public static $SETTINGS_LIST = [
|
||||
'twingle_prefix',
|
||||
|
@ -41,7 +42,7 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form {
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function buildQuickForm() {
|
||||
public function buildQuickForm(): void {
|
||||
// Set redirect destination.
|
||||
$this->controller->_destination = CRM_Utils_System::url('civicrm/admin/settings/twingle', 'reset=1');
|
||||
|
||||
|
@ -131,15 +132,14 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form {
|
|||
parent::validate();
|
||||
|
||||
// if activity creation is active, make sure the fields are set
|
||||
$protection_mode = CRM_Utils_Array::value('twingle_protect_recurring', $this->_submitValues);
|
||||
$protection_mode = $this->_submitValues['twingle_protect_recurring'] ?? NULL;
|
||||
if ($protection_mode == CRM_Twingle_Config::RCUR_PROTECTION_ACTIVITY) {
|
||||
foreach (['twingle_protect_recurring_activity_type',
|
||||
'twingle_protect_recurring_activity_subject',
|
||||
'twingle_protect_recurring_activity_status',
|
||||
'twingle_protect_recurring_activity_assignee',
|
||||
] as $activity_field) {
|
||||
$current_value = CRM_Utils_Array::value($activity_field, $this->_submitValues);
|
||||
if (empty($current_value)) {
|
||||
if (NULL !== ($this->_submitValues[$activity_field] ?? NULL)) {
|
||||
$this->_errors[$activity_field] = E::ts('This is required for activity creation');
|
||||
}
|
||||
}
|
||||
|
@ -151,12 +151,12 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form {
|
|||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function postProcess() {
|
||||
public function postProcess(): void {
|
||||
$values = $this->exportValues();
|
||||
|
||||
// store settings
|
||||
foreach (self::$SETTINGS_LIST as $setting) {
|
||||
Civi::settings()->set($setting, CRM_Utils_Array::value($setting, $values));
|
||||
Civi::settings()->set($setting, $values[$setting]);
|
||||
}
|
||||
|
||||
parent::postProcess();
|
||||
|
@ -164,11 +164,13 @@ class CRM_Twingle_Form_Settings extends CRM_Core_Form {
|
|||
|
||||
/**
|
||||
* Get a list of option group items
|
||||
* @param $group_id string group ID or name
|
||||
* @return array list of ID(value) => label
|
||||
* @throws CiviCRM_API3_Exception
|
||||
* @param string $group_id
|
||||
* Group ID or name.
|
||||
* @param array<int> $reserved
|
||||
* @return array<int|string, string> list of ID(value) => label
|
||||
* @throws \CRM_Core_Exception
|
||||
*/
|
||||
protected function getOptionValueList($group_id, $reserved = [0, 1]) {
|
||||
protected function getOptionValueList(string $group_id, array $reserved = [0, 1]): array {
|
||||
$list = ['' => E::ts('-select-')];
|
||||
$query = civicrm_api3('OptionValue', 'get', [
|
||||
'option_group_id' => $group_id,
|
||||
|
|
|
@ -19,7 +19,7 @@ use CRM_Twingle_ExtensionUtil as E;
|
|||
|
||||
class CRM_Twingle_Page_Configuration extends CRM_Core_Page {
|
||||
|
||||
public function run() {
|
||||
public function run(): void {
|
||||
parent::run();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ use CRM_Twingle_ExtensionUtil as E;
|
|||
|
||||
class CRM_Twingle_Page_Profiles extends CRM_Core_Page {
|
||||
|
||||
public function run() {
|
||||
public function run():void {
|
||||
CRM_Utils_System::setTitle(E::ts('Twingle API Profiles'));
|
||||
$profiles = [];
|
||||
foreach (CRM_Twingle_Profile::getProfiles() as $profile_name => $profile) {
|
||||
|
|
|
@ -28,20 +28,20 @@ class CRM_Twingle_Profile {
|
|||
* @var string
|
||||
* The name of the profile.
|
||||
*/
|
||||
protected $name = NULL;
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, mixed>
|
||||
* The properties of the profile.
|
||||
*/
|
||||
protected $data = NULL;
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* CRM_Twingle_Profile constructor.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the profile.
|
||||
* @param array $data
|
||||
* @param array<string, mixed> $data
|
||||
* The properties of the profile
|
||||
*/
|
||||
public function __construct($name, $data) {
|
||||
|
@ -56,7 +56,7 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Logs (production) access to this profile
|
||||
*/
|
||||
public function logAccess() {
|
||||
public function logAccess(): void {
|
||||
CRM_Core_DAO::executeQuery('
|
||||
UPDATE civicrm_twingle_profile
|
||||
SET
|
||||
|
@ -80,19 +80,29 @@ class CRM_Twingle_Profile {
|
|||
},
|
||||
explode(',', $selector)
|
||||
);
|
||||
return in_array($project_id, $project_ids);
|
||||
return in_array($project_id, $project_ids, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* Retrieves the profile's configured custom field mapping.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* The profile's configured custom field mapping
|
||||
*/
|
||||
public function getCustomFieldMapping() {
|
||||
$custom_field_mapping = [];
|
||||
if (!empty($custom_field_definition = $this->getAttribute('custom_field_mapping'))) {
|
||||
foreach (preg_split('/\r\n|\r|\n/', $custom_field_definition, -1, PREG_SPLIT_NO_EMPTY) as $custom_field_map) {
|
||||
[$twingle_field_name, $custom_field_name] = explode('=', $custom_field_map);
|
||||
$custom_field_mapping[$twingle_field_name] = $custom_field_name;
|
||||
if (is_string($custom_field_definition = $this->getAttribute('custom_field_mapping'))) {
|
||||
$custom_field_maps = preg_split(
|
||||
'/\r\n|\r|\n/',
|
||||
$custom_field_definition,
|
||||
-1,
|
||||
PREG_SPLIT_NO_EMPTY
|
||||
);
|
||||
if (FALSE !== $custom_field_maps) {
|
||||
foreach ($custom_field_maps as $custom_field_map) {
|
||||
[$twingle_field_name, $custom_field_name] = explode('=', $custom_field_map);
|
||||
$custom_field_mapping[$twingle_field_name] = $custom_field_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $custom_field_mapping;
|
||||
|
@ -101,7 +111,7 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Retrieves all data attributes of the profile.
|
||||
*
|
||||
* @return array
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
|
@ -119,9 +129,9 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Sets the profile name.
|
||||
*
|
||||
* @param $name
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name) {
|
||||
public function setName(string $name): void {
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
|
@ -146,8 +156,8 @@ class CRM_Twingle_Profile {
|
|||
* @throws \Civi\Twingle\Exceptions\ProfileException
|
||||
* When the attribute name is not known.
|
||||
*/
|
||||
public function setAttribute($attribute_name, $value) {
|
||||
if (!in_array($attribute_name, self::allowedAttributes())) {
|
||||
public function setAttribute($attribute_name, $value): void {
|
||||
if (!in_array($attribute_name, self::allowedAttributes(), TRUE)) {
|
||||
throw new ProfileException(
|
||||
E::ts('Unknown attribute %1.', [1 => $attribute_name]),
|
||||
ProfileException::ERROR_CODE_UNKNOWN_PROFILE_ATTRIBUTE
|
||||
|
@ -160,27 +170,19 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Get the CiviCRM transaction ID (to be used in contributions and recurring contributions)
|
||||
*
|
||||
* @param $twingle_id string Twingle ID
|
||||
* @param string $twingle_id Twingle ID
|
||||
* @return string CiviCRM transaction ID
|
||||
*/
|
||||
public function getTransactionID($twingle_id) {
|
||||
public function getTransactionID(string $twingle_id) {
|
||||
$prefix = Civi::settings()->get('twingle_prefix');
|
||||
if (empty($prefix)) {
|
||||
return $twingle_id;
|
||||
}
|
||||
else {
|
||||
return $prefix . $twingle_id;
|
||||
}
|
||||
return ($prefix ?? '') . $twingle_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the profile is valid (i.e. consistent and not colliding
|
||||
* with other profiles).
|
||||
*
|
||||
* @throws Exception
|
||||
* When the profile could not be successfully validated.
|
||||
*/
|
||||
public function verifyProfile() {
|
||||
public function verifyProfile(): void {
|
||||
// TODO: check
|
||||
// data of this profile consistent?
|
||||
// conflicts with other profiles?
|
||||
|
@ -189,14 +191,14 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Persists the profile within the CiviCRM settings.
|
||||
*/
|
||||
public function saveProfile() {
|
||||
public function saveProfile(): void {
|
||||
// make sure it's valid
|
||||
$this->verifyProfile();
|
||||
|
||||
// check if the profile exists
|
||||
$profile_id = CRM_Core_DAO::singleValueQuery(
|
||||
'SELECT id FROM civicrm_twingle_profile WHERE name = %1', [1 => [$this->name, 'String']]);
|
||||
if ($profile_id) {
|
||||
if (isset($profile_id)) {
|
||||
// existing profile -> just update the config
|
||||
CRM_Core_DAO::executeQuery(
|
||||
'UPDATE civicrm_twingle_profile SET config = %2 WHERE name = %1',
|
||||
|
@ -219,7 +221,7 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Deletes the profile from the database
|
||||
*/
|
||||
public function deleteProfile() {
|
||||
public function deleteProfile(): void {
|
||||
CRM_Core_DAO::executeQuery(
|
||||
'DELETE FROM civicrm_twingle_profile WHERE name = %1',
|
||||
[1 => [$this->name, 'String']]
|
||||
|
@ -229,7 +231,7 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Returns an array of attributes allowed for a profile.
|
||||
*
|
||||
* @return array
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function allowedAttributes() {
|
||||
return array_merge(
|
||||
|
@ -273,9 +275,9 @@ class CRM_Twingle_Profile {
|
|||
/**
|
||||
* Retrieves a list of supported payment methods.
|
||||
*
|
||||
* @return array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function paymentInstruments() {
|
||||
public static function paymentInstruments(): array {
|
||||
return [
|
||||
'pi_banktransfer' => E::ts('Bank transfer'),
|
||||
'pi_debit_manual' => E::ts('Debit manual'),
|
||||
|
@ -364,10 +366,9 @@ class CRM_Twingle_Profile {
|
|||
* which is responsible for processing the project's data.
|
||||
* Returns the default profile if no match was found.
|
||||
*
|
||||
* @param $project_id
|
||||
* @param string $project_id
|
||||
*
|
||||
* @return CRM_Twingle_Profile
|
||||
* @throws \Civi\Core\Exception\DBQueryException
|
||||
*/
|
||||
public static function getProfileForProject($project_id) {
|
||||
$profiles = self::getProfiles();
|
||||
|
@ -379,9 +380,8 @@ class CRM_Twingle_Profile {
|
|||
}
|
||||
|
||||
// If none matches, use the default profile.
|
||||
$default_profile = $profiles['default'];
|
||||
if (!empty($default_profile)) {
|
||||
return $default_profile;
|
||||
if (isset($profiles['default'])) {
|
||||
return $profiles['default'];
|
||||
}
|
||||
else {
|
||||
throw new ProfileException(
|
||||
|
@ -396,26 +396,21 @@ class CRM_Twingle_Profile {
|
|||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return CRM_Twingle_Profile | NULL
|
||||
* @return CRM_Twingle_Profile|NULL
|
||||
*/
|
||||
public static function getProfile($name) {
|
||||
if (!empty($name)) {
|
||||
$profile_data = CRM_Core_DAO::singleValueQuery(
|
||||
'SELECT config FROM civicrm_twingle_profile WHERE name = %1',
|
||||
[1 => [$name, 'String']]
|
||||
);
|
||||
if ($profile_data) {
|
||||
return new CRM_Twingle_Profile($name, json_decode($profile_data, 1));
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
$profile_data = CRM_Core_DAO::singleValueQuery(
|
||||
'SELECT config FROM civicrm_twingle_profile WHERE name = %1',
|
||||
[1 => [$name, 'String']]
|
||||
);
|
||||
return isset($profile_data) ? new CRM_Twingle_Profile($name, (array) json_decode($profile_data, TRUE)) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of all profiles persisted within the current CiviCRM
|
||||
* settings, including the default profile.
|
||||
*
|
||||
* @return array
|
||||
* @return array<string, \CRM_Twingle_Profile>
|
||||
* profile_name => CRM_Twingle_Profile
|
||||
*/
|
||||
public static function getProfiles() {
|
||||
|
@ -439,7 +434,9 @@ class CRM_Twingle_Profile {
|
|||
*/
|
||||
public static function getProfileStats() {
|
||||
$stats = [];
|
||||
$profile_data = CRM_Core_DAO::executeQuery('SELECT name, last_access, access_counter FROM civicrm_twingle_profile');
|
||||
$profile_data = CRM_Core_DAO::executeQuery(
|
||||
'SELECT name, last_access, access_counter FROM civicrm_twingle_profile'
|
||||
);
|
||||
while ($profile_data->fetch()) {
|
||||
// phpcs:disable Drupal.Arrays.Array.ArrayIndentation
|
||||
$stats[$profile_data->name] = [
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
declare(strict_types = 1);
|
||||
|
||||
use CRM_Twingle_ExtensionUtil as E;
|
||||
use Civi\Twingle\Exceptions\BaseException;
|
||||
|
||||
class CRM_Twingle_Submission {
|
||||
|
||||
|
@ -40,18 +41,18 @@ class CRM_Twingle_Submission {
|
|||
public const EMPLOYER_RELATIONSHIP_TYPE_ID = 5;
|
||||
|
||||
/**
|
||||
* @param array &$params
|
||||
* @param array<string, mixed> &$params
|
||||
* A reference to the parameters array of the submission.
|
||||
*
|
||||
* @param \CRM_Twingle_Profile $profile
|
||||
* The Twingle profile to use for validation, defaults to the default
|
||||
* profile.
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @throws \CRM_Core_Exception
|
||||
* When invalid parameters have been submitted.
|
||||
*/
|
||||
public static function validateSubmission(&$params, $profile = NULL) {
|
||||
if (!$profile) {
|
||||
public static function validateSubmission(&$params, $profile = NULL): void {
|
||||
if (!isset($profile)) {
|
||||
$profile = CRM_Twingle_Profile::createDefaultProfile();
|
||||
}
|
||||
|
||||
|
@ -62,8 +63,8 @@ class CRM_Twingle_Submission {
|
|||
'quarterly',
|
||||
'yearly',
|
||||
'monthly',
|
||||
])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
], TRUE)) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Invalid donation rhythm.'),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -71,8 +72,9 @@ class CRM_Twingle_Submission {
|
|||
|
||||
// Get the payment instrument defined within the profile, or return an error
|
||||
// if none matches (i.e. an unknown payment method was submitted).
|
||||
if (!$payment_instrument_id = $profile->getAttribute('pi_' . $params['payment_method'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
$payment_instrument_id = $profile->getAttribute('pi_' . $params['payment_method']);
|
||||
if (!isset($payment_instrument_id)) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Payment method could not be matched to existing payment instrument.'),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -80,16 +82,16 @@ class CRM_Twingle_Submission {
|
|||
$params['payment_instrument_id'] = $payment_instrument_id;
|
||||
|
||||
// Validate date for parameter "confirmed_at".
|
||||
if (!DateTime::createFromFormat('YmdHis', $params['confirmed_at'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
if (FALSE === DateTime::createFromFormat('YmdHis', $params['confirmed_at'])) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Invalid date for parameter "confirmed_at".'),
|
||||
'invalid_format'
|
||||
);
|
||||
}
|
||||
|
||||
// Validate date for parameter "user_birthdate".
|
||||
if (!empty($params['user_birthdate']) && !DateTime::createFromFormat('Ymd', $params['user_birthdate'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
if (!empty($params['user_birthdate']) && FALSE === DateTime::createFromFormat('Ymd', $params['user_birthdate'])) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Invalid date for parameter "user_birthdate".'),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -97,9 +99,10 @@ class CRM_Twingle_Submission {
|
|||
|
||||
// Get the gender ID defined within the profile, or return an error if none
|
||||
// matches (i.e. an unknown gender was submitted).
|
||||
if (!empty($params['user_gender'])) {
|
||||
if (!$gender_id = $profile->getAttribute('gender_' . $params['user_gender'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
if (is_string($params['user_gender'])) {
|
||||
$gender_id = $profile->getAttribute('gender_' . $params['user_gender']);
|
||||
if (!isset($gender_id)) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Gender could not be matched to existing gender.'),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -108,12 +111,12 @@ class CRM_Twingle_Submission {
|
|||
}
|
||||
|
||||
// Validate custom fields parameter, if given.
|
||||
if (!empty($params['custom_fields'])) {
|
||||
if (isset($params['custom_fields'])) {
|
||||
if (is_string($params['custom_fields'])) {
|
||||
$params['custom_fields'] = json_decode($params['custom_fields'], TRUE);
|
||||
}
|
||||
if (!is_array($params['custom_fields'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Invalid format for custom fields.'),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -121,13 +124,13 @@ class CRM_Twingle_Submission {
|
|||
}
|
||||
|
||||
// Validate campaign_id, if given.
|
||||
if (!empty($params['campaign_id'])) {
|
||||
if (isset($params['campaign_id'])) {
|
||||
// Check whether campaign_id is a numeric string and cast it to an integer.
|
||||
if (is_numeric($params['campaign_id'])) {
|
||||
$params['campaign_id'] = intval($params['campaign_id']);
|
||||
}
|
||||
else {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('campaign_id must be a numeric string. '),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -140,7 +143,7 @@ class CRM_Twingle_Submission {
|
|||
['id' => $params['campaign_id']]
|
||||
);
|
||||
}
|
||||
catch (CiviCRM_API3_Exception $e) {
|
||||
catch (CRM_Core_Exception $e) {
|
||||
unset($params['campaign_id']);
|
||||
}
|
||||
}
|
||||
|
@ -152,28 +155,33 @@ class CRM_Twingle_Submission {
|
|||
*
|
||||
* @param string $contact_type
|
||||
* The contact type to look for/to create.
|
||||
* @param array $contact_data
|
||||
* @param array<string, mixed> $contact_data
|
||||
* Data to use for contact lookup/to create a contact with.
|
||||
* @param CRM_Twingle_Profile $profile
|
||||
* Profile used for this process
|
||||
* @param array $submission
|
||||
* @param array<string, mixed> $submission
|
||||
* Submission data
|
||||
*
|
||||
* @return int|NULL
|
||||
* The ID of the matching/created contact, or NULL if no matching contact
|
||||
* was found and no new contact could be created.
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @throws \CRM_Core_Exception
|
||||
* When invalid data was given.
|
||||
*/
|
||||
public static function getContact($contact_type, $contact_data, $profile, $submission = []) {
|
||||
public static function getContact(
|
||||
string $contact_type,
|
||||
array $contact_data,
|
||||
CRM_Twingle_Profile $profile,
|
||||
array $submission = []
|
||||
) {
|
||||
// If no parameters are given, do nothing.
|
||||
if (empty($contact_data)) {
|
||||
if ([] === $contact_data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// add xcm profile
|
||||
$xcm_profile = $profile->getAttribute('xcm_profile');
|
||||
if (!empty($xcm_profile)) {
|
||||
if (isset($xcm_profile) && '' !== $xcm_profile) {
|
||||
$contact_data['xcm_profile'] = $xcm_profile;
|
||||
}
|
||||
|
||||
|
@ -181,7 +189,7 @@ class CRM_Twingle_Submission {
|
|||
CRM_Twingle_Submission::setCampaign($contact_data, 'contact', $submission, $profile);
|
||||
|
||||
// Prepare values: country.
|
||||
if (!empty($contact_data['country'])) {
|
||||
if (isset($contact_data['country'])) {
|
||||
if (is_numeric($contact_data['country'])) {
|
||||
// If a country ID is given, update the parameters.
|
||||
$contact_data['country_id'] = $contact_data['country'];
|
||||
|
@ -190,12 +198,12 @@ class CRM_Twingle_Submission {
|
|||
else {
|
||||
// Look up the country depending on the given ISO code.
|
||||
$country = civicrm_api3('Country', 'get', ['iso_code' => $contact_data['country']]);
|
||||
if (!empty($country['id'])) {
|
||||
if (isset($country['id'])) {
|
||||
$contact_data['country_id'] = $country['id'];
|
||||
unset($contact_data['country']);
|
||||
}
|
||||
else {
|
||||
throw new \CiviCRM_API3_Exception(
|
||||
throw new \CRM_Core_Exception(
|
||||
E::ts('Unknown country %1.', [1 => $contact_data['country']]),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -204,7 +212,7 @@ class CRM_Twingle_Submission {
|
|||
}
|
||||
|
||||
// Prepare values: language.
|
||||
if (!empty($contact_data['preferred_language'])) {
|
||||
if (is_string($contact_data['preferred_language']) && '' !== $contact_data['preferred_language']) {
|
||||
$mapping = CRM_Core_I18n_PseudoConstant::longForShortMapping();
|
||||
// Override the default mapping for German.
|
||||
$mapping['de'] = 'de_DE';
|
||||
|
@ -214,39 +222,31 @@ class CRM_Twingle_Submission {
|
|||
// Pass to XCM.
|
||||
$contact_data['contact_type'] = $contact_type;
|
||||
$contact = civicrm_api3('Contact', 'getorcreate', $contact_data);
|
||||
if (empty($contact['id'])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $contact['id'];
|
||||
return isset($contact['id']) ? (int) $contact['id'] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares an organisation's work address, unless the contact already has one.
|
||||
*
|
||||
* @param $contact_id
|
||||
* @param int $contact_id
|
||||
* The ID of the contact to share the organisation address with.
|
||||
* @param $organisation_id
|
||||
* @param int $organisation_id
|
||||
* The ID of the organisation whose address to share with the contact.
|
||||
* @param $location_type_id
|
||||
* @param int $location_type_id
|
||||
* The ID of the location type to use for address lookup.
|
||||
*
|
||||
* @return boolean
|
||||
* Whether the organisation address has been shared with the contact.
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @throws \CRM_Core_Exception
|
||||
* When looking up or creating the shared address failed.
|
||||
*/
|
||||
public static function shareWorkAddress(
|
||||
$contact_id,
|
||||
$organisation_id,
|
||||
$location_type_id = self::LOCATION_TYPE_ID_WORK
|
||||
int $contact_id,
|
||||
int $organisation_id,
|
||||
int $location_type_id = self::LOCATION_TYPE_ID_WORK
|
||||
) {
|
||||
if (empty($organisation_id)) {
|
||||
// Only if organisation exists.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check whether organisation has a WORK address.
|
||||
$existing_org_addresses = civicrm_api3('Address', 'get', [
|
||||
'contact_id' => $organisation_id,
|
||||
|
@ -285,13 +285,9 @@ class CRM_Twingle_Submission {
|
|||
* @param int $organisation_id
|
||||
* The ID of the employer contact.
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @throws \CRM_Core_Exception
|
||||
*/
|
||||
public static function updateEmployerRelation($contact_id, $organisation_id) {
|
||||
if (empty($contact_id) || empty($organisation_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
public static function updateEmployerRelation(int $contact_id, int $organisation_id): void {
|
||||
// see if there is already one
|
||||
$existing_relationship = civicrm_api3('Relationship', 'get', [
|
||||
'relationship_type_id' => self::EMPLOYER_RELATIONSHIP_TYPE_ID,
|
||||
|
@ -318,15 +314,15 @@ class CRM_Twingle_Submission {
|
|||
* functionality is activated within the Twingle extension settings.
|
||||
*
|
||||
* @return bool
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @throws \CRM_Core_Exception
|
||||
*/
|
||||
public static function civiSepaEnabled() {
|
||||
$sepa_extension = civicrm_api3('Extension', 'get', [
|
||||
'full_name' => 'org.project60.sepa',
|
||||
'is_active' => 1,
|
||||
]);
|
||||
return Civi::settings()->get('twingle_use_sepa')
|
||||
&& $sepa_extension['count'];
|
||||
return (bool) Civi::settings()->get('twingle_use_sepa')
|
||||
&& $sepa_extension['count'] >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -337,7 +333,7 @@ class CRM_Twingle_Submission {
|
|||
* The submitted "donation_rhythm" paramter according to the API action
|
||||
* specification.
|
||||
*
|
||||
* @return array
|
||||
* @return array{'frequency_unit'?: string, 'frequency_interval'?: int}
|
||||
* An array with "frequency_unit" and "frequency_interval" keys, to be added
|
||||
* to contribution parameter arrays.
|
||||
*/
|
||||
|
@ -378,19 +374,21 @@ class CRM_Twingle_Submission {
|
|||
* @return int
|
||||
* The next possible day of this or the next month to start collecting.
|
||||
*/
|
||||
public static function getSEPACycleDay($start_date, $creditor_id) {
|
||||
public static function getSEPACycleDay($start_date, $creditor_id): int {
|
||||
$buffer_days = (int) CRM_Sepa_Logic_Settings::getSetting('pp_buffer_days');
|
||||
$frst_notice_days = (int) CRM_Sepa_Logic_Settings::getSetting('batching.FRST.notice', $creditor_id);
|
||||
$earliest_rcur_date = strtotime("$start_date + $frst_notice_days days + $buffer_days days");
|
||||
if (FALSE === ($earliest_rcur_date = strtotime("$start_date + $frst_notice_days days + $buffer_days days"))) {
|
||||
throw new BaseException(E::ts('Could not calculate SEPA cycle day from configuration.'));
|
||||
}
|
||||
|
||||
// Find the next cycle day
|
||||
$cycle_days = CRM_Sepa_Logic_Settings::getListSetting('cycledays', range(1, 28), $creditor_id);
|
||||
$earliest_cycle_day = $earliest_rcur_date;
|
||||
while (!in_array(date('j', $earliest_cycle_day), $cycle_days)) {
|
||||
while (!in_array(date('j', $earliest_cycle_day), $cycle_days, TRUE)) {
|
||||
$earliest_cycle_day = strtotime('+ 1 day', $earliest_cycle_day);
|
||||
}
|
||||
|
||||
return date('j', $earliest_cycle_day);
|
||||
return (int) date('j', $earliest_cycle_day);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -399,16 +397,21 @@ class CRM_Twingle_Submission {
|
|||
* from the submission data. Should that be empty, the profile's default
|
||||
* campaign is used.
|
||||
*
|
||||
* @param array $entity_data
|
||||
* @param array<string, mixed> $entity_data
|
||||
* the data set where the campaign_id should be set
|
||||
* @param string $context
|
||||
* defines the type of the entity_data: one of 'contribution', 'membership','mandate', 'recurring', 'contact'
|
||||
* @param array $submission
|
||||
* @param array<string, mixed> $submission
|
||||
* the submitted data
|
||||
* @param CRM_Twingle_Profile $profile
|
||||
* the twingle profile used
|
||||
*/
|
||||
public static function setCampaign(&$entity_data, $context, $submission, $profile) {
|
||||
public static function setCampaign(
|
||||
array &$entity_data,
|
||||
string $context,
|
||||
array $submission,
|
||||
CRM_Twingle_Profile $profile
|
||||
): void {
|
||||
// first: make sure it's not set from other workflows
|
||||
unset($entity_data['campaign_id']);
|
||||
|
||||
|
@ -418,13 +421,13 @@ class CRM_Twingle_Submission {
|
|||
// backward compatibility:
|
||||
$enabled_contexts = ['contribution', 'contact'];
|
||||
}
|
||||
if (in_array($context, $enabled_contexts)) {
|
||||
if (in_array($context, $enabled_contexts, TRUE)) {
|
||||
// use the submitted campaign if set
|
||||
if (!empty($submission['campaign_id'])) {
|
||||
if (is_numeric($submission['campaign_id'])) {
|
||||
$entity_data['campaign_id'] = $submission['campaign_id'];
|
||||
}
|
||||
// otherwise use the profile's
|
||||
elseif (!empty($campaign = $profile->getAttribute('campaign'))) {
|
||||
elseif (is_numeric($campaign = $profile->getAttribute('campaign'))) {
|
||||
$entity_data['campaign_id'] = $campaign;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
declare(strict_types = 1);
|
||||
|
||||
use CRM_Twingle_ExtensionUtil as E;
|
||||
use Civi\Twingle\Exceptions\BaseException;
|
||||
|
||||
class CRM_Twingle_Tools {
|
||||
|
||||
|
@ -29,11 +30,11 @@ class CRM_Twingle_Tools {
|
|||
* Check if the attempted modification of the recurring contribution is allowed.
|
||||
* If not, an exception will be raised
|
||||
*
|
||||
* @param $recurring_contribution_id int
|
||||
* @param $change array
|
||||
* @param int $recurring_contribution_id
|
||||
* @param array<mixed> $change
|
||||
* @throws Exception if the change is not allowed
|
||||
*/
|
||||
public static function checkRecurringContributionChange($recurring_contribution_id, $change) {
|
||||
public static function checkRecurringContributionChange(int $recurring_contribution_id, array $change): void {
|
||||
// check if a change to the status is planned
|
||||
if (empty($change['contribution_status_id'])) {
|
||||
return;
|
||||
|
@ -77,14 +78,17 @@ class CRM_Twingle_Tools {
|
|||
}
|
||||
|
||||
// this _IS_ on of the cases where we should step in:
|
||||
CRM_Twingle_Tools::processRecurringContributionTermination($recurring_contribution_id, $recurring_contribution);
|
||||
CRM_Twingle_Tools::processRecurringContributionTermination(
|
||||
$recurring_contribution_id,
|
||||
$recurring_contribution
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $recurring_contribution_id int recurring contribution ID to check
|
||||
* @param $recurring_contribution array recurring contribution data, optional
|
||||
* @return bool|null true, false or null if can't be determined
|
||||
* @throws CiviCRM_API3_Exception
|
||||
* @throws \CRM_Core_Exception
|
||||
*/
|
||||
public static function isTwingleRecurringContribution($recurring_contribution_id, $recurring_contribution = NULL) {
|
||||
// this currently only works with prefixes
|
||||
|
@ -106,11 +110,13 @@ class CRM_Twingle_Tools {
|
|||
/**
|
||||
* Execute the recurring contribution protection
|
||||
*
|
||||
* @param $recurring_contribution_id int recurring contribution ID
|
||||
* @param $recurring_contribution array recurring contribution fields
|
||||
* @param int $recurring_contribution_id
|
||||
* Recurring contribution ID.
|
||||
* @param array<mixed> $recurring_contribution
|
||||
* Recurring contribution fields.
|
||||
* @throws Exception could be one of the measures
|
||||
*/
|
||||
public static function processRecurringContributionTermination($recurring_contribution_id, $recurring_contribution) {
|
||||
public static function processRecurringContributionTermination(int $recurring_contribution_id, array $recurring_contribution) {
|
||||
// check if we're suspended
|
||||
if (self::$protection_suspended) {
|
||||
return;
|
||||
|
@ -124,7 +130,7 @@ class CRM_Twingle_Tools {
|
|||
|
||||
case CRM_Twingle_Config::RCUR_PROTECTION_EXCEPTION:
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
throw new Exception(E::ts(
|
||||
throw new BaseException(E::ts(
|
||||
'This is a Twingle recurring contribution. It should be terminated through the Twingle interface, otherwise it will still be collected.'
|
||||
));
|
||||
|
||||
|
@ -183,10 +189,10 @@ class CRM_Twingle_Tools {
|
|||
/**
|
||||
* Check if the given payment instrument is SEPA
|
||||
*
|
||||
* @param $payment_instrument_id string payment instrument
|
||||
* @param string $payment_instrument_id
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isSDD($payment_instrument_id) {
|
||||
public static function isSDD(string $payment_instrument_id) {
|
||||
static $sepa_payment_instruments = NULL;
|
||||
if ($sepa_payment_instruments === NULL) {
|
||||
// init with instrument names
|
||||
|
@ -208,11 +214,10 @@ class CRM_Twingle_Tools {
|
|||
/**
|
||||
* Get a CiviSEPA mandate for the given contribution ID
|
||||
*
|
||||
* @param $contribution_id integer contribution ID *or* recurring contribution ID
|
||||
* @return integer mandate ID or null
|
||||
* @param int $contribution_id contribution ID *or* recurring contribution ID
|
||||
* @return array<string, mixed>|null mandate or null
|
||||
*/
|
||||
public static function getMandateFor($contribution_id) {
|
||||
$contribution_id = (int) $contribution_id;
|
||||
public static function getMandateFor(int $contribution_id): ?array {
|
||||
if ($contribution_id) {
|
||||
try {
|
||||
// try recurring mandate
|
||||
|
|
|
@ -25,7 +25,7 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base {
|
|||
/**
|
||||
* Installer script
|
||||
*/
|
||||
public function install() {
|
||||
public function install(): void {
|
||||
// create a DB table for the twingle profiles
|
||||
$this->executeSqlFile('sql/civicrm_twingle_profile.sql');
|
||||
|
||||
|
@ -43,7 +43,7 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base {
|
|||
* /**
|
||||
* Copy financial_type_id setting to new setting financial_type_id_recur.
|
||||
*/
|
||||
public function upgrade_4000() {
|
||||
public function upgrade_4000(): bool {
|
||||
$this->ctx->log->info('Applying update 4000: Copying Financial type to new setting Financial type (recurring).');
|
||||
foreach (CRM_Twingle_Profile::getProfiles() as $profile) {
|
||||
$profile->setAttribute('financial_type_id_recur', $profile->getAttribute('financial_type_id'));
|
||||
|
@ -57,7 +57,7 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base {
|
|||
*
|
||||
* @link https://civicrm.org/advisory/civi-sa-2019-21-poi-saved-search-and-report-instance-apis
|
||||
*/
|
||||
public function upgrade_5011() {
|
||||
public function upgrade_5011(): bool {
|
||||
// Do not use CRM_Core_BAO::getItem() or Civi::settings()->get().
|
||||
// Extract and unserialize directly from the database.
|
||||
$twingle_profiles_query = CRM_Core_DAO::executeQuery("
|
||||
|
@ -78,14 +78,14 @@ class CRM_Twingle_Upgrader extends CRM_Extension_Upgrader_Base {
|
|||
* @return TRUE on success
|
||||
* @throws Exception
|
||||
*/
|
||||
public function upgrade_5140() {
|
||||
public function upgrade_5140(): bool {
|
||||
$this->ctx->log->info('Converting twingle profiles.');
|
||||
|
||||
// create a DB table for the twingle profiles
|
||||
$this->executeSqlFile('sql/civicrm_twingle_profile.sql');
|
||||
|
||||
// migrate the current profiles
|
||||
if ($profiles_data = Civi::settings()->get('twingle_profiles')) {
|
||||
if (is_array($profiles_data = Civi::settings()->get('twingle_profiles'))) {
|
||||
foreach ($profiles_data as $profile_name => $profile_data) {
|
||||
$profile = new CRM_Twingle_Profile($profile_name, $profile_data);
|
||||
$data = json_encode($profile->getData());
|
||||
|
|
|
@ -35,14 +35,16 @@ class BaseException extends \Exception {
|
|||
|
||||
/**
|
||||
* BaseException Constructor
|
||||
* @param string $message
|
||||
* Error message
|
||||
* @param string $error_code
|
||||
* A meaningful error code
|
||||
* @param string|null $message
|
||||
* Error message
|
||||
* @param string|null $error_code
|
||||
* A meaningful error code
|
||||
* @param \Throwable|null $previous
|
||||
* A previously thrown exception to include.
|
||||
*/
|
||||
public function __construct(string $message = '', string $error_code = '') {
|
||||
parent::__construct($message, 1);
|
||||
$this->log_message = !empty($message) ? E::LONG_NAME . ': ' . $message : '';
|
||||
public function __construct(?string $message = '', ?string $error_code = '', ?\Throwable $previous = NULL) {
|
||||
parent::__construct($message, 1, $previous);
|
||||
$this->log_message = '' !== $message ? E::LONG_NAME . ': ' . $message : '';
|
||||
$this->code = $error_code;
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,7 @@ class BaseException extends \Exception {
|
|||
* @return string
|
||||
*/
|
||||
public function getErrorCode() {
|
||||
return $this->code;
|
||||
return (string) $this->code;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use CRM_Twingle_ExtensionUtil as E;
|
|||
* TwingleDonation.Cancel API specification (optional)
|
||||
* This is used for documentation and validation.
|
||||
*
|
||||
* @param array $params description of fields supported by this API call
|
||||
* @param array<string, array<string, mixed>> $params description of fields supported by this API call
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
|
@ -61,8 +61,8 @@ function _civicrm_api3_twingle_donation_Cancel_spec(&$params) {
|
|||
/**
|
||||
* TwingleDonation.Cancel API
|
||||
*
|
||||
* @param array $params
|
||||
* @return array API result descriptor
|
||||
* @param array<string, mixed> $params
|
||||
* @return array<string, mixed> API result descriptor
|
||||
* @see civicrm_api3_create_success
|
||||
* @see civicrm_api3_create_error
|
||||
*/
|
||||
|
@ -75,7 +75,7 @@ function civicrm_api3_twingle_donation_Cancel($params) {
|
|||
try {
|
||||
// Validate date for parameter "cancelled_at".
|
||||
if (!DateTime::createFromFormat('YmdHis', $params['cancelled_at'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Invalid date for parameter "cancelled_at".'),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -89,7 +89,7 @@ function civicrm_api3_twingle_donation_Cancel($params) {
|
|||
]);
|
||||
$contribution_type = 'Contribution';
|
||||
}
|
||||
catch (CiviCRM_API3_Exception $exception) {
|
||||
catch (CRM_Core_Exception $exception) {
|
||||
$contribution = civicrm_api3('ContributionRecur', 'getsingle', [
|
||||
'trxn_id' => $default_profile->getTransactionID($params['trx_id']),
|
||||
]);
|
||||
|
@ -101,9 +101,9 @@ function civicrm_api3_twingle_donation_Cancel($params) {
|
|||
&& CRM_Twingle_Tools::isSDD($contribution['payment_instrument_id'])
|
||||
) {
|
||||
// End SEPA mandate if applicable.
|
||||
$mandate = CRM_Twingle_Tools::getMandateFor($contribution['id']);
|
||||
$mandate = CRM_Twingle_Tools::getMandateFor((int) $contribution['id']);
|
||||
if (!$mandate) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('SEPA Mandate for contribution [%1 not found.', [1 => $contribution['id']]),
|
||||
'api_error'
|
||||
);
|
||||
|
@ -112,7 +112,7 @@ function civicrm_api3_twingle_donation_Cancel($params) {
|
|||
|
||||
// Mandates can not be terminated in the past.
|
||||
$end_date = date_create_from_format('YmdHis', $params['cancelled_at']);
|
||||
if ($end_date) {
|
||||
if (FALSE !== $end_date) {
|
||||
// Mandates can not be terminated in the past:
|
||||
$end_date = date('Ymd', max(
|
||||
time(),
|
||||
|
@ -128,7 +128,7 @@ function civicrm_api3_twingle_donation_Cancel($params) {
|
|||
$end_date,
|
||||
$params['cancel_reason']
|
||||
)) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Could not terminate SEPA mandate'),
|
||||
'api_error'
|
||||
);
|
||||
|
|
|
@ -21,7 +21,7 @@ use CRM_Twingle_ExtensionUtil as E;
|
|||
* TwingleDonation.Endrecurring API specification (optional)
|
||||
* This is used for documentation and validation.
|
||||
*
|
||||
* @param array $params description of fields supported by this API call
|
||||
* @param array<string, array<string, mixed>> $params description of fields supported by this API call
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
|
@ -54,8 +54,8 @@ function _civicrm_api3_twingle_donation_endrecurring_spec(&$params) {
|
|||
/**
|
||||
* TwingleDonation.Endrecurring API
|
||||
*
|
||||
* @param array $params
|
||||
* @return array API result descriptor
|
||||
* @param array<string, mixed> $params
|
||||
* @return array<string, mixed> API result descriptor
|
||||
* @see civicrm_api3_create_success
|
||||
* @see civicrm_api3_create_error
|
||||
*/
|
||||
|
@ -67,8 +67,8 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
|||
|
||||
try {
|
||||
// Validate date for parameter "ended_at".
|
||||
if (!DateTime::createFromFormat('YmdHis', $params['ended_at'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
if (FALSE === DateTime::createFromFormat('YmdHis', $params['ended_at'])) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Invalid date for parameter "ended_at".'),
|
||||
'invalid_format'
|
||||
);
|
||||
|
@ -86,9 +86,9 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
|||
&& CRM_Twingle_Tools::isSDD($contribution['payment_instrument_id'])
|
||||
) {
|
||||
// END SEPA MANDATE
|
||||
$mandate = CRM_Twingle_Tools::getMandateFor($contribution['id']);
|
||||
if (!$mandate) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
$mandate = CRM_Twingle_Tools::getMandateFor((int) $contribution['id']);
|
||||
if (!isset($mandate)) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('SEPA Mandate for recurring contribution [%1 not found.', [1 => $contribution['id']]),
|
||||
'api_error'
|
||||
);
|
||||
|
@ -96,7 +96,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
|||
|
||||
$mandate_id = $mandate['id'];
|
||||
$end_date = date_create_from_format('YmdHis', $params['ended_at']);
|
||||
if ($end_date) {
|
||||
if (FALSE !== $end_date) {
|
||||
// Mandates can not be terminated in the past:
|
||||
$end_date = date('Ymd', max(
|
||||
time(),
|
||||
|
@ -109,7 +109,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
|||
|
||||
// verify that the mandate has not been terminated in the past
|
||||
if ($mandate['status'] != 'FRST' && $mandate['status'] != 'RCUR') {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('SEPA Mandate [%1] already terminated.', [1 => $mandate_id]),
|
||||
'api_error'
|
||||
);
|
||||
|
@ -120,7 +120,7 @@ function civicrm_api3_twingle_donation_endrecurring($params) {
|
|||
$end_date,
|
||||
E::ts('Mandate closed by TwingleDonation.Endrecurring API call')
|
||||
)) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Could not terminate SEPA mandate'),
|
||||
'api_error'
|
||||
);
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
declare(strict_types = 1);
|
||||
|
||||
use CRM_Twingle_ExtensionUtil as E;
|
||||
use Civi\Twingle\Exceptions\BaseException;
|
||||
|
||||
/**
|
||||
* TwingleDonation.Submit API specification
|
||||
* This is used for documentation and validation.
|
||||
*
|
||||
* @param array $params
|
||||
* @param array<string,array<string,mixed>> $params
|
||||
* Description of fields supported by this API call.
|
||||
*
|
||||
* @return void
|
||||
|
@ -259,8 +260,8 @@ function _civicrm_api3_twingle_donation_Submit_spec(&$params) {
|
|||
/**
|
||||
* TwingleDonation.Submit API
|
||||
*
|
||||
* @param array $params
|
||||
* @return array API result descriptor
|
||||
* @param array<string, mixed> $params
|
||||
* @return array<string, mixed> API result descriptor
|
||||
* @see civicrm_api3_create_success
|
||||
* @see civicrm_api3_create_error
|
||||
*/
|
||||
|
@ -294,7 +295,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
'trxn_id' => $profile->getTransactionID($params['trx_id']),
|
||||
]);
|
||||
if ($existing_contribution['count'] > 0 || $existing_contribution_recur['count'] > 0) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Contribution with the given transaction ID already exists.'),
|
||||
'api_error'
|
||||
);
|
||||
|
@ -303,7 +304,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
// Extract custom field values using the profile's mapping of Twingle fields
|
||||
// to CiviCRM custom fields.
|
||||
$custom_fields = [];
|
||||
if (!empty($params['custom_fields'])) {
|
||||
if (is_array($params['custom_fields'])) {
|
||||
$custom_field_mapping = $profile->getCustomFieldMapping();
|
||||
|
||||
// Make all params available for custom field mapping
|
||||
|
@ -343,11 +344,9 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
'user_city' => 'city',
|
||||
'user_country' => 'country',
|
||||
] as $address_param => $address_component) {
|
||||
if (!empty($params[$address_param])) {
|
||||
if (isset($params[$address_param]) && '' !== $params[$address_param]) {
|
||||
$params[$address_component] = $params[$address_param];
|
||||
if ($address_param != $address_component) {
|
||||
unset($params[$address_param]);
|
||||
}
|
||||
unset($params[$address_param]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,13 +368,13 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
}
|
||||
|
||||
// Prepare parameter mapping for organisation.
|
||||
if (!empty($params['user_company'])) {
|
||||
if (is_string($params['user_company']) && '' !== $params['user_company']) {
|
||||
$params['organization_name'] = $params['user_company'];
|
||||
unset($params['user_company']);
|
||||
}
|
||||
|
||||
// Remove parameter "id".
|
||||
if (!empty($params['id'])) {
|
||||
if (isset($params['id'])) {
|
||||
unset($params['id']);
|
||||
}
|
||||
|
||||
|
@ -419,67 +418,67 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
}
|
||||
|
||||
// Get the prefix ID defined within the profile
|
||||
if (!empty($params['user_gender'])) {
|
||||
$prefix_id = (int) $profile->getAttribute('prefix_' . $params['user_gender']);
|
||||
if ($prefix_id) {
|
||||
$contact_data['prefix_id'] = $prefix_id;
|
||||
}
|
||||
if (
|
||||
isset($params['user_gender'])
|
||||
&& NULL !== ($prefix_id = $profile->getAttribute('prefix_' . $params['user_gender']))
|
||||
) {
|
||||
$contact_data['prefix_id'] = $prefix_id;
|
||||
}
|
||||
|
||||
// Add custom field values.
|
||||
if (!empty($custom_fields['Contact'])) {
|
||||
if (isset($custom_fields['Contact'])) {
|
||||
$contact_data += $custom_fields['Contact'];
|
||||
}
|
||||
if (!empty($custom_fields['Individual'])) {
|
||||
if (isset($custom_fields['Individual'])) {
|
||||
$contact_data += $custom_fields['Individual'];
|
||||
}
|
||||
|
||||
// Organisation lookup.
|
||||
if (!empty($params['organization_name'])) {
|
||||
if (is_string($params['organization_name']) && '' !== $params['organization_name']) {
|
||||
$organisation_data = [
|
||||
'organization_name' => $params['organization_name'],
|
||||
];
|
||||
|
||||
// Add custom field values.
|
||||
if (!empty($custom_fields['Organization'])) {
|
||||
if (isset($custom_fields['Organization'])) {
|
||||
$organisation_data += $custom_fields['Organization'];
|
||||
}
|
||||
|
||||
if (!empty($submitted_address)) {
|
||||
if ([] !== $submitted_address) {
|
||||
$organisation_data += $submitted_address;
|
||||
// Use configured location type for organisation address.
|
||||
$organisation_data['location_type_id'] = (int) $profile->getAttribute('location_type_id_organisation');
|
||||
}
|
||||
if (!$organisation_id = CRM_Twingle_Submission::getContact(
|
||||
if (!is_int($organisation_id = CRM_Twingle_Submission::getContact(
|
||||
'Organization',
|
||||
$organisation_data,
|
||||
$profile,
|
||||
$params
|
||||
)) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
))) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Organisation contact could not be found or created.'),
|
||||
'api_error'
|
||||
);
|
||||
}
|
||||
}
|
||||
elseif (!empty($submitted_address)) {
|
||||
elseif ([] !== $submitted_address) {
|
||||
$contact_data += $submitted_address;
|
||||
}
|
||||
|
||||
if (!$contact_id = CRM_Twingle_Submission::getContact(
|
||||
if (!is_int($contact_id = CRM_Twingle_Submission::getContact(
|
||||
'Individual',
|
||||
$contact_data,
|
||||
$profile,
|
||||
$params
|
||||
)) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
))) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Individual contact could not be found or created.'),
|
||||
'api_error'
|
||||
);
|
||||
}
|
||||
|
||||
// Save user_extrafield as contact note.
|
||||
if (!empty($params['user_extrafield'])) {
|
||||
if (isset($params['user_extrafield']) && '' != $params['user_extrafield']) {
|
||||
civicrm_api3('Note', 'create', [
|
||||
'entity_table' => 'civicrm_contact',
|
||||
'entity_id' => $contact_id,
|
||||
|
@ -512,13 +511,13 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
// If usage of double opt-in is selected, use MailingEventSubscribe.create
|
||||
// to add contact to newsletter groups defined in the profile
|
||||
$result_values['newsletter']['newsletter_double_opt_in']
|
||||
= ($profile->getAttribute('newsletter_double_opt_in'))
|
||||
= (bool) $profile->getAttribute('newsletter_double_opt_in')
|
||||
? 'true'
|
||||
: 'false';
|
||||
if (
|
||||
$profile->getAttribute('newsletter_double_opt_in') &&
|
||||
!empty($params['newsletter']) &&
|
||||
!empty($groups = $profile->getAttribute('newsletter_groups'))
|
||||
(bool) $profile->getAttribute('newsletter_double_opt_in')
|
||||
&& isset($params['newsletter'])
|
||||
&& is_array($groups = $profile->getAttribute('newsletter_groups'))
|
||||
) {
|
||||
$group_memberships = array_column(
|
||||
civicrm_api3(
|
||||
|
@ -539,7 +538,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
'id' => (int) $group_id,
|
||||
]
|
||||
)['visibility'] == 'Public Pages';
|
||||
if (!in_array($group_id, $group_memberships) && $is_public_group) {
|
||||
if (!in_array($group_id, $group_memberships, FALSE) && $is_public_group) {
|
||||
$result_values['newsletter'][][$group_id] = civicrm_api3(
|
||||
'MailingEventSubscribe',
|
||||
'create',
|
||||
|
@ -557,8 +556,8 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
// If requested, add contact to newsletter groups defined in the profile.
|
||||
}
|
||||
elseif (
|
||||
!empty($params['newsletter'])
|
||||
&& !empty($groups = $profile->getAttribute('newsletter_groups'))
|
||||
isset($params['newsletter'])
|
||||
&& is_array($groups = $profile->getAttribute('newsletter_groups'))
|
||||
) {
|
||||
foreach ($groups as $group_id) {
|
||||
civicrm_api3(
|
||||
|
@ -575,7 +574,10 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
}
|
||||
|
||||
// If requested, add contact to postinfo groups defined in the profile.
|
||||
if (!empty($params['postinfo']) && !empty($groups = $profile->getAttribute('postinfo_groups'))) {
|
||||
if (
|
||||
isset($params['postinfo'])
|
||||
&& is_array($groups = $profile->getAttribute('postinfo_groups'))
|
||||
) {
|
||||
foreach ($groups as $group_id) {
|
||||
civicrm_api3('GroupContact', 'create', [
|
||||
'group_id' => $group_id,
|
||||
|
@ -588,7 +590,10 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
|
||||
// If requested, add contact to donation_receipt groups defined in the
|
||||
// profile.
|
||||
if (!empty($params['donation_receipt']) && !empty($groups = $profile->getAttribute('donation_receipt_groups'))) {
|
||||
if (
|
||||
isset($params['donation_receipt'])
|
||||
&& is_array($groups = $profile->getAttribute('donation_receipt_groups'))
|
||||
) {
|
||||
foreach ($groups as $group_id) {
|
||||
civicrm_api3('GroupContact', 'create', [
|
||||
'group_id' => $group_id,
|
||||
|
@ -611,18 +616,18 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
];
|
||||
|
||||
// Add custom field values.
|
||||
if (!empty($custom_fields['Contribution'])) {
|
||||
if (isset($custom_fields['Contribution'])) {
|
||||
$contribution_data += $custom_fields['Contribution'];
|
||||
}
|
||||
|
||||
if (!empty($params['purpose'])) {
|
||||
if (isset($params['purpose'])) {
|
||||
$contribution_data['note'] = $params['purpose'];
|
||||
}
|
||||
|
||||
// set campaign, subject to configuration
|
||||
CRM_Twingle_Submission::setCampaign($contribution_data, 'contribution', $params, $profile);
|
||||
|
||||
if (!empty($contribution_source = $profile->getAttribute('contribution_source'))) {
|
||||
if (NULL !== ($contribution_source = $profile->getAttribute('contribution_source'))) {
|
||||
$contribution_data['source'] = $contribution_source;
|
||||
}
|
||||
|
||||
|
@ -637,8 +642,8 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
'debit_iban',
|
||||
'debit_bic',
|
||||
] as $sepa_attribute) {
|
||||
if (empty($params[$sepa_attribute])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
if (!isset($params[$sepa_attribute])) {
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Missing attribute %1 for SEPA mandate', [
|
||||
1 => $sepa_attribute,
|
||||
]),
|
||||
|
@ -648,6 +653,11 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
}
|
||||
|
||||
$creditor_id = $profile->getAttribute('sepa_creditor_id');
|
||||
if (!is_int($creditor_id)) {
|
||||
throw new BaseException(
|
||||
E::ts('SEPA creditor is not configured for profile "%1".', [1 => $profile->getName()])
|
||||
);
|
||||
}
|
||||
|
||||
// Compose mandate data from contribution data, ...
|
||||
$mandate_data =
|
||||
|
@ -669,10 +679,10 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
// phpcs:ignore Drupal.Formatting.SpaceUnaryOperator.PlusMinus
|
||||
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
||||
// Add custom field values.
|
||||
if (!empty($custom_fields['ContributionRecur'])) {
|
||||
if (isset($custom_fields['ContributionRecur'])) {
|
||||
$mandate_data += $custom_fields['ContributionRecur'];
|
||||
}
|
||||
if (!empty($mandate_source = $profile->getAttribute('contribution_source'))) {
|
||||
if (NULL !== ($mandate_source = $profile->getAttribute('contribution_source'))) {
|
||||
$mandate_data['source'] = $mandate_source;
|
||||
}
|
||||
|
||||
|
@ -691,7 +701,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
|
||||
// If requested, let CiviSEPA generate the mandate reference
|
||||
$use_own_mandate_reference = Civi::settings()->get('twingle_dont_use_reference');
|
||||
if (!empty($use_own_mandate_reference)) {
|
||||
if ((bool) $use_own_mandate_reference) {
|
||||
unset($mandate_data['reference']);
|
||||
}
|
||||
|
||||
|
@ -730,7 +740,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
+ CRM_Twingle_Submission::getFrequencyMapping($params['donation_rhythm']);
|
||||
|
||||
// Add custom field values.
|
||||
if (!empty($custom_fields['ContributionRecur'])) {
|
||||
if (isset($custom_fields['ContributionRecur'])) {
|
||||
$contribution_recur_data += $custom_fields['ContributionRecur'];
|
||||
$contribution_data += $custom_fields['ContributionRecur'];
|
||||
}
|
||||
|
@ -740,7 +750,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
|
||||
$contribution_recur = civicrm_api3('ContributionRecur', 'create', $contribution_recur_data);
|
||||
if ($contribution_recur['is_error']) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Could not create recurring contribution.'),
|
||||
'api_error'
|
||||
);
|
||||
|
@ -766,7 +776,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
]);
|
||||
$contribution_data['contribution_recur_id'] = $parent_contribution['id'];
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
catch (CRM_Core_Exception $exception) {
|
||||
$result_values['parent_contribution'] = E::ts(
|
||||
'Could not find recurring contribution with given parent transaction ID.'
|
||||
);
|
||||
|
@ -775,7 +785,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
|
||||
$contribution = civicrm_api3('Contribution', 'create', $contribution_data);
|
||||
if ($contribution['is_error']) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
throw new CRM_Core_Exception(
|
||||
E::ts('Could not create contribution'),
|
||||
'api_error'
|
||||
);
|
||||
|
@ -799,12 +809,12 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
}
|
||||
else {
|
||||
// this is a follow-up recurring payment
|
||||
$membership_type_id = FALSE;
|
||||
$membership_type_id = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// CREATE the membership if required
|
||||
if (!empty($membership_type_id)) {
|
||||
if (isset($membership_type_id)) {
|
||||
$membership_data = [
|
||||
'contact_id' => $contact_id,
|
||||
'membership_type_id' => $membership_type_id,
|
||||
|
@ -821,7 +831,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
|
||||
// call the postprocess API
|
||||
$postprocess_call = $profile->getAttribute('membership_postprocess_call');
|
||||
if (!empty($postprocess_call)) {
|
||||
if (is_string($postprocess_call)) {
|
||||
[$pp_entity, $pp_action] = explode('.', $postprocess_call, 2);
|
||||
try {
|
||||
// gather the contribution IDs
|
||||
|
@ -829,7 +839,7 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
if (isset($contribution_recur['id'])) {
|
||||
$recurring_contribution_id = $contribution_recur['id'];
|
||||
}
|
||||
elseif (!empty($result_values['sepa_mandate'])) {
|
||||
elseif (isset($result_values['sepa_mandate'])) {
|
||||
$mandate = reset($result_values['sepa_mandate']);
|
||||
if ($mandate['entity_table'] == 'civicrm_contribution_recur') {
|
||||
$recurring_contribution_id = (int) $mandate['entity_id'];
|
||||
|
@ -851,14 +861,20 @@ function civicrm_api3_twingle_donation_Submit($params) {
|
|||
// refresh membership data
|
||||
$result_values['membership'] = civicrm_api3('Membership', 'getsingle', ['id' => $membership['id']]);
|
||||
}
|
||||
catch (CiviCRM_API3_Exception $ex) {
|
||||
catch (CRM_Core_Exception $exception) {
|
||||
// TODO: more error handling?
|
||||
Civi::log()
|
||||
->warning(
|
||||
"Twingle membership postprocessing call {$pp_entity}.{$pp_action} has failed: " . $ex->getMessage()
|
||||
);
|
||||
throw new Exception(
|
||||
E::ts('Twingle membership postprocessing call has failed, see log for more information')
|
||||
Civi::log()->warning(
|
||||
sprintf(
|
||||
'Twingle membership postprocessing call %s.%s has failed: %s',
|
||||
$pp_entity,
|
||||
$pp_action,
|
||||
$exception->getMessage()
|
||||
)
|
||||
);
|
||||
throw new BaseException(
|
||||
E::ts('Twingle membership postprocessing call has failed, see log for more information'),
|
||||
NULL,
|
||||
$exception
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<!-- Conflicts with PHPStan type hints -->
|
||||
<exclude name="Drupal.Commenting.VariableComment.IncorrectVarType"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.ParamTypeSpaces"/>
|
||||
<exclude name="Drupal.Commenting.FunctionComment.ReturnTypeSpaces"/>
|
||||
<exclude name="Drupal.Commenting.VariableComment.MissingVar"/>
|
||||
|
||||
<!-- Don't enforce phpdoc type hint because it (might) only duplicate a PHP type hint -->
|
||||
|
|
|
@ -9,5 +9,6 @@ parameters:
|
|||
- {VENDOR_DIR}/civicrm/civicrm-core/Civi/
|
||||
- {VENDOR_DIR}/civicrm/civicrm-core/CRM/
|
||||
- {VENDOR_DIR}/civicrm/civicrm-core/api/
|
||||
- {VENDOR_DIR}/civicrm/civicrm-packages/
|
||||
bootstrapFiles:
|
||||
- {VENDOR_DIR}/autoload.php
|
||||
|
|
|
@ -8,7 +8,7 @@ use CRM_Twingle_ExtensionUtil as E;
|
|||
*/
|
||||
function twingle_civicrm_pre($op, $objectName, $id, &$params) {
|
||||
if ($objectName == 'ContributionRecur' && $op == 'edit') {
|
||||
CRM_Twingle_Tools::checkRecurringContributionChange($id, $params);
|
||||
CRM_Twingle_Tools::checkRecurringContributionChange((int) $id, $params);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue