From 897857a200c3c319c5ea6d7a7882e4c639de0c69 Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Wed, 25 Sep 2024 15:49:17 +0200 Subject: [PATCH] (wip) Replace various ocurrences of APIv3 calls to CiviSEPA entities with APIv4 calls for checking Financial ACLs permissions --- CRM/Sepa/BAO/SEPAMandate.php | 37 +++++++++---- CRM/Sepa/BAO/SEPATransactionGroup.php | 39 ++++++++++---- CRM/Sepa/Form/CreateMandate.php | 13 +++-- CRM/Sepa/Form/RetryCollection.php | 10 ++-- CRM/Sepa/Logic/Batching.php | 10 ++-- CRM/Sepa/Logic/PaymentInstruments.php | 6 ++- CRM/Sepa/Page/CreateMandate.php | 30 ++++++++--- .../Action/CreateOneOffMandate.php | 7 ++- .../Action/CreateRecurringMandate.php | 7 ++- .../Action/TerminateMandate.php | 10 ++-- api/v3/SepaMandate.php | 24 ++++++--- org.project60.sepacustom/sepacustom.php | 9 +++- sepa.php | 52 +++++++++++-------- 13 files changed, 176 insertions(+), 78 deletions(-) diff --git a/CRM/Sepa/BAO/SEPAMandate.php b/CRM/Sepa/BAO/SEPAMandate.php index fdbfc575..0a51d776 100644 --- a/CRM/Sepa/BAO/SEPAMandate.php +++ b/CRM/Sepa/BAO/SEPAMandate.php @@ -21,6 +21,8 @@ * */ +use CRM_Sepa_ExtensionUtil as E; + /** * Class contains functions for Sepa mandates @@ -48,9 +50,14 @@ static function add(&$params) { // new mandate, use the default creditor $default_creditor = CRM_Sepa_Logic_Settings::defaultCreditor(); $params['creditor_id'] = $default_creditor->id; - } else { + } + else { // existing mandate, get creditor - $params['creditor_id'] = civicrm_api3('SepaMandate', 'getvalue', array ('id' => $params['id'], 'return' => 'creditor_id')); + $params['creditor_id'] = \Civi\Api4\SepaMandate::get(TRUE) + ->addSelect('creditor_id') + ->addWhere('id', '=', $params['id']) + ->execute() + ->single()['creditor_id']; } } $creditor = civicrm_api3 ('SepaCreditor', 'getsingle', array ('id' => $params['creditor_id'], 'return' => 'mandate_prefix,creditor_type')); @@ -371,16 +378,22 @@ static function terminateMandate($mandate_id, $new_end_date_str, $cancel_reason= } // first, load the mandate - $mandate = civicrm_api("SepaMandate", "getsingle", array('id'=>$mandate_id, 'version'=>3)); - if (isset($mandate['is_error'])) { + try { + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('id', '=', $mandate_id) + ->execute() + ->single(); + } + catch (Exception $exception) { $lock->release(); - $error_message = sprintf(ts("Cannot read mandate [%s]. Error was: '%s'", array('domain' => 'org.project60.sepa')), $mandate_id, $mandate['error_message']); + $error_message = E::ts("Cannot read mandate [%1]. Error was: '%2'", [1 => $mandate_id, 2 => $exception->getMessage()]); if ($error_to_ui) { CRM_Core_Session::setStatus($error_message, ts('Error'), 'error'); return FALSE; - } else { - throw new Exception($error_message); + } + else { + throw new CRM_Core_Exception($error_message); } } @@ -546,7 +559,10 @@ static function modifyMandate($mandate_id, $changes) { } // load the mandate - $mandate = civicrm_api3('SepaMandate', 'getsingle', array('id' => $mandate_id)); + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('id', '=', $mandate_id) + ->execute() + ->single(); if ($mandate['type'] != 'RCUR') { $lock->release(); throw new Exception(ts("You can only modify RCUR mandates.", array('domain' => 'org.project60.sepa'))); @@ -906,7 +922,10 @@ public static function getLastMandateOfContact($cid) { ]); if ($result->fetch()) { // return the mandate - return civicrm_api3('SepaMandate', 'getsingle', array('id' => $result->mandate_id)); + return \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('id', '=', $result->mandate_id) + ->execute() + ->single(); } else { return FALSE; diff --git a/CRM/Sepa/BAO/SEPATransactionGroup.php b/CRM/Sepa/BAO/SEPATransactionGroup.php index 740c59da..cde44ece 100644 --- a/CRM/Sepa/BAO/SEPATransactionGroup.php +++ b/CRM/Sepa/BAO/SEPATransactionGroup.php @@ -184,8 +184,13 @@ function generateXML ($id = null) { * @return int id of the sepa file entity created, or an error message string */ static function createFile($txgroup_id, $override = false) { - $txgroup = civicrm_api('SepaTransactionGroup', 'getsingle', array('id'=>$txgroup_id, 'version'=>3)); - if (isset($txgroup['is_error']) && $txgroup['is_error']) { + try { + $txgroup = \Civi\Api4\SepaTransactionGroup::get(TRUE) + ->addWhere('id', '=', $txgroup_id) + ->execute() + ->single(); + } + catch (CRM_Core_Exception $exception) { return "Cannot find transaction group ".$txgroup_id; } @@ -252,7 +257,10 @@ static function createFile($txgroup_id, $override = false) { * @return an update array with the txgroup or a string with an error message */ static function adjustCollectionDate($txgroup_id, $latest_submission_date) { - $txgroup = civicrm_api3('SepaTransactionGroup', 'getsingle', array('id' => $txgroup_id)); + $txgroup = \Civi\Api4\SepaTransactionGroup::get(TRUE) + ->addWhere('id', '=', $txgroup_id) + ->execute() + ->single(); if ($txgroup['type'] == 'RTRY') { $txgroup['type'] = 'RCUR'; } @@ -277,12 +285,16 @@ static function adjustCollectionDate($txgroup_id, $latest_submission_date) { } // reload the item - $txgroup = civicrm_api('SepaTransactionGroup', 'getsingle', array('version'=>3, 'id'=>$txgroup_id)); - if (!empty($txgroup['is_error'])) { - return $txgroup['error_message']; - } else { - return $txgroup; + try { + $txgroup = \Civi\Api4\SepaTransactionGroup::get(TRUE) + ->addWhere('id', '=', $txgroup_id) + ->execute() + ->single(); } + catch (Exception $exception) { + return $exception->getMessage(); + } + return $txgroup; } @@ -302,9 +314,14 @@ static function adjustCollectionDate($txgroup_id, $latest_submission_date) { */ static function deleteGroup($txgroup_id, $delete_contributions_mode = 'no') { // load the group - $txgroup = civicrm_api('SepaTransactionGroup', 'getsingle', array('id' => $txgroup_id, 'version' => 3)); - if (!empty($txgroup['is_error'])) { - return "Transaction group [$txgroup_id] could not be loaded. Error was: ".$txgroup['error_message']; + try { + $txgroup = \Civi\Api4\SepaTransactionGroup::get(TRUE) + ->addWhere('id', '=', $txgroup_id) + ->execute() + ->single(); + } + catch (Exception $exception) { + return "Transaction group [$txgroup_id] could not be loaded. Error was: " . $exception->getMessage(); } // first, delete the contents of this group diff --git a/CRM/Sepa/Form/CreateMandate.php b/CRM/Sepa/Form/CreateMandate.php index eca16ca9..208598c3 100644 --- a/CRM/Sepa/Form/CreateMandate.php +++ b/CRM/Sepa/Form/CreateMandate.php @@ -469,9 +469,11 @@ public function postProcess() { try { $mandate = civicrm_api3('SepaMandate', 'createfull', $mandate_data); - $mandate = civicrm_api3('SepaMandate', 'getsingle', array( - 'id' => $mandate['id'], - 'return' => 'reference,id,type')); + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addSelect('reference', 'id', 'type') + ->addWhere('id', '=', $mandate['id']) + ->execute() + ->single(); // if we get here, everything went o.k. CRM_Core_Session::setStatus(E::ts("'%3' SEPA Mandate %1 created.", array( @@ -483,7 +485,10 @@ public function postProcess() { // terminate old mandate, of requested if (!empty($values['replace'])) { - $rpl_mandate = civicrm_api3('SepaMandate', 'getsingle', array('id' => $values['replace'])); + $rpl_mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('id', '=', $values['replace']) + ->execute() + ->single(); CRM_Sepa_BAO_SEPAMandate::terminateMandate( $values['replace'], diff --git a/CRM/Sepa/Form/RetryCollection.php b/CRM/Sepa/Form/RetryCollection.php index 6f9798ad..023e8348 100644 --- a/CRM/Sepa/Form/RetryCollection.php +++ b/CRM/Sepa/Form/RetryCollection.php @@ -222,11 +222,11 @@ protected function getCreditorList() { */ protected function getGroupList() { $txgroup_list = array(); - $txgroup_query = civicrm_api3('SepaTransactionGroup', 'get', array( - 'option.limit' => 0, - 'type' => array('IN' => array('RCUR', 'FRST')), - 'return' => 'reference,id')); - foreach ($txgroup_query['values'] as $txgroup) { + $txgroup_query = \Civi\Api4\SepaTransactionGroup::get(TRUE) + ->addSelect('reference', 'id') + ->addWhere('type', 'IN', ['RCUR', 'FRST']) + ->execute(); + foreach ($txgroup_query as $txgroup) { $txgroup_list[$txgroup['id']] = $txgroup['reference']; } return $txgroup_list; diff --git a/CRM/Sepa/Logic/Batching.php b/CRM/Sepa/Logic/Batching.php index 94b3ed53..d1f8356f 100644 --- a/CRM/Sepa/Logic/Batching.php +++ b/CRM/Sepa/Logic/Batching.php @@ -718,10 +718,12 @@ public static function getCycleDay($rcontribution, $creditor_id) { if (!empty($rcontribution['mandate_first_executed'])) { $date = $rcontribution['mandate_first_executed']; } else { - $mandate = civicrm_api3('SepaMandate', 'getsingle', array( - 'entity_table' => 'civicrm_contribution_recur', - 'entity_id' => $rcontribution['id'], - 'return' => 'status')); + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addSelect('status') + ->addWhere('entity_table', '=', 'civicrm_contribution_recur') + ->addWhere('entity_id', '=', $rcontribution['id']) + ->execute() + ->single(); if ($mandate['status'] == 'RCUR') { // support for RCUR without first contribution diff --git a/CRM/Sepa/Logic/PaymentInstruments.php b/CRM/Sepa/Logic/PaymentInstruments.php index 290f352f..9e8a1f2c 100644 --- a/CRM/Sepa/Logic/PaymentInstruments.php +++ b/CRM/Sepa/Logic/PaymentInstruments.php @@ -76,7 +76,11 @@ public static function getSDDPaymentInstrumentsForContribution($contribution_id) return null; } else { // get the creditor ID - $mandate = civicrm_api3('SepaMandate', 'getsingle', ['return' => 'creditor_id,type,status', 'id' => $mandate_id]); + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addSelect('creditor_id', 'type', 'status') + ->addWhere('id', '=', $mandate_id) + ->execute() + ->single(); return self::getPaymentInstrumentsForCreditor($mandate['creditor_id'], $mandate['type']); } } diff --git a/CRM/Sepa/Page/CreateMandate.php b/CRM/Sepa/Page/CreateMandate.php index 71ea6ad9..ffb33187 100644 --- a/CRM/Sepa/Page/CreateMandate.php +++ b/CRM/Sepa/Page/CreateMandate.php @@ -28,6 +28,8 @@ require_once 'CRM/Core/Page.php'; require_once 'packages/php-iban-1.4.0/php-iban.php'; +use CRM_Sepa_ExtensionUtil as E; + class CRM_Sepa_Page_CreateMandate extends CRM_Core_Page { function run() { @@ -327,9 +329,18 @@ function prepareCreateForm($contact_id) { * Will prepare the form by cloning the data from the given mandate */ function prepareClonedData($mandate_id) { - $mandate = civicrm_api('SepaMandate', 'getsingle', array('id'=>$mandate_id, 'version'=>3)); - if (isset($mandate['is_error']) && $mandate['is_error']) { - CRM_Core_Session::setStatus(sprintf(ts("Couldn't load mandate #%s", array('domain' => 'org.project60.sepa')), $mandate_id), ts('Error', array('domain' => 'org.project60.sepa')), 'error'); + try { + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('id', '=', $mandate) + ->execute() + ->single(); + } + catch (Exception $exception) { + CRM_Core_Session::setStatus( + E::ts("Couldn't load mandate #%1", [1 => $mandate_id]), + E::ts('Error'), + 'error' + ); return; } @@ -440,15 +451,20 @@ function validateParameters() { } // check reference - if (!empty($_REQUEST['reference'])) { + $reference = CRM_Utils_Request::retrieve('reference', 'String'); + if (!empty($reference)) { // check if it is formally correct - if (!preg_match("/^[A-Z0-9\\-]{4,35}$/", $_REQUEST['reference'])) { + if (!preg_match("/^[A-Z0-9\\-]{4,35}$/", $reference)) { $errors['reference'] = ts("Reference has to be an upper case alphanumeric string between 4 and 35 characters long.", array('domain' => 'org.project60.sepa')); } else { // check if the reference is taken - $count = civicrm_api3('SepaMandate', 'getcount', array("reference" => $_REQUEST['reference'])); + $count = \Civi\Api4\SepaMandate::get(TRUE) + ->selectRowCount() + ->addWhere('reference', '=', $reference) + ->execute() + ->countMatched(); if ($count > 0) { - $errors['reference'] = ts("This reference is already in use.", array('domain' => 'org.project60.sepa')); + $errors['reference'] = E::ts('This reference is already in use.'); } } } diff --git a/Civi/Sepa/ActionProvider/Action/CreateOneOffMandate.php b/Civi/Sepa/ActionProvider/Action/CreateOneOffMandate.php index fbd214f4..325a9bd6 100644 --- a/Civi/Sepa/ActionProvider/Action/CreateOneOffMandate.php +++ b/Civi/Sepa/ActionProvider/Action/CreateOneOffMandate.php @@ -22,6 +22,7 @@ use \Civi\ActionProvider\Parameter\Specification; use \Civi\ActionProvider\Parameter\SpecificationBag; +use Civi\Api4\SepaMandate; use CRM_Sepa_ExtensionUtil as E; class CreateOneOffMandate extends AbstractAction { @@ -126,7 +127,11 @@ protected function doAction(ParameterBagInterface $parameters, ParameterBagInter // create mandate try { $mandate = \civicrm_api3('SepaMandate', 'createfull', $mandate_data); - $mandate = \civicrm_api3('SepaMandate', 'getsingle', ['id' => $mandate['id'], 'return' => 'id,reference']); + $mandate = SepaMandate::get(TRUE) + ->addSelect('id', 'reference') + ->addWhere('id', '=', $mandate['id']) + ->execute() + ->single(); $output->setParameter('mandate_id', $mandate['id']); $output->setParameter('mandate_reference', $mandate['reference']); $output->setParameter('error', ''); diff --git a/Civi/Sepa/ActionProvider/Action/CreateRecurringMandate.php b/Civi/Sepa/ActionProvider/Action/CreateRecurringMandate.php index 0b1eedbe..dd8415d2 100644 --- a/Civi/Sepa/ActionProvider/Action/CreateRecurringMandate.php +++ b/Civi/Sepa/ActionProvider/Action/CreateRecurringMandate.php @@ -21,6 +21,7 @@ use \Civi\ActionProvider\Parameter\Specification; use \Civi\ActionProvider\Parameter\SpecificationBag; +use Civi\Api4\SepaMandate; use CRM_Sepa_ExtensionUtil as E; class CreateRecurringMandate extends CreateOneOffMandate { @@ -150,7 +151,11 @@ protected function doAction(ParameterBagInterface $parameters, ParameterBagInter // create mandate try { $mandate = \civicrm_api3('SepaMandate', 'createfull', $mandate_data); - $mandate = \civicrm_api3('SepaMandate', 'getsingle', ['id' => $mandate['id'], 'return' => 'id,reference,entity_id']); + $mandate = SepaMandate::get(TRUE) + ->addSelect('id', 'reference', 'entity_id') + ->addWhere('id', '=', $mandate['id']) + ->execute() + ->single(); $output->setParameter('mandate_id', $mandate['id']); $output->setParameter('recurring_contribution_id', $mandate['entity_id']); $output->setParameter('mandate_reference', $mandate['reference']); diff --git a/Civi/Sepa/ActionProvider/Action/TerminateMandate.php b/Civi/Sepa/ActionProvider/Action/TerminateMandate.php index fab45494..547a3e60 100644 --- a/Civi/Sepa/ActionProvider/Action/TerminateMandate.php +++ b/Civi/Sepa/ActionProvider/Action/TerminateMandate.php @@ -22,6 +22,7 @@ use \Civi\ActionProvider\Parameter\SpecificationBag; use Civi\FormProcessor\API\Exception; +use Civi\Sepa\DataProcessor\Source\SepaMandate; use CRM_Sepa_ExtensionUtil as E; class TerminateMandate extends AbstractAction { @@ -79,10 +80,11 @@ protected function doAction(ParameterBagInterface $parameters, ParameterBagInter if ($mandateReference) { // find mandate ID with reference try { - $mandateId = civicrm_api3('SepaMandate', 'getvalue', [ - 'return' => "id", - 'reference' => $mandateReference, - ]); + $mandateId = \Civi\Api4\SepaMandate::get(TRUE) + ->addSelect('id') + ->addWhere('reference', '=', $mandateReference) + ->execute() + ->single()['id']; if ($mandateId) { $output->setParameter('mandate_id', $mandateId); // terminate mandate with cancel reason from parameter if provided else condiguration cancel reason diff --git a/api/v3/SepaMandate.php b/api/v3/SepaMandate.php index 84f17cb5..77d83720 100644 --- a/api/v3/SepaMandate.php +++ b/api/v3/SepaMandate.php @@ -441,10 +441,14 @@ function civicrm_api3_sepa_mandate_modify($params) { // look up mandate ID if only reference is given if (empty($params['mandate_id']) && !empty($params['reference'])) { - $mandate = civicrm_api3('SepaMandate', 'get', array('reference' => $params['reference'], 'return' => 'id')); - if ($mandate['id']) { - $params['mandate_id'] = $mandate['id']; - } else { + try { + $params['mandate_id'] = \Civi\Api4\SepaMandate::get(TRUE) + ->addSelect('id') + ->addWhere('reference', '=', $params['reference']) + ->execute() + ->single()['id']; + } + catch (Exception $exception) { return civicrm_api3_create_error("Couldn't identify mandate with reference '{$params['reference']}'."); } } @@ -519,10 +523,14 @@ function _civicrm_api3_sepa_mandate_modify_spec(&$params) { function civicrm_api3_sepa_mandate_terminate($params) { // look up mandate ID if only reference is given if (empty($params['mandate_id']) && !empty($params['reference'])) { - $mandate = civicrm_api3('SepaMandate', 'get', array('reference' => $params['reference'], 'return' => 'id')); - if ($mandate['id']) { - $params['mandate_id'] = $mandate['id']; - } else { + try { + $params['mandate_id'] = \Civi\Api4\SepaMandate::get(TRUE) + ->addSelect('id') + ->addWhere('reference', '=', $params['reference']) + ->execute() + ->single()['id']; + } + catch (Exception $exception) { return civicrm_api3_create_error("Couldn't identify mandate with reference '{$params['reference']}'."); } } diff --git a/org.project60.sepacustom/sepacustom.php b/org.project60.sepacustom/sepacustom.php index 3cf31f10..f2d9cd65 100644 --- a/org.project60.sepacustom/sepacustom.php +++ b/org.project60.sepacustom/sepacustom.php @@ -115,8 +115,13 @@ function sepacustom_civicrm_create_mandate(&$mandate_parameters) { for ($n=0; $n < 10; $n++) { $reference_candidate = sprintf($reference, $n); // check if it exists - $mandate = civicrm_api('SepaMandate', 'getsingle', array('version' => 3, 'reference' => $reference_candidate)); - if (isset($mandate['is_error']) && $mandate['is_error']) { + try { + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('reference', '=', $reference_candidate) + ->execute() + ->single(); + } + catch (Exception $exception) { // does not exist! take it! $mandate_parameters['reference'] = $reference_candidate; return; diff --git a/sepa.php b/sepa.php index 643dc7b6..fd5f1fce 100644 --- a/sepa.php +++ b/sepa.php @@ -46,7 +46,8 @@ function sepa_civicrm_pageRun( &$page ) { ]); } - } elseif (get_class($page) == "CRM_Contribute_Page_Tab") { + } + elseif (get_class($page) == "CRM_Contribute_Page_Tab") { // single contribuion view if (CRM_Core_Permission::check('view sepa mandates')) { $contribution_id = $page->getTemplate()->get_template_vars('id'); @@ -59,34 +60,40 @@ function sepa_civicrm_pageRun( &$page ) { $contribution_recur_id = $page->getTemplate()->get_template_vars('contribution_recur_id'); if (empty($contribution_recur_id)) return; - $mandate = civicrm_api3('SepaMandate', 'getsingle', [ - 'entity_table' => 'civicrm_contribution_recur', - 'entity_id' => $contribution_recur_id - ]); + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('entity_table', '=', 'civicrm_contribution_recur') + ->addWhere('entity_id', '=', $contribution_recur_id) + ->execute() + ->single(); } else { // this is a OOFF contribtion - $mandate = civicrm_api3('SepaMandate', 'getsingle', [ - 'entity_table' => 'civicrm_contribution', - 'entity_id' => $contribution_id - ]); + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('entity_table', '=', 'civicrm_contribution') + ->addWhere('entity_id', '=', $contribution_id) + ->execute() + ->single(); } // add txgroup information - $txgroup_search = civicrm_api3('SepaContributionGroup', 'get', [ - 'contribution_id' => $contribution_id - ]); - if (empty($txgroup_search['id'])) { + $txgroup_search = \Civi\Api4\SepaContributionGroup::get(TRUE) + ->addWhere('contribution_id', '=', $contribution_id) + ->execute() + ->indexBy('id'); + if ($txgroup_search->count() === 0) { $mandate['tx_group'] = ts('None', ['domain' => 'org.project60.sepa']); - } else { - $group = reset($txgroup_search['values']); + } + else { + $group = $txgroup_search->first(); if (empty($group['txgroup_id'])) { $mandate['tx_group'] = ts('Error', ['domain' => 'org.project60.sepa']); - } else { - $mandate['tx_group'] = civicrm_api3('SepaTransactionGroup', 'getvalue', [ - 'return' => 'reference', - 'id' => $group['txgroup_id'] - ]); + } + else { + $mandate['tx_group'] = \Civi\Api4\SepaTransactionGroup::get(TRUE) + ->addSelect('reference') + ->addWhere('id', '=', $group['txgroup_id']) + ->execute() + ->single()['reference']; } } @@ -112,7 +119,10 @@ function sepa_civicrm_pageRun( &$page ) { // this is not a SEPA recurring contribution return; } - $mandate = civicrm_api3("SepaMandate","getsingle", ['id' => $mandate_id]); + $mandate = \Civi\Api4\SepaMandate::get(TRUE) + ->addWhere('id', '=', $mandate_id) + ->execute() + ->single(); // load notes $mandate['notes'] = [];