Set ContactType.name as required in the schema.
[civicrm-core.git] / CRM / Admin / Form / MessageTemplates.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 +--------------------------------------------------------------------+
10 */
11
12 use Civi\Api4\MessageTemplate;
13
14 /**
15 *
16 * @package CRM
17 * @copyright CiviCRM LLC https://civicrm.org/licensing
18 */
19
20 /**
21 * This class generates form components for Message templates
22 * used by membership, contributions, event registrations, etc.
23 */
24 class CRM_Admin_Form_MessageTemplates extends CRM_Core_Form {
25 /**
26 * which (and whether) mailing workflow this template belongs to
27 * @var int
28 */
29 protected $_workflow_id = NULL;
30
31 /**
32 * Is document file is already loaded as default value?
33 *
34 * @var bool
35 */
36 protected $_is_document = FALSE;
37
38 /**
39 * PreProcess form - load existing values.
40 *
41 * @throws \API_Exception
42 * @throws \CRM_Core_Exception
43 * @throws \Civi\API\Exception\UnauthorizedException
44 */
45 public function preProcess() {
46 $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
47 $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'add');
48 $this->assign('action', $this->_action);
49 $this->_values = [];
50 if ($this->_id) {
51 $this->_values = (array) MessageTemplate::get()->addWhere('id', '=', $this->_id)->setSelect(['*'])->execute()->first();
52 }
53 }
54
55 /**
56 * Set default values for the form.
57 *
58 * The default values are retrieved from the database.
59 */
60 public function setDefaultValues() {
61 $defaults = $this->_values;
62
63 if (empty($defaults['pdf_format_id'])) {
64 $defaults['pdf_format_id'] = 'null';
65 }
66 if (empty($defaults['file_type'])) {
67 $defaults['file_type'] = 0;
68 }
69
70 if ($this->_action & CRM_Core_Action::ADD) {
71 $defaults['is_active'] = 1;
72 }
73
74 if ($this->_action & CRM_Core_Action::UPDATE) {
75 $documentInfo = CRM_Core_BAO_File::getEntityFile('civicrm_msg_template', $this->_id, TRUE);
76 if (!empty($documentInfo)) {
77 $defaults['file_type'] = 1;
78 $this->_is_document = TRUE;
79 $this->assign('attachment', $documentInfo);
80 }
81 }
82
83 return $defaults;
84 }
85
86 /**
87 * Build the form object.
88 */
89 public function buildQuickForm() {
90 // For VIEW we only want Done button
91 if ($this->_action & CRM_Core_Action::VIEW) {
92 // currently, the above action is used solely for previewing default workflow templates
93 $cancelURL = CRM_Utils_System::url('civicrm/admin/messageTemplates', 'selectedChild=workflow&reset=1');
94 $cancelURL = str_replace('&amp;', '&', $cancelURL);
95 $this->addButtons([
96 [
97 'type' => 'cancel',
98 'name' => ts('Done'),
99 'js' => ['onclick' => "location.href='{$cancelURL}'; return false;"],
100 'isDefault' => TRUE,
101 ],
102 ]);
103 }
104 else {
105 $this->_workflow_id = $this->_values['workflow_id'] ?? NULL;
106 $this->checkUserPermission($this->_workflow_id);
107 $this->assign('workflow_id', $this->_workflow_id);
108
109 if ($this->_workflow_id) {
110 $selectedChild = 'workflow';
111 }
112 else {
113 $selectedChild = 'user';
114 }
115
116 $cancelURL = CRM_Utils_System::url('civicrm/admin/messageTemplates', "selectedChild={$selectedChild}&reset=1");
117 $cancelURL = str_replace('&amp;', '&', $cancelURL);
118 $buttons[] = [
119 'type' => 'upload',
120 'name' => $this->_action & CRM_Core_Action::DELETE ? ts('Delete') : ts('Save'),
121 'isDefault' => TRUE,
122 ];
123 if (!($this->_action & CRM_Core_Action::DELETE)) {
124 $buttons[] = [
125 'type' => 'submit',
126 'name' => ts('Save and Done'),
127 'subName' => 'done',
128 ];
129 }
130 $buttons[] = [
131 'type' => 'cancel',
132 'name' => ts('Cancel'),
133 'js' => ['onclick' => "location.href='{$cancelURL}'; return false;"],
134 ];
135 $this->addButtons($buttons);
136 }
137
138 if ($this->_action & CRM_Core_Action::DELETE) {
139 $this->assign('msg_title', $this->_values['msg_title']);
140 return;
141 }
142
143 $breadCrumb = [
144 [
145 'title' => ts('Message Templates'),
146 'url' => CRM_Utils_System::url('civicrm/admin/messageTemplates', 'action=browse&reset=1'),
147 ],
148 ];
149 CRM_Utils_System::appendBreadCrumb($breadCrumb);
150
151 $this->applyFilter('__ALL__', 'trim');
152 $this->add('text', 'msg_title', ts('Message Title'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_MessageTemplate', 'msg_title'), TRUE);
153
154 $options = [ts('Compose On-screen'), ts('Upload Document')];
155 $element = $this->addRadio('file_type', ts('Source'), $options);
156 if ($this->_id) {
157 $element->freeze();
158 }
159
160 $this->addElement('file', "file_id", ts('Upload Document'), 'size=30 maxlength=255');
161 $this->addUploadElement("file_id");
162
163 $this->add('text', 'msg_subject',
164 ts('Message Subject'),
165 CRM_Core_DAO::getAttribute('CRM_Core_DAO_MessageTemplate', 'msg_subject')
166 );
167
168 //get the tokens.
169 $tokens = CRM_Core_SelectValues::contactTokens();
170 $tokens = array_merge($tokens, CRM_Core_SelectValues::domainTokens());
171
172 $this->assign('tokens', CRM_Utils_Token::formatTokensForDisplay($tokens));
173
174 // if not a system message use a wysiwyg editor, CRM-5971
175 if ($this->_id &&
176 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_MessageTemplate',
177 $this->_id,
178 'workflow_id'
179 )
180 ) {
181 $this->add('textarea', 'msg_html', ts('HTML Message'),
182 "cols=50 rows=6"
183 );
184 }
185 else {
186 $this->add('wysiwyg', 'msg_html', ts('HTML Message'),
187 [
188 'cols' => '80',
189 'rows' => '8',
190 'onkeyup' => "return verify(this)",
191 'preset' => 'civimail',
192 ]
193 );
194 }
195
196 $this->add('textarea', 'msg_text', ts('Text Message'),
197 "cols=50 rows=6"
198 );
199
200 $this->add('select', 'pdf_format_id', ts('PDF Page Format'),
201 [
202 'null' => ts('- default -'),
203 ] + CRM_Core_BAO_PdfFormat::getList(TRUE), FALSE
204 );
205
206 $this->add('checkbox', 'is_active', ts('Enabled?'));
207 $this->addFormRule([__CLASS__, 'formRule'], $this);
208
209 if ($this->_action & CRM_Core_Action::VIEW) {
210 $this->freeze();
211 CRM_Utils_System::setTitle(ts('View System Default Message Template'));
212 }
213 }
214
215 /**
216 * Restrict users access based on permission
217 *
218 * @param int $workflowId
219 */
220 private function checkUserPermission($workflowId) {
221 if (isset($workflowId)) {
222 $canView = CRM_Core_Permission::check('edit system workflow message templates');
223 }
224 else {
225 $canView = CRM_Core_Permission::check('edit user-driven message templates');
226 }
227
228 if (!$canView && !CRM_Core_Permission::check('edit message templates')) {
229 CRM_Core_Session::setStatus(ts('You do not have permission to view requested page.'), ts('Access Denied'));
230 $url = CRM_Utils_System::url('civicrm/admin/messageTemplates', "reset=1");
231 CRM_Utils_System::redirect($url);
232 }
233 }
234
235 /**
236 * Global form rule.
237 *
238 * @param array $params
239 * The input form values.
240 * @param array $files
241 * The uploaded files if any.
242 * @param array $self
243 *
244 * @return array
245 * array of errors
246 */
247 public static function formRule($params, $files, $self) {
248 // If user uploads non-document file other than odt/docx
249 if (!empty($files['file_id']['tmp_name']) &&
250 array_search($files['file_id']['type'], CRM_Core_SelectValues::documentApplicationType()) == NULL
251 ) {
252 $errors['file_id'] = ts('Invalid document file format');
253 }
254 // If default is not set and no document file is uploaded
255 elseif (empty($files['file_id']['tmp_name']) && !empty($params['file_type']) && !$self->_is_document) {
256 //On edit page of docx/odt message template if user changes file type but forgot to upload document
257 $errors['file_id'] = ts('Please upload document');
258 }
259
260 return empty($errors) ? TRUE : $errors;
261 }
262
263 /**
264 * Process the form submission.
265 *
266 * @throws \API_Exception
267 * @throws \CRM_Core_Exception
268 * @throws \Civi\API\Exception\UnauthorizedException
269 */
270 public function postProcess() {
271 if ($this->_action & CRM_Core_Action::DELETE) {
272 CRM_Core_BAO_MessageTemplate::del($this->_id);
273 }
274 elseif ($this->_action & CRM_Core_Action::VIEW) {
275 // currently, the above action is used solely for previewing default workflow templates
276 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/messageTemplates', 'selectedChild=workflow&reset=1'));
277 }
278 else {
279 // store the submitted values in an array
280 $params = $this->controller->exportValues();
281
282 if ($this->_action & CRM_Core_Action::UPDATE) {
283 $params['id'] = $this->_id;
284 }
285
286 if (!empty($params['file_type'])) {
287 unset($params['msg_html']);
288 unset($params['msg_text']);
289 CRM_Utils_File::formatFile($params, 'file_id');
290 }
291 // delete related file references if html/text/pdf template are chosen over document
292 elseif (!empty($this->_id)) {
293 $entityFileDAO = new CRM_Core_DAO_EntityFile();
294 $entityFileDAO->entity_id = $this->_id;
295 $entityFileDAO->entity_table = 'civicrm_msg_template';
296 if ($entityFileDAO->find(TRUE)) {
297 $fileDAO = new CRM_Core_DAO_File();
298 $fileDAO->id = $entityFileDAO->file_id;
299 $fileDAO->find(TRUE);
300 $entityFileDAO->delete();
301 $fileDAO->delete();
302 }
303 }
304
305 $this->_workflow_id = $this->_values['workflow_id'] ?? NULL;
306 if ($this->_workflow_id) {
307 $params['workflow_id'] = $this->_workflow_id;
308 $params['is_active'] = TRUE;
309 }
310
311 $messageTemplate = MessageTemplate::save()->setDefaults($params)->setRecords([['id' => $this->_id]])->execute()->first();
312 CRM_Core_Session::setStatus(ts('The Message Template \'%1\' has been saved.', [1 => $messageTemplate['msg_title']]), ts('Saved'), 'success');
313
314 if (isset($this->_submitValues['_qf_MessageTemplates_upload'])) {
315 // Save button was pressed
316 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/messageTemplates/add', "action=update&id={$messageTemplate['id']}&reset=1"));
317 }
318 // Save and done button was pressed
319 if ($this->_workflow_id) {
320 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/messageTemplates', 'selectedChild=workflow&reset=1'));
321 }
322 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/messageTemplates', 'selectedChild=user&reset=1'));
323 }
324 }
325
326 }