5 * Purpose: to archive old entries in the csv files and old files
8 * @subpackage ediHistory
9 * @link https://www.open-emr.org
10 * @author Kevin McCormick
11 * @copyright Copyright (c) 2016 Kevin McCormick Longview, Texas
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 // a security measure to prevent direct web access to this file
16 // must be accessed through the main calling script ibr_history.php
17 // from admin at rune-city dot com; found in php manual
18 //if (!defined('SITE_IN')) die('Direct access not allowed!');
22 //require_once("$srcdir/edihistory/test_edih_csv_inc.php");
24 // constant DS = DIRECTORY_SEPARATOR
27 * Report on edi_history
29 * @uses csv_parameters()
30 * @uses csv_assoc_array()
32 * @param string archive date in CCYYMMDD format
34 * @return array array[i] = filename
36 function edih_archive_report($period = '')
42 // edih_archive_date returns empty string if no period
43 $tper = edih_archive_date($period);
44 $chkdt = ($tper) ?
$tper : 'None';
45 $strdt = ($tper) ?
substr($chkdt, 0, 4) . '-' . substr($chkdt, 4, 2) . '-' . substr($chkdt, 6, 2) : 'None';
47 csv_edihist_log("edih_archive_report: creating archive report with date $chkdt");
49 $bdir = csv_edih_basedir();
50 $params = csv_parameters('ALL');
51 if (!is_array($params) && count($params)) {
52 csv_edihist_log("edih_archive_report: invalid csv_parameters");
53 return "<p>There was an error creating the report.</p>";
57 $str_html .= "<h3>Report on edi files using archive date " . text($strdt) . "</h3>" . PHP_EOL
;
58 foreach ($params as $key => $param) {
70 $fdir = $param['directory'];
73 $dir_ar = scandir($fdir);
74 if (is_array($dir_ar) && ((count($dir_ar) - 2) > 0)) {
75 $str_html .= "<H3><em>Type</em> " . text($tp) . "</H3>" . PHP_EOL
;
76 $str_html .= "<ul>" . PHP_EOL
;
77 $dir_ct = count($dir_ar);
78 foreach ($dir_ar as $fn) {
79 if ($fn == 'README.txt') {
84 if (substr($fn, 0, 1) == '.') {
89 if (is_dir($fdir . DS
. $fn)) {
95 $dir_sz +
= filesize($fdir . DS
. $fn);
99 $csv_ar = csv_assoc_array($tp, 'file');
100 $row_ct = (is_array($csv_ar)) ?
count($csv_ar) : 0;
102 foreach ($csv_ar as $row) {
103 // tally amount of claim transactions in the files
105 $clm_ct +
= $row['Claim_ct'];
109 $clm_ct +
= ($row['Accept'] +
$row['Reject']);
113 $clm_ct +
= $row['Claim_ct'];
116 // check for duplicates
117 // here assume that files with multiple rows are consecutive
118 if ($fntp !== $row['FileName']) {
119 $fntp = $row['FileName'];
120 // count files that would be archived
121 if (($chkdt != 'None') && strcmp($row['Date'], $chkdt) < 0) {
130 $dir_kb = csv_convert_bytes($dir_sz);
132 csv_edihist_log("edih_archive_report: error $tp file count $dir_ct with csv rows $row_ct");
136 $mis = ($fntp_ct == $dir_ct ) ?
"(check/eft count or ISA--IEA count)" : "(mismatch csv $fntp_ct dir $dir_ct)";
139 $str_html .= "<li><em>Note:</em> 837 Claims files are not archived </li>" . PHP_EOL
;
143 $str_html .= "<li>files directory has " . text($dir_ct) . " files, using " . text($dir_kb) . " </li>" . PHP_EOL
;
144 $str_html .= ($subdir_ct && ($tp != 'f837')) ?
"<li> <em>warning</em> found " . text($subdir_ct) . " sub-directories</li>" . PHP_EOL
: "";
145 $str_html .= "<li>files csv table has " . text($row_ct) . " rows " . text($mis) . "</li>" . PHP_EOL
;
146 $str_html .= ($clm_ct) ?
"<li>there are " . text($clm_ct) . " claim transactions counted</li>" . PHP_EOL
: "";
147 $str_html .= ($old_ct) ?
"<li>Archive date " . text($strdt) . " would archive " . text($old_ct) . " files </li>" . PHP_EOL
: "";
148 $str_html .= "</ul>" . PHP_EOL
;
150 $str_html .= "<p><em>Type</em> <b>" . text($tp) . "</b> <br /> -- empty " . text($tp) . " file directory</p>" . PHP_EOL
;
153 $str_html .= "<p><em>warning</em> <b>" . text($tp) . "</b> file directory does not exist</p>" . PHP_EOL
;
157 $str_html .= "<p>Report end</p>" . PHP_EOL
;
164 * Format the date used in comparisons
166 * @param string period from select list e.g. 6m, 12m
168 * @return string archive date in CCYYMMDD format
170 function edih_archive_date($period)
178 $is_period = preg_match('/\d{1,2}(?=m)/', $period, $matches);
180 if (count($matches)) {
183 if (strpos($period, 'm')) {
184 // take the number part of 'period'
185 // so modstr will be '-N month'
186 $modstr = '-' . $matches[0] . ' month';
187 $dtstr1 = $gtdt['mon'] . '/01/' . $gtdt['year'];
188 } elseif (strpos($period, 'y')) {
189 $modstr = '-' . $matches[0] . ' year';
190 $dtstr1 = $gtdt['mon'] . '/01/' . $gtdt['year'];
192 csv_edihist_log("edih_archive_date: incorrect date period $period");
198 $dtpd1 = date_create($dtstr1);
199 $dtm = date_modify($dtpd1, $modstr);
200 $dtpd2 = $dtm->format('Ymd');
202 csv_edihist_log("edih_archive_date: failed to parse $period");
206 csv_edihist_log("edih_archive_date: invalid argment $period");
210 // the testing date in CCYYMMDD format
216 * Create an array of file names to be archived
217 * The 'Date' column in the files_[type].csv file
218 * is compared to the archive date. If the date is less
219 * than the archive date, the "FileName' value is copied
221 * @param array csv file rows array
222 * @param string archive date in CCYYMMDD format
224 * @return array array[i] = filename
226 function edih_archive_filenames($csv_ar, $archive_date)
229 if ($archive_date && strlen($archive_date) == 8 && is_numeric($archive_date)) {
230 $testdate = (string)$archive_date;
232 csv_edihist_log("edih_archive_filenames: invalid archive date $archive_date");
237 if (!is_array($csv_ar) ||
!count($csv_ar)) {
238 csv_edihist_log("edih_archive_filenames: failed to get csv file array $file_type");
244 foreach ($csv_ar as $row) {
245 if (strcmp($row['Date'], $archive_date) < 0) {
246 $fn_ar[] = $row['FileName'];
250 $ret_ar = (count($fn_ar)) ?
array_values(array_unique($fn_ar)) : $fn_ar;
256 * Create a new csv array by omitting rows which reference
257 * a file name that is to be archived
259 * @uses csv_file_type()
260 * @uses csv_assoc_array()
262 * @param string the file type
263 * @param string the csv type file or claim
264 * @param array the array of archived file names and retained file names
268 function edih_archive_csv_split($csv_ar, $filename_array)
271 if (!is_array($filename_array) ||
!count($filename_array)) {
272 csv_edihist_log('csv_archive_table; invalid filename array');
277 if (is_array($csv_ar) && count($csv_ar)) {
278 csv_edihist_log("edih_archive_csv_split: csv rows " . count($csv_ar) . " old files " . count($filename_array));
280 csv_edihist_log("edih_archive_csv_split: failed to get csv file array");
285 // if the to be archived file name is in the row,
286 // do not copy it to the new csv array
288 $arch_ar['arch'] = array();
289 $arch_ar['keep'] = array();
291 foreach ($csv_ar as $row) {
292 if (in_array($row['FileName'], $filename_array)) {
293 $arch_ar['arch'][] = $row;
295 $arch_ar['keep'][] = $row;
300 csv_edihist_log("edih_archive_csv_split: 'arch' array rows " . count($arch_ar['arch']));
301 csv_edihist_log("edih_archive_csv_split: 'keep' array rows " . count($arch_ar['keep']));
308 * Creates a zip archive of the files in the $filename_ar array and
309 * returns the path/name of the archive or FALSE on error
311 * @param array $parameters array for file type from csv_parameters
312 * @param array $filename_ar array of filenames to be archived
313 * @param string $archive_date date of archive to be incorporated in archive file name
315 * @return bool result of zipArchive functions
317 function edih_archive_create_zip($parameters, $filename_ar, $archive_date, $archive_filename)
319 // we deal with possible maximum files issues by chunking the $fn_ar array
321 $ft = $parameters['type'];
322 $fdir = $parameters['directory'];
323 $tmp_dir = csv_edih_tmpdir();
324 // archive csv rows -- same name as from edih_archive_main
325 // $fn_files_arch = $tmp_dir.DS.'arch_'.basename($files_csv);
326 $files_csv_arch = 'arch_' . basename($parameters['files_csv']);
327 // $fn_claims_arch = $tmp_dir.DS.'arch_'.basename($claim_csv);
328 $claims_csv_arch = 'arch_' . basename($parameters['claims_csv']);
332 // to handle possibility of more than 200 files in the archive
333 // use the 'chunk' method
334 if (count($filename_ar) > $f_max) {
335 $fn_ar2 = array_chunk($filename_ar, $f_max);
337 $fn_ar2[] = $filename_ar;
341 $zip_name = $tmp_dir . DS
. $archive_filename;
342 csv_edihist_log("edih_archive_create_zip: using $zip_name");
344 $zip_obj = new ZipArchive();
345 csv_edihist_log("edih_archive_create_zip: now opening archive $archive_filename");
346 if (is_file($zip_name)) {
347 $isOK = $zip_obj->open($zip_name, ZipArchive
::CHECKCONS
);
349 if ($zip_obj->locateName($ft) === false) {
350 $isOK = $zip_obj->addEmptyDir($ft);
352 csv_edihist_log("edih_archive_create_zip: adding $ft ZipArchive error $msg");
357 $msg = $zip_obj->getStatusString();
358 csv_edihist_log("edih_archive_create_zip: $ft ZipArchive error $msg");
362 $isOK = $zip_obj->open($zip_name, ZipArchive
::CREATE
);
363 $isOK = $zip_obj->addEmptyDir('csv');
364 $isOK = $zip_obj->addEmptyDir($ft);
365 $zip_obj->setArchiveComment("edi_history archive prior to $archive_date");
368 // we are working with the open archive
369 // now add the old csv files to the archive
370 if (is_file($tmp_dir . DS
. $files_csv_arch)) {
371 csv_edihist_log("edih_archive_create_zip: now adding $files_csv_arch to archive");
372 $isOK = $zip_obj->addFile($tmp_dir . DS
. $files_csv_arch, 'csv' . DS
. $files_csv_arch);
375 if (is_file($tmp_dir . DS
. $claims_csv_arch)) {
376 csv_edihist_log("edih_archive_create_zip: now adding $claims_csv_arch to archive");
377 $isOK = $zip_obj->addFile($tmp_dir . DS
. $claims_csv_arch, 'csv' . DS
. $claims_csv_arch);
381 csv_edihist_log("edih_archive_create_zip: now closing archive");
382 $isOK = $zip_obj->close();
383 if ($isOK !== true) {
384 $msg = $zip_obj->getStatusString();
385 csv_edihist_log("edih_archive_create_zip: $ft ZipArchive error $msg");
390 csv_edihist_log("edih_archive_create_zip: with file name groups " . count($fn_ar2));
391 foreach ($fn_ar2 as $fnz) {
392 // reopen the zip archive on each loop so the open file count is controlled
393 if (is_file($zip_name)) {
394 csv_edihist_log("edih_archive_create_zip: now opening archive");
395 $isOK = $zip_obj->open($zip_name, ZipArchive
::CHECKCONS
);
399 if ($isOK === true) {
400 // we are working with the open archive
401 // now add the old x12 files to the archive
402 csv_edihist_log("edih_archive_create_zip: now adding $ft files to archive");
403 foreach ($fnz as $fz) {
404 if ($fz == '.' ||
$fz == '..') {
408 if (is_file($fdir . DS
. $fz) && is_readable($fdir . DS
. $fz)) {
409 $isOK = $zip_obj->addFile($fdir . DS
. $fz, $ft . DS
. $fz);
411 // possible that file is in csv table, but not in directory?
412 $msg = $zip_obj->getStatusString();
413 csv_edihist_log("edih_archive_create_zip: error adding file $fz zipArchive: $msg");
415 } // end foreach($fnz as $fz)
416 // close zip object for next iteration of chunked array
417 csv_edihist_log("edih_archive_create_zip: now closing archive");
418 $isOK = $zip_obj->close();
419 // errors on close would be non-existing file added or something else
420 if ($isOK !== true) {
421 $msg = $zip_obj->getStatusString();
422 csv_edihist_log("edih_archive_create_zip: $ft ZipArchive error $msg");
427 // ZipArchive open() failed -- try to get the error message and return false
428 $msg = $zip_obj->getStatusString();
429 csv_edihist_log("edih_archive_create_zip: $ft ZipArchive failed $msg");
433 } // end foreach($fn_ar2 as $fnz)
439 * Archived files have been included in archive file
440 * so we move the files to the archive tmp directory, for later deletion
442 * @param array parameters array for type
443 * @param array filename array
445 * @return int count of moved files
447 function edih_archive_move_old($parameters, $filename_ar)
450 if (!is_array($filename_ar) ||
!count($filename_ar)) {
454 if (!is_array($parameters) ||
!count($parameters)) {
459 clearstatcache(true);
462 $fn_ar_ct = count($filename_ar);
463 $ft = $parameters['type'];
464 $fdir = $parameters['directory'];
465 $fdir = realpath($fdir);
466 $rndir = csv_edih_tmpdir() . DS
. $ft;
469 csv_edihist_log("edih_archive_delete_old: $ft dir OK");
470 if (is_dir($rndir) ||
mkdir($rndir)) {
471 $rndir = realpath($rndir);
472 csv_edihist_log("edih_archive_delete_old: $ft move dir OK");
475 csv_edihist_log("edih_archive_delete_old: $ft move dir error");
479 csv_edihist_log("edih_archive_delete_old: $ft dir error");
485 csv_edihist_log("edih_archive_delete_old: $ft old file count $fn_ar_ct");
486 foreach ($filename_ar as $fn) {
487 // if we have added the file to the archive, remove it from the storage directory
488 // but keep the /history/tmp file copy for now
489 if (is_file($fdir . DS
. $fn)) {
490 $isrn = rename($fdir . DS
. $fn, $rndir . DS
. $fn);
497 csv_edihist_log("edih_archive_delete_old: $ft failed to move $fn");
501 csv_edihist_log("edih_archive_delete_old: $ft directory error for files or tmp");
510 * create associative array from archive csv file
512 * @uses edih_archive_csv_array()
516 * @param string optional filepath
520 function edih_archive_csv_array($filetype, $csv_type, $filepath = '')
525 $tmpdir = csv_edih_tmpdir();
526 $tmpcsv = $tmpdir . DS
. 'csv';
528 $csvtp = (strpos($csv_type, 'aim')) ?
'claims' : 'files';
530 if (is_file($filepath)) {
531 $csv_arch_path = $filepath;
533 $csv_arch_path = $tmpcsv . DS
. 'arch_' . $csvtp . '_' . $filetype . '.csv';
540 // relies on first row being header or column names
541 if (($fh = fopen($csv_arch_path, "rb")) !== false) {
542 while (($data = fgetcsv($fh, 2048, ",")) !== false) {
543 if (is_null($data)) {
548 for ($i = 0; $i < $ct; $i++
) {
549 $csv_ar[$ky][$h[$i]] = $data[$i];
563 csv_edihist_log('edih_archive_csv_array; invalid file path ' . $csv_arch_path);
572 * combine the csv file in the archive with the current csv file
574 * @uses edih_archive_csv_array()
581 function edih_archive_csv_combine($filetype, $csvtype)
586 $bdir = csv_edih_basedir();
587 $tmpdir = csv_edih_tmpdir();
588 $tmpcsv = $tmpdir . DS
. 'csv';
590 $csvtp = (strpos($csvtype, 'aim')) ?
'claims' : 'files';
591 $csv_arch_file = $tmpcsv . DS
. 'arch_' . $csvtp . '_' . $filetype . '.csv';
592 $csv_new_file = $tmpdir . DS
. 'cmb_' . $csvtp . '_' . $filetype . '.csv';
594 // arrays used to eliminate duplicate rows
595 $dup_ar = $dup_unique = $dup_keys = array();
596 // combine files by combining arrays and writing a tmp file
597 // get the present csv file contents
598 $car1 = csv_assoc_array($filetype, $csvtp);
599 // get the archived csv contents
600 if (is_file($csv_arch_file)) {
601 $car2 = edih_archive_csv_array($filetype, $csvtp, $csv_arch_file);
604 // possibility of empty arrays if no data rows in a csv file
605 $hdrc1 = (is_array($car1) && count($car1)) ?
array_keys($car1[0]) : array();
606 $hdrc2 = (is_array($car2) && count($car2)) ?
array_keys($car2[0]) : array();
607 if (count($hdrc1) && ($hdrc1 === $hdrc2)) {
609 } elseif (empty($hdrc1) && count($hdrc2)) {
611 } elseif (empty($hdrc2) && count($hdrc1)) {
614 // array mismatch error (impossible?)
615 csv_edihist_log("edih_archive_csv_combine: $filetype $csvtp array header mismatch");
616 // just use the current csv file
617 $hdr_ar = csv_table_header($filetype, $csvtp);
618 $car_cmb_unique = $car1;
622 foreach ($hdrc1 as $h) {
623 $dbg_str .= $h . ' ';
626 csv_edihist_log("edih_archive_csv_combine: $csvtp car1 header $dbg_str");
628 csv_edihist_log("edih_archive_csv_combine: $csvtp car1 header empty");
633 foreach ($hdrc2 as $h) {
634 $dbg_str .= $h . ' ';
637 csv_edihist_log("edih_archive_csv_combine: $csvtp car2 header $dbg_str");
639 csv_edihist_log("edih_archive_csv_combine: $csvtp car2 header empty");
645 // if the arrays checked out
646 if (!isset($car_cmb_unique)) {
647 // if we have archive csv rows
648 if (is_array($car1) && is_array($car2)) {
649 // put the archive rows first
650 $car_cmb = array_merge($car2, $car1);
651 // now eliminate duplicates
652 if ($csvtp == 'files') {
653 if ($filetype == 'f835') {
659 // array_column() php v5.5
660 foreach ($car_cmb as $idx => $row) {
661 $dup_ar[$idx] = $row[$ky];
664 csv_edihist_log("edih_archive_csv_combine: $csvtp array row count " . count($dup_ar));
665 $dup_unique = array_unique($dup_ar);
666 $dup_keys = array_keys($dup_unique);
667 csv_edihist_log("edih_archive_csv_combine: $csvtp index row count " . count($dup_keys));
668 foreach ($dup_keys as $k) {
669 $car_cmb_unique[] = $car_cmb[$k];
672 csv_edihist_log("edih_archive_csv_combine: $csvtp combined row count " . count($car_cmb_unique));
673 } elseif ($csvtp == 'claims') {
674 $ct = count($hdr_ar);
675 $ftxt = $csvtp . ' array' . PHP_EOL
;
676 foreach ($car_cmb as $idx => $row) {
678 for ($i = 0; $i < $ct; $i++
) {
679 $r_str .= $row[$hdr_ar[$i]];
682 $dup_ar[$idx] = $r_str;
683 $ftxt .= $r_str . PHP_EOL
;
686 csv_edihist_log("edih_archive_csv_combine: $csvtp array row count " . count($dup_ar));
687 file_put_contents($tmpdir . DS
. 'archive' . DS
. 'claimstr.txt', $ftxt);
689 $dup_unique = array_unique($dup_ar);
690 $dup_keys = array_keys($dup_unique);
691 csv_edihist_log("edih_archive_csv_combine: $csvtp index row count " . count($dup_keys));
692 foreach ($dup_keys as $k) {
693 $car_cmb_unique[] = $car_cmb[$k];
696 csv_edihist_log("edih_archive_csv_combine: $csvtp combined row count " . count($car_cmb_unique));
698 $car_cmb_unique = $car_cmb;
701 csv_edihist_log("edih_archive_csv_combine: array keys mismatch $filetype");
704 csv_edihist_log("edih_archive_csv_combine: error reading archived csv " . $csvtp . "_" . $filetype . ".csv");
708 $fh = fopen($csv_new_file, 'wb');
710 fputcsv($fh, $hdr_ar);
713 foreach ($car_cmb_unique as $row) {
718 // close new csv file
721 csv_edihist_log("edih_archive_csv_combine: failed to open $filetype new csv file");
728 * Unpack an existing archive and restore it to current csv records
729 * and replace the files in the respective directories
731 * @uses edih_archive_csv_combine
736 function edih_archive_restore($archive_name)
740 $bdir = csv_edih_basedir();
741 $tmpdir = csv_edih_tmpdir();
742 $archdir = $bdir . DS
. 'archive';
744 if (is_file($archdir . DS
. $archive_name)) {
745 $arch = realpath($archdir . DS
. $archive_name);
746 $str_out .= "Archive: restoring " . text($archive_name) . "<br />";
747 csv_edihist_log("edih_archive_restore: restoring $archive_name");
749 $str_out = "Archive: restore archive bad file name " . text($archive_name) . " <br />";
750 csv_edihist_log("edih_archive_restore: restore archive bad file name $archive_name");
755 $zip_obj = new ZipArchive();
756 // open archive (ZipArchive::CHECKCONS the ZipArchive::CREATE is supposedly necessary for microsoft)
757 //$res = $zip_obj->open($arch, ZipArchive::CHECKCONS);
758 if ($zip_obj->open($arch, ZipArchive
::CHECKCONS
) === true) {
759 $f_ct = $zip_obj->numFiles
;
760 $str_out .= "Extracting " . text($f_ct) . " items from " . text($archive_name) . " <br />";
761 csv_edihist_log("edih_archive_restore: Extracting $f_ct items from $archive_name");
762 $isOK = $zip_obj->extractTo($tmpdir);
764 $msg = $zip_obj->getStatusString();
765 csv_edihist_log("edih_archive_restore: error extracting archive");
766 $str_out .= "Archive: error extracting archive " . text($archive_name) . " <br />";
767 $str_out .= "zipArchive: " . text($msg) . " <br />";
771 $msg = $zip_obj->getStatusString();
772 csv_edihist_log("edih_archive_restore: error opening archive");
773 $str_out .= "Archive: error opening archive <br />" . PHP_EOL
;
774 $str_out .= "zipArchive: " . text($msg) . " <br />";
778 // now traverse the tmpdir and replace things
779 // we should have tmp/csv/files_[ftype].csv claims_[ftype].csv
780 // tmp/[ftype]/x12_filenames
781 $arch_ar = scandir($tmpdir);
783 foreach ($arch_ar as $fa) {
784 if ($fa == '.' ||
$fa == '..') {
788 if (is_dir($tmpdir . DS
. $fa)) {
793 // if a /history/ftype dir exists
794 if (is_dir($bdir . DS
. $fa)) {
804 csv_edihist_log("edih_archive_restore: types in archive $tpstr");
805 $str_out .= "Archive: types in archive " . text($tpstr) . " <br />" . PHP_EOL
;
807 foreach ($type_ar as $ft) {
808 $str_out .= "Archive: now restoring " . text($ft) . "<br />" . PHP_EOL
;
809 csv_edihist_log("edih_archive_restore: now restoring $ft");
811 $frows = edih_archive_csv_combine($ft, 'file');
812 csv_edihist_log("edih_archive_restore: files_$ft csv combined rows $frow");
813 $crows = edih_archive_csv_combine($ft, 'claim');
814 csv_edihist_log("edih_archive_restore: claims_$ft csv combined rows $frow");
816 $file_ar = scandir($tmpdir . DS
. $ft);
817 foreach ($file_ar as $fn) {
818 if ($fn == '.' ||
$fn == '..') {
822 if (is_file($tmpdir . DS
. $ft . DS
. $fn)) {
823 $rn = rename($tmpdir . DS
. $ft . DS
. $fn, $bdir . DS
. $ft . DS
. $fn);
825 $str_out .= " -- error restoring " . text($ft) . DS
. text($fn) . "<br />" . PHP_EOL
;
826 csv_edihist_log("edih_archive_restore: error restoring " . $ft . DS
. $fn);
831 // this will catch the csv files for the particulat type
832 $str_out .= "Archive: now replacing csv tables for " . text($ft) . "<br />" . PHP_EOL
;
833 csv_edihist_log("edih_archive_restore: now replacing csv tables for $ft");
835 $rnf = rename($tmpdir . DS
. 'cmb_files_' . $ft . '.csv', $bdir . DS
. 'csv' . DS
. 'files_' . $ft . '.csv');
836 $rnc = rename($tmpdir . DS
. 'cmb_claims_' . $ft . '.csv', $bdir . DS
. 'csv' . DS
. 'claims_' . $ft . '.csv');
837 $str_out .= ($rnf) ?
"" : " -- error restoring files_" . text($ft) . ".csv <br />" . PHP_EOL
;
838 $str_out .= ($rnc) ?
"" : " -- error restoring claims_" . text($ft) . ".csv <br />" . PHP_EOL
;
842 csv_edihist_log("edih_archive_restore: now removing archive file");
843 $str_out .= "Archive: now removing archive file <br />" . PHP_EOL
;
846 csv_edihist_log("edih_archive_restore: error removing $archdir.DS.$archive_name");
847 $str_out .= ($rnf) ?
"" : " -- error removing " . text($archdir) . "." . DS
. "." . text($archive_name) . PHP_EOL
;
851 //edih_archive_cleanup($arch_fn, $tp_ar);
852 csv_edihist_log("edih_archive_restore: now removing temporary files");
853 $str_out .= "Archive: now removing temporary files <br />" . PHP_EOL
;
856 $is_clear = csv_clear_tmpdir();
858 $str_out .= "Archive: temporary files removed. Process complete.<br />" . PHP_EOL
;
860 $str_out .= "Archive: still some files in /history/tmp/. Process complete.<br />" . PHP_EOL
;
869 * restores files from the tmp dir if the archive process needs to be aborted
871 * @uses csv_edih_basedir()
872 * @uses csv_edih_tmpdir()
873 * @uses csv_parameters()
877 function edih_archive_undo()
880 // archive process creates files in /history/tmp
881 // /tmp/old_files_[type].csv copy of pre-archive csv record
882 // /tmp/old_claims_[type].csv copy of pre-archive csv record
883 // /tmp/new_files_[type].csv csv record of non-archived files
884 // /tmp/new_claims_[type].csv csv record of non-archived files
885 // /tmp/arch_files_[type].csv csv record of archived files (to be put in zip file)
886 // /tmp/arch_claims_[type].csv csv record of archived files (to be put in zip file)
887 // /tmp/[type]/filename_to_be_archived all the archived files for [type]
890 $bdir = csv_edih_basedir();
891 $tmpdir = csv_edih_tmpdir();
892 $archdir = $bdir . DS
. 'archive';
894 $params = csv_parameters("ALL");
895 $types_ar = array_keys($params);
897 csv_edihist_log("edih_archive_undo: restoring prior csv files files");
898 foreach ($types_ar as $ft) {
899 if (is_file($tmpdir . DS
. 'old_files_' . $ft . '.csv')) {
900 $rn = rename($tmpdir . DS
. 'old_files_' . $ft . '.csv', $bdir . DS
. 'csv' . DS
. 'files_' . $ft . '.csv');
902 csv_edihist_log("edih_archive_undo: restored prior files_$ft ");
904 csv_edihist_log("edih_archive_undo: restore failed for prior files_$ft ");
908 if (is_file($tmpdir . DS
. 'old_claims_' . $ft . '.csv')) {
909 $rn = rename($tmpdir . DS
. 'old_claims_' . $ft . '.csv', $bdir . DS
. 'csv' . DS
. 'claims_' . $ft . '.csv');
911 csv_edihist_log("edih_archive_undo: restored prior claimss_$ft ");
913 csv_edihist_log("edih_archive_undo: restore failed for prior claims_$ft ");
918 $arch_ar = scandir($tmpdir);
919 foreach ($arch_ar as $fa) {
920 if ($fa == "." && $fa == "..") {
924 if (is_dir($tmpdir . DS
. $fa)) {
925 if (in_array($fa, $types_ar)) {
926 $fpath = $params[$fa]['directory'];
927 if ($dh = opendir($tmpdir . DS
. $fa)) {
928 $str_out .= "Archive: undo restoring " . text($fa) . " files<br />" . PHP_EOL
;
929 csv_edihist_log("edih_archive_undo: restoring $fa files");
930 while (false !== ($entry = readdir($dh))) {
931 if ($entry != "." && $entry != "..") {
932 if (is_file($fpath . DS
. $entry)) {
933 // file was not moved
935 rename($tmpdir . DS
. $fa . DS
. $entry, $fpath . DS
. $entry);
951 * After the archive is created, the csv record needs to be re-written so the archived
952 * files are not in the csv file and hence, not searched for.
954 * @uses csv_table_header()
956 * @param string $csv_path the tmp csv file path is expected
957 * @param array $row_array the data rows to be written (an associative array)
959 * @return integer count the rows written
961 function edih_archive_rewrite_csv($csv_path, $csv_keys, $row_array)
963 // @param string $csv_path -- the tmp csv file path is expected
964 // @param array $heading_ar -- the column heading for the csv file
965 // @param array $row_array -- the data rows to be written
967 // count characters written -- returned by fputcsv
971 if (is_array($row_array)) {
972 csv_edihist_log("edih_archive_rewrite_csv: row array count " . count($row_array));
974 csv_edihist_log("edih_archive_rewrite_csv: row array not array");
978 if (is_array($row_array) && is_array($csv_keys)) {
979 if (count($csv_keys)) {
983 csv_edihist_log("edih_archive_rewrite_csv: invalid row array");
987 //$csv_path should end with /history/tmp/[arch|keep]_[files|claims]_[type].csv
988 // with 'w' flag, place the file pointer at the beginning of the file
989 // and truncate the file to zero length.
990 // If the file does not exist, attempt to create it.
991 $fh3 = fopen($csv_path, 'wb');
993 // write the heading row first
994 $ocwct +
= fputcsv($fh3, $h_ar);
995 // wrote heading, now add rows
996 foreach ($row_array as $row) {
997 $ocwct +
= fputcsv($fh3, $row);
1002 csv_edihist_log("edih_archive_rewrite_csv: wrote " . count($row_array) . " rows to " . basename($csv_path));
1004 csv_edihist_log("edih_archive_rewrite_csv: failed to open $csv_path");
1012 * cleanup archived files after archive created
1014 * @param string name of archive file
1015 * @param array array of types included in archive
1019 function edih_archive_cleanup($archivename, $types_ar)
1024 if (is_array($types_ar) && count($types_ar)) {
1027 csv_edihist_log("edih_archive_cleanup: no types in file types list");
1028 $str_out = "no types in file types list" . PHP_EOL
;
1032 $bdir = csv_edih_basedir();
1033 $tmpdir = csv_edih_tmpdir();
1034 $archivedir = $bdir . DS
. 'archive';
1036 // move archive file to archive directory
1037 csv_edihist_log("edih_archive_cleanup: now clearing temporary files");
1038 $str_out .= "Archive: now clearing temporary files<br />" . PHP_EOL
;
1039 // delete archived files from edih tmp dir
1040 foreach ($tdirs as $td) {
1041 csv_edihist_log("edih_archive_cleanup: cleaning up for $td");
1042 if (is_dir($tmpdir . DS
. $td)) {
1043 $fn_ar = scandir($tmpdir . DS
. $td);
1044 foreach ($fn_ar as $fn) {
1045 if ($fn == '.' ||
$fn == '..') {
1049 if (is_file($tmpdir . DS
. $td . DS
. $fn)) {
1050 $ul = unlink($tmpdir . DS
. $td . DS
. $fn);
1052 csv_edihist_log("edih_archive_cleanup: error removing file $fn");
1053 $str_out .= "<p>edih_archive_cleanup: error removing file " . text($td) . DS
. text($fn) . "</p>";
1060 // try to remove the now empty directory
1061 csv_edihist_log("edih_archive_cleanup: removing tmp $td");
1062 rmdir($tmpdir . DS
. $td);
1065 csv_edihist_log("edih_archive_cleanup: removed $fct files from $td");
1073 * The main function in this edih_archive.php script. This function gets the parameters array
1074 * from csv_parameters() and calls the archiving functions on each type of file
1075 * in the parameters array.
1077 * @uses edih_archive_date()
1078 * @uses csv_edih_basedir()
1079 * @uses csv_parameters()
1080 * @uses csv_edih_tmpdir()
1081 * @uses csv_table_header()
1082 * @uses edih_archive_filenames()
1083 * @uses edih_archive_rewrite_csv()
1084 * @uses edih_archive_csv_split()
1085 * @uses edih_archive_create_zip()
1087 * @param string from select drop-down 6m, 12m, 18m, etc
1089 * @return string descriptive message in html format
1091 function edih_archive_main($period)
1096 $archive_date = edih_archive_date($period);
1097 if ($archive_date) {
1098 $archive_dir = csv_edih_basedir() . DS
. 'archive';
1099 $tmp_dir = csv_edih_tmpdir();
1100 $arch_fn = $archive_date . '_archive.zip';
1101 $params = csv_parameters();
1103 csv_edihist_log("edih_archive_main: error creating archive date from $period");
1104 $out_html = "Error creating archive date from " . text($period) . "<br />" . PHP_EOL
;
1107 $out_html = "Archive period invalid.<br />" . PHP_EOL
;
1112 if (is_dir($archive_dir)) {
1113 if (is_file($archive_dir . DS
. $arch_fn)) {
1114 csv_edihist_log("edih_archive_main: archive file $arch_fn already exists");
1115 $out_html = "Archive: archive file " . text($arch_fn) . " already exists<br />" . PHP_EOL
;
1119 // should have been created at setup
1120 if (!mkdir($archive_dir, 0755)) {
1121 csv_edihist_log("edih_archive_main: archive directory does not exist");
1122 $out_html = "Archive: archive directory does not exist<br />" . PHP_EOL
;
1128 foreach ($params as $k => $p) {
1130 $ft = $p['type']; // could be $k
1132 if ($ft == 'f837') {
1133 csv_edihist_log("edih_archive_main: 837 Claims files are not archived");
1137 $fdir = $p['directory'];
1138 $scan = scandir($fdir);
1139 if (!$scan ||
count($scan) < 3) {
1144 $files_csv = $p['files_csv'];
1145 $claims_csv = $p['claims_csv'];
1146 $date_col = $p['filedate'];
1147 $fncol = 'FileName';
1149 // create three csv file paths 'old_', 'arch_', and 'keep_'
1150 // files csv temporary names
1151 $fn_files_old = $tmp_dir . DS
. 'old_' . basename($files_csv);
1152 $fn_files_arch = $tmp_dir . DS
. 'arch_' . basename($files_csv);
1153 $fn_files_keep = $tmp_dir . DS
. 'keep_' . basename($files_csv);
1154 // claims csv temporary names
1155 $fn_claims_old = $tmp_dir . DS
. 'old_' . basename($claims_csv);
1156 $fn_claims_arch = $tmp_dir . DS
. 'arch_' . basename($claims_csv);
1157 $fn_claims_keep = $tmp_dir . DS
. 'keep_' . basename($claims_csv);
1159 $fh_ar = csv_table_header($ft, 'file');
1160 $ch_ar = csv_table_header($ft, 'claim');
1161 // copy existing csv files -- continue to next type if no files_csv
1162 $iscpc = $iscpf = false;
1163 if (is_file($files_csv)) {
1164 $iscpf = copy($files_csv, $fn_files_old);
1165 csv_edihist_log("edih_archive_main: copy $ft files csv to tmp dir");
1167 csv_edihist_log("edih_archive_main: $ft files csv does not exist");
1171 if (is_file($claims_csv)) {
1172 $iscpc = copy($claims_csv, $fn_claims_old);
1173 csv_edihist_log("edih_archive_main: copy $ft claims csv to tmp dir");
1175 if ($ft == 'f997') {
1176 // there may be no 997 type claims records, so create a dummy file
1177 $fh = fopen($fn_claims_old, 'wb');
1179 fputcsv($fh, $ch_ar);
1183 csv_edihist_log("edih_archive_main: $ft claims csv does not exist");
1189 if (!$iscpf ||
!$iscpc) {
1190 csv_edihist_log("edih_archive_csv_old: copy to tmp dir failed for csv file $ft");
1191 $out_html = "Archive temporary files operation failed ... aborting <br />" . PHP_EOL
;
1192 // need to call archive_undo()
1193 $out_html .= edih_archive_undo();
1198 $csv_files_ar = csv_assoc_array($ft, 'file');
1199 $csv_claims_ar = csv_assoc_array($ft, 'claim');
1200 // get filenames to be archived
1203 $fn_ar = edih_archive_filenames($csv_files_ar, $archive_date);
1204 if (count($fn_ar)) {
1207 // get the old and new csv row arrays for files_csv
1208 $arch_new = edih_archive_csv_split($csv_files_ar, $fn_ar);
1210 if (isset($arch_new['keep'])) {
1212 $frws = edih_archive_rewrite_csv($fn_files_keep, $fh_ar, $arch_new['keep']);
1213 $out_html .= "type " . text($ft) . " keep files_csv file with " . text($frws) . " rows<br />";
1216 if (isset($arch_new['arch'])) {
1218 $frws2 = edih_archive_rewrite_csv($fn_files_arch, $fh_ar, $arch_new['arch']);
1219 $out_html .= "type " . text($ft) . " archive files_csv file with " . text($frws2) . " rows<br />";
1222 $out_html .= "type $ft error creating new files_csv tables";
1225 // repeat for claims_csv
1226 $arch_new = edih_archive_csv_split($csv_claims_ar, $fn_ar);
1228 if (isset($arch_new['keep'])) {
1230 $crws = edih_archive_rewrite_csv($fn_claims_keep, $ch_ar, $arch_new['keep']);
1231 $out_html .= "type " . text($ft) . " keep claims_csv file with " . text($crws) . " rows<br />";
1234 if (isset($arch_new['arch'])) {
1236 $crws = edih_archive_rewrite_csv($fn_claims_arch, $ch_ar, $arch_new['arch']);
1237 $out_html .= "type " . text($ft) . " archive claims_csv file with " . text($crws) . " rows<br />";
1240 $out_html .= "type " . text($ft) . " error creating new claims csv tables<br />";
1243 // now the csv_records are in files
1244 // file records in $fn_files_arch $fn_files_keep
1245 // claim records in $fn_claims_arch $fn_claims_new
1247 // create a zip archive
1248 // zf is result of zipArchive functions true or false
1249 $zf = edih_archive_create_zip($p, $fn_ar, $archive_date, $arch_fn);
1251 // delete archived files
1253 // replace the csv files
1254 $rn = rename($fn_files_keep, $files_csv);
1256 csv_edihist_log("edih_archive_main: replaced $files_csv");
1258 csv_edihist_log("edih_archive_main: error trying to replace $files_csv");
1261 $rn = rename($fn_claims_keep, $claims_csv);
1263 csv_edihist_log("edih_archive_main: replaced $claims_csv");
1265 csv_edihist_log("edih_archive_main: error trying to replace $claims_csv");
1268 // move archive files to tmpdir/ftype
1269 // $rndir = mkdir($tmpdir.DS.$fdir);
1270 csv_edihist_log("edih_archive_main: $ft now moving old files ");
1271 $del = edih_archive_move_old($p, $fn_ar);
1272 $out_html .= "Archive moved " . text($del . " " . $ft) . " type files<br />" . PHP_EOL
;
1275 csv_edihist_log("edih_archive_main: type $ft error in creating archive");
1276 $out_html .= "type " . text($ft) . " error in creating archive<br />" . PHP_EOL
;
1279 csv_edihist_log("edih_archive_main: search found no type $ft files older than $period");
1280 $out_html .= "Archive: type " . text($ft) . " archive found no files older than " . text($period) . "<br />" . PHP_EOL
;
1282 } // end foreach($params as $k=>$p)
1284 if (is_file($tmp_dir . DS
. $arch_fn)) {
1285 $rn = rename($tmp_dir . DS
. $arch_fn, $archive_dir . DS
. $arch_fn);
1286 $cm = chmod($archive_dir . DS
. $arch_fn, 0400);
1288 csv_edihist_log("edih_archive_main: moved $arch_fn to archive directory");
1290 csv_edihist_log("edih_archive_main: error moving archive file $arch_fn");
1291 $out_html .= "<p>edih_archive_main: error moving archive file " . text($arch_fn) . "</p>";
1294 csv_edihist_log("edih_archive_main: is_file false $tmp_dir.DS.$arch_fn");
1297 //edih_archive_cleanup($arch_fn, $tp_ar);
1298 $is_clear = csv_clear_tmpdir();
1300 $out_html .= "Archive: temporary files removed. Process complete.<br />" . PHP_EOL
;
1302 $out_html .= "Archive: still some files in /history/tmp/. Process complete.<br />" . PHP_EOL
;