Odyssey
mcEstmntMntc.data
1 <?php
2 /*
3  * FILE: mcEstmntMntc.data
4  * Backend functions for mEstmntMtnc.prg and cEstmntMntc.prg
5  */
6 
7 /**
8  * function GetDocType()
9  * @return The document type to filter on and save for estatements.
10  */
11 function GetDocType() {
12  return 4;
13 }
14 
15 /**
16  * function GetFilePermissions()
17  * This is the basic file permission octal code to set.
18  * It gives read and write permissions to owner and group.
19  * Other users have no permissions to the file.
20  *
21  * The default file mode when a file is created (at least in mac):
22  * Read and write to owner.
23  * Read only permission to group and other users.
24  *
25  * The file system is controlled based on the group
26  * so both the owner and the group need the write permission.
27  */
28 function GetFilePermissions() {
29  return 0660;
30 }
31 
32 /**
33  * function GetExecPermission()
34  * This adds to the basic file permission (octal code).
35  * It gives execute rights to the owner.
36  * No execute rights is given to the group or other users.
37  */
38 function GetExecPermission() {
39  return 0100;
40 }
41 
42 /**
43  * function GetGlobalDirectory()
44  * @return The directory to save changes to the default.
45  */
46 function GetGlobalDirectory() {
47  return "/home/homecu/skeleton/en_US";
48 }
49 
50 /**
51  * function GetCuDirectory($cu)
52  * Get the directory to save the CU files.
53  * @param $cu -- the credit union
54  * @return string
55  */
56 function GetCuDirectory($cu) {
57  return "/home/" . strtolower($cu) . "/bin";
58 }
59 
60 /**
61  * GetEstatementText()
62  * @return the official text for estatements. This is important because there is a lot of logic revolving over the text of the section.
63  */
64 function GetEstatementText() {
65  return "eStatement";
66 }
67 
68 /**
69  * function GetBackupSuffix()
70  * Gets the string to separate the file from the backup part.
71  * @return string
72  */
73 function GetBackupSuffix() {
74  return "bk";
75 }
76 
77 /**
78  * function GetExecutableFileExtensions()
79  * Gets a list of file extensions to change the mode to executable for.
80  * @return array
81  */
82 function GetExecutableFileExtensions() {
83  return array("pl");
84 }
85 
86 /**
87  * function GetPdfDefsFile()
88  * Gets the pdfdefs file. This is the file to test PDF in the eStatements tab.
89  * @return string
90  */
91 function GetPdfDefsFile() {
92  return "pdfdefs";
93 }
94 
95 /**
96  * function GetTmpDir($cu)
97  * Gets the temporary directory to write any pdf input and output files.
98  * @param $cu -- the credit union
99  * @return string
100  */
101 function GetTmpDir($cu) {
102  return "/home/" . strtolower($cu) . "/tmp";
103 }
104 
105 /**
106  * function GetDefaultTmpInput($cu)
107  * Gets the default input file for testing pdf.
108  * @param $cu -- the credit union
109  * @return string
110  */
111 function GetDefaultTmpInput($cu) {
112  return GetTmpDir($cu) . "/testpdfinput.txt";
113 }
114 
115 /**
116  * function GetDefaultTmpOutput($cu)
117  * Gets the default output file for testing pdf.
118  * @param $cu -- the credit union
119  * @return string
120  */
121 function GetDefaultTmpOutput($cu) {
122  return GetTmpDir($cu) . "/testpdfoutput.pdf";
123 }
124 
125 /**
126  * function GetCheckMORunningSecs()
127  * Get the time (in seconds) to check to see if
128  * Manual operations (redo/undo) is complete.
129  *
130  * @return int
131  */
132 function GetCheckMORunningSecs() {
133  return 10;
134 }
135 
136 /**
137  * function GetMOLastXPeriods()
138  * Get the number of prev periods to get from summary log.
139  *
140  * @return int
141  */
142 function GetMOLastXPeriods() {
143  return 10;
144 }
145 
146 /**
147  * function ExtractPdfDefsForms($cu, $giveContents = false)
148  * This function finds all the forms defined in the pdfdefs document along with the USEFORM addition to the file.
149  *
150  * @param $cu -- the credit union
151  * @param $giveContents -- if true, then also return the contents of the pdfdefs file (since we already have it at this point.)
152  *
153  * @return $status -- "000" if successful, nonzero otherwise.
154  * @return $error -- "" if successful, nonempty otherwise.
155  * @return $data.formArray -- associate array of forms and the USEFORM addition to the file.
156  * @return $data.contents -- if $giveContents is set, the contents of the pdfdefs file.
157  */
158 function ExtractPdfDefsForms($cu, $giveContents = false) {
159  try {
160  $file = GetCuDirectory($cu) . "/" . GetPdfDefsFile();
161 
162  if (!file_exists($file)) {
163  throw new exception ("File does not exist.", 3);
164  }
165 
166  $contents = file_get_contents($file);
167  if ($contents === false) {
168  throw new exception ("File contents could not be found.", 1);
169  }
170  $matches = array();
171  $results = preg_match_all ('/^\s*(.*\s*NEWFORM=([a-z0-9_]+).*>>)$/im', $contents, $matches, PREG_SET_ORDER);
172 
173  if ($results === false) {
174  throw new exception ("Regex failed.", 2);
175  }
176 
177  $returnResults = array();
178 
179  // Return an associated array of the form with the added useform line.
180  foreach($matches as $match) {
181  $returnResults[$match[2]] = str_ireplace("NEWFORM", "USEFORM", $match[1]);
182  }
183 
184  $returnArray = array("status" => "000", "error" => "", "data" => array("formArray" => $returnResults));
185 
186  if ($giveContents) {
187  $returnArray["data"]["contents"] = $contents;
188  }
189 
190  } catch (exception $e) {
191  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
192  }
193  return $returnArray;
194 }
195 
196 /**
197  * function SubstituteKeywords($textIn, $cu)
198  * Substitutes CU strings when first creating a file for the CU or when reverting file to the defaults.
199  * #~CUUPPER~# -- the uppercase of the credit union. E.g. SCRUBCU
200  * #~CULOWER~# -- the lowercase of the credit union. E.g. scrubcu
201  * #~CUHOME~# -- the file location of the credit union. E.g. /home/scrubcu
202  *
203  * @param $textIn -- the string contents of the file.
204  * @param $cu -- the credit union in any case.
205  *
206  * @return $status -- "000" if successful, nonzero otherwise
207  * @return $error -- "" if successful, nonempty otherwise
208  * @return $data -- The translated text
209  */
210 function SubstituteKeywords($textIn, $cu) {
211  try {
212  if (!isset($textIn)) {
213  throw new exception ("Text in is required.", 1);
214  }
215  if (!isset($cu) || trim($cu) == "") {
216  throw new exception ("Cu is required.", 2);
217  }
218  if (trim($textIn) != "") {
219  $cu = trim($cu);
220  $cuUpper = strtoupper($cu);
221  $cuLower = strtolower($cu);
222  $cuHome = "/home/$cuLower";
223 
224  // Use both # (comment in many scripts) and ~ for safety. Don't want to replace variable names.
225  $textIn = str_replace("#~CUUPPER~#", $cuUpper, $textIn);
226  $textIn = str_replace("#~CULOWER~#", $cuLower, $textIn);
227  $textIn = str_replace("#~CUHOME~#", $cuHome, $textIn);
228  }
229 
230  $returnArray = array("status" => "000", "error" => "", "data" => $textIn);
231  } catch (exception $e) {
232  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
233  }
234  return $returnArray;
235 }
236 
237 /**
238  * function ReadEstmntDefinitions($dbh)
239  * Reads a list of estatement definitions from the docs table.
240  *
241  * @param $dbh -- the database connection
242  *
243  * @return "status" -- "000" if successful, nonzero otherwise
244  * @return "error" -- "" if successful, nonempty otherwise
245  * @return "data"."gridData" -- the returned data for the grid
246  * @return "data"."vendorData" -- the vendors available (for extra tab.)
247  * @return "data"."docnameData" -- the docnames available (for extra tab.)
248  * @return "data"."formList" -- a list of forms in the pdfdefs file (for estatement tab.)
249  * @return "data"."configList" -- a list of configurations used in both tabs.
250  * @return "data"."currentVendor" -- the label for the current vendor used in a label on the estatement tab.
251  * @return "data"."filesAffected" -- a list of files affected used for a warning mesage when starting a new configuration.
252  * @return "data"."extraDocumentData" -- documents available on the extra tab.
253  * @return "data"."extraVendorData" -- vendors available on the extra tab.
254  * @return "operation" -- This is read. Easier to see if there is any additional things to be done after coming back.
255  */
256 function ReadEstmntDefinitions($dbh, $cu, $section) {
257 
258  try {
259  $isGlobal = !isset($cu) || trim($cu) == "";
260  $upperCu = null;
261  if ($isGlobal) {
262  $sql = "select d.docsid as docid, d.docsname as docname, d.docsdesc as descr, d.docsmaintsort as sort, d.docsmaintsection as section,
263  d.docstitle as vendor from cucmsdocs d
264  where d.docstype = " . GetDocType();
265  } else {
266  $upperCu = strtoupper(trim($cu));
267  if (!isset($section) || trim($section) == "") {
268  throw new exception ("Section is required.", 3);
269  }
270 
271  if ($section == "Utility") {
272  $sql = "select d.docsid as docid, d.docsname as docname, d.docsdesc as descr, d.docsmaintsort as sort, trim(d.docstitle) as vendor
273  from cucmsdocs d
274  where d.docstype = " . GetDocType() . " and d.docsmaintsection = '" . prep_save($section) . "'
275  order by d.docsmaintsort";
276  } else {
277  $sql = "select d.docsid as docid, d.docsname as docname, d.docsdesc as descr, d.docsmaintsort as sort, trim(d.docstitle) as vendor,
278  trim(e.docstitle) as vendorl from cucmsdocs d
279  inner join cucmsdocs e on d.docsname = e.docsname and d.docstype = e.docstype and d.docsmaintsection = e.docsmaintsection
280  and d.docstype = " . GetDocType() . " and d.docsmaintsection = '" . prep_save($section) . "'
281  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCu, 10) . "'
282  order by d.docsmaintsort, e.docstitle";
283  }
284  }
285 
286  $sth = db_query($sql, $dbh);
287  if (!$sth) {
288  throw new exception ("Select query failed.", 1);
289  }
290 
291  $results = db_fetch_all($sth);
292  $gridData = $results === false ? array() : $results;
293  $first = true;
294  $currentVendor = null;
295  // ASSUME that the vendor is on the first record. Unless something goes horribly wrong, all records for the Credit Union should have the same vendor.
296 
297  if (!$isGlobal && $section !== "Utility") {
298  $gridMap = array();
299  foreach($gridData as $row) {
300  if ($first) {
301  $first = false;
302  $currentVendor = $row["vendor"];
303  }
304  if (!HCU_array_key_exists($row["docid"], $gridMap)) {
305  $row["allvendors"] = array($row["vendorl"]);
306  unset($row["vendorl"]);
307  $gridMap[$row["docid"]] = $row;
308  } else {
309  $gridMap[$row["docid"]]["allvendors"][] = $row["vendorl"];
310  }
311  }
312  $gridData = array_values($gridMap);
313  }
314 
315  $estatementTextPlural = GetEstatementText() . "s";
316  $data = array("gridData" => $gridData);
317  if ($isGlobal) {
318  $sql = "select distinct trim(docstitle) as vendor from cucmsdocs where docstype = " . GetDocType() . " order by 1";
319  $sth = db_query($sql, $dbh);
320  if (!$sth) {
321  throw new exception ("Select query failed.", 2);
322  }
323  $results = db_fetch_all($sth);
324  $results = $results === false ? array() : $results;
325  $vendorData = array();
326  foreach($results as $row) {
327  $vendorData[] = $row["vendor"];
328  }
329  $data["vendorData"] = $vendorData;
330 
331  $sql = "select distinct trim(docsname) as name from cucmsdocs where docstype = " . GetDocType() . " order by 1";
332  $sth = db_query($sql, $dbh);
333  if (!$sth) {
334  throw new exception ("Select query failed.", 8);
335  }
336  $results = db_fetch_all($sth);
337  $results = $results === false ? array() : $results;
338  $docData = array();
339  foreach($results as $row) {
340  $docData[] = $row["name"];
341  }
342  $data["docnameData"] = $docData;
343  } else if ($section == "Credit Card") {
344  $data["currentVendor"] = $currentVendor;
345 
346  $filesAffected = array();
347  $sql = "select d.docsid as docid, d.docsname as docname from cucmsdocs d
348  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCu, 10) . "'
349  where d.docsmaintsection = '" . prep_save($section) . "' and d.docstype = " . GetDocType() . "
350  order by d.docsmaintsort";
351  $sth = db_query($sql, $dbh);
352  if (!$sth) {
353  throw new exception ("Select query failed.", 3);
354  }
355  $results = db_fetch_all($sth);
356  $toBeDeleted = $results === false ? array() : $results;
357 
358  // Step 2: remove files.
359  foreach ($toBeDeleted as $row) {
360  $file = "$dir/" . $row["docname"];
361  if (file_exists($file)) {
362  $filesAffected[] = trim($row["docname"]);
363  }
364  }
365  $data["filesAffected"] = $filesAffected;
366  } else if ($section == $estatementTextPlural) {
367 
368  // No need to complain if the pdfdefs file doesn't exist.
369  $results = ExtractPdfDefsForms($cu);
370  $data["formList"] = $results["status"] === "000" ? array_keys($results["data"]["formArray"]) : array();
371 
372  $data["currentVendor"] = $currentVendor;
373  $sql = "select distinct trim(d.docstitle) as value, trim(d.docsmaintsection) as section, a.cu is not null as default
374  from cucmsdocs d
375  left join cuadmin a on trim(docstitle) = a.vendor and a.cu = '" . prep_save($upperCu, 10) . "'
376  where d.docstype = " . GetDocType() . "
377  order by 2, 3 desc, 1";
378  $sth = db_query($sql, $dbh);
379  if (!$sth) {
380  throw new exception ("Select query failed.", 7);
381  }
382  $results = db_fetch_all($sth);
383  $configList = $results === false ? array() : $results;
384 
385  foreach($configList as $i => $row) {
386  if ($row["default"] == "t") {
387  $row["default"] = true;
388  $row["text"] = $row["value"] . " (Default)";
389  } else {
390  $row["default"] = false;
391  $row["text"] = $row["value"];
392  }
393  $configList[$i] = $row;
394  }
395  $data["configList"] = $configList;
396 
397  // Need to find all the files that would be overwritten with a "start new config."
398  $dir = GetCuDirectory($cu);
399  if (!is_readable($dir)) {
400  throw new exception ("CU directory is not readable.", 9);
401  }
402 
403  $filesAffected = array();
404  $sql = "select d.docsid as docid, d.docsname as docname from cucmsdocs d
405  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCu, 10) . "'
406  where d.docsmaintsection = '" . prep_save($section) . "' and d.docstype = " . GetDocType() . "
407  order by d.docsmaintsort";
408  $sth = db_query($sql, $dbh);
409  if (!$sth) {
410  throw new exception ("Select query failed.", 3);
411  }
412  $results = db_fetch_all($sth);
413  $toBeDeleted = $results === false ? array() : $results;
414 
415  // Step 2: remove files.
416  foreach ($toBeDeleted as $row) {
417  $file = "$dir/" . $row["docname"];
418  if (file_exists($file)) {
419  $filesAffected[] = trim($row["docname"]);
420  }
421  }
422  $data["filesAffected"] = $filesAffected;
423 
424  $sql = "select trim(d.docsname) as docname from cucmsdocs d where d.docsmaintsection = 'Disclosure' and d.docstype = " . GetDocType() . "
425  except
426  select trim(d.docsname) as docname from cucmsdocs d
427  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCu, 10)
428  . "' and d.docsmaintsection = 'Disclosure' and d.docstype = " . GetDocType() . "
429  order by 1";
430 
431  $sth = db_query($sql, $dbh);
432  if (!$sth) {
433  throw new exception ("Select query failed.", 4);
434  }
435  $extraDocumentData = db_fetch_all($sth);
436  if ($extraDocumentData === false) {
437  $extraDocumentData = array();
438  }
439  $data["extraDocumentData"] = $extraDocumentData;
440 
441  $sql = "select d.docsid as docid, trim(d.docsname) as docname, trim(d.docstitle) as vendor from cucmsdocs d
442  where d.docstype = " . GetDocType() . " and d.docsmaintsection = 'Disclosure'
443  order by docsname, docstitle";
444  $sth = db_query($sql, $dbh);
445  if (!$sth) {
446  throw new exception ("Select query failed.", 5);
447  }
448  $extraVendorData = db_fetch_all($sth);
449  if ($extraVendorData === false) {
450  $extraVendorData = array();
451  }
452  $data["extraVendorData"] = $extraVendorData;
453 
454  $results = ReadManualOperations($dbh, $cu);
455  if ($results["status"] !== "000") {
456  throw new exception ($results["error"], 10);
457  }
458 
459  $data["moData"] = $results["data"];
460  }
461 
462  $returnArray = array("status" => "000", "error" => "", "data" => $data, "operation" => "readInit", "section" => $section);
463  } catch (exception $e) {
464  $data = array("gridData" => array());
465  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "data" => $data, "operation" => "readInit");
466  }
467  return $returnArray;
468 }
469 
470 /**
471  * function ReadManualOperations($dbh, $cu)
472  * This reads all the additional data needed for the manual operations dialog.
473  *
474  * @param $dbh -- the database connection
475  * @param $cu -- the credit union
476  *
477  * @return $status -- "000" if successful, nonzero otherwise
478  * @return $error -- "" if successful, nonempty otherwise
479  * @return $data.moActions -- list of acceptable actions
480  * @return $data.moPeriods -- last X periods from summary log file
481  * @return $data.moAllFiles -- Files uploaded for estatement/cc
482  */
483 function ReadManualOperations($dbh, $cu) {
484  try {
485 
486  $cuLower = strtolower($cu);
487  $cuDir = "/home/$cuLower";
488  $tmpDir = $cuDir . "/tmp";
489 
490  $returnData = array();
491  $returnData["moActions"] = array(
492  array("text" => "Reload", "value" => "reload"),
493  array("text" => "Undo", "value" => "undo")
494  );
495 
496  $lastPeriods = array();
497  $summaryFile = "$cuDir/stmnt/summary.log";
498  $numPeriods = GetMOLastXPeriods();
499  if (file_exists($summaryFile)) {
500  $lines = file($summaryFile);
501  $lineCount = count($lines);
502  for($i = 0; $i != $numPeriods; $i++) {
503  $lineNum = $lineCount - 1 - $i;
504  if ($lineNum < 0) {
505  break;
506  }
507  $line = $lines[$lineNum];
508  $f = explode("\t", $line);
509  $lastPeriods[] = array(
510  "date" => trim($f[0]),
511  "period" => trim($f[8]),
512  "action" => trim($f[4])
513  );
514  }
515  }
516 
517  $returnData["moPeriods"] = $lastPeriods;
518 
519  $allFiles = array();
520 
521  foreach(glob("$tmpDir/${cuLower}stmnt.daz*") as $filename) {
522  $fileRec = array("type" => "statement", "filename" => basename($filename));
523  $fileRec["date"] = date("F d Y H:i:s", filemtime($filename));
524  $allFiles[] = $fileRec;
525  }
526  foreach(glob("$tmpDir/${cuLower}ccard.daz*") as $filename) {
527  $fileRec = array("type" => "credit card", "filename" => basename($filename));
528  $fileRec["date"] = date("F d Y H:i:s", filemtime($filename));
529  $allFiles[] = $fileRec;
530  }
531 
532  $returnData["moAllFiles"] = $allFiles;
533 
534  $returnArray = array("status" => "000", "error" => "", "data" => $returnData);
535  } catch (exception $e) {
536  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
537  }
538  return $returnArray;
539 }
540 
541 /**
542  * function ExecuteManualOperations($dbh, $cu, $file, $period, $suboperation)
543  * Runs the reload or undo operation
544  *
545  * @param $dbh -- the database connection
546  * @param $cu -- the credit union
547  * @param $file -- the file to reload (no effect for undo)
548  * @param $period -- the period to upload for
549  * @param $suboperation -- "reload" or "undo"
550  *
551  * @return $status -- "000" if successful, nonzero otherwise
552  * @return $error -- "" if successful, nonempty otherwise
553  * @return $operation -- "exec" -- there is some frontend logic on the return
554  */
555 function ExecuteManualOperations($dbh, $cu, $file, $period, $suboperation) {
556  try {
557  if (!in_array($suboperation, array("reload", "undo"))) {
558  throw new exception ("Operation is not valid.", 2);
559  }
560 
561  if ($suboperation == "reload") {
562  if ($file == "") {
563  throw new exception ("File is required.", 3);
564  }
565  }
566 
567  if ($period == "") {
568  throw new exception ("Period is required.", 4);
569  }
570 
571  $ccname = GetCCName();
572  $scriptDir = GetScriptDir();
573  $cuLower = strtolower($cu);
574  $cuDir = "/home/$cuLower";
575 
576  if (!IsPeriodValid($period, is_readable(GetCCConfig($cuDir)))) {
577  throw new exception ("Period is invalid.", 5);
578  }
579 
580  $tmpDir = "$cuDir/tmp";
581  $hasCC = strpos($period, $ccname) !== false;
582  $savedFile = $hasCC ? "$tmpDir/${cuLower}ccard.daz" : "$tmpDir/${cuLower}stmnt.daz";
583 
584  // Verify that file exists for redo. If it does, move it to the correct place.
585  if ($suboperation == "reload") {
586  $reloadFile = "$tmpDir/" . basename($file);
587  if (!file_exists($reloadFile)) {
588  throw new exception ("File is invalid.", 8);
589  }
590  if ($reloadFile !== $savedFile && !copy($reloadFile, $savedFile)) {
591  throw new exception ("File couldn't be copied.", 9);
592  }
593  }
594 
595  putenv("ADMUSER=hcuSupport");
596 
597  $scriptName = $hasCC ? "ccardload.pl" : "stmntload.pl";
598  $undoParam = $suboperation === "undo" ? "--undo" : "";
599  $command = "/usr/bin/nice -19 /usr/bin/env perl $scriptDir/$scriptName $undoParam --noemail " . escapeshellcmd($cuDir) . " \"{$period}\" >/dev/null &";
600 
601  $rc = exec ($command);
602 
603  $returnArray = array("status" => "000", "error" => "", "operation" => "exec");
604  } catch (exception $e) {
605  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "operation" => "exec");
606  }
607  return $returnArray;
608 }
609 
610 /**
611  * function RetrieveStatusManualOperations($dbh, $cu)
612  * This function checks to see if the manual operation has finished.
613  *
614  * @param $dbh -- the database connection
615  * @param $cu -- the credit union
616  *
617  * @return $status -- "000" if successful, nonzero otherwise
618  * @return $error -- "" if successful, nonempty otherwise
619  * @return $infoCode -- 1 if error, 2 if running, 0 otherwise
620  * @return $infoMessage -- A message displayed to user related to code
621  */
622 function RetrieveStatusManualOperations($dbh, $cu) {
623  try {
624  $scriptDir = GetScriptDir();
625  $cuLower = strtolower($cu);
626  $command = "/usr/bin/nice -19 /usr/bin/env perl $scriptDir/stmntload_running_status.pl $cuLower";
627  $commandRs = exec($command);
628  $commandStatusAry = explode("\t", $commandRs);
629  $commandStatus = trim($commandStatusAry[0]);
630 
631  $lastUploadedStatus = 0;
632  switch ($commandStatus) { // index 0 should always be our cases
633  case 'Error':
634  case 'Abort':
635  $lastUploadedStatus = 1; // failed during processing
636  break;
637  case 'Running':
638  $lastUploadedStatus = 2; // waiting or in processing
639  break;
640  case 'Norm/0':
641  case 'Undo/0':
642  default:
643  $lastUploadedStatus = 0; // success / no uploaded files
644  break;
645  }
646 
647  // There is a 60 second delay before the upload process actually begins,
648  // we must check for the existence of the .daz file.
649 
650  // If the .daz file exists, the upload process is currently running
651  $tmpDir = "/home/$cuLower/tmp";
652  if (is_dir($tmpDir) && file_exists("$tmpDir/{$cuLower}stmnt.daz")) {
653  $lastUploadedStatus = 2;
654  }
655 
656  switch($lastUploadedStatus) {
657  case 1:
658  $infoMessage = "eStatement process failed. Please try again.";
659  break;
660  case 2:
661  $infoMessage = GetRunningMOInfo();
662  break;
663  case 0:
664  default:
665  $infoMessage = "";
666  break;
667  }
668 
669  $returnArray = array("status" => "000", "error" => "", "infoCode" => $lastUploadedStatus, "infoMessage" => $infoMessage);
670 
671 
672  } catch (exception $e) {
673  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
674  }
675  return $returnArray;
676 }
677 
678 /**
679  * function GetRunningMOInfo()
680  * This function gets the info message when the reload/undo operation is running.
681  */
682 function GetRunningMOInfo() {
683  return "There is a running eStatement process. This will check every " . GetCheckMORunningSecs() . " seconds or you can close window.";
684 }
685 
686 /**
687  * function IsPeriodValid($periodText, $isCcConfigReadable)
688  * This checks the text of the period to see if it is valid
689  * Valid examples: "CREDIT CARD Jan 2019", "Feb 2018", "Quarter 2 2016"
690  *
691  * @param $periodText -- the text of the period
692  * @param $isCcConfigReadable -- if the credit card config file is readable
693  *
694  * @return true if valid, false otherwise
695  */
696 function IsPeriodValid($periodText, $isCcConfigReadable) {
697  try {
698 
699  $ccname = GetCCName();
700  $hasCC = strpos($periodText, $ccname) !== false;
701  if ($hasCC && !$isCcConfigReadable) {
702  throw new exception ("CC Config is not readable", 1);
703  }
704 
705  $pattern = GetPeriodPattern();
706  $doesMatch = preg_match($pattern, $periodText) === 1;
707 
708  if (!$doesMatch) {
709  throw new exception ("Period does not match", 2);
710  }
711 
712  $valid = true;
713  } catch (exception $e) {
714  $valid = false;
715  }
716  return $valid;
717 }
718 
719 /**
720  * function GetMonthAbbrevs()
721  * Gets a list of month abbreviations
722  *
723  * @return Jan, Feb, Mar....
724  */
725 function GetMonthAbbrevs() {
726  $date = DateTime::createFromFormat('d-m-Y|', '01-01-2019');
727  $monthAbbrevs = array();
728  for($i = 0; $i != 12; $i++) {
729  $monthAbbrevs[] = $date->format("M");
730  $date->setDate(2019, $date->format("m") + 1, 1);
731  }
732 
733  return $monthAbbrevs;
734 }
735 
736 /**
737  * function GetPeriodPattern()
738  * Gets the regex pattern for valid periods
739  *
740  * @return string
741  */
742 function GetPeriodPattern() {
743  $ccname = GetCCName();
744  $monthAbbrevs = GetMonthAbbrevs();
745 
746  $quarterPattern = 'Quarter [1-4]';
747  $halfPattern = '(?:1st Half)|(?:2nd Half)';
748  $yearPattern = '[1-9]\d{3}';
749  $monthPattern = '(?:' . implode(')|(?:', $monthAbbrevs) . ')';
750 
751  $pattern = '/(?:' . $ccname . ' )?(?:' . $quarterPattern
752  . ')|(?:' . $monthPattern . ')|(?:' . $halfPattern . ') ' . $yearPattern . '/';
753  return $pattern;
754 }
755 
756 /**
757  * function UpdateEstmntDefinitionsMntc($dbh, $dataItem)
758  * Updates the settings of the file. (Either creates a new record or modifies any existing record.)
759  *
760  * @param $dbh -- the database connection
761  * @param $dataItem -- the dataItem of the record in a json-encoded string.
762  *
763  * @return "status" -- "000" if successful, nonzero otherwise
764  * @return "error" -- "" if successful, nonempty otherwise
765  * @return "operation" -- either "create" or "update"
766  * @return "info" -- Gives feedback to the user
767  */
768 function UpdateEstmntDefinitionsMntc($dbh, $dataItem) {
769  try {
770  $operation = "update";
771  $isGlobal = !isset($cu) || trim($cu) == "";
772 
773  $results = _ValidateDataItemUpdateGlobal($dataItem);
774 
775  if ($results ["status"] !== "000") {
776  throw new exception ($results["error"], 1);
777  }
778  extract($results["data"]);
779 
780  // duplicate check.
781  $sql = "select 'FOUND' from cucmsdocs where docstitle = '" . prep_save($vendor, 100) . "' and docsname = '" . prep_save($docname, 50) . "' and docstype = "
782  . GetDocType() . " and docsid <> $docid"; // Still works with an add because I make sure that docid is 0 in that case.
783  $sth = db_query($sql, $dbh);
784  if (!$sth) {
785  throw new exception ("Duplicate check failed.", 4);
786  }
787  if (db_num_rows($sth) > 0) {
788  throw new exception ("Cannot save duplicate record.", 5);
789  }
790  if ($isAdd) {
791  $sql = "insert into cucmsdocs (docsname, docsdesc, docstype, docstitle, docsmaintsection, docsmaintsort)
792  values ('" . prep_save($docname, 50) . "', '" . prep_save($descr, 250) . "', " . GetDocType() . ", '" . prep_save($vendor, 100)
793  . "', '" . prep_save($section) . "', $sort)
794  returning docsid as docid, docsname as docname, docstitle as vendor, docsmaintsection as section, docsmaintsort as sort, docsdesc as descr";
795  } else {
796  $sql = "update cucmsdocs set docsname = '" . prep_save($docname, 50) . "', docsdesc = '" . prep_save($descr, 250) . "', docstitle = '"
797  . prep_save($vendor, 100) . "',
798  docsmaintsection = '" . prep_save($section) . "', docsmaintsort = $sort
799  where docsid = $docid and docstype = " . GetDocType() . "
800  returning docsid as docid, docsname as docname, docstitle as vendor, docsmaintsection as section, docsmaintsort as sort, docsdesc as descr";
801  }
802 
803  $sth = db_query($sql, $dbh);
804  if (!$sth) {
805  throw new exception ("Update query failed.", 2);
806  }
807  if (db_affected_rows($sth) == 0) {
808  throw new exception ("Update query failed.", 3);
809  }
810  $updatedRecord = db_fetch_assoc($sth, 0);
811 
812  $returnArray = array("status" => "000", "error" => "", "data" => $updatedRecord, "operation" => $operation, "info" => GetEstatementText()
813  . " was saved successfully.");
814  } catch (exception $e) {
815 
816  $updatedRecord = false;
817  if (!$isAdd) {
818  $sql = "select docsid as docid, docsname as docname, docstitle as vendor, docsmaintsection as section, docsmaintsort as sort, docsdesc as descr
819  from cucmsdocs where docsid = $docid"; // Get the unsaved version.
820  $sth = db_query ($sql, $dbh);
821  if ($sth) {
822  $updatedRecord = db_fetch_all($sth);
823  $updatedRecord = $updatedRecord === false ? false : $updatedRecord[0];
824  }
825  }
826 
827  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "operation" => $operation, "data" => $updatedRecord);
828  }
829  return $returnArray;
830 }
831 
832 /**
833  * function UpdateEstmntCu ($dbh, $dataItem, $cu, $section)
834  * Updates the estatement record from the CU-specific script.
835  *
836  * @param $dbh -- the database connection
837  * @param $dataItem -- the dataItem of the record in the grid.
838  * @param $cu -- the credit union
839  * @param $section -- the section to update
840  *
841  * @return "status" -- "000" if successful, nonzero otherwise
842  * @return "error" -- "" if successful, nonempty otherwise
843  * @return "operation" -- either "create" or "update"
844  * @return "data"."record" -- The updated dataItem for display in the grid
845  * @return "data"."formList" -- a list of forms in the pdfdefs file (for estatement tab.)
846  * @return "section" -- the section to update
847  */
848 function UpdateEstmntCu ($dbh, $dataItem, $cu, $section) {
849  try {
850  $operation = "update";
851 
852  if (!isset($cu) || trim($cu) == "") {
853  throw new exception ("Cu is required.", 8);
854  }
855 
856  $results = _ValidateDataItemUpdateCu($dataItem);
857 
858  if ($results ["status"] !== "000") {
859  throw new exception ($results["error"], 1);
860  }
861  extract($results["data"]);
862  $upperCu = strtoupper(trim($cu));
863 
864  $sql = "select d.docsid as docid, d.docsname as docname, d.docsdesc as descr, d.docsmaintsort as sort, trim(d.docstitle) as vendor,
865  trim(e.docstitle) as vendorl from cucmsdocs d
866  inner join cucmsdocs e on d.docsname = e.docsname and d.docstype = e.docstype and d.docsmaintsection = e.docsmaintsection
867  and d.docstype = " . GetDocType() . " and d.docsmaintsection = '" . prep_save($section) . "' and d.docsid = $docid
868  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCu, 10) . "'
869  order by d.docsmaintsort, e.docstitle";
870  $sth = db_query($sql, $dbh);
871  if (!$sth) {
872  throw new exception ("Select query failed.", 9);
873  }
874  if (db_num_rows($sth) == 0) {
875  $upperCu = strtoupper(trim($cu));
876  $sql = "insert into cucmsfrags (docsid, cu) values ($docid, '" . prep_save($upperCu, 10) . "')";
877 
878  $sth = db_query($sql, $dbh);
879  if (!$sth) {
880  throw new exception ("Update query failed.", 4);
881  }
882  if (db_affected_rows($sth) == 0) {
883  throw new exception ("Update query failed.", 5);
884  }
885 
886  $sql = "select d.docsid as docid, d.docsname as docname, d.docsdesc as descr, d.docsmaintsort as sort, trim(d.docstitle) as vendor,
887  trim(e.docstitle) as vendorl from cucmsdocs d
888  inner join cucmsdocs e on d.docsname = e.docsname and d.docstype = e.docstype and d.docsmaintsection = e.docsmaintsection
889  and d.docstype = " . GetDocType() . " and d.docsmaintsection = '" . prep_save($section) . "' and d.docsid = $docid
890  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCu, 10) . "'
891  order by d.docsmaintsort, e.docstitle";
892  $sth = db_query($sql, $dbh);
893  if (!$sth) {
894  throw new exception ("Select query failed.", 6);
895  }
896  if (db_num_rows($sth) == 0) {
897  throw new exception ("Select query failed.", 7);
898  }
899  $gridData = db_fetch_all($sth);
900  $gridData = $gridData === false ? array() : $gridData;
901  } else {
902  // Update file only.
903  $gridData = db_fetch_all($sth);
904  $gridData = $gridData === false ? array() : $gridData;
905  }
906 
907  $data = array();
908 
909  $gridMap = array();
910  foreach($gridData as $row) {
911  if (!HCU_array_key_exists($row["docid"], $gridMap)) {
912  $row["allvendors"] = array($row["vendorl"]);
913  unset($row["vendorl"]);
914  $gridMap[$row["docid"]] = $row;
915  } else {
916  $gridMap[$row["docid"]]["allvendors"][] = $row["vendorl"];
917  }
918  }
919  $data["record"] = $gridMap[$docid];
920 
921  // File operation
922  $results = UpdateEstmntFile($dbh, $docid, $contents, $cu, $section);
923  if ($results ["status"] !== "000") {
924  throw new exception ("File wasn't saved.", 10);
925  }
926 
927  switch(trim($data["record"]["docname"])) {
928  case GetPdfDefsFile():
929  // No need to complain if the pdfdefs file doesn't exist.
930  $results = ExtractPdfDefsForms($cu);
931  $data["formList"] = $results["status"] === "000" ? array_keys($results["data"]["formArray"]) : array();
932  break;
933  }
934 
935  $returnArray = array("status" => "000", "error" => "", "data" => $data, "operation" => $operation, "info" => GetEstatementText() . " file saved successfully.",
936  "section" => $section);
937 
938  } catch (exception $e) {
939  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "operation" => $operation, "data" => array("record" => array()),
940  "section" => $section);
941  }
942  return $returnArray;
943 }
944 
945 /**
946  * function _ValidateDataItemUpdate($dataItem)
947  * This ensures that the dataItem is in the right format
948  *
949  * @param $dataItem -- the dataItem input to validate.
950  *
951  * @return "status" -- "000" if successful, nonzero otherwise
952  * @return "error" -- "" if successful, nonempty otherwise
953  * @return "data" -- the sanitized dataItem
954  */
955 function _ValidateDataItemUpdateGlobal($dataItem) {
956  try {
957  if (!is_string($dataItem) || $dataItem == "") {
958  throw new exception ("DataItem is not valid.", 1);
959  }
960  $dataItem = HCU_JsonDecode($dataItem);
961  if (!is_array($dataItem) || count($dataItem) == 0) {
962  throw new exception ("DataItem is not valid.", 2);
963  }
964 
965  if (!HCU_array_key_exists("docid", $dataItem) || intval($dataItem["docid"]) == 0) {
966  $dataItem ["isAdd"] = true;
967  $dataItem["docid"] = 0;
968  $dataItem ["operation"] = "create";
969  } else {
970  $dataItem ["isAdd"] = false;
971  $dataItem ["operation"] = "update";
972  }
973 
974  if (!HCU_array_key_exists("docname", $dataItem) || trim($dataItem["docname"]) == "") {
975  throw new exception ("Doc name is required.", 4);
976  }
977 
978  if (!HCU_array_key_exists("sort", $dataItem)) {
979  $dataItem ["sort"] = 0;
980  } else {
981  $dataItem ["sort"] = intval($dataItem ["sort"]);
982  }
983 
984  if (!HCU_array_key_exists("vendor", $dataItem) || trim($dataItem["vendor"]) == "") {
985  throw new exception ("Vendor is required.", 7);
986  }
987 
988  $returnArray = array("status" => "000", "error" => "", "data" => $dataItem);
989  } catch (exception $e) {
990  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
991  }
992  return $returnArray;
993 }
994 
995 /**
996  * function _ValidateDataItemUpdate($dataItem)
997  * This ensures that the dataItem is in the right format
998  *
999  * @param $dataItem -- the dataItem input to validate.
1000  *
1001  * @return "status" -- "000" if successful, nonzero otherwise
1002  * @return "error" -- "" if successful, nonempty otherwise
1003  * @return "data" -- the sanitized dataItem
1004  */
1005 function _ValidateDataItemUpdateCu($dataItem) {
1006  try {
1007  if (!is_string($dataItem) || $dataItem == "") {
1008  throw new exception ("DataItem is not valid.", 1);
1009  }
1010  $dataItem = HCU_JsonDecode($dataItem);
1011  if (!is_array($dataItem) || count($dataItem) == 0) {
1012  throw new exception ("DataItem is not valid.", 2);
1013  }
1014 
1015  if (!HCU_array_key_exists("docid", $dataItem) || intval($dataItem["docid"]) == 0) {
1016  throw new exception ("DataItem is not valid.", 3);
1017  }
1018 
1019  if (!HCU_array_key_exists("contents", $dataItem) || trim($dataItem["contents"]) == "") {
1020  throw new exception ("Contents are not valid.", 4);
1021  }
1022 
1023  $returnArray = array("status" => "000", "error" => "", "data" => $dataItem);
1024  } catch (exception $e) {
1025  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
1026  }
1027  return $returnArray;
1028 }
1029 
1030 /**
1031  * function RemoveEstmntDefinitionsMntc($dbh, $docid, $cu, $section)
1032  * Remove the estatement definitions
1033  *
1034  * @param $dbh -- the database connection
1035  * @param $docid -- the docid to delete
1036  * @param $cu -- the credit union
1037  * @param $section -- the section to remove from
1038  *
1039  * @return "status" -- "000" if successful, nonzero otherwise
1040  * @return "error" -- "" if successful, nonempty otherwise
1041  * @return "info" -- A successful message
1042  * @return "data"."record" -- the record that was deleted.
1043  * @return "data"."formList" -- a list of forms in the pdfdefs file (for estatement tab.)
1044  * @return "section" -- the section to remove from
1045  */
1046 function RemoveEstmntDefinitionsMntc($dbh, $docid, $cu, $section) {
1047  try {
1048  $upperCu = isset($cu) ? trim(strtoupper($cu)) : "";
1049  $lowerCu = strtolower($upperCu);
1050  if ($upperCu != "") {
1051  $sql = "select d.docsid as docid, d.docsname as docname, d.docstitle as vendor, docsdesc as descr from cucmsdocs d
1052  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCu, 10) . "'
1053  where d.docstype = " . GetDocType() . " and d.docsid = " . intval($docid);
1054  } else {
1055  $sql = "select d.docsid as docid, d.docsname as docname, d.docstitle as vendor, d.docsdesc as descr from cucmsdocs d
1056  where d.docstype = " . GetDocType() . " and d.docsid = " . intval($docid);
1057  }
1058 
1059  $sth = db_query($sql, $dbh);
1060  if (!$sth) {
1061  throw new exception ("SQL is not valid.", 1);
1062  }
1063  if (db_num_rows($sth) == 0) {
1064  throw new exception ("Document record is not found.", 2);
1065  }
1066 
1067  list($docid, $docname, $vendor) = db_fetch_array($sth, 0);
1068 
1069  if ($cu == "") {
1070  $dir = GetGlobalDirectory();
1071  $filename = "$docname.$vendor";
1072  } else {
1073  $dir = GetCuDirectory($lowerCu);
1074  $filename = "$docname";
1075  }
1076 
1077  if (!is_writable($dir)) {
1078  throw new exception ("Directory is not writable.", 4);
1079  }
1080  $fullname = "$dir/$filename";
1081  if (file_exists($fullname)) {
1082  $results = unlink($fullname);
1083  if ($results === false) {
1084  throw new exception ("File could not be removed.", 5);
1085  }
1086  }
1087 
1088  if (isset($cu) && trim($cu) != "") {
1089  $sql = "delete from cucmsfrags where docsid = $docid and cu = '" . prep_save($upperCu, 10) . "'";
1090  } else {
1091  $sql = "delete from cucmsdocs where docsid = $docid and docstype = " . GetDocType() . " and docsresponsetype is null";
1092  }
1093 
1094  // Ensure that you cannot delete a record from the regular custom content.
1095  $sth = db_query($sql, $dbh);
1096 
1097  if (!$sth) {
1098  throw new exception ("Delete failed.", 1);
1099  }
1100  if (db_affected_rows($sth) == 0) {
1101  throw new exception ("Delete failed.", 2);
1102  }
1103 
1104  $returnArray = array("status" => "000", "error" => "", "info" => GetEstatementText() . " was deleted successfully.", "section" => $section,
1105  "operation" => "delete", "data" => array("record" => array("docid" => $docid, "docname" => $docname, "vendor" => $vendor)));
1106 
1107 
1108  switch(trim($docname)) {
1109  case GetPdfDefsFile():
1110  $returnArray["data"]["formList"] = array();
1111  break;
1112  }
1113  } catch (exception $e) {
1114  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "section" => $section, "operation" => "delete");
1115  }
1116  return $returnArray;
1117 }
1118 
1119 /**
1120  * function ReadEstmntFile($dbh, $docid, $cu)
1121  * This retrieves the contents of the file from the server.
1122  *
1123  * @param $dbh -- the database connection
1124  * @param $docid -- the id of the document
1125  * @param $cu -- the credit union (for the global script this will be an empty string)
1126  *
1127  * @return "status" -- "000" if successful, nonzero otherwise
1128  * @return "error" -- "" if successful, nonempty otherwise
1129  * @return "data" -- a list of items for the dataSource. This will always be one item.
1130  * @return "operation" -- identifies the operation type.
1131  */
1132 function ReadEstmntFileGlobal($dbh, $docid, $fromCuScript, $cu, $vendor) {
1133  $contents = "";
1134  try {
1135 
1136  if (isset($vendor) && trim($vendor) != "") {
1137  $sql = "select e.docsid as docid, e.docsname as docname, e.docstitle as vendor, e.docsdesc as descr from cucmsdocs d
1138  inner join cucmsdocs e on d.docstype = e.docstype and d.docsname = e.docsname and e.docstitle = '" . prep_save($vendor, 100) . "'
1139  where d.docstype = " . GetDocType() . " and d.docsid = " . intval($docid);
1140  } else {
1141  $sql = "select d.docsid as docid, d.docsname as docname, d.docstitle as vendor, d.docsdesc as descr from cucmsdocs d
1142  where d.docstype = " . GetDocType() . " and d.docsid = " . intval($docid);
1143  }
1144 
1145  $sth = db_query($sql, $dbh);
1146  if (!$sth) {
1147  throw new exception ("SQL is not valid.", 1);
1148  }
1149  if (db_num_rows($sth) == 0) {
1150  throw new exception ("Document record is not found.", 2);
1151  }
1152 
1153  list($docid, $docname, $vendor) = db_fetch_array($sth, 0);
1154 
1155  $dirList = array("Directory" => GetGlobalDirectory());
1156  $filename = "$docname.$vendor";
1157 
1158  foreach ($dirList as $title => $dir) {
1159  if (!is_readable($dir)) {
1160  throw new exception ("$title is not readable.", 3);
1161  }
1162  $fullname = "$dir/$filename";
1163  if (file_exists($fullname)) {
1164  $contents = file_get_contents($fullname);
1165  if ($contents === false) {
1166  throw new exception ("File is not readable.", 6);
1167  }
1168  break;
1169  }
1170  }
1171 
1172  if ($fromCuScript) {
1173  $results = SubstituteKeywords($contents, $cu);
1174  if ($results ["status"] !== "000") {
1175  throw new exception ("$retrieveFile could not translate correctly.", 7);
1176  }
1177  $contents = $results["data"];
1178  }
1179 
1180  $returnArray = array("status" => "000", "error" => "", "data" => array(array("docid" => $docid, "contents" => $contents, "filename" => $filename)),
1181  "operation" => "read");
1182  } catch (exception $e) {
1183  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "operation" => "read", "data" => array());
1184  }
1185  return $returnArray;
1186 }
1187 
1188 /**
1189  * function ReadEstmntFileCu($dbh, $docid, $cu, $section, $vendor, $isDifferentVendor)
1190  * Reads an estatement file if coming from the CU-specific file.
1191  *
1192  * @param $dbh -- the database connection
1193  * @param $cu -- the credit union
1194  * @param $section -- the section to update
1195  *
1196  * @return "status" -- "000" if successful, nonzero otherwise
1197  * @return "error" -- "" if successful, nonempty otherwise
1198  * @return "data" -- a list of items for the dataSource. This will always be one item.
1199  * @return "operation" -- identifies the operation type.
1200  */
1201 function ReadEstmntFileCu($dbh, $docid, $cu, $section) {
1202  $contents = "";
1203  try {
1204 
1205  $sql = "select d.docsid as docid, d.docsname as docname, d.docstitle as vendor, d.docsdesc as descr from cucmsdocs d
1206  where d.docstype = " . GetDocType() . " and d.docsid = " . intval($docid);
1207 
1208  $sth = db_query($sql, $dbh);
1209  if (!$sth) {
1210  throw new exception ("SQL is not valid.", 1);
1211  }
1212  if (db_num_rows($sth) == 0) {
1213  throw new exception ("Document record is not found.", 2);
1214  }
1215 
1216  list($docid, $docname, $vendor) = db_fetch_array($sth, 0);
1217 
1218  $dirList = array("Directory" => GetCuDirectory($cu));
1219  $filename = "$docname";
1220 
1221  foreach ($dirList as $title => $dir) {
1222  if (!is_readable($dir)) {
1223  throw new exception ("$title is not readable.", 3);
1224  }
1225  $fullname = "$dir/$filename";
1226  if (file_exists($fullname)) {
1227  $contents = file_get_contents($fullname);
1228  if ($contents === false) {
1229  throw new exception ("File is not readable.", 6);
1230  }
1231  break;
1232  }
1233  }
1234 
1235  $returnArray = array("status" => "000", "error" => "", "data" => array(array("docid" => $docid, "contents" => $contents, "filename" => $filename)),
1236  "operation" => "read");
1237  } catch (exception $e) {
1238  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "operation" => "read", "data" => array());
1239  }
1240  return $returnArray;
1241 }
1242 
1243 /**
1244  * function UpdateEstmntFile($dbh, $docid, $contents, $cu, $section)
1245  * This creates/modifies an existing file.
1246  *
1247  * @param $dbh -- the database connection
1248  * @param $docid -- the id of the document
1249  * @param $contents -- the contents of the file to save
1250  * @param $cu -- the credit union (for the global script this will be an empty string)
1251  * @param $section -- the section where the estatement file is located
1252  *
1253  * @return "status" -- "000" if successful, nonzero otherwise
1254  * @return "error" -- "" if successful, nonempty otherwise
1255  * @return "operation" -- identifies the operation type.
1256  * @return "info" -- give feedback to the user.
1257  */
1258 function UpdateEstmntFile($dbh, $docid, $contents, $cu, $section) {
1259  try {
1260  $sql = "select d.docsid as docid, d.docsname as docname, d.docstitle as vendor from cucmsdocs d
1261  where docstype = " . GetDocType() . " and docsid = " . intval($docid);
1262  $sth = db_query($sql, $dbh);
1263  if (!$sth) {
1264  throw new exception ("SQL is not valid.", 1);
1265  }
1266  if (db_num_rows($sth) == 0) {
1267  throw new exception ("Document record is not found.", 2);
1268  }
1269 
1270  list($docid, $docname, $vendor) = db_fetch_array($sth, 0);
1271 
1272  if ($cu == "") {
1273  $dir = GetGlobalDirectory();
1274  $filename = "$docname.$vendor";
1275  } else {
1276  $dir = GetCuDirectory($cu);
1277  $filename = "$docname";
1278  }
1279 
1280  if (!is_writable($dir)) {
1281  throw new exception ("Directory is not writable.", 3);
1282  }
1283  $fullname = "$dir/$filename";
1284  $results = file_put_contents($fullname, $contents);
1285  if ($results === false) {
1286  throw new exception ("File was not written.", 6);
1287  }
1288 
1289  // Add File permissions
1290  $dontSetExecutableBit = $cu == ""; // Perl templates SHOULD NOT be executable. ONLY perl scripts in the Cu directory.
1291  $results = SetFileMetadata($fullname, $dontSetExecutableBit);
1292  if ($results["status"] != "000") {
1293  throw new exception ("File metadata was not updated.", 10);
1294  }
1295 
1296  $returnArray = array("status" => "000", "error" => "", "operation" => "update", "info" => GetEstatementText() . " file was saved successfully.");
1297  } catch (exception $e) {
1298  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "operation" => "update");
1299  }
1300  return $returnArray;
1301 }
1302 
1303 /**
1304  * function RevertEstmntFile($dbh, $docid, $cu)
1305  * This reverts the file to the default file if it exists, otherwise it sets the file to empty string.
1306  *
1307  * @param $dbh -- the database connection
1308  * @param $docid -- the id of the document
1309  * @param $cu -- the credit union (for the global script this will be an empty string)
1310  *
1311  * @return "status" -- "000" if successful, nonzero otherwise
1312  * @return "error" -- "" if successful, nonempty otherwise
1313  * @return "info" -- give feedback to the user.
1314  * @return "data"."record" -- this is an empty array. Necessary because this operation uses the read functionality.
1315  * @return "data"."formList" -- a list of forms in the pdfdefs file (for estatement tab.)
1316  */
1317 function RevertEstmntFile($dbh, $docid, $cu, $section) {
1318  try {
1319  if ($cu == "") {
1320  throw new exception ("Cu needs to be defined.", 9);
1321  }
1322  $sql = "select d.docsid as docid, d.docsname as docname, d.docstitle as vendor from cucmsdocs d
1323  where docstype = " . GetDocType() . " and docsid = " . intval($docid);
1324  $sth = db_query($sql, $dbh);
1325  if (!$sth) {
1326  throw new exception ("SQL is not valid.", 1);
1327  }
1328  if (db_num_rows($sth) == 0) {
1329  throw new exception ("Document record is not found.", 2);
1330  }
1331 
1332  list($docid, $docname, $vendor) = db_fetch_array($sth, 0);
1333 
1334  $filename = null;
1335  $defaultFilename = "$docname.$vendor";
1336  $realDir = GetCuDirectory($cu);
1337  $defaultDir = GetGlobalDirectory();
1338  $filename = "$docname";
1339 
1340  if (!is_writable($realDir)) {
1341  throw new exception ("Directory is not writable.", 3);
1342  }
1343  $fullname = "$realDir/$filename";
1344 
1345  $contents = "";
1346  if (!is_readable($defaultDir)) {
1347  throw new exception ("Default directory is not readable.", 4);
1348  }
1349 
1350  $defaultFullname = "$defaultDir/$defaultFilename";
1351  if (file_exists($defaultFullname)) {
1352  $contents = file_get_contents($defaultFullname);
1353  if ($contents === false) {
1354  throw new exception ("Default contents are not readable.", 5);
1355  }
1356  if (!isset($contents) || trim($contents) == "") {
1357  throw new exception ("No default found.", 7);
1358  }
1359  }
1360 
1361  $results = SubstituteKeywords($contents, $cu);
1362  if ($results ["status"] !== "000") {
1363  throw new exception ($results ["error"], 8);
1364  }
1365  $contents = $results ["data"];
1366 
1367  $results = file_put_contents($fullname, $contents);
1368  if ($results === false) {
1369  throw new exception ("File was not written.", 6);
1370  }
1371 
1372  $results = SetFileMetadata($fullname);
1373  if ($results["status"] != "000") {
1374  throw new exception ("File metadata was not updated.", 10);
1375  }
1376 
1377  $returnArray = array("status" => "000", "error" => "", "info" => GetEstatementText() . " file was reverted successfully.",
1378  "data" => array("record" => array()));
1379 
1380  if (isset($docname)) {
1381  switch(trim($docname)) {
1382  case GetPdfDefsFile():
1383  // No need to complain if the pdfdefs file doesn't exist.
1384  $results = ExtractPdfDefsForms($cu);
1385  $returnArray["data"]["formList"] = $results["status"] === "000" ? array_keys($results["data"]["formArray"]) : array();
1386  break;
1387  }
1388  }
1389  } catch (exception $e) {
1390  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "data" => array("record" => array()));
1391  }
1392  return $returnArray;
1393 }
1394 
1395 /**
1396  * function SetFileMetadata($fullname, $isBackup = false)
1397  * Need to set file metadata every time it is created or updated (for the executable bit only).
1398  *
1399  * @param $fullname the full path for the file.
1400  * @param $isBackup if backup, do not set executable bit.
1401  *
1402  */
1403 function SetFileMetadata($fullname, $isBackup = false) {
1404  try {
1405  $docname = basename($fullname);
1406 
1407  // Add executable bit for executable files. Determine this from the file extension which is assumed to be the text after the last period.
1408  $pos = strrpos($docname, ".");
1409  $ext = $pos === false ? "" : substr($docname, $pos + 1);
1410  $execBit = GetExecPermission();
1411 
1412  $currentPerm = intval(substr(sprintf('%o', fileperms($fullname)), -4), 8);
1413  $neededFilePerms = GetFilePermissions();
1414 
1415  if (in_array($ext, GetExecutableFileExtensions())) {
1416  // ONLY care about the executable bit
1417 
1418  // If backup, unset it. If not backup, set it.
1419  if ($isBackup) {
1420  if (!chmod($fullname, $neededFilePerms)) {
1421  throw new exception ("Change mode failed.", 9);
1422  }
1423  } else {
1424  if (!chmod($fullname, $neededFilePerms | $execBit)) {
1425  throw new exception ("Change mode failed.", 10);
1426  }
1427  }
1428  } else if ($currentPerm != $neededFilePerms) {
1429  if (!chmod($fullname, $neededFilePerms)) {
1430  throw new exception ("Change mode failed.", 11);
1431  }
1432  }
1433 
1434  $returnArray = array("status" => "000", "error" => "");
1435  } catch (exception $e) {
1436  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
1437  }
1438  return $returnArray;
1439 }
1440 
1441 /**
1442  * function StartNewConfig($dbh, $cu, $vendor, $section)
1443  * Starts new configuration using the global defaults for a vendor
1444  *
1445  * @param $dbh -- the database connection
1446  * @param $cu -- the credit union
1447  * @param $vendor -- the vendor to use
1448  * @param $section -- the section to use
1449  *
1450  * @return "status" -- "000" if successful, nonzero otherwise
1451  * @return "error" -- "" if successful, nonempty otherwise
1452  * @return "data"."gridData" -- the new data. Data signature needs to match the read function.
1453  * @return "data"."currentVendor" -- needed for the message.
1454  * @return "data"."filesOverwritten" -- needed to show on confirm backup.
1455  * @return "data"."formList" -- a list of forms in the pdfdefs file (for estatement tab.)
1456  */
1457 function StartNewConfig($dbh, $cu, $vendor, $section) {
1458  try {
1459  $isGlobal = !isset($cu) || trim($cu) == "";
1460  if ($isGlobal) {
1461  throw new exception ("Cu is required.", 1);
1462  }
1463  $upperCaseCu = strtoupper(trim($cu));
1464 
1465  $dir = GetCuDirectory($cu);
1466 
1467  if (!is_writable($dir)) {
1468  throw new exception ("Directory is not writable.", 2);
1469  }
1470 
1471  // Step 1: gather data.
1472  $sql = "select d.docsid as docid, d.docsname as docname, d.docsdesc as descr, d.docsmaintsort as sort, trim(d.docstitle) as vendor,
1473  trim(e.docstitle) as vendorl from cucmsdocs d
1474  inner join cucmsdocs e on d.docsname = e.docsname and d.docstype = e.docstype and d.docsmaintsection = e.docsmaintsection
1475  and d.docstype = " . GetDocType() . " and d.docsmaintsection = '" . prep_save($section) . "' and d.docstitle = '" . prep_save($vendor, 100) . "'
1476  order by d.docsmaintsort, e.docstitle";
1477  $sth = db_query($sql, $dbh);
1478  if (!$sth) {
1479  throw new exception ("Select query failed.", 1);
1480  }
1481  $results = db_fetch_all($sth);
1482  $toBeAdded = $results === false ? array() : $results;
1483 
1484  $gridMap = array();
1485  $filesOverwritten = array();
1486  foreach($toBeAdded as $row) {
1487  if (!HCU_array_key_exists($row["docid"], $gridMap)) {
1488  $row["allvendors"] = array($row["vendorl"]);
1489  unset($row["vendorl"]);
1490  $gridMap[$row["docid"]] = $row;
1491 
1492  $filesOverwritten[] = trim($row["docname"]);
1493  } else {
1494  $gridMap[$row["docid"]]["allvendors"][] = $row["vendorl"];
1495  }
1496  }
1497  $toBeAdded = array_values($gridMap);
1498 
1499  if (count($toBeAdded) == 0) {
1500  throw new exception ("There is no configuration for $vendor.", 12);
1501  }
1502 
1503  $sql = "select d.docsid as docid, d.docsname as docname from cucmsdocs d
1504  inner join cucmsfrags f on d.docsid = f.docsid and f.cu = '" . prep_save($upperCaseCu, 10) . "'
1505  where d.docsmaintsection = '" . prep_save($section) . "' and d.docstype = " . GetDocType() . "
1506  order by d.docsmaintsort";
1507  $sth = db_query($sql, $dbh);
1508  if (!$sth) {
1509  throw new exception ("Select query failed.", 3);
1510  }
1511  $results = db_fetch_all($sth);
1512  $toBeDeleted = $results === false ? array() : $results;
1513 
1514  // Step 2: remove files.
1515  foreach ($toBeDeleted as $row) {
1516  $file = "$dir/" . $row["docname"];
1517  if (file_exists($file)) {
1518  if (!unlink($file)) {
1519  throw new exception ("$file was not deleted.", 4);
1520  }
1521  }
1522  }
1523 
1524  // Step 3: add files
1525  $globalDir = GetGlobalDirectory();
1526 
1527  if (!is_readable($globalDir)) {
1528  throw new exception ("Global Directory is not readable.", 6);
1529  }
1530 
1531  foreach ($toBeAdded as $row) {
1532  $saveFile = "$dir/" . $row["docname"];
1533  $retrieveFile = "$globalDir/" . $row["docname"] . ".$vendor";
1534  if (!file_exists($retrieveFile)) {
1535  throw new exception ("$retrieveFile does not exist.", 5);
1536  }
1537 
1538  $fileContents = file_get_contents($retrieveFile);
1539  if ($fileContents === false) {
1540  throw new exception ("$retrieveFile is not readable.", 8);
1541  }
1542 
1543  $results = SubstituteKeywords($fileContents, $cu);
1544  if ($results ["status"] !== "000") {
1545  throw new exception ("$retrieveFile could not translate correctly.", 14);
1546  }
1547  $fileContents = $results["data"];
1548 
1549  $results = file_put_contents($saveFile, $fileContents);
1550  if ($results === false) {
1551  throw new exception ("$saveFile is not writable.", 9);
1552  }
1553 
1554  $results = SetFileMetadata($saveFile);
1555  if ($results["status"] != "000") {
1556  throw new exception ("File metadata change failed.", 15);
1557  }
1558  }
1559 
1560  // No need to complain if the pdfdefs file doesn't exist.
1561  $results = ExtractPdfDefsForms($cu);
1562  $formList = $results["status"] === "000" ? array_keys($results["data"]["formArray"]) : array();
1563 
1564  if (!db_work ($dbh, HOMECU_WORK_BEGIN)) {
1565  throw new exception("Begin query failed.", 13);
1566  }
1567 
1568  // Step 4: remove records
1569  $docidsToDelete = array();
1570  foreach ($toBeDeleted as $row) {
1571  $docidsToDelete [] = intval($row["docid"]);
1572  }
1573 
1574  if (count($docidsToDelete) > 0) {
1575  $sql = "delete from cucmsfrags where cu = '" . prep_save($upperCaseCu, 10) . "' and docsid in (" . implode(",", $docidsToDelete) . ")";
1576  $sth = db_query($sql, $dbh);
1577  if (!$sth) {
1578  throw new exception ("Delete failed.", 110);
1579  }
1580  }
1581 
1582  // Step 5: add records
1583  $toAdd = array();
1584  foreach ($toBeAdded as $row) {
1585  $toAdd [] = "('" . prep_save($upperCaseCu, 10) . "', " . intval($row["docid"]) . ")";
1586  }
1587 
1588  if (count($toAdd) > 0) {
1589  $sql = "insert into cucmsfrags (cu, docsid) values " . implode(", ", $toAdd);
1590  $sth = db_query($sql, $dbh);
1591  if (!$sth) {
1592  throw new exception ("Add failed.", 111);
1593  }
1594  }
1595 
1596  if (!db_work ($dbh, HOMECU_WORK_COMMIT)) {
1597  throw new exception ("End query failed.", 113);
1598  }
1599 
1600  $returnArray = array("status" => "000", "error" => "", "data" => array("gridData" => $toBeAdded, "currentVendor" => $vendor,
1601  "filesAffected" => $filesOverwritten, "formList" => $formList),
1602  "operation" => "read", "section" => $section, "info" => "Configuration changed to $vendor successfully.");
1603  } catch (exception $e) {
1604  if ($e->getCode() >= 100) {
1605  db_work($dbh, HOMECU_WORK_ROLLBACK); // Got greater problems if this fails.
1606  }
1607 
1608  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "data" => array("gridData" => array()), "operation" => "read",
1609  "section" => $section);
1610  }
1611  return $returnArray;
1612 }
1613 
1614 /**
1615  * function ReadBackupFiles($dbh, $cu)
1616  * Reads the backup files
1617  *
1618  * @param $dbh -- the database connection
1619  * @param $cu -- the credit union
1620  *
1621  * @return "status" -- "000" if successful, nonzero otherwise
1622  * @return "error" -- "" if successful, nonempty otherwise
1623  * @return "data" -- a list of all the backup files.
1624  */
1625 function ReadBackupFiles($dbh, $cu) {
1626  try {
1627  $gridData = array();
1628  $backupSuffix = GetBackupSuffix();
1629 
1630  if (!isset($cu) || trim($cu) == "") {
1631  throw new exception ("Cu is required.", 1);
1632  }
1633 
1634  $dir = GetCuDirectory($cu);
1635 
1636  if (!is_writable($dir)) {
1637  throw new exception ("Cu directory is not writable.", 2);
1638  }
1639 
1640  if ($dh = opendir($dir)) {
1641  while (($file = readdir($dh)) !== false) {
1642  $split = explode(".", $file);
1643  $count = count($split);
1644  if ($count >= 3) {
1645  $keyword = $split [$count - 1];
1646  $maybe = $split [$count - 2];
1647 
1648  if ($maybe == $backupSuffix && filetype("$dir/$file") == "file") {
1649  $gridData[] = array("file" => $file, "keyword" => $keyword);
1650  }
1651  }
1652 
1653  }
1654  closedir($dh);
1655  }
1656  $returnArray = array("status" => "000", "error" => "", "data" => $gridData);
1657  } catch (exception $e) {
1658  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "data" => array());
1659  }
1660  return $returnArray;
1661 }
1662 
1663 /**
1664  * function MakeBackup($dbh, $cu, $keyword)
1665  * This makes a backup.
1666  *
1667  * @param $dbh -- the database connection
1668  * @param $cu -- the credit union
1669  * @param $keyword -- the keyword
1670  *
1671  * @return "status" -- "000" if successful, nonzero otherwise
1672  * @return "error" -- "" if successful, nonempty otherwise
1673  * @return "info" -- feedback that it was successful.
1674  */
1675 function MakeBackup($dbh, $cu, $keyword) {
1676  try {
1677  $gridData = array();
1678  $backupSuffix = GetBackupSuffix();
1679 
1680  if (!isset($cu) || trim($cu) == "") {
1681  throw new exception ("Cu is required.", 1);
1682  }
1683 
1684  if (!isset($keyword) || trim($keyword) == "") {
1685  throw new exception ("Keyword is required.", 3);
1686  }
1687 
1688  $sql = "select d.docsid as docid, d.docsname as docname, d.docstitle as vendor, docsdesc as descr, docsmaintsection as section from cucmsdocs d
1689  where docstype = " . GetDocType();
1690  $sth = db_query($sql, $dbh);
1691 
1692  if (!$sth) {
1693  throw new exception ("Select has errors.", 4);
1694  }
1695 
1696  $validFiles = array();
1697  $results = db_fetch_all($sth, $dbh);
1698  $results = $results === false ? array() : $results;
1699  foreach($results as $row) {
1700  $validFiles[] = trim($row["docname"]);
1701  }
1702 
1703  $dir = GetCuDirectory($cu);
1704 
1705  if (!is_writable($dir)) {
1706  throw new exception ("Cu directory is not writable.", 2);
1707  }
1708 
1709  if ($dh = opendir($dir)) {
1710  while (($file = readdir($dh)) !== false) {
1711  if (in_array($file, $validFiles)) {
1712  $oldFile = "$dir/$file";
1713  $newFile = "$dir/$file.$backupSuffix.$keyword";
1714  if (!copy($oldFile, $newFile)) {
1715  throw new exception ("File wasn't copied.", 5);
1716  }
1717 
1718  $results = SetFileMetadata($newFile, true);
1719  if ($results["status"] != "000") {
1720  throw new exception ("Metadata was not updated.", 6);
1721  }
1722 
1723  $gridData[] = array("file" => "$file.$backupSuffix.$keyword", "keyword" => $keyword);
1724  } else {
1725  $split = explode(".", $file);
1726  $count = count($split);
1727  if ($count >= 3) {
1728  $testKeyword = $split [$count - 1];
1729  $maybe = $split [$count - 2];
1730 
1731  if ($maybe == $backupSuffix && filetype("$dir/$file") == "file") {
1732  $gridData[] = array("file" => $file, "keyword" => $testKeyword);
1733  }
1734  }
1735  }
1736  }
1737  closedir($dh);
1738  }
1739 
1740  $returnArray = array("status" => "000", "error" => "", "data" => $gridData, "info" => "Backup was made successfully.");
1741  } catch (exception $e) {
1742  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "data" => array());
1743  }
1744  return $returnArray;
1745 }
1746 
1747 /**
1748  * function RemoveBackup($dbh, $cu, $keyword)
1749  * This removes the backup according to the keyword. (All files ending with .bk.$keyword are removed.)
1750  *
1751  * @param $dbh -- the database connection
1752  * @param $cu -- the credit union
1753  * @param $keyword -- the $keyword that appears at the end of the file name.
1754  *
1755  * @return "status" -- "000" if successful, nonzero otherwise
1756  * @return "error" -- "" if successful, nonempty otherwise
1757  * @return "info" -- feedback that it was successful.
1758  * @return "data" -- a list of backup files after the deletion.
1759  */
1760 function RemoveBackup($dbh, $cu, $keyword) {
1761  try {
1762  $gridData = array();
1763  $backupSuffix = GetBackupSuffix();
1764 
1765  if (!isset($cu) || trim($cu) == "") {
1766  throw new exception ("Cu is required.", 1);
1767  }
1768 
1769  if (!isset($keyword) || trim($keyword) == "") {
1770  throw new exception ("Keyword is required.", 3);
1771  }
1772 
1773  $dir = GetCuDirectory($cu);
1774 
1775  if (!is_writable($dir)) {
1776  throw new exception ("Cu directory is not writable.", 2);
1777  }
1778 
1779  if ($dh = opendir($dir)) {
1780  while (($file = readdir($dh)) !== false) {
1781  $split = explode(".", $file);
1782  $count = count($split);
1783 
1784  if ($count >= 3) {
1785  $testKeyword = $split [$count - 1];
1786  $maybe = $split [$count - 2];
1787 
1788  if ($maybe == $backupSuffix && filetype("$dir/$file") == "file") {
1789  if ($testKeyword == $keyword) {
1790  if (!unlink("$dir/$file")) {
1791  throw new exception ("File could not be deleted.", 3);
1792  }
1793  } else {
1794  $gridData[] = array("file" => $file, "keyword" => $testKeyword);
1795  }
1796  }
1797  }
1798 
1799  }
1800  closedir($dh);
1801  }
1802 
1803  $returnArray = array("status" => "000", "error" => "", "data" => $gridData, "info" => "Backup was removed successfully.");
1804  } catch (exception $e) {
1805  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "data" => array());
1806  }
1807  return $returnArray;
1808 }
1809 
1810 /**
1811  * function ViewBackup($dbh, $cu, $file)
1812  * This will view the backup file.
1813  *
1814  * @param $dbh -- the database connection (verifies the information so you cannot request any file.)
1815  * @param $cu -- the credit union
1816  * @param $file -- the file (basename)
1817  *
1818  * @return "status" -- "000" if successful, nonzero otherwise
1819  * @return "error" -- "" if successful, nonempty otherwise
1820  * @return "data"."file" -- the file viewed.
1821  * @return "data"."contents" -- the contents of the file.
1822  * @return "operation" -- "backup"
1823  */
1824 function ViewBackup($dbh, $cu, $file) {
1825  try {
1826  if (!isset($cu) || trim($cu) == "") {
1827  throw new exception ("Cu is required.", 1);
1828  }
1829 
1830  if (!isset($file) || trim($file) == "") {
1831  throw new exception ("File is required.", 3);
1832  }
1833 
1834  $matches = null;
1835  if (preg_match('/^(.*)[.](' . GetBackupSuffix() . '[.][^.]+)$/', $file, $matches) !== 1){
1836  throw new exception ("File is not valid.", 9);
1837  }
1838  $regularFile = $matches[1];
1839 
1840  // If it is valid, then there should be an entry in the doc table for this file.
1841  $sql = "select 'FOUND' from cucmsdocs d
1842  where d.docsname = '" . prep_save($regularFile, 50) . "' and docsmaintsection is not null
1843  and docstype = " . GetDocType();
1844 
1845  $sth = db_query($sql, $dbh);
1846  if (!$sth) {
1847  throw new exception ("Found query failed.", 5);
1848  }
1849  if (db_num_rows($sth) == 0) {
1850  throw new exception ("File is not valid.", 6);
1851  }
1852 
1853  $dir = GetCuDirectory($cu);
1854 
1855  if (!is_readable($dir)) {
1856  throw new exception ("Cu directory is not writable.", 2);
1857  }
1858 
1859  if (!is_readable("$dir/$file")) {
1860  throw new exception ("File is not readable.", 7);
1861  }
1862 
1863  $contents = file_get_contents("$dir/$file");
1864  if ($contents === false) {
1865  throw new exception ("File is not readable.", 8);
1866  }
1867 
1868  $returnArray = array("status" => "000", "error" => "", "data" => array("file" => $file, "contents" => $contents), "operation" => "backup");
1869  } catch (exception $e) {
1870  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage(), "operation" => "backup", "data" => array());
1871  }
1872  return $returnArray;
1873 }
1874 
1875 /**
1876  * function TestPdfDefs ($cu, $selectedForm)
1877  * Creates an input file with the pdfdef file plus the selected form.
1878  * Then calls the TestPdfFile function to create a PDF.
1879  *
1880  * @param $cu -- the credit union
1881  * @param $selectedForm -- the selected form
1882  *
1883  * @return $status -- "000" if successful, nonzero otherwise.
1884  * @return $error -- "" if successful, nonempty otherwise.
1885  */
1886 function TestPdfDefs ($cu, $selectedForm) {
1887  try {
1888  $results = ExtractPdfDefsForms($cu, true);
1889  if ($results["status"] !== "000") {
1890  throw new exception ("Forms are not valid.", 1);
1891  }
1892  extract($results["data"]);
1893 
1894  $useformLine = HCU_array_key_value($selectedForm, $formArray);
1895 
1896  if ($useformLine === false) {
1897  throw new exception ("Form is not found.", 2);
1898  }
1899 
1900  $contents .= "\n$useformLine";
1901 
1902  $inputFile = GetDefaultTmpInput($cu);
1903 
1904  $results = file_put_contents($inputFile, $contents);
1905  if ($results === false) {
1906  throw new exception ("Temporary file was not created.", 3);
1907  }
1908 
1909  $returnArray = TestPdfFile($inputFile, $cu);
1910 
1911  } catch (exception $e) {
1912  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
1913  }
1914  return $returnArray;
1915 }
1916 
1917 /**
1918  * function TestPdfDisclosure ($dbh, $cu, $docid, $section)
1919  * Calls the TestPdfFile function with the input file being the disclosure file.
1920  *
1921  * @param $dbh -- the database connection
1922  * @param $cu -- the credit union
1923  * @param $docid -- the docid of the disclosure form
1924  * @param $section -- the section of the disclosure form
1925  *
1926  * @return $status -- "000" if successful, nonzero otherwise.
1927  * @return $error -- "" if successful, nonempty otherwise.
1928  */
1929 function TestPdfDisclosure ($dbh, $cu, $docid, $section) {
1930  try {
1931  $sql = "select docsname, docstitle
1932  from cucmsdocs
1933  where docsid = " . intval($docid) . " and docsmaintsection = '" . prep_save($section) . "'
1934  and docstype = " . GetDocType();
1935  $sth = db_query($sql, $dbh);
1936  if (!$sth) {
1937  throw new exception ("Query failed.", 1);
1938  }
1939  if (db_num_rows($sth) <= 0) {
1940  throw new exception ("File not found.", 2);
1941  }
1942  list($file, $vendor) = db_fetch_row($sth, 0);
1943 
1944  if ($section == "Utility") {
1945  $inputFile = GetGlobalDirectory() . "/" . basename($file) . "." . $vendor;
1946  } else {
1947  $inputFile = GetCuDirectory($cu) . "/" . basename($file);
1948  }
1949 
1950  $returnArray = TestPdfFile($inputFile, $cu);
1951  } catch (exception $e) {
1952  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
1953  }
1954  return $returnArray;
1955 }
1956 
1957 /**
1958  * function TestPdfFile ($inputFile, $cu)
1959  * Tests an input file by running the pdf writer script and then tests the output file.
1960  *
1961  * @param $inputFile -- the input file to create the output file from.
1962  * @param $cu -- the credit union
1963  *
1964  * @return $status -- "000" if successful, nonzero otherwise.
1965  * @return $error -- "" if successful, nonempty otherwise.
1966  */
1967 function TestPdfFile ($inputFile, $cu) {
1968  try {
1969  $outputFile = GetDefaultTmpOutput($cu);
1970 
1971  if (!file_exists($inputFile)) {
1972  throw new exception ("input file doesn't exist.", 1);
1973  }
1974 
1975  $cmd = "/opt/odyssey/tools/bin/pdffile.cgi $inputFile $outputFile 2>&1";
1976  $output = array();
1977  $returnVar = "";
1978  $results = exec($cmd, $output, $returnVar);
1979 
1980  if ($results === false) {
1981  throw new exception ("Command failed.", 2);
1982  }
1983 
1984  if ($results !== "") {
1985  throw new exception ($results, 3);
1986  }
1987 
1988  if (!file_exists($outputFile)) {
1989  throw new exception ("output file wasn't created successfully.", 4);
1990  }
1991 
1992  $returnArray = array("status" => "000", "error" => "");
1993  } catch (exception $e) {
1994  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
1995  }
1996  return $returnArray;
1997 }
1998 
1999 /**
2000  * function ViewPdfTestOutput($cu)
2001  * Shows the output PDF file.
2002  *
2003  * @param $cu -- the credit union
2004  */
2005 function ViewPdfTestOutput($cu) {
2006 
2007  $pdffile = fopen(GetDefaultTmpOutput($cu), "r");
2008  $sArray = fstat($pdffile);
2009  $size = $sArray["size"];
2010  header ("Content-Type: application/pdf");
2011  header ("Content-length: $size");
2012  fpassthru ($pdffile);
2013  pclose ($pdffile);
2014 }