Merge pull request #15241 from civicrm/5.18
[civicrm-core.git] / CRM / SMS / Form / Upload.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
32 */
33
34/**
b8c71ffa 35 * This file is used to build the form configuring mass sms details.
6a488035
TO
36 */
37class CRM_SMS_Form_Upload extends CRM_Core_Form {
38 public $_mailingID;
39
00be9182 40 public function preProcess() {
6a488035 41 $this->_mailingID = $this->get('mailing_id');
6a488035
TO
42 }
43
44 /**
c490a46a 45 * Set default values for the form.
6a488035 46 */
00be9182 47 public function setDefaultValues() {
6a488035
TO
48 $mailingID = CRM_Utils_Request::retrieve('mid', 'Integer', $this, FALSE, NULL);
49
39404680 50 // Need to differentiate new/reuse mailing, CRM-2873.
6a488035
TO
51 $reuseMailing = FALSE;
52 if ($mailingID) {
53 $reuseMailing = TRUE;
54 }
55 else {
56 $mailingID = $this->_mailingID;
57 }
58
59 $count = $this->get('count');
60 $this->assign('count', $count);
61
62 $this->set('skipTextFile', FALSE);
63
be2fb01f 64 $defaults = [];
6a488035
TO
65
66 if ($mailingID) {
67 $dao = new CRM_Mailing_DAO_Mailing();
68 $dao->id = $mailingID;
69 $dao->find(TRUE);
70 $dao->storeValues($dao, $defaults);
71
39404680
SB
72 // We don't want to retrieve template details once it is
73 // set in session.
6a488035
TO
74 $templateId = $this->get('template');
75 $this->assign('templateSelected', $templateId ? $templateId : 0);
76 if (isset($defaults['msg_template_id']) && !$templateId) {
1e035d58 77 $defaults['SMStemplate'] = $defaults['msg_template_id'];
c6327d7d 78 $messageTemplate = new CRM_Core_DAO_MessageTemplate();
6a488035
TO
79 $messageTemplate->id = $defaults['msg_template_id'];
80 $messageTemplate->selectAdd();
81 $messageTemplate->selectAdd('msg_text');
82 $messageTemplate->find(TRUE);
83
1e035d58 84 $defaults['sms_text_message'] = $messageTemplate->msg_text;
6a488035
TO
85 }
86
87 if (isset($defaults['body_text'])) {
1e035d58 88 $defaults['sms_text_message'] = $defaults['body_text'];
6a488035
TO
89 $this->set('textFile', $defaults['body_text']);
90 $this->set('skipTextFile', TRUE);
91 }
92 }
93
39404680 94 // Fix for CRM-2873.
6a488035
TO
95 if (!$reuseMailing) {
96 $textFilePath = $this->get('textFilePath');
97 if ($textFilePath &&
98 file_exists($textFilePath)
99 ) {
1e035d58 100 $defaults['sms_text_message'] = file_get_contents($textFilePath);
101 if (strlen($defaults['sms_text_message']) > 0) {
6a488035
TO
102 $this->set('skipTextFile', TRUE);
103 }
104 }
105 }
106
107 $defaults['upload_type'] = 1;
108
109 return $defaults;
110 }
111
112 /**
fe482240 113 * Build the form object.
6a488035
TO
114 */
115 public function buildQuickForm() {
116 $session = CRM_Core_Session::singleton();
353ffa53 117 $config = CRM_Core_Config::singleton();
be2fb01f 118 $options = [];
6a488035
TO
119 $tempVar = FALSE;
120
121 $this->assign('max_sms_length', CRM_SMS_Provider::MAX_SMS_CHAR);
122
123 // this seems so hacky, not sure what we are doing here and why. Need to investigate and fix
124 $session->getVars($options,
125 "CRM_SMS_Controller_Send_{$this->controller->_key}"
126 );
127
be2fb01f
CW
128 $attributes = ['onclick' => "showHideUpload();"];
129 $options = [ts('Upload Content'), ts('Compose On-screen')];
6a488035
TO
130
131 $this->addRadio('upload_type', ts('I want to'), $options, $attributes, "&nbsp;&nbsp;");
132
133 CRM_Mailing_BAO_Mailing::commonCompose($this);
134
135 $this->addElement('file', 'textFile', ts('Upload TEXT Message'), 'size=30 maxlength=60');
136 $this->setMaxFileSize(1024 * 1024);
137 $this->addRule('textFile', ts('File size should be less than 1 MByte'), 'maxfilesize', 1024 * 1024);
138 $this->addRule('textFile', ts('File must be in UTF-8 encoding'), 'utf8File');
139
be2fb01f 140 $this->addFormRule(['CRM_SMS_Form_Upload', 'formRule'], $this);
6a488035 141
be2fb01f
CW
142 $buttons = [
143 [
6ea503d4 144 'type' => 'back',
f212d37d 145 'name' => ts('Previous'),
be2fb01f
CW
146 ],
147 [
6a488035 148 'type' => 'upload',
f212d37d 149 'name' => ts('Next'),
6a488035
TO
150 'spacing' => '&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;',
151 'isDefault' => TRUE,
be2fb01f
CW
152 ],
153 [
6a488035
TO
154 'type' => 'cancel',
155 'name' => ts('Cancel'),
be2fb01f
CW
156 ],
157 ];
6a488035
TO
158
159 $this->addButtons($buttons);
160 }
161
162 public function postProcess() {
be2fb01f
CW
163 $params = $ids = [];
164 $uploadParams = ['from_name'];
6a488035
TO
165
166 $formValues = $this->controller->exportValues($this->_name);
167
168 foreach ($uploadParams as $key) {
a7488080 169 if (!empty($formValues[$key])) {
6a488035
TO
170 $params[$key] = $formValues[$key];
171 $this->set($key, $formValues[$key]);
172 }
173 }
174
175 if (!$formValues['upload_type']) {
176 $contents = NULL;
177 if (isset($formValues['textFile']) &&
178 !empty($formValues['textFile'])
179 ) {
180 $contents = file_get_contents($formValues['textFile']['name']);
181 $this->set($key, $formValues['textFile']['name']);
182 }
183 if ($contents) {
184 $params['body_text'] = $contents;
185 }
186 else {
187 $params['body_text'] = 'NULL';
188 }
189 }
190 else {
1e035d58 191 $text_message = $formValues['sms_text_message'];
6a488035
TO
192 $params['body_text'] = $text_message;
193 $this->set('textFile', $params['body_text']);
194 $this->set('text_message', $params['body_text']);
195 }
196
197 $params['name'] = $this->get('name');
198
199 $session = CRM_Core_Session::singleton();
200 $params['contact_id'] = $session->get('userID');
be2fb01f 201 $composeFields = [
353ffa53
TO
202 'SMStemplate',
203 'SMSsaveTemplate',
204 'SMSupdateTemplate',
205 'SMSsaveTemplateName',
be2fb01f 206 ];
6a488035 207 $msgTemplate = NULL;
39404680 208 // Mail template is composed.
6a488035 209 if ($formValues['upload_type']) {
be2fb01f 210 $composeParams = [];
6a488035 211 foreach ($composeFields as $key) {
a7488080 212 if (!empty($formValues[$key])) {
6a488035
TO
213 $composeParams[$key] = $formValues[$key];
214 $this->set($key, $formValues[$key]);
215 }
216 }
217
1e035d58 218 if (!empty($composeParams['SMSupdateTemplate'])) {
be2fb01f 219 $templateParams = [
6a488035
TO
220 'msg_text' => $text_message,
221 'is_active' => TRUE,
1e035d58 222 'is_sms' => TRUE,
be2fb01f 223 ];
6a488035 224
1e035d58 225 $templateParams['id'] = $formValues['SMStemplate'];
6a488035 226
c6327d7d 227 $msgTemplate = CRM_Core_BAO_MessageTemplate::add($templateParams);
6a488035
TO
228 }
229
1e035d58 230 if (!empty($composeParams['SMSsaveTemplate'])) {
be2fb01f 231 $templateParams = [
6a488035
TO
232 'msg_text' => $text_message,
233 'is_active' => TRUE,
1e035d58 234 'is_sms' => TRUE,
be2fb01f 235 ];
6a488035 236
1e035d58 237 $templateParams['msg_title'] = $composeParams['SMSsaveTemplateName'];
6a488035 238
c6327d7d 239 $msgTemplate = CRM_Core_BAO_MessageTemplate::add($templateParams);
6a488035
TO
240 }
241
242 if (isset($msgTemplate->id)) {
243 $params['msg_template_id'] = $msgTemplate->id;
244 }
245 else {
1e035d58 246 $params['msg_template_id'] = CRM_Utils_Array::value('SMStemplate', $formValues);
6a488035
TO
247 }
248 $this->set('template', $params['msg_template_id']);
249 }
250
251 $ids['mailing_id'] = $this->_mailingID;
252
39404680 253 // Build SMS in mailing table.
6a488035
TO
254 CRM_Mailing_BAO_Mailing::create($params, $ids);
255 }
256
257 /**
fe482240 258 * Validation.
6a488035 259 *
901b501a
TO
260 * @param array $params
261 * (ref.) an assoc array of name/value pairs.
6a488035 262 *
77b97be7
EM
263 * @param $files
264 * @param $self
265 *
72b3a70c
CW
266 * @return bool|array
267 * mixed true or array of errors
6a488035 268 */
00be9182 269 public static function formRule($params, $files, $self) {
a7488080 270 if (!empty($_POST['_qf_Import_refresh'])) {
6a488035
TO
271 return TRUE;
272 }
be2fb01f 273 $errors = [];
6a488035
TO
274 $template = CRM_Core_Smarty::singleton();
275
6a488035
TO
276 $domain = CRM_Core_BAO_Domain::getDomain();
277
278 $mailing = new CRM_Mailing_BAO_Mailing();
279 $mailing->id = $self->_mailingID;
280 $mailing->find(TRUE);
281
282 $session = CRM_Core_Session::singleton();
be2fb01f 283 $values = [
6ea503d4 284 'contact_id' => $session->get('userID'),
6a488035 285 'version' => 3,
be2fb01f 286 ];
6a488035
TO
287 require_once 'api/api.php';
288 $contact = civicrm_api('contact', 'get', $values);
289
39404680 290 // CRM-4524.
6a488035
TO
291 $contact = reset($contact['values']);
292
be2fb01f 293 $verp = array_flip(['optOut', 'reply', 'unsubscribe', 'resubscribe', 'owner']);
6a488035
TO
294 foreach ($verp as $key => $value) {
295 $verp[$key]++;
296 }
297
be2fb01f 298 $urls = array_flip(['forward', 'optOutUrl', 'unsubscribeUrl', 'resubscribeUrl']);
6a488035
TO
299 foreach ($urls as $key => $value) {
300 $urls[$key]++;
301 }
302
6a488035
TO
303 $skipTextFile = $self->get('skipTextFile');
304
305 if (!$params['upload_type']) {
306 if ((!isset($files['textFile']) || !file_exists($files['textFile']['tmp_name']))) {
307 if (!($skipTextFile)) {
308 $errors['textFile'] = ts('Please provide a Text');
309 }
310 }
311 }
312 else {
1e035d58 313 if (empty($params['sms_text_message'])) {
314 $errors['sms_text_message'] = ts('Please provide a Text');
6a488035
TO
315 }
316 else {
a7488080 317 if (!empty($params['text_message'])) {
6a488035
TO
318 $messageCheck = CRM_Utils_Array::value('text_message', $params);
319 if ($messageCheck && (strlen($messageCheck) > CRM_SMS_Provider::MAX_SMS_CHAR)) {
be2fb01f 320 $errors['text_message'] = ts("You can configure the SMS message body up to %1 characters", [1 => CRM_SMS_Provider::MAX_SMS_CHAR]);
6a488035
TO
321 }
322 }
323 }
1e035d58 324 if (!empty($params['SMSsaveTemplate']) && empty($params['SMSsaveTemplateName'])) {
325 $errors['SMSsaveTemplateName'] = ts('Please provide a Template Name.');
6a488035
TO
326 }
327 }
328
329 if (($params['upload_type'] || file_exists(CRM_Utils_Array::value('tmp_name', $files['textFile']))) ||
330 (!$params['upload_type'] && $params['text_message'])
331 ) {
332
333 if (!$params['upload_type']) {
334 $str = file_get_contents($files['textFile']['tmp_name']);
335 $name = $files['textFile']['name'];
336 }
337 else {
1e035d58 338 $str = $params['sms_text_message'];
6a488035
TO
339 $name = 'text message';
340 }
341
be2fb01f 342 $dataErrors = [];
6a488035 343
39404680
SB
344 // Do a full token replacement on a dummy verp, the current
345 // contact and domain, and the first organization.
6a488035 346
6a488035
TO
347 // here we make a dummy mailing object so that we
348 // can retrieve the tokens that we need to replace
349 // so that we do get an invalid token error
350 // this is qute hacky and I hope that there might
351 // be a suggestion from someone on how to
352 // make it a bit more elegant
353
353ffa53
TO
354 $dummy_mail = new CRM_Mailing_BAO_Mailing();
355 $mess = "body_text";
6a488035 356 $dummy_mail->$mess = $str;
353ffa53 357 $tokens = $dummy_mail->getTokens();
6a488035
TO
358
359 $str = CRM_Utils_Token::replaceSubscribeInviteTokens($str);
360 $str = CRM_Utils_Token::replaceDomainTokens($str, $domain, NULL, $tokens['text']);
361 $str = CRM_Utils_Token::replaceMailingTokens($str, $mailing, NULL, $tokens['text']);
362 $str = CRM_Utils_Token::replaceOrgTokens($str, $org);
363 $str = CRM_Utils_Token::replaceActionTokens($str, $verp, $urls, NULL, $tokens['text']);
364 $str = CRM_Utils_Token::replaceContactTokens($str, $contact, NULL, $tokens['text']);
365
366 $unmatched = CRM_Utils_Token::unmatchedTokens($str);
367 $contentCheck = CRM_Utils_String::htmlToText($str);
368
369 if (!empty($unmatched) && 0) {
370 foreach ($unmatched as $token) {
371 $dataErrors[] = '<li>' . ts('Invalid token code') . ' {' . $token . '}</li>';
372 }
373 }
374 if (strlen($contentCheck) > CRM_SMS_Provider::MAX_SMS_CHAR) {
be2fb01f 375 $dataErrors[] = '<li>' . ts('The body of the SMS cannot exceed %1 characters.', [1 => CRM_SMS_Provider::MAX_SMS_CHAR]) . '</li>';
6a488035
TO
376 }
377 if (!empty($dataErrors)) {
be2fb01f 378 $errors['textFile'] = ts('The following errors were detected in %1:', [
408b79bf 379 1 => $name,
be2fb01f 380 ]) . ' <ul>' . implode('', $dataErrors) . '</ul>';
6a488035
TO
381 }
382 }
383
c6327d7d 384 $templateName = CRM_Core_BAO_MessageTemplate::getMessageTemplates();
1e035d58 385 if (!empty($params['SMSsaveTemplate']) && in_array(CRM_Utils_Array::value('SMSsaveTemplateName', $params), $templateName)
6a488035 386 ) {
1e035d58 387 $errors['SMSsaveTemplate'] = ts('Duplicate Template Name.');
6a488035
TO
388 }
389 return empty($errors) ? TRUE : $errors;
390 }
391
392 /**
fe482240 393 * Display Name of the form.
6a488035 394 *
6a488035
TO
395 *
396 * @return string
397 */
398 public function getTitle() {
399 return ts('SMS Content');
400 }
96025800 401
5ec6b0ad
TM
402 /**
403 * List available tokens for this form.
404 *
405 * @return array
406 */
407 public function listTokens() {
408 $tokens = CRM_Core_SelectValues::contactTokens();
409 return $tokens;
410 }
411
6a488035 412}