From 22f1ea5e8c07c8ff9f61ed16cc1a0dd40c94a6af Mon Sep 17 00:00:00 2001 From: John Saigle Date: Wed, 29 Jan 2020 15:31:38 -0500 Subject: [PATCH] [Tools] Enable PHPCS for CouchDB_Import_Demographics.php --- test/run-php-linter.sh | 1 + tools/CouchDB_Import_Demographics.php | 460 +++++++++++++++----------- 2 files changed, 277 insertions(+), 184 deletions(-) diff --git a/test/run-php-linter.sh b/test/run-php-linter.sh index 55d5484da01..adf080be871 100755 --- a/test/run-php-linter.sh +++ b/test/run-php-linter.sh @@ -45,6 +45,7 @@ declare -a tools_list=( 'populate_visit_windows.php' 'manage_modules.php' 'DB_date_zeros_removal.php' + 'CouchDB_Import_Demographics.php' ) # And on all PHP files in this array diff --git a/tools/CouchDB_Import_Demographics.php b/tools/CouchDB_Import_Demographics.php index 04d8c9656f8..42e91db3a15 100755 --- a/tools/CouchDB_Import_Demographics.php +++ b/tools/CouchDB_Import_Demographics.php @@ -1,103 +1,131 @@ #!/usr/bin/env php + * @license Loris license + * @link https://www.github.com/aces/Loris-Trunk/ + */ require_once __DIR__ . "/../vendor/autoload.php"; require_once 'generic_includes.php'; require_once 'CouchDB.class.inc'; require_once 'Database.class.inc'; -class CouchDBDemographicsImporter { +/** + * Imports demographics to CouchDB + * + * @category Main + * @package Loris + * @author Loris Team + * @license Loris license + * @link https://www.github.com/aces/Loris-Trunk/ + */ +class CouchDBDemographicsImporter +{ var $SQLDB; // reference to the database handler, store here instead // of using Database::singleton in case it's a mock. var $CouchDB; // reference to the CouchDB database handler // this is just in an instance variable to make // the code a little more readable. - var $Dictionary = array( - 'DoB' => array( + var $Dictionary = [ + 'DoB' => [ 'Description' => 'Date of Birth', - 'Type' => 'date' - ), - 'DoD' => array( + 'Type' => 'date' + ], + 'DoD' => [ 'Description' => 'Date of Death', - 'Type' => 'date' - ), - 'CandID' => array( + 'Type' => 'date' + ], + 'CandID' => [ 'Description' => 'DCC Candidate Identifier', - 'Type' => 'varchar(255)' - ), - 'PSCID' => array( + 'Type' => 'varchar(255)', + ], + 'PSCID' => [ 'Description' => 'Project Candidate Identifier', - 'Type' => 'varchar(255)' - ), - 'Visit_label' => array( + 'Type' => 'varchar(255)', + ], + 'Visit_label' => [ 'Description' => 'Visit of Candidate', - 'Type' => 'varchar(255)' - ), - 'Cohort' => array( + 'Type' => 'varchar(255)', + ], + 'Cohort' => [ 'Description' => 'Cohort of this session', - 'Type' => 'varchar(255)' - ), - 'Sex' => array( + 'Type' => 'varchar(255)', + ], + 'Sex' => [ 'Description' => 'Candidate\'s biological sex', - 'Type' => "enum('Male', 'Female', 'Other')" - ), - 'Site' => array( + 'Type' => "enum('Male', 'Female', 'Other')" + ], + 'Site' => [ 'Description' => 'Site that this visit took place at', - 'Type' => "varchar(3)", - ), - 'Current_stage' => array( + 'Type' => "varchar(3)", + ], + 'Current_stage' => [ 'Description' => 'Current stage of visit', - 'Type' => "enum('Not Started','Screening','Visit','Approval','Subject','Recycling Bin')" - ), - 'Failure' => array( - 'Description' => 'Whether Recycling Bin Candidate was failure or withdrawal', - 'Type' => "enum('Failure','Withdrawal','Neither')", - ), - 'CEF' => array( + 'Type' => "enum('Not Started','Screening','Visit'," . + "'Approval','Subject','Recycling Bin')", + ], + 'Failure' => [ + 'Description' => 'Whether Recycling Bin Candidate was failure or ' + .'withdrawal', + 'Type' => "enum('Failure','Withdrawal','Neither')", + ], + 'CEF' => [ 'Description' => 'Caveat Emptor flag', - 'Type' => "enum('true','false')", - ), - 'CEF_reason' => array( + 'Type' => "enum('true','false')", + ], + 'CEF_reason' => [ 'Description' => 'Reason for Caveat Emptor flag', - 'Type' => "varchar(255)", - ), - 'CEF_comment' => array( + 'Type' => "varchar(255)", + ], + 'CEF_comment' => [ 'Description' => 'Comment on Caveat Emptor flag', - 'Type' => "varchar(255)", - ), - 'Comment' => array( + 'Type' => "varchar(255)", + ], + 'Comment' => [ 'Description' => 'Candidate comment', - 'Type' => "varchar(255)", - ), - 'Status' => array( + 'Type' => "varchar(255)", + ], + 'Status' => [ 'Description' => 'Participant status', - 'Type' => "varchar(255)", - ), - 'Status_reason' => array( - 'Description' => 'Reason for status - only filled out if status is inactive or incomplete', - 'Type' => "int(10)", - ), - 'Status_comments' => array( + 'Type' => "varchar(255)", + ], + 'Status_reason' => [ + 'Description' => 'Reason for status - only filled out if status ' + . 'is inactive or incomplete', + 'Type' => "int(10)", + ], + 'Status_comments' => [ 'Description' => 'Participant status comments', - 'Type' => "text", - ), - 'session_feedback' => array( + 'Type' => "text", + ], + 'session_feedback' => [ 'Description' => 'Behavioural feedback at the session level', - 'Type' => "varchar(255)", - ) - ); + 'Type' => "varchar(255)", + ], + ]; - var $Config = array( - 'Meta' => array( - 'DocType' => 'ServerConfig' - ), - 'Config' => array( + var $Config = [ + 'Meta' => ['DocType' => 'ServerConfig'], + 'Config' => [ 'GroupString' => 'How to arrange data: ', - 'GroupOptions' => - array('Cross-sectional', 'Longitudinal') - ) - ); + 'GroupOptions' => [ + 'Cross-sectional', + 'Longitudinal', + ], + ], + ]; - function __construct() { + /** + * Create a new instance + */ + function __construct() + { $factory = \NDB_Factory::singleton(); $config = \NDB_Config::singleton(); $couchConfig = $config->getSetting('CouchDB'); @@ -111,25 +139,48 @@ function __construct() { ); } - function _getSubproject($id) { - $config = \NDB_Config::singleton(); + /** + * Get subproject title + * + * @param int $id The subproject ID + * + * @return string + */ + function _getSubproject($id) + { + $config = \NDB_Config::singleton(); $subprojs = $config->getSubprojectSettings($id); - if($subprojs['id'] == $id) { + if ($subprojs['id'] == $id) { return $subprojs['title']; } } - function _getProject($id) { + /** + * Get project name + * + * @param int $id The projectID + * + * @return string + */ + function _getProject($id) + { $config = \NDB_Config::singleton(); - $projs = $config->getProjectSettings($id); - if($projs['id'] == $id) { + $projs = $config->getProjectSettings($id); + if ($projs['id'] == $id) { return $projs['Name']; } } - function _generateQuery() { + /** + * Builds SQL query. + * + * @return string + */ + function _generateQuery() + { $config = \NDB_Config::singleton(); + //phpcs:disable $fieldsInQuery = "SELECT c.DoB, c.DoD, c.CandID, @@ -149,7 +200,7 @@ function _generateQuery() { ps.participant_suboptions as Status_reason, ps.reason_specify as Status_comments, GROUP_CONCAT(fbe.Comment) as session_feedback"; - $tablesToJoin = " FROM session s + $tablesToJoin = " FROM session s JOIN candidate c USING (CandID) LEFT JOIN psc p ON (p.CenterID=s.CenterID) LEFT JOIN caveat_options c_o ON (c_o.ID=c.flagged_reason) @@ -158,7 +209,8 @@ function _generateQuery() { LEFT JOIN participant_status_options pso ON (pso.ID=ps.participant_status) LEFT JOIN feedback_bvl_thread fbt ON (fbt.CandID=c.CandID) LEFT JOIN feedback_bvl_entry fbe ON (fbe.FeedbackID=fbt.FeedbackID)"; - $groupBy=" GROUP BY s.ID, + //phpcs:enable + $groupBy =" GROUP BY s.ID, c.DoB, c.CandID, c.PSCID, @@ -177,182 +229,222 @@ function _generateQuery() { ps.participant_suboptions, ps.reason_specify"; - // If proband fields are being used, add proband information into the query + // If proband fields are being used, add proband information into the + // query if ($config->getSetting("useProband") === "true") { - $probandFields = ", c.ProbandSex as Sex_proband, ROUND(DATEDIFF(c.DoB, c.ProbandDoB) / (365/12)) AS Age_difference"; + $probandFields = ", c.ProbandSex as Sex_proband, " + ."ROUND(DATEDIFF(c.DoB, c.ProbandDoB) / (365/12)) " . + "AS Age_difference"; $fieldsInQuery .= $probandFields; - $groupBy .= ", c.ProbandSex, Age_difference"; + $groupBy .= ", c.ProbandSex, Age_difference"; } - // If expected date of confinement is being used, add EDC information into the query + // If expected date of confinement is being used, add EDC information + // into the query if ($config->getSetting("useEDC") === "true") { - $EDCFields = ", c.EDC as EDC"; + $EDCFields = ", c.EDC as EDC"; $fieldsInQuery .= $EDCFields; - $groupBy .= ", c.EDC"; + $groupBy .= ", c.EDC"; } // If consent is being used, add consent information into query if ($config->getSetting("useConsent") === "true") { - $consents = \Utility::getConsentList(); - foreach($consents as $consentID=>$consent) { - $consentName = $consent['Name']; - $cField = $this->SQLDB->escape("cc$consentID"); - $consentFields = ", + $consents = \Utility::getConsentList(); + foreach ($consents as $consentID => $consent) { + $consentName = $consent['Name']; + $cField = $this->SQLDB->escape("cc$consentID"); + $consentFields = ", $cField.Status AS " . $consentName . ", $cField.DateGiven AS " . $consentName . "_date, $cField.DateWithdrawn AS " . $consentName . "_withdrawal"; - $fieldsInQuery .= $consentFields; - $tablesToJoin .= " - LEFT JOIN candidate_consent_rel $cField ON ($cField.CandidateID=c.CandID) - AND $cField.ConsentID=(SELECT ConsentID FROM consent WHERE Name='" . $consentName . "') "; - $groupBy .= ", + $fieldsInQuery .= $consentFields; + $tablesToJoin .= " + LEFT JOIN candidate_consent_rel $cField + ON ($cField.CandidateID=c.CandID) + AND $cField.ConsentID=(SELECT ConsentID + FROM consent + WHERE Name='" . $consentName . "') "; + $groupBy .= ", $cField.Status, $cField.DateGiven, $cField.DateWithdrawn"; - } + } } - $whereClause=" WHERE s.Active='Y' AND c.Active='Y' AND c.Entity_type != 'Scanner'"; + $whereClause =" WHERE s.Active='Y' AND c.Active='Y' " + ."AND c.Entity_type != 'Scanner'"; $concatQuery = $fieldsInQuery . $tablesToJoin . $whereClause . $groupBy; return $concatQuery; } - function _updateDataDict() { + /** + * Update data dictionary + * + * @return void + */ + function _updateDataDict() + { $config = \NDB_Config::singleton(); // If proband fields are being used, update the data dictionary if ($config->getSetting("useProband") === "true") { - $this->Dictionary["Sex_proband"] = array( + $this->Dictionary["Sex_proband"] = [ 'Description' => 'Proband\'s biological sex', - 'Type' => "enum('Male','Female', 'Other')" - ); - $this->Dictionary["Age_difference"] = array( - 'Description' => 'Age difference between the candidate and the proband', - 'Type' => "int" - ); + 'Type' => "enum('Male','Female', 'Other')" + ]; + $this->Dictionary["Age_difference"] = [ + 'Description' => 'Age difference between the candidate and ' . + 'the proband', + 'Type' => "int", + ]; } - // If expected date of confinement is being used, update the data dictionary + // If expected date of confinement is being used, update the data + // dictionary if ($config->getSetting("useEDC") === "true") { - $this->Dictionary["EDC"] = array( + $this->Dictionary["EDC"] = [ 'Description' => 'Expected Date of Confinement (Due Date)', - 'Type' => "varchar(255)" - ); + 'Type' => "varchar(255)", + ]; } - $projects = \Utility::getProjectList(); - $projectsEnum = "enum('"; + $projects = \Utility::getProjectList(); + $projectsEnum = "enum('"; $projectsEnum .= implode("', '", $projects); $projectsEnum .= "')"; - $this->Dictionary["Project"] = array( + $this->Dictionary["Project"] = [ 'Description' => 'Project for which the candidate belongs', - 'Type' => $projectsEnum - ); + 'Type' => $projectsEnum, + ]; // If consent is being used, update the data dictionary if ($config->getSetting("useConsent") === "true") { - $consents = \Utility::getConsentList(); - foreach($consents as $consent) { - $consentName = $consent['Name']; - $consentLabel = $consent['Label']; - $this->Dictionary[$consentName] = array( - 'Description' => $consentLabel, - 'Type' => "enum('yes','no')" - ); - $this->Dictionary[$consentName . "_date"] = array( - 'Description' => $consentLabel . ' Date', - 'Type' => "date" - ); - $this->Dictionary[$consentName . "_withdrawal"] = array( - 'Description' => $consentLabel . ' Withdrawal Date', - 'Type' => "date" - ); - } - } - /* - // Add any candidate parameter fields to the data dictionary - $parameterCandidateFields = $this->SQLDB->pselect("SELECT * from parameter_type WHERE SourceFrom='parameter_candidate' AND Queryable=1", - array()); - foreach($parameterCandidateFields as $field) { - if(isset($field['Name'])) { - $fname = $field['Name']; - $Dict[$fname] = array(); - $Dict[$fname]['Description'] = $field['Description']; - $Dict[$fname]['Type'] = $field['Type']; + $consents = \Utility::getConsentList(); + foreach ($consents as $consent) { + $consentName = $consent['Name']; + $consentLabel = $consent['Label']; + $this->Dictionary[$consentName] = [ + 'Description' => $consentLabel, + 'Type' => "enum('yes','no')", + ]; + $this->Dictionary[$consentName . "_date"] = [ + 'Description' => $consentLabel . ' Date', + 'Type' => "date", + ]; + $this->Dictionary[$consentName . "_withdrawal"] = [ + 'Description' => $consentLabel . ' Withdrawal Date', + 'Type' => "date", + ]; } } - */ } - function run() { - $config = $this->CouchDB->replaceDoc('Config:BaseConfig', $this->Config); + /** + * Run the query + * + * @return void + */ + function run() + { + $config = $this->CouchDB->replaceDoc( + 'Config:BaseConfig', + $this->Config + ); print "Updating Config:BaseConfig: $config"; // Run query - $max_len = $this->SQLDB->run("SET SESSION group_concat_max_len = 100000;", array()); - $demographics = $this->SQLDB->pselect($this->_generateQuery(), array()); + $max_len = $this->SQLDB->run( + "SET SESSION group_concat_max_len = 100000;", + [] + ); + $demographics = $this->SQLDB->pselect($this->_generateQuery(), []); $this->CouchDB->beginBulkTransaction(); $config_setting = \NDB_Config::singleton(); - foreach($demographics as $demographics) { - $id = 'Demographics_Session_' . $demographics['PSCID'] . '_' . $demographics['Visit_label']; - $demographics['Cohort'] = $this->_getSubproject($demographics['SubprojectID']); + foreach ($demographics as $demographics) { + $id = 'Demographics_Session_' + . $demographics['PSCID'] + . '_' + . $demographics['Visit_label']; + $demographics['Cohort'] + = $this->_getSubproject($demographics['SubprojectID']); unset($demographics['SubprojectID']); - if(isset($demographics['ProjectID'])) { - $demographics['Project'] = $this->_getProject($demographics['ProjectID']); + if (isset($demographics['ProjectID'])) { + $demographics['Project'] + = $this->_getProject($demographics['ProjectID']); unset($demographics['ProjectID']); } if ($config_setting->getSetting("useFamilyID") === "true") { - $familyID = $this->SQLDB->pselectOne("SELECT FamilyID FROM family + $familyID = $this->SQLDB->pselectOne( + "SELECT FamilyID FROM family WHERE CandID=:cid", - array('cid'=>$demographics['CandID'])); + ['cid' => $demographics['CandID']] + ); if (!empty($familyID)) { - $this->Dictionary["FamilyID"] = array( - 'Description' => 'FamilyID of Candidate', - 'Type' => "int(6)", - ); - $demographics['FamilyID'] = $familyID; - $familyFields = $this->SQLDB->pselect("SELECT candID as Family_ID, + $this->Dictionary["FamilyID"] = [ + 'Description' => 'FamilyID of Candidate', + 'Type' => "int(6)", + ]; + $demographics['FamilyID'] = $familyID; + $familyFields = $this->SQLDB->pselect( + "SELECT candID as Family_ID, Relationship_type as Relationship_to_candidate FROM family WHERE FamilyID=:fid AND CandID<>:cid", - array('fid'=>$familyID, 'cid'=>$demographics['CandID'])); - $num_family = 1; + [ + 'fid' => $familyID, + 'cid' => $demographics['CandID'], + ] + ); + $num_family = 1; if (!empty($familyFields)) { - foreach($familyFields as $row) { + foreach ($familyFields as $row) { + // This script needs further refactoring because the + // indentation is too severe. Disable phpcs for this + // section. + //phpcs:disable //adding each sibling id and relationship to the file - $this->Dictionary["Family_CandID".$num_family] = array( - 'Description' => 'CandID of Family Member '.$num_family, - 'Type' => "varchar(255)", - ); + $this->Dictionary["Family_CandID".$num_family] = array( + 'Description' => 'CandID of Family Member '.$num_family, + 'Type' => "varchar(255)", + ); $this->Dictionary["Relationship_type_Family".$num_family] = array( - 'Description' => 'Relationship of candidate to Family Member '.$num_family, - 'Type' => "enum('half_sibling','full_sibling','1st_cousin')", - ); - $demographics['Family_CandID'.$num_family] = $row['Family_ID']; + 'Description' => 'Relationship of candidate to Family Member '.$num_family, + 'Type' => "enum('half_sibling','full_sibling','1st_cousin')", + ); + $demographics['Family_CandID'.$num_family] = $row['Family_ID']; $demographics['Relationship_type_Family'.$num_family] = $row['Relationship_to_candidate']; - $num_family += 1; + $num_family += 1; + //phpcs:enable } } } } - $success = $this->CouchDB->replaceDoc($id, array('Meta' => array( - 'DocType' => 'demographics', - 'identifier' => array($demographics['PSCID'], $demographics['Visit_label']) - ), - 'data' => $demographics - )); + $success = $this->CouchDB->replaceDoc( + $id, + [ + 'Meta' => [ + 'DocType' => 'demographics', + 'identifier' => [ + $demographics['PSCID'], + $demographics['Visit_label'], + ], + ], + 'data' => $demographics, + ] + ); print "$id: $success\n"; } $this->_updateDataDict(); - $this->CouchDB->replaceDoc('DataDictionary:Demographics', - array('Meta' => array('DataDict' => true), - 'DataDictionary' => array('demographics' => $this->Dictionary) - ) - ); + $this->CouchDB->replaceDoc( + 'DataDictionary:Demographics', + [ + 'Meta' => ['DataDict' => true], + 'DataDictionary' => ['demographics' => $this->Dictionary], + ] + ); print $this->CouchDB->commitBulkTransaction(); - } } // Don't run if we're doing the unit tests; the unit test will call run. -if(!class_exists('UnitTestCase')) { +if (!class_exists('UnitTestCase')) { $Runner = new CouchDBDemographicsImporter(); $Runner->run(); }