CMS  Version 3.9
abstract_questionnaire_send_manager.inc
Go to the documentation of this file.
1 <?php
7 Fakoli::using("questionnaire", "settings");
8 Fakoli::usingFile("/cms/components/questionnaire/abstract_questionnaire_manager.inc");
9 
38 define("questionnaire_sent", "1");
39 define("questionnaire_send_failed", "2");
40 define("questionnaire_opened", "3");
41 define("questionnaire_no_additional", "4");
42 define("questionnaire_reminder_sent", "5");
43 define("questionnaire_reminder_failed", "6");
44 define("questionnaire_test_sent", "7");
45 define("questionnaire_test_failed", "8");
46 
47 abstract class AbstractQuestionnaireSendManager extends AbstractQuestionnaireManager
48 {
49  var $item;
50  var $recipients;
51  var $responses = array();
52  var $excludes = array();
53  var $addl_recipients = array();
54 
55  function AbstractQuestionnaireSendManager($item)
56  {
57  $this->item = $item;
58 
59  $identifier = $_REQUEST["identifier"];
60  $sendId = $this->getSendPageIdentifier();
61 
62  if($sendId == $_REQUEST["identifier"])
63  {
64  $this->validateSend();
65  }
66  }
67 
68  abstract function getComponentName();
69 
75  abstract function getCreateManager();
76 
81  abstract function getResponseClass();
82 
87  abstract function getResultsManager();
88 
89 
94  function getClassName()
95  {
96  return $this->item->prettifyClassName();
97  }
98 
99 
105  function getSendTestEmailDialog()
106  {
107  return "send_test_email_dialog";
108  }
109 
115  function getSendTestEmailHandler()
116  {
117  return "send_test_email";
118  }
119 
126  function getReminderDialog()
127  {
128  return "reminder_dialog";
129  }
130 
136  function getSendAdditionalHandler()
137  {
138  return "send_additional_emails";
139  }
140 
148  function getRecipientsDialog()
149  {
150  return "recipients_dialog";
151  }
152 
159  function getOpenHandler()
160  {
161  $class = codify(strtolower($this->getClassName()));
162  return "open_{$class}";
163  }
164 
171  function getCloseHandler()
172  {
173  $class = codify(strtolower($this->getClassName()));
174  return "close_{$class}";
175  }
176 
183  function getMessageSelectDialog()
184  {
185  return "message_select_dialog";
186  }
187 
193  function getSendPageIdentifier()
194  {
195  $class = codify(strtolower($this->getClassName()));
196  return "{$class}_preview";
197  }
198 
204  function getConfirmationPage()
205  {
206  $class = codify(strtolower($this->getClassName()));
207  return "{$class}_confirmation";
208  }
209 
215  function getEmailForm()
216  {
217  $class = codify(strtolower($this->getClassName()));
218  return "{$class}_email";
219  }
220 
227  function getQuestionForm()
228  {
229  $mgr = $this->getCreateManager();
230  return $mgr->getQuestionForm();
231  }
232 
239  function getQuestionnaireFormIdentifier()
240  {
241  $mgr = $this->getCreateManager();
242  return $mgr->getQuestionnaireFormIdentifier();
243  }
244 
251  function getQuestionListIdentifier()
252  {
253  $mgr = $this->getCreateManager();
254  return $mgr->getQuestionListIdentifier();
255  }
256 
263  function getSenderEmail()
264  {
265  $item = clone $this->item;
266  $item->filter = null;
267  $component_name = $this->getComponentName();
268 
269  global $user;
270 
271  if($item->hasField("sender_email") && $item->sender_email)
272  {
273  return $item->sender_email;
274  }
275 
276  $email = Settings::getValue($component_name, "sender_email");
277 
278  if(!$email)
279  {
280  $email = $user->email;
281  }
282 
283  return $email;
284  }
285 
291  function setOneRecipientField(&$form, $field, $label = "", $columns = 80)
292  {
294  $renderer->removeDuplicates = true;
295  $renderer->columns = $columns;
296  }
297 
298 
305  function getAllRecipients()
306  {
307  $item = $this->item;
308  $item->filter = null;
309 
310  $recipients = explode(",", $item->recipients);
311 
312  if($item->hasField("sender_email") && $item->sender_email)
313  {
314  if(array_search($item->sender_email, $recipients !== FALSE))
315  {
316  $this->excludes[] = $item->sender_email;
317  }
318  }
319 
320  if($item->hasField("user_id") && $item->user_id)
321  {
322  $user = $item->Author();
323  if(array_search($user->email, $recipients) !== FALSE)
324  {
325  $this->excludes[] = $user->email;
326  }
327  }
328 
329  if($item->hasField("cc_recipients") && $item->cc_recipients)
330  {
331  $ccs = explode(",", $item->cc_recipients);
332  foreach($ccs as $cc)
333  {
334  $recipients[] = $cc;
335  $this->excludes[] = $cc;
336  }
337  }
338 
339  return $recipients;
340  }
341 
348  function generateResponses($recipients)
349  {
350  $item = $this->item;
351  $responseClass = $this->getResponseClass();
352  $itemPk = $item->getPrimaryKey();
353  $responses = array();
354 
355  $indexedResponses = IndexedQuery::create($responseClass, "WHERE {$itemPk}=:{$itemPk}", "email")
356  ->bind(":{$itemPk}", $item->$itemPk)
357  ->execute();
358 
359  foreach($recipients as $recipient)
360  {
361  if(!array_key_exists($recipient, $indexedResponses))
362  {
363  $response = $this->generateToken($recipient);
364  $response->save();
365  }
366  else
367  {
368  $response = $indexedResponses[$recipient];
369  }
370  $responses[] = $response;
371  }
372 
373  return $responses;
374  }
375 
376  /*
377  * generateToken
378  *
379  * Create a token to grant access to enter responses to
380  * the questionnaire/survey. Before accepting a generated
381  * token, we need to make sure that that token does not
382  * exist already.
383  *
384  * @return obj instance of response class
385  */
386  function generateToken($email)
387  {
388  $surveyResponse = null;
389  $itemPk = $this->item->getPrimaryKey();
390  $responseClass = $this->getResponseClass();
391 
392  if(!$response)
393  {
394  $response = new $responseClass();
395 
396  do
397  {
398  $code = "";
399 
400  for($i = 0; $i < 5; ++$i)
401  {
402  $code .= chr(rand(ord('A'), ord('Z')));
403  }
404 
405  $response->token = $code;
406  // Set any initial default fields (e.g., status)
407  $response->setDefaults();
408  $response->$itemPk = $this->item->$itemPk;
409  $response->email = $email;
410  }
411  while(!$response->insert());
412  }
413 
414  return $response;
415  }
416 
425  function getSampleResponse()
426  {
427  global $user;
428 
429  $author = $this->item->Author();
430  $email = ($author) ? $author->email : $user->email;
431 
432  $response = $this->findResponseByEmail($email);
433 
434  if(!$response)
435  {
436  $response = $this->generateToken($email);
437  }
438 
439  if(!$response->isTester())
440  {
441  $response->excludeResponse();
442  }
443 
444  return $response;
445  }
446 
454  function findResponseByEmail($email)
455  {
456  $response_class = $this->getResponseClass();
457  $pk = $this->getPrimaryKey();
458 
459  $responses = Query::create($response_class, "WHERE {$pk}=:{$pk} AND email=:email")
460  ->bind(":{$pk}", $this->item->$pk, ":email", $email)
461  ->execute();
462 
463  return (count($responses) > 0) ? $responses[0] : null;
464  }
465 
466 
472  function setExcluded()
473  {
474  $item = $this->item;
475 
476  $indexedResponses = reindexList($this->responses, "email");
477 
478  if(!count($this->excludes))
479  {
480  return;
481  }
482 
483  foreach($this->excludes as $excludeEmail)
484  {
485  if(!array_key_exists($excludeEmail, $indexedResponses)) continue;
486 
487  $response = $indexedResponses[$excludeEmail];
488 
489  // In case user puts same email in recipients and additional or cc recipients
490  if(is_array($response))
491  {
492  $response = $response[0];
493  }
494 
495  $response->excludeResponse();
496  }
497  }
498 
505  function sendRequests($form)
506  {
507  $rtn = $this->sendToRecipients();
508  if($rtn == questionnaire_sent)
509  {
510  $this->item->setStatus("open");
511  }
512 
513  return $rtn;
514  }
515 
516  function sendToRecipients()
517  {
518  if($this->item->additional_recipients)
519  {
520  return $this->sendToAdditional();
521  }
522 
523  $recipients = $this->getAllRecipients();
524 
525  if(!$recipients)
526  {
527  if($this->allowAnonymous())
528  {
529  $this->item->setStatus("open");
530  return questionnaire_opened;
531  }
532  return;
533  }
534 
535  $this->responses = $this->generateResponses($recipients);
536 
537  $this->setExcluded();
538 
539  if(!count($this->responses))
540  {
541  return;
542  }
543 
544  $rtn = $this->sendEmails();
545 
546  return $rtn;
547  }
548 
549  function allowAnonymous()
550  {
551  $item = clone $this->item;
552  $item->filter = null;
553 
554  return ($item->hasField("allow_anonymous_responses") && $item->allow_anonymous_responses) ? true : false;
555  }
556 
557  function sendActions()
558  {
559  $class = $this->getClassName();
560  return array (
561  "send_additional" => "Send Additional Emails", // only on preview/manage page
562  "send_test" => "Send Test Email To...",
563  "send" => "Preview &amp; Send",
564  "close" => "Close $class",
565  "reopen" => "ReOpen $class",
566  "send_reminders" => "Send Reminders",
567  );
568  }
569 
575  function getSendActions()
576  {
577  $item = clone $this->item;
578  $item->filter = null;
579 
580  // No send actions are valid when the survey is not valid
581  if(!$this->isValid()) return;
582 
583  $sendActions = $this->sendActions();
584 
585  if(!is_array($sendActions) || !count($sendActions))
586  {
587  return null;
588  }
589 
595  $send_identifier = $this->getSendPageIdentifier();
596  $identifier = $_REQUEST["identifier"];
597  if(($item->isSent() && !$this->hasAdditional()) || $identifier == $send_identifier || $item->isClosed())
598  {
599  unset($sendActions["send"]);
600  }
601 
606  if(!$this->hasAdditional() || $identifier != $send_identifier)
607  {
608  unset($sendActions["send_additional"]);
609  }
610 
611  if(!$item->isOpen())
612  {
613  unset($sendActions["close"]);
614  }
615 
616  if(!$item->isClosed())
617  {
618  unset($sendActions["reopen"]);
619  }
620 
621  $nonResponseCount = count($this->getNonResponsives());
622  if($nonResponseCount == 0 || $item->isClosed())
623  {
624  unset($sendActions["send_reminders"]);
625  }
626 
627  return $sendActions;
628  }
629 
630  function hasAdditional()
631  {
632  $item = clone $this->item;
633  $item->filter = null;
634 
635  if($item->hasField("additional_recipients") && $item->additional_recipients)
636  {
637  return true;
638  }
639 
640  return false;
641  }
642 
649  function sendToAdditional()
650  {
651  $item = $this->item;
652  $item->filter = null;
653 
654  if(!$this->hasAdditional())
655  {
656  return;
657  }
658 
659  $addl_recipients = explode(",", $item->additional_recipients);
660  $addl_recipients = array_unique($addl_recipients);
661 
662  // array_diff not providing expected result
663  $new_recipients = array();
664  foreach($addl_recipients as $addl_recipient)
665  {
666  if(!preg_match("/$addl_recipient/", $item->recipients))
667  {
668  $new_recipients[] = $addl_recipient;
669  }
670  }
671 
672  $addl_recipients = $new_recipients;
673 
674  if(!count($addl_recipients))
675  {
676  $item->additional_recipients = '';
677  $item->filter = new InclusionFilter("additional_recipients");
678  $item->save();
680  }
681 
682  $this->excludes = $addl_recipients;
683  $this->addl_recipients = $addl_recipients;
684 
685  $this->responses = $this->generateResponses($addl_recipients);
686 
687  $this->setExcluded();
688 
689  if(!count($this->responses))
690  {
691  return;
692  }
693 
694  $rtn = $this->sendEmails();
695 
696  $this->moveAdditionalToRecipientList();
697 
699  }
700 
701 
710  function sendEmails()
711  {
712  $item = $this->item;
713 
714  $message = $this->getMessage();
715  $subject = $this->getSubject();
716 
717  $sender_email = $this->getSenderEmail();
718 
719  foreach($this->responses as $response)
720  {
721  $rtn = $this->sendOneEmail($response, $subject, $message, $sender_email);
722  }
723 
724  $this->moveAdditionalToRecipientList();
725 
726  return $rtn;
727  }
728 
729  function getSubject()
730  {
731  $item = clone $this->item;
732  $item->filter = null;
733  $component_name = $this->getComponentName();
734 
735  if($item && $item->hasField("subject") && $item->subject)
736  {
737  return $item->subject;
738  }
739 
740  return Settings::getValue($component_name, "email_subject");
741  }
742 
743  function getMessage()
744  {
745  $component_name = $this->getComponentName();
746 
747  $footer = Settings::getValue($component_name, "message_footer");
748  $message = $this->item->message;
749 
750  if($footer)
751  {
752  $message .= "\r\n\r\n{$footer}";
753  }
754 
755  return $message;
756  }
757 
758  function sendOneEmail($response, $subject, $message, $sender_email)
759  {
760  $responseClass = $this->getResponseClass();
761 
762  $mergeMgr = new MergeCodeManager($response, $message, $responseClass);
763  $recipientMessage = $mergeMgr->searchAndReplace($message);
764 
765  $emailHandler = new EmailHandler($response->email, $subject, $recipientMessage, $sender_email);
766  return $emailHandler->send();
767  }
768 
769  /*
770  * Add the set of additional recipients to the existing recipients
771  * field values. We don't use the item's field value "additional_recipients"
772  * because that may not match the final list which excludes duplicates.
773  */
774  function moveAdditionalToRecipientList()
775  {
776  $item = $this->item;
777  $item->filter = null;
778 
779  if(!$item->hasField("additional_recipients"))
780  {
781  return;
782  }
783 
784  if(!count($this->addl_recipients))
785  {
786  return;
787  }
788 
789  $recipients = explode(",", $item->recipients);
790  foreach($this->addl_recipients as $ar)
791  {
792  $recipients[] = $ar;
793  }
794 
795  $item->recipients = implode(",", $recipients);
796  $item->additional_recipients = '';
797  $item->filter = new InclusionFilter("recipients", "additional_recipients");
798  $item->save();
799  }
800 
801 
809  function sendTests($recipients)
810  {
811  $recipients = explode(",", $recipients);
812  $recipients = array_unique($recipients);
813 
814  $this->responses = $this->generateResponses($recipients);
815 
816  $this->excludes = $recipients;
817 
818  $this->setExcluded();
819 
820  if(!count($this->responses))
821  {
822  return;
823  }
824 
825  return $this->sendEmails();
826  }
827 
831  function getNonResponsives()
832  {
833  return $this->item->getNonResponders();
834  }
835 
843  function sendReminderEmails()
844  {
845  $recipients = explode(",", $this->recipients);
846 
847  if(!count($recipients)) return;
848 
849  $this->responses = $this->generateResponses($recipients);
850 
851  if(!count($this->responses)) return;
852 
853  return $this->sendEmails();
854  }
855 
859  function buildSendTestEmailForm($dashboard = 0)
860  {
861  global $user;
862 
863  $item = $this->item;
864  $component_name = $this->getComponentName();
865  $dialog = $this->getSendTestEmailDialog();
866  $itemPk = $this->getPrimaryKey();
867 
868  $email = new EmailTemplate();
869  $email->filter = new InclusionFilter("recipients");
870  $email->recipients = $user->email;
871 
872  $form = new AutoForm($email, "POST", "/action/{$component_name}/{$dialog}?{$itemPk}={$item->$itemPk}&dashboard=$dashboard", "SendTestEmail_form");
873  $form->ajaxSubmit("function(result) {questionnaireSendMgr.testEmailResult(result);}", "function() {document.id('{$form->id}_error').set('text','Failed to communicate with server'); }");
874  $form->required("recipients");
875  $recipientRenderer = new EmailListFieldRenderer($form, "recipients");
876  $recipientRenderer->removeDuplicates = true;
877  $form->submitLabel = "Send Test Email";
878  $form->button("Cancel", "questionnaireSendMgr.closeDialog()", null, true);
879  $form->annotate("recipients", "Recipients of a test email will receive a valid response token but their responses will not be counted in the results. (separate email addresses with a comma ',')");
880 
881  return $form;
882  }
883 
887  function buildReminderForm($dashboard = 0)
888  {
889  $item = $this->item;
890  $component_name = $this->getComponentName();
891  $handler = $this->getReminderDialog();
892  $pk = $this->getPrimaryKey();
893  $id = $this->item->$pk;
894 
895  $mgr = $this->getResultsManager();
896  $nonResponsives = $item->getNonResponders();
897  // displayed in modal dialog
898  $item->set("nonresponsive_count", count($nonResponsives));
899  $item->recipients = formatItems($nonResponsives, "{token}", ", ");
900  // Set the recipient list for use when form is submitted
901  $this->recipients = formatItems($nonResponsives, "{email}", ",");
902 
903  $item->filter = new InclusionFilter("title", "recipients", "sender_email", "message", "subject");
904  $form = new AutoForm($item, "POST", "/action/{$component_name}/{$handler}?{$pk}={$id}&dashboard=$dashboard", "Reminder_form");
905  $form->ajaxSubmit("function(result) {questionnaireSendMgr.reminderDialogResult(result);}", "function() {document.id('{$form->id}_error').set('text','Failed to communicate with server'); }");
906 
907  $form->getRenderer("message")->rows = 10;
908  $form->submitLabel = "Send Reminders";
909  $form->annotate("message", "You can use the email template message as is or customize it for this reminder.");
910  $form->readOnly("sender_email", "recipients", "title");
911  $form->required("message", "subject");
912  $form->button("Cancel", "questionnaireSendMgr.closeDialog()", null, true);
913  $form->alias("recipients", "Recipient Tokens");
914 
915  return $form;
916  }
917 
918 
934  function getTesterIntro($response)
935  {
936  global $user;
937  $item = $this->item;
938  $pk = $this->getPrimaryKey();
939  $item_id = $item->$pk;
940  $response_class = $this->getResponseClass();
941 
942  $out = "<div class='questionnaire_tester_block'>\n";
943  $out .= "<p id='action_result' class='questionnaire_action_result' style='display: none'></p>\n";
944 
945  if(!$response && $user)
946  {
947  $response = $this->findResponseByEmail($user->email);
948  }
949 
950  if($response)
951  {
952  $editLink = $response->getEditUrl();
953  }
954 
955  $out .= "<p>";
956  if($user && $item->isAuthor())
957  {
958  $out .= "Since you have access privileges to this survey, ";
959  }
960  else if($response)
961  {
962  $out .= "Since you are a test user, ";
963  }
964 
965  if(($user || $response) && $item->isClosed())
966  {
967  $out .= "you can override the closed survey status to try out this survey. ";
968  $out .= "</br></br><a href=\"#\" onclick=\"questionnaireMgr.showResponseTokenDialog();\">{$item->title}</a>\n";
969  }
970  else
971  {
972  $out .= "you can access this survey using a test access token.\n";
973  }
974 
975  $out .= "</p>\n";
976 
977  $out .= "<p>";
978  if($response && $response->isSubmitted())
979  {
980  $out .= $response->format("Your survey response token <b>{token}</b> has been submitted. You can reset the token to start over.");
981  }
982  else if($response)
983  {
984  $out .= $response->format("You can use the link above to enter your survey token <b>{token}</b> or use this direct link $editLink.");
985  }
986  elseif($user && $item->isAuthor())
987  {
988  $out .= "If you would like to receive a survey token, send a test survey request email using one of the buttons below.";
989  }
990 
991  if(!$response || ($response && $response->isTester()))
992  {
993  $out .= " Your responses will be excluded from the survey results. ";
994  }
995  else if($user && $response && !$response->isTester())
996  {
997  $out .= " Your response token is currently set to be included in the results. We recommend you set your response to be <a href='#' onclick=\"questionnaireMgr.excludeResponse({$response->response_id}); return false\">excluded</a> from results tabulation. ";
998  }
999  $out .= "</p>";
1000 
1001  $out .= "<div class='button_row' style='text-align: middle;'>\n";
1002  if(!$response && $user && $item->isAuthor())
1003  {
1004  $out .= "<a class='button' href='#' onclick=\"questionnaireSendMgr.sendTestEmail(); return false;\">Send Test Email to {$user->email}</a>\n";
1005  }
1006  else if($response && $response->isSubmitted())
1007  {
1008  $out .= $response->format("<a class='button' href='#' onclick=\"questionnaireMgr.resetToken({response_id}, 1); return false\">Reset Token</a>\n");
1009  }
1010 
1011  $out .= "</div>\n";
1012  $out .= "</div>\n";
1013 
1014  return $out;
1015  }
1016 
1021  function getSendPageHeading($tabs = null)
1022  {
1023  $item = $this->item;
1024  $out = "";
1025 
1026  $out = "<div id='questionnaire_heading'>";
1030  if($tabs && $item->isSent())
1031  {
1032  $nextPage = $tabs->getNextPage();
1033  $out .= "<button id='next_page_button' class='button' onclick=\"go('$nextPage')\">Next Page &raquo;</button>\n";
1034  }
1035 
1036  if (!$item->isSent())
1037  {
1038  $out .= "<h3>Survey Preview &amp; Send</h3>\n";
1039  }
1040  else
1041  {
1042  $out .= "<h3>Manage Survey</h3>\n";
1043  }
1044 
1045  $out .= $this->getStatusMessage();
1046  $out .= "</div>";
1047 
1048  if($item->isSent())
1049  {
1050  $out .= "<h4>Responses Received</h4>\n";
1051  $out .= $this->getProgressBar();
1052  }
1053 
1054  return $out;
1055  }
1056 
1061  function getResultsPageButtons()
1062  {
1063  $item = clone $this->item;
1064  $item->filter = null;
1065 
1066  $mgr = $this->getResultsManager();
1067  $recipientCount = $mgr->getRecipientCount();
1068  $responseCount = $mgr->getResponseCount();
1069 
1070  $buttons = array();
1071  if($item->isOpen() AND $recipientCount > 0 AND $responseCount < $recipientCount)
1072  {
1073  $buttons[] = "<a class=\"button\" href='#' onclick=\"questionnaireSendMgr.showReminderDialog(); return false;\">Send Survey Reminders</a>&nbsp;&nbsp;\n";
1074  }
1075 
1076  if ($this->allowAnonymous())
1077  {
1078  $buttons[] = $item->format("<a target='_blank' href='anonymous_response?{$pk}={{$pk}}' class='button'>Enter an Anonymous Survey Response</a>\n");
1079  }
1080 
1081  if(count($buttons))
1082  {
1083  $out = "<p>" . implode("&nbsp;&nbsp", $buttons) . "</p>\n";
1084 
1085  }
1086 
1087  return $out;
1088  }
1089 
1090  function getProgressBar()
1091  {
1092  $mgr = $this->getResultsManager();
1093  return $mgr->getProgressBar();
1094  }
1095 
1096  function formatDefaultConfirmationMessage()
1097  {
1098  $sitename = Settings::getValue("settings", "sitename");
1099 
1100  return "<p>Thank you for submitting your survey.</p><p>Continue to the <a href='/'>{$sitename} home page.</a></p>";
1101  }
1102 
1103 
1104  function getStatusMessage()
1105  {
1106  $item = clone $this->item;
1107  $item->filter = null;
1108 
1109  $class = strtolower($this->getClassName());
1110 
1111  if (!$item->isSent())
1112  {
1113  if(!$this->allowAnonymous())
1114  {
1115  $out = "<p>This survey has not yet been sent.</p>";
1116  }
1117  else
1118  {
1119  $out = "<p>Since this $class allows anonymous responses, the recipient field is not required. However, if you specify one or more recipients, you must provide an email message.</p>\n";
1120  }
1121  }
1122  else
1123  {
1124  $out .= $item->format("<p>This survey was opened on {start_date:F d, Y}");
1125  if($item->isClosed())
1126  {
1127  $out .= $item->format(" and closed on {end_date:F d, Y}");
1128  }
1129  $out .= ".</p>";
1130  }
1131 
1132  return $out;
1133  }
1134 
1135  function getEmailPageHeading()
1136  {
1137  $item = $this->item;
1138  $out = "<div id='questionnaire_heading'>";
1139  $out .= "<p>";
1140  $out .= $this->getStatusMessage();
1141 
1142  if($item->isAuthor() && $item->isClosed())
1143  {
1144  $out .= " If you wish to send additional survey requests, you must first
1145  <a href='#' onclick=\"questionnaireSendMgr.openToRespondents(); return false;\">reopen</a>
1146  the survey.";
1147  }
1148 
1149  $out .= "</p>\n";
1150 
1151  return $out;
1152  }
1153 
1154  function getCCRecipientsAnnotation()
1155  {
1156  if($this->item->isClosed()) return "";
1157 
1158  global $user;
1159 
1160  return "CC Recipients will receive a copy of the email with a valid survey response token but their responses
1161  will not be counted in the results. (separate email addresses with a comma ',')</br>
1162  <div class='button_row'>\n<a class='button' onclick=\"questionnaireSendMgr.addEmailToCCRecipients('{$user->email}'); return false;\">Add Me To CC Recipients</a>&nbsp;&nbsp;
1163  <a class='button' onclick=\"questionnaireSendMgr.addEmailToCCRecipients('sender'); return false;\">Add Sender Email to CC Recipients</a>\n</div>\n";
1164  }
1165 
1166  function getMessageAnnotation()
1167  {
1168  if($this->item->isClosed()) return "";
1169 
1170  return "Select from a set of boilerplate messages which you can then customize for this survey.<br>
1171  <div class='button_row'>\n<a href='#' class='button' onclick=\"questionnaireSendMgr.showMessageSelectDialog(); return false;\">Select a Message</span></a>&nbsp&nbsp;
1172  <a href='#' class='button' onclick=\"questionnaireSendMgr.showAdvancedFeaturesDialog(); return false\">Advanced Features</a>\n</div>\n";
1173  }
1174 
1175  /*
1176  * Draw a:link button options on Preview/Manage Survey tab
1177  *
1178  * public view
1179  * close/reopen
1180  * send test
1181  * send reminders
1182  */
1183  function getManageLinks()
1184  {
1185  $item = clone $this->item;
1186  $item->filter = null;
1187  $class = $this->getClassName();
1188 
1189  $actions = $this->getSendActions();
1190 
1191  if(count($actions) > 0)
1192  {
1193  foreach($actions as $name => $label)
1194  {
1195  $buttons[] = "<a class='button' href=\"#\" onclick=\"questionnaireSendMgr.handleSendAction('{$name}'); return false;\">{$label}</a>";
1196  }
1197  }
1198 
1199  $out = "<p>" . implode("&nbsp;&nbsp;", $buttons) . "</p>\n";
1200  return $out;
1201  }
1202 
1218  function isValid()
1219  {
1220  $this->validation_msg = "";
1221  $mgr = $this->getCreateManager();
1222 
1223  $msg = $this->validateSend();
1224 
1225  if($msg) return false;
1226 
1227  $msg = $mgr->validateQuestionnaire();
1228 
1229  if($msg) return false;
1230 
1231  return true;
1232  }
1233 
1238  function getSendSubmitLabel()
1239  {
1240  $item = clone $this->item;
1241  $item->filter = null;
1242  $class = $this->getClassName();
1243 
1244  if($item->recipients || ($item->hasField("cc_recipients") && $item->cc_recipients))
1245  {
1246  $label = "Send $class Emails";
1247  }
1248  else
1249  {
1250  $label = "Open to Anonymous Respondents";
1251  }
1252 
1253  return $label;
1254  }
1255 
1256  function validate()
1257  {
1258  $this->validation_msg = "";
1259  $mgr = $this->getCreateManager();
1260 
1261  $msg = $mgr->validateQuestionnaire();
1262  if($msg) $msg .= "<br>";
1263  $msg .= $this->validateSend();
1264  $this->validation_msg = $msg;
1265  }
1266 
1267  function writeSendValidationMsg()
1268  {
1269  $msg = $this->validateSend();
1270  echo "<div id='warning'>{$msg}</div>\n";
1271  }
1272 
1273  function writeQuestionnaireValidationMsg()
1274  {
1275  $mgr = $this->getCreateManager();
1276  $mgr->writeQuestionnaireValidationMsg();
1277  }
1278 
1279  function validateSend()
1280  {
1281  $item = clone $this->item;
1282  $item->filter = null;
1283 
1284  $pk = $this->getPrimaryKey();
1285  $id = $item->$pk;
1286  $email_form = $this->getEmailForm();
1287  $msg = "";
1288 
1289  if(!$item->recipients && !$this->allowAnonymous())
1290  {
1291  if($msg) $msg .= "<br>";
1292  $msg .= "You must enter at least one recipient email address.";
1293  }
1294 
1295  $recipientFields[] = "recipients";
1296  $this->validateRecipients($msg, $item->recipients);
1297 
1298  if($item->hasField("cc_recipients"))
1299  {
1300  $this->validateRecipients($msg, $item->cc_recipients);
1301  $recipientFields[] = "recipients";
1302  }
1303 
1304  if($item->hasField("additional_recipients"))
1305  {
1306  $this->validateRecipients($msg, $item->cc_recipients);
1307  $recipientFields[] = "recipients";
1308  }
1309 
1310  $empty = true;
1311  foreach($recipientsFields as $field)
1312  {
1313  if($item->$field)
1314  {
1315  $empty = false;
1316  }
1317  }
1318 
1319  if(!$item->message && (!$this->allowAnonymous() || !$empty))
1320  {
1321  if($msg) $msg .= "<br>";
1322  $msg .= "You must enter a message for the email.";
1323  }
1324 
1325  return $msg;
1326  }
1327 
1328  function validateRecipients(&$msg, $values)
1329  {
1330  if(!$values) return $msg;
1331 
1332  $recipients = explode(",", $values);
1333 
1334  foreach($recipients as $recipient)
1335  {
1336  if(!preg_match('/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i', $recipient))
1337  {
1338  if($msg) $msg .= "<br>";
1339  $msg .= "<warning>$recipient</warning> is an invalid email address.<br>";
1340  }
1341  }
1342  }
1343 
1351  function getInfoMsg($sent = null, $dashboard = false)
1352  {
1353  if(!$sent)
1354  {
1355  $sent = checkNumeric($_GET["sent"]);
1356  if(!$sent) return "";
1357  }
1358 
1359  $messages = $this->getSendResultMessages($dashboard);
1360 
1361  return $messages[$sent];
1362  }
1363 
1364  function getSendResultMessages($dashboard = false)
1365  {
1366  $class = strtolower($this->getClassName());
1367 
1368  if(!$dashboard)
1369  {
1370  return array(
1371  questionnaire_sent => "Your $class requests have been sent.",
1372  questionnaire_send_failed => "Your $class requests could not be sent.",
1373  questionnaire_opened => "Your $class has been opened to respondents.",
1374  questionnaire_no_additional => "There were no additional recipients who did not already receive the $class request.",
1375  questionnaire_reminder_sent => "Reminder emails have been sent.",
1376  questionnaire_reminder_failed => "Reminder emails could not be sent.",
1377  questionnaire_test_sent => "A test email has been sent.",
1378  questionnaire_test_failed => "A test email coult not be sent."
1379  );
1380  }
1381  else
1382  {
1383  return array(
1384  questionnaire_sent => "Requests sent",
1385  questionnaire_send_failed => "Requests failed",
1386  questionnaire_opened => "$class opened",
1387  questionnaire_no_additional => "No new additional",
1388  questionnaire_reminder_sent => "Reminders sent",
1389  questionnaire_reminder_failed => "Reminders failed",
1390  questionnaire_test_sent => "Test email sent",
1391  questionnaire_test_failed => "Test email failed"
1392  );
1393  }
1394  }
1395 
1410  function writeScript()
1411  {
1412  $item = $this->item;
1413  $itemPk = $item->getPrimaryKey();
1414  $item_id = ($item->$itemPk) ? $item->$itemPk : 0;
1415  $component_name = $this->getComponentName();
1416  $item_label = $item->prettifyClassName();
1417  $send_test_email_dialog = $this->getSendTestEmailDialog();
1418  $send_test_email_handler = $this->getSendTestEmailHandler();
1419  $send_additional_handler = $this->getSendAdditionalHandler();
1420 
1421  $open_handler = $this->getOpenHandler();
1422  $reminder_dialog = $this->getReminderDialog();
1423  $close_handler = $this->getCloseHandler();
1424  $send_page_identifier = $this->getSendPageIdentifier();
1425  $recipients_dialog = $this->getRecipientsDialog();
1426  $message_select_dialog = $this->getMessageSelectDialog();
1427  $info_msg = $this->getInfoMsg();
1428 
1429  ob_start();
1430  ?>
1431 <script type="text/javascript" src="/components/questionnaire/js/questionnaire_send.js"></script>
1432 <script type="text/javascript">
1433 var questionnaireSendMgr;
1434 
1435 window.addEvent('domready', function()
1436 {
1437  questionnaireSendMgr = new QuestionnaireSendManager(
1438  '<?php echo $itemPk ?>',
1439  <?php echo $item_id ?>,
1440  '<?php echo $component_name ?>',
1441  '<?php echo $item_label ?>',
1442  '<?php echo $send_test_email_dialog ?>',
1443  '<?php echo $send_test_email_handler ?>',
1444  '<?php echo $send_additional_handler ?>',
1445  '<?php echo $open_handler ?>',
1446  '<?php echo $close_handler ?>',
1447  '<?php echo $reminder_dialog ?>',
1448  '<?php echo $send_page_identifier ?>',
1449  '<?php echo $recipients_dialog ?>',
1450  '<?php echo $message_select_dialog ?>',
1451  '<?php echo $info_msg ?>'
1452  );
1453 
1454 });
1455 </script>
1456 <?
1457  $script .= ob_get_contents();
1458  ob_end_clean();
1459 
1460  return $script;
1461  }
1462 
1463 
1464 } // AbstractQuestionnaireSendManager
1465 ?>
$form
$tabs
$handler
Definition: event_form.inc:62
$out
Definition: page.inc:66
$name
Definition: upload.inc:54
Questionnaire/Survey Implementation instructions.
static using()
Import the datamodels, views and manifest for the specified component(s).
Definition: core.inc:116
static usingFile()
Uses the specified framework file(s) from the framework directory.
Definition: core.inc:369
static getValue($component, $name)
Retrieve the value of the specified Setting.
Definition: settings.inc:104
global $user
$messages
const questionnaire_sent
Optional - for surveys/questionnaires that send requests for responses via email.
$code
Definition: hide_hint.inc:36
$email recipients
Definition: mail_to.inc:53
$message
Definition: mail_to.inc:49
$renderer
if(! $user) if(! $response_id) $response
$table column("Redirect From", "<a href='redirect_form?redirect_id={redirect_id}'>{redirect_from}</a>", true, "width: 30%") -> column("Redirect To", "<a href='{redirect_to}' target='_blank'>{redirect_to}</a>", true, "width: 30%") ->column("Last Modified", "{last_modified}", true, "width: 20%; text-align: center") ->column("Override", "{ override true
Definition: redirects.inc:9
$identifier
Definition: rss.inc:37
$msg
Definition: save.inc:10