Commit 6af2fd06 authored by mattwire's avatar mattwire
Browse files

Initial commit

parents
<?php
use CRM_Activityimportrtf_ExtensionUtil as E;
class CRM_Activityimportrtf_Advimport_Activityrtf extends CRM_Advimport_Helper_PHPExcel {
/**
* Available fields.
*/
function getMapping(&$form) {
$map = [
'contact_id' => [
'label' => 'ContactID',
'field' => 'contact_id',
'mandatory' => TRUE,
'validate' => 'Integer',
],
'create_date' => [
'label' => 'Create Date',
'aliases' => ['CreateDate'],
'field' => 'create_date',
'mandatory' => TRUE,
'validate' => 'String',
'description' => 'The create date for the activity',
],
'subject_a' => [
'label' => 'Subject A',
'aliases' => ['CorrespType'],
'field' => 'subject_a',
'mandatory' => TRUE,
'validate' => 'String',
'description' => 'The first part of the subject',
],
'subject_b' => [
'label' => 'Subject B',
'aliases' => ['Subject'],
'field' => 'subject_b',
'mandatory' => FALSE,
'validate' => 'String',
'description' => 'The second part of the subject',
],
'rtf_data' => [
'label' => 'RTF data',
'aliases' => ['Correspondence'],
'field' => 'rtf_data',
'mandatory' => TRUE,
'validate' => 'String',
'description' => 'Data in rich text format',
],
];
return $map;
}
/**
* Returns a human-readable name for this helper.
*/
function getHelperLabel() {
return E::ts("Activity Import RTF");
}
/**
* Import an item gotten from the queue.
*
* This is where, in custom PHP import scripts, you would program all
* the logic on how to handle imports the old fashioned way.
*/
function processItem($params) {
$params = CRM_Activityimportrtf_Advimport_Helper::cleanupParams($params);
CRM_Activityimportrtf_Advimport_Helper::checkMandatory($this, $params);
$document = new \RtfHtmlPhp\Document($params['rtf_data']);
$formatter = new \RtfHtmlPhp\Html\HtmlFormatter();
$html = $formatter->Format($document);
if (empty($html)) {
CRM_Advimport_Utils::logImportMessage($params, 'No/empty RTF data');
return;
}
try {
$contact = civicrm_api3('Contact', 'getsingle', ['id' => $params['contact_id']]);
}
catch (Exception $e) {
Throw new Exception("Contact ID does not exist: {$params['contact_id']}");
}
$result = civicrm_api3('Activity', 'create', [
'activity_type_id' => (int)\Civi::settings()->get('activityimportrtf_activitytype'),
'target_id' => $params['contact_id'],
'created_date' => CRM_Activityimportrtf_Advimport_Helper::formatDate($params['create_date'], $params, \Civi::settings()->get('activityimportrtf_dateformat')),
'subject' => $params['subject_a'] . (!empty($params['subject_b']) ? ":{$params['subject_b']}" : ''),
'details' => $html,
'status_id' => "Completed",
]);
}
}
<?php
/**
* https://civicrm.org/licensing
*/
/**
* Class CRM_Mjwshared_Advimport_Helper Version: 20191120
*/
class CRM_Activityimportrtf_Advimport_Helper {
/**
* The possible options for a Yes/No field
*/
public const OPTIN_YESNO_UNSET = NULL;
public const OPTIN_YESNO_YES = 1;
public const OPTIN_YESNO_NO = 0;
/**
* Parse an item, trimming and checking for mandatory params
*
* @param array $params
* @param array $mandatoryParams
*
* @return array|bool
*/
public static function checkMandatory($form, $params) {
$fields = $form->getMapping($form);
foreach ($fields as $key => $detail) {
if (!empty($detail['mandatory'])) {
$mandatoryParams[] = $key;
}
}
// Check if this is a blank entry
foreach ($mandatoryParams as $mandatory) {
if (empty($params[$mandatory])) {
Throw new Exception ("Missing mandatory param: {$mandatory}");
}
}
return TRUE;
}
/**
* Clean the passed params
* @param array $params
*
* @return array
*/
public static function cleanupParams($params) {
// Cleanup input
foreach ($params as $key => $value) {
$params[$key] = trim($value);
}
return $params;
}
public static function formatDate($date, $params, $dateFormat='Y-m-d H:i:s') {
$date = trim($date);
$format = $dateFormat;
if (strpos($date, ' ') === FALSE) {
$date = $date . ' 00:00:00';
}
$dateobj = \DateTime::createFromFormat($format, $date);
if (!$dateobj) {
Throw new Exception("Could not convert date {$date} (expected format: {$dateFormat})");
}
return $dateobj->format('YmdHis');
}
public static function mapYesNo($yesNo) {
switch (mb_strtolower(trim($yesNo))) {
case 'yes':
return 1;
case 'no':
default:
return 0;
}
}
public static function mapCampaign($params) {
if (empty($params['campaign'])) {
return NULL;
}
$campaign = civicrm_api3('Campaign', 'get', [
'title' => $params['campaign'],
]);
if (!empty($campaign['id'])) {
return $campaign['id'];
}
CRM_Advimport_Utils::logImportWarning($params, 'Unknown Campaign: ' . $params['campaign']);
return NULL;
}
/**
* Try and get the country ID, lookup iso code then name
*
* @param $params
*
* @return integer|null
*/
public static function mapCountry($params) {
try {
return civicrm_api3('Country', 'getvalue', [
'return' => "id",
'iso_code' => $params['country'],
]);
} catch (Exception $e) {
try {
return civicrm_api3('Country', 'getvalue', [
'return' => "id",
'name' => $params['country'],
]);
} catch (Exception $e) {
CRM_Advimport_Utils::logImportWarning($params, 'Unknown Country iso code: ' . $params['country']);
return NULL;
}
}
}
public static function getThankyouDate($params) {
if (!empty(self::mapYesNo($params['thankyou_sent']))) {
return self::formatDate($params['receive_date'], $params);
}
return NULL;
}
/**
* Map the prefix (eg. Mr. Mrs. etc) Civi adds a "." by default so we check with and without
*
* @param $params
*
* @return string|null
* @throws \CiviCRM_API3_Exception
*/
public static function mapPrefix($params) {
if (!isset($params['prefix_name'])) {
return NULL;
}
$validPrefix = civicrm_api3('OptionValue', 'get', [
'option_group_id' => "individual_prefix",
'name' => $params['prefix_name'],
]);
if (!empty($validPrefix['count'])) {
return $params['prefix_name'];
}
if (substr($params['prefix_name'], -1) !== '.') {
$params['prefix_name'] = $params['prefix_name'] . '.';
}
$validPrefix = civicrm_api3('OptionValue', 'get', [
'option_group_id' => "individual_prefix",
'name' => $params['prefix_name'],
]);
if (!empty($validPrefix['count'])) {
return $params['prefix_name'];
}
CRM_Advimport_Utils::logImportWarning($params, 'Prefix (Title) could not be found: ' . $params['prefix_name']);
return NULL;
}
public static function mapStateProvince($params) {
try {
return civicrm_api3('StateProvince', 'getvalue', [
'return' => "id",
'name' => $params['state_province_name'],
]);
} catch (Exception $e) {
if ($params['state_province_name'] === 'Oxford') {
return 'Oxfordshire';
}
CRM_Advimport_Utils::logImportWarning($params, 'Unknown State/Province: ' . $params['state_province_name']);
return NULL;
}
}
public static function formatAmountForAPI($amount) {
return filter_var($amount, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
}
public static function mapOptin($optInValue) {
$optInValue = mb_strtolower(trim($optInValue));
if (empty($optInValue)) {
return self::OPTIN_YESNO_UNSET;
}
switch ($optInValue) {
case 'no':
return self::OPTIN_YESNO_NO;
default:
return self::OPTIN_YESNO_YES;
}
}
/**
* Map the OCM attendee status to CiviCRM
*
* @param string $attendeeStatus
*
* @return string
*/
public static function mapAttendeeStatus($attendeeStatus) {
$statusMap = [
$attendeeStatus => 'Attendee',
];
if (array_key_exists($attendeeStatus, $statusMap)) {
return $statusMap[$attendeeStatus];
}
else {
return 'Attendee';
}
}
/**
* Use this to clean up and array for an update function eg. Api4 address.update
* @param $addressParams
*
* @return null|array
*/
public static function unsetEmptyArrayElements($addressParams) {
$newAddressParams = NULL;
foreach ($addressParams as $key => $value) {
if (!empty($value)) {
$newAddressParams[$key] = $value;
}
}
return $newAddressParams;
}
/**
* Returns the default location ID
*
* @return int
* @throws \CiviCRM_API3_Exception
*/
public static function getDefaultLocation() {
try {
return civicrm_api3('LocationType', 'getvalue', [
'return' => "id",
'is_default' => 1,
]);
}
catch (Exception $e) {
return 1;
}
}
/**
* Helper function to add or update an address given a set of fields
*
* @param int $contactID
* @param array $params
*
* @throws \Civi\API\Exception\UnauthorizedException
*/
public static function addOrUpdateAddress($contactID, $params) {
// Overwrite address / phone each time
if (!empty($params['street_address'])) {
$addressValues = [
'contact_id' => $contactID,
'location_type_id' => self::getDefaultLocation(),
'is_primary' => 1,
'street_address' => $params['street_address'],
'city' => $params['city'],
'state_province_id' => self::mapStateProvince($params),
'country_id' => self::mapCountry($params),
'postal_code' => $params['postal_code'],
];
$addressWhere = [
['AND',
[
['is_primary', '=', 1],
['contact_id', '=', $contactID],
['location_type_id', '=', self::getDefaultLocation()],
]
],
];
$addressValues = self::unsetEmptyArrayElements($addressValues);
if ($addressValues) {
$addressCount = \Civi\Api4\Address::get()
->selectRowCount()
->setWhere($addressWhere)
->execute()
->count();
if (empty($addressCount)) {
\Civi\Api4\Address::create()
->setValues($addressValues)
->execute();
}
else {
\Civi\Api4\Address::update()
->setWhere($addressWhere)
->setValues($addressValues)
->execute();
}
}
}
}
/**
* Helper function to add or update a phone given a set of fields
*
* @param int $contactID
* @param array $params
*
* @throws \Civi\API\Exception\UnauthorizedException
*/
public static function addOrUpdatePhone($contactID, $params) {
if (!empty($params['phone'])) {
$phoneValues = [
'contact_id' => $contactID,
'phone' => $params['phone'],
'location_type_id' => self::getDefaultLocation(),
'is_primary' => 1,
];
$phoneWhere = [
['AND',
[
['is_primary', '=', 1],
['contact_id', '=', $contactID],
['location_type_id', '=', self::getDefaultLocation()],
]
],
];
$phoneValues = self::unsetEmptyArrayElements($phoneValues);
if ($phoneValues) {
$phoneCount = \Civi\Api4\Phone::get()
->selectRowCount()
->setWhere($phoneWhere)
->execute()
->count();
if (empty($phoneCount)) {
\Civi\Api4\Phone::create()
->setValues($phoneValues)
->execute();
}
else {
\Civi\Api4\Phone::update()
->setWhere($phoneWhere)
->setValues($phoneValues)
->execute();
}
}
}
}
/**
* Helper function to add or update an email given a set of fields
*
* @param int $contactID
* @param array $params
*
* @throws \Civi\API\Exception\UnauthorizedException
*/
public static function addOrUpdateEmail($contactID, $params) {
if (!empty($params['email'])) {
$emailValues = [
'contact_id' => $contactID,
'email' => $params['email'],
'location_type_id' => self::getDefaultLocation(),
'is_primary' => 1,
];
$emailWhere = [
['AND',
[
['is_primary', '=', 1],
['contact_id', '=', $contactID],
['location_type_id', '=', self::getDefaultLocation()],
]
],
];
$emailValues = self::unsetEmptyArrayElements($emailValues);
if ($emailValues) {
$emailCount = \Civi\Api4\Email::get()
->selectRowCount()
->setWhere($emailWhere)
->execute()
->count();
if (empty($emailCount)) {
\Civi\Api4\Email::create()
->setValues($emailValues)
->execute();
}
else {
\Civi\Api4\Email::update()
->setWhere($emailWhere)
->setValues($emailValues)
->execute();
}
}
}
}
public static function addOrUpdateContact($params) {
$contactValues = [
'first_name' => $params['first_name'],
'last_name' => $params['last_name'],
'contact_type' => "Individual",
'prefix' => self::mapPrefix($params),
];
$contactValues = self::unsetEmptyArrayElements($contactValues);
$whereAnd = [
['contact_type', '=', "Individual"],
['first_name', '=', $params['first_name']],
];
if (!empty($params['last_name'])) {
// In the case of an anonymouse donor it is possible to just have a firstname - ie. "Anon"
$whereAnd[] = ['last_name', '=', $params['last_name']];
}
if (!empty($params['email'])) {
$whereAnd[] = ['emails.email', '=', $params['email']];
}
$contactWhere = [['AND', $whereAnd]];
if ($contactValues) {
$contact = \Civi\Api4\Contact::get()
->setSelect(['id'])
->setWhere($contactWhere)
->execute()
->first();
if (empty($contact)) {
$contact = \Civi\Api4\Contact::create()
->setValues($contactValues)
->execute()
->first();
}
else {
$contact = \Civi\Api4\Contact::update()
->setWhere($contactWhere)
->setValues($contactValues)
->execute()
->first();
}
CRM_Advimport_Utils::addContactToGroupOrTag($contact['id'], $params);
return $contact['id'];
}
return NULL;
}
/**
* Get the payment instrument ID from the name
* @param array $params
*
* @return int
*/
public static function getPaymentInstrumentID($params) {
$paymentInstrumentID = self::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', $params['payment_instrument'], 'get');
if (!$paymentInstrumentID) {
$paymentInstrumentID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Cash');
CRM_Advimport_Utils::logImportWarning($params, "Payment instrument '{$params['payment_instrument']}' not found! We used the default 'Cash'");
}
return $paymentInstrumentID;
}
/**
* Return a transaction ID for a contribution in form trxn_id-advimport_id-import_row_id
* @param array $params
*
* @return string
*/
public static function getTransactionID($params) {
if (empty($params['trxn_id'])) {
$params['trxn_id'] = 'advimport';
}
return "{$params['trxn_id']}-{$params['advimport_id']}-{$params['import_row_id']}";
}
/**
* Fetch the key for a field option given its name.
*
* @param string $baoName
* @param string $fieldName
* @param string|int $value
* @param string $context
*
* @return bool|null|string|int
* FALSE if the given field has no associated option list
* NULL if the given key has no corresponding option
* String|Number if key is found
*/
public static function getKey($baoName, $fieldName, $value, $context = 'validate') {
$values = $baoName::buildOptions($fieldName, $context);
if ($values === FALSE) {
return FALSE;
}
return CRM_Utils_Array::key($value, $values);
}
}
This diff is collapsed.
# Activity Import RTF
This extension provides an importer for activity CSV files containing RTF data in one column.
It converts the RTF data into HTML and saves it in the "details" field of an activity.
The extension is licensed under [AGPL-3.0](LICENSE.txt).
## Requirements
* PHP v7.1+