Odyssey
flagBadEmails.prg
1 <?php
2 /**
3  * @author Samuel Bennett
4  * @package broadcastEmails.prg -- replaces SetupMail.prg, SendMail.prg, FlagEmail.prg, memberSearch.prg, emailSearch.prg
5  */
6 
7 // Globals
8 $showSQL = $SYSENV["devmode"];
9 $self = "$menu_link?ft=$ft";
10 $jsonFile = "$home_path/admin/mailer";
11 $selectArray = array("all", "withE", "withoutE", "withBP", "withText");
12 
13 // validateEmail is a function in hcuFunctions.i.
14 
15 if ($operation != "") {
16  switch($operation) {
17  case "badFlagFilter":
18  $returnArray = badFlagFilter($dbh, $Cu);
19  break;
20  case "saveFlags":
21  $returnArray = saveFlags($dbh, $Cu, $Cn);
22  break;
23  default:
24  $returnArray = array("sql" => array(), "error" => array("Operation is not recognized: $operation."));
25  }
26 
27  header('Content-type: application/json');
28  if (!$showSQL) {
29  unset($returnArray["sql"]);
30  }
31  print HCU_JsonEncode($returnArray);
32 } else {
33  printFlagEmailsPage($self);
34 }
35 
36 /**
37  * function saveFlags($dbh, $Cu, $Cn)
38  * Save the flag changes. This will only modify the email flag bit in msg_tx in the user table.
39  *
40  * @param integer $dbh -- the database connection
41  * @param string $Cu -- the credit union
42  * @param string $Cn -- the logged in user
43  * @return array: One or one errors, the sqls used
44  */
45 function saveFlags($dbh, $Cu, $Cn) {
46  $sqls = array();
47  $parameters = array("a" => array("changedList" => ""));
48 
49  $string = array("filter" => HCUFILTER_INPUT_STRING);
50  HCU_ImportVars($parameters, "a", array("changedList" => $string));
51  extract($parameters["a"]);
52  $changedList = isset($changedList) ? trim($changedList) : "";
53 
54  try {
55  if ($changedList == "") {
56  throw new exception("Changed List is required.", 1);
57  }
58  $changedList= HCU_JsonDecode($changedList, true);
59  if (!is_array($changedList)) {
60  throw new exception("Changed List is invalid.", 2);
61  }
62  $updateTable = array();
63  $badMap = array();
64 
65  foreach($changedList as $row) {
66  $userId = trim($row["user_id"]);
67  $isBad = intval($row["isbad"]);
68  $badMap[$userId] = $isBad;
69  if ($userId === "") {
70  throw new exception("User Id is required.", 3);
71  }
72  if (!is_numeric($isBad)) {
73  throw new exception("Is Bad needs to be a number.", 5);
74  }
75  }
76  if (count($badMap) == 0) {
77  throw new exception("Should have something in the bad map.", 8);
78  }
79 
80  $sql = "select user_id, msg_tx from ${Cu}user where user_id in ('" . implode("','", array_keys($badMap)) . "')";
81  $sqls[] = $sql;
82  $sth = db_query($sql, $dbh);
83  if (!$sth) {
84  throw new exception("msg tx query failed.", 6);
85  }
86  $txMap = array();
87  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
88  $txMap[trim($row["user_id"])] = intval($row["msg_tx"]);
89  }
90  $firstUserId = -1;
91 
92  $EMAIL_FLAG = GetMsgTxValue('MSGTX_FORCE_EM');
93  foreach($badMap as $userId => $isBad) {
94  if ($firstUserId == -1) {
95  $firstUserId = $userId;
96  }
97  $tx = intval($txMap[$userId]);
98  $updateTable[] = array("_action" => "update", "user_id" => $userId, "msg_tx" => $isBad == 1 ? ($tx | $EMAIL_FLAG) : ($tx & ~$EMAIL_FLAG));
99  }
100  $updateTable = array("user" => $updateTable);
101 
102  $sql = "select email from cuadminusers where user_name = '$Cn' and cu = '$Cu'";
103  $sqls[] = $sql;
104  $sth = db_query($sql, $dbh);
105  if (!$sth) {
106  throw new exception("Email query failed.", 9);
107  }
108  $email = db_fetch_row($sth)[0];
109 
110  if (DataUserTableUpdate($dbh, array("cu" => $Cu), null, $updateTable, $firstUserId, "EMAIL_FLAG", "admin", "broadcastEmails.prg", "A", "Email Flag update",
111  $Cn, $email, trim($_SERVER["REMOTE_ADDR"])) === false) {
112  throw new exception("User update failed.", 7);
113  }
114  } catch(exception $e) {
115  return array("error" => array($e->getMessage()), "sql" => $sqls);
116  }
117  return array("error" => array(), "sql" => $sqls);
118 }
119 
120 /**
121  * function badFlagFilter($dbh, $Cu, $EMAIL_FLAG)
122  * The load for the bad flag page
123  *
124  * @param integer $dbh -- the database connection
125  * @param string $Cu -- the credit union
126  * @return array
127  * $errors -- one or zero errors found
128  * $sqls -- the SQLs used
129  * $gridData -- List of users with emails fitting the criteria.
130  */
131 function badFlagFilter($dbh, $Cu) {
132  $sqls = array();
133  $parameters = array("a" => array("type" => "", "list" => ""));
134 
135  $string = array("filter" => HCUFILTER_INPUT_STRING);
136  HCU_ImportVars($parameters, "a", array("type" => $string, "list" => $string));
137  extract($parameters["a"]);
138 
139  $type = isset($type) ? trim($type) : "";
140  $list = isset($list) ? trim($list) : "";
141 
142  $gridData = array();
143  try {
144  $EMAIL_FLAG = GetMsgTxValue('MSGTX_FORCE_EM');
145  switch($type) {
146  case "list":
147  if ($list == "") {
148  throw new exception("List is required.", 3);
149  }
150  $list = preg_split('/\s/', $list);
151  $validList = array();
152  for($i = 0, $count = count($list); $i != $count; $i++) {
153  $email = $list[$i];
154  if ($email == "") {
155  continue;
156  }
157  if (!validateEmail($email)) {
158  throw new exception("List is invalid.", 4);
159  }
160  $validList[] = $email;
161  }
162  if (count($validList) == 0) {
163  throw new exception("List is invalid.", 5);
164  }
165  $sql = "select user_id, email, user_name, coalesce(msg_tx,0) & $EMAIL_FLAG as isbad from ${Cu}user
166  where lower(email) in ('" . strtolower(implode("','", $validList)) . "')";
167  $sqls[] = $sql;
168  $sth = db_query($sql, $dbh);
169  if (!$sth) {
170  throw new exception("Select query failed.", 6);
171  }
172  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
173  $row["previousIsbad"] = $row["isbad"];
174  $gridData[] = $row;
175  }
176  break;
177  case "bad":
178  $sql = "select user_id, email, user_name, 1 as isbad from ${Cu}user where (coalesce(msg_tx,0) & $EMAIL_FLAG) <> 0";
179  $sqls[] = $sql;
180  $sth = db_query($sql, $dbh);
181  if (!$sth) {
182  throw new exception("Select query failed.", 7);
183  }
184  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
185  $row["previousIsbad"] = $row["isbad"];
186  $gridData[] = $row;
187  }
188  break;
189  case "":
190  throw new exception("Type is required.", 2);
191  break;
192  default:
193  throw new exception("Type is unknown.", 1);
194  }
195  } catch(exception $e) {
196  return array("error" => array($e->getMessage()), "sql" => $sqls, "gridData" => array());
197  }
198  return array("error" => array(), "sql" => $sqls, "gridData" => $gridData);
199 }
200 
201 /**
202  * function printFlagEmailsPage($self)
203  * prints out the page to flag emails.
204  *
205  * @param string $self -- the address to this script
206  */
207 function printFlagEmailsPage($self) { ?>
208  <script type="text/javascript">
209  <?php // Library javascript functions
210  getShowWaitFunctions();
211 
212  /**
213  * function init()
214  * initializes the flag email grid, sets up click events, and then opens the filter dialog.
215  */
216  ?>
217  function init()
218  {
219  var rowA = 0;
220  var grid = $("#grid").kendoGrid({
221  dataSource: {
222  data: [],
223  schema: {
224  model: {
225  id: "user_id",
226  fields: {
227  user_id: {type: "number"},
228  user_name: {type: "number"},
229  email: {type: "string"},
230  isbad: {type: "number"},
231  previousIsbad: {type: "number"}
232  }
233  }
234  }
235  },
236  columns: [
237  {field: "email", title: "Email"},
238  {field: "user_name", title: "User #", width: "150px"},
239  {field: "isbad", headerTemplate: "<input type='checkbox' class='allCheckbox'>", sortable: false, filterable: false, width: "10px"}
240  ],
241  rowTemplate: "<tr data-uid='#: uid #'><td>#: email #</td><td>#: user_name #</td><td><input type='checkbox' class='singleCheckbox'"
242  + "#= isbad == 1 ? ' checked' : '' #></td></tr>",
243  sortable: true,
244  scrollable: false,
245  noRecords: {
246  template: "<tr><td colspan='4'>No Records Found</td></tr>"
247  },
248  dataBound: function() {
249  $("#grid .allCheckbox").prop("checked", $("#grid .singleCheckbox:not(:checked)").length == 0);
250  }
251  }).data("kendoGrid");
252 
253  $("#grid").on("click", ".allCheckbox", function() {
254  $("#formInfoDiv").hide();
255  var data = grid.dataSource.data();
256  var checked = $(this).prop("checked");
257  for(var i = 0; i!= data.length; i++) {
258  data[i].isbad = checked ? 1 : 0;
259  }
260  $("#grid .singleCheckbox").prop("checked", checked);
261  });
262 
263  $("#grid").on("click", ".singleCheckbox", function() {
264  $("#formInfoDiv").hide();
265  var checked= $(this).prop("checked");
266  grid.dataItem($(this).closest("tr")).isbad= checked ? 1 : 0;
267 
268  if (checked && $("#grid .singleCheckbox:not(:checked)").length == 0) {
269  $("#grid .allCheckbox").prop("checked", true);
270  } else if (!checked && $("#grid .singleCheckbox:checked").length != 0) {
271  $("#grid .allCheckbox").prop("checked", false);
272  }
273  });
274 
275  $(".saveBtn").click(function() {
276  $("#formInfoDiv").hide();
277  var changedList = [];
278  var data = grid.dataSource.data();
279  for(var i = 0; i != data.length; i++) {
280  var row = data[i];
281  if (row.isbad != row.previousIsbad) {
282  changedList.push({user_id: row.user_id, isbad: row.isbad});
283  }
284  }
285  var parameters = {changedList: kendo.stringify(changedList)};
286  showWaitWindow();
287  $.post("<?php echo $self; ?>&operation=saveFlags", parameters, function(data) {
288  hideWaitWindow();
289  if (data.error.length > 0) {
290  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
291  $("#formInfoDiv").hide();
292  } else {
293  $("#formInfoDiv").show();
294  }
295  });
296  return false;
297  });
298 
299  $(".refilterBtn").click(function() {
300  openFilterDialog();
301  return false;
302  });
303 
304  openFilterDialog();
305  }
306 
307  <?php
308  /**
309  * function openFilterDialog()
310  * Opens the filter dialog.
311  */
312  ?>
313  function openFilterDialog() {
314  $("#formInfoDiv").hide();
315  var filterDialog = $("#filterDialog").data("kendoDialog");
316  var filterDDL = $("#filterTypeDDL").data("kendoDropDownList");
317  $("#gridDiv").hide();
318  var onInit = filterDialog == null;
319  if (onInit) {
320  filterDialog = $("<div id='filterDialog'></div>").appendTo("body").kendoDialog({
321  title: "Filter",
322  content: $("#popupTemplate").html(),
323  actions: [
324  {text: "Filter", primary: true, action: function() {
325  if ($.homecuValidator.validate()) {
326  var parameters = {type: filterDDL.value(), list: $("#emailInput").val()};
327  showWaitWindow();
328  $.post("<?php echo $self; ?>&operation=badFlagFilter", parameters, function(data) {
329  hideWaitWindow();
330  if (data.error.length > 0) {
331  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
332  } else {
333  $("#grid").data("kendoGrid").dataSource.data(data.gridData);
334  $("#gridDiv").show();
335  filterDialog.close();
336  }
337  });
338  }
339  return false;
340  }},
341  {text: "Cancel"}
342  ],
343  width: 650,
344  visible: false,
345  open: function() {
346  if (window.activeWindows != null) {
347  window.activeWindows.push(this);
348  }
349  },
350  close: function() {
351  if (window.activeWindows != null) {
352  window.activeWindows.pop();
353  }
354  $.homecuValidator.setup({formValidate:'gridDiv', formStatusField: 'formValidateDiv'});
355  },
356  width: 400
357  }).data("kendoDialog");
358 
359  filterDDL = $("#filterTypeDDL").kendoDropDownList({
360  dataSource: {
361  data: [ {text: "Emails In List", value: "list"}, {text: "All Flagged Emails", value: "bad"}]
362  },
363  dataTextField: "text",
364  dataValueField: "value",
365  change: function() {
366  switch(this.value()) {
367  case "list":
368  $("#listDiv").show();
369  break;
370  case "bad":
371  $("#listDiv").hide();
372  break;
373  }
374  }
375  }).data("kendoDropDownList");
376  }
377 
378  $.homecuValidator.setup({formValidate:'popupForm', formStatusField: 'formPopupValidateDiv', homecuCustomRules: {
379  validateemails: function(input) {
380  <?php // Don't care if it isn't on the email input or if it isn't visible (Other filter mode). ?>
381  if (!$(input).is("[name='emailInput']") || !$(input).is(":visible")) {
382  return true;
383  }
384  var emails = $(input).val().trim();
385  if (emails == "") {
386  $(input).attr("data-validateemails-msg", "Please enter at least one email.");
387  return false;
388  }
389  emails = emails.split(/\s+/);
390  for(var i = 0; i != emails.length; i++) {
391  var email = emails[i];
392  if (email.match(/(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/) != null || email.match(/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/) == null) {
393  $(input).attr("data-validateemails-msg", "Emails are not valid.");
394  return false;
395  }
396  }
397  return true;
398  }
399  }});
400 
401  filterDDL.select(0);
402  $("#listDiv").show();
403  $("#emailInput").val("");
404 
405  filterDialog.open();
406  $("#filterDialog").data("successful", false);
407  }
408 
409  var activeWindows = [];
410  $(document).ready(function() {
411  init();
412  <?php printClickOverlayEvent(); ?>
413  });
414  </script>
415  <script id="popupTemplate" type="text/x-kendo-template">
416  <div id="formPopupValidateDiv"></div>
417  <form id="popupForm">
418  <div class="container hcu-all-100 hcu-template vsgPrimary">
419  <div class="row hcuSpacer">
420  <div class="col-xs-4">
421  Filter:
422  </div>
423  <div class="col-xs-8">
424  <div id="filterTypeDDL" class="hcu-all-100"></div>
425  </div>
426  </div>
427  <div class="row hcuSpacer" id="listDiv">
428  <div class="col-xs-4">
429  Email List:
430  </div>
431  <div class="col-xs-8">
432  <textarea class="k-input hcu-all-100" type="text" id="emailInput" name="emailInput" style="height:100px" row=15 col=40></textarea>
433  </div>
434  </div>
435  </div>
436  </form>
437  </script>
438  <div class="container hcu-all-100 hcu-template vsgPrimary">
439  <div class="row hcuSpacer">
440  <div id="formValidateDiv" class="k-block k-error-colored formValidateDiv" style="display:none;"></div>
441  </div>
442  <div id="gridDiv" style="display:none;">
443  <div class="row hcuSpacer">
444  <div class="col-xs-12">
445  <div id="grid"></div>
446  </div>
447  </div>
448  <div class="hcu-edit-buttons k-state-default row">
449  <a class="refilterBtn" href="#">Refilter</a>
450  &nbsp;&nbsp;&nbsp;
451  <a class="saveBtn k-button k-primary" href="#"><i class="fa fa-check"></i>Save</a>
452  </div>
453  </div>
454 
455  </div>
456 <?php }