diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index c4e1999f0..41d0772e4 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -6,7 +6,7 @@ jobs: run-unit-tests: runs-on: ubuntu-latest - container: compucorp/civicrm-buildkit:1.1.1-php7.2-chrome + container: compucorp/civicrm-buildkit:1.3.0-php8.0-chrome env: CIVICRM_EXTENSIONS_DIR: site/web/sites/all/modules/civicrm/tools/extensions @@ -28,7 +28,15 @@ jobs: run : amp config:set --mysql_dsn=mysql://root:root@mysql:3306 - name: Build Drupal site - run: civibuild create drupal-clean --civi-ver 5.39.1 --cms-ver 7.85 --web-root $GITHUB_WORKSPACE/site + run: civibuild create drupal-clean --civi-ver 5.51.3 --cms-ver 7.79 --web-root $GITHUB_WORKSPACE/site + + - uses: compucorp/apply-patch@1.0.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + repo: compucorp/civicrm-core + version: 5.51.3 + path: site/web/sites/all/modules/civicrm - uses: actions/checkout@v2 with: diff --git a/CRM/Case/Export/Form/Map.php b/CRM/Case/Export/Form/Map.php deleted file mode 100644 index 7af90c3bf..000000000 --- a/CRM/Case/Export/Form/Map.php +++ /dev/null @@ -1,11 +0,0 @@ -getLoggedInContactID(); @@ -38,7 +37,7 @@ public function from($fieldName, $mode, $side) { /** * Alters where statement to include case locks. */ - public function where(&$query) { + public static function where(&$query) { if ($query->_mode == CRM_Contact_BAO_QUERY::MODE_ACTIVITY) { $query->_where[0][] = CRM_Contact_BAO_Query::buildClause("activity_lock", 'IS NULL'); @@ -47,9 +46,7 @@ public function where(&$query) { } /** - * Implements getPanesMapper, required by getPanesMapper hook. - * - * @param $panes + * {@inheritDoc} */ public function getPanesMapper(&$panes) { diff --git a/CRM/Civicase/Event/Listener/AssetBuilder.php b/CRM/Civicase/Event/Listener/AssetBuilder.php new file mode 100644 index 000000000..d9c2a9752 --- /dev/null +++ b/CRM/Civicase/Event/Listener/AssetBuilder.php @@ -0,0 +1,29 @@ +asset == 'angular-modules.json') { + $caseCategoryName = \Civi::cache('metadata')->get('current_case_category'); + CRM_Civicase_Hook_Helper_CaseTypeCategory::addWordReplacements($caseCategoryName); + + // Rebuild the asset if it has been built. + if (!empty($event->content)) { + Modules::buildAngularModules($event); + } + } + } + +} diff --git a/CRM/Civicase/Form/Report/BaseExtendedReport.php b/CRM/Civicase/Form/Report/BaseExtendedReport.php index f00584d64..5f6e08469 100644 --- a/CRM/Civicase/Form/Report/BaseExtendedReport.php +++ b/CRM/Civicase/Form/Report/BaseExtendedReport.php @@ -1173,23 +1173,9 @@ protected function addAggregateTotalField($fieldName, array $aggregates) { * of fields to be selected in the column header fields which is not * possible in the original function in base class. * - * @param array $specs - * Specifications. - * @param string $tableName - * Table name. - * @param string|null $daoName - * DAO name. - * @param string|null $tableAlias - * Table alias. - * @param array $defaults - * Defaults. - * @param array $options - * Options. - * - * @return array - * Column lists. + * @inheritDoc */ - protected function buildColumns(array $specs, $tableName, $daoName = NULL, $tableAlias = NULL, array $defaults = [], array $options = []) { + protected function buildColumns($specs, $tableName, $daoName = NULL, $tableAlias = NULL, $defaults = [], $options = []) { if (!$tableAlias) { $tableAlias = str_replace('civicrm_', '', $tableName); @@ -1283,8 +1269,8 @@ protected function buildColumns(array $specs, $tableName, $daoName = NULL, $tabl } } } - $columns[$tableName]['prefix'] = isset($options['prefix']) ? $options['prefix'] : ''; - $columns[$tableName]['prefix_label'] = isset($options['prefix_label']) ? $options['prefix_label'] : ''; + $columns[$tableName]['prefix'] = $options['prefix'] ?? ''; + $columns[$tableName]['prefix_label'] = $options['prefix_label'] ?? ''; if (isset($options['group_title'])) { $groupTitle = $options['group_title']; } @@ -1305,12 +1291,9 @@ protected function buildColumns(array $specs, $tableName, $daoName = NULL, $tabl * results for the row totals based on new Data aggregate functions * introduced. * - * @param array $rows - * Result rows. - * @param bool $pager - * Pager. + * @inheritDoc */ - public function formatDisplay(array &$rows, $pager = TRUE) { + public function formatDisplay(&$rows, $pager = TRUE) { // Set pager based on if any limit was applied in the query. if ($pager) { $this->setPager(); @@ -1352,19 +1335,7 @@ public function formatDisplay(array &$rows, $pager = TRUE) { /** * Use the options for the field to map the display value. * - * @param string $value - * Value of the field. - * @param array $row - * Row display values. - * @param string $selectedField - * Selected field. - * @param string $criteriaFieldName - * Criteria field name. - * @param array $specs - * Specifications of the column. - * - * @return string - * Label of the option ids. + * @inheritDoc */ public function alterFromOptions($value, array &$row, $selectedField, $criteriaFieldName, array $specs) { if ($specs['data_type'] == 'ContactReference') { @@ -1798,10 +1769,9 @@ public function buildQuickForm() { * when next the report instance is opened, those panes are automatically * expanded. * - * @param array $params - * Params. + * @inheritDoc */ - public function setParams(array $params) { + public function setParams($params) { if (empty($params)) { $this->_params = $params; return; diff --git a/CRM/Civicase/Form/Report/ColumnDefinitionTrait.php b/CRM/Civicase/Form/Report/ColumnDefinitionTrait.php index 296618c3b..1ed18a248 100644 --- a/CRM/Civicase/Form/Report/ColumnDefinitionTrait.php +++ b/CRM/Civicase/Form/Report/ColumnDefinitionTrait.php @@ -253,13 +253,9 @@ public function getCaseColumns(array $options) { /** * Get contact columns. * - * @param array $options - * Options for generating the columns. - * - * @return array - * Contact columns + * @inheritDoc */ - public function getContactColumns(array $options = []) { + protected function getContactColumns($options = []) { $defaultOptions = [ 'prefix' => '', 'prefix_label' => '', diff --git a/CRM/Civicase/Form/Report/ExtendedReport.php b/CRM/Civicase/Form/Report/ExtendedReport.php index e9a221eac..37b283a1d 100644 --- a/CRM/Civicase/Form/Report/ExtendedReport.php +++ b/CRM/Civicase/Form/Report/ExtendedReport.php @@ -830,7 +830,7 @@ function aggregateSelect() { * * @throws Exception */ - function addColumnAggregateSelect($fieldName, $dbAlias, $spec) { + public function addColumnAggregateSelect($fieldName, $dbAlias, array $spec) { if (empty($fieldName)) { $this->addAggregateTotal($fieldName); return; @@ -2314,7 +2314,7 @@ protected function addNullToFilterOptions($table, $fieldName, $label = '--does n * @param string $fieldAlias * @param string $title */ - protected function addRowHeader($tableAlias, $selectedField, $fieldAlias, $title = '') { + protected function addRowHeader($tableAlias, array $selectedField, $fieldAlias, $title = '') { if (empty($tableAlias)) { $this->_select = 'SELECT 1 '; // add a fake value just to save lots of code to calculate whether a comma is required later $this->_rollup = NULL; @@ -2578,7 +2578,7 @@ public function sectionTotals() { * * @param $rows */ - function alterRollupRows(&$rows) { + function alterRollupRows(array &$rows) { if (count($rows) === 1) { // If the report only returns one row there is no rollup. return; @@ -2636,7 +2636,7 @@ function alterRollupRows(&$rows) { * * @return string */ - function alterFromOptions($value, &$row, $selectedField, $criteriaFieldName, $specs) { + public function alterFromOptions($value, array &$row, $selectedField, $criteriaFieldName, array $specs) { if ($specs['data_type'] == 'ContactReference') { if (!empty($row[$selectedField])) { return CRM_Contact_BAO_Contact::displayName($row[$selectedField]); @@ -7488,7 +7488,7 @@ protected function getCustomDataDaos($extends) { * @param $prefixLabel * @param $tableKey */ - protected function addCustomTableToColumns($field, $currentTable, $prefix, $prefixLabel, $tableKey) { + protected function addCustomTableToColumns(array $field, $currentTable, $prefix, $prefixLabel, $tableKey) { $entity = $field['extends']; if (in_array($entity, ['Individual', 'Organization', 'Household'])) { $entity = 'Contact'; @@ -7572,7 +7572,7 @@ protected function getCustomFieldMetadata($field, $prefixLabel, $prefix = '') { * @return array * @throws \Exception */ - protected function getCustomFieldOptions($spec) { + protected function getCustomFieldOptions(array $spec) { $options = []; if (!empty($spec['options'])) { return $spec['options']; diff --git a/CRM/Civicase/Helper/Category.php b/CRM/Civicase/Helper/Category.php index f276890bb..96e2dfe51 100644 --- a/CRM/Civicase/Helper/Category.php +++ b/CRM/Civicase/Helper/Category.php @@ -29,7 +29,7 @@ public static function get(string $categoryName) { $categoryData = array_shift($categoryData['values']); $categoryCustomFields = (new CaseCategoryCustomFieldsSetting())->get($categoryData['value']); - $categoryData['singular_label'] = $categoryCustomFields['singular_label']; + $categoryData['singular_label'] = $categoryCustomFields['singular_label'] ?? NULL; return $categoryData; } diff --git a/CRM/Civicase/Hook/BuildForm/DisplayAllCustomGroupsInCaseForm.php b/CRM/Civicase/Hook/BuildForm/DisplayAllCustomGroupsInCaseForm.php deleted file mode 100644 index f1e0984bb..000000000 --- a/CRM/Civicase/Hook/BuildForm/DisplayAllCustomGroupsInCaseForm.php +++ /dev/null @@ -1,77 +0,0 @@ -shouldRun($form)) { - return; - } - - $caseId = $form->getVar('_entityId'); - $caseType = $form->getVar('_subType'); - $customGroups = CRM_Civicase_APIHelpers_CustomGroups::getAllActiveGroupsForEntity( - self::CASE_ENTITY_NAME - ); - $formattedCustomGroups = []; - - foreach ($customGroups['values'] as $customGroup) { - // Will return the right custom fields for the given case type. - // Fields belonging to other case types are removed. - $customGroupTree = CRM_Core_BAO_CustomGroup::getTree( - self::CASE_ENTITY_NAME, - NULL, - $caseId, - $customGroup['id'], - $caseType - ); - - // Removes extra data not used for displaying the custom fields: - $customGroupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($customGroupTree); - unset($customGroupTree['info']); - - $formattedCustomGroups = array_merge($formattedCustomGroups, $customGroupTree); - } - - // Adds the actual field element to each custom field: - CRM_Core_BAO_CustomGroup::buildQuickForm($form, $formattedCustomGroups); - - $form->setVar('_groupTree', $formattedCustomGroups); - } - - /** - * Determines if the hook should run. - * - * The Case Form is targeted to support validation for custom fields. The - * Custom Data form is targeted to add the actual fields. - * - * @param CRM_Core_Form $form - * CiviCRM Form. - * - * @return bool - * True when updating the case form or case form's custom groups. - */ - private function shouldRun(CRM_Core_Form $form) { - $isCaseEntity = $form->getVar('_type') === self::CASE_ENTITY_NAME; - $isCustomDataForm = get_class($form) === CRM_Custom_Form_CustomDataByType::class; - $isCaseForm = get_class($form) === CRM_Case_Form_Case::class; - - return $isCaseEntity && ( - $isCustomDataForm || $isCaseForm - ); - } - -} diff --git a/CRM/Civicase/Hook/BuildForm/HandleDraftActivities.php b/CRM/Civicase/Hook/BuildForm/HandleDraftActivities.php index 48432a080..8205aeb8e 100644 --- a/CRM/Civicase/Hook/BuildForm/HandleDraftActivities.php +++ b/CRM/Civicase/Hook/BuildForm/HandleDraftActivities.php @@ -13,7 +13,7 @@ class CRM_Civicase_Hook_BuildForm_HandleDraftActivities { ]; const PDF_LETTER_FORM_NAME = 'CRM_Contact_Form_Task_PDF'; - const EMAIL_FORM_NAME = 'CRM_Contact_Form_Task_Email'; + const EMAIL_FORM_NAME = 'CRM_Case_Form_Task_Email'; const SPECIAL_FORMS = [ self::PDF_LETTER_FORM_NAME, self::EMAIL_FORM_NAME, @@ -96,7 +96,7 @@ private function addSaveDraftButton(CRM_Core_Form &$form, $formName) { 'id' => $id, 'return' => 'case_id', ]); - $composeUrl = CRM_Utils_System::url("civicrm/activity/$atype/add", [ + $composeUrl = CRM_Utils_System::url("civicrm/case/$atype/add", [ 'action' => 'add', 'reset' => 1, 'caseId' => $caseId['case_id'][0], diff --git a/CRM/Civicase/Hook/BuildForm/LimitRecipientFieldsToOnlySelectedContacts.php b/CRM/Civicase/Hook/BuildForm/LimitRecipientFieldsToOnlySelectedContacts.php index 4b1bb96f9..818ddb95f 100644 --- a/CRM/Civicase/Hook/BuildForm/LimitRecipientFieldsToOnlySelectedContacts.php +++ b/CRM/Civicase/Hook/BuildForm/LimitRecipientFieldsToOnlySelectedContacts.php @@ -57,7 +57,7 @@ public function limitRecipientFields(CRM_Core_Form &$form) { */ private function shouldRun($formName) { return ( - $formName === CRM_Contact_Form_Task_Email::class && + $formName === CRM_Case_Form_Task_Email::class && CRM_Utils_Array::value('caseRolesBulkEmail', $_GET, '0') === '1' && CRM_Utils_Array::value('snippet', $_GET, '0') === CRM_Core_Smarty::PRINT_JSON && CRM_Utils_Array::value('cid', $_GET, '0') && diff --git a/CRM/Civicase/Hook/BuildForm/RestrictCaseEmailContacts.php b/CRM/Civicase/Hook/BuildForm/RestrictCaseEmailContacts.php index 685ff1e6a..0b991794c 100644 --- a/CRM/Civicase/Hook/BuildForm/RestrictCaseEmailContacts.php +++ b/CRM/Civicase/Hook/BuildForm/RestrictCaseEmailContacts.php @@ -40,8 +40,8 @@ public function run(CRM_Core_Form $form, $formName) { * True when the hook can run. */ private function shouldRun() { - $isEmailForm = get_class($this->form) === CRM_Contact_Form_Task_Email::class; - $isCaseEmail = !empty($this->form->getVar('_caseId')); + $isEmailForm = get_class($this->form) === CRM_Case_Form_Task_Email::class; + $isCaseEmail = !empty(CRM_Utils_Request::retrieve('caseid', 'Positive')); $shouldRestrictContacts = (bool) Civi::settings()->get('civicaseRestrictCaseEmailContacts'); $isBulkEmail = CRM_Utils_Array::value('caseRolesBulkEmail', $_GET, '0') === '1'; @@ -56,7 +56,7 @@ private function shouldRun() { * switching cases or updating the contacts for the existing one. */ private function addListOfCaseContactsToSettings() { - $caseId = $this->form->getVar('_caseId'); + $caseId = CRM_Utils_Request::retrieve('caseid', 'Positive'); $caseDetailsResponse = civicrm_api3('Case', 'getdetails', [ 'id' => $caseId, diff --git a/CRM/Civicase/Hook/BuildForm/TokenTree.php b/CRM/Civicase/Hook/BuildForm/TokenTree.php index 5cd9e735f..782d9aef1 100644 --- a/CRM/Civicase/Hook/BuildForm/TokenTree.php +++ b/CRM/Civicase/Hook/BuildForm/TokenTree.php @@ -56,7 +56,7 @@ public function run(CRM_Core_Form &$form, $formName) { if (!$this->shouldRun($formName)) { return; } - $this->isEmailForm = $form instanceof CRM_Contact_Form_Task_Email; + $this->isEmailForm = $form instanceof CRM_Case_Form_Task_Email; $this->setAllRelevantCustomFields(); $this->attachNewTokenTreeToForm($form); } @@ -479,7 +479,7 @@ private function shouldRun($formName) { return CRM_Utils_Request::retrieve('caseid', 'Integer') && in_array( $formName, - [CRM_Contact_Form_Task_Email::class, CRM_Contact_Form_Task_PDF::class] + [CRM_Case_Form_Task_Email::class, CRM_Contact_Form_Task_PDF::class] ); } diff --git a/CRM/Civicase/Hook/Helper/CaseTypeCategory.php b/CRM/Civicase/Hook/Helper/CaseTypeCategory.php index 9879ee617..cc6d48d2f 100644 --- a/CRM/Civicase/Hook/Helper/CaseTypeCategory.php +++ b/CRM/Civicase/Hook/Helper/CaseTypeCategory.php @@ -68,11 +68,6 @@ public static function addWordReplacements($caseCategoryName) { return; } - $currentCaseCategory = \Civi::cache('metadata')->get('current_case_category'); - if ($currentCaseCategory === $caseCategoryName) { - return; - } - CRM_Core_Resources::singleton()->flushStrings()->resetCacheCode(); \Civi::cache('metadata')->set('current_case_category', $caseCategoryName); $wordReplacements = CaseCategoryHelper::getWordReplacements($caseCategoryName); diff --git a/CRM/Civicase/Hook/PostProcess/ActivityFormStatusWordReplacement.php b/CRM/Civicase/Hook/PostProcess/ActivityFormStatusWordReplacement.php index 1d6024faf..3c4536b9f 100644 --- a/CRM/Civicase/Hook/PostProcess/ActivityFormStatusWordReplacement.php +++ b/CRM/Civicase/Hook/PostProcess/ActivityFormStatusWordReplacement.php @@ -32,6 +32,7 @@ public function run($formName, CRM_Core_Form $form) { return; } + $caseId = ((array) $caseId)[0] ?? NULL; $caseCategoryName = CaseCategoryHelper::getCategoryName($caseId); CaseCategoryWordReplacementHelper::addWordReplacements($caseCategoryName); $translatedActivityTypeName = civicaseTs($form->getVar('_activityTypeName')); diff --git a/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCases.php b/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCases.php index 6e8ca8154..0d77e4c18 100644 --- a/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCases.php +++ b/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCases.php @@ -67,7 +67,7 @@ private function addActivityToAllSelectedCases() { * Whether the hook should run or not. */ private function shouldRun($formName) { - return $formName === CRM_Contact_Form_Task_Email::class && + return $formName === CRM_Case_Form_Task_Email::class && !empty(CRM_Utils_Array::value('allCaseIds', $_GET, '0')) && !empty(CRM_Utils_Array::value('caseid', $_GET, '0')); } diff --git a/CRM/Civicase/Hook/PostProcess/HandleDraftActivity.php b/CRM/Civicase/Hook/PostProcess/HandleDraftActivity.php index d2bbc768b..46a64fdda 100644 --- a/CRM/Civicase/Hook/PostProcess/HandleDraftActivity.php +++ b/CRM/Civicase/Hook/PostProcess/HandleDraftActivity.php @@ -82,7 +82,7 @@ private function markPdfActivityAsComplete($form, $draftActivityID) { * Whether the hook should run or not. */ private function shouldRun($formName, $urlParams) { - $specialForms = ['CRM_Contact_Form_Task_PDF', 'CRM_Contact_Form_Task_Email']; + $specialForms = ['CRM_Contact_Form_Task_PDF', 'CRM_Case_Form_Task_Email']; return in_array($formName, $specialForms) && !empty($urlParams['draft_id']); } diff --git a/CRM/Civicase/Hook/ValidateForm/SaveActivityDraft.php b/CRM/Civicase/Hook/ValidateForm/SaveActivityDraft.php index 4588f00e9..e3893a1da 100644 --- a/CRM/Civicase/Hook/ValidateForm/SaveActivityDraft.php +++ b/CRM/Civicase/Hook/ValidateForm/SaveActivityDraft.php @@ -12,7 +12,7 @@ class CRM_Civicase_Hook_ValidateForm_SaveActivityDraft { */ private $specialForms = [ 'pdf' => 'CRM_Contact_Form_Task_PDF', - 'email' => 'CRM_Contact_Form_Task_Email', + 'email' => 'CRM_Case_Form_Task_Email', ]; /** @@ -34,7 +34,7 @@ public function run($formName, array &$fields, array &$files, CRM_Core_Form &$fo return; } - if (!array_key_exists($form->getButtonName('refresh'), $fields['buttons'])) { + if (empty($fields['buttons']) || !array_key_exists($form->getButtonName('refresh'), $fields['buttons'])) { return; } @@ -56,7 +56,7 @@ private function saveDraftForSpecialForms($formName, CRM_Core_Form &$form, array // The validate stage provides an opportunity to bypass normal // form processing, save the draft & return early. $activityType = $form->getVar('_activityTypeId'); - $caseId = $form->getVar('_caseId'); + $caseId = CRM_Utils_Request::retrieve('caseid', 'String'); if (!$activityType) { $activityType = $formName == 'CRM_Contact_Form_Task_PDF' ? 'Print PDF Letter' : 'Email'; } diff --git a/CRM/Civicase/Hook/ValidateForm/SendBulkEmail.php b/CRM/Civicase/Hook/ValidateForm/SendBulkEmail.php index b9d0715da..5f6ffbeaf 100644 --- a/CRM/Civicase/Hook/ValidateForm/SendBulkEmail.php +++ b/CRM/Civicase/Hook/ValidateForm/SendBulkEmail.php @@ -2,6 +2,12 @@ /** * Send bulk email. + * + * CiviCRM only supports sending bulk emails to clients in a single case, + * Sending to clients in multiple case, like we do in CiviCase + * results in the case tokens not being resolved. to bypass this limitation + * in CiviCRM we use this hook to intercept the email form, + * and then send the bulk email to a case at a time. */ class CRM_Civicase_Hook_ValidateForm_SendBulkEmail { @@ -45,7 +51,7 @@ class CRM_Civicase_Hook_ValidateForm_SendBulkEmail { * * @var array|int[] */ - private $originalToContactEmails; + private $originalToContactEmails = []; /** * CRM_Civicase_Hook_ValidateForm_SendBulkEmail constructor. @@ -82,26 +88,33 @@ public function __construct() { * @return bool * TRUE if the hook ran, false otherwise. */ - public function run($formName, array &$fields, array &$files, CRM_Core_Form &$form, array &$errors) { + public function run($formName, array &$fields, array &$files, CRM_Core_Form $form, array &$errors) { $this->form = $form; if (!$this->shouldRun()) { return FALSE; } + $data = $this->form->controller->container(); $this->originalContactIds = $this->form->_contactIds; - $this->originalToContactEmails = $this->form->_toContactEmails; + $this->originalToContactEmails = explode(',', $data['values']['Email']['to']); $casesContactInfo = $this->getCasesContactInfo(); $messageSentCount = 0; foreach ($casesContactInfo as $caseId => $contactIds) { - $this->sendEmailForCase($caseId, $contactIds); + // We are cloning here because we want each form submission + // for a caseID to be handle as a new form submission in CiviCRM + // though the only thing being changed for each form is the case ID + // and to field. + $emailForm = clone $this->form; + $this->sendEmailForCase($emailForm, $caseId, $contactIds); $messageSentCount += count($contactIds); } - if ($messageSentCount > count($this->originalContactIds)) { + if ($messageSentCount > 1) { $this->updateStatusMessage($messageSentCount); } + if (CRM_Utils_Array::value('snippet', $_GET) === 'json') { CRM_Core_Page_AJAX::returnJsonResponse([]); } @@ -117,7 +130,7 @@ public function run($formName, array &$fields, array &$files, CRM_Core_Form &$fo */ private function shouldRun() { return ( - get_class($this->form) === CRM_Contact_Form_Task_Email::class && + get_class($this->form) === CRM_Case_Form_Task_Email::class && !empty($this->caseIds) && (!empty($this->caseRoles) || $this->isClientRoleSelected) ); @@ -209,23 +222,33 @@ private function getCaseRoleContacts(array $casesContactInfo) { /** * Send the emails for the contacts associated with the given case. * + * @param CRM_Case_Form_Task_Email $form + * A clone of the form object. * @param int $caseId * The Id of the Case. * @param array|int[] $contactIds * Array with contact Ids. */ - private function sendEmailForCase(int $caseId, array $contactIds) { + private function sendEmailForCase(CRM_Case_Form_Task_Email $form, int $caseId, array $contactIds) { $_GET['caseid'] = $_REQUEST['caseid'] = $caseId; - $this->form->_caseId = $caseId; - $this->form->_contactIds = $contactIds; + $form->_caseId = $caseId; + $form->_contactIds = $contactIds; $toContactEmails = []; - foreach ($contactIds as $contactId) { - $originalPosition = array_search($contactId, $this->originalContactIds); - $toContactEmails[] = $this->originalToContactEmails[$originalPosition]; + + $data = &$form->controller->container(); + foreach ($this->originalToContactEmails as $emailId) { + $separatedEmailId = explode('::', $emailId); + $id = $separatedEmailId[0]; + + if (in_array($id, $contactIds)) { + $toContactEmails[$id] = $emailId; + } } - $this->form->_toContactEmails = $toContactEmails; - $this->form->submit($this->form->exportValues()); + + $data['values']['Email']['to'] = implode(',', $toContactEmails); + + $form->submit($form->exportValues()); } /** @@ -236,14 +259,11 @@ private function sendEmailForCase(int $caseId, array $contactIds) { */ private function updateStatusMessage(int $messageSentCount) { $status = CRM_Core_Session::singleton()->getStatus(TRUE)[0]; - - $originalMessage = count($this->originalContactIds) === 1 - ? 'One message was sent successfully.' - : count($this->originalContactIds) . ' messages were sent successfully.'; + $originalMessage = explode('.', $status['text'])[0] ?? ""; $status['text'] = str_replace( $originalMessage, - "$messageSentCount messages were sent successfully.", + "$messageSentCount messages were sent successfully", $status['text'] ); CRM_Core_Session::setStatus( diff --git a/CRM/Civicase/Hook/alterAPIPermissions/CaseCategory.php b/CRM/Civicase/Hook/alterAPIPermissions/CaseCategory.php index 1dfd3fe30..983357b1b 100644 --- a/CRM/Civicase/Hook/alterAPIPermissions/CaseCategory.php +++ b/CRM/Civicase/Hook/alterAPIPermissions/CaseCategory.php @@ -204,7 +204,7 @@ private function getCaseCategoryNameFromCaseTypeCategory(array $params, $key) { } $caseTypeCategoryParam = $params[$key]; - if (array_key_exists('IN', $caseTypeCategoryParam)) { + if (is_array($caseTypeCategoryParam) && array_key_exists('IN', $caseTypeCategoryParam)) { foreach ($caseTypeCategoryParam['IN'] as $caseCategory) { return $this->getCaseTypeCategoryNameFromOptions($caseCategory); } diff --git a/CRM/Civicase/Hook/alterMailParams/SubjectCaseTypeCategoryProcessor.php b/CRM/Civicase/Hook/alterMailParams/SubjectCaseTypeCategoryProcessor.php index 8224d1e48..cf659eac6 100644 --- a/CRM/Civicase/Hook/alterMailParams/SubjectCaseTypeCategoryProcessor.php +++ b/CRM/Civicase/Hook/alterMailParams/SubjectCaseTypeCategoryProcessor.php @@ -69,6 +69,9 @@ public function run(array &$params, $context) { * returns TRUE if hook should run, FALSE otherwise. */ private function shouldRun(array $params, $context, $caseId) { + if (empty($params['subject'])) { + return FALSE; + } // If case id is set and email subject starts with '[case '. return $caseId && strpos($params['subject'], $this->toReplace) === 0; } diff --git a/CRM/Civicase/Page/MyActivities.php b/CRM/Civicase/Page/MyActivities.php index 2bfd9df24..addbc1935 100644 --- a/CRM/Civicase/Page/MyActivities.php +++ b/CRM/Civicase/Page/MyActivities.php @@ -20,7 +20,7 @@ class CRM_Civicase_Page_MyActivities extends CRM_Core_Page { public function run() { $loader = new AngularLoader(); $loader->setPageName('civicrm/case/my-activities'); - $loader->setModules(['crmApp', 'my-activities']); + $loader->addModules(['crmApp', 'my-activities']); $loader->load(); CRM_Core_Resources::singleton() diff --git a/CRM/Civicase/Service/ManageWorkflowMenu.php b/CRM/Civicase/Service/ManageWorkflowMenu.php index 3fcd3601e..88ed78f49 100644 --- a/CRM/Civicase/Service/ManageWorkflowMenu.php +++ b/CRM/Civicase/Service/ManageWorkflowMenu.php @@ -50,7 +50,7 @@ public function create(string $instanceTypeName, bool $showCategoryNameOnMenuLab ? 'Manage ' . $caseTypeCategory['name'] : 'Manage Workflows'; - if ($parentMenuForCaseCategory['id']) { + if (!empty($parentMenuForCaseCategory['id'])) { $this->addSeparatorToTheLastMenuOf( $parentMenuForCaseCategory['id'] ); diff --git a/CRM/Civicase/Test/Fabricator/Case.php b/CRM/Civicase/Test/Fabricator/Case.php index bfb010566..c4619dbc4 100644 --- a/CRM/Civicase/Test/Fabricator/Case.php +++ b/CRM/Civicase/Test/Fabricator/Case.php @@ -1,31 +1,45 @@ - 'test test', - ); - - public static function fabricate($params = array()) { - if (empty($params['contact_id'])) { - throw new Exception('Please specify contact_id value'); - } - - if (empty($params['creator_id'])) { - throw new Exception('Please specify creator_id value'); - } - - if (empty($params['case_type_id'])) { - throw new Exception('Please specify case_type_id value'); - } - - $params = array_merge(self::$defaultParams, $params); - $result = civicrm_api3('Case', 'create', $params); - - return array_shift($result['values']); - } - -} + 'test test', + ]; + + /** + * Fabricate Case. + * + * @param array $params + * Parameters. + * + * @return mixed + * Api result. + */ + public static function fabricate(array $params = []) { + if (empty($params['contact_id'])) { + throw new Exception('Please specify contact_id value'); + } + + if (empty($params['creator_id'])) { + throw new Exception('Please specify creator_id value'); + } + + if (empty($params['case_type_id'])) { + throw new Exception('Please specify case_type_id value'); + } + + $params = array_merge(self::$defaultParams, $params); + $result = civicrm_api3('Case', 'create', $params); + + return array_shift($result['values']); + } + +} diff --git a/CRM/Civicase/Test/Fabricator/CaseType.php b/CRM/Civicase/Test/Fabricator/CaseType.php index b6a6c1360..555539375 100644 --- a/CRM/Civicase/Test/Fabricator/CaseType.php +++ b/CRM/Civicase/Test/Fabricator/CaseType.php @@ -1,42 +1,56 @@ - 'test case type', - 'name' => 'test_case_type', - 'is_active' => 1, - 'sequential' => 1, - 'weight' => 100, - 'definition' => array( - 'activityTypes' => array( - array('name' => 'Test'), - ), - 'activitySets' => array( - array( - 'name' => 'set1', - 'label' => 'Label 1', - 'timeline' => 1, - 'activityTypes' => array( - array('name' => 'Open Case', 'status' => 'Completed'), - ), - ), - ), - ), - ); - - public static function fabricate($params = array()) { - $params = array_merge(self::$defaultParams, $params); - $result = civicrm_api3( - 'CaseType', - 'create', - $params - ); - - return array_shift($result['values']); - } - -} + 'test case type', + 'name' => 'test_case_type', + 'is_active' => 1, + 'sequential' => 1, + 'weight' => 100, + 'definition' => [ + 'activityTypes' => [ + ['name' => 'Meeting'], + ], + 'activitySets' => [ + [ + 'name' => 'set1', + 'label' => 'Label 1', + 'timeline' => 1, + 'activityTypes' => [ + ['name' => 'Open Case', 'status' => 'Completed'], + ], + ], + ], + ], + ]; + + /** + * Fabricates new CaseType entity. + * + * @param array $params + * Case parameters. + * + * @return array + * Values of newly created Case entity. + */ + public static function fabricate(array $params = []) { + $params = array_merge(self::$defaultParams, $params); + $result = civicrm_api3( + 'CaseType', + 'create', + $params + ); + + return array_shift($result['values']); + } + +} diff --git a/CRM/Civicase/XMLProcessor/Report.php b/CRM/Civicase/XMLProcessor/Report.php index 040ac2961..bdfbf3aae 100644 --- a/CRM/Civicase/XMLProcessor/Report.php +++ b/CRM/Civicase/XMLProcessor/Report.php @@ -3,25 +3,21 @@ use CRM_Civicase_Helper_CaseCategory as CaseCategoryHelper; /** - * Class CRM_Civicase_XMLProcessor_Report. + * XMLProcessor report class. */ class CRM_Civicase_XMLProcessor_Report extends CRM_Case_XMLProcessor_Report { /** - * Get Activities which match the sent filters. + * The selected activities. * - * @param int $clientID - * Client ID. - * @param int $caseID - * Case Id. - * @param array $activityTypes - * Activity Types. - * @param array $activities - * Activities. - * @param array $selectedActivities - * Selected activities. + * @var array */ - public function getActivities($clientID, $caseID, array $activityTypes, array &$activities, array $selectedActivities = NULL) { + public $selectedActivities; + + /** + * {@inheritDoc} + */ + public function getActivities($clientID, $caseID, $activityTypes, &$activities) { // Get all activities for this case that in this activityTypes set. foreach ($activityTypes as $aType) { $activityTypesMap[$aType['id']] = $aType; @@ -52,7 +48,7 @@ public function getActivities($clientID, $caseID, array $activityTypes, array &$ $dao = CRM_Core_DAO::executeQuery($query, $params); while ($dao->fetch()) { $activityTypeInfo = $activityTypesMap[$dao->activity_type_id]; - if (count($selectedActivities) === 0 || in_array($dao->id, $selectedActivities)) { + if (count($this->selectedActivities) === 0 || in_array($dao->id, $this->selectedActivities)) { $activities[] = $this->getActivity($clientID, $dao, $activityTypeInfo @@ -62,25 +58,9 @@ public function getActivities($clientID, $caseID, array $activityTypes, array &$ } /** - * Get the Case Report for the sent filter. - * - * @param int $clientID - * Client ID. - * @param int $caseID - * Case Id. - * @param string $activitySetName - * The activity set name. - * @param array $params - * Parameters. - * @param CRM_Civicase_XMLProcessor_Report $report - * CRM_Civicase_XMLProcessor_Report object. - * @param array $selectedActivities - * Selected activities. - * - * @return mixed - * Report contents. + * {@inheritDoc} */ - public static function getCaseReport($clientID, $caseID, $activitySetName, array $params, CRM_Civicase_XMLProcessor_Report $report, array $selectedActivities = NULL) { + public static function getCaseReport($clientID, $caseID, $activitySetName, $params, $report) { $template = CRM_Core_Smarty::singleton(); @@ -136,7 +116,8 @@ public static function getCaseReport($clientID, $caseID, $activitySetName, array // Now collect all the information about activities. $activities = []; - $report->getActivities($clientID, $caseID, $activityTypes, $activities, $selectedActivities); + + $report->getActivities($clientID, $caseID, $activityTypes, $activities); $template->assign_by_ref('activities', $activities); // Now run the template. $contents = $template->fetch('CRM/Case/XMLProcessor/Report.tpl'); @@ -417,6 +398,7 @@ public static function printCaseReport() { } } } + $report->selectedActivities = $selectedActivities; $template->assign('caseRelationships', $caseRelationships); $template->assign('caseRoles', $caseRoles); $template->assign('otherRelationships', $otherRelationships); @@ -427,8 +409,7 @@ public static function printCaseReport() { $caseID, $activitySetName, $params, - $report, - $selectedActivities + $report ); $caseCategoryName = CRM_Civicase_Helper_CaseCategory::getCategoryName($caseID); @@ -464,7 +445,8 @@ private static function getCaseCustomValues($caseId) { foreach ($caseCustomGroup['fields'] as $customField) { if (isset($customField['value']['id'])) { $displayField = $customField['value']['display']; - if ($customField['data_type'] === 'Money' && in_array($customField['html_type'], ['Radio', 'Select'])) { + if ($customField['data_type'] === 'Money' + && in_array($customField['html_type'], ['Radio', 'Select'])) { $displayField = $customField['value']['data']; } if ($customField['data_type'] === 'File') { diff --git a/ang/civicase/activity/activity-forms/services/activity-form-services/add-custom-path-activity-form.service.js b/ang/civicase/activity/activity-forms/services/activity-form-services/add-custom-path-activity-form.service.js index 9f0eb51f5..a96f3042c 100644 --- a/ang/civicase/activity/activity-forms/services/activity-form-services/add-custom-path-activity-form.service.js +++ b/ang/civicase/activity/activity-forms/services/activity-form-services/add-custom-path-activity-form.service.js @@ -10,7 +10,7 @@ */ function AddCustomPathActivityForm (civicaseCrmUrl) { var ACTIVITY_TYPES_CUSTOM_PATHS = { - Email: 'civicrm/activity/email/add', + Email: 'civicrm/case/email/add', 'Print PDF Letter': 'civicrm/activity/pdf/add' }; diff --git a/ang/civicase/activity/activity-forms/services/activity-form-services/draft-email-activity-form.service.js b/ang/civicase/activity/activity-forms/services/activity-form-services/draft-email-activity-form.service.js index 33ea1933c..f218c9e9b 100644 --- a/ang/civicase/activity/activity-forms/services/activity-form-services/draft-email-activity-form.service.js +++ b/ang/civicase/activity/activity-forms/services/activity-form-services/draft-email-activity-form.service.js @@ -45,8 +45,12 @@ draftFormParameters.caseid = activity.case_id; } + var viewUrl = 'civicrm/activity/email/'; + var addUrl = 'civicrm/case/email/'; + var url = action === 'view' ? viewUrl : addUrl; + return civicaseCrmUrl( - 'civicrm/activity/email/' + action, + url + action, draftFormParameters ); } diff --git a/ang/civicase/case/actions/services/email-case-action.service.js b/ang/civicase/case/actions/services/email-case-action.service.js index 9723d1268..cda9a7cc4 100644 --- a/ang/civicase/case/actions/services/email-case-action.service.js +++ b/ang/civicase/case/actions/services/email-case-action.service.js @@ -198,7 +198,7 @@ } var popupPath = { - path: 'civicrm/activity/email/add', + path: 'civicrm/case/email/add', query: { action: 'add', hideDraftButton: 1, diff --git a/ang/civicase/case/details/directives/case-details.directive.js b/ang/civicase/case/details/directives/case-details.directive.js index 66c207052..e51b13db3 100644 --- a/ang/civicase/case/details/directives/case-details.directive.js +++ b/ang/civicase/case/details/directives/case-details.directive.js @@ -147,7 +147,7 @@ }).join(',') }; - civicaseCrmLoadForm(civicaseCrmUrl('civicrm/activity/email/add', createEmailURLParams)) + civicaseCrmLoadForm(civicaseCrmUrl('civicrm/case/email/add', createEmailURLParams)) .on('crmFormSuccess', function () { $rootScope.$broadcast('civicase::activity::updated'); }); diff --git a/ang/civicase/case/details/people-tab/directives/case-roles-tab.directive.html b/ang/civicase/case/details/people-tab/directives/case-roles-tab.directive.html index 6f2a8c034..3b1a02ea5 100644 --- a/ang/civicase/case/details/people-tab/directives/case-roles-tab.directive.html +++ b/ang/civicase/case/details/people-tab/directives/case-roles-tab.directive.html @@ -175,7 +175,7 @@

