diff --git a/docs/wiki/01_STUDY_PARAMETERS_SETUP/02_Clinical_Instruments/03_instrument_install.md b/docs/wiki/01_STUDY_PARAMETERS_SETUP/02_Clinical_Instruments/03_instrument_install.md index fb7f50d3fc..fd2076846e 100644 --- a/docs/wiki/01_STUDY_PARAMETERS_SETUP/02_Clinical_Instruments/03_instrument_install.md +++ b/docs/wiki/01_STUDY_PARAMETERS_SETUP/02_Clinical_Instruments/03_instrument_install.md @@ -34,7 +34,7 @@ following the documentation. **PHP instruments** behave slightly differently than LINST instruments and require more manual steps for installation. In order to be able to generate the SQL table for PHP instruments, they must first be parsed. The LORIS codebase -includes a tool under the `tools/` directory called the `lorisform_parser.php` +includes a tool under the `tools/` directory called the `ip_output_builder.php` allowing for a PHP instrument to be parsed into an intermediary serialized format and automatically stored in the `tools/ip_output.txt` file. @@ -48,11 +48,11 @@ Follow the steps below to install a new PHP instrument. 1. Move your newly created instrument `NDB_BVL_Instrument_TEST_NAME.class.inc` into the `project/instruments/` directory. 2. Navigate to the LORIS `tools/` directory. - 3. Run the instrument through the `lorisform_parser.php` to parse the PHP + 3. Run the instrument through the `ip_output_builder.php` to parse the PHP instrument into the intermediary serialed format. - ``` - ls ../project/instruments/NDB_BVL_Instrument_TEST_NAME.class.inc | php lorisform_parser.php - ``` + ``` + php ip_output_builder.php --one-instrument=TEST_NAME + ``` 4. Run the `generate_tables_sql.php` tool to converted the serialized format into an SQL `CREATE TABLE` SQL patch. The patch will be created in the `project/` directory by default. @@ -64,10 +64,9 @@ Follow the steps below to install a new PHP instrument. 6. Register the instrument in the `test_names` table of the database by running the following command. Make sure to replace the `'TEST_NAME'` value with the actual test name used in your instrument. - - ``` - INSERT INTO test_names (Test_name,Sub_group) SELECT 'TEST_NAME', ID FROM test_subgroups WHERE Subgroup_name='Instruments'; - ``` + ``` + INSERT INTO test_names (Test_name,Sub_group) SELECT 'TEST_NAME', ID FROM test_subgroups WHERE Subgroup_name='Instruments'; + ``` > _**Note:** The `Sub_group` entry in the query above is necessary for the > instrument registration. See the [Instrument Grouping](#instrument-grouping) @@ -119,7 +118,3 @@ assigned to categories and sorted accordingly on the user's interface. New entries can be added to the `test_subgroups` table to create new categories and instruments can be assigned a category by updating the `Sub_group` column in the `test_names` table with the desired `ID` from the `test_subgroups` table. - - - - diff --git a/modules/datadict/README.md b/modules/datadict/README.md index 0509a0cd8a..9e688babe1 100644 --- a/modules/datadict/README.md +++ b/modules/datadict/README.md @@ -11,7 +11,7 @@ The module displays and manages the data dictionary for fields already stored in the LORIS `parameter_type` table. This table is generally autopopulated and provides a dictionary for imaging headers (populated by the imaging pipeline) and behavioural instruments -(populated by the `lorisform_parser.php` script). +(populated by the `tools/ip_output_builder.php` script). It does not provide a way to enter new fields into the data dictionary, or describe the data dictionary for arbitrary SQL fields which are @@ -34,7 +34,7 @@ The data comes from two sources: 1. The LORIS imaging pipeline scripts, which must be setup separately 2. The `tools/data_dictionary_builder.php` script, which loads the behavioural data dictionary based on the `ip_output.txt` file created - by `tools/lorisform_parser.php` + by `tools/ip_output_builder.php` ## Interactions with LORIS diff --git a/php/libraries/LorisFormDictionaryImpl.class.inc b/php/libraries/LorisFormDictionaryImpl.class.inc index 467e3401ae..946474fcb4 100644 --- a/php/libraries/LorisFormDictionaryImpl.class.inc +++ b/php/libraries/LorisFormDictionaryImpl.class.inc @@ -6,7 +6,7 @@ use \LORIS\Data\Scope; use \LORIS\Data\Cardinality; /** * Helper to extract a dictionary from a LorisForm, primarily - * used by instruments. This is based on lorisform_parser.php + * used by instruments. This is based on ip_output_builder.php * * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 */ diff --git a/php/libraries/NDB_BVL_Instrument.class.inc b/php/libraries/NDB_BVL_Instrument.class.inc index ea7263abe0..a3335e97cf 100644 --- a/php/libraries/NDB_BVL_Instrument.class.inc +++ b/php/libraries/NDB_BVL_Instrument.class.inc @@ -153,7 +153,7 @@ abstract class NDB_BVL_Instrument extends NDB_Page /** * True if the instrument page is being loaded by a script - * such as the lorisform_parser where all elements should be added to form, + * such as the ip_output_builder where all elements should be added to form, * ignoring age-dependent or other conditional display logic in the form. * To be called from within individual instrument forms. */ diff --git a/php/libraries/NDB_BVL_Instrument_LINST.class.inc b/php/libraries/NDB_BVL_Instrument_LINST.class.inc index 3ff16551e1..69166dbb28 100644 --- a/php/libraries/NDB_BVL_Instrument_LINST.class.inc +++ b/php/libraries/NDB_BVL_Instrument_LINST.class.inc @@ -32,6 +32,11 @@ use \LORIS\Data\Types\DateType; */ class NDB_BVL_Instrument_LINST extends \NDB_BVL_Instrument { + /** + * Line read size buffer. + */ + public const int LINE_BUFFER_SIZE = 131072; + public $InstrumentType = 'LINST'; public $LinstQuestions = []; @@ -394,7 +399,7 @@ class NDB_BVL_Instrument_LINST extends \NDB_BVL_Instrument ]; // Buffer = 128KB - while (($line = fgets($fp, 131072)) !== false) { + while (($line = fgets($fp, self::LINE_BUFFER_SIZE)) !== false) { $pieces = preg_split("/{@}/", $line); $this->LinstLines[] = $pieces; diff --git a/tools/exporters/data_dictionary_builder.php b/tools/exporters/data_dictionary_builder.php index f30ea9fd46..e4647af207 100755 --- a/tools/exporters/data_dictionary_builder.php +++ b/tools/exporters/data_dictionary_builder.php @@ -13,7 +13,7 @@ * * Input: * data_dictionary_builder.php takes as input the ip_output.txt file (generated - * by lorisform_parser.php) and inserts records for each field of each + * by tools/ip_output_builder.php) and inserts records for each field of each * discovered NDB_BVL_Instrument. To be complete, this tool must be run on an * ip_output.txt file that was constructed from all instruments. * @@ -116,7 +116,7 @@ break; case "table": $table = $bits[1]; - //`testname` was only recently added to the lorisform parser, for + //`testname` was only recently added to the ip_output_builder, for //backwards compatibility, instruments with no testname parameter //should assume the testname from the `table` name (to maintain //status quo) although it might be incorrect since instrument names diff --git a/tools/generate_tables_sql.php b/tools/generate_tables_sql.php index 5d9fb6fc78..d3307688e3 100755 --- a/tools/generate_tables_sql.php +++ b/tools/generate_tables_sql.php @@ -3,7 +3,7 @@ /** * The script generate_tables_sql.php takes the ip_output.txt file generated from - * lorisform_parser.php and outputs an sql build file for the table of each + * ip_output_builder.php and outputs an sql build file for the table of each * instrument it finds in the ip_output.txt file. These sql files are output * to the tables_sql/ subdirectory. * @@ -34,6 +34,12 @@ $tblCount = 0; $parameterCount = 0; foreach ($instruments as $instrument) { + // skip last line (empty instrument) + if (empty($instrument)) { + continue; + } + + // parse instrument $catId = ""; $output = ""; $items = explode("\n", trim($instrument)); diff --git a/tools/generate_tables_sql_and_testNames.php b/tools/generate_tables_sql_and_testNames.php index 4cb987e4f9..5a6f00066b 100755 --- a/tools/generate_tables_sql_and_testNames.php +++ b/tools/generate_tables_sql_and_testNames.php @@ -3,7 +3,7 @@ /** * The script generate_tables_sql_and_testNames.php takes - * the ip_output.txt file generated from lorisform_parser.php + * the ip_output.txt file generated from ip_output_builder.php * and outputs an sql build file for the table of each instrument * it finds in the ip_output.txt file. * These sql files are output to the tables_sql/ subdirectory. @@ -21,7 +21,10 @@ require_once __DIR__ . "/generic_includes.php"; -$data = stream_get_contents(STDIN); +// read ip_output.txt +$fp = fopen(__DIR__ . "/ip_output.txt", "r"); +$data = fread($fp, filesize(__DIR__ . "/ip_output.txt")); +fclose($fp); $instruments = explode("{-@-}", trim($data)); @@ -29,6 +32,12 @@ $parameterCount = 0; $pages = []; foreach ($instruments as $instrument) { + // skip last line (empty instrument) + if (empty($instrument)) { + continue; + } + + // parse instrument $catId = ""; $output = ""; $items = explode("\n", trim($instrument)); @@ -71,6 +80,9 @@ continue 2; break; + case "testname": + continue 2; + // generate specific column definitions for specific HTML elements default: if ($bits[1] == "") { diff --git a/tools/ip_output_builder.php b/tools/ip_output_builder.php new file mode 100644 index 0000000000..bf2327ef89 --- /dev/null +++ b/tools/ip_output_builder.php @@ -0,0 +1,628 @@ +#!/usr/bin/env php + + * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 + * @link https://github.com/aces/Loris + */ + +require_once __DIR__ . "/generic_includes.php"; + +use \LORIS\LorisInstance; +use \Loris\Behavioural\NDB_BVL_Instrument_LINST; + +// parse args +$flags = getopt( + "lmo:h", + [ + "add-linst", + "add-meta", + "one-instrument:", + "help" + ] +); + +// +if (isset($flags["h"]) || isset($flags["help"])) { + usage(); + exit(0); +} + +// add options +$addLINST = isset($flags["l"]) || isset($flags["add-linst"]); +$addMeta = isset($flags["m"]) || isset($flags["add-meta"]); + +if ($addMeta && !$addLINST) { + fprintf(STDERR, "Option '--add-meta' requires '--add-linst'.\n"); + usage(); + exit(0); +} + +// should add "linst" instruments? +if ($addLINST) { + fprintf(STDOUT, "[option:add-linst] LINST instrument files will be added.\n"); +} + +// should add linst ".meta" file content? +if ($addMeta) { + fprintf(STDOUT, "[option:add-meta] LINST \".meta\" files will be added.\n"); +} + +// only one instrument +$instrumentTarget = $flags["o"] ?? $flags["one-instrument"] ?? null; +if ($instrumentTarget !== null) { + fprintf( + STDOUT, + "[option:one-instrument] Only targeting instrument: {$instrumentTarget}\n" + ); +} + +/** + * Clean label regex. + */ +const CLEAN_LABEL_REGEX = "/\s+/"; + +// loris base path +$lorisBase = $lorisInstance->getConfiguration()->getSetting("base"); +if ($lorisBase === null) { + fprintf(STDERR, "No 'base' defined for LORIS in the database. Please add it."); + exit(1); +} +$lorisBase = rtrim($lorisBase, "/"); + +// define paths +$instrumentDir = "{$lorisBase}/project/instruments"; +$outputFile = "{$lorisBase}/tools/ip_output.txt"; + +// get the list of instruments +$instruments = getInstruments($lorisInstance, $instrumentDir); + +// if only one instrument to parse +if ($instrumentTarget !== null) { + if (!array_key_exists($instrumentTarget, $instruments)) { + fprintf( + STDERR, + "[option:one-instrument] Targeted instrument does not" + . " exist or is excluded: {$instrumentTarget}\n" + ); + exit(1); + } + + // select only this instrument + $instruments = array_filter( + $instruments, + fn($i) => $i === $instrumentTarget, + ARRAY_FILTER_USE_KEY + ); +} + +// open ip_output.txt +$ipOutput = fopen($outputFile, "w"); + +// tells if an instrument file name targets a linst instrument +$isLINST = fn($instrumentFile) => str_ends_with($instrumentFile, ".linst"); + +// add instruments to ip_output.txt +foreach ($instruments as $instrumentName => $instrumentFileName) { + // log delimiter + fprintf(STDOUT, "---------------------------------------------------\n"); + + // process according to the file type + if ($isLINST($instrumentFileName)) { + // skip linst + if (!$addLINST) { + fprintf(STDOUT, "Skipping LINST instrument: {$instrumentName}\n"); + continue; + } + + // + fprintf(STDOUT, "Copying LINST instrument: {$instrumentName}\n"); + $barename = substr($instrumentFileName, 0, strpos($instrumentFileName, ".")); + $res = copyLINSTInstrument( + $ipOutput, + $instrumentName, + "{$instrumentDir}/{$instrumentFileName}", + $addMeta, + "{$instrumentDir}/{$barename}.meta" + ); + } else { + // parse and add PHP instrument to ip_ouput.txt + fprintf(STDOUT, "Parsing PHP instrument: {$instrumentName}\n"); + $res = parsePHPInstrument( + $lorisInstance, + $ipOutput, + $instrumentName, + "{$instrumentDir}/{$instrumentFileName}" + ); + } + + // result + if ($res === true) { + fprintf(STDOUT, "Complete!\n"); + } else { + fprintf(STDERR, "Error!\n"); + } + + // adding the star wars bomber terminal tag for each instrument + // at the end for the instrument to include possible ".meta" in + // ".linst" instrument case. + fwrite($ipOutput, "{-@-}\n"); +} + +// close ip_output.txt file +fclose($ipOutput); + +// -------------------------------------------------- +// Functions +// -------------------------------------------------- + +/** + * Reads a file and returns the content. + * + * @param string $instrumentFilePath the instrument file path + * + * @return string the file full data. + */ +function getInstrumentFileData(string $instrumentFilePath): string +{ + if (!is_file($instrumentFilePath)) { + throw new \LorisException( + "File does not exist or is not accessible: {$instrumentFilePath}" + ); + } + + // open file + $fp = fopen($instrumentFilePath, "r"); + if ($fp === false) { + throw new \LorisException("Failed to open {$instrumentFilePath}"); + } + + // Read data + // Using the same buffer as in NDB_BVL_Instrument_LINST. + // Based on very long line (lots of options) in some REDCap instruments. + $data = ""; + while (!feof($fp)) { + $line = fgets($fp, NDB_BVL_Instrument_LINST::LINE_BUFFER_SIZE); + if ($line === false) { + continue; + } + $data .= trim($line) . "\n"; + } + + // close and return + fclose($fp); + return $data; +} + +/** + * Add a linst file data to the "ip_output.txt". + * + * @param mixed $ipOutput the ip_output.txt file descriptor. + * @param string $instrumentName the instrument name + * @param string $instrumentFilePath the instrument ".linst" file path + * @param bool $addMeta add the ".meta" content to the beginning. + * @param string $instrumentMetaFile the instrument ".meta" file path + * + * @return bool true if the copying worked, else false. + */ +function copyLINSTInstrument( + mixed $ipOutput, + string $instrumentName, + string $instrumentFilePath, + bool $addMeta = false, + string $instrumentMetaFile = null +): bool { + // output final + $output = ""; + + // do add ".meta" content? + if ($addMeta) { + fprintf( + STDOUT, + "[option:add-meta] Reading file: {$instrumentMetaFile}\n" + ); + try { + $output .= getInstrumentFileData($instrumentMetaFile); + } catch (\LorisException $le) { + fprintf( + STDERR, + "[option:add-meta][skipped] {$le->getMessage()}\n" + ); + } + } + + // get ".linst" data + try { + $output .= getInstrumentFileData($instrumentFilePath); + } catch (\LorisException $le) { + fprintf(STDERR, "{$le->getMessage()}\n"); + return false; + } + + // copy to ip_output file + if (empty($output)) { + fprintf(STDERR, "Nothing to output, 'ip_output.txt' not created\n"); + } else { + fwrite($ipOutput, $output); + } + + // good end + return true; +} + +/** + * Parse a PHP instrument to the "ip_output.txt" stream. + * + * @param LorisInstance $loris the loris instance + * @param mixed $ipOutput the ip_output.txt file descriptor. + * @param string $instrumentName the instrument name + * @param string $instrumentFilePath the instrument file path + * + * @return bool true if the parsing worked, else false. + */ +function parsePHPInstrument( + LorisInstance $loris, + mixed $ipOutput, + string $instrumentName, + string $instrumentFilePath +): bool { + // get data + try { + $data = getInstrumentFileData($instrumentFilePath); + } catch (\LorisException $le) { + fprintf(STDERR, "{$le->getMessage()}\n"); + return false; + } + + // check instrument state + preg_match("/class (.+) extends NDB_BVL_Instrument/", $data, $matches); + if (empty($matches[1])) { + fprintf( + STDERR, + "File '{$instrumentFilePath}' does not contain an instrument.\n" + ); + return false; + } + + // match + fprintf(STDOUT, "Reading file {$instrumentFilePath}\n"); + $className = $matches[1]; + + // include + fprintf(STDOUT, "Requiring file...\n"); + include_once $instrumentFilePath; + + // instantiate + fprintf(STDOUT, "Instantiating new object...\n"); + $obj = new $className( + $loris, + new NullModule($loris, "loris"), + "", + "", + "", + "" + ); + + // setup instrument + fprintf(STDOUT, "Initializing instrument object...\n"); + $obj->setup(null, null); + $subtests = $obj->getSubtestList(); + foreach ($subtests as $subtest) { + $obj->page = $subtest['Name']; + fprintf(STDOUT, "Building instrument page '$subtest[Name]'...\n"); + $obj->_setupForm(); + } + + if (is_array($obj->getFullName())) { + fprintf( + STDERR, + "Could not find row for {$className} in table test_names," + . " please populate test_names, instrument_subtests\n" + ); + return false; + } + + // parse + fprintf(STDOUT, "Parsing instrument object...\n"); + if (empty($output)) { + $output = ""; + } + + $output .= "testname{@}" . $obj->testName . "\n"; + $output .= "table{@}" . $obj->table . "\n"; + $output .= "title{@}" . $obj->getFullName() . "\n"; + + $formElements = $obj->form->toElementArray(); + + $output .= parseElements($obj, $formElements["elements"]); + + // write in file + if (empty($output)) { + fprintf(STDERR, "Nothing to output, 'ip_output.txt' not created\n"); + } else { + fwrite($ipOutput, $output); + } + + // good end + return true; +} + +/** + * Create a linst formated string for an LorisForm element. + * + * @param NDB_BVL_Instrument $instrument an instrument instancer + * @param LorisFormElement $elements The element to parse. + * @param string $groupLabel The group label + * + * @return string LINST formated element. + */ +function parseElements($instrument, $elements, $groupLabel = "") +{ + $output = ''; + foreach ($elements as $element) { + + // clean label + $label = cleanLabel($element["label"], $groupLabel); + + // parse element + switch ($element["type"]) { + case "select": + $output .="select"; + if (array_key_exists("multiple", $element)) { + $output .="multiple"; + } + $output .="{@}".$element["name"]."{@}".$label."{@}"; + $optionsOutput =""; + foreach ($element["options"] as $key => $option) { + if (!empty($optionsOutput)) { + $optionsOutput .="{-}"; + } + if (is_null($option) || $option==="") { + $optionsOutput .="NULL"; + } else { + $optionsOutput .="'".$key."'"; + } + $optionsOutput .="=>'".addslashes($option)."'"; + } + $output .= $optionsOutput."\n"; + break; + + case "text": + $output .= "text{@}".$element["name"]."{@}".$label."\n"; + break; + + case "textarea": + $output .= "textarea{@}".$element["name"]."{@}".$label."\n"; + break; + + case "date": + $options = "{@}"; + if (array_key_exists("options", $element) + && isset($element["options"]["minYear"]) + && isset($element["options"]["maxYear"]) + ) { + $options = $element["options"]["minYear"] + ."{@}" + .$element["options"]["maxYear"]; + } + $output .= "date{@}".$element["name"]."{@}".$label."{@}".$options."\n"; + break; + + case "group": + $output .= parseElements($instrument, $element["elements"], $label); + break; + + case "header": + $name = ""; + if (array_key_exists("name", $element)) { + $name = $element["name"]; + } + $output .= "header{@}".$name."{@}".$element["label"]."\n"; + break; + + case "static": + //see how static element is used... + if (!array_key_exists("name", $element)) { + $output .="header{@}{@}".$label."\n"; + } elseif (($element["name"] == null) + || array_key_exists($element["name"], $instrument->localDefaults) + || $element["name"] =="lorisSubHeader" + ) { + //element is plain form text, or a header. + $output .= "header{@}".$element["name"]."{@}".$label."\n"; + } else { + //element reports a database score + $output .= "static{@}".$element["name"]."{@}".$label."\n"; + } + + break; + + case "advcheckbox": + $output .= "checkbox{@}".$element["name"]."{@}".$label."\n"; + break; + + case "html_quickform_radio": + $mainquestion = addslashes($element->_label); + $optionfield = addslashes($element->_text); + if ($element->_attributes["position"] == "first") { + $output .= "radio{@}"; + $output .= $element->_attributes["name"] . "{@}"; + $output .= $mainquestion . "{@}"; + } + $output .= "'" . $element->_attributes["value"] + . "'=>'" . $optionfield . "'"; + if ($element->_attributes["position"] == "last") { + $output .= "\n"; + } else { + $output .= "{-}"; + } + break; + case "time": + $output .= "time{@}".$element["name"]."{@}".$label."\n"; + break; + case "html": + case "file": + case "hidden": + // skip because it's useless + fprintf( + STDERR, + "SKIP: skipping quickform element type: ".$element["type"]."\n" + ); + break; + + default: + fprintf( + STDERR, + "WARNING: Unknown form element type: ".$element["type"]."\n" + ); + break; + } + } + return $output; +} + + /** + * Clean a raw label. + * + * @param null|string $rawLabel the raw label to clean. + * @param string $groupLabel an optional group label to include in the + * cleaning. + * + * @return string the cleaned label + */ +function cleanLabel( + ?string $rawLabel = null, + string $groupLabel = "" +): string { + // return group label instead + if ($rawLabel === null || empty(trim($rawLabel))) { + return trim(preg_replace(CLEAN_LABEL_REGEX, " ", $groupLabel)); + } + + // clean the raw label + $label = str_replace(" ", "", $rawLabel); + return trim(preg_replace(CLEAN_LABEL_REGEX, " ", $label)); +} + +/** + * Get the list of parsable PHP instruments. + * + * @param LorisInstance $loris the loris instance + * @param string $instrumentDir the instrument directory path + * + * @return array the list of selected instrument [name => filename] + */ +function getInstruments(LorisInstance $loris, string $instrumentDir): array +{ + // instruments to skip + $excludedInstruments = getExcludedInstruments($loris); + + // building list + fprintf(STDOUT, "Building instrument list...\n"); + $instruments = []; + foreach (new DirectoryIterator($instrumentDir) as $fileInfo) { + // skip self/parent directory + if ($fileInfo->isDot()) { + continue; + } + + // skip if is directory + if ($fileInfo->isDir()) { + continue; + } + + // skip if is linst or php only + if (!str_ends_with($fileInfo->getBasename(), ".class.inc") + && !str_ends_with($fileInfo->getBasename(), ".php") + && !str_ends_with($fileInfo->getBasename(), ".linst") + ) { + continue; + } + + // clean instrument name + // - remove extension + // - remove "NDB_BVL_Instrument_" prefix if any + $instrumentName = str_replace( + "NDB_BVL_Instrument_", + "", + substr( + $fileInfo->getBasename(), + 0, + strpos($fileInfo->getBasename(), ".") + ) + ); + + // skip excluded instruments + if (in_array($instrumentName, $excludedInstruments)) { + fprintf(STDOUT, " -> excluded instrument: {$instrumentName}"); + continue; + } + + // register instrument + $instruments[$instrumentName] = $fileInfo->getFilename(); + } + + // order instruments by key + ksort($instruments, SORT_STRING); + + // log + $numberOfInstruments = count($instruments); + fprintf(STDOUT, "Total instruments found: {$numberOfInstruments}\n"); + + // return the list of sorted instruments + return $instruments; +} + +/** + * Get the excluded instruments from the config file + * + * @param LorisInstance $loris a loris instance. + * + * @return array List of instruments to be skipped + */ +function getExcludedInstruments(LorisInstance $loris): array +{ + // Get the abbreviated instruments + $config = $loris->getConfiguration(); + $rawExcludedInstruments = $config->getSetting('excluded_instruments'); + + // + $excludedInstruments = []; + foreach ($rawExcludedInstruments as $instruments) { + foreach (Utility::asArray($instruments) as $instrument) { + $excludedInstruments[] = $instrument; + } + } + return $excludedInstruments; +} + +/** + * Prints help text for this tool. + * + * @return void + */ +function usage(): void +{ + $msg = ""; + $msg .= "Usage: ip_output_builder.php [-l|--add-linst]"; + $msg .= " [-m|--add-meta] [-o=INST|--one-instrument=INST]"; + $msg .= " [-h|--help]\n\n"; + $msg .= "Options:\n"; + $msg .= " -l/--add-linst Add LINST instrument processing\n"; + $msg .= " -m/--add-meta If '--add-linst' is used, add '.meta' file"; + $msg .= " content\n"; + $msg .= " -o/--one-instrument Only process one instrument INST\n"; + $msg .= " -h/--help Show this screen\n"; + + // display message + fprintf(STDOUT, $msg); +} diff --git a/tools/lorisform_parser.php b/tools/lorisform_parser.php index b7d0a3a69f..b2822b194e 100755 --- a/tools/lorisform_parser.php +++ b/tools/lorisform_parser.php @@ -19,6 +19,9 @@ require_once __DIR__ . "/../vendor/autoload.php"; require_once __DIR__ . "/generic_includes.php"; +// depreaction notice +fprintf(STDERR, "Tool is deprecated. Use 'tools/ip_output_builder.php' instead.\n"); + $instrumentsToSkip = []; $instruments = getExcludedInstruments(); foreach ($instruments as $instrument) { diff --git a/tools/redcap2linst.php b/tools/redcap2linst.php index 3571489f38..56f2c96194 100644 --- a/tools/redcap2linst.php +++ b/tools/redcap2linst.php @@ -255,11 +255,9 @@ function writeLINSTFile( } else { // write field line fwrite($fp, "$field\n"); - } } - fwrite($fp, "{-@-}\n"); fclose($fp); // META file