Odyssey
userSupportSecureMessages.prg
1 <?php
2 /**
3  * @package UserSupport (Subpackage secure messages)
4  * @author SPB
5  *
6  * This script is run when either:
7  * 1) The user opens up the secure messages (conversation) card in the user hub.
8  * 2) The user clicks on the secure messages link on the left.
9  */
10 require_once("$admLibrary/userSearch.i");
11 $parameters = array("a" => array("operation" => "", "payload" => "", "mode" => "", "parentId" => "", "message" => "", "subject" => "", "markUnread" => ""));
12 $string = array("filter" => FILTER_DEFAULT);
13 HCU_ImportVars($parameters, "a", array("operation" => $string, "payload" => $string, "mode" => $string, "parentId" => $string, "message" => $string, "subject" => $string,
14  "markUnread" => $string));
15 extract($parameters["a"]);
16 
17 $operation = isset($operation) ? trim($operation) : "";
18 $payload = !isset($payload) ? "" : trim($payload);
19 
20 $userId = null;
21 if ($payload != "") {
22  try { $userId = HCU_PayloadDecode($Cu, $payload); } catch(exception $e) {}
23  $userId = isset($userId) ? $userId["user_id"] : null;
24 }
25 
26 $mode = isset($mode) ? trim($mode) : "";
27 $parentId = isset($parentId) ? trim($parentId) : "";
28 $message = isset($message) ? trim($message) : "";
29 $subject = isset($subject) ? trim($subject) : "";
30 
31 if ($operation != "") {
32  // Take out the reads for the all secure message page because the user payload is not relevant here.
33  if ($operation == "readSecureMessages" && $ft == 20) {
34  $returnArray = readSecureMessages($dbh, $Cu, $mode, $userId, $showSQL);
35  } else if ($operation == "readThread" && $ft == 20) {
36  $returnArray = readThread($dbh, $Cu, $parentId, $userId, true);
37  } else if ($operation == "markReadState") {
38  $returnArray = MarkReadState($dbh, $Cu, $parentId, $markUnread); // Nor is it relevant to mark a thread as read/unread.
39  } else if (isset($userId)) {
40  switch($operation) {
41  case "readSecureMessages":
42  $returnArray = readSecureMessages($dbh, $Cu, $mode, $userId, $showSQL);
43  break;
44  case "sendSecureMessage":
45  $returnArray = sendSecureMessage($dbh, $Cu, $Cn, $message, $subject, $userId, $parentId);
46  break;
47  case "readThread":
48  $returnArray = readThread($dbh, $Cu, $parentId, $userId);
49  break;
50  case "deleteThread":
51  $returnArray = deleteThread($dbh, $Cu, $parentId, $userId);
52  break;
53  default: // Won't get here
54  $returnArray = array("error" => array("Operation not specified: '$operation'"), "record" => array(), "sql" => array());
55  }
56  } else {
57  $returnArray = array("error" => "No User Found", "record" => array(), "sql" => array());
58  }
59 
60  header('Content-type: application/json');
61  if (!$showSQL) {
62  unset($returnArray["sql"]);
63  }
64  print HCU_JsonEncode($returnArray);
65 } else {
66  if ($ft == 3) { // Secure Messages through user hub
67  if (isset($userId)) {
68  printPage("$menu_link?ft=$ft", true, $payload, readSecureMessages($dbh, $Cu, 1, $userId, $showSQL));
69  } else { ?>
70  <div class='noUserFound'><div>No User Found</div></div>
71  <?php }
72  } else if ($ft == 20) { // Standalone Secure Messages
73  printPage("$menu_link?ft=$ft", false, "", null);
74  }
75 }
76 
77 /**
78  * function MarkReadState($dbh, $Cu, $parentId, $markUnread)
79  * This toggles the read flag
80  *
81  * @param $dbh -- the database connection
82  * @param $Cu -- the credit union
83  * @param $parentId -- The parent id
84  * @param $markUnread -- "Y" if marking unread, "N" if marking read.
85  *
86  * @return Errors if they exist. Code of error if it exists. ParentId and markUnread variables.
87  */
88 function MarkReadState($dbh, $Cu, $parentId, $markUnread) {
89  try {
90  $sqls = array();
91  if ($parentId == "") {
92  throw new exception("Parent id is required.", 1);
93  }
94  if (!is_numeric($parentId)) {
95  throw new exception("Parent id is not numeric.", 2);
96  }
97  if (!in_array($markUnread, array("Y", "N"))) {
98  throw new exception("Mark unread is invalid.", 3);
99  }
100  $markUnreadDB = $markUnread === "Y" ? "true" : "false";
101  $sql = "update cuadmeco set unread = $markUnreadDB where cu = '$Cu' and messageid = $parentId and origination = 1;";
102  $sqls[] = $sql;
103  $sth = db_query($sql, $dbh);
104  if (!$sth) {
105  throw new exception("Check query failed.", 4);
106  }
107  $returnArray = array("error" => array(), "code" => "000", "sql" => $sqls, "parentId" => $parentId, "markUnread" => $markUnread);
108  } catch (exception $e) {
109  $returnArray = array("error" => array($e->getMessage()), "code" => $e->getCode(), "sql" => $sqls);
110  }
111  return $returnArray;
112 }
113 
114 /**
115  * function getSecureMessageFilterSort($dontCompile=false)
116  * Gets the current filter and sort for the secure message grid
117  *
118  * @param boolean $dontCompile -- if true, don't create the filter or sort. (Need the other values though.)
119  * @return array --
120  * $filter -- a json_encoded string to plug into the kendo grid dataSource.
121  * $sort -- a json_encoded string to plug into the kendo grid dataSource.
122  * $show -- 1,2,3 for showing inbox messages, outbox messages, and unread messages.
123  * $duration -- 1,2,3 for showing messages in past 30 days, past 60 days, and all time.
124  * $sortDir -- The direction that the grid is currently sorting.
125  * $sortField -- The field that the grid is currently sorting.
126  */
127 function getSecureMessageFilterSort($dontCompile = false) {
128  $parameters = array("a" => array("hasFilter" => "", "duration" => "", "show" => "", "sortField" => "", "sortDir" => ""));
129  $string = array("filter" => FILTER_SANITIZE_STRING);
130  HCU_ImportVars($parameters, "a", array("hasFilter" => $string, "duration" => $string, "show" => $string, "sortField" => $string, "sortDir" => $string));
131  extract($parameters["a"]);
132  $hasFilter = isset($hasFilter) ? trim($hasFilter) : "";
133  $duration = isset($duration) ? trim($duration) : "";
134  $show = isset($show) ? trim($show) : "";
135  $showDir = isset($sortDir) ? trim($sortDir) : "";
136  $sortField = isset($sortField) ? trim($sortField) : "";
137 
138  try {
139  if ($hasFilter != "Y") {
140  throw new exception("Filter is not defined.", 1);
141  }
142  if ($duration == "") {
143  throw new exception("Duration is not defined.", 2);
144  }
145  if ($show == "") {
146  throw new exception("Show is not defined.", 3);
147  }
148  if ($sortField == "") {
149  throw new exception("Sort field is not defined.", 5);
150  }
151  if ($sortDir == "") {
152  throw new exception("Sort dir is not defined.", 7);
153  }
154  if (!is_numeric($duration) || $duration < 1 || $duration > 3) {
155  throw new exception("Duration is invalid.", 4);
156  }
157  if (!is_numeric($show) || $show < 1 || $show > 3) {
158  throw new exception("Show is invalid.", 6);
159  }
160  if (!in_array($sortDir, array("asc", "desc"))) {
161  throw new exception("Sort dir is invalid.", 8);
162  }
163  if (!in_array($sortField, array("messageid", "parentid", "date", "unread", "memdeleted", "admdeleted", "origination", "subject", "user_id"))) {
164  throw new exception("Sort field is invalid.", 9);
165  }
166  } catch(exception $e) {
167  // Something is wrong with the sort or filter saved so do defaults (or this is the first time inside this page)
168  $duration = 1;
169  $show = 1;
170  $sortDir = "desc";
171  $sortField = "date";
172  }
173 
174  if (!$dontCompile) {
175  $filter = array();
176  $filter[] = array("field" => "origination", "operator" => "eq", "value" => $show == 2 ? 0 : 1);
177  if ($show == 3) {
178  $filter[] = array("field" => "unread", "operator" => "eq", "value" => "Y");
179  }
180  $filter = HCU_JsonEncode($filter);
181 
182  $sort = array(array("field" => $sortField, "dir" => $sortDir));
183  $sort = HCU_JsonEncode($sort);
184  } else {
185  $filter = "";
186  $sort = "";
187  }
188 
189  return array("filter" => $filter, "sort" => $sort, "show" => $show, "duration" => $duration, "sortDir" => $sortDir, "sortField" => $sortField);
190 }
191 
192 /**
193  * function deleteThread($dbh, $Cu)
194  * Removes the entire conversation from admin. If the member has also removed a message, it removes the records from the database.
195  *
196  * @param integer $dbh -- the database connection
197  * @param string $Cu -- the credit union
198  * @param integer $parentId -- the parentId of the starting message
199  * @param integer $userId -- the user Id of the banking member of the message strand
200  * @return array --
201  * $error -- array of zero or one errors
202  * $code -- nonzero if there is an error
203  * $sql -- all SQLs used
204  */
205 function deleteThread($dbh, $Cu, $parentId, $userId) {
206  $sqls = array();
207  try {
208  if ($parentId == "") {
209  throw new exception("Parent id is required.", 1);
210  }
211  if (!is_numeric($parentId)) {
212  throw new exception("Parent id is not numeric.", 2);
213  }
214  $parentId = intval($parentId);
215 
216  // Each thread is to one member. Verify the user payload and then cannot modify cleartext parameters to delete another thread.
217  $sql = "select 'FOUND' from cuadmeco where cu = '$Cu' and parentid = $parentId and user_id <> $userId";
218  $sqls[] = $sql;
219  $sth = db_query($sql, $dbh);
220  if (!$sth) {
221  throw new exception("Check query failed.", 4);
222  }
223  if (db_num_rows($sth) > 0) {
224  throw new exception("Wrong user.", 5);
225  }
226 
227  $updateSQL = "update cuadmeco set admdeleted = true where cu = '$Cu' and parentid = $parentId";
228  $deleteSQL = "delete from cuadmeco where cu = '$Cu' and parentid = $parentId and admdeleted and memdeleted";
229  $sqls[] = $updateSQL;
230  $sqls[] = $deleteSQL;
231  $sth = db_query("$updateSQL; $deleteSQL;",$dbh);
232 
233  if (!$sth) {
234  throw new exception("Deletion failed.", 3);
235  }
236  } catch(exception $e) {
237  return array("error" => array($e->getMessage()), "code" => $e->getCode(), "sql" => $sqls);
238  }
239  return array("error" => array(), "code" => 0, "sql" => $sqls);
240 }
241 
242 /**
243  * function readThread($dbh, $Cu)
244  * Reads the conversation history for a thread.
245  *
246  * @param integer $dbh -- the database connection
247  * @param string $Cu -- the credit union
248  * @param integer $parentId -- the id of the starting message
249  * @param integer $userId -- the banking user id
250  * @param boolean $getUserPayload -- if true, this data call will also return the user payload
251  * @return array --
252  * $error -- array of zero or one errors encountered
253  * $code -- nonzero if there is an error
254  * $sql -- array of SQLs used
255  * $threadData -- data for the thread grid. Shows the message texts of all conversations in the thread
256  * $username -- the username of the banking user
257  * $subject -- the subject of conversation
258  * $userId -- the userId of the banking user
259  * $payload -- the payload of the banking user (needed if not in the user hub)
260  */
261 function readThread($dbh, $Cu, $parentId, $userId, $getUserPayload = false) {
262  $sqls = array();
263  try {
264  if ($parentId == "") {
265  throw new exception("Parent id is required.", 1);
266  }
267  if (!is_numeric($parentId)) {
268  throw new exception("Parent id is not numeric.", 2);
269  }
270  $parentId = intval($parentId);
271 
272  // Each thread is to one member. Verify the user payload and then cannot modify cleartext parameters to delete another thread.
273  if (isset($userId)) {
274  $sql = "select 'FOUND' from cuadmeco where cu = '$Cu' and parentid = $parentId and user_id <> $userId";
275  $sqls[] = $sql;
276  $sth = db_query($sql, $dbh);
277  if (!$sth) {
278  throw new exception("Check query failed.", 8);
279  }
280  if (db_num_rows($sth) > 0) {
281  throw new exception("Wrong user.", 9);
282  }
283  }
284 
285  $tz = GetCreditUnionTimezone($dbh, $Cu);
286 
287  $setSQL = "set time zone '$tz'";
288  $querySQL = "select a.messageid, a.user_id, u.user_name, a.date, to_char(a.date, 'TZ') as timezone, a.origination, a.subject, a.messagetext, a.admin, au.realname as adminname
289  from cuadmeco a left join {$Cu}user u on u.user_id = a.user_id left join cuadminusers au on a.admin = au.user_name and a.cu = au.cu
290  where a.cu = '$Cu' and a.parentid = $parentId order by a.date";
291  $sqls[] = $setSQL;
292  $sqls[] = $querySQL;
293  $sth = db_query("$setSQL; $querySQL;", $dbh);
294  if (!$sth) {
295  throw new exception("Query failed.", 5);
296  }
297 
298  $threadData = array();
299  $username = "";
300  $subject = "";
301  $userId = "";
302  $parentIdFound = false;
303  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
304  if (intval($row["messageid"]) == $parentId) {
305  $userId = intval($row["user_id"]);
306  if ($userId == 0) {
307  $username = "NO USER";
308  } else {
309  $username = $row["user_name"];
310  }
311  $subject = $row["subject"];
312  $parentIdFound = true;
313 
314  $subject = convertMicrosoftCharacters($subject);
315  $subject = nl2br(htmlentities($subject, ENT_QUOTES, "UTF-8", false));
316  }
317  unset($row["user_name"]);
318  unset($row["subject"]);
319  unset($row["user_id"]);
320 
321  $row["messagetext"] = convertMicrosoftCharacters($row["messagetext"]);
322  $row["messagetext"] = nl2br(htmlentities($row["messagetext"], ENT_QUOTES, "UTF-8", false));
323  $threadData[] = $row;
324  }
325 
326  $payload = "";
327  if ($getUserPayload) {
328  $payloadReturn = readUserSearch($dbh, $Cu, array("a" => array("id" => $userId)));
329  if ($payloadReturn["code"] != 0) {
330  throw new exception("Payload return failed.", 10);
331  }
332  $payload = $payloadReturn["encryption"];
333  }
334 
335  // Opened up the conversation so mark them as read (only the ones coming from the member. It is assumed that the CU read their emails before sending them.)
336  $sql = "update cuadmeco set unread = false where cu = '$Cu' and parentid = $parentId and origination = 1";
337  $sqls[] = $sql;
338  $sth = db_query($sql, $dbh);
339  if (!$sth) {
340  throw new exception("update unread failed.", 7);
341  }
342 
343  if (!$parentIdFound) {
344  throw new exception("Parent id not found.", 6);
345  }
346  } catch(exception $e) {
347  return array("error" => array($e->getMessage()), "code" => $e->getCode(), "sql" => $sqls);
348  }
349  return array("error" => array(), "code" => 0, "sql" => $sqls, "record" => array("username" => $username, "subject" => $subject, "userId" => $userId, "threadData" => $threadData),
350  "payload" => $payload);
351 }
352 
353 /**
354  * function sendSecureMessage($dbh, $Cu)
355  * Creates an entry in the database for the response. Sends a "CU has sent you a secure message." email to the user.
356  *
357  * @param integer $dbh -- the database connection
358  * @param string $Cu -- the credit union
359  * @param string $message -- the contents of the message
360  * @param string $subject -- the subject of the message
361  * @param integer $userId -- the banking user id of the thread
362  * @param integer $parentId -- the id of the starting message in the thread
363  * @return array --
364  * $error -- array of zero or one errors encountered
365  * $code -- nonzero if there is an error
366  * $sql -- all sqls used
367  */
368 function sendSecureMessage($dbh, $Cu, $Cn, $message, $subject, $userId, $parentId) {
369  $sqls = array();
370  try {
371  if ($message == "") {
372  throw new exception("Message is required.", 1);
373  }
374  if ($subject == "") {
375  throw new exception("Subject is required.", 2);
376  }
377  if ($userId == "") {
378  throw new exception("User id is required.", 203);
379  }
380  if ($parentId == "") {
381  $parentId = intval($parentId);
382  } else if (!is_numeric($parentId)) {
383  throw new exception("Parent id is not numeric.", 4);
384  }
385  if (!is_numeric($userId)) {
386  throw new exception("User id is not numeric.", 205);
387  }
388  $sql = "select user_name, email from {$Cu}user where user_id = $userId";
389  $sqls[] = $sql;
390  $sth = db_query($sql, $dbh);
391 
392  if (!$sth) {
393  throw new exception("Select query failed.", 206);
394  }
395  if (db_num_rows($sth) == 0) {
396  throw new exception("User not found.", 207);
397  }
398  list($username, $userEmail) = db_fetch_array($sth, 0);
399 
400  // get the From email address
401  $sql = "select email from cuadmnotify where role = 'securemsgfrom' and cu = '$Cu'";
402  $sqls[] = $sql;
403  $sth = db_query($sql,$dbh);
404 
405  if (!$sth) {
406  throw new exception("From email query failed.", 111);
407  }
408  if (db_num_rows($sth) == 0) {
409  throw new exception("From email not found.", 112);
410  }
411 
412  list($admFrom) = db_fetch_array($sth,0);
413  $admFrom = trim($admFrom);
414 
415  if ($admFrom == "") {
416  throw new exception("From email is empty.", 113);
417  }
418 
419  // validateEmail is a function in hcuFunctions.i (included from main.)
420  if (!validateEmail($admFrom)) {
421  throw new exception("From email is not valid.", 114);
422  }
423  if (!validateEmail($userEmail)) {
424  throw new exception("User email is not valid.", 215);
425  }
426 
427  $orgname = "";
428  $pname = "";
429  $sql = "select orgname, pname from cuadmin where cu = '$Cu'";
430  $sqls[] = $sql;
431  $sth = db_query($sql,$dbh);
432 
433  if (!$sth) { // I cannot image this one failing but check it.
434  throw new exception("Cu query failed.", 16);
435  }
436  if (db_num_rows($sth) == 0) {
437  throw new exception("CU not found.", 17);
438  }
439  list($orgname, $pname) = db_fetch_array($sth, 0);
440 
441  $sql = "select nextval('cuadmeco_messageid_seq')";
442  $sqls[] = $sql;
443  $sth = db_query($sql,$dbh);
444  if (!$sth) {
445  throw new exception("Nextval query failed.", 18);
446  }
447  if (db_num_rows($sth) == 0) {
448  throw new exception("Nextval query failed.", 19);
449  }
450 
451  list($messageId) = db_fetch_array($sth, 0);
452  $parentId = $parentId == 0 ? $messageId : $parentId;
453 
454  $tz = GetCreditUnionTimezone($dbh, $Cu);
455 
456  $date = new DateTime();
457  $date->setTimezone(new DateTimeZone($tz));
458  $formattedDate = $date->format("Y-m-d H:i:s");
459  $formattedTz = $date->format("T");
460 
461  $message = prep_save(hcu_displayHtml(preg_replace( "/[\`\;]/", "", $message)));
462 
463  // Safer to put the insert statement at the end so that any other error doesn't make a problem in the database.
464  $sql = "insert into cuadmeco (messageid, parentid, cu, user_id, date, unread, memdeleted, admdeleted, origination, subject, messagetext, admin)
465  values ($messageId, $parentId, '$Cu', '$userId', now(), true, false, false, 0, '" . prep_save($subject)
466  . "', '$message', '$Cn')";
467 
468  $sqls[] = $sql;
469  $sth = db_query($sql, $dbh);
470  if (!$sth) {
471  throw new exception("Insert failed.", 10);
472  }
473 
474  $newMessage = array("messageid" => $messageId, "parentid" => $parentId, "date" => $formattedDate, "timezone" => $formattedTz,
475  "unread" => "N", "memdeleted" => "N", "admdeleted" => "N", "origination" => 0, "subject" => $subject, "user_id" => $userId, "username" => $username, "originalsubject" => $subject);
476 
477  // mail to user at $savedEmail address
478  $orgname = isset($orgname) ? trim($orgname) : "";
479  $pname = isset($pname) ? trim($pname) : "";
480  $notify = new ErrorMail;
481  $notify->mailto = $userEmail;
482  $notify->mailfrom = $admFrom;
483  $notify->replyto = $admFrom;
484  $notify->subject = "$orgname Secure Message";
485  $notify->msgbody = "$orgname has sent you a secure message. Please sign in to $pname to read it.\n\n" . date("m/d/Y H:i:s T");
486  $notify->callingfunction = __FUNCTION__;
487  $notify->file = __FILE__;
488  $notify->cu = $Cu;
489 
490  $notify->SendMail();
491  } catch(exception $e) {
492  $vagueError = "";
493  if ($e->getCode() >= 200 && $e->getCode() < 300) {
494  $vagueError = "User email is not set or is invalid. Please make sure the user has set up an email address.";
495  } else if ($e->getCode() >= 100 && $e->getCode() < 200) {
496  $vagueError = "Admin email is not set or is invalid. To ensure an email is sent to the user, please enter a 'Secure Message Notification Mailed From' email address.";
497  } else {
498  $vagueError = "No email sent to user.";
499  }
500  return array("error" => array($vagueError), "code" => $e->getCode(), "sql" => $sqls);
501  }
502  return array("error" => array(), "code" => 0, "sql" => $sqls, "newMessage" => $newMessage, "info" => "Message has been sent successfully.");
503 }
504 
505 /**
506  * function readSecureMessages($dbh, $Cu, $mode, $userId)
507  * Reads the secure messages in a time period (last 30 days, last 60 days, all) for a CU
508  *
509  * @param integer $dbh -- the database connection
510  * @param string $Cu -- the credit union
511  * @param integer $mode -- 1) last 30 days, 2) last 60 days, 3) all.
512  * @param integer $userId -- the userId of the user.
513  * @param boolean $showSQL -- turn it off for non devmode.
514  * @return array --
515  * $error -- one or zero errors encountered
516  * $code -- nonzero if an error exists
517  * $messages -- array of secure messages for the CU
518  * $sql -- array of SQLs used
519  */
520 function readSecureMessages($dbh, $Cu, $mode, $userId, $showSQL) {
521  $messages = array();
522  $sqls = array();
523  try {
524  if ($mode == "") {
525  throw new exception("Mode is required.", 3);
526  }
527  if (!is_numeric($mode) || $mode < 1 || $mode > 3) {
528  throw new exception("Mode is invalid.", 2);
529  }
530 
531  if ($userId != "" && !is_numeric($userId)) {
532  throw new exception("User id needs to be numeric.", 6);
533  }
534 
535  $tz = GetCreditUnionTimezone($dbh, $Cu);
536 
537  $setSQL = "set time zone '$tz'";
538 
539  $querySQL = "select o.parentid, b.date, to_char(b.date, 'TZ') as timezone, a.unread, b.origination, o.subject, b.user_id, u.user_name as username from
540  (select parentid, bool_or(unread and origination = 1) as unread, max(messageid) as messageid, bool_and(admdeleted) as deleted from cuadmeco
541  where cu = '$Cu' group by parentid) a
542  inner join cuadmeco b on a.messageid = b.messageid inner join ${Cu}user u on b.user_id = u.user_id inner join cuadmeco o on a.parentid = o.messageid and not a.deleted";
543 
544  if ($userId != "") {
545  $querySQL .= " and b.user_id = " . intval($userId);
546  }
547 
548  if ($mode != 3) {
549  $date = new DateTime();
550  $date = DateTime::createFromFormat("Y-m-d", $date->format("Y-m-d")); // Remove time but keep the date.
551  $date->modify("-" . ($mode*30) . " days");
552  $date = $date->format("Y-m-d");
553 
554  $querySQL .= " and cast(b.date as date) >= '$date'";
555  }
556  $sqls[] = $setSQL;
557  $sqls[] = $querySQL;
558  $sth = db_query("$setSQL; $querySQL;", $dbh);
559  if (!$sth) {
560  throw new exception("Select query failed.", 1);
561  }
562  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
563  $row["unread"] = $row["unread"] == "t" ? "Y" : "N";
564 
565  $row["subject"] = preg_replace("/[^[ !-~]/", '', convertMicrosoftCharacters($row["subject"]));
566  $messages[] = $row;
567  }
568  $returnArray = array("error" => array(), "code" => 0, "messages" => $messages, "sql" => $sqls);
569  } catch(exception $e) {
570  $returnArray = array("error" => array($e->getMessage()), "code" => $e->getCode(), "messages" => array(), "sql" => $sqls);
571  }
572 
573  if (!$showSQL) {
574  unset($returnArray["sql"]);
575  }
576  return $returnArray;
577 }
578 
579 /**
580  * function printPage($self, $Cu, $dbh, $userId, $fromUserHub)
581  *
582  * Prints all the scripts, templates, and HTML necessary for the main popup.
583  *
584  * @param string $self -- The URL of this script.
585  * @param integer $userId -- The userId of the user.
586  * @param boolean $fromUserHub -- If from the user hub or not. (Affects where the data calls are getting the payload and whether to lookup the user when creating a new message.)
587  * @param string $payload -- The payload needed for all calls.
588  * @param array $readData -- The results of the read function.
589  */
590 function printPage($self, $fromUserHub, $payload, $readData) { ?>
591  <script type="text/javascript">
592  //# sourceURL=secureMessages.js
593  <?php if (!$fromUserHub) {
594  // Library javascript functions
595  getShowWaitFunctions();
596 
597  printUserSearch($self, "secureMessagesSearchResponse");
598  } ?>
599 
600  var userSupportContents = {};
601  userSupportContents.secureMessages = [];
602  userSupportContents.maxDuration = -1;
603  userSupportContents.payload = "<?php echo isset($payload) ? $payload : "null"; ?>";
604 
605  <?php
606  /**
607  * function init()
608  *
609  * This is the main function to get everything ready on the javascript side.
610  */
611  ?>
612  function init() {
613  $.homecuValidator.setup({ formStatusField: "formValidateDiv", formValidate:'filterDiv'});
614  $("#externalTabWindow").data("preferredHeight", 500);
615  <?php $sortFilter = getSecureMessageFilterSort(); ?>
616  var grid = $("#grid").kendoGrid({
617  dataSource: {
618  transport: {
619  read: function (options) {
620  options.success(userSupportContents.secureMessages);
621  }
622  },
623  schema: {
624  model: {
625  id: "parentid",
626  fields: {
627  parentid: {type: "number"},
628  date: {type: "date"},
629  unread: {type: "string"},
630  origination: {type: "number"},
631  subject: {type: "string"},
632  user_id: {type: "string"},
633  timezone: {type: "string"},
634  username: {type: "string"}
635  }
636  }
637  },
638  filter: <?php echo $sortFilter["filter"]; ?>,
639  sort: <?php echo $sortFilter["sort"]; ?>
640  },
641  columns: [
642  {field: "origination", title: "&nbsp;", width: "50px"},
643  {field: "username", title: "User", width: "100px"},
644  {field: "subject", title: "Topic"},
645  {field: "date", title: "Date", width: "175px"}
646  ],
647  rowTemplate: $("#rowTemplate").html(),
648  sortable: {allowUnsort: false},
649  toolbar: '<a class="k-button k-button-icontext k-grid-createMessage" href="\\#"><span class="fa fa-plus"></span>&nbsp;Add Message</a>'
650  + '<br><br><span class="hcu-secondary"><span class="vsgSecondary">To mark discussion unread, right-click on message.</span></span>',
651  noRecords: {
652  template: "<span class=\"hcu-secondary\"><span class=\"vsgSecondary\">No records found.</span></span>"
653  }
654  }).data("kendoGrid");
655 
656  <?php if ($fromUserHub) { ?>
657  $("#grid").css({maxHeight: "400px"});
658  $("#grid .k-grid-content").css({maxHeight: "310px"});
659  <?php } ?>
660 
661  $(".showOption:eq(<?php echo intval($sortFilter["show"]) - 1; ?>)").addClass("selected");
662  $(".durationOption:eq(<?php echo intval($sortFilter["duration"]) - 1; ?>)").addClass("selected");
663  userSupportContents.maxDuration = <?php echo $sortFilter["duration"]; ?>;
664 
665  $(".selected span").addClass("fa fa-caret-right");
666 
667  $(".showOption").on("click", "a", function() {
668  if (!$(this).hasClass("selected")) {
669  $(".showOption.selected span").removeClass("fa fa-caret-right");
670  $(".showOption.selected").removeClass("selected");
671  var showOption = $(this).closest(".showOption");
672  $(showOption).addClass("selected");
673  $(showOption).find("span").addClass("fa fa-caret-right");
674  filterSecureMessages();
675  }
676  return false;
677  });
678 
679  $(".durationOption").on("click", "a", function() {
680  if (!$(this).hasClass("selected")) {
681  $(".durationOption.selected span").removeClass("fa fa-caret-right");
682  $(".durationOption.selected").removeClass("selected");
683  var durationOption = $(this).closest(".durationOption");
684  $(durationOption).addClass("selected");
685  $(durationOption).find("span").addClass("fa fa-caret-right");
686  filterSecureMessages();
687  }
688  return false;
689  });
690 
691  $("#findInput").on("keyup keydown blur", function() {
692  filterSecureMessages();
693  });
694 
695  <?php if ($fromUserHub) { ?>
696  $("#grid").on("click", ".k-grid-createMessage", function() {
697  openSecureMessageWindow(0);
698  return false;
699  });
700  <?php } else { ?>
701  $("#grid").on("click", ".k-grid-createMessage", function() {
702  openUserSearch();
703  return false;
704  });
705  <?php } ?>
706 
707  $("#grid").on("click", ".k-grid-content tr", function() {
708  var tr = $(this);
709  var dataItem = grid.dataItem(tr);
710  openSecureMessageWindow(dataItem.parentid, dataItem.userId, dataItem.username);
711  return false;
712  });
713 
714  var parameters = {};
715  parameters.mode = Number($(".durationOption.selected").data("type"));
716  <?php if ($fromUserHub) { ?>
717  var data = <?php echo HCU_JsonEncode($readData); ?>;
718  if (data.error.length > 0) {
719  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError )
720  } else {
721  userSupportContents.secureMessages = data.messages;
722  var grid = $("#grid").data("kendoGrid");
723  grid.dataSource.read();
724  }
725  <?php } else { ?>
726  showWaitWindow();
727  $.post("<?php echo $self; ?>&operation=readSecureMessages", parameters, function(data) {
728  hideWaitWindow();
729  if (data.error.length > 0) {
730  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError )
731  } else {
732  userSupportContents.secureMessages = data.messages;
733  var grid = $("#grid").data("kendoGrid");
734  grid.dataSource.read();
735  }
736  });
737  <?php } ?>
738 
739  var contextMenu = $("#contextMenu").kendoContextMenu({
740  target: "#grid",
741  filter: "tbody tr",
742  popupCollision: false,
743  copyAnchorStyles: false,
744  open: function(e) { <?php // Control which menu items get displayed. ?>
745  var dataItem = grid.dataItem($(e.target));
746  if (dataItem.unread == "Y") {
747  $(e.item).find(".markReadLi").show();
748  $(e.item).find(".markUnreadLi").hide();
749  } else {
750  $(e.item).find(".markReadLi").hide();
751  $(e.item).find(".markUnreadLi").show();
752  }
753  },
754  select: function(e) {
755  var dataItem = grid.dataItem($(e.target));
756  switch($(e.item).text().trim()) {
757  case "Open":
758  openSecureMessageWindow(dataItem.parentid, dataItem.userId, dataItem.username);
759  break;
760  case "Mark Read":
761  MarkReadState(dataItem, false);
762  break;
763  case "Mark Unread":
764  MarkReadState(dataItem, true);
765  break;
766  }
767  }
768  }).data("kendoContextMenu");
769  }
770 
771  <?php
772  /**
773  * function MarkReadState(dataItem, markUnread)
774  * Changes the read state from read to unread and vice versa.
775  *
776  * @param dataItem -- the dataItem of the table row.
777  * @param markUnread -- true or false. If true, mark unread. If false, mark read.
778  */
779  ?>
780  function MarkReadState(dataItem, markUnread) {
781  markUnread = markUnread === true ? "Y" : "N";
782  var parameters = {markUnread: markUnread, parentId: dataItem.parentid};
783 
784  $.post("<?php echo $self; ?>&operation=markReadState", parameters, function(data) {
785  hideWaitWindow();
786 
787  if (data.error.length > 0) {
788  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
789  } else {
790 
791  <?php // Update unread status ?>
792  for(var i = 0; i != userSupportContents.secureMessages.length; i++) {
793  var message = userSupportContents.secureMessages[i];
794  if (message.parentid == data.parentId) {
795  message.unread = data.markUnread;
796  break;
797  }
798  }
799 
800  var grid = $("#grid").data("kendoGrid");
801  grid.dataSource.read();
802  }
803  });
804  }
805 
806  <?php if (!$fromUserHub) {
807  /**
808  * function secureMessagesSearchResponse(mode, encryptedMessage, dataItem)
809  * This is hooked into the user search results. It essentially opens up the secure message window with data from the search.
810  */
811  ?>
812  function secureMessagesSearchResponse(mode, encryptedMessage, dataItem) {
813  switch(mode) {
814  case "successfulSelection":
815  case "successfulOneRecord":
816  openSecureMessageWindow(0, dataItem.user_id, dataItem.user_name, encryptedMessage);
817  break;
818  }
819  }
820 
821  <?php }
822 
823  // End of init function. Start of additional functions.
824 
825  /**
826  * $("#filterBtn").click(function()) (anonymous)
827  * This function will apply the filter selections to the grid. If the duration of the grid increases e.g. past 30 days to all then there will be a new call to get the other data.
828  * Otherwise, grid will just be filtered. So changing the duration from ALL to past 30 days will filter the extra data out versus calling the remote read again.
829  * Global variable maxDuration is used to check if the data exists in the grid.
830  * The previous values of duration and show variables are saved so that if there actually is no changes, then nothing happens.
831  */
832  ?>
833  function filterSecureMessages() {
834  var duration = Number($(".durationOption.selected").data("type"));
835  var show = $(".showOption.selected").data("type");
836 
837  var reread = false;
838  var filter = [];
839 
840  <?php if (!$fromUserHub) { ?>
841  var find = $("#findInput").val().trim();
842 
843  if (find != "") {
844  filter.push({logic: "or", filters: [
845  <?php // Have to change the kendo type in the schema from number to string to use "contains". This will be a problem if direct filtering is needed on the grid. ?>
846  {field: "user_id", operator: "contains", value: find},
847  {field: "username", operator: "contains", value: find},
848  {field: "subject", operator: "contains", value: find} <?php // already case-insensitive ?>
849  ]});
850  }
851  <?php } ?>
852 
853  if (duration > userSupportContents.maxDuration) { <?php // data is not currently in grid, will need to retrieve more data. ?>
854  reread = true;
855  } else if (duration != 3) {
856  var date = new Date();
857  date.setHours(0,0,0,0);
858  date.setDate(date.getDate() - duration * 30);
859  filter.push({field: "date", operator: "gte", value: date});
860  }
861 
862  switch(show) {
863  case "unread":
864  filter.push({field: "unread", operator: "eq", value: "Y"}); <?php // notice the missing break. This is not a mistake. Origination of 1 is needed in addition to unread. ?>
865  case "in":
866  filter.push({field: "origination", operator: "eq", value: 1});
867  break;
868  case "out":
869  filter.push({field: "origination", operator: "eq", value: 0});
870  break;
871  }
872 
873  var grid = $("#grid").data("kendoGrid");
874  if (reread) {
875  showWaitWindow();
876  var parameters = <?php echo !$fromUserHub ? "{mode: duration}" : "{mode: duration, payload: userSupportContents.payload}" ?>;
877  $.post("<?php echo $self; ?>&operation=readSecureMessages", parameters, function(data) {
878  hideWaitWindow();
879  if (data.error.length > 0) {
880  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
881  } else {
882  userSupportContents.secureMessages = data.messages;
883  grid.dataSource.filter(filter);
884  grid.dataSource.read();
885 
886  userSupportContents.maxDuration = duration;
887  }
888  });
889  } else {
890  grid.dataSource.filter(filter);
891  }
892  }
893 
894  <?php
895  /**
896  * function openSecureMessageWindow(parentId, dataItem)
897  * Opens the secure message window.
898  *
899  * @param integer parentId -- the parentId of the secureMessage.
900  */ ?>
901  function openSecureMessageWindow(parentId, userId, username, payload) {
902  $("#secureMessageWindow").data("rereadGrid", false);
903  var secureMessageWindow = $("#secureMessageWindow").data("kendoWindow");
904  if (secureMessageWindow == null) {
905  secureMessageWindow = $("<div id='secureMessageWindow'></div>").appendTo("body").kendoWindow({
906  modal: true,
907  title: "Edit Thread",
908  visible: false,
909  resizable: false,
910  minWidth: 300,
911  maxWidth: 500,
912  width: "90%",
913  close: function(e) {
914  if (!$("#secureMessageWindow").data("invalid")) {
915  if ($("#secureMessageWindow").data("rereadGrid")) {
916  $("#grid").data("kendoGrid").dataSource.read();
917  }
918  } else {
919  potentiallyCancelChanges();
920  e.preventDefault();
921  return false;
922  }
923 
924  if (window.activeWindows != null) {
925  window.activeWindows.pop();
926  }
927  },
928  open: function() {
929  $("#secureMessageWindow").data("invalid", true);
930  if (window.activeWindows != null) {
931  window.activeWindows.push(this);
932  }
933  var kWindow = $(this.wrapper);
934  var left = 1/2 * $(window).width() - 1/2 * $(kWindow).width();
935  $(kWindow).css({position: "absolute", top: "10px", left: left + "px"});
936  },
937  activate: function() {
938  window.setTimeout(scrollThread, 100);
939  thisA = $(".k-icon.k-i-print").hide().parent();
940  $(thisA).append("<i class='fa fa-print fa-xs printBtn'></i>");
941  $(thisA).parent().find(".printBtn,.k-i-close").css({verticalAlign:"middle"});
942  },
943  actions: ["print", "Close"] <?php //printBtn ?>
944  }).data("kendoWindow");
945 
946  $("#secureMessageWindow").on("click", ".sendBtn", function() {
947  if ($.homecuValidator.validate()) {
948  $("#secureMessageWindow").data("invalid", false);
949  $("#secureMessageWindow").removeClass("hasError");
950  var parameters = {};
951  parameters.message = $("#messageInput").val();
952 
953  var dataItem = $("#secureMessageWindow").data("data");
954  var parentId = dataItem.parentId;
955 
956  if (parentId != 0) {
957  parameters.parentId = parentId;
958  parameters.subject = "Re: " + dataItem.subject;
959  } else {
960  parameters.subject = $("[name='topicInput']").val();
961  }
962  <?php if (!$fromUserHub) { ?>
963  parameters.payload = $("#secureMessageWindow").data("payload");
964  <?php } else { ?>
965  parameters.payload = userSupportContents.payload;
966  <?php } ?>
967 
968  showWaitWindow();
969  $.post("<?php echo $self; ?>&operation=sendSecureMessage", parameters, function(data) {
970  hideWaitWindow();
971 
972  if (data.error.length > 0) {
973  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
974  } else {
975  if (parentId == 0) {
976  userSupportContents.secureMessages.push(data.newMessage);
977  $("#secureMessageWindow").data("rereadGrid", true);
978 
979  $.homecuValidator.setup({ formStatusField: "formValidateDiv", formValidate:'filterDiv'});
980  $.homecuValidator.displayMessage(data.info, $.homecuValidator.settings.statusSuccess);
981  }
982  secureMessageWindow.close();
983  }
984  });
985  }
986 
987  return false;
988  });
989 
990  $("#secureMessageWindow").on("click", ".cancelBtn", function() {
991  secureMessageWindow.close();
992  return false;
993  });
994 
995  $(".k-window:has(#secureMessageWindow)").on("click", ".printBtn", function() {
996  showPrintThreadPopup();
997  return false;
998  });
999 
1000  $("#secureMessageWindow").on("click", ".deleteBtn", function() {
1001  openDeleteDialogSecureMessages();
1002  return false;
1003  });
1004  } <?php // End if secureWindow is not defined. ?>
1005 
1006  $("#secureMessageWindow").data("data", null);
1007  $("#secureMessageWindow").data("payload", null);
1008 
1009  if (parentId == 0) {
1010  $("#secureMessageWindow").removeClass("hasParent");
1011  var template = kendo.template($("#windowTemplate").html());
1012  var zeData = {parentId: Number(parentId), subject: "", threadData: []};
1013  if (userId != null) {
1014  zeData.userId = userId;
1015  zeData.username = username;
1016  }
1017  template = template(zeData);
1018  $("#secureMessageWindow").data("data", zeData);
1019  secureMessageWindow.setOptions({title: "Add Message"});
1020  secureMessageWindow.content(template).open();
1021 
1022  $("#topicInput").attr("required", "required");
1023  $("#topicInput").attr("data-required-msg", "Topic cannot be blank");
1024 
1025  $.homecuValidator.setup({formValidate:'secureMessageForm', formStatusField: 'editValidateDiv'});
1026 
1027  $(".k-window:has(#secureMessageWindow) .k-window-action:eq(0)").hide();
1028  <?php // Hide the print. "Clicking "Print" with a new message shows an empty screen. Probably don't need to offer to print nothing." ?>
1029 
1030  <?php if (!$fromUserHub) { ?>
1031  $("#secureMessageWindow").data("payload", payload);
1032  <?php } ?>
1033  } else {
1034  $(".k-window:has(#secureMessageWindow) .k-window-action:eq(0)").show();
1035  var parameters = {parentId: parentId};
1036  <?php if ($fromUserHub) { ?>
1037  parameters.payload = userSupportContents.payload;
1038  <?php } ?>
1039  showWaitWindow();
1040  $.post("<?php echo $self; ?>&operation=readThread", parameters, function(data) {
1041  hideWaitWindow();
1042 
1043  if (data.error.length > 0) {
1044  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
1045  } else {
1046  data.record.parentId = parentId;
1047  var template = kendo.template($("#windowTemplate").html());
1048  template = template(data.record);
1049  secureMessageWindow.setOptions({title: "User Messages"});
1050  secureMessageWindow.content(template).open();
1051 
1052  $("#secureMessageWindow").removeClass("hasError");
1053  $("#secureMessageWindow").addClass("hasParent");
1054  $("#secureMessageWindow").data("data", data.record);
1055 
1056  <?php if (!$fromUserHub) { ?>
1057  $("#secureMessageWindow").data("payload", data.payload);
1058  <?php } ?>
1059 
1060  $.homecuValidator.setup({formValidate:'secureMessageForm', formStatusField: 'editValidateDiv'});
1061 
1062  <?php // Update unread status ?>
1063  for(var i = 0; i != userSupportContents.secureMessages.length; i++) {
1064  var message = userSupportContents.secureMessages[i];
1065  if (message.parentid == parentId) {
1066  message.unread = "N";
1067  $("#secureMessageWindow").data("rereadGrid", true);
1068  break;
1069  }
1070  }
1071  }
1072  });
1073  }
1074 
1075  }
1076 
1077  <?php
1078  /**
1079  * function potentiallyCancelChanges()
1080  * This displays the discard changes dialog on close if there are changes made.
1081  */
1082  ?>
1083  function potentiallyCancelChanges() {
1084  if ($("[name='messageInput']").val().trim() == "" && ($("#secureMessageWindow").data("parentId") != 0 || $("[name='topicInput']").val().trim() == "")) {
1085  $("#secureMessageWindow").data("invalid", false);
1086  if ($("#secureMessageWindow").data("rereadGrid")) {
1087  $("#grid").data("kendoGrid").dataSource.read();
1088  }
1089  $("#secureMessageWindow").data("kendoWindow").close();
1090  } else {
1091  var discardChangesDialog = $("#discardChangesDialog").data("kendoDialog");
1092  if (discardChangesDialog == null) {
1093  discardChangesDialog = $("<div id='discardChangesDialog'></div>").appendTo("body").kendoDialog({
1094  title: "Discard Changes",
1095  content: "<p>Changes have been made to this message.</p><p>Do you wish to discard your changes?</p>",
1096  actions: [
1097  {text: "No"},
1098  {text: "Yes", primary: true, action: function() {
1099  $("#secureMessageWindow").data("invalid", false);
1100  $("#secureMessageWindow").data("kendoWindow").close();
1101  if ($("#secureMessageWindow").data("rereadGrid")) {
1102  $("#grid").data("kendoGrid").dataSource.read();
1103  }
1104  }}
1105  ],
1106  visible: false,
1107  open: function() {
1108  if (window.activeWindows != null) {
1109  window.activeWindows.push(this);
1110  }
1111  },
1112  close: function() {
1113  if (window.activeWindows != null) {
1114  window.activeWindows.pop();
1115  }
1116  }
1117  }).data("kendoDialog");
1118  }
1119  discardChangesDialog.open();
1120  }
1121  }
1122 
1123  <?php
1124  /**
1125  * function showPrintThreadPopup()
1126  * This opens a new window for printing.
1127  */
1128  ?>
1129  function showPrintThreadPopup() {
1130  var zeData = $("#secureMessageWindow").data("data");
1131  var template = kendo.template($("#printTemplate").html());
1132  $("#printForm [name='shell']").val(template(zeData));
1133  template = kendo.template($("#printTemplateTitle").html());
1134  $("#printForm [name='title']").val(template(zeData));
1135 
1136  var printWindow = window.open("", "printWindow");
1137  $("#printForm").submit();
1138  }
1139 
1140  <?php
1141  /**
1142  * function openDeleteDialogSecureMessages()
1143  * Opens the delete confirm dialog for secure messages.
1144  */
1145  ?>
1146  function openDeleteDialogSecureMessages() {
1147  var deleteDialog = $("#deleteDialog").data("kendoDialog");
1148  if (deleteDialog == null) {
1149  deleteDialog = $("<div id='deleteDialog'></div>").appendTo("body").kendoDialog({
1150  title: "Delete Thread",
1151  content: "<p>You are about to delete this thread</p><p>Do you wish to continue?</p>",
1152  actions: [
1153  {text: "No"},
1154  {text: "Yes", primary: true, action: function() {
1155  var parentId = $("#secureMessageWindow").data("data").parentId;
1156  var parameters = {parentId: parentId};
1157  <?php if ($fromUserHub) { ?>
1158  parameters.payload = userSupportContents.payload;
1159  <?php } else { ?>
1160  parameters.payload = $("#secureMessageWindow").data("payload");
1161  <?php } ?>
1162  showWaitWindow();
1163  $.post("<?php echo $self; ?>&operation=deleteThread", parameters, function(data) {
1164  hideWaitWindow();
1165  if (data.error.length > 0) {
1166  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
1167  } else {
1168  $("#secureMessageWindow").data("invalid", false);
1169  userSupportContents.secureMessages = $.grep(userSupportContents.secureMessages, function(n,i) { return n.parentid != parentId; });
1170  $("#grid").data("kendoGrid").dataSource.read();
1171  $("#secureMessageWindow").data("kendoWindow").close();
1172  }
1173  });
1174  }}
1175  ],
1176  visible: false,
1177  open: function() {
1178  if (window.activeWindows != null) {
1179  window.activeWindows.push(this);
1180  }
1181  },
1182  close: function() {
1183  if (window.activeWindows != null) {
1184  window.activeWindows.pop();
1185  }
1186  }
1187  }).data("kendoDialog");
1188  }
1189  deleteDialog.open();
1190  }
1191 
1192  <?php
1193  /**
1194  * function scrollThread()
1195  * This is responsible for scrolling the message part of the thread on popup.
1196  */
1197  ?>
1198  function scrollThread() {
1199  var selector = $(".threadDiv");
1200  $(selector).height();
1201  $(selector).animate({scrollTop: $(selector).prop('scrollHeight')}, {duration: 2000});
1202  }
1203 
1204  <?php if (!$fromUserHub) { ?> var activeWindows = []; <?php } ?>
1205  $(document).ready(function() {
1206  init();
1207  <?php if (!$fromUserHub) { printClickOverlayEvent(); } ?>
1208  });
1209  </script>
1210  <script type="text/x-kendo-template" id="windowTemplate">
1211  # var editing = parentId != 0; #
1212  <div class="container-fluid hcu-template">
1213  <div id="editValidateDiv" class="formValidateDiv k-block k-error-colored row" style="display: none;"></div>
1214  # if (editing) { #
1215  <div class="row">
1216  <?php printThreadTemplate(); ?>
1217  </div>
1218  # } #
1219  <div class="row well well-sm hcuSpacer">
1220  <form id="secureMessageForm">
1221  <?php if (!$fromUserHub) {
1222  dialogPrintInputLine("User", "#: username #", "userInput", 0, "disabled", "text", true, "", false, false, true);
1223  }
1224  dialogPrintInputLine("Topic", "# if (editing) { # Re: #: subject # # } #", "topicInput", 0, "# if (editing) { # disabled # } #", "text", true, "", false, false, true); ?>
1225 
1226  <div class="row hcuSpacer"><label class="col-xs-3">Message</label><div class="col-xs-9">
1227  <textarea class="k-textbox hcu-all-100" id="messageInput" name="messageInput" rows="9" cols="75" wrap="physical"
1228  required data-required-msg="Message body cannot be blank" ></textarea>
1229  </div></div>
1230  </form>
1231  </div>
1232  <div class="hcu-edit-buttons k-state-default row">
1233  # if (editing) { #
1234  <span class="hcu-icon-delete">
1235  <a class="deleteBtn" href="\\#"><i class="fa fa-trash-o fa-lg"></i></a>
1236  </span>
1237  # } #
1238  <a class="cancelBtn" href="\\#">Cancel</a>
1239  &nbsp;&nbsp;&nbsp;
1240  <a class="sendBtn k-button k-primary" href="\\#"><i class="fa fa-check"></i>Send</a>
1241  </div>
1242  </div>
1243  </script>
1244  <script type="text/x-kendo-template" id="printTemplate">
1245  <div class="printDiv">
1246  <?php printThreadTemplate(true); ?>
1247  </div>
1248  </script>
1249  <script type="text/x-kendo-template" id="printTemplateTitle">
1250  Thread "#: subject #" with user #: username #
1251  </script>
1252  <script type="text/x-kendo-template" id="rowTemplate">
1253  # var inTD = origination == 1 ? "<td class='inOutTD'><div class='k-success-colored'>In</div></td>" : "<td class='inOutTD'><div class='k-info-colored'>Out</div></td>"; #
1254  <tr data-uid='#: uid #' class='# if (unread == "Y") { # unreadThread # } #'>#= inTD #<td>#: username #</td><td>#: subject #</td>
1255  <td>#= kendo.toString(date, "MM/dd/yyyy HH:mm") # #: timezone #</td></tr>
1256  </script>
1257  <?php if (!$fromUserHub) {
1258  printUserSearchTemplate();
1259  }
1260 
1261  if ($fromUserHub) { // The difference: NOT responsive because it is inside of a dialog.?>
1262  <div style="container-fluid">
1263  <div id="formValidateDiv" class="col-xs-12 k-block k-error-colored formValidateDiv" style="display:none;"></div>
1264  <div class="row hcuSpacer filterDiv userHub" id="filterDiv">
1265  <label class="col-xs-2">Type</label>
1266  <div class="col-xs-4">
1267  <span class="showOption" data-type="in"><span></span><a href="#">in</a></span> | <span class="showOption" data-type="out"><span></span><a href="#">out</a></span>
1268  | <span class="showOption" data-type="unread"><span></span><a href="#">unread</a></span> | <span class="showOption" data-type="all"><span></span><a href="#">all</a>
1269  </div>
1270  <label class="col-xs-2">Duration</label>
1271  <div class="col-xs-4">
1272  <span class="durationOption" data-type="1"><span></span><a href="#">30 days</a></span> | <span class="durationOption" data-type="2"><span></span><a href="#">60 days</a></span>
1273  | <span class="durationOption" data-type="3"><span></span><a href="#">all</a></span>
1274  </div>
1275  </div>
1276  <?php printSimple("<div id='grid' class='pointerGrid'></div>"); ?>
1277  </div>
1278  <?php } else { ?>
1279  <div style="container-fluid">
1280  <div id="formValidateDiv" class="col-xs-12 k-block k-error-colored formValidateDiv" style="display:none;"></div>
1281  <div class="hcuSpacer filterDiv standalone row" id="filterDiv">
1282  <div class="col-xs-12 col-sm-6 hcuSpacer">
1283  <label class="col-xs-4">User/topic</label>
1284  <div class="col-xs-8"><input type="text" class="k-input k-textbox hcu-all-100" id="findInput"></div>
1285  </div>
1286  <div class="col-xs-12 col-sm-6">
1287  <label class="col-xs-4">Type</label>
1288  <div class="col-xs-8">
1289  <span class="showOption" data-type="in"><span></span><a href="#">in</a></span> | <span class="showOption" data-type="out"><span></span><a href="#">out</a></span>
1290  | <span class="showOption" data-type="unread"><span></span><a href="#">unread</a></span> | <span class="showOption" data-type="all"><span></span><a href="#">all</a>
1291  </div>
1292  </div>
1293  <div class="col-xs-12 col-sm-6 hcuSpacer">
1294  <label class="col-xs-4">Duration</label>
1295  <div class="col-xs-8">
1296  <span class="durationOption" data-type="1"><span></span><a href="#">30 days</a></span>
1297  | <span class="durationOption" data-type="2"><span></span><a href="#">60 days</a></span>
1298  | <span class="durationOption" data-type="3"><span></span><a href="#">all</a></span>
1299  </div>
1300  </div>
1301  </div>
1302  <?php printSimple("<div id='grid' class='pointerGrid'></div>"); ?>
1303  </div>
1304  <?php } ?>
1305 
1306  <ul id="contextMenu">
1307  <li class="markReadLi">Mark Read</li>
1308  <li class="markUnreadLi">Mark Unread</li>
1309  <li class="openLi">Open</li>
1310  </ul>
1311 
1312  <form id="printForm" method="post" action="shell.prg" target="printWindow">
1313  <input type="hidden" name="shell" value="">
1314  <input type="hidden" name="title" value="">
1315  </form>
1316 </div>
1317 <?php }
1318 
1319 /**
1320  * function printThreadTemplate($actuallyPrint = false)
1321  * This will print the thread template which is the message part of the thread.
1322  *
1323  * @param boolean $actuallyPrint -- This is funny. I originally called this "print..." because it is printing javascript from PHP. However, this refers to the "print" function.
1324  */
1325 function printThreadTemplate($actuallyPrint = false) {
1326  if ($actuallyPrint) { ?>
1327  <div class="row">
1328  <?php printHubLabelBlock(array("User" => "#: username #", "Subject" => "#: subject #")); ?>
1329  </div>
1330  <div class="row">
1331  <hr>
1332  </div>
1333  <?php } ?>
1334  <div class="threadDiv row hcu-no-padding">
1335  # for (var i = 0; i != threadData.length; i++) { var row = threadData[i]; #
1336  <span class='k-block k-shadow # if (row.origination == 0) { # threadCU k-info-colored # } else { # k-success-colored threadMember # } #'>
1337  <span class='threadTitle'># if (row.origination == 0) { if (row.adminname == null) { # #: row.admin # # }
1338  else { # #: row.adminname # # } # Said # } else { # User # } #</span>
1339  <span class='threadDate'>#= kendo.toString(row.date, "MM/dd/yyyy HH:mm") # #: row.timezone #</span>
1340  <br>#= row.messagetext #
1341  </span>
1342  # } #
1343  </div>
1344 <?php }
Definition: User.php:7