From 2e9051c710b62fd9fb5fd8bff48cdf5bb3d0e98e Mon Sep 17 00:00:00 2001 From: DemeritCowboy Date: Sun, 27 Oct 2019 08:18:35 -0400 Subject: [PATCH] fix misfiled pdf merges --- CRM/Case/Form/Task.php | 22 +++- CRM/Core/Form/Task.php | 51 +++++++++ tests/phpunit/CRM/Case/Form/TaskTest.php | 133 +++++++++++++++++++++++ 3 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/CRM/Case/Form/TaskTest.php diff --git a/CRM/Case/Form/Task.php b/CRM/Case/Form/Task.php index 43d77f1ced..157ce6223d 100644 --- a/CRM/Case/Form/Task.php +++ b/CRM/Case/Form/Task.php @@ -50,7 +50,9 @@ class CRM_Case_Form_Task extends CRM_Core_Form_Task { * @inheritDoc */ public function setContactIDs() { - $this->_contactIds = CRM_Core_DAO::getContactIDsFromComponent($this->_entityIds, + // @todo Parameters shouldn't be needed and should be class member + // variables instead, set appropriately by each subclass. + $this->_contactIds = $this->getContactIDsFromComponent($this->_entityIds, 'civicrm_case_contact', 'case_id' ); } @@ -64,4 +66,22 @@ class CRM_Case_Form_Task extends CRM_Core_Form_Task { return CRM_Contact_BAO_Query::MODE_CASE; } + /** + * Override of CRM_Core_Form_Task::orderBy() + * + * @return string + */ + public function orderBy() { + if (empty($this->_entityIds)) { + return ''; + } + $order_array = []; + foreach ($this->_entityIds as $item) { + // Ordering by conditional in mysql. This evaluates to 0 or 1, so we + // need to order DESC to get the '1'. + $order_array[] = 'case_id = ' . CRM_Core_DAO::escapeString($item) . ' DESC'; + } + return 'ORDER BY ' . implode(',', $order_array); + } + } diff --git a/CRM/Core/Form/Task.php b/CRM/Core/Form/Task.php index d9279d2000..cd659e3a1f 100644 --- a/CRM/Core/Form/Task.php +++ b/CRM/Core/Form/Task.php @@ -217,4 +217,55 @@ abstract class CRM_Core_Form_Task extends CRM_Core_Form { return $this->queryMode ?: CRM_Contact_BAO_Query::MODE_CONTACTS; } + /** + * Given the component id, compute the contact id + * since it's used for things like send email. + * + * @todo At the moment this duplicates a similar function in CRM_Core_DAO + * because right now only the case component is using this. Since the + * default $orderBy is '' which is what the original does, others should be + * easily convertable as NFC. + * @todo The passed in variables should be class member variables. Shouldn't + * need to have passed in vars. + * + * @param $componentIDs + * @param string $tableName + * @param string $idField + * + * @return array + */ + public function getContactIDsFromComponent($componentIDs, $tableName, $idField = 'id') { + $contactIDs = []; + + if (empty($componentIDs)) { + return $contactIDs; + } + + $orderBy = $this->orderBy(); + + $IDs = implode(',', $componentIDs); + $query = " +SELECT contact_id + FROM $tableName + WHERE $idField IN ( $IDs ) $orderBy +"; + + $dao = CRM_Core_DAO::executeQuery($query); + while ($dao->fetch()) { + $contactIDs[] = $dao->contact_id; + } + return $contactIDs; + } + + /** + * Default ordering for getContactIDsFromComponent. Subclasses can override. + * + * @return string + * SQL fragment. Either return '' or a valid order clause including the + * words "ORDER BY", e.g. "ORDER BY `{$this->idField}`" + */ + public function orderBy() { + return ''; + } + } diff --git a/tests/phpunit/CRM/Case/Form/TaskTest.php b/tests/phpunit/CRM/Case/Form/TaskTest.php new file mode 100644 index 0000000000..dc6c6f6b9e --- /dev/null +++ b/tests/phpunit/CRM/Case/Form/TaskTest.php @@ -0,0 +1,133 @@ +quickCleanup(['civicrm_case_contact', 'civicrm_case', 'civicrm_contact']); + } + + /** + * Test the order of the corresponding ids in the output matches the order + * of the ids in the input, i.e. case_contacts matches cases. + * + * @param $input array + * @param $selected_search_results array + * @param $expected array + * + * @dataProvider contactIDProvider + */ + public function testSetContactIDs($input, $selected_search_results, $expected) { + $this->createCaseContacts($input); + $task = new CRM_Case_Form_Task(); + + // This simulates the selection from the search results list. What we're + // testing is that no matter what order the cases were created or what + // mysql feels like doing today, the order of the retrieved contacts ends + // up matching the order that the cases came in from search results. + $task->_entityIds = $selected_search_results; + + $task->setContactIDs(); + $this->assertEquals($expected, $task->_contactIds); + } + + private function createCaseContacts($caseContacts) { + foreach ($caseContacts as $caseContact) { + // The corresponding case needs to exist. We don't care about most of + // its values, just the case_id. + CRM_Core_DAO::executeQuery("INSERT INTO civicrm_case (id, start_date, case_type_id, details, status_id, created_date) VALUES ({$caseContact['case_id']}, '2019-01-01', 1, '', 1, NOW())"); + // Ditto the contact + CRM_Core_DAO::executeQuery("INSERT INTO civicrm_contact (id, contact_type, created_date, image_URL, sort_name) VALUES ({$caseContact['contact_id']}, 'Individual', NOW(), '', 'Contact {$caseContact['contact_id']}')"); + // And now case_contact + CRM_Core_DAO::executeQuery("INSERT INTO civicrm_case_contact (contact_id, case_id) VALUES ({$caseContact['contact_id']}, {$caseContact['case_id']})"); + } + } + + /** + * Data provider for testSetContactIDs + * @return array + */ + public function contactIDProvider() { + return [ + // empty input + [[], [], []], + // one input + [ + [ + ['contact_id' => 1, 'case_id' => 2], + ], + // the case id's in the order they were passed in from search results + [2], + // the retrieved contacts listed in the expected order + [1], + ], + // some input + [ + [ + ['contact_id' => 1, 'case_id' => 2], + ['contact_id' => 3, 'case_id' => 4], + ['contact_id' => 5, 'case_id' => 6], + ], + [2, 4, 6], + [1, 3, 5], + ], + [ + [ + ['contact_id' => 1, 'case_id' => 2], + ['contact_id' => 3, 'case_id' => 4], + ['contact_id' => 5, 'case_id' => 6], + ], + [4, 2, 6], + [3, 1, 5], + ], + + // some more input + [ + [ + ['contact_id' => 17, 'case_id' => 12], + ['contact_id' => 3, 'case_id' => 8], + ['contact_id' => 25, 'case_id' => 45], + ['contact_id' => 18, 'case_id' => 33], + ], + [12, 8, 45, 33], + [17, 3, 25, 18], + ], + [ + [ + ['contact_id' => 17, 'case_id' => 12], + ['contact_id' => 3, 'case_id' => 8], + ['contact_id' => 25, 'case_id' => 45], + ['contact_id' => 18, 'case_id' => 33], + ], + [45, 8, 33, 12], + [25, 3, 18, 17], + ], + [ + [ + ['contact_id' => 17, 'case_id' => 12], + ['contact_id' => 3, 'case_id' => 8], + ['contact_id' => 25, 'case_id' => 45], + ['contact_id' => 18, 'case_id' => 33], + ], + [12, 33, 45, 8], + [17, 18, 25, 3], + ], + [ + [ + ['contact_id' => 17, 'case_id' => 12], + ['contact_id' => 3, 'case_id' => 8], + ['contact_id' => 25, 'case_id' => 45], + ['contact_id' => 18, 'case_id' => 33], + ], + [8, 33, 12, 45], + [3, 18, 17, 25], + ], + ]; + } + +} -- 2.25.1