{{ ts('%1 Contacts', {1: roles.getCountOfAssignedRoles()}) }}

{{ role.email }} @@ -214,7 +214,7 @@

{{ ts('%1 Contacts', {1: roles.getCountOfAssignedRoles()}) }}

  • - {{ ts('Send Email') }} + {{ ts('Send Email') }}
  • {{ ts('Print/Merge Document') }} diff --git a/ang/civicase/case/details/people-tab/directives/other-relationships-tab.directive.html b/ang/civicase/case/details/people-tab/directives/other-relationships-tab.directive.html index 77aea26ec..b7875ad83 100644 --- a/ang/civicase/case/details/people-tab/directives/other-relationships-tab.directive.html +++ b/ang/civicase/case/details/people-tab/directives/other-relationships-tab.directive.html @@ -122,7 +122,7 @@

    {{ ts('%1 Contacts', {1: relationsPageObj.total}) }}

    + ng-href="{{ 'civicrm/case/email/add' | civicaseCrmUrl:{ action: 'add', caseid: item.id, reset: 1, cid: contact.contact_id } }}"> {{ contact.email }} @@ -152,7 +152,7 @@

    {{ ts('%1 Contacts', {1: relationsPageObj.total}) }}

  • + ng-href="{{ 'civicrm/case/email/add' | civicaseCrmUrl:{ action: 'add', caseid: item.id, reset: 1, cid: contact.id } }}"> {{ ts('Send Email') }}
  • diff --git a/ang/civicase/contact/directives/contact-popover-content.directive.js b/ang/civicase/contact/directives/contact-popover-content.directive.js index 0c07bf200..ff311eb48 100644 --- a/ang/civicase/contact/directives/contact-popover-content.directive.js +++ b/ang/civicase/contact/directives/contact-popover-content.directive.js @@ -40,7 +40,7 @@ emailUrlParameters.caseid = $scope.caseId; } - return civicaseCrmUrl('civicrm/activity/email/add', emailUrlParameters); + return civicaseCrmUrl('civicrm/case/email/add', emailUrlParameters); } } })(angular); diff --git a/ang/test/civicase/activity/activity-forms/services/activity-forms-services/add-custom-path-activity-form.service.spec.js b/ang/test/civicase/activity/activity-forms/services/activity-forms-services/add-custom-path-activity-form.service.spec.js index 289df86f7..7394f9cc8 100644 --- a/ang/test/civicase/activity/activity-forms/services/activity-forms-services/add-custom-path-activity-form.service.spec.js +++ b/ang/test/civicase/activity/activity-forms/services/activity-forms-services/add-custom-path-activity-form.service.spec.js @@ -94,7 +94,7 @@ }); it('returns the form url to create a new activity', () => { - expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/activity/email/add', { + expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/case/email/add', { action: 'add', reset: 1, caseid: activity.case_id, diff --git a/ang/test/civicase/activity/activity-forms/services/activity-forms-services/draft-email-activity-form.service.spec.js b/ang/test/civicase/activity/activity-forms/services/activity-forms-services/draft-email-activity-form.service.spec.js index bfb69c294..3105bd545 100644 --- a/ang/test/civicase/activity/activity-forms/services/activity-forms-services/draft-email-activity-form.service.spec.js +++ b/ang/test/civicase/activity/activity-forms/services/activity-forms-services/draft-email-activity-form.service.spec.js @@ -67,7 +67,7 @@ }); it('returns the popup form URL for the draft activity in create mode by default', () => { - expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/activity/email/add', + expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/case/email/add', expectedActivityFormUrlParams); }); }); @@ -83,7 +83,7 @@ }); it('returns the popup form URL for the draft activity in create mode by default', () => { - expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/activity/email/add', + expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/case/email/add', expectedActivityFormUrlParams); }); }); diff --git a/ang/test/civicase/case/actions/services/email-case-action.service.spec.js b/ang/test/civicase/case/actions/services/email-case-action.service.spec.js index df1cdc980..1112132c5 100644 --- a/ang/test/civicase/case/actions/services/email-case-action.service.spec.js +++ b/ang/test/civicase/case/actions/services/email-case-action.service.spec.js @@ -96,7 +96,7 @@ it('returns the path to open the send email popup and hides the draft button', () => { expect(returnValue).toEqual({ - path: 'civicrm/activity/email/add', + path: 'civicrm/case/email/add', query: { action: 'add', reset: 1, @@ -167,7 +167,7 @@ it('adds bulk email activitiy to all the selected cases', () => { expect(returnValue).toEqual({ - path: 'civicrm/activity/email/add', + path: 'civicrm/case/email/add', query: { action: 'add', reset: 1, diff --git a/ang/test/civicase/case/details/directives/case-details.directive.spec.js b/ang/test/civicase/case/details/directives/case-details.directive.spec.js index 4d723244a..a09311bcf 100644 --- a/ang/test/civicase/case/details/directives/case-details.directive.spec.js +++ b/ang/test/civicase/case/details/directives/case-details.directive.spec.js @@ -629,7 +629,7 @@ }); it('open a popup to create emails', function () { - expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/activity/email/add', { + expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/case/email/add', { action: 'add', caseid: $scope.item.id, atype: '3', diff --git a/ang/test/civicase/contact/directives/contact-popover-content.directive.spec.js b/ang/test/civicase/contact/directives/contact-popover-content.directive.spec.js index 9d8fd31b1..68eb63e49 100644 --- a/ang/test/civicase/contact/directives/contact-popover-content.directive.spec.js +++ b/ang/test/civicase/contact/directives/contact-popover-content.directive.spec.js @@ -44,7 +44,7 @@ }); it('returns the URL for sending a standalone email activity', () => { - expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/activity/email/add', { + expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/case/email/add', { action: 'add', cid: $scope.contactId, reset: 1 @@ -63,7 +63,7 @@ }); it('returns the URL for sending a case email activity', () => { - expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/activity/email/add', { + expect(civicaseCrmUrl).toHaveBeenCalledWith('civicrm/case/email/add', { action: 'add', caseid: $scope.caseId, cid: $scope.contactId, diff --git a/api/v3/Activity/Getdayswithactivities.php b/api/v3/Activity/Getdayswithactivities.php index a1bd173c5..ac2565b60 100644 --- a/api/v3/Activity/Getdayswithactivities.php +++ b/api/v3/Activity/Getdayswithactivities.php @@ -143,7 +143,7 @@ function _join_to_case(CRM_Utils_SQL_Select $query, $value) { function _get_case_ids(array $caseParams) { $results = civicrm_api3('Case', 'getcaselist', array_merge([ 'return' => 'id', - 'options' => [limit => 0], + 'options' => ['limit' => 0], ], $caseParams))['values']; return array_column($results, 'id'); diff --git a/api/v3/Activity/Getmonthswithactivities.php b/api/v3/Activity/Getmonthswithactivities.php index d54f472a8..c01d4ac13 100644 --- a/api/v3/Activity/Getmonthswithactivities.php +++ b/api/v3/Activity/Getmonthswithactivities.php @@ -55,7 +55,7 @@ function civicrm_api3_activity_Getmonthswithactivities(array $params) { $grouped_activity_dates = []; foreach ($activities as $activity) { - list($activity_year, $activity_month) = explode('-', $activity['activity_date_time']); + [$activity_year, $activity_month] = explode('-', $activity['activity_date_time']); $activity_group_index = -1; foreach ($grouped_activity_dates as $key => $val) { @@ -119,7 +119,7 @@ function get_records_from_activity_get_api(array $params) { $sort = explode(', ', $options['sort']); foreach ($sort as $index => &$sortString) { - list($sortField, $dir) = array_pad(explode(' ', $sortString), 2, 'ASC'); + [$sortField, $dir] = array_pad(explode(' ', $sortString), 2, 'ASC'); if ($sortField == 'is_overdue') { $incomplete = implode(',', array_keys(CRM_Activity_BAO_Activity::getStatusesByType(CRM_Activity_BAO_Activity::INCOMPLETE))); $sql->orderBy("IF((a.activity_date_time >= NOW() OR a.status_id NOT IN ($incomplete)), 0, 1) $dir", NULL, $index); @@ -134,5 +134,5 @@ function get_records_from_activity_get_api(array $params) { $params['return'] = array_keys($options['return']); } - return _civicrm_api3_basic_get(CRM_Activity_BAO_Activity, $params, FALSE, 'Activity', $sql); + return _civicrm_api3_basic_get('CRM_Activity_BAO_Activity', $params, FALSE, 'Activity', $sql); } diff --git a/api/v3/Case/Getdetails.php b/api/v3/Case/Getdetails.php index 7622de2c2..6bcd2739e 100644 --- a/api/v3/Case/Getdetails.php +++ b/api/v3/Case/Getdetails.php @@ -70,16 +70,16 @@ function _civicrm_api3_case_getdetails_spec(array &$spec) { * @throws API_Exception */ function civicrm_api3_case_getdetails(array $params) { - list( + [ 'resultMetadata' => $resultMetadata, 'params' => $params, 'toReturn' => $toReturn, - 'sql' => $sql - ) = CaseDetailsQuery::get($params); + 'sql' => $sql, + ] = CaseDetailsQuery::get($params); // Call the case api. $result = civicrm_api3_case_get(['sequential' => 0] + $params, $sql); - if (!empty($result['values'])) { + if (!empty($result['values']) && is_array($result['values'])) { $ids = array_keys($result['values']); // Remove legacy cruft. diff --git a/civicase.php b/civicase.php index 922e66310..196181472 100644 --- a/civicase.php +++ b/civicase.php @@ -74,6 +74,11 @@ function civicase_civicrm_config(&$config) { ['CRM_Civicase_Event_Listener_CaseCustomFields', 'loadOnDemand'], 10 ); + + Civi::dispatcher()->addListener( + 'hook_civicrm_buildAsset', + ['CRM_Civicase_Event_Listener_AssetBuilder', 'addWordReplacements'] + ); } /** @@ -185,6 +190,7 @@ function civicase_civicrm_alterMenu(&$items) { $items['civicrm/case/activity']['ids_arguments']['json'][] = 'civicase_reload'; $items['civicrm/activity']['ids_arguments']['json'][] = 'civicase_reload'; $items['civicrm/activity/email/add']['ids_arguments']['json'][] = 'civicase_reload'; + $items['civicrm/case/email/add']['ids_arguments']['json'][] = 'civicase_reload'; $items['civicrm/activity/pdf/add']['ids_arguments']['json'][] = 'civicase_reload'; $items['civicrm/case/cd/edit']['ids_arguments']['json'][] = 'civicase_reload'; $items['civicrm/export/standalone']['ids_arguments']['json'][] = 'civicase_reload'; @@ -214,7 +220,6 @@ function civicase_civicrm_buildForm($formName, &$form) { new CRM_Civicase_Hook_BuildForm_ModifyCaseTypesForAdvancedSearch(), new CRM_Civicase_Hook_BuildForm_AddCaseCategoryInstanceField(), new CRM_Civicase_Hook_BuildForm_AddStyleFieldToCaseCustomGroups(), - new CRM_Civicase_Hook_BuildForm_DisplayAllCustomGroupsInCaseForm(), new CRM_Civicase_Hook_BuildForm_RemoveExportActionFromReports(), new CRM_Civicase_Hook_BuildForm_RestrictCaseEmailContacts(), new CRM_Civicase_Hook_BuildForm_LimitRecipientFieldsToOnlySelectedContacts(), diff --git a/info.xml b/info.xml index 3b1012ecc..735ad0fce 100644 --- a/info.xml +++ b/info.xml @@ -18,7 +18,7 @@ 2.9.2 stable - 5.39 + 5.51 Supported CiviCRM versions : diff --git a/tests/phpunit/BaseHeadlessTest.php b/tests/phpunit/BaseHeadlessTest.php index ff660162d..2eda63621 100644 --- a/tests/phpunit/BaseHeadlessTest.php +++ b/tests/phpunit/BaseHeadlessTest.php @@ -1,13 +1,58 @@ installMe(__DIR__) ->apply(); } -} \ No newline at end of file + + /** + * {@inheritDoc} + */ + public function getMockBuilder($className) { + $mockBuilder = (new class($this, $className) extends PHPUnit_Framework_MockObject_MockBuilder { + + /** + * {@inheritDoc} + */ + public function getMock() { + static::setSupressedErrorHandler(); + + try { + return parent::getMock(); + } finally { + restore_error_handler(); + } + } + + /** + * Supress depreciation warnings. + */ + public static function setSupressedErrorHandler() { + $previousHandler = set_error_handler(function ($code, $description, $file = NULL, $line = NULL, $context = NULL) use (&$previousHandler) { + if ($code & E_DEPRECATED) { + return TRUE; + } + + return $previousHandler($code, $description, $file, $line, $context); + }); + } + + }); + + return $mockBuilder; + } + +} diff --git a/tests/phpunit/CRM/Civicase/Hook/BuildForm/TokenTreeTest.php b/tests/phpunit/CRM/Civicase/Hook/BuildForm/TokenTreeTest.php index c6c91249b..5f25d68c3 100644 --- a/tests/phpunit/CRM/Civicase/Hook/BuildForm/TokenTreeTest.php +++ b/tests/phpunit/CRM/Civicase/Hook/BuildForm/TokenTreeTest.php @@ -29,11 +29,11 @@ class CRM_Civicase_Hook_BuildForm_TokenTreeTest extends BaseHeadlessTest { public function testRun() { $this->setContactCustomFields(); $this->setCaseCustomFields(); - $form = new CRM_Contact_Form_Task_Email(); + $form = new CRM_Case_Form_Task_Email(); $form->assign('tokens', $this->getTokens()); $_GET['caseid'] = $_REQUEST['caseid'] = 1; $hook = new TokenTree(); - $hook->run($form, CRM_Contact_Form_Task_Email::class); + $hook->run($form, CRM_Case_Form_Task_Email::class); $setting = CRM_Core_Resources::singleton()->getSettings(); $this->assertNotEmpty($setting['civicase-base']['custom_token_tree']); $newTokenTree = $this->format(json_decode($setting['civicase-base']['custom_token_tree'], TRUE)); diff --git a/tests/phpunit/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCasesTest.php b/tests/phpunit/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCasesTest.php index 413d2fff2..6d91ebc59 100644 --- a/tests/phpunit/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCasesTest.php +++ b/tests/phpunit/CRM/Civicase/Hook/PostProcess/AttachEmailActivityToAllCasesTest.php @@ -25,8 +25,8 @@ public function testHookAddActivitiesToAllSelectedCases() { $_GET['allCaseIds'] = $_REQUEST['allCaseIds'] = $allCaseIds; (new AttachEmailActivityToAllCases())->run( - CRM_Contact_Form_Task_Email::class, - new CRM_Contact_Form_Task_Email() + CRM_Case_Form_Task_Email::class, + new CRM_Case_Form_Task_Email() ); foreach ($cases as $caseId) { diff --git a/tests/phpunit/CRM/Civicase/Hook/ValidateForm/SendBulkEmailTest.php b/tests/phpunit/CRM/Civicase/Hook/ValidateForm/SendBulkEmailTest.php index 60e270c49..e5b571f9c 100644 --- a/tests/phpunit/CRM/Civicase/Hook/ValidateForm/SendBulkEmailTest.php +++ b/tests/phpunit/CRM/Civicase/Hook/ValidateForm/SendBulkEmailTest.php @@ -1,5 +1,6 @@ registerCurrentLoggedInContactInSession($loggedInUser['id']); + $this->loggedInUser = CRM_Civicase_Test_Fabricator_Contact::fabricateWithEmail(); + $this->registerCurrentLoggedInContactInSession($this->loggedInUser['id']); $this->caseType = CRM_Civicase_Test_Fabricator_CaseType::fabricate()['id']; } @@ -71,7 +80,7 @@ public function testHookCreateEmailForCases() { ); $this->assertEquals(0, count($emailsSent)); - $this->form = new CRM_Contact_Form_Task_Email(); + $this->form = new CRM_Case_Form_Task_Email(); $this->runHook( 'Test {case.id} for contact {contact.contact_id}', 'Body for {contact.first_name} {case.id}', @@ -139,7 +148,7 @@ public function testHookDoNotSendEmailToExcludedContact() { ); $this->assertEquals(0, count($emailsSent)); - $this->form = new CRM_Contact_Form_Task_Email(); + $this->form = new CRM_Case_Form_Task_Email(); $this->runHook( 'Test {case.id} for contact {contact.contact_id}', 'Body for {contact.first_name} {case.id}', @@ -174,7 +183,7 @@ public function testHookRunsWhenEmailFormIsUsed() { $_REQUEST['caseRoles'] = $_GET['caseRoles'] = 'client'; - $this->form = new CRM_Contact_Form_Task_Email(); + $this->form = new CRM_Case_Form_Task_Email(); $result = $this->runHook( '', '', @@ -211,7 +220,7 @@ public function testHookDoesNotRunWhenOtherFormIsUsed() { public function testHookDoesNotRunWhenNoCasesAreSelected() { $_REQUEST['caseRoles'] = $_GET['caseRoles'] = ''; - $this->form = new CRM_Contact_Form_Task_Email(); + $this->form = new CRM_Case_Form_Task_Email(); $result = $this->runHook('', '', [], []); $this->assertFalse($result); @@ -299,9 +308,20 @@ private function createCaseForContact(int $contactId) { * Return the result of calling the hook. */ private function runHook(string $subject, string $body, array $cases, array $contacts) { + $formName = $this->form->getName(); + $senderEmail = $this->callAPISuccess('Email', 'getsingle', ['contact_id' => $this->loggedInUser['id']]); + + $formValues = [ + 'to' => [], + 'cc_id' => [], + 'bcc_id' => [], + 'subject' => $subject, + 'text_message' => $body, + 'html_message' => $body, + 'from_email_address' => $senderEmail['id'], + ]; $_REQUEST['allCaseIds'] = $_GET['allCaseIds'] = implode(',', $cases); - $formName = 'Test Form'; $fields = $files = $errors = []; $this->form->_contactIds = []; @@ -315,15 +335,34 @@ private function runHook(string $subject, string $body, array $cases, array $con 'contact_id' => $contact['id'], 'preferred_mail_format' => 'HTML', ]; + $formValues['to'][$contact['id']] = $contact['id'] . '::' . $contact['email']; } + $formValues['to'] = implode(',', $formValues['to']); + + $this->setFormSubmitValues($formName, $formValues); + return (new SendBulkEmailHook())->run($formName, $fields, $files, $this->form, $errors); + } + + /** + * Sets the form submission values in Session and element. + * + * @param string $formName + * The form name. + * @param array $formValues + * The values of the form fields. + */ + private function setFormSubmitValues(string $formName, array $formValues) { + $this->form->controller = new CRM_Core_Controller_Simple(get_class($this->form), $formName); + $_SESSION['_' . $this->form->controller->_name . '_container']['values'][$formName] = $formValues; + $_SESSION['_' . $this->form->controller->_name . '_container']['values']['Search'] = []; $this->form->addElement('hidden', 'cc_id', []); $this->form->addElement('hidden', 'bcc_id', []); - $this->form->addElement('hidden', 'subject', $subject); - $this->form->addElement('hidden', 'text_message', $body); - $this->form->addElement('hidden', 'html_message', $body); - - return (new SendBulkEmailHook())->run($formName, $fields, $files, $this->form, $errors); + $this->form->addElement('hidden', 'to', $formValues['to']); + $this->form->addElement('hidden', 'subject', $formValues['subject']); + $this->form->addElement('hidden', 'text_message', $formValues['text_message']); + $this->form->addElement('hidden', 'html_message', $formValues['html_message']); + $this->form->addElement('hidden', 'from_email_address', $formValues['from_email_address']); } /** diff --git a/tests/phpunit/Helpers/MailHelpersTrait.php b/tests/phpunit/Helpers/MailHelpersTrait.php index 2f82f6aca..9ae42ad8a 100644 --- a/tests/phpunit/Helpers/MailHelpersTrait.php +++ b/tests/phpunit/Helpers/MailHelpersTrait.php @@ -40,7 +40,11 @@ public function getNotificationsByEmail(array $emails) { $headerValues = []; foreach ($allHeaders as $headerLine) { $tmp = explode(': ', $headerLine); - $headerValues[$tmp[0]] = $tmp[1]; + // Not all headers are separated by `: ` some headers + // are separated by by `=` + // e.g. boundary="=_450418403cfd293a551c46b24aeb05c6" + // we simply ignore such header value. + $headerValues[$tmp[0]] = $tmp[1] ?? ''; } $emails[$result->recipient_email][] = array_merge(