You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

123 lines
4.0 KiB

#!/usr/bin/php
<?php
/**
* CLI script to compute patient duplication scores in patient_data.dupscore.
* The score is a measure of the likelihood that the patient is a duplicate of
* some patient created before it. Optional arguments specifying values are:
*
* --webdir The full path to the OpenEMR web directory. Defaults to the directory
* two levels above that of this script.
* --site The site ID. Defaults to "default".
* --maxmins The maximum number of minutes to run. Defaults to 60. Use 0 for no limit.
*
* Arguments not having a value may be:
*
* -q Suppresses messages on stdout.
* -c Clears existing scores to recompute all of them; except scores of -1
* are not cleared because they are manually assigned.
*
* Because we are comparing every patient with every other patient, this script can
* run for a very long time with a large database. Thus we want to do it offline.
* If --maxmins is exceeded the script will terminate but may be run again to resume
* where it left off.
*
* A common usage is:
* php /var/www/html/openemr/contrib/util/dupscore.cli.php --maxmins=240
*
* Here is a sample crontab entry to automatically run up to 2 hours nightly:
* 3 1 * * * root php /var/www/html/openemr/contrib/util/dupscore.cli.php -q --maxmins=120
*
* @package OpenEMR
* @link http://www.open-emr.org
* @author Rod Roark <rod@sunsetsystems.com>
* @copyright Copyright (c) 2021 Rod Roark <rod@sunsetsystems.com>
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/
// The number of scores to compute between tests for time expiration.
$querylimit = 1000;
if (php_sapi_name() !== 'cli') {
die("This script must be run from the command line!\n");
}
$args = getopt('cq', array('webdir:', 'site:', 'maxmins:'));
// print_r($args); // debugging
$args['webdir'] = $args['webdir'] ?? dirname(dirname(dirname(__FILE__)));
$args['site'] = $args['site'] ?? 'default';
$args['maxmins'] = floatval($args['maxmins'] ?? 60);
if (stripos(PHP_OS, 'WIN') === 0) {
$args['webdir'] = str_replace("\\", "/", $args['webdir']);
}
// Bring in some libraries and settings shared with web scripts.
$_GET['site'] = $args['site'];
$ignoreAuth = 1;
require_once($args['webdir'] . "/interface/globals.php");
// Bring in the getDupScoreSQL() function.
require_once("$srcdir/dupscore.inc.php");
$endtime = time() + 365 * 24 * 60 * 60; // a year from now
if (!empty($args['maxmins'])) {
$endtime = time() + $args['maxmins'] * 60;
}
if (isset($args['c'])) {
// Note -1 means the patient is manually flagged as not a duplicate.
sqlStatementNoLog("UPDATE patient_data SET dupscore = -9 WHERE dupscore != -1");
if (!isset($args['q'])) {
echo xl("All scores have been cleared.") . "\n";
}
}
$count = 0;
$finished = false;
while (!$finished && time() < $endtime) {
$scores = array();
$query1 = "SELECT p1.pid, MAX(" . getDupScoreSQL() . ") AS dupscore" .
" FROM patient_data AS p1, patient_data AS p2" .
" WHERE p1.dupscore = -9 AND p2.pid < p1.pid" .
" GROUP BY p1.pid ORDER BY p1.pid LIMIT " . escape_limit($querylimit);
// echo "$query1\n"; // debugging
$res1 = sqlStatementNoLog($query1);
while ($row1 = sqlFetchArray($res1)) {
$scores[$row1['pid']] = $row1['dupscore'];
};
foreach ($scores as $pid => $score) {
sqlStatementNoLog(
"UPDATE patient_data SET dupscore = ? WHERE pid = ?",
array($score, $pid)
);
++$count;
}
if (!isset($args['q']) && count($scores) > 0) {
echo "$count... ";
}
if (count($scores) < $querylimit) {
$finished = true;
}
}
if (!isset($args['q'])) {
if (!$count) {
echo xl("No patients without scores were found.");
}
if ($finished) {
echo "\n" . xl("All done.") . "\n";
} else {
echo "\n" . xl("This run is incomplete due to time expiration.") . "\n";
}
}
if (!$finished) {
exit(1);
}