Merge pull request #42 from pradpnayak/CRM-11983
[civicrm-core.git] / CRM / Mailing / Form / Upload.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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-2013
32 * $Id$
33 *
34 */
35
36 /**
37 * This file is used to build the form configuring mailing details
38 */
39 class CRM_Mailing_Form_Upload extends CRM_Core_Form {
40 public $_mailingID;
41
42 function preProcess() {
43 $this->_mailingID = $this->get('mailing_id');
44 if (CRM_Core_Permission::check('administer CiviCRM')) {
45 $this->assign('isAdmin', 1);
46 }
47
48 //when user come from search context.
49 $ssID = $this->get('ssID');
50 $this->assign('ssid',$ssID);
51 $this->_searchBasedMailing = CRM_Contact_Form_Search::isSearchContext($this->get('context'));
52 if(CRM_Contact_Form_Search::isSearchContext($this->get('context')) && !$ssID){
53 $params = array();
54 $result = CRM_Core_BAO_PrevNextCache::getSelectedContacts();
55 $this->assign("value", $result);
56 }
57 }
58 /**
59 * This function sets the default values for the form.
60 * the default values are retrieved from the database
61 *
62 * @access public
63 *
64 * @return None
65 */
66 function setDefaultValues() {
67 $mailingID = CRM_Utils_Request::retrieve('mid', 'Integer', $this, FALSE, NULL);
68
69 //need to differentiate new/reuse mailing, CRM-2873
70 $reuseMailing = FALSE;
71 if ($mailingID) {
72 $reuseMailing = TRUE;
73 }
74 else {
75 $mailingID = $this->_mailingID;
76 }
77
78 $count = $this->get('count');
79 $this->assign('count', $count);
80
81 $this->set('skipTextFile', FALSE);
82 $this->set('skipHtmlFile', FALSE);
83
84 $defaults = array();
85
86 $htmlMessage = NULL;
87 if ($mailingID) {
88 $dao = new CRM_Mailing_DAO_Mailing();
89 $dao->id = $mailingID;
90 $dao->find(TRUE);
91 $dao->storeValues($dao, $defaults);
92
93 //we don't want to retrieve template details once it is
94 //set in session
95 $templateId = $this->get('template');
96 $this->assign('templateSelected', $templateId ? $templateId : 0);
97 if (isset($defaults['msg_template_id']) && !$templateId) {
98 $defaults['template'] = $defaults['msg_template_id'];
99 $messageTemplate = new CRM_Core_DAO_MessageTemplates();
100 $messageTemplate->id = $defaults['msg_template_id'];
101 $messageTemplate->selectAdd();
102 $messageTemplate->selectAdd('msg_text, msg_html');
103 $messageTemplate->find(TRUE);
104
105 $defaults['text_message'] = $messageTemplate->msg_text;
106 $htmlMessage = $messageTemplate->msg_html;
107 }
108
109 if (isset($defaults['body_text'])) {
110 $defaults['text_message'] = $defaults['body_text'];
111 $this->set('textFile', $defaults['body_text']);
112 $this->set('skipTextFile', TRUE);
113 }
114
115 if (isset($defaults['body_html'])) {
116 $htmlMessage = $defaults['body_html'];
117 $this->set('htmlFile', $defaults['body_html']);
118 $this->set('skipHtmlFile', TRUE);
119 }
120
121 //set default from email address.
122 if (CRM_Utils_Array::value('from_name', $defaults) && CRM_Utils_Array::value('from_email', $defaults)) {
123 $defaults['from_email_address'] = array_search('"' . $defaults['from_name'] . '" <' . $defaults['from_email'] . '>',
124 CRM_Core_OptionGroup::values('from_email_address')
125 );
126 }
127 else {
128 //get the default from email address.
129 $defaultAddress = CRM_Core_OptionGroup::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1');
130 foreach ($defaultAddress as $id => $value) {
131 $defaults['from_email_address'] = $id;
132 }
133 }
134
135 if (CRM_Utils_Array::value('replyto_email', $defaults)) {
136 $replyToEmail = CRM_Core_OptionGroup::values('from_email_address');
137 foreach ($replyToEmail as $value) {
138 if (strstr($value, $defaults['replyto_email'])) {
139 $replyToEmailAddress = $value;
140 break;
141 }
142 }
143 $replyToEmailAddress = explode('<', $replyToEmailAddress);
144 $replyToEmailAddress = $replyToEmailAddress[0] . '<' . $replyToEmailAddress[1];
145 $this->replytoAddress = $defaults['reply_to_address'] = array_search($replyToEmailAddress, $replyToEmail);
146 }
147 }
148
149 //fix for CRM-2873
150 if (!$reuseMailing) {
151 $textFilePath = $this->get('textFilePath');
152 if ($textFilePath &&
153 file_exists($textFilePath)
154 ) {
155 $defaults['text_message'] = file_get_contents($textFilePath);
156 if (strlen($defaults['text_message']) > 0) {
157 $this->set('skipTextFile', TRUE);
158 }
159 }
160
161 $htmlFilePath = $this->get('htmlFilePath');
162 if ($htmlFilePath &&
163 file_exists($htmlFilePath)
164 ) {
165 $defaults['html_message'] = file_get_contents($htmlFilePath);
166 if (strlen($defaults['html_message']) > 0) {
167 $htmlMessage = $defaults['html_message'];
168 $this->set('skipHtmlFile', TRUE);
169 }
170 }
171 }
172
173 if ($this->get('html_message')) {
174 $htmlMessage = $this->get('html_message');
175 }
176
177 $htmlMessage = str_replace(array("\n", "\r"), ' ', $htmlMessage);
178 $htmlMessage = str_replace("'", "\'", $htmlMessage);
179 $this->assign('message_html', $htmlMessage);
180
181 $defaults['upload_type'] = 1;
182 if (isset($defaults['body_html'])) {
183 $defaults['html_message'] = $defaults['body_html'];
184 }
185
186 //CRM-4678 setdefault to default component when composing new mailing.
187 if (!$reuseMailing) {
188 $componentFields = array(
189 'header_id' => 'Header',
190 'footer_id' => 'Footer',
191 );
192 foreach ($componentFields as $componentVar => $componentType) {
193 $defaults[$componentVar] = CRM_Mailing_PseudoConstant::defaultComponent($componentType, '');
194 }
195 }
196
197 return $defaults;
198 }
199
200 /**
201 * Function to actually build the form
202 *
203 * @return None
204 * @access public
205 */
206 public function buildQuickForm() {
207 $session = CRM_Core_Session::singleton();
208 $config = CRM_Core_Config::singleton();
209 $options = array();
210 $tempVar = FALSE;
211
212 // this seems so hacky, not sure what we are doing here and why. Need to investigate and fix
213 $session->getVars($options,
214 "CRM_Mailing_Controller_Send_{$this->controller->_key}"
215 );
216
217 $fromEmailAddress = CRM_Core_PseudoConstant::fromEmailAddress('from_email_address');
218 if (empty($fromEmailAddress)) {
219 //redirect user to enter from email address.
220 $url = CRM_Utils_System::url('civicrm/admin/options/from_email_address', 'group=from_email_address&action=add&reset=1');
221 $status = ts("There is no valid from email address present. You can add here <a href='%1'>Add From Email Address.</a>", array(1 => $url));
222 $session->setStatus($status, ts('Notice'));
223 }
224 else {
225 foreach ($fromEmailAddress as $key => $email) {
226 $fromEmailAddress[$key] = htmlspecialchars($fromEmailAddress[$key]);
227 }
228 }
229
230 $this->add('select', 'from_email_address',
231 ts('From Email Address'), array(
232 '' => '- select -') + $fromEmailAddress, TRUE
233 );
234
235 //Added code to add custom field as Reply-To on form when it is enabled from Mailer settings
236 if (isset($config->replyTo) && !empty($config->replyTo) &&
237 ! CRM_Utils_Array::value( 'override_verp', $options ) ) {
238 $this->add('select', 'reply_to_address', ts('Reply-To'),
239 array('' => '- select -') + $fromEmailAddress
240 );
241 }
242 elseif (CRM_Utils_Array::value('override_verp', $options)) {
243 $trackReplies = TRUE;
244 $this->assign('trackReplies', $trackReplies);
245 }
246
247 $this->add('text', 'subject', ts('Mailing Subject'),
248 CRM_Core_DAO::getAttribute('CRM_Mailing_DAO_Mailing', 'subject'), TRUE
249 );
250
251 $attributes = array('onclick' => "showHideUpload();");
252 $options = array(ts('Upload Content'), ts('Compose On-screen'));
253
254 $this->addRadio('upload_type', ts('I want to'), $options, $attributes, "&nbsp;&nbsp;");
255
256 CRM_Mailing_BAO_Mailing::commonCompose($this);
257
258 $this->addElement('file', 'textFile', ts('Upload TEXT Message'), 'size=30 maxlength=60');
259 $this->setMaxFileSize(1024 * 1024);
260 $this->addRule('textFile', ts('File size should be less than 1 MByte'), 'maxfilesize', 1024 * 1024);
261 $this->addRule('textFile', ts('File must be in UTF-8 encoding'), 'utf8File');
262
263 $this->addElement('file', 'htmlFile', ts('Upload HTML Message'), 'size=30 maxlength=60');
264 $this->setMaxFileSize(1024 * 1024);
265 $this->addRule('htmlFile',
266 ts('File size should be less than %1 MByte(s)',
267 array(1 => 1)
268 ),
269 'maxfilesize',
270 1024 * 1024
271 );
272 $this->addRule('htmlFile', ts('File must be in UTF-8 encoding'), 'utf8File');
273
274 //fix upload files when context is search. CRM-3711
275 $ssID = $this->get('ssID');
276 if ($this->_searchBasedMailing && $ssID) {
277 $this->set('uploadNames', array('textFile', 'htmlFile'));
278 }
279
280 CRM_Core_BAO_File::buildAttachment($this,
281 'civicrm_mailing',
282 $this->_mailingID
283 );
284
285 $this->add('select', 'header_id', ts('Mailing Header'),
286 array('' => ts('- none -')) + CRM_Mailing_PseudoConstant::component('Header')
287 );
288
289 $this->add('select', 'footer_id', ts('Mailing Footer'),
290 array('' => ts('- none -')) + CRM_Mailing_PseudoConstant::component('Footer')
291 );
292
293 $this->addFormRule(array('CRM_Mailing_Form_Upload', 'formRule'), $this);
294
295 $buttons = array(
296 array('type' => 'back',
297 'name' => ts('<< Previous'),
298 ),
299 array(
300 'type' => 'upload',
301 'name' => ts('Next >>'),
302 'spacing' => '&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;',
303 'isDefault' => TRUE,
304 ),
305 array(
306 'type' => 'upload',
307 'name' => ts('Save & Continue Later'),
308 'subName' => 'save',
309 ),
310 array(
311 'type' => 'cancel',
312 'name' => ts('Cancel'),
313 ),
314 );
315 $this->addButtons($buttons);
316 }
317
318 public function postProcess() {
319 $params = $ids = array();
320 $uploadParams = array('header_id', 'footer_id', 'subject', 'from_name', 'from_email');
321 $fileType = array('textFile', 'htmlFile');
322
323 $formValues = $this->controller->exportValues($this->_name);
324
325 foreach ($uploadParams as $key) {
326 if (CRM_Utils_Array::value($key, $formValues) ||
327 in_array($key, array('header_id', 'footer_id'))
328 ) {
329 $params[$key] = $formValues[$key];
330 $this->set($key, $formValues[$key]);
331 }
332 }
333
334 if (!$formValues['upload_type']) {
335 foreach ($fileType as $key) {
336 $contents = NULL;
337 if (isset($formValues[$key]) &&
338 !empty($formValues[$key])
339 ) {
340 $contents = file_get_contents($formValues[$key]['name']);
341 $this->set($key, $formValues[$key]['name']);
342 }
343 if ($contents) {
344 $params['body_' . substr($key, 0, 4)] = $contents;
345 }
346 else {
347 $params['body_' . substr($key, 0, 4)] = 'NULL';
348 }
349 }
350 }
351 else {
352 $text_message = $formValues['text_message'];
353 $params['body_text'] = $text_message;
354 $this->set('textFile', $params['body_text']);
355 $this->set('text_message', $params['body_text']);
356 $html_message = $formValues['html_message'];
357
358 // dojo editor does some html conversion when tokens are
359 // inserted as links. Hence token replacement fails.
360 // this is hack to revert html conversion for { to %7B and
361 // } to %7D by dojo editor
362 $html_message = str_replace('%7B', '{', str_replace('%7D', '}', $html_message));
363
364 $params['body_html'] = $html_message;
365 $this->set('htmlFile', $params['body_html']);
366 $this->set('html_message', $params['body_html']);
367 }
368
369 $params['name'] = $this->get('name');
370
371 $session = CRM_Core_Session::singleton();
372 $params['contact_id'] = $session->get('userID');
373 $composeFields = array(
374 'template', 'saveTemplate',
375 'updateTemplate', 'saveTemplateName',
376 );
377 $msgTemplate = NULL;
378 //mail template is composed
379 if ($formValues['upload_type']) {
380 $composeParams = array();
381
382 foreach ($composeFields as $key) {
383 if (CRM_Utils_Array::value($key, $formValues)) {
384 $composeParams[$key] = $formValues[$key];
385 $this->set($key, $formValues[$key]);
386 }
387 }
388
389 if (CRM_Utils_Array::value('updateTemplate', $composeParams)) {
390 $templateParams = array(
391 'msg_text' => $text_message,
392 'msg_html' => $html_message,
393 'msg_subject' => $params['subject'],
394 'is_active' => TRUE,
395 );
396
397 $templateParams['id'] = $formValues['template'];
398
399 $msgTemplate = CRM_Core_BAO_MessageTemplates::add($templateParams);
400 }
401
402 if (CRM_Utils_Array::value('saveTemplate', $composeParams)) {
403 $templateParams = array(
404 'msg_text' => $text_message,
405 'msg_html' => $html_message,
406 'msg_subject' => $params['subject'],
407 'is_active' => TRUE,
408 );
409
410 $templateParams['msg_title'] = $composeParams['saveTemplateName'];
411
412 $msgTemplate = CRM_Core_BAO_MessageTemplates::add($templateParams);
413 }
414
415 if (isset($msgTemplate->id)) {
416 $params['msg_template_id'] = $msgTemplate->id;
417 }
418 else {
419 $params['msg_template_id'] = CRM_Utils_Array::value('template', $formValues);
420 }
421 $this->set('template', $params['msg_template_id']);
422 }
423
424 CRM_Core_BAO_File::formatAttachment($formValues,
425 $params,
426 'civicrm_mailing',
427 $this->_mailingID
428 );
429 $ids['mailing_id'] = $this->_mailingID;
430
431 //handle mailing from name & address.
432 $fromEmailAddress = CRM_Utils_Array::value($formValues['from_email_address'],
433 CRM_Core_PseudoConstant::fromEmailAddress('from_email_address')
434 );
435
436 //get the from email address
437 $params['from_email'] = CRM_Utils_Mail::pluckEmailFromHeader($fromEmailAddress);
438
439 //get the from Name
440 $params['from_name'] = CRM_Utils_Array::value(1, explode('"', $fromEmailAddress));
441
442 //Add Reply-To to headers
443 if (CRM_Utils_Array::value('reply_to_address', $formValues)) {
444 $replyToEmail = CRM_Core_PseudoConstant::fromEmailAddress('from_email_address');
445 $params['replyto_email'] = CRM_Utils_Array::value($formValues['reply_to_address'], $replyToEmail);
446 }
447
448 /* Build the mailing object */
449
450 CRM_Mailing_BAO_Mailing::create($params, $ids);
451
452 if (isset($this->_submitValues['_qf_Upload_upload_save']) &&
453 $this->_submitValues['_qf_Upload_upload_save'] == 'Save & Continue Later'
454 ) {
455 //when user perform mailing from search context
456 //redirect it to search result CRM-3711.
457 $ssID = $this->get('ssID');
458 if ($ssID && $this->_searchBasedMailing) {
459 if ($this->_action == CRM_Core_Action::BASIC) {
460 $fragment = 'search';
461 }
462 elseif ($this->_action == CRM_Core_Action::PROFILE) {
463 $fragment = 'search/builder';
464 }
465 elseif ($this->_action == CRM_Core_Action::ADVANCED) {
466 $fragment = 'search/advanced';
467 }
468 else {
469 $fragment = 'search/custom';
470 }
471
472 $context = $this->get('context');
473 if (!CRM_Contact_Form_Search::isSearchContext($context)) {
474 $context = 'search';
475 }
476 $urlParams = "force=1&reset=1&ssID={$ssID}&context={$context}";
477 $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this);
478 if (CRM_Utils_Rule::qfKey($qfKey)) {
479 $urlParams .= "&qfKey=$qfKey";
480 }
481
482 $session = CRM_Core_Session::singleton();
483 $draftURL = CRM_Utils_System::url('civicrm/mailing/browse/unscheduled', 'scheduled=false&reset=1');
484 $status = ts("You can continue later by clicking the 'Continue' action to resume working on it.<br />From <a href='%1'>Draft and Unscheduled Mailings</a>.", array(1 => $draftURL));
485 CRM_Core_Session::setStatus($status, ts('Mailing Saved'), 'success');
486
487 // Redirect user to search.
488 $url = CRM_Utils_System::url('civicrm/contact/' . $fragment, $urlParams);
489 }
490 else {
491 $status = ts("Click the 'Continue' action to resume working on it.");
492 $url = CRM_Utils_System::url('civicrm/mailing/browse/unscheduled', 'scheduled=false&reset=1');
493 }
494 CRM_Core_Session::setStatus($status, ts('Mailing Saved'), 'success');
495 return $this->controller->setDestination($url);
496 }
497 }
498
499 /**
500 * Function for validation
501 *
502 * @param array $params (ref.) an assoc array of name/value pairs
503 *
504 * @return mixed true or array of errors
505 * @access public
506 * @static
507 */
508 static function formRule($params, $files, $self) {
509 if (CRM_Utils_Array::value('_qf_Import_refresh', $_POST)) {
510 return TRUE;
511 }
512 $errors = array();
513 $template = CRM_Core_Smarty::singleton();
514
515
516 if (isset($params['html_message'])) {
517 $htmlMessage = str_replace(array("\n", "\r"), ' ', $params['html_message']);
518 $htmlMessage = str_replace("'", "\'", $htmlMessage);
519 $template->assign('htmlContent', $htmlMessage);
520 }
521
522 $domain = CRM_Core_BAO_Domain::getDomain();
523
524 $mailing = new CRM_Mailing_BAO_Mailing();
525 $mailing->id = $self->_mailingID;
526 $mailing->find(TRUE);
527
528 $session = CRM_Core_Session::singleton();
529 $values = array('contact_id' => $session->get('userID'),
530 'version' => 3,
531 );
532 require_once 'api/api.php';
533 $contact = civicrm_api('contact', 'get', $values);
534
535 //CRM-4524
536 $contact = reset($contact['values']);
537
538 $verp = array_flip(array('optOut', 'reply', 'unsubscribe', 'resubscribe', 'owner'));
539 foreach ($verp as $key => $value) {
540 $verp[$key]++;
541 }
542
543 $urls = array_flip(array('forward', 'optOutUrl', 'unsubscribeUrl', 'resubscribeUrl'));
544 foreach ($urls as $key => $value) {
545 $urls[$key]++;
546 }
547
548
549 // set $header and $footer
550 foreach (array(
551 'header', 'footer') as $part) {
552 $$part = array();
553 if ($params["{$part}_id"]) {
554 //echo "found<p>";
555 $component = new CRM_Mailing_BAO_Component();
556 $component->id = $params["{$part}_id"];
557 $component->find(TRUE);
558 ${$part}['textFile'] = $component->body_text;
559 ${$part}['htmlFile'] = $component->body_html;
560 $component->free();
561 }
562 else {
563 ${$part}['htmlFile'] = ${$part}['textFile'] = '';
564 }
565 }
566
567
568 $skipTextFile = $self->get('skipTextFile');
569 $skipHtmlFile = $self->get('skipHtmlFile');
570
571 if (!$params['upload_type']) {
572 if ((!isset($files['textFile']) || !file_exists($files['textFile']['tmp_name'])) &&
573 (!isset($files['htmlFile']) || !file_exists($files['htmlFile']['tmp_name']))
574 ) {
575 if (!($skipTextFile || $skipHtmlFile)) {
576 $errors['textFile'] = ts('Please provide either a Text or HTML formatted message - or both.');
577 }
578 }
579 }
580 else {
581 if (!CRM_Utils_Array::value('text_message', $params) && !CRM_Utils_Array::value('html_message', $params)) {
582 $errors['html_message'] = ts('Please provide either a Text or HTML formatted message - or both.');
583 }
584 if (CRM_Utils_Array::value('saveTemplate', $params) && !CRM_Utils_Array::value('saveTemplateName', $params)) {
585 $errors['saveTemplateName'] = ts('Please provide a Template Name.');
586 }
587 }
588
589 foreach (array(
590 'text', 'html') as $file) {
591 if (!$params['upload_type'] && !file_exists(CRM_Utils_Array::value('tmp_name', $files[$file . 'File']))) {
592 continue;
593 }
594 if ($params['upload_type'] && !$params[$file . '_message']) {
595 continue;
596 }
597
598 if (!$params['upload_type']) {
599 $str = file_get_contents($files[$file . 'File']['tmp_name']);
600 $name = $files[$file . 'File']['name'];
601 }
602 else {
603 $str = $params[$file . '_message'];
604 $str = ($file == 'html') ? str_replace('%7B', '{', str_replace('%7D', '}', $str)) : $str;
605 $name = $file . ' message';
606 }
607
608 /* append header/footer */
609
610 $str = $header[$file . 'File'] . $str . $footer[$file . 'File'];
611
612 $dataErrors = array();
613
614 /* First look for missing tokens */
615
616 $err = CRM_Utils_Token::requiredTokens($str);
617 if ($err !== TRUE) {
618 foreach ($err as $token => $desc) {
619 $dataErrors[] = '<li>' . ts('This message is missing a required token - {%1}: %2',
620 array(1 => $token, 2 => $desc)
621 ) . '</li>';
622 }
623 }
624
625 /* Do a full token replacement on a dummy verp, the current
626 * contact and domain, and the first organization. */
627
628
629 // here we make a dummy mailing object so that we
630 // can retrieve the tokens that we need to replace
631 // so that we do get an invalid token error
632 // this is qute hacky and I hope that there might
633 // be a suggestion from someone on how to
634 // make it a bit more elegant
635
636 $dummy_mail = new CRM_Mailing_BAO_Mailing();
637 $mess = "body_{$file}";
638 $dummy_mail->$mess = $str;
639 $tokens = $dummy_mail->getTokens();
640
641 $str = CRM_Utils_Token::replaceSubscribeInviteTokens($str);
642 $str = CRM_Utils_Token::replaceDomainTokens($str, $domain, NULL, $tokens[$file]);
643 $str = CRM_Utils_Token::replaceMailingTokens($str, $mailing, NULL, $tokens[$file]);
644 $str = CRM_Utils_Token::replaceOrgTokens($str, $org);
645 $str = CRM_Utils_Token::replaceActionTokens($str, $verp, $urls, NULL, $tokens[$file]);
646 $str = CRM_Utils_Token::replaceContactTokens($str, $contact, NULL, $tokens[$file]);
647
648 $unmatched = CRM_Utils_Token::unmatchedTokens($str);
649
650 if (!empty($unmatched) && 0) {
651 foreach ($unmatched as $token) {
652 $dataErrors[] = '<li>' . ts('Invalid token code') . ' {' . $token . '}</li>';
653 }
654 }
655 if (!empty($dataErrors)) {
656 $errors[$file . 'File'] = ts('The following errors were detected in %1:', array(
657 1 => $name)) . ' <ul>' . implode('', $dataErrors) . '</ul><br /><a href="' . CRM_Utils_System::docURL2('Sample CiviMail Messages', TRUE, NULL, NULL, NULL, "wiki") . '" target="_blank">' . ts('More information on required tokens...') . '</a>';
658 }
659 }
660
661 $templateName = CRM_Core_BAO_MessageTemplates::getMessageTemplates();
662 if (CRM_Utils_Array::value('saveTemplate', $params)
663 && in_array(CRM_Utils_Array::value('saveTemplateName', $params), $templateName)
664 ) {
665 $errors['saveTemplate'] = ts('Duplicate Template Name.');
666 }
667 return empty($errors) ? TRUE : $errors;
668 }
669
670 /**
671 * Display Name of the form
672 *
673 * @access public
674 *
675 * @return string
676 */
677 public function getTitle() {
678 return ts('Mailing Content');
679 }
680 }
681