Odyssey
surveyMntc.data
1 <?php
2 /**
3  * File: surveyMntc.prg
4  * Version 2 for survey maintenance and marketing messages using the favorite Kendo.
5  */
6 
7 
8 
9 /**
10  * function saveIntro($isMarketing, $dbh, $Cu)
11  * Data call to save the intro information for the survey. (Only available for survey maintenance, not marketing messages.)
12  *
13  * @param boolean $isMarketing -- if true, exits with an error message.
14  * @param integer $dbh -- the database connection
15  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
16  * @return array --
17  * $error -- Array of errors (if one were to exist)
18  * $code -- zero if no errors; non-zero for the existence of an error
19  * $sql -- list of sqls used
20  */
21 function saveIntro($isMarketing, $dbh, $Cu, $languageArray)
22 {
23  $parameters= array();
24  $sqls= array();
25 
26  try
27  {
28  if ($isMarketing)
29  throw new exception("Operation not available for marketing messages!", 8);
30  if ($languageArray == "")
31  throw new exception("Language array is invalid!", 1);
32  $languageArray= HCU_JsonDecode($languageArray);
33  if (!is_array($languageArray))
34  throw new exception("Language array is invalid!", 2);
35 
36  $validLanguages= array();
37  // Requery here to check for existence
38  $sql= "select language from culanguage";
39  $sqls[]= $sql;
40 
41  $sth= db_query($sql, $dbh);
42  if (!$sth)
43  throw new exception("Language query failed!", 5);
44 
45 
46  for($i=0; $row=db_fetch_array($sth, $i); $i++)
47  {
48  $validLanguages[]= $row[0];
49  }
50 
51  foreach($languageArray as $languageRow)
52  {
53  if (!HCU_array_key_exists("language", $languageRow) || !HCU_array_key_exists("surveyintro", $languageRow) || !HCU_array_key_exists("exists", $languageRow))
54  throw new exception("Language array is invalid!", 3);
55  if (!in_array($languageRow["exists"], array("Y", "N")))
56  throw new exception("Exists variable is invalid!", 4);
57  if (!in_array($languageRow["language"], $validLanguages))
58  throw new exception("Language is invalid!", 6);
59  }
60 
61  if (!db_work ($dbh, HOMECU_WORK_BEGIN))
62  throw new exception("begin query failed!", 9);
63 
64  foreach($languageArray as $languageRow)
65  {
66  $language= trim($languageRow["language"]);
67  $surveyintro= trim(strip_tags($languageRow["surveyintro"]));
68  $exists= $languageRow["exists"] == "Y";
69 
70  if ($exists)
71  {
72  $sql= $surveyintro == "" ? "delete from cusurveyintro where cu='$Cu' and language='" . prep_save($language, 5) . "'"
73  : "update cusurveyintro set surveyintro='" . prep_save($surveyintro) . "' where cu='$Cu' and language='" . prep_save($language, 5) . "'";
74  $sqls[]= $sql;
75  }
76  else if ($surveyintro != "")
77  {
78  $sql= "insert into cusurveyintro (cu, language, surveyintro) values ('$Cu', '" . prep_save($language, 5) . "', '" . prep_save($surveyintro) . "')";
79  $sqls[]= $sql;
80  }
81 
82  $sth= db_query($sql, $dbh);
83  if (!$sth)
84  throw new exception("surveyinto update failed!", 110);
85  }
86 
87  if (!db_work($dbh, HOMECU_WORK_COMMIT))
88  throw new exception("commit work failed!", 111);
89  }
90  catch(exception $e)
91  {
92  if ($e->getCode() >= 100)
93  db_work($dbh, HOMECU_WORK_ROLLBACK); // Got greater problems if this fails.
94 
95  return array("error" => array($e->getMessage()), "code" => $e->getCode(), "sql" => $sqls);
96  }
97  return array("error" => array(), "code" => 0, "sql" => $sqls);
98 }
99 
100 /**
101  * function readIntro($isMarketing, $dbh, $Cu)
102  * Reads the intro information from the database
103  *
104  * @param boolean $isMarketing -- if true, exits with an error message.
105  * @param integer $dbh -- the database connection
106  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
107  * @return array --
108  * $error -- Array of errors (if one were to exist)
109  * $code -- zero if no errors; non-zero for the existence of an error
110  * $sql -- list of sqls used
111  * $languageArray -- data for the tab strip
112  */
113 function readIntro($isMarketing, $dbh, $Cu)
114 {
115  $sqls= array();
116  try
117  {
118  if ($isMarketing)
119  throw new exception("Operation not available for marketing messages!", 2);
120  $sql= "select l.description, l.language, i.surveyintro from culanguage l left join cusurveyintro i on l.language = i.language and i.cu='$Cu' order by l.language";
121  $sqls[]= $sql;
122  $sth= db_query($sql, $dbh);
123  if (!$sth)
124  throw new exception("select query failed!", 1);
125  $languageArray= array();
126  for($i=0; $row= db_fetch_assoc($sth, $i); $i++)
127  {
128  $surveyintro= trim($row["surveyintro"]);
129  $row["exists"]= $surveyintro != "";
130  $row["surveyintro"]= $surveyintro;
131  $row["description"]= isset($row["description"]) ? trim($row["description"]) : "";
132  $row["language"]= isset($row["language"]) ? trim($row["language"]) : "";
133  $row["blank"]= " ";
134  $row["index"]= $i;
135  $languageArray[]= $row;
136  }
137  }
138  catch(exception $e)
139  {
140  return array("code" => $e->getCode(), "error" => array($e->getMessage()), "sql" => $sqls);
141  }
142  return array("code" => 0, "error" => array(), "sql" => $sqls, "languageArray" => $languageArray);
143 }
144 
145 /**
146  * function readResultDetails($isMarketing, $dbh, $Cu)
147  * Reads the data for the result details (for if/when you wish to see which members selected such a stupid answer.)
148  *
149  * @param boolean $isMarketing -- if true, exits with an error message.
150  * @param integer $dbh -- the database connection
151  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
152  * @return array --
153  * $error -- Array of errors (if one were to exist)
154  * $code -- zero if no errors; non-zero for the existence of an error
155  * $sql -- list of sqls used
156  * $topData -- data for the survey id, Cu, and answer the page is for
157  * $bottomData -- the dirtbag report of all the members that selected such a stupid answer
158  */
159 function readResultDetails($isMarketing, $dbh, $Cu, $surveyid, $language, $answerid)
160 {
161  $sqls= array();
162 
163  $surveyid= isset($surveyid) ? intval($surveyid) : 0;
164  $answerid= isset($answerid) ? intval($answerid) : 0;
165  $language= isset($language) ? trim($language) : "";
166 
167  try
168  {
169  if ($isMarketing)
170  throw new exception("Operation not available for marketing messages!", 2);
171 
172  $sql= "with subset as (select d.answerid, d.surveyid, d.language, c.cu as saysfound, c.user_id, c.user_name, c.optin, c.email, d.answertext as answer, q.question, m.surveyname,
173  m.startdate, m.stopdate from cusurveydetail d
174  inner join cusurveymaster m on d.surveyid = m.surveyid and d.cu = m.cu and d.surveyid= $surveyid and d.cu= '$Cu' and d.language= '" . prep_save($language, 5) . "'
175  inner join cusurveyquest q on d.surveyid = q.surveyid and d.cu = q.cu and d.language = q.language
176  left join (select s.cu, s.answerid, s.surveyid, s.language, u.user_name, u.egenl_flag as optin, u.email, u.user_id from cusurveysays s
177  inner join ${Cu}user u on s.user_id= u.user_id) c on d.surveyid= c.surveyid and d.cu = c.cu and d.language = c.language and d.answerid= c.answerid)
178  select a.*, coalesce(b.votes, 0) as votes, coalesce(c.totalvotes, 0) as totalvotes
179  from (select * from subset where answerid= $answerid) a
180  cross join (select count(saysfound) from subset where answerid= $answerid) b(votes)
181  cross join (select count(saysfound) from subset) c(totalvotes)";
182  $sqls[]= $sql;
183  $sth= db_query($sql, $dbh);
184  if (!$sth)
185  throw new exception("Subset query failed!", 1);
186 
187  $first= true;
188  $topData= array();
189  $bottomData= array();
190  for($i=0; $row= db_fetch_assoc($sth, $i); $i++)
191  {
192  if ($first)
193  {
194  $startdate= new DateTime($row["startdate"]);
195  $stopdate= new DateTime($row["stopdate"]);
196  $row["range"]= $startdate->format("m/d/Y") . " - " . $stopdate->format("m/d/Y");
197  $row["percentage"]= $row["totalvotes"] == 0 ? 0 : $row["votes"] / $row["totalvotes"];
198  $topData[]= $row;
199 
200  unset($topData[0]["user_id"]);
201  unset($topData[0]["user_name"]);
202  unset($topData[0]["optin"]);
203  unset($topData[0]["email"]);
204  unset($topData[0]["startdate"]);
205  unset($topData[0]["stopdate"]);
206  $first= false;
207  }
208 
209  if (isset($row["saysfound"]))
210  $bottomData[]= array("user_id" => $row["user_id"], "user_name" => $row["user_name"], "optin" => trim($row["optin"]) == "Y", "email" => $row["email"]);
211  }
212  }
213  catch (Exception $e)
214  {
215  return array("sql" => $sqls, "error" => array($e->getMessage()), "code" => $e->getCode());
216  }
217  return array("sql" => $sqls, "error" => array(), "code" => 0, "topData" => $topData, "bottomData" => $bottomData);
218 }
219 
220 /**
221  * function readResults($isMarketing, $dbh, $Cu)
222  * Reads the data for the results of a particular survey or any other survey modes: "all", "past", "present", "future", "draft".
223  *
224  * @param boolean $isMarketing -- if true, exits with an error message.
225  * @param integer $dbh -- the database connection
226  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
227  * @return array --
228  * $error -- Array of errors (if one were to exist)
229  * $code -- zero if no errors; non-zero for the existence of an error
230  * $sql -- list of sqls used
231  * $data -- data in an usable format: Array of surveys which have an array of languages which have an array of answers
232  */
233 function readResults($isMarketing, $dbh, $Cu, $mode, $surveyid)
234 {
235  $parameters= array();
236  $sqls= array();
237 
238  try
239  {
240  if ($isMarketing)
241  throw new exception("Operation not available for marketing messages!", 3);
242 
243  $masterSubquery= getMasterSubquery($Cu, false, $mode, $surveyid);
244  $sql= "select a.surveyid, a.surveyname, a.startdate, a.stopdate, l.description, l.language, b.answerid, b.count, q.question, b.answertext
245  from ($masterSubquery) a
246  inner join (select d.surveyid, d.answerid, d.language, d.answertext, count(s.oid) as count from cusurveydetail d
247  left join cusurveysays s on d.cu = s.cu and d.surveyid = s.surveyid and d.answerid = s.answerid and d.language = s.language and d.cu='$Cu'
248  group by d.surveyid, d.answerid, d.language, d.answertext) as b on a.surveyid = b.surveyid
249  inner join culanguage l on b.language = l.language
250  inner join cusurveyquest q on b.language = q.language and b.surveyid = q.surveyid and q.cu= '$Cu' order by a.startdate desc, a.stopdate desc, a.surveyid, l.language, b.answerid";
251  $sqls[]= $sql;
252 
253  $sth= db_query($sql, $dbh);
254  if (!$sth)
255  throw new exception("Count query failed!", 2);
256 
257  $map= array();
258  $sort= 0;
259  for($i=0; list($surveyid, $surveyname, $startdate, $stopdate, $description, $language, $answerid, $numVotes, $question, $answer) = db_fetch_array($sth, $i); $i++)
260  {
261  $details= array();
262 
263  $startdate= new DateTime($startdate);
264  $stopdate= new DateTime($stopdate);
265  $range= $startdate->format("m/d/Y") . " - " . $stopdate->format("m/d/Y");
266 
267  if (!isset($map[$surveyid]))
268  $map[$surveyid]= array("surveyid" => $surveyid, "surveyname" => $surveyname, "range" => $range, "details" => array(), "sort" => $sort++);
269  if (!isset($map[$surveyid]["details"][$language]))
270  $map[$surveyid]["details"][$language]= array("description" => $description, "language" => $language, "total" => 0, "question" => $question, "answers" => array());
271  $map[$surveyid]["details"][$language]["answers"][]= array("answerid" => $answerid, "text" => $answer, "count" => $numVotes);
272  $map[$surveyid]["details"][$language]["total"]+= $numVotes;
273  }
274 
275  $colorList= array('Green','Red','Blue','Orange','Purple');
276  $clLength= count($colorList);
277  foreach($map as $surveyid => $hRow)
278  {
279  foreach($hRow["details"] as $language => $iRow)
280  {
281  shuffle($colorList);
282  foreach($iRow["answers"] as $j => $jRow)
283  {
284  $map[$surveyid]["details"][$language]["answers"][$j]["percentage"]= $iRow["total"] == 0 ? 0 : round(floatval($jRow["count"]) / intval($iRow["total"]), 2);
285  $map[$surveyid]["details"][$language]["answers"][$j]["color"]= $colorList[$j % $clLength];
286  }
287  }
288  }
289 
290  // Need to convert to arrays for display
291  $map= array_values($map);
292  for($i=0, $length=count($map); $i != $length; $i++)
293  {
294  $map[$i]["details"]= array_values($map[$i]["details"]);
295  }
296  }
297  catch (Exception $e)
298  {
299  return array("sqls" => $sqls, "error" => array($e->getMessage()), "code" => $e->getCode());
300  }
301 
302  return array("sqls" => $sqls, "error" => array(), "code" => 0, "data" => $map);
303 }
304 
305 /**
306  * function save($isMarketing, $dbh, $Cu, $extendDateOnly=false)
307  * Saves the survey depending on several factors: surveyid: if zero, then it is a create; $isMarketing: surveytype is saved accordingly;
308  * $extendDateOnly: if true, then very little is being saved
309  *
310  * @param boolean $isMarketing -- If true, doesn't validate and save answers. Also, affects the surveytype when creating a new one.
311  * @param integer $dbh -- the database connection
312  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
313  * @param boolean $extendDateOnly -- if true, will only save $startdate, $stopdate, $dontshow. It also will not clear the cusurveysays table for the surveyid.
314  * @return array --
315  * $error -- Array of errors (if one were to exist)
316  * $code -- zero if no errors; non-zero for the existence of an error
317  * $sql -- list of sqls used
318  */
319 function save($isMarketing, $dbh, $Cu, $surveyid, $startdate, $stopdate, $surveyname, $surveytitle, $runstat, $employee, $incBalances, $dontshow, $questions, $answers, $extendDateOnly=false)
320 {
321  $sqls= array();
322 
323  $surveyid= isset($surveyid) ? intval($surveyid) : 0;
324  $startdate= isset($startdate) ? trim($startdate) : "";
325  $stopdate= isset($stopdate) ? trim($stopdate) : "";
326  $surveyname= isset($surveyname) ? trim($surveyname) : "";
327  $surveytitle= isset($surveytitle) ? trim($surveytitle) : "";
328  $employee= isset($employee) ? strtoupper(trim($employee)) : "";
329  $incBalances= isset($incBalances) ? strtoupper(trim($incBalances)) : "";
330  $dontshow= isset($dontshow) ? strtoupper(trim($dontshow)) : "";
331  $questions= isset($questions) ? trim($questions) : "";
332  $answers= isset($answers) ? trim($answers) : "";
333 
334  try
335  {
336  $dateA= DateTime::createFromFormat("Y-m-d", $startdate);
337  if (!$dateA)
338  throw new exception("Start date is invalid.", 1);
339  if ($dateA->format("Y-m-d") != $startdate)
340  throw new exception("Start date is invalid.", 2);
341  $dateB= DateTime::createFromFormat("Y-m-d", $stopdate);
342  if (!$dateB)
343  throw new exception("Stop date is invalid.", 3);
344  if ($dateB->format("Y-m-d") != $stopdate)
345  throw new exception("Stop date is invalid.", 4);
346  if (!in_array($dontshow, array("Y", "N")))
347  throw new exception("Don't Show is invalid.", 9);
348 
349  if ($dateB < $dateA)
350  throw new exception("Stop date need to be after start date.", 19);
351 
352  if (!$extendDateOnly)
353  {
354  if (!is_numeric($runstat))
355  throw new exception("Runstat is invalid.", 5);
356  if (!in_array($runstat, array(0,1)))
357  throw new exception("Runstat is invalid.", 6);
358  if (!in_array($employee, array("Y", "N")))
359  throw new exception("Employee is invalid.", 7);
360  if (!in_array($incBalances, array("Y", "N")))
361  throw new exception("IncBalances is invalid.", 8);
362  }
363 
364  $surveytype= $isMarketing ? 1 : 0;
365 
366  if (!db_work ($dbh, HOMECU_WORK_BEGIN))
367  throw new exception("begin query failed.", 227);
368 
369  if ($surveyid == 0)
370  {
371  if ($extendDateOnly)
372  throw new exception("Can only extend dates of the existing.", 118);
373 
374  $sql= "select nextval('cusurveymaster_surveyid_seq')";
375  $sqls[]= $sql;
376 
377  $sth= db_query($sql, $dbh);
378  if (!$sth)
379  throw new exception("Nextval query failed.", 212);
380  if (db_num_rows($sth) == 0)
381  throw new exception("Nextval query failed.", 213);
382  list($surveyid)= db_fetch_array($sth, 0);
383  $sql= "insert into cusurveymaster (surveyid, cu, startdate, stopdate, surveyname, surveytitle, qstyle, runstat, employee, inc_balances, surveytype, dontshow)
384  values ($surveyid, '$Cu', '$startdate','$stopdate','" . prep_save($surveyname, 50) . "','" . prep_save($surveytitle) . "', 3, $runstat, '$employee', '$incBalances',
385  $surveytype, '$dontshow')";
386  }
387  else
388  {
389  $sql= $extendDateOnly ? "update cusurveymaster set startdate= '$startdate', stopdate='$stopdate', dontshow='$dontshow', surveyname='" . prep_save($surveyname, 50) . "'
390  where cu='$Cu' and surveyid=$surveyid"
391  : "update cusurveymaster set startdate= '$startdate', stopdate='$stopdate', surveyname='" . prep_save($surveyname, 50) . "', surveytitle='" . prep_save($surveytitle)
392  . "', runstat= $runstat, employee= '$employee', inc_balances='$incBalances', dontshow='$dontshow' where cu='$Cu' and surveyid=$surveyid";
393  }
394 
395  $sth= db_query($sql, $dbh);
396  if (!$sth)
397  throw new exception("insert/update cusurveymaster failed.", 228);
398 
399  if (!$extendDateOnly)
400  {
401  $validLanguages= array();
402  if ($questions != "" || $answers != "")
403  {
404  // Requery here to check for existence
405  $sql= "select language from culanguage";
406  $sqls[]= $sql;
407 
408  $sth= db_query($sql, $dbh);
409  if (!$sth)
410  throw new exception("Language query failed.", 214);
411 
412 
413  for($i=0; $row=db_fetch_array($sth, $i); $i++)
414  {
415  $validLanguages[]= $row[0];
416  }
417  }
418 
419  $questionExists= array("english" => false, "spanish" => false, "polish" => false);
420  $questionsForSQL= array();
421  if ($questions != "")
422  {
423  $questions= HCU_JsonDecode($questions);
424  if (!is_array($questions))
425  throw new exception($isMarketing ? "Messages weren't properly encoded." : "Questions weren't properly encoded.", 110);
426  foreach($questions as $questionRow)
427  {
428  $question= trim($questionRow["question"]);
429  $language= trim($questionRow["language"]);
430  $question= $isMarketing ? strip_tags(str_replace(array("<!--", "-->"), "", $question), "<b><i><p><a><li><ol><ul><em><br><tt><strong><blockquote><img><span><div><style>")
431  : strip_tags($question);
432 
433  if (!in_array($language, $validLanguages))
434  throw new exception("Language is not valid.", 115);
435  switch($language)
436  {
437  case "en_US":
438  $questionExists["english"]= $question != "";
439  break;
440  case "es_US":
441  $questionExists["spanish"]= $question != "";
442  break;
443  case "pl_US":
444  $questionExists["polish"]= $question != "";
445  break;
446  }
447 
448  $questionsForSQL[]= "('" . prep_save($language, 5) . "', '" . prep_save($question) . "')";
449  }
450  }
451 
452  $sql= "delete from cusurveyquest where cu='$Cu' and surveyid='$surveyid'";
453  $sqls[]= $sql;
454  $sth= db_query($sql, $dbh);
455  if (!$sth)
456  throw new exception("delete cusurveyquest failed.", 229);
457 
458  if (count($questionsForSQL) > 0)
459  {
460  $sql= "insert into cusurveyquest (cu, surveyid, language, question) select '$Cu', $surveyid, a.* from (values " . implode(", ", $questionsForSQL) . ") as a";
461  $sqls[]= $sql;
462  $sth= db_query($sql, $dbh);
463  if (!$sth)
464  throw new exception("insert cusurveyquest failed.", 230);
465  }
466 
467 
468  if (!$questionExists["english"])
469  throw new exception("Please include a " . ($isMarketing ? "message body" : "question") . " for English.", 121);
470 
471  if (!$isMarketing)
472  {
473  $answerExists= array("english" => false, "spanish" => false, "polish" => false);
474  $answersForSQL= array();
475  if ($answers != "")
476  {
477  $answers= HCU_JsonDecode($answers);
478  if (!is_array($answers))
479  throw new exception("Answers weren't properly encoded.", 116);
480 
481  $index= 1;
482  foreach($answers as $answerRow)
483  {
484  $english= trim($answerRow["english"]);
485  $polish= trim($answerRow["polish"]);
486  $spanish= trim($answerRow["spanish"]);
487 
488  if ($english == "")
489  {
490  if ($polish == "" && $spanish == "")
491  continue; // Skip empty row
492  throw new exception("English answer must be populated if either the polish or spanish answers are populated.", 122);
493  }
494 
495  $answersForSQL[]= "($index, 'en_US', '" . prep_save($english, 255) . "')";
496 
497  if ($polish != "")
498  {
499  $answerExists["polish"]= true;
500  if (!$questionExists["polish"])
501  throw new exception("Polish question is required when there are one or more Polish answers.", 123);
502  $answersForSQL[]= "($index, 'pl_US', '" . prep_save($polish, 255) . "')";
503  }
504 
505  if ($spanish != "")
506  {
507  $answerExists["spanish"]= true;
508  if (!$questionExists["spanish"])
509  throw new exception("Spanish question is required when there are one or more Spanish answers.", 124);
510  $answersForSQL[]= "($index, 'es_US', '" . prep_save($spanish, 255) . "')";
511  }
512  $index++;
513  }
514  }
515  $sql= "delete from cusurveydetail where cu='$Cu' and surveyid='$surveyid'";
516  $sqls[]= $sql;
517  $sth= db_query($sql, $dbh);
518  if (!$sth)
519  throw new exception("delete cusurveydetail failed.", 231);
520 
521  if (count($answersForSQL) > 0)
522  {
523  $sql= "insert into cusurveydetail (cu, surveyid, slidermin, slidermax, answerid, language, answertext)
524  select '$Cu', $surveyid, 0, 0, a.* from (values " . implode(", ", $answersForSQL) . ") as a";
525  $sqls[]= $sql;
526  $sth= db_query($sql, $dbh);
527  if (!$sth)
528  throw new exception("insert cusurveydetail failed!", 132);
529  }
530 
531 
532  if ($questionExists["spanish"] && !$answerExists["spanish"])
533  throw new exception("One or more Spanish answers are required when there is a Spanish question.", 125);
534  if ($questionExists["polish"] && !$answerExists["polish"])
535  throw new exception("One or more Polish answers are required when there is a Polish question.", 126);
536  }
537 
538  // Delete results
539  $sql= "delete from cusurveysays where surveyid='$surveyid' and cu='$Cu'";
540  $sqls[]= $sql;
541  $sth= db_query($sql, $dbh);
542  if (!$sth)
543  throw new exception("delete cusurveysays failed!", 233);
544  } // End !$extendDateOnly
545 
546  if (!db_work($dbh, HOMECU_WORK_COMMIT))
547  throw new exception("commit work failed!", 234);
548  }
549  catch (Exception $e)
550  {
551  if ($e->getCode() >= 100)
552  db_work($dbh, HOMECU_WORK_ROLLBACK); // Got greater problems if this fails.
553 
554  return array("sql" => $sqls, "error" => array($e->getCode >= 200 ? "Save failed with code: " . $e->getCode() . "." : $e->getMessage()), "code" => $e->getCode());
555  }
556  return array("sql" => $sqls, "error" => array(), "code" => 0);
557 }
558 
559 /**
560  * function getMasterSubquery($Cu, $isMarketing, $mode="all", $surveyid=0)
561  * This will get the master subquery. SQL and logic was copied in several places so I made this function
562  *
563  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
564  * @param boolean $isMarketing -- affects the surveytype limitation for the query
565  * @param string $mode --
566  * "all" -- No additional limit (still have limits for the Cu and $isMarketing). Function can be called like getMasterSubquery($Cu, $isMarketing). In that case, this is assumed.
567  * "single" -- Filters to a particular surveyid. Data calls don't have to specify the $mode parameter. In that case, this is assumed.
568  * "past", "present", "future" -- If the survey is not a draft and the survey is past, present, or in the future.
569  * "draft" -- If the survey is a draft.
570  * @param integer $surveyid -- Only used for $mode of single to limit the SQL.
571  * @return string -- a select statement of the master table with the stipulations according to mode, Cu, and isMarketing.
572  */
573 function getMasterSubquery($Cu, $isMarketing, $mode="all", $surveyid=0)
574 {
575  $masterWhere= array("cu='$Cu'", $isMarketing ? "surveytype = 1" : "coalesce(surveytype, 0) = 0");
576  switch($mode)
577  {
578  case "all":
579  break;
580  case "present":
581  $masterWhere[]= "runstat = 1";
582  $masterWhere[]= "now() between startdate and stopdate";
583  break;
584  case "past":
585  $masterWhere[]= "runstat = 1";
586  $masterWhere[]= "startdate <= stopdate"; // Don't want to get invalid surveys
587  $masterWhere[]= "now() > stopdate";
588  break;
589  case "future":
590  $masterWhere[]= "runstat = 1";
591  $masterWhere[]= "startdate <= stopdate"; // Don't want to get invalid surveys
592  $masterWhere[]= "now() < startdate";
593  break;
594  case "draft":
595  $masterWhere[]= "runstat = 0";
596  break;
597  case "single":
598  case "":
599  if (intval($surveyid) == 0)
600  throw new exception("Survey needs to be defined.", 2);
601  $masterWhere[]= "surveyid = $surveyid";
602  break;
603  default:
604  throw new exception("Mode is invalid.", 1);
605  }
606 
607  return "select surveyid, startdate, stopdate, surveyname, runstat, employee, dontshow, inc_balances, surveytitle from cusurveymaster"
608  . (count($masterWhere) > 0 ? " where " . implode(" and ", $masterWhere) : "");
609 }
610 
611 /**
612  * function readView($isMarketing, $dbh, $Cu, $includeMasterData=false)
613  * This will read the view (For the surveyView popup and extend dates)
614  *
615  * @param boolean $isMarketing -- Affects the surveytype limitation and if true, removes the surveyintro and answers from the query and resulting data.
616  * @param integer $dbh -- the database connection
617  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
618  * @param boolean $includeMasterData -- if true, more data will be extracted from the master table plus the output will be different
619  * @return array --
620  * $error-- array of zero or one errors
621  * $code-- zero if there is an error; non-zero if there are no errors.
622  * $sql-- array of sqls used
623  * $data-- If $includeMasterData, then it will return #2. Otherwise, it will return #1. If $isMarketing, answers array is not added/populated.
624  * 1) {languages: [{language, description, surveyintro, title, surveys: [{surveyid, question, answers: [{id, text}, ...]}, ...]}, ...]}
625  * 2) {surveys: [{surveyid, question, startdate, stopdate, surveytitle, surveyname, isDraft, affectsEmployees, isPopup, dontShow,
626  * languages: [{language, description, surveyintro, question, answers: [{id, text}, ...]}, ...]}, ...]}
627  */
628 function readView($isMarketing, $dbh, $Cu, $surveyid, $mode, $includeMasterData=false)
629 {
630  $sqls= array();
631 
632  $surveyid= isset($surveyid) ? intval($surveyid) : 0;
633  $mode= isset($mode) ? trim($mode) : "";
634 
635  try
636  {
637  $masterSubquery= getMasterSubquery($Cu, $isMarketing, $mode, $surveyid);
638  $sql= "select a.pname, q.question, l.language, l.description, " . (!$isMarketing ? "i.surveyintro, d.answerid, d.answertext, " : "")
639  . ($includeMasterData ? "m.* " : "m.surveyid ") . "from cuadmin a inner join culanguage l on a.cu= '$Cu' cross join ($masterSubquery) m
640  left join cusurveyquest q on a.cu = q.cu and m.surveyid = q.surveyid and l.language = q.language "
641  . (!$isMarketing ? "left join cusurveydetail d on a.cu = d.cu and l.language = d.language and m.surveyid = d.surveyid
642  left join cusurveyintro i on a.cu= i.cu and l.language = i.language " : "")
643  . "order by l.language, m.stopdate, m.surveyid" . (!$isMarketing ? ", d.answerid" : "");
644  $sqls[]= $sql;
645  $sth= db_query($sql, $dbh);
646 
647  if (!$sth)
648  throw new exception("Query failed!", 1);
649 
650  $data= array();
651  $first= true;
652  for($i=0; $row= db_fetch_assoc($sth, $i); $i++)
653  {
654  $language= isset($row["language"]) ? trim($row["language"]) : "";
655  $description= isset($row["description"]) ? trim($row["description"]) : "";
656  $surveyintro= isset($row["surveyintro"]) ? trim($row["surveyintro"]) : "";
657  $question= isset($row["question"]) ? trim($row["question"]) : "";
658  $answer= isset($row["answertext"]) ? trim($row["answertext"]) : "";
659 
660  if ($includeMasterData)
661  {
662  if (!isset($data[$row["surveyid"]]))
663  {
664  $surveyRow= array("surveyid" => $row["surveyid"], "question" => trim($row["question"]), "languages" => array(), "startdate" => $row["startdate"],
665  "surveytitle" => $row["surveytitle"], "surveyname" => $row["surveyname"], "stopdate" => $row["stopdate"], "runstat" => $row["runstat"],
666  "employee" => $row["employee"], "dontshow" => $row["dontshow"], "inc_balances" => $row["inc_balances"]);
667  modifyMasterData($surveyRow);
668  $data[$row["surveyid"]]= $surveyRow;
669  }
670  if ($question != "" || $answer != "")
671  {
672  if (!isset($data[$row["surveyid"]]["languages"][$row["language"]]))
673  $data[$row["surveyid"]]["languages"][$row["language"]]= array("language" => $language, "description" => $description, "surveyintro" => $surveyintro,
674  "answers" => array(), "question" => $question);
675  if (!$isMarketing && isset($row["answerid"]))
676  $data[$row["surveyid"]]["languages"][$row["language"]]["answers"][]= array("id" => $row["answerid"], "text" => $answer);
677  }
678  }
679  else
680  {
681  if (!isset($data[$row["language"]]))
682  $data[$row["language"]]= array("language" => $language, "description" => $description, "surveyintro" => $surveyintro,
683  "title" => $language == "en_US" ? "" : $description, "surveys" => array());
684  if ($question != "" || $answer != "")
685  {
686  if (!isset($data[$row["language"]]["surveys"][$row["surveyid"]]))
687  {
688  $surveyRow= array("surveyid" => $row["surveyid"], "question" => $question, "answers" => array());
689  $data[$row["language"]]["surveys"][$row["surveyid"]]= $surveyRow;
690  }
691  if (!$isMarketing && isset($row["answerid"]))
692  $data[$row["language"]]["surveys"][$row["surveyid"]]["answers"][]= array("id" => $row["answerid"], "text" => $answer);
693  }
694  }
695  }
696 
697  $data= array_values($data);
698  for($i=0, $iCount= count($data); $i != $iCount; $i++)
699  {
700  if ($includeMasterData)
701  $data[$i]["languages"]= array_values($data[$i]["languages"]);
702  else
703  $data[$i]["surveys"]= array_values($data[$i]["surveys"]);
704  }
705  }
706  catch(exception $e)
707  {
708  return array("error" => array($e->getMessage()), "code" => $e->getCode(), "sql" => $sqls);
709  }
710  return array("error" => array(), "code" => 0, "sql" => $sqls, "data" => $data);
711 }
712 
713 /**
714  * function readNew($isMarketing, $dbh, $Cu)
715  * This is called on the edit page when the surveyid is zero to create. It needs only to get the languages from the database.
716  *
717  * @param integer $dbh -- the database connection
718  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
719  * @return array --
720  * $error-- array of zero or one errors
721  * $code-- zero if there is an error; non-zero if there are no errors.
722  * $sql-- array of sqls used
723  * $questionData-- array of languages and an empty string for the question in that language.
724  */
725 function readNew($dbh, $Cu)
726 {
727  try
728  {
729  $sql= "select l.description, l.language, '' as question from culanguage l order by l.language";
730  $sqls[]= $sql;
731 
732  $sth= db_query($sql, $dbh);
733  if (!$sth)
734  throw new exception("Survey question query failed!", 3);
735  $questionData= array();
736  for($i=0; $row= db_fetch_assoc($sth, $i); $i++)
737  {
738  $row["exists"]= false;
739  $questionData[]= $row;
740  }
741  }
742  catch(exception $e)
743  {
744  return array("sql" => $sqls, "error" => array($e->getMessage()), "code" => $e->getCode());
745  }
746  return array("sql" => $sqls, "error" => array(), "code" => 0, "questionData" => $questionData);
747 }
748 
749 /**
750  * function modifyMasterData(&$row)
751  * Changes the boolean values to actual boolean values for display.
752  *
753  * @param {} $row -- Represents the master row and is directly updated.
754  */
755 function modifyMasterData(&$row)
756 {
757  $row["isDraft"]= intval($row["runstat"]) == 0;
758  $row["affectsEmployees"]= trim($row["employee"]) == "Y";
759  $row["isPopup"]= trim($row["inc_balances"]) != "Y";
760  $row["dontShow"]= trim($row["dontshow"]) == "Y";
761  unset($row["runstat"]);
762  unset($row["employee"]);
763  unset($row["inc_balances"]);
764  unset($row["dontshow"]);
765 }
766 
767 /**
768  * function readEdit($isMarketing, $dbh, $Cu, $includeMainInfo=true, $includeHasResults=true)
769  * Reads the data of a surveyid dependent on $isMarketing
770  *
771  * @param boolean $isMarketing -- Affects the surveytype limitation. If false, queries for the answers to the survey. Affects what is returned.
772  * @param integer $dbh -- the database connection
773  * @param string $Cu -- the credit union code uppercase (from high above; it's like manna)
774  * @return array --
775  * $error-- array of zero or one errors
776  * $code-- zero if there is an error; non-zero if there are no errors.
777  * $sql-- array of sqls used
778  * $questionData-- array of languages and the question in that language. If there isn't a record for the question in that language, then the question will be an empty string.
779  * $masterData-- The top-level data for the surveyid.
780  * $hasResults-- If $isMarketing, then this is if the survey is not a draft. If !$isMarketing, then this is if there is a record in the cusurveysays table for the survey.
781  * $answerData-- Array of the possible answers (only for !$isMarketing)
782  * $nextAnswerRowid-- the next rowid when creating a new answer (only for !$isMarketing)
783  */
784 function readEdit($isMarketing, $dbh, $Cu, $surveyid, $includeMainInfo=true, $includeHasResults=true)
785 {
786  $sqls= array();
787  $surveyid= trim($surveyid) ? intval($surveyid) : 0;
788 
789  $hasResults= false;
790  try
791  {
792  if ($includeMainInfo)
793  {
794  $sql= getMasterSubquery($Cu, $isMarketing, "single", $surveyid);
795  $sqls[]= $sql;
796 
797  $sth= db_query($sql, $dbh);
798  if (!$sth)
799  throw new exception("Survey master query failed.", 101);
800  if (db_num_rows($sth) == 0)
801  throw new exception("Survey master record not found.", 102);
802 
803  $masterData= db_fetch_assoc($sth, 0);
804  if ($includeHasResults && $isMarketing)
805  $hasResults= intval($masterData["runstat"]) != 0;
806  modifyMasterData($masterData);
807  }
808 
809  $sql= "select trim(l.description) as description, trim(l.language) as language, trim(coalesce(q.question, '')) as question, q.cu from culanguage l
810  left join cusurveyquest q on l.language = q.language and q.cu= '$Cu' and q.surveyid= '$surveyid' order by l.language";
811  $sqls[]= $sql;
812 
813  $sth= db_query($sql, $dbh);
814  if (!$sth)
815  throw new exception("Survey question query failed.", 103);
816 
817  $hasSpanish=false;
818  $hasPolish=false;
819  $questionData= array();
820  for($i=0; $row= db_fetch_assoc($sth, $i); $i++)
821  {
822  $row["exists"]= isset($row["cu"]);
823  unset($row["cu"]);
824 
825  switch(trim($row["language"]))
826  {
827  case "pl_US":
828  $hasPolish= $row["exists"] && $row["question"] != "";
829  break;
830  case "es_US":
831  $hasSpanish= $row["exists"] && $row["question"] != "";
832  break;
833  }
834  $questionData[]= $row;
835  }
836 
837 
838  if (!$isMarketing)
839  {
840  $sql= "select d.answerid, d.answertext, d.language from cusurveydetail d where d.surveyid='$surveyid' and cu='$Cu' order by d.answerid";
841  $sqls[]= $sql;
842 
843  $sth= db_query($sql, $dbh);
844  if (!$sth)
845  throw new exception("Survey detail query failed.", 104);
846 
847  $answerData= array();
848  for($i=0; $row= db_fetch_assoc($sth, $i); $i++)
849  {
850  $answerid= intval($row["answerid"]);
851  $text= trim($row["answertext"]);
852  if (!isset($answerData[$answerid]))
853  $answerData[$answerid]= array("rowid" => $i+1, "polish" => "", "spanish" => "", "english" => "");
854  switch($row["language"])
855  {
856  case "pl_US":
857  $answerData[$answerid]["polish"]= $text;
858  $hasPolish= true;
859  break;
860  case "es_US":
861  $answerData[$answerid]["spanish"]= $text;
862  $hasSpanish= true;
863  break;
864  case "en_US":
865  case "":
866  $answerData[$answerid]["english"]= $text;
867  break;
868  default:
869  throw new exception("Only English, Polish, and Spanish are allowed.", 6);
870  }
871  }
872  $nextAnswerRowid= $i+1;
873 
874  if ($includeHasResults)
875  {
876  $sql= "select count(*) from cusurveysays s where s.surveyid= $surveyid and cu='$Cu'";
877  $sth= db_query($sql, $dbh);
878  if (!$sth)
879  throw new exception("Count query failed!", 5);
880  $hasResults= intval(db_fetch_array($sth, 0)[0]) > 0;
881  }
882  }
883  }
884  catch (Exception $e)
885  {
886  return array("sql" => $sqls, "error" => array($e->getCode() >= 200 ? "Display failed with code: " . $e->getCode() . "." : $e->getMessage()), "code" => $e->getCode());
887  }
888  $returnArray= array("sql" => $sqls, "error" => array(), "code" => 0, "masterData" => $masterData, "questionData" => $questionData, "hasResults" => $includeHasResults && $hasResults,
889  "hasSpanish" => $hasSpanish, "hasPolish" => $hasPolish);
890  if (!$isMarketing)
891  {
892  $returnArray["answerData"]= array_values($answerData);
893  $returnArray["nextAnswerRowid"]= $nextAnswerRowid;
894  }
895  return $returnArray;
896 }
897 
898 /**
899  * function delete($isMarketing, $dbh, $Cu)
900  * Deletes the survey or marketing message
901  *
902  * @param integer $dbh -- the database connection
903  * @param string $Cu -- the credit union in uppercase
904  * @return array --
905  * $error-- array of zero or one errors
906  * $code-- zero if there is an error; non-zero if there are no errors.
907  * $sql-- array of sqls used
908  */
909 function delete($dbh, $Cu, $surveyid)
910 {
911  $sqls= array();
912 
913  $surveyid= trim($surveyid) ? intval($surveyid) : 0;
914 
915  if (!db_work ($dbh, HOMECU_WORK_BEGIN))
916  throw new exception("begin query failed.", 1);
917 
918  try
919  {
920  $sql= "delete from cusurveymaster where surveyid='$surveyid' and cu='$Cu'";
921  $sqls[]= $sql;
922  $sth= db_query($sql, $dbh);
923  if (!$sth)
924  throw new exception("cusurveymaster delete failed.", 102);
925 
926  $sql= "delete from cusurveydetail where surveyid='$surveyid' and cu='$Cu'";
927  $sqls[]= $sql;
928  $sth= db_query($sql, $dbh);
929  if (!$sth)
930  throw new exception("cusurveydetail delete failed.", 103);
931 
932  $sql= "delete from cusurveysays where surveyid='$surveyid' and cu='$Cu'";
933  $sqls[]= $sql;
934  $sth= db_query($sql, $dbh);
935  if (!$sth)
936  throw new exception("cusurveysays delete failed.", 104);
937 
938  $sql= "delete from cusurveyquest where surveyid='$surveyid' and cu='$Cu'";
939  $sqls[]= $sql;
940  $sth= db_query($sql, $dbh);
941  if (!$sth)
942  throw new exception("cusurveyquest delete failed.", 105);
943 
944  if (!db_work($dbh, HOMECU_WORK_COMMIT))
945  throw new exception("commit work failed.", 106);
946  }
947  catch(exception $e)
948  {
949  if ($e->getCode() >= 100)
950  db_work($dbh, HOMECU_WORK_ROLLBACK); // Got greater problems if this fails.
951 
952  return array("code" => $e->getCode(), "error" => array("Delete failed with code: " . $e->getCode() . "."), "sql" => $sqls);
953  }
954  return array("code" => 0, "error" => array(), "sql" => $sqls);
955 }
956 
957 /**
958  * function mainCmp($a, $b)
959  * Compare function for sorting main read. Sorts the status first and then by the $startdate and then by the $stopdate.
960  *
961  * @param {} $a -- the first one to compare
962  * @param {} $b -- the second one to compare
963  * @return If > 0, $a is sorted higher than $b. If < 0, $b is sorted higher than $a. Otherwise, no resort happens.
964  */
965 function mainCmp($a, $b)
966 {
967  $statusPriority= array_flip(array("", "Invalid", "Draft", "Present", "Future", "Past"));
968  $statusCompare= intval($statusPriority[$b["status"]]) - intval($statusPriority[$a["status"]]);
969  if ($statusCompare != 0)
970  return $statusCompare;
971  $startCompare= $a["startMs"] - $b["startMs"];
972  if ($startCompare != 0)
973  return $startCompare;
974  $stopCompare= $a["stopMs"] - $b["stopMs"];
975  return $stopCompare;
976 }
977 
978 /**
979  * function readMain($isMarketing, $dbh, $Cu)
980  * This function reads for the main page
981  *
982  * @param boolean $isMarketing -- affects the surveytype limitation
983  * @param integer $dbh -- the database connection
984  * @param string $Cu -- the credit union in uppercase
985  * @return array --
986  * $error-- array of zero or one errors
987  * $code-- zero if there is an error; non-zero if there are no errors.
988  * $sql-- array of sqls used
989  * $record-- array of all the surveyids that are limited by surveytype.
990  */
991 function readMain($isMarketing, $dbh, $Cu)
992 {
993  $sqls= array();
994  try
995  {
996  $sql= getMasterSubquery($Cu, $isMarketing);
997  $sqls[]= $sql;
998 
999  $sth= db_query($sql, $dbh);
1000  if (!$sth)
1001  throw new exception("Read query failed!", 1);
1002  $records= array();
1003  $now= new DateTime();
1004  $now= DateTime::createFromFormat("Y-m-d", $now->format("Y-m-d"));
1005  for($i=0; $record= db_fetch_assoc($sth, $i); $i++)
1006  {
1007  $start= DateTime::createFromFormat("Y-m-d", $record["startdate"]);
1008  $stop= DateTime::createFromFormat("Y-m-d", $record["stopdate"]);
1009 
1010  $record["startMs"]= intval($start->format("U"));
1011  $record["stopMs"]= intval($start->format("U"));
1012 
1013  $record["range"]= $start->format("m/d/y") . " - " . $stop->format("m/d/y");
1014 
1015  if ($record["runstat"] == 0)
1016  $record["status"]= "Draft";
1017  else if ($stop < $start)
1018  $record["status"]= "Invalid";
1019  else if ($now < $start)
1020  $record["status"]= "Future";
1021  else if ($now > $stop)
1022  $record["status"]= "Past";
1023  else
1024  $record["status"]= "Present";
1025 
1026  $record["surveyType"]= $record["inc_balances"] == "Y" ? "Balances" : "Popup";
1027 
1028  unset($record["runstat"]);
1029  unset($record["datestat"]);
1030  unset($record["inc_balances"]);
1031  $records[]= $record;
1032  }
1033 
1034  // Sort:
1035  usort($records, "mainCmp");
1036  $sortid= 1;
1037  for($i=0, $length=count($records); $i!= $length; $i++)
1038  {
1039  $records[$i]["sortid"]= $sortid++;
1040  unset($records[$i]["startMs"]);
1041  unset($records[$i]["stopMs"]);
1042  }
1043  }
1044  catch(exception $e)
1045  {
1046  return array("code" => $e->getCode(), "error" => array($e->getMessage()), "sql" => $sqls);
1047  }
1048  return array("code" => 0, "error" => array(), "record" => $records, "sql" => $sqls);
1049 }