diff --git a/civicrm.php b/civicrm.php index 9f1a2d13208702cf0f067fef3a4ce9d99fe0affb..83a1063aa40b23a0df026f3e0a66fa62c78223e3 100644 --- a/civicrm.php +++ b/civicrm.php @@ -2,7 +2,7 @@ /* Plugin Name: CiviCRM Description: CiviCRM - Growing and Sustaining Relationships -Version: 5.18.3 +Version: 5.18.4 Author: CiviCRM LLC Author URI: https://civicrm.org/ Plugin URI: https://wiki.civicrm.org/confluence/display/CRMDOC/Installing+CiviCRM+for+WordPress @@ -137,17 +137,6 @@ if ( file_exists( CIVICRM_SETTINGS_PATH ) ) { // Prevent CiviCRM from rendering its own header define( 'CIVICRM_UF_HEAD', TRUE ); -/** - * Setting this to 'true' will replace all mailing URLs calls to 'extern/url.php' - * and 'extern/open.php' with their REST counterpart 'civicrm/v3/url' and 'civicrm/v3/open'. - * - * Use for test purposes, may affect mailing - * performance, see Plugin->replace_tracking_urls() method. - */ -if ( ! defined( 'CIVICRM_WP_REST_REPLACE_MAILING_TRACKING' ) ) { - define( 'CIVICRM_WP_REST_REPLACE_MAILING_TRACKING', false ); -} - /** * Define CiviCRM_For_WordPress Class. @@ -291,7 +280,6 @@ class CiviCRM_For_WordPress { // Set a one-time-only option add_option( 'civicrm_activation_in_progress', 'true' ); - add_option('civicrm_setup_do_activation_redirect', true); } @@ -322,11 +310,6 @@ class CiviCRM_For_WordPress { // Change option so this action never fires again update_option( 'civicrm_activation_in_progress', 'false' ); - if (!isset($_GET['activate-multi'])) { - wp_redirect(admin_url("options-general.php?page=civicrm-install")); - exit; - } - update_option('civicrm_setup_do_activation_redirect', 'false'); } @@ -533,9 +516,6 @@ class CiviCRM_For_WordPress { include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.basepage.php'; $this->basepage = new CiviCRM_For_WordPress_Basepage; - // Include REST API autoloader class - require_once( CIVICRM_PLUGIN_DIR . 'wp-rest/Autoloader.php' ); - } @@ -648,12 +628,6 @@ class CiviCRM_For_WordPress { // Register hooks for clean URLs. $this->register_hooks_clean_urls(); - // Set up REST API. - CiviCRM_WP_REST\Autoloader::add_source( $source_path = trailingslashit( CIVICRM_PLUGIN_DIR . 'wp-rest' ) ); - - // Init REST API. - new CiviCRM_WP_REST\Plugin; - } diff --git a/civicrm/CRM/ACL/Form/WordPress/Permissions.php b/civicrm/CRM/ACL/Form/WordPress/Permissions.php index bad293c934c17f1d0567697ce7abc3b935b3501e..65191fb9793aed95be6ef1190364b5fd59b5a109 100644 --- a/civicrm/CRM/ACL/Form/WordPress/Permissions.php +++ b/civicrm/CRM/ACL/Form/WordPress/Permissions.php @@ -54,7 +54,7 @@ class CRM_ACL_Form_WordPress_Permissions extends CRM_Core_Form { } foreach ($wp_roles->role_names as $role => $name) { // Don't show the permissions options for administrator, as they have all permissions - if ( is_multisite() OR $role !== 'administrator') { + if ($role !== 'administrator') { $roleObj = $wp_roles->get_role($role); if (!empty($roleObj->capabilities)) { foreach ($roleObj->capabilities as $ckey => $cname) { diff --git a/civicrm/CRM/Contribute/BAO/Contribution.php b/civicrm/CRM/Contribute/BAO/Contribution.php index 33a350ef6ae8a7cb681e0d680d8ee762975bb9f1..51e4775c1dae03e6d12ddb77c7beae2388b3368f 100644 --- a/civicrm/CRM/Contribute/BAO/Contribution.php +++ b/civicrm/CRM/Contribute/BAO/Contribution.php @@ -4053,13 +4053,6 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $financialTypeId = $contribution['financial_type_id']; $feeFinancialAccount = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($financialTypeId, 'Expense Account is'); - if ($paymentBalance == 0 && $info['payLater']) { - // @todo - review - this looks very unlikely to be correct. - // the balance should be correct based on payment transactions not - // assumptions. - $paymentBalance = $total; - } - $info['total'] = $total; $info['paid'] = $total - $paymentBalance; $info['balance'] = $paymentBalance; diff --git a/civicrm/CRM/Contribute/Form/AdditionalPayment.php b/civicrm/CRM/Contribute/Form/AdditionalPayment.php index 10219870fc62503ee79ae3dab2d31bbad4e5d8d3..68912379641bf641404bd51626f3316a07ddae5e 100644 --- a/civicrm/CRM/Contribute/Form/AdditionalPayment.php +++ b/civicrm/CRM/Contribute/Form/AdditionalPayment.php @@ -67,8 +67,6 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract protected $fromEmailId = NULL; - protected $_fromEmails = NULL; - protected $_view = NULL; public $_action = NULL; @@ -94,18 +92,14 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract CRM_Utils_System::setTitle($title); return; } - $this->_fromEmails = CRM_Core_BAO_Email::getFromEmail(); - $entityType = 'contribution'; if ($this->_component == 'event') { $entityType = 'participant'; $this->_contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'contribution_id', 'participant_id'); $eventId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'event_id', 'id'); - $this->_fromEmails = CRM_Event_BAO_Event::getFromEmailIds($eventId); } else { $this->_contributionId = $this->_id; - $this->_fromEmails['from_email_id'] = CRM_Core_BAO_Email::getFromEmail(); } $paymentInfo = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($this->_id, $entityType); @@ -222,7 +216,11 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract //add receipt for offline contribution $this->addElement('checkbox', 'is_email_receipt', ts('Send Receipt?')); - $this->add('select', 'from_email_address', ts('Receipt From'), $this->_fromEmails['from_email_id']); + if ($this->_component === 'event') { + $eventID = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'event_id', 'id'); + } + + $this->add('select', 'from_email_address', ts('Receipt From'), CRM_Financial_BAO_Payment::getValidFromEmailsForPayment($eventID ?? NULL)); $this->add('textarea', 'receipt_text', ts('Confirmation Message')); @@ -330,8 +328,10 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract /** * Process Payments. + * * @param array $submittedValues * + * @throws \CiviCRM_API3_Exception */ public function submit($submittedValues) { $this->_params = $submittedValues; @@ -375,7 +375,7 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract $statusMsg = ts('The payment record has been processed.'); // send email if (!empty($paymentID) && !empty($this->_params['is_email_receipt'])) { - $sendResult = civicrm_api3('Payment', 'sendconfirmation', ['id' => $paymentID])['values'][$paymentID]; + $sendResult = civicrm_api3('Payment', 'sendconfirmation', ['id' => $paymentID, 'from' => $submittedValues['from_email_address']])['values'][$paymentID]; if ($sendResult['is_sent']) { $statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.'); } diff --git a/civicrm/CRM/Core/BAO/FinancialTrxn.php b/civicrm/CRM/Core/BAO/FinancialTrxn.php index b02538e4294d08ae3b409854e590bac877feb6d2..e8e886d41d0db20c3a25547bea5a8ebc23094b8a 100644 --- a/civicrm/CRM/Core/BAO/FinancialTrxn.php +++ b/civicrm/CRM/Core/BAO/FinancialTrxn.php @@ -737,4 +737,23 @@ WHERE ceft.entity_id = %1"; return TRUE; } + /** + * Generate and assign an arbitrary value to a field of a test object. + * + * Always set is_payment to 1 as this is used for Payment api as well as FinancialTrxn. + * + * @param string $fieldName + * @param array $fieldDef + * @param int $counter + * The globally-unique ID of the test object. + */ + protected function assignTestValue($fieldName, &$fieldDef, $counter) { + if ($fieldName === 'is_payment') { + $this->is_payment = 1; + } + else { + parent::assignTestValue($fieldName, $fieldDef, $counter); + } + } + } diff --git a/civicrm/CRM/Core/BAO/MessageTemplate.php b/civicrm/CRM/Core/BAO/MessageTemplate.php index 4b81879706d30b8f65adb8c8e3bf30afd1379a55..3c28a5a4aea4e4fe6a1831dd620a8330e02337cd 100644 --- a/civicrm/CRM/Core/BAO/MessageTemplate.php +++ b/civicrm/CRM/Core/BAO/MessageTemplate.php @@ -385,7 +385,7 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate { ]; $params = array_merge($defaults, $params); - // Core#644 - handle contact ID passed as "From". + // Core#644 - handle Email ID passed as "From". if (isset($params['from'])) { $params['from'] = CRM_Utils_Mail::formatFromAddress($params['from']); } diff --git a/civicrm/CRM/Core/DAO.php b/civicrm/CRM/Core/DAO.php index 83dac3f4333a8f1b76dd8b3a467f3318ce9dabfc..d1b7668fee2e305b21841274695a09f8caaf3d4d 100644 --- a/civicrm/CRM/Core/DAO.php +++ b/civicrm/CRM/Core/DAO.php @@ -1982,6 +1982,12 @@ SELECT contact_id // Prefer to instantiate BAO's instead of DAO's (when possible) // so that assignTestValue()/assignTestFK() can be overloaded. $baoName = str_replace('_DAO_', '_BAO_', $daoName); + if ($baoName === 'CRM_Financial_BAO_FinancialTrxn') { + // OMG OMG OMG this is so incredibly bad. The BAO is insanely named. + // @todo create a new class called what the BAO SHOULD be + // that extends BAO-crazy-name.... migrate. + $baoName = 'CRM_Core_BAO_FinancialTrxn'; + } if (class_exists($baoName)) { $daoName = $baoName; } diff --git a/civicrm/CRM/Core/Payment/PayPalIPN.php b/civicrm/CRM/Core/Payment/PayPalIPN.php index d7a13692b65f29a8d05c2d5cc21780c9467f2c2c..c5484857c30e1d532451e1dd6f9c994d686990a1 100644 --- a/civicrm/CRM/Core/Payment/PayPalIPN.php +++ b/civicrm/CRM/Core/Payment/PayPalIPN.php @@ -336,7 +336,8 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN { Civi::log()->debug('PayPalIPN: Received (ContactID: ' . $ids['contact'] . '; trxn_id: ' . $input['trxn_id'] . ').'); - if ($this->retrieve('membershipID', 'Integer', FALSE)) { + // Debugging related to possible missing membership linkage + if ($contributionRecurID && $this->retrieve('membershipID', 'Integer', FALSE)) { $templateContribution = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution($contributionRecurID); $membershipPayment = civicrm_api3('MembershipPayment', 'get', [ 'contribution_id' => $templateContribution['id'], diff --git a/civicrm/CRM/Financial/BAO/Payment.php b/civicrm/CRM/Financial/BAO/Payment.php index ccc65c2dd83206ad12998df80a81d4beeec053af..db3c92a60d0e5038c9f4effe0e1828b98aa14c7e 100644 --- a/civicrm/CRM/Financial/BAO/Payment.php +++ b/civicrm/CRM/Financial/BAO/Payment.php @@ -59,28 +59,41 @@ class CRM_Financial_BAO_Payment { $isPaymentCompletesContribution = self::isPaymentCompletesContribution($params['contribution_id'], $params['total_amount']); - if ($params['total_amount'] > 0) { - $balanceTrxnParams['to_financial_account_id'] = CRM_Contribute_BAO_Contribution::getToFinancialAccount($contribution, $params); - $balanceTrxnParams['from_financial_account_id'] = CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship($contribution['financial_type_id'], 'Accounts Receivable Account is'); - $balanceTrxnParams['total_amount'] = $params['total_amount']; - $balanceTrxnParams['contribution_id'] = $params['contribution_id']; - $balanceTrxnParams['trxn_date'] = CRM_Utils_Array::value('trxn_date', $params, CRM_Utils_Array::value('contribution_receive_date', $params, date('YmdHis'))); - $balanceTrxnParams['fee_amount'] = CRM_Utils_Array::value('fee_amount', $params); - $balanceTrxnParams['net_amount'] = CRM_Utils_Array::value('total_amount', $params); - $balanceTrxnParams['currency'] = $contribution['currency']; - $balanceTrxnParams['trxn_id'] = CRM_Utils_Array::value('contribution_trxn_id', $params, NULL); - $balanceTrxnParams['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_FinancialTrxn', 'status_id', 'Completed'); - $balanceTrxnParams['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $params, $contribution['payment_instrument_id']); - $balanceTrxnParams['check_number'] = CRM_Utils_Array::value('check_number', $params); - $balanceTrxnParams['is_payment'] = 1; - - if (!empty($params['payment_processor'])) { - // I can't find evidence this is passed in - I was gonna just remove it but decided to deprecate as I see getToFinancialAccount - // also anticipates it. - CRM_Core_Error::deprecatedFunctionWarning('passing payment_processor is deprecated - use payment_processor_id'); - $balanceTrxnParams['payment_processor_id'] = $params['payment_processor']; + $whiteList = ['check_number', 'payment_processor_id', 'fee_amount', 'total_amount', 'contribution_id', 'net_amount', 'card_type_id', 'pan_truncation', 'trxn_result_code', 'payment_instrument_id', 'trxn_id']; + $paymentTrxnParams = array_intersect_key($params, array_fill_keys($whiteList, 1)); + $paymentTrxnParams['is_payment'] = 1; + if (!empty($params['payment_processor'])) { + // I can't find evidence this is passed in - I was gonna just remove it but decided to deprecate as I see getToFinancialAccount + // also anticipates it. + CRM_Core_Error::deprecatedFunctionWarning('passing payment_processor is deprecated - use payment_processor_id'); + $paymentTrxnParams['payment_processor_id'] = $params['payment_processor']; + } + if (isset($paymentTrxnParams['payment_processor_id']) && empty($paymentTrxnParams['payment_processor_id'])) { + // Don't pass 0 - ie the Pay Later processor as it is a pseudo-processor. + unset($paymentTrxnParams['payment_processor_id']); + } + if (empty($paymentTrxnParams['payment_instrument_id'])) { + if (!empty($params['payment_processor_id'])) { + $paymentTrxnParams['payment_instrument_id'] = civicrm_api3('PaymentProcessor', 'getvalue', ['return' => 'payment_instrument_id', 'id' => $paymentTrxnParams['payment_processor_id']]); } - $trxn = CRM_Core_BAO_FinancialTrxn::create($balanceTrxnParams); + else { + // Fall back on the payment instrument already used - should we deprecate this? + $paymentTrxnParams['payment_instrument_id'] = $contribution['payment_instrument_id']; + } + } + if (empty($paymentTrxnParams['trxn_id']) && !empty($paymentTrxnParams['contribution_trxn_id'])) { + CRM_Core_Error::deprecatedFunctionWarning('contribution_trxn_id is deprecated - use trxn_id'); + $paymentTrxnParams['trxn_id'] = $paymentTrxnParams['contribution_trxn_id']; + } + + if ($params['total_amount'] > 0) { + $paymentTrxnParams['to_financial_account_id'] = CRM_Contribute_BAO_Contribution::getToFinancialAccount($contribution, $params); + $paymentTrxnParams['from_financial_account_id'] = CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship($contribution['financial_type_id'], 'Accounts Receivable Account is'); + $paymentTrxnParams['trxn_date'] = CRM_Utils_Array::value('trxn_date', $params, CRM_Utils_Array::value('contribution_receive_date', $params, date('YmdHis'))); + $paymentTrxnParams['currency'] = $contribution['currency']; + $paymentTrxnParams['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_FinancialTrxn', 'status_id', 'Completed'); + + $trxn = CRM_Core_BAO_FinancialTrxn::create($paymentTrxnParams); // @todo - this is just weird & historical & inconsistent - why 2 tracks? if (!empty($params['line_item']) && !empty($trxn)) { @@ -196,9 +209,35 @@ class CRM_Financial_BAO_Payment { 'toEmail' => $entities['contact']['email'], 'tplParams' => self::getConfirmationTemplateParameters($entities), ]; + if (!empty($params['from']) && !empty($params['check_permissions'])) { + // Filter from against permitted emails. + $validEmails = self::getValidFromEmailsForPayment($entities['event']['id'] ?? NULL); + if (!isset($validEmails[$params['from']])) { + // Ignore unpermitted parameter. + unset($params['from']); + } + } + $sendTemplateParams['from'] = $params['from'] ?? key(CRM_Core_BAO_Email::domainEmails()); return CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); } + /** + * Get valid from emails for payment. + * + * @param int $eventID + * + * @return array + */ + public static function getValidFromEmailsForPayment($eventID = NULL) { + if ($eventID) { + $emails = CRM_Event_BAO_Event::getFromEmailIds($eventID); + } + else { + $emails['from_email_id'] = CRM_Core_BAO_Email::getFromEmail(); + } + return $emails['from_email_id']; + } + /** * Load entities related to the current payment id. * @@ -213,6 +252,7 @@ class CRM_Financial_BAO_Payment { * - event = [.... full event details......] * - contribution = ['id' => x], * - payment = [payment info + payment summary info] + * @throws \CiviCRM_API3_Exception */ protected static function loadRelatedEntities($id) { $entities = []; diff --git a/civicrm/CRM/Report/Form.php b/civicrm/CRM/Report/Form.php index 8090032de0de291ec5aa7f9295f47592a3493d4f..77495fdcbaa1c586e3199d2bb8c8231029c278cf 100644 --- a/civicrm/CRM/Report/Form.php +++ b/civicrm/CRM/Report/Form.php @@ -155,9 +155,6 @@ class CRM_Report_Form extends CRM_Core_Form { */ protected $_groupFilter = FALSE; - // [ML] Required for civiexportexcel - public $supportsExportExcel = TRUE; - /** * Has the report been optimised for group filtering. * @@ -2845,11 +2842,6 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND $this->_absoluteUrl = TRUE; $this->addPaging = FALSE; } - elseif ($this->_outputMode == 'excel2007') { - $printOnly = TRUE; - $this->_absoluteUrl = TRUE; - $this->addPaging = FALSE; - } elseif ($this->_outputMode == 'group') { $this->assign('outputMode', 'group'); } @@ -3502,9 +3494,6 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND elseif ($this->_outputMode == 'csv') { CRM_Report_Utils_Report::export2csv($this, $rows); } - elseif ($this->_outputMode == 'excel2007') { - CRM_CiviExportExcel_Utils_Report::export2excel2007($this, $rows); - } elseif ($this->_outputMode == 'group') { $group = $this->_params['groups']; $this->add2group($group); diff --git a/civicrm/CRM/Report/Form/Contribute/Summary.php b/civicrm/CRM/Report/Form/Contribute/Summary.php index e193637490010755aa71662ec88c264cbe1a1033..b3bce81d9b3b979f409e2e8d108825c6c4e37d5f 100644 --- a/civicrm/CRM/Report/Form/Contribute/Summary.php +++ b/civicrm/CRM/Report/Form/Contribute/Summary.php @@ -65,6 +65,13 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { */ protected $groupFilterNotOptimised = FALSE; + /** + * Indicate that report is not fully FGB compliant. + * + * @var bool + */ + public $optimisedForOnlyFullGroupBy; + /** * Class constructor. */ @@ -584,12 +591,9 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { $this->_groupBy = "GROUP BY " . implode(', ', $groupBy); } else { - $groupBy = "{$this->_aliases['civicrm_contact']}.id"; $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contact']}.id"; } $this->_groupBy .= $this->_rollup; - // append select with ANY_VALUE() keyword - $this->_select = CRM_Contact_BAO_Query::appendAnyValueToSelect($this->_selectClauses, $groupBy); } /** @@ -733,75 +737,6 @@ ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_ parent::postProcess(); } - /** - * Build table rows for output. - * - * @param string $sql - * @param array $rows - */ - public function buildRows($sql, &$rows) { - CRM_Core_DAO::disableFullGroupByMode(); - $dao = CRM_Core_DAO::executeQuery($sql); - CRM_Core_DAO::reenableFullGroupByMode(); - $this->addToDeveloperTab($sql); - if (!is_array($rows)) { - $rows = array(); - } - - // use this method to modify $this->_columnHeaders - $this->modifyColumnHeaders(); - $contriRows = array(); - $unselectedSectionColumns = $this->unselectedSectionColumns(); - - //CRM-16338 if both soft-credit and contribution are enabled then process the contribution's - //total amount's average, count and sum separately and add it to the respective result list - $softCredit = (!empty($this->_params['fields']['soft_amount']) && !empty($this->_params['fields']['total_amount'])) ? TRUE : FALSE; - if ($softCredit) { - $this->from('contribution'); - $this->customDataFrom(); - $contriSQL = "{$this->_select} {$this->_from} {$this->_where} {$this->_groupBy} {$this->_having} {$this->_orderBy} {$this->_limit}"; - $contriDAO = CRM_Core_DAO::executeQuery($contriSQL); - $this->addToDeveloperTab($contriSQL); - $contriFields = array( - 'civicrm_contribution_total_amount_sum', - 'civicrm_contribution_total_amount_avg', - 'civicrm_contribution_total_amount_count', - ); - $contriRows = array(); - while ($contriDAO->fetch()) { - $contriRow = array(); - foreach ($contriFields as $column) { - $contriRow[$column] = $contriDAO->$column; - } - $contriRows[] = $contriRow; - } - } - - $count = 0; - while ($dao->fetch()) { - $row = array(); - foreach ($this->_columnHeaders as $key => $value) { - if ($softCredit && array_key_exists($key, $contriRows[$count])) { - $row[$key] = $contriRows[$count][$key]; - } - elseif (property_exists($dao, $key)) { - $row[$key] = $dao->$key; - } - } - - // section headers not selected for display need to be added to row - foreach ($unselectedSectionColumns as $key => $values) { - if (property_exists($dao, $key)) { - $row[$key] = $dao->$key; - } - } - - $count++; - $rows[] = $row; - } - - } - /** * Build chart. * @@ -868,7 +803,30 @@ ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_ $entryFound = FALSE; $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(); $contributionPages = CRM_Contribute_PseudoConstant::contributionPage(); - + //CRM-16338 if both soft-credit and contribution are enabled then process the contribution's + //total amount's average, count and sum separately and add it to the respective result list + $softCredit = (!empty($this->_params['fields']['soft_amount']) && !empty($this->_params['fields']['total_amount'])) ? TRUE : FALSE; + if ($softCredit) { + $this->from('contribution'); + $this->customDataFrom(); + $contriSQL = "{$this->_select} {$this->_from} {$this->_where} {$this->_groupBy} {$this->_having} {$this->_orderBy} {$this->_limit}"; + CRM_Core_DAO::disableFullGroupByMode(); + $contriDAO = CRM_Core_DAO::executeQuery($contriSQL); + CRM_Core_DAO::reenableFullGroupByMode(); + $this->addToDeveloperTab($contriSQL); + $contriFields = array( + 'civicrm_contribution_total_amount_sum', + 'civicrm_contribution_total_amount_avg', + 'civicrm_contribution_total_amount_count', + ); + $count = 0; + while ($contriDAO->fetch()) { + foreach ($contriFields as $column) { + $rows[$count][$column] = $contriDAO->$column; + } + $count++; + } + } foreach ($rows as $rowNum => $row) { // make count columns point to detail report if (!empty($this->_params['group_bys']['receive_date']) && diff --git a/civicrm/CRM/Upgrade/Incremental/sql/5.18.4.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/5.18.4.mysql.tpl new file mode 100644 index 0000000000000000000000000000000000000000..e41a9986413a6ac40f950a735cf0a77e12b09766 --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/5.18.4.mysql.tpl @@ -0,0 +1 @@ +{* file to handle db changes in 5.18.4 during upgrade *} diff --git a/civicrm/CRM/Utils/System/WordPress.php b/civicrm/CRM/Utils/System/WordPress.php index 9c074c5a88f968ec53575493c050393beb256563..382892d314b62688942bcfdacbc56655b2324cc1 100644 --- a/civicrm/CRM/Utils/System/WordPress.php +++ b/civicrm/CRM/Utils/System/WordPress.php @@ -827,13 +827,11 @@ class CRM_Utils_System_WordPress extends CRM_Utils_System_Base { $contactCreated = 0; $contactMatching = 0; - // previously used $wpdb - which means WordPress *must* be bootstrapped - $wpUsers = get_users(array( - 'blog_id' => get_current_blog_id(), - 'number' => -1, - )); + global $wpdb; + $wpUserIds = $wpdb->get_col("SELECT $wpdb->users.ID FROM $wpdb->users"); - foreach ($wpUsers as $wpUserData) { + foreach ($wpUserIds as $wpUserId) { + $wpUserData = get_userdata($wpUserId); $contactCount++; if ($match = CRM_Core_BAO_UFMatch::synchronizeUFMatch($wpUserData, $wpUserData->$id, diff --git a/civicrm/api/v3/Contact.php b/civicrm/api/v3/Contact.php index bcaa9954cc8b0fd69302347da3932079c93408b0..200605bdc87b75e8f935825a60cb19b5d8031a4c 100644 --- a/civicrm/api/v3/Contact.php +++ b/civicrm/api/v3/Contact.php @@ -1195,7 +1195,7 @@ function _civicrm_api3_contact_merge_spec(&$params) { $params['mode'] = [ 'title' => ts('Dedupe mode'), 'description' => ts("In 'safe' mode conflicts will result in no merge. In 'aggressive' mode the merge will still proceed (hook dependent)"), - 'api.default' => ['safe', 'aggressive'], + 'api.default' => 'safe', 'options' => ['safe' => ts('Abort on unhandled conflict'), 'aggressive' => ts('Proceed on unhandled conflict. Note hooks may change handling here.')], ]; } diff --git a/civicrm/api/v3/Payment.php b/civicrm/api/v3/Payment.php index 4ac10c070fc8714e0f2984ee44ba7ae22b6e8fd8..9bea138405796591f0329dda977dcb94c926b7ea 100644 --- a/civicrm/api/v3/Payment.php +++ b/civicrm/api/v3/Payment.php @@ -126,9 +126,12 @@ function civicrm_api3_payment_cancel($params) { * @param array $params * Input parameters. * - * @throws API_Exception * @return array * Api result array + * + * @throws \API_Exception + * @throws \CRM_Core_Exception + * @throws \CiviCRM_API3_Exception */ function civicrm_api3_payment_create($params) { // Check if it is an update @@ -165,9 +168,16 @@ function _civicrm_api3_payment_create_spec(&$params) { 'type' => CRM_Utils_Type::T_FLOAT, ], 'payment_processor_id' => [ - 'title' => ts('Payment Processor ID'), + 'name' => 'payment_processor_id', 'type' => CRM_Utils_Type::T_INT, - 'description' => ts('Payment processor ID - required for payment processor payments'), + 'title' => ts('Payment Processor'), + 'description' => ts('Payment Processor for this payment'), + 'where' => 'civicrm_financial_trxn.payment_processor_id', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'localizable' => 0, + 'FKClassName' => 'CRM_Financial_DAO_PaymentProcessor', ], 'id' => [ 'title' => ts('Payment ID'), @@ -184,6 +194,103 @@ function _civicrm_api3_payment_create_spec(&$params) { 'type' => CRM_Utils_Type::T_BOOLEAN, 'api.default' => TRUE, ], + 'payment_instrument_id' => [ + 'name' => 'payment_instrument_id', + 'type' => CRM_Utils_Type::T_INT, + 'title' => ts('Payment Method'), + 'description' => ts('FK to payment_instrument option group values'), + 'where' => 'civicrm_financial_trxn.payment_instrument_id', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'localizable' => 0, + 'html' => [ + 'type' => 'Select', + ], + 'pseudoconstant' => [ + 'optionGroupName' => 'payment_instrument', + 'optionEditPath' => 'civicrm/admin/options/payment_instrument', + ], + ], + 'card_type_id' => [ + 'name' => 'card_type_id', + 'type' => CRM_Utils_Type::T_INT, + 'title' => ts('Card Type ID'), + 'description' => ts('FK to accept_creditcard option group values'), + 'where' => 'civicrm_financial_trxn.card_type_id', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'localizable' => 0, + 'html' => [ + 'type' => 'Select', + ], + 'pseudoconstant' => [ + 'optionGroupName' => 'accept_creditcard', + 'optionEditPath' => 'civicrm/admin/options/accept_creditcard', + ], + ], + 'trxn_result_code' => [ + 'name' => 'trxn_result_code', + 'type' => CRM_Utils_Type::T_STRING, + 'title' => ts('Transaction Result Code'), + 'description' => ts('processor result code'), + 'maxlength' => 255, + 'size' => CRM_Utils_Type::HUGE, + 'where' => 'civicrm_financial_trxn.trxn_result_code', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'localizable' => 0, + ], + 'trxn_id' => [ + 'name' => 'trxn_id', + 'type' => CRM_Utils_Type::T_STRING, + 'title' => ts('Transaction ID'), + 'description' => ts('Transaction id supplied by external processor. This may not be unique.'), + 'maxlength' => 255, + 'size' => 10, + 'where' => 'civicrm_financial_trxn.trxn_id', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], + ], + 'check_number' => [ + 'name' => 'check_number', + 'type' => CRM_Utils_Type::T_STRING, + 'title' => ts('Check Number'), + 'description' => ts('Check number'), + 'maxlength' => 255, + 'size' => 6, + 'where' => 'civicrm_financial_trxn.check_number', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], + ], + 'pan_truncation' => [ + 'name' => 'pan_truncation', + 'type' => CRM_Utils_Type::T_STRING, + 'title' => ts('Pan Truncation'), + 'description' => ts('Last 4 digits of credit card'), + 'maxlength' => 4, + 'size' => 4, + 'where' => 'civicrm_financial_trxn.pan_truncation', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'localizable' => 0, + 'html' => [ + 'type' => 'Text', + ], + ], ]; } @@ -266,12 +373,9 @@ function _civicrm_api3_payment_cancel_spec(&$params) { */ function civicrm_api3_payment_sendconfirmation($params) { $allowedParams = [ - 'receipt_from_email', - 'receipt_from_name', - 'cc_receipt', - 'bcc_receipt', - 'receipt_text', + 'from', 'id', + 'check_permissions', ]; $input = array_intersect_key($params, array_flip($allowedParams)); // use either the contribution or membership receipt, based on whether it’s a membership-related contrib or not @@ -300,4 +404,8 @@ function _civicrm_api3_payment_sendconfirmation_spec(&$params) { 'title' => ts('Payment ID'), 'type' => CRM_Utils_Type::T_INT, ]; + $params['from_email_address'] = [ + 'title' => ts('From email; an email string or the id of a valid email'), + 'type' => CRM_Utils_Type::T_STRING, + ]; } diff --git a/civicrm/api/v3/utils.php b/civicrm/api/v3/utils.php index 5a8c0e54b75c6679425ed21816b1da15db8fc660..8d45e84ff8ddabe54b8cafc05128a52449a1542a 100644 --- a/civicrm/api/v3/utils.php +++ b/civicrm/api/v3/utils.php @@ -390,6 +390,9 @@ function _civicrm_api3_get_BAO($name) { // not the other cache info like search results (which could in fact be in Redis or another cache engine) $name = 'PrevNextCache'; } + if ($name === 'Payment') { + $name = 'FinancialTrxn'; + } $dao = _civicrm_api3_get_DAO($name); if (!$dao) { return NULL; diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php index 43c4037a6e452d9d89e08ffa5315c86b0d5bb5af..988dc85d0f7e3b0f7b2629ec1de06a4b5b8f988a 100644 --- a/civicrm/civicrm-version.php +++ b/civicrm/civicrm-version.php @@ -1,7 +1,7 @@ <?php /** @deprecated */ function civicrmVersion( ) { - return array( 'version' => '5.18.3', + return array( 'version' => '5.18.4', 'cms' => 'Wordpress', 'revision' => '' ); } diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md index 7534552e0a46b79886f7a997232e5b4f5f6e23ad..a888d4db215d05b524d416429b7ee083a6a55cad 100644 --- a/civicrm/release-notes.md +++ b/civicrm/release-notes.md @@ -15,6 +15,15 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress +## CiviCRM 5.18.4 + +Released October 22, 2019 + +- **[Synopsis](release-notes/5.18.4.md#synopsis)** +- **[Bugs resolved](release-notes/5.18.4.md#bugs)** +- **[Credits](release-notes/5.18.4.md#credits)** +- **[Feedback](release-notes/5.18.4.md#feedback)** + ## CiviCRM 5.18.3 Released October 15, 2019 diff --git a/civicrm/release-notes/5.18.4.md b/civicrm/release-notes/5.18.4.md new file mode 100644 index 0000000000000000000000000000000000000000..4bd2f232a5a827dbb0516f1dfa5846cd2c083bdd --- /dev/null +++ b/civicrm/release-notes/5.18.4.md @@ -0,0 +1,47 @@ +# CiviCRM 5.18.4 + +Released Oct 22, 2019 + +- **[Synopsis](#synopsis)** +- **[Bugs resolved](#bugs)** +- **[Credits](#credits)** +- **[Feedback](#feedback)** + +## <a name="synopsis"></a>Synopsis + +| *Does this version...?* | | +|:--------------------------------------------------------------- |:-------:| +| Fix security vulnerabilities? | no | +| Change the database schema? | no | +| Alter the API? | no | +| Require attention to configuration options? | no | +| Fix problems installing or upgrading to a previous version? | no | +| Introduce features? | no | +| **Fix bugs?** | **yes** | + +## <a name="bugs"></a>Bugs resolved + +* **_CiviMember_: Fix status tracking when using PayPal Standard and non-recurring payments ([#15538](https://github.com/civicrm/civicrm-core/pull/15538))** +* **_CiviContribute_: Fix omission when saving via "AdditionalPayment" / "Payment.create" ([#15537](https://github.com/civicrm/civicrm-core/pull/15537))** +* **_CiviContribute_: Fix "From" in email notification for "AdditionalPayment" / "Payment.sendconfirmation" ([dev/core#1322](https://lab.civicrm.org/dev/core/issues/1322): [#15552](https://github.com/civicrm/civicrm-core/pull/15552))** +* **_CiviContribute_: Fix incorrect balance in email receipt ([dev/core#1333](https://lab.civicrm.org/dev/core/issues/1333): [#15562](https://github.com/civicrm/civicrm-core/pull/15562))** +* **_CiviReport_: Fix pagination on "Contribution Summary" ([dev/core#1252](https://lab.civicrm.org/dev/core/issues/1252): [#15559](https://github.com/civicrm/civicrm-core/pull/15559))** +* **_Dedupe API_: Restore previous default ("mode=safe") ([#15527](https://github.com/civicrm/civicrm-core/pull/15527))** + +## <a name="credits"></a>Credits + +This release was developed by the following authors and reviewers: + +Wikimedia Foundation - Eileen McNaughton; Tadpole Collective - Kevin +Cristiano; Richard van Oosterhout; MJW Consulting - Matthew Wire; iXiam - +Vangelis Pantazis; Fuzion - Jitendra Purohit; CiviCRM - Tim Otten; CiviCoop - +Jaap Jansma; Australian Greens - Seamus Lee + +## <a name="feedback"></a>Feedback + +These release notes are edited by Tim Otten and Andrew Hunt. If you'd like to +provide feedback on them, please login to https://chat.civicrm.org/civicrm and +contact `@agh1`. + + + diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql index e188902324d9a99262b09cdf5b1cf6a5c2f86855..4555015d7aba9a44ab1b9af46abc23f9471476f0 100644 --- a/civicrm/sql/civicrm_data.mysql +++ b/civicrm/sql/civicrm_data.mysql @@ -24050,4 +24050,4 @@ INSERT INTO `civicrm_report_instance` ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) VALUES ( @domainID, 'Survey Details', 'survey/detail', 'Detailed report for canvassing, phone-banking, walk lists or other surveys.', 'access CiviReport', 'a:39:{s:6:"fields";a:2:{s:9:"sort_name";s:1:"1";s:6:"result";s:1:"1";}s:22:"assignee_contact_id_op";s:2:"eq";s:25:"assignee_contact_id_value";s:0:"";s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:17:"street_number_min";s:0:"";s:17:"street_number_max";s:0:"";s:16:"street_number_op";s:3:"lte";s:19:"street_number_value";s:0:"";s:14:"street_name_op";s:3:"has";s:17:"street_name_value";s:0:"";s:15:"postal_code_min";s:0:"";s:15:"postal_code_max";s:0:"";s:14:"postal_code_op";s:3:"lte";s:17:"postal_code_value";s:0:"";s:7:"city_op";s:3:"has";s:10:"city_value";s:0:"";s:20:"state_province_id_op";s:2:"in";s:23:"state_province_id_value";a:0:{}s:13:"country_id_op";s:2:"in";s:16:"country_id_value";a:0:{}s:12:"survey_id_op";s:2:"in";s:15:"survey_id_value";a:0:{}s:12:"status_id_op";s:2:"eq";s:15:"status_id_value";s:1:"1";s:11:"custom_1_op";s:2:"in";s:14:"custom_1_value";a:0:{}s:11:"custom_2_op";s:2:"in";s:14:"custom_2_value";a:0:{}s:17:"custom_3_relative";s:1:"0";s:13:"custom_3_from";s:0:"";s:11:"custom_3_to";s:0:"";s:11:"description";s:75:"Detailed report for canvassing, phone-banking, walk lists or other surveys.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviReport";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}'); -UPDATE civicrm_domain SET version = '5.18.3'; +UPDATE civicrm_domain SET version = '5.18.4'; diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql index 40c9a6ed4d83ebea0381793fce4d10eff7aaddc7..cff8879d8e5d9f8953dc44e671590b0ceeddcb51 100644 --- a/civicrm/sql/civicrm_generated.mysql +++ b/civicrm/sql/civicrm_generated.mysql @@ -399,7 +399,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_domain` WRITE; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; -INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.18.3',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); +INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.18.4',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */; UNLOCK TABLES; diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php index 1f08a2e9258b672feb6a4e4a89f93560256ffbd1..8887f2c0f706ecf59cbd11683726ab55ada1c0d3 100644 --- a/civicrm/vendor/autoload.php +++ b/civicrm/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit5c8197a8f03eba874713d8c48301b95d::getLoader(); +return ComposerAutoloaderInitdb2000479593e65ef23454e56d74a73f::getLoader(); diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php index 20a82015a0ebda1f5ba8303f2ee0114ffb2e588d..a5b2d30db0b2d137301748a0d237fdd43f72ac10 100644 --- a/civicrm/vendor/composer/autoload_real.php +++ b/civicrm/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit5c8197a8f03eba874713d8c48301b95d +class ComposerAutoloaderInitdb2000479593e65ef23454e56d74a73f { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInit5c8197a8f03eba874713d8c48301b95d return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit5c8197a8f03eba874713d8c48301b95d', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitdb2000479593e65ef23454e56d74a73f', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit5c8197a8f03eba874713d8c48301b95d', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitdb2000479593e65ef23454e56d74a73f', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); @@ -31,7 +31,7 @@ class ComposerAutoloaderInit5c8197a8f03eba874713d8c48301b95d if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit5c8197a8f03eba874713d8c48301b95d::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitdb2000479593e65ef23454e56d74a73f::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -52,19 +52,19 @@ class ComposerAutoloaderInit5c8197a8f03eba874713d8c48301b95d $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit5c8197a8f03eba874713d8c48301b95d::$files; + $includeFiles = Composer\Autoload\ComposerStaticInitdb2000479593e65ef23454e56d74a73f::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire5c8197a8f03eba874713d8c48301b95d($fileIdentifier, $file); + composerRequiredb2000479593e65ef23454e56d74a73f($fileIdentifier, $file); } return $loader; } } -function composerRequire5c8197a8f03eba874713d8c48301b95d($fileIdentifier, $file) +function composerRequiredb2000479593e65ef23454e56d74a73f($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php index 796e004a7750ce6cd4a0cf6df9fcfa5994bba723..b7b53c380c3f17b89bb6fe736643761095933259 100644 --- a/civicrm/vendor/composer/autoload_static.php +++ b/civicrm/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit5c8197a8f03eba874713d8c48301b95d +class ComposerStaticInitdb2000479593e65ef23454e56d74a73f { public static $files = array ( '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', @@ -468,11 +468,11 @@ class ComposerStaticInit5c8197a8f03eba874713d8c48301b95d public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit5c8197a8f03eba874713d8c48301b95d::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit5c8197a8f03eba874713d8c48301b95d::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit5c8197a8f03eba874713d8c48301b95d::$prefixesPsr0; - $loader->fallbackDirsPsr0 = ComposerStaticInit5c8197a8f03eba874713d8c48301b95d::$fallbackDirsPsr0; - $loader->classMap = ComposerStaticInit5c8197a8f03eba874713d8c48301b95d::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitdb2000479593e65ef23454e56d74a73f::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitdb2000479593e65ef23454e56d74a73f::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitdb2000479593e65ef23454e56d74a73f::$prefixesPsr0; + $loader->fallbackDirsPsr0 = ComposerStaticInitdb2000479593e65ef23454e56d74a73f::$fallbackDirsPsr0; + $loader->classMap = ComposerStaticInitdb2000479593e65ef23454e56d74a73f::$classMap; }, null, ClassLoader::class); } diff --git a/civicrm/xml/version.xml b/civicrm/xml/version.xml index 29eb4c5bf5de05983084fe4d66f536e15a1ecfcf..993e529593d159ad825f8611aed4e846ec269ed0 100644 --- a/civicrm/xml/version.xml +++ b/civicrm/xml/version.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="iso-8859-1" ?> <version> - <version_no>5.18.3</version_no> + <version_no>5.18.4</version_no> </version> diff --git a/wp-rest/.editorconfig b/wp-rest/.editorconfig deleted file mode 100644 index 09dc3747d33a42560841336306fc106d96b39a47..0000000000000000000000000000000000000000 --- a/wp-rest/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -# EditorConfig is awesome: https://editorconfig.org - -# Not top-most EditorConfig file -root = false - -# Tab indentation -[*.php] -indent_style = tab -indent_size = 4 diff --git a/wp-rest/Autoloader.php b/wp-rest/Autoloader.php deleted file mode 100644 index dfa95f8a0219f6d8126f0b77110135049c693690..0000000000000000000000000000000000000000 --- a/wp-rest/Autoloader.php +++ /dev/null @@ -1,115 +0,0 @@ -<?php -/** - * Autoloader class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST; - -class Autoloader { - - /** - * Instance. - * - * @since 0.1 - * @var string - */ - private static $instance = null; - - /** - * Namespace. - * - * @since 0.1 - * @var string - */ - private $namespace = 'CiviCRM_WP_REST'; - - /** - * Autoloader directory sources. - * - * @since 0.1 - * @var array - */ - private static $source_directories = []; - - /** - * Constructor. - * - * @since 0.1 - */ - private function __construct() { - - $this->register_autoloader(); - - } - - /** - * Creates an instance of this class. - * - * @since 0.1 - */ - private static function instance() { - - if ( ! self::$instance ) self::$instance = new self; - - } - - /** - * Adds a directory source. - * - * @since 0.1 - * @param string $source The source path - */ - public static function add_source( string $source_path ) { - - // make sure we have an instance - self::instance(); - - if ( ! is_readable( trailingslashit( $source_path ) ) ) - return \WP_Error( 'civicrm_wp_rest_error', sprintf( __( 'The source %s is not readable.', 'civicrm' ), $source ) ); - - self::$source_directories[] = $source_path; - - } - - /** - * Registers the autoloader. - * - * @since 0.1 - * @return bool Wehather the autoloader has been registered or not - */ - private function register_autoloader() { - - return spl_autoload_register( [ $this, 'autoload' ] ); - - } - - /** - * Loads the classes. - * - * @since 0.1 - * @param string $class_name The class name to load - */ - private function autoload( $class_name ) { - - if ( false === strpos( $class_name, $this->namespace ) ) return; - - $parts = explode( '\\', $class_name ); - - // remove namespace and join class path - $class_path = str_replace( '_', '-', implode( DIRECTORY_SEPARATOR, array_slice( $parts, 1 ) ) ); - - array_map( function( $source_path ) use ( $class_path ) { - - $path = $source_path . $class_path . '.php'; - - if ( ! file_exists( $path ) ) return; - - require $path; - - }, static::$source_directories ); - - } - -} diff --git a/wp-rest/Civi/Mailing-Hooks.php b/wp-rest/Civi/Mailing-Hooks.php deleted file mode 100644 index 7113088b3ba4f868b6ad0ed286af3c205979b3f5..0000000000000000000000000000000000000000 --- a/wp-rest/Civi/Mailing-Hooks.php +++ /dev/null @@ -1,136 +0,0 @@ -<?php -/** - * CiviCRM Mailing_Hooks class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Civi; - -class Mailing_Hooks { - - /** - * Mailing Url endpoint. - * - * @since 0.1 - * @var string - */ - public $url_endpoint; - - /** - * Mailing Open endpoint. - * - * @since 0.1 - * @var string - */ - public $open_endpoint; - - /** - * Constructor. - * - * @since 0.1 - */ - public function __construct() { - - $this->url_endpoint = rest_url( 'civicrm/v3/url' ); - - $this->open_endpoint = rest_url( 'civicrm/v3/open' ); - - } - - /** - * Register hooks. - * - * @since 0.1 - */ - public function register_hooks() { - - add_filter( 'civicrm_alterMailParams', [ $this, 'do_mailing_urls' ], 10, 2 ); - - } - - /** - * Filters the mailing html and replaces calls to 'extern/url.php' and - * 'extern/open.php' with their REST counterparts 'civicrm/v3/url' and 'civicrm/v3/open'. - * - * @uses 'civicrm_alterMailParams' - * - * @since 0.1 - * @param array &$params Mail params - * @param string $context The Context - * @return array $params The filtered Mail params - */ - public function do_mailing_urls( &$params, $context ) { - - if ( $context == 'civimail' ) { - - $params['html'] = $this->replace_html_mailing_tracking_urls( $params['html'] ); - - $params['text'] = $this->replace_text_mailing_tracking_urls( $params['text'] ); - - } - - return $params; - - } - - /** - * Replace html mailing tracking urls. - * - * @since 0.1 - * @param string $contnet The mailing content - * @return string $content The mailing content - */ - public function replace_html_mailing_tracking_urls( string $content ) { - - $doc = \phpQuery::newDocument( $content ); - - foreach ( $doc[ '[href*="civicrm/extern/url.php"], [src*="civicrm/extern/open.php"]' ] as $element ) { - - $href = pq( $element )->attr( 'href' ); - $src = pq( $element )->attr( 'src' ); - - // replace extern/url - if ( strpos( $href, 'civicrm/extern/url.php' ) ) { - - $query_string = strstr( $href, '?' ); - pq( $element )->attr( 'href', $this->url_endpoint . $query_string ); - - } - - // replace extern/open - if ( strpos( $src, 'civicrm/extern/open.php' ) ) { - - $query_string = strstr( $src, '?' ); - pq( $element )->attr( 'src', $this->open_endpoint . $query_string ); - - } - - unset( $href, $src, $query_string ); - - } - - return $doc->html(); - - } - - /** - * Replace text mailing tracking urls. - * - * @since 0.1 - * @param string $contnet The mailing content - * @return string $content The mailing content - */ - public function replace_text_mailing_tracking_urls( string $content ) { - - // replace extern url - $content = preg_replace( '/http.*civicrm\/extern\/url\.php/i', $this->url_endpoint, $content ); - - // replace open url - $content = preg_replace( '/http.*civicrm\/extern\/open\.php/i', $this->open_endpoint, $content ); - - return $content; - - } - -} diff --git a/wp-rest/Controller/AuthorizeIPN.php b/wp-rest/Controller/AuthorizeIPN.php deleted file mode 100644 index 4cd9da9a97786f3176f55ec59c2528a77b774554..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/AuthorizeIPN.php +++ /dev/null @@ -1,123 +0,0 @@ -<?php -/** - * AuthorizeIPN controller class. - * - * Replacement for CiviCRM's 'extern/authorizeIPN.php'. - * - * @see https://docs.civicrm.org/sysadmin/en/latest/setup/payment-processors/authorize-net/#shell-script-testing-method - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class AuthorizeIPN extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'authorizeIPN'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/authorizeIPN/params', $request->get_params(), $request ); - - $authorize_IPN = new \CRM_Core_Payment_AuthorizeNetIPN( $params ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=AuthNet', $params ); - - /** - * Filter AuthorizeIPN object. - * - * @param CRM_Core_Payment_AuthorizeNetIPN $authorize_IPN - * @param array $params - * @param WP_REST_Request $request - */ - $authorize_IPN = apply_filters( 'civi_wp_rest/controller/authorizeIPN/instance', $authorize_IPN, $params, $request ); - - try { - - if ( ! method_exists( $authorize_IPN, 'main' ) || ! $this->instance_of_crm_base_ipn( $authorize_IPN ) ) - return $this->civi_rest_error( sprintf( __( '%s must implement a "main" method.', 'civicrm' ), get_class( $authorize_IPN ) ) ); - - $result = $authorize_IPN->main(); - - } catch ( \CRM_Core_Exception $e ) { - - \Civi::log()->error( $e->getMessage() ); - \Civi::log()->error( 'error data ', [ 'data' => $e->getErrorData() ] ); - \Civi::log()->error( 'REQUEST ', [ 'params' => $params ] ); - - return $this->civi_rest_error( $e->getMessage() ); - - } - - return rest_ensure_response( $result ); - - } - - /** - * Checks whether object is an instance of CRM_Core_Payment_AuthorizeNetIPN or CRM_Core_Payment_BaseIPN. - * - * Needed because the instance is being filtered through 'civi_wp_rest/controller/authorizeIPN/instance'. - * - * @since 0.1 - * @param CRM_Core_Payment_AuthorizeNetIPN|CRM_Core_Payment_BaseIPN $object - * @return bool - */ - public function instance_of_crm_base_ipn( $object ) { - - return $object instanceof \CRM_Core_Payment_BaseIPN || $object instanceof \CRM_Core_Payment_AuthorizeNetIPN; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Base.php b/wp-rest/Controller/Base.php deleted file mode 100644 index 7546377e9e0973103beeaf4fff5e9789df04070c..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/Base.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Base controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -use CiviCRM_WP_REST\Endpoint\Endpoint_Interface; - -abstract class Base extends \WP_REST_Controller implements Endpoint_Interface { - - /** - * Route namespace. - * - * @since 0.1 - * @var string - */ - protected $namespace = 'civicrm/v3'; - - /** - * Gets the endpoint namespace. - * - * @since 0.1 - * @return string $namespace - */ - public function get_namespace() { - - return $this->namespace; - - } - - /** - * Gets the rest base route. - * - * @since 0.1 - * @return string $rest_base - */ - public function get_rest_base() { - - return '/' . $this->rest_base; - - } - - /** - * Retrieves the endpoint ie. '/civicrm/v3/rest'. - * - * @since 0.1 - * @return string $rest_base - */ - public function get_endpoint() { - - return '/' . $this->get_namespace() . $this->get_rest_base(); - - } - - /** - * Checks whether the requested route is equal to this endpoint. - * - * @since 0.1 - * @param WP_REST_Request $request - * @return bool $is_current_endpoint True if it's equal, false otherwise - */ - public function is_current_endpoint( $request ) { - - return $this->get_endpoint() == $request->get_route(); - - } - - /** - * Authorization status code. - * - * @since 0.1 - * @return int $status - */ - protected function authorization_status_code() { - - $status = 401; - - if ( is_user_logged_in() ) $status = 403; - - return $status; - - } - - /** - * Wrapper for WP_Error. - * - * @since 0.1 - * @param string|\CiviCRM_API3_Exception $error - * @param mixed $data Error data - * @return WP_Error $error - */ - protected function civi_rest_error( $error, $data = [] ) { - - if ( $error instanceof \CiviCRM_API3_Exception ) { - - return $error->getExtraParams(); - - } - - return new \WP_Error( 'civicrm_rest_api_error', $error, empty( $data ) ? [ 'status' => $this->authorization_status_code() ] : $data ); - - } - -} diff --git a/wp-rest/Controller/Cxn.php b/wp-rest/Controller/Cxn.php deleted file mode 100644 index 7f7cca5c5621c3eb3441ca7060d5e1048eb85ade..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/Cxn.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php -/** - * Cxn controller class. - * - * CiviConnect endpoint, replacement for CiviCRM's 'extern/cxn.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Cxn extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'cxn'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/cxn/params', $request->get_params(), $request ); - - // init connection server - $cxn = \CRM_Cxn_BAO_Cxn::createApiServer(); - - /** - * Filter connection server object. - * - * @param Civi\Cxn\Rpc\ApiServer $cxn - * @param array $params - * @param WP_REST_Request $request - */ - $cxn = apply_filters( 'civi_wp_rest/controller/cxn/instance', $cxn, $params, $request ); - - try { - - $result = $cxn->handle( $request->get_body() ); - - } catch ( Civi\Cxn\Rpc\Exception\CxnException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\ExpiredCertException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\InvalidCertException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\InvalidMessageException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\GarbledMessageException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } - - /** - * Bypass WP and send request from Cxn. - */ - add_filter( 'rest_pre_serve_request', function( $served, $response, $request, $server ) use ( $result ) { - - // Civi\Cxn\Rpc\Message->send() - $result->send(); - - return true; - - }, 10, 4 ); - - return rest_ensure_response( $result ); - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Open.php b/wp-rest/Controller/Open.php deleted file mode 100644 index 450ef991a34897a169761dc9c1fdfcc57b4a0bf5..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/Open.php +++ /dev/null @@ -1,129 +0,0 @@ -<?php -/** - * Open controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Open extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'open'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [ $this, 'get_item' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Get item. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - $queue_id = $request->get_param( 'q' ); - - // track open - \CRM_Mailing_Event_BAO_Opened::open( $queue_id ); - - // serve tracker file - add_filter( 'rest_pre_serve_request', [ $this, 'serve_tracker_file' ], 10, 4 ); - - } - - /** - * Serves the tracker gif file. - * - * @since 0.1 - * @param bool $served Whether the request has been served - * @param WP_REST_Response $result - * @param WP_REST_Request $request - * @param WP_REST_Server $server - * @return bool $served Whether the request has been served - */ - public function serve_tracker_file( $served, $result, $request, $server ) { - - // tracker file path - $file = CIVICRM_PLUGIN_DIR . 'civicrm/i/tracker.gif'; - - // set headers - $server->send_header( 'Content-type', 'image/gif' ); - $server->send_header( 'Cache-Control', 'must-revalidate, post-check=0, pre-check=0' ); - $server->send_header( 'Content-Description', 'File Transfer' ); - $server->send_header( 'Content-Disposition', 'inline; filename=tracker.gif' ); - $server->send_header( 'Content-Length', filesize( $file ) ); - - $buffer = readfile( $file ); - - return true; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm/v3/open', - 'description' => __( 'CiviCRM Open endpoint', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'q' ], - 'properties' => [ - 'q' => [ - 'type' => 'integer' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'q' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ] - ]; - - } - -} diff --git a/wp-rest/Controller/PayPalIPN.php b/wp-rest/Controller/PayPalIPN.php deleted file mode 100644 index 5b5c38004525287b69024d51ea378cb5615f60bc..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/PayPalIPN.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php -/** - * PayPalIPN controller class. - * - * PayPal IPN endpoint, replacement for CiviCRM's 'extern/ipn.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class PayPalIPN extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'ipn'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/ipn/params', $request->get_params(), $request ); - - if ( $request->get_method() == 'GET' ) { - - // paypal standard - $paypal_IPN = new \CRM_Core_Payment_PayPalIPN( $params ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=PayPal_Standard', $params ); - - } else { - - // paypal pro - $paypal_IPN = new \CRM_Core_Payment_PayPalProIPN( $params ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=PayPal', $params ); - - } - - /** - * Filter PayPalIPN object. - * - * @param CRM_Core_Payment_PayPalIPN|CRM_Core_Payment_PayPalProIPN $paypal_IPN - * @param array $params - * @param WP_REST_Request $request - */ - $paypal_IPN = apply_filters( 'civi_wp_rest/controller/ipn/instance', $paypal_IPN, $params, $request ); - - try { - - if ( ! method_exists( $paypal_IPN, 'main' ) || ! $this->instance_of_crm_base_ipn( $paypal_IPN ) ) - return $this->civi_rest_error( sprintf( __( '%s must implement a "main" method.', 'civicrm' ), get_class( $paypal_IPN ) ) ); - - $result = $paypal_IPN->main(); - - } catch ( \CRM_Core_Exception $e ) { - - \Civi::log()->error( $e->getMessage() ); - \Civi::log()->error( 'error data ', [ 'data' => $e->getErrorData() ] ); - \Civi::log()->error( 'REQUEST ', [ 'params' => $params ] ); - - return $this->civi_rest_error( $e->getMessage() ); - - } - - return rest_ensure_response( $result ); - - } - - /** - * Checks whether object is an instance of CRM_Core_Payment_BaseIPN|CRM_Core_Payment_PayPalProIPN|CRM_Core_Payment_PayPalIPN. - * - * Needed because the instance is being filtered through 'civi_wp_rest/controller/ipn/instance'. - * - * @since 0.1 - * @param CRM_Core_Payment_BaseIPN|CRM_Core_Payment_PayPalProIPN|CRM_Core_Payment_PayPalIPN $object - * @return bool - */ - public function instance_of_crm_base_ipn( $object ) { - - return $object instanceof \CRM_Core_Payment_BaseIPN || $object instanceof \CRM_Core_Payment_PayPalProIPN || $object instanceof \CRM_Core_Payment_PayPalIPN; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/PxIPN.php b/wp-rest/Controller/PxIPN.php deleted file mode 100644 index d68fc8d787ae3e87eb449f36b459e0b8d24d845a..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/PxIPN.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php -/** - * PxIPN controller class. - * - * PxPay IPN endpoint, replacement for CiviCRM's 'extern/pxIPN.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class PxIPN extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'pxIPN'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter payment processor params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( - 'civi_wp_rest/controller/pxIPN/params', - $this->get_payment_processor_args( $request ), - $request - ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=Payment_Express', $params ); - - try { - - $result = \CRM_Core_Payment_PaymentExpressIPN::main( ...$params ); - - } catch ( \CRM_Core_Exception $e ) { - - \Civi::log()->error( $e->getMessage() ); - \Civi::log()->error( 'error data ', [ 'data' => $e->getErrorData() ] ); - \Civi::log()->error( 'REQUEST ', [ 'params' => $params ] ); - - return $this->civi_rest_error( $e->getMessage() ); - - } - - return rest_ensure_response( $result ); - - } - - /** - * Get payment processor necessary params. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $args - */ - public function get_payment_processor_args( $request ) { - - // get payment processor types - $payment_processor_types = civicrm_api3( 'PaymentProcessor', 'getoptions', [ - 'field' => 'payment_processor_type_id' - ] ); - - // payment processor params - $params = apply_filters( 'civi_wp_rest/controller/pxIPN/payment_processor_params', [ - 'user_name' => $request->get_param( 'userid' ), - 'payment_processor_type_id' => array_search( - 'DPS Payment Express', - $payment_processor_types['values'] - ), - 'is_active' => 1, - 'is_test' => 0 - ] ); - - // get payment processor - $payment_processor = civicrm_api3( 'PaymentProcessor', 'get', $params ); - - $args = $payment_processor['values'][$payment_processor['id']]; - - $method = empty( $args['signature'] ) ? 'pxpay' : 'pxaccess'; - - return [ - $method, - $request->get_param( 'result' ), - $args['url_site'], - $args['user_name'], - $args['password'], - $args['signature'] - ]; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Rest.php b/wp-rest/Controller/Rest.php deleted file mode 100644 index 61706f85fdc56b540829ca685dc607b173e45795..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/Rest.php +++ /dev/null @@ -1,522 +0,0 @@ -<?php -/** - * Rest controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Rest extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'rest'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_items' ], - 'permission_callback' => [ $this, 'permissions_check' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Check get permission. - * - * @since 0.1 - * @param WP_REST_Request $request - * @return bool - */ - public function permissions_check( $request ) { - - if ( ! $this->is_valid_api_key( $request ) ) - return $this->civi_rest_error( __( 'Param api_key is not valid.', 'civicrm' ) ); - - if ( ! $this->is_valid_site_key() ) - return $this->civi_rest_error( __( 'Param key is not valid.', 'civicrm' ) ); - - return true; - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_items( $request ) { - - /** - * Filter formatted api params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/rest/api_params', $this->get_formatted_api_params( $request ), $request ); - - try { - - $items = civicrm_api3( ...$params ); - - } catch ( \CiviCRM_API3_Exception $e ) { - - $items = $this->civi_rest_error( $e ); - - } - - if ( ! isset( $items ) || empty( $items ) ) - return rest_ensure_response( [] ); - - /** - * Filter civi api result. - * - * @since 0.1 - * @param array $items - * @param WP_REST_Request $request - */ - $data = apply_filters( 'civi_wp_rest/controller/rest/api_result', $items, $params, $request ); - - // only collections of items, ie any action but 'getsingle' - if ( isset( $data['values'] ) ) { - - $data['values'] = array_reduce( $items['values'] ?? $items, function( $items, $item ) use ( $request ) { - - $response = $this->prepare_item_for_response( $item, $request ); - - $items[] = $this->prepare_response_for_collection( $response ); - - return $items; - - }, [] ); - - } - - $response = rest_ensure_response( $data ); - - // check wheather we need to serve xml or json - if ( ! in_array( 'json', array_keys( $request->get_params() ) ) ) { - - /** - * Adds our response holding Civi data before dispatching. - * - * @since 0.1 - * @param WP_HTTP_Response $result Result to send to client - * @param WP_REST_Server $server The REST server - * @param WP_REST_Request $request The request - * @return WP_HTTP_Response $result Result to send to client - */ - add_filter( 'rest_post_dispatch', function( $result, $server, $request ) use ( $response ) { - - return $response; - - }, 10, 3 ); - - // serve xml - add_filter( 'rest_pre_serve_request', [ $this, 'serve_xml_response' ], 10, 4 ); - - } else { - - // return json - return $response; - - } - - } - - /** - * Get formatted api params. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $params - */ - public function get_formatted_api_params( $request ) { - - $args = $request->get_params(); - - $entity = $args['entity']; - $action = $args['action']; - - // unset unnecessary args - unset( $args['entity'], $args['action'], $args['key'], $args['api_key'] ); - - if ( ! isset( $args['json'] ) || is_numeric( $args['json'] ) ) { - - $params = $args; - - } else { - - $params = is_string( $args['json'] ) ? json_decode( $args['json'], true ) : []; - - } - - // ensure check permissions is enabled - $params['check_permissions'] = true; - - return [ $entity, $action, $params ]; - - } - - /** - * Matches the item data to the schema. - * - * @since 0.1 - * @param object $item - * @param WP_REST_Request $request - */ - public function prepare_item_for_response( $item, $request ) { - - return rest_ensure_response( $item ); - - } - - /** - * Serves XML response. - * - * @since 0.1 - * @param bool $served Whether the request has already been served - * @param WP_REST_Response $result - * @param WP_REST_Request $request - * @param WP_REST_Server $server - */ - public function serve_xml_response( $served, $result, $request, $server ) { - - // get xml from response - $xml = $this->get_xml_formatted_data( $result->get_data() ); - - // set content type header - $server->send_header( 'Content-Type', 'text/xml' ); - - echo $xml; - - return true; - - } - - /** - * Formats CiviCRM API result to XML. - * - * @since 0.1 - * @param array $data The CiviCRM api result - * @return string $xml The formatted xml - */ - protected function get_xml_formatted_data( array $data ) { - - // xml document - $xml = new \DOMDocument(); - - // result set element <ResultSet> - $result_set = $xml->createElement( 'ResultSet' ); - - // xmlns:xsi attribute - $result_set->setAttribute( 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance' ); - - // count attribute - if ( isset( $data['count'] ) ) $result_set->setAttribute( 'count', $data['count'] ); - - // build result from result => values - if ( isset( $data['values'] ) ) { - - array_map( function( $item ) use ( $result_set, $xml ) { - - // result element <Result> - $result = $xml->createElement( 'Result' ); - - // format item - $result = $this->get_xml_formatted_item( $item, $result, $xml ); - - // append result to result set - $result_set->appendChild( $result ); - - }, $data['values'] ); - - } else { - - // result element <Result> - $result = $xml->createElement( 'Result' ); - - // format item - $result = $this->get_xml_formatted_item( $data, $result, $xml ); - - // append result to result set - $result_set->appendChild( $result ); - - } - - // append result set - $xml->appendChild( $result_set ); - - return $xml->saveXML(); - - } - - /** - * Formats a single api result to xml. - * - * @since 0.1 - * @param array $item The single api result - * @param DOMElement $parent The parent element to append to - * @param DOMDocument $doc The document - * @return DOMElement $parent The parent element - */ - public function get_xml_formatted_item( array $item, \DOMElement $parent, \DOMDocument $doc ) { - - // build field => values - array_map( function( $field, $value ) use ( $parent, $doc ) { - - // entity field element - $element = $doc->createElement( $field ); - - // handle array values - if ( is_array( $value ) ) { - - array_map( function( $key, $val ) use ( $element, $doc ) { - - // child element, append underscore '_' otherwise createElement - // will throw an Invalid character exception as elements cannot start with a number - $child = $doc->createElement( '_' . $key, $val ); - - // append child - $element->appendChild( $child ); - - }, array_keys( $value ), $value ); - - } else { - - // assign value - $element->nodeValue = $value; - - } - - // append element - $parent->appendChild( $element ); - - }, array_keys( $item ), $item ); - - return $parent; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm/v3/rest', - 'description' => __( 'CiviCRM API3 WP rest endpoint wrapper', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'entity', 'action', 'params' ], - 'properties' => [ - 'is_error' => [ - 'type' => 'integer' - ], - 'version' => [ - 'type' => 'integer' - ], - 'count' => [ - 'type' => 'integer' - ], - 'values' => [ - 'type' => 'array' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'key' => [ - 'type' => 'string', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return $this->is_valid_site_key(); - - } - ], - 'api_key' => [ - 'type' => 'string', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return $this->is_valid_api_key( $request ); - - } - ], - 'entity' => [ - 'type' => 'string', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_string( $value ); - - } - ], - 'action' => [ - 'type' => 'string', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_string( $value ); - - } - ], - 'json' => [ - 'type' => ['integer', 'string', 'array'], - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ) || is_array( $value ) || $this->is_valid_json( $value ); - - } - ] - ]; - - } - - /** - * Checks if string is a valid json. - * - * @since 0.1 - * @param string $param - * @return bool - */ - protected function is_valid_json( $param ) { - - $param = json_decode( $param, true ); - - if ( ! is_array( $param ) ) return false; - - return ( json_last_error() == JSON_ERROR_NONE ); - - } - - /** - * Validates the site key. - * - * @since 0.1 - * @return bool $is_valid_site_key - */ - private function is_valid_site_key() { - - return \CRM_Utils_System::authenticateKey( false ); - - } - - /** - * Validates the api key. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return bool $is_valid_api_key - */ - private function is_valid_api_key( $request ) { - - $api_key = $request->get_param( 'api_key' ); - - if ( ! $api_key ) return false; - - $contact_id = \CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact', $api_key, 'id', 'api_key' ); - - // validate contact and login - if ( $contact_id ) { - - $wp_user = $this->get_wp_user( $contact_id ); - - $this->do_user_login( $wp_user ); - - return true; - - } - - return false; - - } - - /** - * Get WordPress user data. - * - * @since 0.1 - * @param int $contact_id The contact id - * @return bool|WP_User $user The WordPress user data - */ - protected function get_wp_user( int $contact_id ) { - - try { - - // Get CiviCRM domain group ID from constant, if set. - $domain_id = defined( 'CIVICRM_DOMAIN_ID' ) ? CIVICRM_DOMAIN_ID : 0; - - // If this fails, get it from config. - if ( $domain_id === 0 ) { - $domain_id = CRM_Core_Config::domainID(); - } - - // Call API. - $uf_match = civicrm_api3( 'UFMatch', 'getsingle', [ - 'contact_id' => $contact_id, - 'domain_id' => $domain_id, - ] ); - - } catch ( \CiviCRM_API3_Exception $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } - - $wp_user = get_userdata( $uf_match['uf_id'] ); - - return $wp_user; - - } - - /** - * Logs in the WordPress user, needed to respect CiviCRM ACL and permissions. - * - * @since 0.1 - * @param WP_User $user - */ - protected function do_user_login( \WP_User $user ) { - - if ( is_user_logged_in() ) return; - - wp_set_current_user( $user->ID, $user->user_login ); - - wp_set_auth_cookie( $user->ID ); - - do_action( 'wp_login', $user->user_login, $user ); - - } - -} diff --git a/wp-rest/Controller/Soap.php b/wp-rest/Controller/Soap.php deleted file mode 100644 index 17402cc579a834ca8854014e683a53aad5011399..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/Soap.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/** - * Soap controller class. - * - * Soap endpoint, replacement for CiviCRM's 'extern/soap.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Soap extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'soap'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/soap/params', $request->get_params(), $request ); - - // init soap server - $soap_server = new \SoapServer( - NULL, - [ - 'uri' => 'urn:civicrm', - 'soap_version' => SOAP_1_2, - ] - ); - - $crm_soap_server = new \CRM_Utils_SoapServer(); - - $soap_server->setClass( 'CRM_Utils_SoapServer', \CRM_Core_Config::singleton()->userFrameworkClass ); - $soap_server->setPersistence( SOAP_PERSISTENCE_SESSION ); - - /** - * Bypass WP and send request from Soap server. - */ - add_filter( 'rest_pre_serve_request', function( $served, $response, $request, $server ) use ( $soap_server ) { - - $soap_server->handle(); - - return true; - - }, 10, 4 ); - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Url.php b/wp-rest/Controller/Url.php deleted file mode 100644 index 9286856e7c88e6d1cf9057cf78da943cb34f73d1..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/Url.php +++ /dev/null @@ -1,214 +0,0 @@ -<?php -/** - * Url controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Url extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'url'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [ $this, 'get_item' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter formatted api params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/url/params', $this->get_formatted_params( $request ), $request ); - - // track url - $url = \CRM_Mailing_Event_BAO_TrackableURLOpen::track( $params['queue_id'], $params['url_id'] ); - - /** - * Filter url. - * - * @param string $url - * @param array $params - * @param WP_REST_Request $request - */ - $url = apply_filters( 'civi_wp_rest/controller/url/before_parse_url', $url, $params, $request ); - - // parse url - $url = $this->parse_url( $url, $params ); - - $this->do_redirect( $url ); - - } - - /** - * Get formatted api params. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $params - */ - protected function get_formatted_params( $request ) { - - $args = $request->get_params(); - - $params = [ - 'queue_id' => isset( $args['qid'] ) ? $args['qid'] ?? '' : $args['q'] ?? '', - 'url_id' => $args['u'] - ]; - - // unset unnecessary args - unset( $args['qid'], $args['u'], $args['q'] ); - - if ( ! empty( $args ) ) { - - $params['query'] = http_build_query( $args ); - - } - - return $params; - - } - - /** - * Parses the url. - * - * @since 0.1 - * @param string $url - * @param array $params - * @return string $url - */ - protected function parse_url( $url, $params ) { - - // CRM-18320 - Fix encoded ampersands - $url = str_replace( '&', '&', $url ); - - // CRM-7103 - Look for additional query variables and append them - if ( isset( $params['query'] ) && strpos( $url, '?' ) ) { - - $url .= '&' . $params['query']; - - } elseif ( isset( $params['query'] ) ) { - - $url .= '?' . $params['query']; - - } - - return apply_filters( 'civi_wp_rest/controller/url/parsed_url', $url, $params ); - - } - - /** - * Do redirect. - * - * @since 0.1 - * @param string $url - */ - protected function do_redirect( $url ) { - - wp_redirect( $url ); - - exit; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm_api3/v3/url', - 'description' => __( 'CiviCRM API3 wrapper', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'qid', 'u' ], - 'properties' => [ - 'qid' => [ - 'type' => 'integer' - ], - 'q' => [ - 'type' => 'integer' - ], - 'u' => [ - 'type' => 'integer' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'qid' => [ - 'type' => 'integer', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'q' => [ - 'type' => 'integer', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'u' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ] - ]; - - } - -} diff --git a/wp-rest/Controller/Widget.php b/wp-rest/Controller/Widget.php deleted file mode 100644 index 13fa1e2adde648de8c24b1278039385569bd5c21..0000000000000000000000000000000000000000 --- a/wp-rest/Controller/Widget.php +++ /dev/null @@ -1,214 +0,0 @@ -<?php -/** - * Widget controller class. - * - * Widget endpoint, replacement for CiviCRM's 'extern/widget.php' - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Widget extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'widget'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [ $this, 'get_item' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Get item. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter mandatory params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( - 'civi_wp_rest/controller/widget/params', - $this->get_mandatory_params( $request ), - $request - ); - - $jsonvar = 'jsondata'; - - if ( ! empty( $request->get_param( 'format' ) ) ) $jsonvar .= $request->get_param( 'cpageId' ); - - $data = \CRM_Contribute_BAO_Widget::getContributionPageData( ...$params ); - - $response = 'var ' . $jsonvar . ' = ' . json_encode( $data ) . ';'; - - /** - * Adds our response data before dispatching. - * - * @since 0.1 - * @param WP_HTTP_Response $result Result to send to client - * @param WP_REST_Server $server The REST server - * @param WP_REST_Request $request The request - * @return WP_HTTP_Response $result Result to send to client - */ - add_filter( 'rest_post_dispatch', function( $result, $server, $request ) use ( $response ) { - - return rest_ensure_response( $response ); - - }, 10, 3 ); - - // serve javascript - add_filter( 'rest_pre_serve_request', [ $this, 'serve_javascript' ], 10, 4 ); - - } - - /** - * Get mandatory params from request. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $params The widget params - */ - protected function get_mandatory_params( $request ) { - - $args = $request->get_params(); - - return [ - $args['cpageId'], - $args['widgetId'], - $args['includePending'] ?? false - ]; - - } - - /** - * Serve jsondata response. - * - * @since 0.1 - * @param bool $served Whether the request has already been served - * @param WP_REST_Response $result - * @param WP_REST_Request $request - * @param WP_REST_Server $server - * @return bool $served - */ - public function serve_javascript( $served, $result, $request, $server ) { - - // set content type header - $server->send_header( 'Expires', gmdate( 'D, d M Y H:i:s \G\M\T', time() + 60 ) ); - $server->send_header( 'Content-Type', 'application/javascript' ); - $server->send_header( 'Cache-Control', 'max-age=60, public' ); - - echo $result->get_data(); - - return true; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm_api3/v3/widget', - 'description' => __( 'CiviCRM API3 wrapper', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'cpageId', 'widgetId' ], - 'properties' => [ - 'cpageId' => [ - 'type' => 'integer', - 'minimum' => 1 - ], - 'widgetId' => [ - 'type' => 'integer', - 'minimum' => 1 - ], - 'format' => [ - 'type' => 'integer' - ], - 'includePending' => [ - 'type' => 'boolean' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'cpageId' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'widgetId' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'format' => [ - 'type' => 'integer', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'includePending' => [ - 'type' => 'boolean', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_string( $value ); - - } - ] - ]; - - } - -} diff --git a/wp-rest/Endpoint/Endpoint-Interface.php b/wp-rest/Endpoint/Endpoint-Interface.php deleted file mode 100644 index 9497cde5099ecbd7936571b0b73e318652abea7f..0000000000000000000000000000000000000000 --- a/wp-rest/Endpoint/Endpoint-Interface.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Endpoint Interface class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Endpoint; - -interface Endpoint_Interface { - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes(); - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema(); - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args(); - -} diff --git a/wp-rest/Plugin.php b/wp-rest/Plugin.php deleted file mode 100644 index 4038a56b1b6cab395e1a2d143cfe8882a7edb456..0000000000000000000000000000000000000000 --- a/wp-rest/Plugin.php +++ /dev/null @@ -1,193 +0,0 @@ -<?php -/** - * Main plugin class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST; - -use CiviCRM_WP_REST\Civi\Mailing_Hooks; - -class Plugin { - - /** - * Constructor. - * - * @since 0.1 - */ - public function __construct() { - - $this->register_hooks(); - - $this->setup_objects(); - - } - - /** - * Register hooks. - * - * @since 1.0 - */ - protected function register_hooks() { - - add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] ); - - add_filter( 'rest_pre_dispatch', [ $this, 'bootstrap_civi' ], 10, 3 ); - - add_filter( 'rest_post_dispatch', [ $this, 'maybe_reset_wp_timezone' ], 10, 3); - - } - - /** - * Bootstrap CiviCRM when hitting a the 'civicrm' namespace. - * - * @since 0.1 - * @param mixed $result - * @param WP_REST_Server $server REST server instance - * @param WP_REST_Request $request The request - * @return mixed $result - */ - public function bootstrap_civi( $result, $server, $request ) { - - if ( false !== strpos( $request->get_route(), 'civicrm' ) ) { - - $this->maybe_set_user_timezone( $request ); - - civi_wp()->initialize(); - - } - - return $result; - - } - - /** - * Setup objects. - * - * @since 0.1 - */ - private function setup_objects() { - - if ( CIVICRM_WP_REST_REPLACE_MAILING_TRACKING ) { - - // register mailing hooks - $mailing_hooks = ( new Mailing_Hooks )->register_hooks(); - - } - - } - - /** - * Registers Rest API routes. - * - * @since 0.1 - */ - public function register_rest_routes() { - - // rest endpoint - $rest_controller = new Controller\Rest; - $rest_controller->register_routes(); - - // url controller - $url_controller = new Controller\Url; - $url_controller->register_routes(); - - // open controller - $open_controller = new Controller\Open; - $open_controller->register_routes(); - - // authorizenet controller - $authorizeIPN_controller = new Controller\AuthorizeIPN; - $authorizeIPN_controller->register_routes(); - - // paypal controller - $paypalIPN_controller = new Controller\PayPalIPN; - $paypalIPN_controller->register_routes(); - - // pxpay controller - $paypalIPN_controller = new Controller\PxIPN; - $paypalIPN_controller->register_routes(); - - // civiconnect controller - $cxn_controller = new Controller\Cxn; - $cxn_controller->register_routes(); - - // widget controller - $widget_controller = new Controller\Widget; - $widget_controller->register_routes(); - - // soap controller - $soap_controller = new Controller\Soap; - $soap_controller->register_routes(); - - /** - * Opportunity to add more rest routes. - * - * @since 0.1 - */ - do_action( 'civi_wp_rest/plugin/rest_routes_registered' ); - - } - - /** - * Sets the timezone to the users timezone when - * calling the civicrm/v3/rest endpoint. - * - * @since 0.1 - * @param WP_REST_Request $request The request - */ - private function maybe_set_user_timezone( $request ) { - - if ( $request->get_route() != '/civicrm/v3/rest' ) return; - - $timezones = [ - 'wp_timezone' => date_default_timezone_get(), - 'user_timezone' => get_option( 'timezone_string', false ) - ]; - - // filter timezones - add_filter( 'civi_wp_rest/plugin/timezones', function() use ( $timezones ) { - - return $timezones; - - } ); - - if ( empty( $timezones['user_timezone'] ) ) return; - - /** - * CRM-12523 - * CRM-18062 - * CRM-19115 - */ - date_default_timezone_set( $timezones['user_timezone'] ); - \CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone(); - - } - - /** - * Resets the timezone to the original WP - * timezone after calling the civicrm/v3/rest endpoint. - * - * @since 0.1 - * @param mixed $result - * @param WP_REST_Server $server REST server instance - * @param WP_REST_Request $request The request - * @return mixed $result - */ - public function maybe_reset_wp_timezone( $result, $server, $request ) { - - if ( $request->get_route() != '/civicrm/v3/rest' ) return $result; - - $timezones = apply_filters( 'civi_wp_rest/plugin/timezones', null ); - - if ( empty( $timezones['wp_timezone'] ) ) return $result; - - // reset wp timezone - date_default_timezone_set( $timezones['wp_timezone'] ); - - return $result; - - } - -} diff --git a/wp-rest/README.md b/wp-rest/README.md deleted file mode 100644 index 77234de84a195dc6fbb22e1e7d460ff7d44587f2..0000000000000000000000000000000000000000 --- a/wp-rest/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# CiviCRM WP REST API Wrapper - -This is a WordPress plugin that aims to expose CiviCRM's [extern](https://github.com/civicrm/civicrm-core/tree/master/extern) scripts as WordPress REST endpoints. - -This plugin requires: - -- PHP 7.1+ -- WordPress 4.7+ -- CiviCRM to be installed and activated. - -### Endpoints - -1. `civicrm/v3/rest` - a wrapper around `civicrm_api3()` - - **Parameters**: - - - `key` - **required**, the site key - - `api_key` - **required**, the contact api key - - `entity` - **required**, the API entity - - `action` - **required**, the API action - - `json` - **optional**, json formatted string with the API parameters/argumets, or `1` as in `json=1` - - By default all calls to `civicrm/v3/rest` return XML formatted results, to get `json` formatted result pass `json=1` or a json formatted string with the API parameters, like in the example 2 below. - - **Examples**: - - 1. `https://example.com/wp-json/civicrm/v3/rest?entity=Contact&action=get&key=<site_key>&api_key=<api_key>&group=Administrators` - - 2. `https://example.com/wp-json/civicrm/v3/rest?entity=Contact&action=get&key=<site_key>&api_key=<api_key>&json={"group": "Administrators"}` - -2. `civicrm/v3/url` - a substition for `civicrm/extern/url.php` mailing tracking - -3. `civicrm/v3/open` - a substition for `civicrm/extern/open.php` mailing tracking - -4. `civicrm/v3/authorizeIPN` - a substition for `civicrm/extern/authorizeIPN.php` (for testing Authorize.net as per [docs](https://docs.civicrm.org/sysadmin/en/latest/setup/payment-processors/authorize-net/#shell-script-testing-method)) - - **_Note_**: this endpoint has **not been tested** - -5. `civicrm/v3/ipn` - a substition for `civicrm/extern/ipn.php` (for PayPal Standard and Pro live transactions) - - **_Note_**: this endpoint has **not been tested** - -6. `civicrm/v3/cxn` - a substition for `civicrm/extern/cxn.php` - -7. `civicrm/v3/pxIPN` - a substition for `civicrm/extern/pxIPN.php` - - **_Note_**: this endpoint has **not been tested** - -8. `civicrm/v3/widget` - a substition for `civicrm/extern/widget.php` - -9. `civicrm/v3/soap` - a substition for `civicrm/extern/soap.php` - - **_Note_**: this endpoint has **not been tested** - -### Settings - -Set the `CIVICRM_WP_REST_REPLACE_MAILING_TRACKING` constant to `true` to replace mailing url and open tracking calls with their counterpart REST endpoints, `civicrm/v3/url` and `civicrm/v3/open`. - -_Note: use this setting with caution, it may affect performance on large mailings, see `CiviCRM_WP_REST\Civi\Mailing_Hooks` class._