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