3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
12 use Civi\Api4\MessageTemplate
;
13 use Civi\Token\TokenProcessor
;
18 * @copyright CiviCRM LLC https://civicrm.org/licensing
22 * This class generates form components for Message templates
23 * used by membership, contributions, event registrations, etc.
25 class CRM_Admin_Form_MessageTemplates
extends CRM_Core_Form
{
27 * which (and whether) mailing workflow this template belongs to
30 protected $_workflow_id = NULL;
33 * Is document file is already loaded as default value?
37 protected $_is_document = FALSE;
42 public $submitOnce = TRUE;
45 * PreProcess form - load existing values.
47 * @throws \API_Exception
48 * @throws \CRM_Core_Exception
49 * @throws \Civi\API\Exception\UnauthorizedException
51 public function preProcess() {
52 $this->_id
= CRM_Utils_Request
::retrieve('id', 'Positive', $this);
53 $this->_action
= CRM_Utils_Request
::retrieve('action', 'String', $this, FALSE, 'add');
54 $this->assign('action', $this->_action
);
57 $this->_values
= (array) MessageTemplate
::get()->addWhere('id', '=', $this->_id
)->setSelect(['*'])->execute()->first();
62 * Set default values for the form.
64 * The default values are retrieved from the database.
66 public function setDefaultValues() {
67 $defaults = $this->_values
;
69 if (empty($defaults['pdf_format_id'])) {
70 $defaults['pdf_format_id'] = 'null';
72 if (empty($defaults['file_type'])) {
73 $defaults['file_type'] = 0;
76 if ($this->_action
& CRM_Core_Action
::ADD
) {
77 $defaults['is_active'] = 1;
80 if ($this->_action
& CRM_Core_Action
::UPDATE
) {
81 $documentInfo = CRM_Core_BAO_File
::getEntityFile('civicrm_msg_template', $this->_id
, TRUE);
82 if (!empty($documentInfo)) {
83 $defaults['file_type'] = 1;
84 $this->_is_document
= TRUE;
85 $this->assign('attachment', $documentInfo);
93 * Build the form object.
95 public function buildQuickForm() {
96 // For VIEW we only want Done button
97 if ($this->_action
& CRM_Core_Action
::VIEW
) {
98 // currently, the above action is used solely for previewing default workflow templates
99 $cancelURL = CRM_Utils_System
::url('civicrm/admin/messageTemplates', 'selectedChild=workflow&reset=1');
100 $cancelURL = str_replace('&', '&', $cancelURL);
104 'name' => ts('Done'),
105 'js' => ['onclick' => "location.href='{$cancelURL}'; return false;"],
111 $this->_workflow_id
= $this->_values
['workflow_id'] ??
NULL;
112 $this->checkUserPermission($this->_workflow_id
);
113 $this->assign('isWorkflow', (bool) ($this->_values
['workflow_id'] ??
NULL));
115 if ($this->_workflow_id
) {
116 $selectedChild = 'workflow';
119 $selectedChild = 'user';
122 $cancelURL = CRM_Utils_System
::url('civicrm/admin/messageTemplates', "selectedChild={$selectedChild}&reset=1");
123 $cancelURL = str_replace('&', '&', $cancelURL);
126 'name' => $this->_action
& CRM_Core_Action
::DELETE ?
ts('Delete') : ts('Save'),
129 if (!($this->_action
& CRM_Core_Action
::DELETE
)) {
132 'name' => ts('Save and Done'),
138 'name' => ts('Cancel'),
139 'js' => ['onclick' => "location.href='{$cancelURL}'; return false;"],
141 $this->addButtons($buttons);
144 if ($this->_action
& CRM_Core_Action
::DELETE
) {
145 $this->assign('msg_title', $this->_values
['msg_title']);
151 'title' => ts('Message Templates'),
152 'url' => CRM_Utils_System
::url('civicrm/admin/messageTemplates', 'action=browse&reset=1'),
155 CRM_Utils_System
::appendBreadCrumb($breadCrumb);
157 $this->applyFilter('__ALL__', 'trim');
158 $this->add('text', 'msg_title', ts('Message Title'), CRM_Core_DAO
::getAttribute('CRM_Core_DAO_MessageTemplate', 'msg_title'), TRUE);
160 $options = [ts('Compose On-screen'), ts('Upload Document')];
161 $element = $this->addRadio('file_type', ts('Source'), $options);
166 $this->addElement('file', "file_id", ts('Upload Document'), 'size=30 maxlength=255');
167 $this->addUploadElement("file_id");
169 $this->add('text', 'msg_subject',
170 ts('Message Subject'),
171 CRM_Core_DAO
::getAttribute('CRM_Core_DAO_MessageTemplate', 'msg_subject')
174 $tokenProcessor = new TokenProcessor(Civi
::dispatcher(), ['schema' => ['contactId']]);
175 $tokens = $tokenProcessor->listTokens();
177 $this->assign('tokens', CRM_Utils_Token
::formatTokensForDisplay($tokens));
179 // if not a system message use a wysiwyg editor, CRM-5971
181 CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_MessageTemplate',
186 $this->add('textarea', 'msg_html', ts('HTML Message'),
187 ['cols' => 50, 'rows' => 6]
191 $this->add('wysiwyg', 'msg_html', ts('HTML Message'),
195 'onkeyup' => "return verify(this)",
196 'preset' => 'civimail',
201 $this->add('textarea', 'msg_text', ts('Text Message'),
202 ['cols' => 50, 'rows' => 6]
205 $this->add('select', 'pdf_format_id', ts('PDF Page Format'),
207 'null' => ts('- default -'),
208 ] + CRM_Core_BAO_PdfFormat
::getList(TRUE), FALSE
211 $this->add('checkbox', 'is_active', ts('Enabled?'));
212 $this->addFormRule([__CLASS__
, 'formRule'], $this);
214 if ($this->_action
& CRM_Core_Action
::VIEW
) {
216 $this->setTitle(ts('View System Default Message Template'));
221 * Restrict users access based on permission
223 * @param int $workflowId
225 private function checkUserPermission($workflowId) {
226 if (isset($workflowId)) {
227 $canView = CRM_Core_Permission
::check('edit system workflow message templates');
230 $canView = CRM_Core_Permission
::check('edit user-driven message templates');
233 if (!$canView && !CRM_Core_Permission
::check('edit message templates')) {
234 CRM_Core_Session
::setStatus(ts('You do not have permission to view requested page.'), ts('Access Denied'));
235 $url = CRM_Utils_System
::url('civicrm/admin/messageTemplates', "reset=1");
236 CRM_Utils_System
::redirect($url);
243 * @param array $params
244 * The input form values.
245 * @param array $files
246 * The uploaded files if any.
252 public static function formRule($params, $files, $self) {
253 // If user uploads non-document file other than odt/docx
254 if (!empty($files['file_id']['tmp_name']) &&
255 array_search($files['file_id']['type'], CRM_Core_SelectValues
::documentApplicationType()) == NULL
257 $errors['file_id'] = ts('Invalid document file format');
259 // If default is not set and no document file is uploaded
260 elseif (empty($files['file_id']['tmp_name']) && !empty($params['file_type']) && !$self->_is_document
) {
261 //On edit page of docx/odt message template if user changes file type but forgot to upload document
262 $errors['file_id'] = ts('Please upload document');
265 return empty($errors) ?
TRUE : $errors;
269 * Process the form submission.
271 * @throws \API_Exception
272 * @throws \CRM_Core_Exception
273 * @throws \Civi\API\Exception\UnauthorizedException
275 public function postProcess() {
276 if ($this->_action
& CRM_Core_Action
::DELETE
) {
277 CRM_Core_BAO_MessageTemplate
::del($this->_id
);
279 $this->postProcessHook();
281 elseif ($this->_action
& CRM_Core_Action
::VIEW
) {
282 // currently, the above action is used solely for previewing default workflow templates
283 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/admin/messageTemplates', 'selectedChild=workflow&reset=1'));
286 // store the submitted values in an array
287 $params = $this->controller
->exportValues();
289 if ($this->_action
& CRM_Core_Action
::UPDATE
) {
290 $params['id'] = $this->_id
;
293 if (!empty($params['file_type'])) {
294 unset($params['msg_html']);
295 unset($params['msg_text']);
296 CRM_Utils_File
::formatFile($params, 'file_id');
298 // delete related file references if html/text/pdf template are chosen over document
299 elseif (!empty($this->_id
)) {
300 $entityFileDAO = new CRM_Core_DAO_EntityFile();
301 $entityFileDAO->entity_id
= $this->_id
;
302 $entityFileDAO->entity_table
= 'civicrm_msg_template';
303 if ($entityFileDAO->find(TRUE)) {
304 $fileDAO = new CRM_Core_DAO_File();
305 $fileDAO->id
= $entityFileDAO->file_id
;
306 $fileDAO->find(TRUE);
307 $entityFileDAO->delete();
312 $this->_workflow_id
= $this->_values
['workflow_id'] ??
NULL;
313 if ($this->_workflow_id
) {
314 $params['workflow_id'] = $this->_workflow_id
;
315 $params['is_active'] = TRUE;
318 $messageTemplate = MessageTemplate
::save()->setDefaults($params)->setRecords([['id' => $this->_id
]])->execute()->first();
320 // set the id on save, so it can be used in a extension using the posProcess hook
321 $this->_id
= $messageTemplate['id'];
322 $this->postProcessHook();
324 CRM_Core_Session
::setStatus(ts('The Message Template \'%1\' has been saved.', [1 => $messageTemplate['msg_title']]), ts('Saved'), 'success');
326 if (isset($this->_submitValues
['_qf_MessageTemplates_upload'])) {
327 // Save button was pressed
328 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/admin/messageTemplates/add', "action=update&id={$messageTemplate['id']}&reset=1"));
330 // Save and done button was pressed
331 if ($this->_workflow_id
) {
332 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/admin/messageTemplates', 'selectedChild=workflow&reset=1'));
334 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/admin/messageTemplates', 'selectedChild=user&reset=1'));