Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New feature #18282: Possibility to resend failed admin notification e…
…mails(#2539) * dev: created new table for failed email notification and created new … * dev: added column surveyid to new table failed_email * dev: changed columns table failed_email * LSC-267: added controller/view/model for failed email notifications * dev: LSC273 self cleaning after 30 days * Dev: true equal for string comparison * LSC-267: added grid and some controller/db adjustments for failedEmail * Save failed emails to database also fixing database table columns * LSC-267: added/fixed some fields and added basic resend action and modal * subject col now called email_type in create-database.php * Notifications for failed e-mails * Success state as constant * LSC-267: added controller actions/massive action modals/buttons for f… * Only one notification, and only for survey owners * Changed notification message text * If a survey is deleted, the failed email notifications belonging to t… * LSC-267: added buttons and javascript generating modals * LSC-267: added return messages for modals / added ajax reload for jav… * Dev: PSR-12 fixes * Dev: Add missing return types * Dev: Add missing return types * Dev: Fix link casing * LSC-267: capitalized controller name in url * LSC-267: added check for LimeMailer instance * LSC-267: added docs to saveFailedEmail and removed redundant return * LSC-267: updated doc blocks and fixed some conditions / added excepti… * PSR-12 fix * LSC-267: updated view test for FailedEmail * LSC-267: updated view test for FailedEmail * LSC-267: updated permissions for button group and dynamic modalcontent * LSC-267: updated view test for FailedEmail * LSC-267: psr-12 * Merge branch 'master' into task/LSC-267_failed_notification_emails * LSC-267: fixed for url type for get/path * LSC-267: fixed some typos * LSC-267: fixed missing surveyid to display correct data in the table * LSC-267: functional tests for FailedEmail * LSC-267: fixed wrong return values causing errors in ajax calls * LSC-267: WIP testing error on CI * LSC-267: WIP testing error on CI * LSC-267: WIP testing error on CI * LSC-267: WIP testing error on CI * LSC-267: fixed missing function param for saveFailedEmail() / added c… * Fixed issue: thissurvey is null; addCondition second argument is not … * Turn on debug 2 in CI * Fix yaml * Fix line in sed call * Fix sed * LSC-267: added breadcrumb * LSC-267: fixed id/language/recipient not being set right / header all… * LSC-267: added additional checks to wait for modal being closed * LSC-267: adjust waiting time for tests * LSC-267: adjust waiting time for tests * Remove debug 2 * Run entire test suite * LSC-267: added comment for clarification * LSC-267: removed todo * Merge branch 'master' into task/LSC-267_failed_notification_emails * Apply composer no dev * LSC-267: reverted wrong yaml setting to master default
- Loading branch information
Showing
40 changed files
with
2,448 additions
and
598 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
<?php | ||
|
||
class FailedEmailController extends LSBaseController | ||
{ | ||
/** | ||
* this is part of renderWrappedTemplate implement in old responses.php | ||
* | ||
* @param string $view | ||
* @return bool | ||
*/ | ||
public function beforeRender($view) | ||
{ | ||
$surveyId = (int)App()->request->getParam('surveyid'); | ||
$this->aData['surveyid'] = $surveyId; | ||
LimeExpressionManager::SetSurveyId($this->aData['surveyid']); | ||
$this->layout = 'layout_questioneditor'; | ||
$this->aData['title_bar']['title'] = gT('Failed e-mail notifications'); | ||
$this->aData['subaction'] = gT("Failed e-mail notifications"); | ||
|
||
return parent::beforeRender($view); | ||
} | ||
|
||
/** | ||
* @throws CHttpException|CException | ||
*/ | ||
public function actionIndex(): void | ||
{ | ||
$surveyId = sanitize_int(App()->request->getParam('surveyid')); | ||
$permissions = [ | ||
'update' => Permission::model()->hasSurveyPermission($surveyId, 'responses', 'update'), | ||
'delete' => Permission::model()->hasSurveyPermission($surveyId, 'responses', 'delete'), | ||
'read' => Permission::model()->hasSurveyPermission($surveyId, 'responses', 'read') | ||
]; | ||
if (!$surveyId) { | ||
throw new CHttpException(403, gT("Invalid survey ID")); | ||
} | ||
if (!$permissions['read']) { | ||
App()->user->setFlash('error', gT("You do not have permission to access this page.")); | ||
$this->redirect(['surveyAdministration/view', 'surveyid' => $surveyId]); | ||
} | ||
|
||
App()->getClientScript()->registerScriptFile('/application/views/failedEmail/javascript/failedEmail.js', LSYii_ClientScript::POS_BEGIN); | ||
$failedEmailModel = FailedEmail::model(); | ||
$failedEmailModel->setAttributes(App()->getRequest()->getParam('FailedEmail'), false); | ||
$failedEmailModel->setAttribute('surveyid', $surveyId); | ||
$pageSize = App()->request->getParam('pageSize') ?? App()->user->getState('pageSize', App()->params['defaultPageSize']); | ||
$massiveAction = App()->getController()->renderPartial('/failedEmail/partials/massive_action_selector', [ | ||
'surveyId' => $surveyId, | ||
'permissions' => $permissions | ||
], true); | ||
|
||
|
||
$this->render('failedEmail_index', [ | ||
'failedEmailModel' => $failedEmailModel, | ||
'pageSize' => $pageSize, | ||
'massiveAction' => $massiveAction, | ||
]); | ||
} | ||
|
||
/** | ||
* @throws CHttpException|CException | ||
* @return string|void | ||
*/ | ||
public function actionResend() | ||
{ | ||
$surveyId = (int)sanitize_int(App()->request->getParam('surveyid')); | ||
if (!$surveyId) { | ||
throw new CHttpException(403, gT("Invalid survey ID")); | ||
} | ||
if (!Permission::model()->hasSurveyPermission($surveyId, 'responses', 'update')) { | ||
App()->user->setFlash('error', gT("You do not have permission to access this page.")); | ||
$this->redirect(['failedEmail/index/', 'surveyid' => $surveyId]); | ||
} | ||
$preserveResend = App()->request->getParam('preserveResend') ?? false; | ||
$item = [App()->request->getParam('item')]; | ||
$items = json_decode(App()->request->getParam('sItems')); | ||
$selectedItems = $items ?? $item; | ||
$emailsByType = []; | ||
if (!empty($selectedItems)) { | ||
$criteria = new CDbCriteria(); | ||
$criteria->select = 'id, email_type, recipient'; | ||
$criteria->addCondition('surveyid = ' . (int) $surveyId); | ||
$criteria->addInCondition('id', $selectedItems); | ||
$failedEmails = FailedEmail::model()->findAll($criteria); | ||
if (!empty($failedEmails)) { | ||
foreach ($failedEmails as $failedEmail) { | ||
$emailsByType[$failedEmail->email_type][] = [ | ||
'id' => $failedEmail->id, | ||
'recipient' => $failedEmail->recipient, | ||
'language' => $failedEmail->language, | ||
]; | ||
} | ||
global $thissurvey; | ||
$thissurvey = getSurveyInfo($surveyId); | ||
$result = sendSubmitNotifications($surveyId, $emailsByType, $preserveResend, true); | ||
if (!$preserveResend) { | ||
// only delete FailedEmail entries that have succeeded | ||
$criteria->addCondition('status = :status'); | ||
$criteria->params['status'] = FailedEmail::STATE_SUCCESS; | ||
FailedEmail::model()->deleteAll($criteria); | ||
} | ||
// massive action | ||
if ($items) { | ||
return $this->renderPartial('partials/modal/resend_result_body', [ | ||
'successfullEmailCount' => $result['successfullEmailCount'], | ||
'failedEmailCount' => $result['failedEmailCount'] | ||
]); | ||
} | ||
// single action | ||
return $this->renderPartial('/admin/super/_renderJson', [ | ||
"data" => [ | ||
'success' => true, | ||
'html' => $this->renderPartial('partials/modal/resend_result', [ | ||
'successfullEmailCount' => $result['successfullEmailCount'], | ||
'failedEmailCount' => $result['failedEmailCount'] | ||
], true) | ||
] | ||
]); | ||
} | ||
return $this->renderPartial('/admin/super/_renderJson', [ | ||
"data" => [ | ||
'success' => false, | ||
'message' => gT('No match could be found for selection'), | ||
] | ||
]); | ||
} | ||
return $this->renderPartial('/admin/super/_renderJson', [ | ||
"data" => [ | ||
'success' => false, | ||
'message' => gT('Please select at least one item'), | ||
] | ||
]); | ||
} | ||
|
||
/** | ||
* @throws CHttpException|CException | ||
* @return string|void | ||
*/ | ||
public function actionDelete() | ||
{ | ||
$surveyId = sanitize_int(App()->request->getParam('surveyid')); | ||
if (!$surveyId) { | ||
throw new CHttpException(403, gT("Invalid survey ID")); | ||
} | ||
if (!Permission::model()->hasSurveyPermission($surveyId, 'responses', 'delete')) { | ||
App()->user->setFlash('error', gT("You do not have permission to access this page.")); | ||
$this->redirect(['failedEmail/index/', 'surveyid' => $surveyId]); | ||
} | ||
$item = [App()->request->getParam('item')]; | ||
$items = json_decode(App()->request->getParam('sItems')); | ||
$selectedItems = $items ?? $item; | ||
if (!empty($selectedItems)) { | ||
$criteria = new CDbCriteria(); | ||
$criteria->select = 'id, email_type, recipient'; | ||
$criteria->addCondition('surveyid =' . (int) $surveyId); | ||
$criteria->addInCondition('id', $selectedItems); | ||
$failedEmails = new FailedEmail(); | ||
$deletedCount = $failedEmails->deleteAll($criteria); | ||
if ($items) { | ||
return $this->renderPartial('partials/modal/delete_result_body', [ | ||
'deletedCount' => $deletedCount, | ||
]); | ||
} | ||
return $this->renderPartial('/admin/super/_renderJson', [ | ||
"data" => [ | ||
'success' => true, | ||
'html' => $this->renderPartial('partials/modal/delete_result', [ | ||
'deletedCount' => $deletedCount, | ||
], true), | ||
] | ||
]); | ||
} | ||
return $this->renderPartial('/admin/super/_renderJson', [ | ||
"data" => [ | ||
'success' => false, | ||
'message' => gT('Please select at least one item'), | ||
] | ||
]); | ||
} | ||
|
||
/** | ||
* @return void | ||
* @throws CException | ||
* @throws CHttpException | ||
*/ | ||
public function actionModalContent(): void | ||
{ | ||
$id = App()->request->getParam('id'); | ||
$failedEmailModel = new FailedEmail(); | ||
$failedEmail = $failedEmailModel->findByPk($id); | ||
if (!$failedEmail) { | ||
throw new CHttpException(403, gT("Invalid ID")); | ||
} | ||
$surveyId = $failedEmail->surveyid; | ||
$permissions = [ | ||
'update' => Permission::model()->hasSurveyPermission($surveyId, 'responses', 'update'), | ||
'delete' => Permission::model()->hasSurveyPermission($surveyId, 'responses', 'delete'), | ||
'read' => Permission::model()->hasSurveyPermission($surveyId, 'responses', 'read') | ||
]; | ||
$contentFile = App()->request->getParam('contentFile'); | ||
if ( | ||
!($permissions['update'] && $contentFile === 'resend_form') | ||
&& !($permissions['delete'] && $contentFile === 'delete_form') | ||
&& !($permissions['read'] && in_array($contentFile, ['email_content', 'email_error'])) | ||
) { | ||
throw new CHttpException(403, gT("You do not have permission to access this page.")); | ||
} | ||
App()->getController()->renderPartial( | ||
'/failedEmail/partials/modal/' . $contentFile, | ||
['id' => $id, 'surveyId' => $surveyId, 'failedEmail' => $failedEmail] | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.