Odyssey
pdfupload.prg
1 <?php
2 
3 /**
4  * @author MWS <miki@homecu.net>
5  * 4/1/2014
6  * @package pdfupload
7  *
8  * Changed the MAX_FILE_SIZE from 4000000 to 10485760 for ALL pdf uploads
9  *
10  */
11 
12 $parameters= array("a" => array("operation" => "", "filename" => ""));
13 $string= array("filter" => FILTER_SANITIZE_STRING);
14 HCU_ImportVars($parameters, "a", array("operation" => $string, "filename" => $string));
15 extract($parameters["a"]);
16 
17 $self= "$menu_link?ft=$ft";
18 
19 /**
20  * @package Globals */
21 
22 /**
23  * @var integer $maxSize-- refers to the maximum size that the system will allow being uploaded to www3, www5, www6 */
24 $maxSize= 10485760;
25 
26 /**
27  * @var string $dataURL-- what is needed to reference this page. */
28 $dataURL= "$menu_link?ft=$ft";
29 
30 /**
31  * @var boolean $showSQL-- for debugging the sql. */
32 $showSQL= $SYSENV["devmode"];
33 
34 /**
35  * @var string $uploadPath-- the directory to save the files to. */
36 $uploadPath= "$home_path/public_html/pdf/";
37 
38 /**
39  * @var array $allowedFiles-- the particular files available. Must be in this list to be uploaded. $allowedFiles["files"]-- list of files (keys) and file to save (values),
40  * $allowedFiles["allowDelete"]-- boolean, if true, the removeFile button is visible when file is selected and the file is allowed to be deleted (if the URL is called directly)
41  * $allowedFiles["alwaysShow"]-- boolean, if true, the file allows shows in the list. Normally, files are only shown if there is a version in the directory. */
42 
43 $allowedFiles= array(
44  "HomeBanking" => array(
45  "HomeBanking" => array(
46  "Estatement Inserts" => "insert.pdf",
47  "Privacy Policy" => "privacy.pdf",
48  "Fee Schedule" => "fees.pdf"
49  )
50  ),
51  "publicHTML" => array(
52  "Newsletters" => array(
53  "Regular Newsletter" => "newsletter.pdf",
54  "Quarterly Newsletter" => "quarterlynews.pdf",
55  "Youth Newsletter" => "kidsnews.pdf",
56  "Prime Newsletter" => "primenews.pdf",
57  "Senior Newsletter" => "seniornews.pdf",
58  "Teen Newsletter" => "teennews.pdf",
59  "Middle School Newsletter" => "middleschoolnews.pdf"
60  ),
61  "Miscellaneous (For information about linking documents, contact HomeCU.)" => array(
62  "Loan Rates" => "lrates.pdf",
63  "Savings Rates" => "srates.pdf",
64  "Sales (Repo) List" => "forsale.pdf",
65  "General Information" => "info.pdf",
66  "Annual Report" => "annualreport.pdf",
67  "Financial Statement" => "financials.pdf",
68  "Skip-A-Payment Form" => "skip-pay.pdf",
69  "Scholarship Application" => "scholarship.pdf",
70  "Funds Availability" => "funds.pdf",
71  "Holiday Schedule" => "holidays.pdf"
72  )
73  )
74 );
75 
76 // DATABASE
77 $operation= trim($operation);
78 if ($operation != "")
79 {
80  $notJSON= false;
81  switch($operation)
82  {
83  case "uploadFile":
84  $returnArray= uploadFile($uploadPath, $filename, $allowedFiles, $maxSize);
85  break;
86  case "removeFile":
87  $returnArray= removeFile($uploadPath, $filename, $allowedFiles);
88  break;
89  case "readHomeBanking":
90  $files= HCU_array_key_exists("HomeBanking", $allowedFiles) ? $allowedFiles["HomeBanking"] : array();
91  $returnArray= getFileList($dbh, $Cu, $files, $uploadPath, "regular");
92  break;
93  case "readPublicHTML":
94  $files= HCU_array_key_exists("publicHTML", $allowedFiles) ? $allowedFiles["publicHTML"] : array();
95  $returnArray= getFileList($dbh, $Cu, $files, $uploadPath, "grouped");
96  break;
97  case "previewFile":
98  printFilePreview($uploadPath, $filename, $allowedFiles);
99  $notJSON= true;
100  break;
101  default: // Won't get here
102  $returnArray= array("error" => array("Operation not specified: '$operation'"), "record" => array(), "sql" => array());
103  }
104 
105  if (!$notJSON)
106  {
107  header('Content-type: application/json');
108  print HCU_JsonEncode($returnArray);
109  }
110 
111 }
112 // Presentation
113 else
114 {
115  ?>
116 
117  <script type="text/javascript">
118 
119  <?php
120  // Include common functions
121  getShowWaitFunctions();
122 
123  /**
124  * @package Frontend */ ?>
125 
126  <?php
127  /**
128  * function openConfirmFileRemoval(tr)
129  * Opens up the confirmation for deleting the file with options "No" and "Yes." No resets the selection and does nothing else. Yes removes the file from the table and the directory.
130  *
131  * @param HTMLElement tr -- the table row of the selection. From this, I can get everything that I need.
132  */
133  ?>
134  function openConfirmFileRemoval(tr)
135  {
136  var confirmFileRemoval= $("#confirmFileRemoval").data("kendoDialog");
137  if (confirmFileRemoval == null)
138  {
139  confirmFileRemoval= $("<div id='confirmFileRemoval'></div>").appendTo("body").kendoDialog({
140  title: "Confirm File Removal",
141  actions: [
142  {text: "No", action: function() {
143  <?php // Action has been fired off. Now reset to status before action. ?>
144  var tr= $("#confirmFileRemoval").data("tr");
145  var ddl= $(tr).closest(".k-grid").find(".k-grid-toolbar [data-role='dropdownlist']").data("kendoDropDownList");
146  ddl.enable(false);
147  ddl.value(1);
148  $("[name='actionSelection']:checked").prop("checked", false);
149  }},
150  {text: "Yes", primary: true, action: function() {
151  var tr= $("#confirmFileRemoval").data("tr");
152 
153  <?php // Action has been fired off. Now reset to status before action. ?>
154  var ddl= $(tr).closest(".k-grid").find(".k-grid-toolbar [data-role='dropdownlist']").data("kendoDropDownList");
155  ddl.enable(false);
156  ddl.value(1);
157 
158  $(tr).closest(".k-grid").data("kendoGrid").removeRow($(tr));
159  }}
160  ],
161  visible: false,
162  open: function() {
163  if (window.activeWindows != null)
164  window.activeWindows.push(this);
165  },
166  close: function() {
167  if (window.activeWindows != null)
168  window.activeWindows.pop();
169  }
170  }).data("kendoDialog");
171  }
172 
173  var grid= $(tr).closest(".k-grid").data("kendoGrid");
174  var dataItem= grid.dataItem(tr);
175  confirmFileRemoval.content("<p>This file \"" + dataItem.filename + "\" will be deleted.</p><p>Are you sure you want to do this?</p>").open();
176  $("#confirmFileRemoval").data("tr", tr);
177  }
178 
179  <?php
180  /**
181  * function openUploadDialog(tr)
182  * This opens up the dialog needed for upload. If the uploader is not already initialized, then it intializes that.
183  *
184  * @param HTMLElement tr -- the table row of the selection. From this, I can get everything that I need.
185  */
186  ?>
187  function openUploadDialog(tr)
188  {
189  var uploadDialog= $("#uploadDialog").data("kendoDialog");
190  var template= kendo.template($("#uploadTemplate").html());
191  if (uploadDialog == null)
192  {
193  uploadDialog= $("<div id='uploadDialog'></div>").appendTo("body").kendoDialog({
194  title: "Upload File",
195  content: $("#uploadTemplate").html(),
196  actions: [
197  {text: "Cancel", action: function() {
198  $("#uploader").data("kendoUpload").clearAllFiles();
199 
200  <?php // Action has been fired off. Now reset to status before action. ?>
201  var tr= $("#uploadDialog").data("tr");
202  var ddl= $(tr).closest(".k-grid").find(".k-grid-toolbar [data-role='dropdownlist']").data("kendoDropDownList");
203  ddl.enable(false);
204  ddl.value(1);
205  $("[name='actionSelection']:checked").prop("checked", false);
206  }},
207  {text: "Upload", primary: true, action: function() {
208  $("#uploader").data("kendoUpload").upload(); <?php // Manually triggers the upload process. ?>
209  return false;
210  }}
211  ],
212  visible: false,
213  open: function() {
214  if (window.activeWindows != null)
215  window.activeWindows.push(this);
216  },
217  close: function() {
218  $.homecuValidator.setup({formValidate:'pdfuploadDiv', formStatusField: 'statusDiv'});
219  if (window.activeWindows != null)
220  window.activeWindows.pop();
221  }
222  }).data("kendoDialog");
223 
224  var uploader= $("#uploader").kendoUpload({
225  async: {
226  saveUrl: "<?php echo $self; ?>&operation=uploadFile",
227  withCredentials: true,
228  autoUpload: false
229  },
230  multiple: false,
231  showFileList: true,
232  error: function(e)
233  {
234  hideWaitWindow();
235  var response= e.XMLHttpRequest.responseText;
236 
237  if (response.indexOf("PDFUploadFirstErrorLi") != -1)
238  {
239  $("#formValidateMainDiv").show();
240  $("#formValidateMainDiv").html("<p>The following errors were detected:</p><ul>" + response + "</ul>");
241  }
242  else
243  {
244  openAuthFailedDialog(response);
245  }
246 
247  <?php // Action has been fired off. Now reset to status before action. ?>
248  var tr= $("#uploadDialog").data("tr");
249  var ddl= $(tr).closest(".k-grid").find(".k-grid-toolbar [data-role='dropdownlist']").data("kendoDropDownList");
250  ddl.enable(false);
251  ddl.value(1);
252  this.clearAllFiles();
253  },
254  success: function(e)
255  {
256  hideWaitWindow();
257  if (e.response.code == 0)
258  {
259  var tr= $("#uploadDialog").data("tr");
260  var grid= $(tr).closest(".k-grid").data("kendoGrid");
261  grid.dataSource.read();
262  this.clearAllFiles();
263  $("#uploadDialog").data("kendoDialog").close();
264  }
265  else
266  {
267  $.homecuValidator.displayMessage(e.response.error, $.homecuValidator.settings.statusError );
268  e.preventDefault();
269  return false;
270  }
271 
272  },
273  select: function(e) <?php // When a file is selected. If we can prevent at this level, then the user doesn't have to click on the upload to know that the file is invalid. ?>
274  {
275  var error= "";
276  var tr= $("#uploadDialog").data("tr");
277 
278  try
279  {
280  if ($(tr).length == 0)
281  throw "Please select a file.";
282 
283  var file= e.files[0];
284  if (file.extension.toLowerCase() != ".pdf")
285  throw "File needs to be a PDF.";
286 
287  if (file.size > <?php echo $maxSize; ?>)
288  throw "File exceeds the max size.";
289  }
290  catch(err)
291  {
292  error= err;
293  }
294 
295  if (error.length != "")
296  {
297  $.homecuValidator.displayMessage(error, $.homecuValidator.settings.statusError );
298  e.preventDefault();
299  return false;
300  }
301  },
302  upload: function(e)
303  {
304  var error= "";
305  var tr= $("#uploadDialog").data("tr");
306 
307  try
308  {
309  if ($(tr).length == 0)
310  throw "Please select a file.";
311 
312  var file= e.files[0];
313  if (file.extension.toLowerCase() != ".pdf")
314  throw "File needs to be a PDF.";
315 
316  if (file.size > <?php echo $maxSize; ?>)
317  throw "File exceeds the max size.";
318  }
319  catch(err)
320  {
321  error= err;
322  }
323 
324  if (error.length != "")
325  {
326  $.homecuValidator.displayMessage(error, $.homecuValidator.settings.statusError );
327  e.preventDefault();
328  return false;
329  }
330  else
331  {
332  showWaitWindow();
333  var grid= $(tr).closest(".k-grid").data("kendoGrid");
334  var dataItem= grid.dataItem($(tr));
335  e.data= {filename: dataItem.filename};
336  showWaitWindow();
337  }
338  },
339  localization: {
340  select: "Select File"
341  }
342  }).data("kendoUpload");
343 
344  $("#uploadBtn").click(function() { $("#uploader").click(); return false; });
345  $("#uploadFileBtn").click(function() { $(".k-upload-selected").click(); return false; });
346  }
347 
348  var grid= $(tr).closest(".k-grid").data("kendoGrid");
349  var dataItem= grid.dataItem(tr);
350 
351  $("#uploadDialog").find(".filename").text(dataItem.filename);
352  if (dataItem.modified == null)
353  $("#uploadDialog").find(".modified").hide();
354  else
355  {
356  $("#uploadDialog").find(".modified").show();
357  $("#uploadDialog").find(".size").text(dataItem.size);
358  }
359  uploadDialog.open();
360  $("#uploadDialog").data("tr", tr);
361  $.homecuValidator.setup({formValidate:'uploadDialog', formStatusField: 'uploadStatusDiv'});
362  }
363 
364  <?php
365  /**
366  * function openAuthFailedDialog(response)
367  * This opens a dialog if the uploader fails.
368  *
369  * @param response -- the response from the uploader.
370  */
371  ?>
372  function openAuthFailedDialog(response)
373  {
374  var authFailedDialog= $("#authFailedDialog").data("kendoWindow");
375  if (authFailedDialog != null)
376  {
377  authFailedDialog.destroy();
378  $("#authFailedDialog").empty();
379  }
380 
381  authFailedDialog= $("#authFailedDialog").kendoWindow({
382  content: {template: response.replace(/[#]/g, "\\#")}, // have to escape the # for kendo.
383  draggable: false,
384  visible: false,
385  actions: [],
386  modal: true,
387  title: false,
388  width: 400,
389  resizable: false
390  }).data("kendoWindow");
391 
392  authFailedDialog.open().center();
393  }
394 
395  <?php
396  /**
397  * function openFileWindow(filename)
398  * This opens the window for previewing the file. The files are in PDF format so there is an iframe of the contents of the file.
399  *
400  * @param string filename -- the filename from the dataItem of the selection.
401  */
402  ?>
403  function openFileWindow(filename)
404  {
405  var fileWindow= $("#fileWindow").data("kendoWindow");
406  if (fileWindow == null)
407  {
408  var fileWindow= $("<div id='fileWindow'></div>").appendTo("body").kendoWindow({
409  visible: false,
410  open: function() {
411  if (window.activeWindows != null)
412  window.activeWindows.push(this);
413  },
414  close: function() {
415  if (window.activeWindows != null)
416  window.activeWindows.pop();
417  },
418  width: 600,
419  title: "View File",
420  modal: true
421  }).data("kendoWindow");
422 
423  $("#fileWindow").on("click", ".closeBtn", function() {
424  $("#fileWindow").data("kendoWindow").close();
425  });
426  }
427 
428  var template= kendo.template('<div class="hcu-template"><embed height="100%" width="100%" id="viewIframe" src="<?php echo $self; ?>&operation=previewFile&filename=#: filename #"'
429  + 'type="application/pdf"><div class="hcu-edit-buttons k-state-default"><a class="closeBtn k-button k-primary" href="\\#"><i class="fa fa-check"></i>Close</a></div></div>');
430  fileWindow.content(template({operation: "viewFile", filename: filename})).open().center();
431  }
432 
433  <?php
434  /**
435  * function initGrids()
436  * This function initializes the grids which is the first step. All other functions run off of this one.
437  */
438  ?>
439  function initGrids()
440  {
441  $.homecuValidator.setup({formValidate:'pdfuploadDiv', formStatusField: 'statusDiv'});
442  var gridDefinition= {
443  dataSource: {
444  transport: {
445  read: null, <?php // There are two grids that are being created with different URLs. ?>
446  destroy: { url: "<?php echo $self; ?>&operation=removeFile", dataType: "json", type: "POST" },
447  parameterMap: function(data, type) {
448  switch(type)
449  {
450  case "read":
451  return {};
452  case "destroy":
453  return {filename: data.filename};
454  }
455  }
456  },
457  schema: {
458  model: {
459  id: "kendoId",
460  fields: {
461  kendoId: {type: "number"},
462  filename: {type: "string"},
463  modified: {type: "string"},
464  size: {type: "string"},
465  type: {type: "string"}
466  }
467  },
468  errors: "error",
469  data: "data",
470  groups: "data"
471  },
472  error: function(e) {
473  $.homecuValidator.displayMessage(e.errors, $.homecuValidator.settings.statusError );
474  },
475  requestEnd: function(e) {
476  hideWaitWindow();
477 
478  <?php // Action has been fired off. Now reset to status before action. ?>
479  var selected= $("[name='actionSelection']:checked");
480  if ($(selected).length > 0)
481  {
482  var ddl= $(selected).closest(".k-grid").find(".k-grid-toolbar [data-role='dropdownlist']").data("kendoDropDownList");
483  ddl.enable(false);
484  ddl.value(1);
485  }
486 
487  if (e.type == "destroy" && this.options.serverGrouping)
488  {
489  this.read();
490  }
491  }
492  },
493  columns: [
494  {width: 30}, <?php // radio button. ?>
495  {width: 30}, <?php // Preview icon. ?>
496  {field: "filename", title: "Name"},
497  {field: "modified", title: "Modified"},
498  {field: "size", title: "Size"}
499  ],
500  editable: {
501  mode: "inline",
502  confirmation: false
503  },
504  remove: function(e) {
505  this.dataSource.add({id: e.model.id, kendoId: e.model.kendoId, filename: e.model.filename, type: e.model.type, modified: null, size: null});
506  this.dataSource.sync();
507  <?php // Readds the record without modified and size. ?>
508  }
509  };
510 
511  var template= $("#rowTemplate").html();
512  var hbTemplate= template.replace("#####", "");
513  var phTemplate= template.replace("#####", "<td></td>"); <?php // for the grouping column. ?>
514  gridDefinition.dataSource.transport.read= {url: "<?php echo $self; ?>&operation=readHomeBanking", dataType: "json", type: "POST"};
515  gridDefinition.toolbar= "<div id='actionHomeBankingDDL'></div>";
516  gridDefinition.rowTemplate= hbTemplate;
517  var homeBankingGrid= $("#homeBankingGrid").kendoGrid(gridDefinition).data("kendoGrid");
518  gridDefinition.dataSource.transport.read= {url: "<?php echo $self; ?>&operation=readPublicHTML", dataType: "json", type: "POST"};
519  gridDefinition.toolbar= "<div id='actionPublicHTMLDDL'></div>";
520  gridDefinition.rowTemplate= phTemplate;
521  gridDefinition.columns.push({field: "type", hidden: true, groupHeaderTemplate: "#: value #"})
522  gridDefinition.dataSource.group= {field: "type"};
523  gridDefinition.dataSource.serverSorting= true;
524  gridDefinition.dataSource.serverGrouping= true;
525  gridDefinition.remove= undefined;
526  var publicHTMLGrid= $("#publicHTMLGrid").kendoGrid(gridDefinition).data("kendoGrid");
527 
528  var ddlDefinition= {
529  dataSource: [{text: "Action ...", value: 1}, {text: "Upload", value: 2}, {text: "Delete", value: 3}],
530  enable: false,
531  dataTextField: "text",
532  dataValueField: "value",
533  change: function(e) {
534 
535  var tr= $(this.wrapper).closest(".k-grid").find("tr:has([name='actionSelection']:checked)");
536  switch(this.value())
537  {
538  case 1: break; <?php // Nothing to do. Shows the "placeholder." ?>
539  case 2:
540  openUploadDialog(tr);
541  break;
542  case 3:
543  openConfirmFileRemoval(tr);
544  break;
545  }
546 
547 
548  }
549  };
550 
551  var actionHomeBankingDDL= $("#actionHomeBankingDDL").kendoDropDownList(ddlDefinition).data("kendoDropDownList");
552  var actionPublicHTMLDDL= $("#actionPublicHTMLDDL").kendoDropDownList(ddlDefinition).data("kendoDropDownList");
553 
554  <?php // Here are click events on the radio buttons to activate the DDL and only show the valid options. ?>
555  $("#homeBankingGrid,#publicHTMLGrid").on("click", "[name='actionSelection']", function() {
556  var tr= $(this).closest("tr");
557  var grid= $(tr).closest(".k-grid").attr("id");
558  if (grid == "homeBankingGrid")
559  {
560  var ddl= $("#actionHomeBankingDDL").data("kendoDropDownList");
561  var otherDDL= $("#actionPublicHTMLDDL").data("kendoDropDownList");
562  }
563  else
564  {
565  var otherDDL= $("#actionHomeBankingDDL").data("kendoDropDownList");
566  var ddl= $("#actionPublicHTMLDDL").data("kendoDropDownList");
567  }
568  grid= $("#"+grid).data("kendoGrid");
569  var dataItem= grid.dataItem($(tr));
570  var filter= dataItem.modified == null ? {field: "value", operator: "neq", value: 3} : []; <?php // Cannot delete if there is no file there. ?>
571  ddl.enable(true);
572  ddl.dataSource.filter(filter);
573 
574  <?php // Make sure that other DDL is disabled. (When the user selects one in one grid and then selects a row in the other grid.) ?>
575  otherDDL.value(1);
576  otherDDL.enable(false);
577  });
578 
579  $("#homeBankingGrid,#publicHTMLGrid").on("click", ".pdfPreview", function() {
580  var tr= $(this).closest("tr");
581  var grid= $(tr).closest(".k-grid").data("kendoGrid");
582  var dataItem= grid.dataItem($(tr));
583  openFileWindow(dataItem.filename);
584  });
585  }
586 
587  $(document).ready(function() {
588  initGrids();
589  });
590  </script>
591  <?php printDeleteTemplate(); ?>
592  <script id="rowTemplate" type="text/x-kendo-template">
593  # var fileExists= modified != null; #
594  <tr data-uid="#= uid #">
595  #####
596  <td><input type="radio" name="actionSelection"></td>
597  <td># if (fileExists) { # <i class="fa fa-search pdfPreview showClickable"></i> # } else { # &nbsp; # } #</td>
598  <td # if (!fileExists) { # colspan="3" # } #>#: filename #</td>
599  # if (fileExists) { #
600  <td>#= modified #</td>
601  <td>#: size #</td>
602  # } #
603  </tr>
604  </script>
605  <script id="uploadTemplate" type="text/x-kendo-template">
606  <div id="uploadStatusDiv"></div>
607  <div class="container-fluid">
608  <div class="row hcuSpacer vsgSecondary">Upload a file for <span class="filename"></span>.</div>
609  <div class="modified" style="display:none;"><div class="row hcuSpacer vsgSecondary">Upload will overwrite another file with a size of <span class="size"></span>.</div></div>
610  <div class="row hcuSpacer"><input type="file" name="files" id="uploader" accept="application/pdf" /></div>
611  </div>
612  </script>
613  <style>
614  .pdfuploadDiv ul{
615  list-style-position: inside;
616  }
617 
618  #uploadDialog .k-clear-selected, #uploadDialog .k-upload-selected, #uploadDialog .k-upload-status {
619  display: none;
620  }
621  </style>
622 
623  <div id="pdfuploadDiv" class="container-fluid pdfuploadDiv">
624  <div id="statusDiv"></div>
625  <div class="hcuSpacer hcu-no-padding">
626  <div class="well well-sm col-xs-12">
627  <div class="container-fluid">
628  <div class="row hcuSpacer h3">PDF File Upload</div>
629  <div class="row hcuSpacer">
630  Please Note:
631  <ul>
632  <li>Only one file of each type is allowed. Prior copies will be overwritten.</li>
633  <li>File must be a valid <font color='red'>PDF document.</font></li>
634  <li>File must be no larger than <font color='red'>10MB</font> in size.</li>
635  </ul>
636  Contact HomeCU to set up additional upload links in the lists below. Supported uploadable files include:
637  <ul>
638  <li>Newsletters - General, Quarterly, Seniors, Teens, Kids, Middle School</li>
639  <li>Statement Inserts</li>
640  <li>Fee Schedule, Savings Rates, Loan Rates, Sales (Repo) Listing</li>
641  <li>Privacy Policy</li>
642  <li>Annual Report</li>
643  <li>Financial Statement</li>
644  <li>General Information</li>
645  <li>Skip-A-Payment Form</li>
646  <li>Scholarship Application</li>
647  <li>Funds Availability</li>
648  <li>Holiday Schedule</li>
649  </ul>
650  </div>
651  </div>
652  </div>
653  </div>
654  <div class="hcuSpacer hcu-no-padding">
655  <div class="container-fluid">
656  <div class="row hcuSpacer h4">Digital Banking Uploads</div>
657  <div class="row hcuSpacer"><div id="homeBankingGrid"></div></div>
658  </div>
659  </div>
660  <div class="hcuSpacer hcu-no-padding">
661  <div class="container-fluid">
662  <div class="row hcuSpacer h4">Public HTML Uploads</div>
663  <div class="row hcuSpacer"><div id="publicHTMLGrid"></div></div>
664  </div>
665  </div>
666  </div>
667 <?php }
668 
669 /**
670  * @package FUNCTIONS
671  */
672 
673 /**
674  * function getFileList($dbh, $Cu, $files, $uploadPath, $mode)
675  * Gets the list of file for the grids.
676  *
677  * @param $dbh -- the database connection
678  * @param $Cu -- the credit union
679  * @param $files -- array of files to look through
680  * @param $uploadPath -- the path to look for files in
681  * @param $mode --
682  * "grouped" -- if the kendoGrid uses grouping.
683  * "regular" -- the kendoGrid doesn't use grouping.
684  *
685  * @return array --
686  * $data -- List of files and attributes for the grid.
687  * $error -- List of errors encountered.
688  * $code -- Non-error if error encountered.
689  */
690 function getFileList($dbh, $Cu, $files, $uploadPath, $mode)
691 {
692  $fileList= array();
693  $index= 0;
694  $tz= null;
695  $kbMin= 1024;
696  $mbMin= 1024*1024;
697  try
698  {
699  if (!is_writable($uploadPath))
700  throw new exception("PDF Directory is not set up correctly. Please contact HomeCU for assistance.");
701  foreach($files as $typeName => $typeFiles)
702  {
703  foreach($typeFiles as $fileName => $filePath)
704  {
705  $fullPath= "${uploadPath}${filePath}";
706  $modified= null;
707  $size= null;
708 
709  if (is_readable($fullPath))
710  {
711  // Get the modified timestamp from the file function and then convert it to the CU time in the right format.
712  $modified= DateTime::createFromFormat("U", filemtime($fullPath));
713  if (!isset($tz))
714  $tz= new DateTimeZone(GetCreditUnionTimezone($dbh, $Cu));
715  $modified->setTimezone($tz);
716  $modified= $modified->format("m/d/Y H:i:s");
717 
718  $size= filesize($fullPath);
719  if ($size < $kbMin)
720  $size= "$size B";
721  else if ($size < $mbMin)
722  $size= round($size/$kbMin, 2) . " KB";
723  else
724  $size= round($size/$mbMin, 2) . " MB";
725  }
726 
727  $row= array("kendoId" => ++$index, "filename" => $fileName, "type" => $typeName, "modified" => $modified, "size" => $size);
728  if ($mode == "grouped")
729  {
730  if (!HCU_array_key_exists($typeName, $fileList))
731  $fileList[$typeName]= array("field" => "type", "value" => $typeName, "items" => array(), "hasSubgroups" => false, "aggregates" => array());
732  $fileList[$typeName]["items"][]= $row;
733  }
734  else
735  $fileList[]= $row;
736  }
737  }
738 
739  if ($mode == "grouped")
740  $fileList= array_values($fileList);
741 
742  return array("data" => $fileList);
743  }
744  catch(exception $e)
745  {
746  return array("error" => $e->getMessage(), "code" => $e->getCode());
747  }
748 }
749 
750 /**
751  * function uploadFile($uploadPath, $filename, $allowedFiles, $maxSize)
752  * This function uploads a file to the $uploadPath if validated.
753  *
754  * @param $uploadPath -- the path to upload file to.
755  * @param $filename -- the title of the file. This corresponds to the key in the array $allowedFiles.
756  * @param $allowedFiles -- the array of files to search for filename in.
757  * @param $maxSize -- if the size of the file is greater than this, this function returns an error message.
758  *
759  * @return array --
760  * $code -- zero if successful, non-zero otherwise.
761  * $error -- error message if not successful.
762  */
763 function uploadFile($uploadPath, $filename, $allowedFiles, $maxSize)
764 {
765  try
766  {
767  $fileErrors= array(
768  "1" => "1: The file you tried to upload is just too big. The allowable limit is 10MB.",
769  "2" => "2: The file you tried to upload is just too big. The allowable limit is 10MB.",
770  "3" => "3: The file was only partially uploaded",
771  "4" => "4: no file was uploaded");
772 
773  $thisFilePath= null;
774  if (!isset($filename) || trim($filename) == "")
775  throw new exception("Please select a file to upload.", 1);
776  if (!is_writable($uploadPath))
777  throw new exception("PDF Directory is not set up correctly. Please contact HomeCU for assistance.", 2);
778  foreach($allowedFiles as $gridType => $files)
779  {
780  foreach($files as $typeName => $typeFiles)
781  {
782  foreach($typeFiles as $fileName => $filePath)
783  {
784  if (trim($fileName) == trim($filename))
785  {
786  $thisFilePath = $filePath;
787  break;
788  }
789  }
790  if (isset($thisFilePath))
791  break;
792  }
793  }
794 
795  if (!isset($thisFilePath))
796  throw new exception("File isn't valid.", 3);
797 
798  $file = $_FILES['files'];
799 
800  if ($file["size"] > $maxSize)
801  throw new exception("File exceeds the max size.", 4);
802  if ($file["error"] != 0)
803  {
804  $errorInt= $file["error"];
805  throw new exception(HCU_array_key_exists($errorInt, $fileErrors) ? $fileErrors[$errorInt] : "$errorInt: Unknown error.", 5);
806  }
807 
808  $filetmp = $file['tmp_name'];
809  $filemime = explode(";", trim(`file -bi $filetmp`));
810  if (strtolower($filemime[0]) != "application/pdf")
811  throw new exception("Wrong file type ( $filemime[0] ). File must be PDF document.", 6);
812  if (!@move_uploaded_file($filetmp, "${uploadPath}${thisFilePath}"))
813  {
814  @unlink ($filetmp);
815  throw new exception("Couldn't post the file where it belongs. Better call HomeCU.", 7);
816  }
817 
818  @chmod("${uploadPath}${thisFilePath}", 0644);
819  return array("code" => 0);
820  }
821  catch(exception $e)
822  {
823  return array("error" => $e->getMessage(), "code" => $e->getCode());
824  }
825 }
826 
827 /**
828  * function removeFile($uploadPath, $filename, $allowedFiles)
829  * This function removes a file if filename is found in $allowedFiles. Otherwise, it does nothing.
830  *
831  * @param $uploadPath -- the path to remove file from.
832  * @param $filename -- the title of the file. This corresponds to the key in the array $allowedFiles.
833  * @param $allowedFiles -- the array of files to search for filename in.
834  *
835  * @return array --
836  * $data -- If successful, this exists with two possibilities: "path found" or "path NOT found."
837  * $error -- the message text of an error if not successful.
838  * $code -- non-zero if not successful.
839  */
840 function removeFile($uploadPath, $filename, $allowedFiles)
841 {
842  try
843  {
844  $thisFilePath= null;
845  if (!isset($filename) || trim($filename) == "")
846  throw new exception("Please select a file to remove.", 3);
847  if (!is_writable($uploadPath))
848  throw new exception("PDF Directory is not set up correctly. Please contact HomeCU for assistance.", 1);
849  foreach($allowedFiles as $gridType => $files)
850  {
851  foreach($files as $typeName => $typeFiles)
852  {
853  foreach($typeFiles as $fileName => $filePath)
854  {
855  if (trim($fileName) == trim($filename))
856  {
857  $thisFilePath= $filePath;
858  break;
859  }
860  }
861  if (isset($thisFilePath))
862  break;
863  }
864  }
865 
866 
867  if (isset($thisFilePath)) // If file isn't find, treat that as a "success." Nothing found so nothing deleted.
868  {
869  $fullPath= "${uploadPath}${thisFilePath}";
870  if (@file_exists($fullPath) && !@unlink($fullPath)) // Not a problem if the file doesn't exist to begin with.
871  throw new exception("File could not be deleted. Better call HomeCU.", 2);
872  }
873 
874  return array("data" => isset($thisFilePath) ? "path found" : "path NOT found");
875  }
876  catch(exception $e)
877  {
878  return array("error" => $e->getMessage(), "code" => $e->getCode());
879  }
880 }
881 
882 /**
883  * function printFilePreview($uploadPath, $filename, $allowedFiles)
884  * Shows the contents of a PDF if no errors. Otherwise send JSON of errors.
885  *
886  * @param $uploadPath -- the path which the file is.
887  * @param $filename -- the title of the file. This corresponds to the key in the array $allowedFiles.
888  * @param $allowedFiles -- the array of files to search for filename in.
889  */
890 function printFilePreview($uploadPath, $filename, $allowedFiles)
891 {
892  try
893  {
894  $thisFilePath= null;
895  if (!isset($filename) || trim($filename) == "")
896  throw new exception("Please select a file to remove.", 3);
897  if (!is_writable($uploadPath))
898  throw new exception("PDF Directory is not set up correctly. Please contact HomeCU for assistance.", 1);
899  foreach($allowedFiles as $gridType => $files)
900  {
901  foreach($files as $typeName => $typeFiles)
902  {
903  foreach($typeFiles as $fileName => $filePath)
904  {
905  if (trim($fileName) == trim($filename))
906  {
907  $thisFilePath= $filePath;
908  break;
909  }
910  }
911  if (isset($thisFilePath))
912  break;
913  }
914  }
915 
916  if (!isset($thisFilePath))
917  throw new exception("File doesn't exist.", 4);
918 
919  $fullPath= "${uploadPath}${thisFilePath}";
920  if (!@is_readable($fullPath))
921  throw new exception("File doesn't exist.", 2);
922 
923  $pdffile = fopen($fullPath, "r");
924  $sArray=fstat($pdffile);
925  $size=$sArray["size"];
926  header("Content-Type: application/pdf");
927  header("Content-length: $size");
928  fpassthru($pdffile);
929  pclose ($pdffile);
930  }
931  catch(exception $e)
932  {
933  header('Content-type: application/json');
934  print HCU_JsonEncode( array("error" => $e->getMessage(), "code" => $e->getCode()));
935  }
936 }