* * LICENSE: This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * @package OpenEMR * @author Rod Roark * @link http://www.open-emr.org */ require_once("../globals.php"); require_once("$srcdir/acl.inc"); require_once("$srcdir/log.inc"); require_once("$srcdir/formdata.inc.php"); $layouts = array( 'DEM' => xl('Demographics'), 'HIS' => xl('History'), 'FACUSR' => xl('Facility Specific User Information') ); if ($GLOBALS['ippf_specific']) { $layouts['GCA'] = xl('Abortion Issues'); $layouts['CON'] = xl('Contraception Issues'); } // Include Layout Based Transaction Forms. $lres = sqlStatement("SELECT * FROM list_options " . "WHERE list_id = 'transactions' ORDER BY seq, title"); while ($lrow = sqlFetchArray($lres)) { $layouts[$lrow['option_id']] = xl_list_label($lrow['title']); } // Include Layout Based Encounter Forms. $lres = sqlStatement("SELECT * FROM list_options " . "WHERE list_id = 'lbfnames' ORDER BY seq, title"); while ($lrow = sqlFetchArray($lres)) { $layouts[$lrow['option_id']] = xl_list_label($lrow['title']); } // Include predefined Validation Rules from list $validations = array(); $lres = sqlStatement("SELECT * FROM list_options " . "WHERE list_id = 'LBF_Validations' ORDER BY seq, title"); while ($lrow = sqlFetchArray($lres)) { $validations[$lrow['option_id']] = xl_list_label($lrow['title']); } // array of the data_types of the fields $datatypes = array( "1" => xl("List box"), "2" => xl("Textbox"), "3" => xl("Textarea"), "4" => xl("Text-date"), "10" => xl("Providers"), "11" => xl("Providers NPI"), "12" => xl("Pharmacies"), "13" => xl("Squads"), "14" => xl("Organizations"), "15" => xl("Billing codes"), "16" => xl("Insurances"), "18" => xl("Visit Categories"), "21" => xl("Checkbox list"), "22" => xl("Textbox list"), "23" => xl("Exam results"), "24" => xl("Patient allergies"), "25" => xl("Checkbox w/text"), "26" => xl("List box w/add"), "27" => xl("Radio buttons"), "28" => xl("Lifestyle status"), "31" => xl("Static Text"), "32" => xl("Smoking Status"), "33" => xl("Race and Ethnicity"), "34" => xl("NationNotes"), "35" => xl("Facilities"), "36" => xl("Multiple Select List"), "40" => xl("Image canvas"), ); $sources = array( 'F' => xl('Form'), 'D' => xl('Patient'), 'H' => xl('History'), 'E' => xl('Visit'), 'V' => xl('VisForm'), ); function nextGroupOrder($order) { if ($order == '9') $order = 'A'; else if ($order == 'Z') $order = 'a'; else $order = chr(ord($order) + 1); return $order; } // Call this when adding or removing a layout field. This will create or drop // the corresponding table column when appropriate. Table columns are not // dropped if they contain any non-empty values. function addOrDeleteColumn($layout_id, $field_id, $add=TRUE) { if (substr($layout_id,0,3) == 'LBF' || substr($layout_id,0,3) == 'LBT' || $layout_id == "FACUSR") return; if ($layout_id == "DEM") $tablename = "patient_data"; else if ($layout_id == "HIS") $tablename = "history_data"; else if ($layout_id == "SRH") $tablename = "lists_ippf_srh"; else if ($layout_id == "CON") $tablename = "lists_ippf_con"; else if ($layout_id == "GCA") $tablename = "lists_ippf_gcac"; else die('Internal error in addOrDeleteColumn()'); // Check if the column currently exists. $tmp = sqlQuery("SHOW COLUMNS FROM `$tablename` LIKE '$field_id'"); $column_exists = !empty($tmp); if ($add && !$column_exists) { sqlStatement("ALTER TABLE `$tablename` ADD `$field_id` TEXT"); newEvent("alter_table", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$tablename ADD $field_id"); } else if (!$add && $column_exists) { // Do not drop a column that has any data. $tmp = sqlQuery("SELECT `$field_id` FROM `$tablename` WHERE " . "`$field_id` IS NOT NULL AND `$field_id` != '' LIMIT 1"); if (!isset($tmp['field_id'])) { sqlStatement("ALTER TABLE `$tablename` DROP `$field_id`"); newEvent("alter_table", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$tablename DROP $field_id "); } } } // Check authorization. $thisauth = acl_check('admin', 'super'); if (!$thisauth) die(xl('Not authorized')); // The layout ID identifies the layout to be edited. $layout_id = empty($_REQUEST['layout_id']) ? '' : $_REQUEST['layout_id']; // Tag style for stuff to hide if not an LBF layout. Currently just for the Source column. $lbfonly = substr($layout_id,0,3) == 'LBF' ? "" : "style='display:none;'"; // Handle the Form actions if ($_POST['formaction'] == "save" && $layout_id) { // If we are saving, then save. $fld = $_POST['fld']; for ($lino = 1; isset($fld[$lino]['id']); ++$lino) { $iter = $fld[$lino]; $field_id = formTrim($iter['id']); $data_type = formTrim($iter['data_type']); $listval = $data_type == 34 ? formTrim($iter['contextName']) : formTrim($iter['list_id']); // Skip conditions for the line are stored as a serialized array. $condarr = array(); for ($cix = 0; !empty($iter['condition_id'][$cix]); ++$cix) { $andor = empty($iter['condition_andor'][$cix]) ? '' : $iter['condition_andor'][$cix]; $condarr[$cix] = array( 'id' => strip_escape_custom($iter['condition_id' ][$cix]), 'itemid' => strip_escape_custom($iter['condition_itemid' ][$cix]), 'operator' => strip_escape_custom($iter['condition_operator'][$cix]), 'value' => strip_escape_custom($iter['condition_value' ][$cix]), 'andor' => strip_escape_custom($andor), ); } $conditions = empty($condarr) ? '' : serialize($condarr); if ($field_id) { sqlStatement("UPDATE layout_options SET " . "source = '" . formTrim($iter['source']) . "', " . "title = '" . formTrim($iter['title']) . "', " . "group_name = '" . formTrim($iter['group']) . "', " . "seq = '" . formTrim($iter['seq']) . "', " . "uor = '" . formTrim($iter['uor']) . "', " . "fld_length = '" . formTrim($iter['lengthWidth']) . "', " . "fld_rows = '" . formTrim($iter['lengthHeight']) . "', " . "max_length = '" . formTrim($iter['maxSize']) . "', " . "titlecols = '" . formTrim($iter['titlecols']) . "', " . "datacols = '" . formTrim($iter['datacols']) . "', " . "data_type= '$data_type', " . "list_id= '" . $listval . "', " . "list_backup_id= '" . formTrim($iter['list_backup_id']) . "', " . "edit_options = '" . formTrim($iter['edit_options']) . "', " . "default_value = '" . formTrim($iter['default']) . "', " . "description = '" . formTrim($iter['desc']) . "', " . "conditions = '" . add_escape_custom($conditions) . "', " . "validation = '" . formTrim($iter['validation']) . "' " . "WHERE form_id = '$layout_id' AND field_id = '$field_id'"); } } } else if ($_POST['formaction'] == "addfield" && $layout_id) { // Add a new field to a specific group $data_type = formTrim($_POST['newdatatype']); $max_length = $data_type == 3 ? 3 : 255; $listval = $data_type == 34 ? formTrim($_POST['contextName']) : formTrim($_POST['newlistid']); sqlStatement("INSERT INTO layout_options (" . " form_id, source, field_id, title, group_name, seq, uor, fld_length, fld_rows" . ", titlecols, datacols, data_type, edit_options, default_value, description" . ", max_length, list_id, list_backup_id " . ") VALUES ( " . "'" . formTrim($_POST['layout_id'] ) . "'" . ",'" . formTrim($_POST['newsource'] ) . "'" . ",'" . formTrim($_POST['newid'] ) . "'" . ",'" . formTrim($_POST['newtitle'] ) . "'" . ",'" . formTrim($_POST['newfieldgroupid']) . "'" . ",'" . formTrim($_POST['newseq'] ) . "'" . ",'" . formTrim($_POST['newuor'] ) . "'" . ",'" . formTrim($_POST['newlengthWidth'] ) . "'" . ",'" . formTrim($_POST['newlengthHeight'] ) . "'" . ",'" . formTrim($_POST['newtitlecols'] ) . "'" . ",'" . formTrim($_POST['newdatacols'] ) . "'" . ",'$data_type'" . ",'" . formTrim($_POST['newedit_options']) . "'" . ",'" . formTrim($_POST['newdefault'] ) . "'" . ",'" . formTrim($_POST['newdesc'] ) . "'" . ",'" . formTrim($_POST['newmaxSize']) . "'" . ",'" . $listval . "'" . ",'" . formTrim($_POST['newbackuplistid']) . "'" . " )"); addOrDeleteColumn($layout_id, formTrim($_POST['newid']), TRUE); } else if ($_POST['formaction'] == "movefields" && $layout_id) { // Move field(s) to a new group in the layout $sqlstmt = "UPDATE layout_options SET ". " group_name='". $_POST['targetgroup']."' ". " WHERE ". " form_id = '".$_POST['layout_id']."' ". " AND field_id IN ("; $comma = ""; foreach (explode(" ", $_POST['selectedfields']) as $onefield) { $sqlstmt .= $comma."'".$onefield."'"; $comma = ", "; } $sqlstmt .= ")"; //echo $sqlstmt; sqlStatement($sqlstmt); } else if ($_POST['formaction'] == "deletefields" && $layout_id) { // Delete a field from a specific group $sqlstmt = "DELETE FROM layout_options WHERE ". " form_id = '".$_POST['layout_id']."' ". " AND field_id IN ("; $comma = ""; foreach (explode(" ", $_POST['selectedfields']) as $onefield) { $sqlstmt .= $comma."'".$onefield."'"; $comma = ", "; } $sqlstmt .= ")"; sqlStatement($sqlstmt); foreach (explode(" ", $_POST['selectedfields']) as $onefield) { addOrDeleteColumn($layout_id, $onefield, FALSE); } } else if ($_POST['formaction'] == "addgroup" && $layout_id) { // all group names are prefixed with a number indicating their display order // this new group is prefixed with the net highest number given the // layout_id $results = sqlStatement("select distinct(group_name) as gname ". " from layout_options where ". " form_id = '".$_POST['layout_id']."'" ); $maxnum = '1'; while ($result = sqlFetchArray($results)) { $tmp = substr($result['gname'], 0, 1); if ($tmp >= $maxnum) $maxnum = nextGroupOrder($tmp); } $data_type = formTrim($_POST['gnewdatatype']); $max_length = $data_type == 3 ? 3 : 255; $listval = $data_type == 34 ? formTrim($_POST['gcontextName']) : formTrim($_POST['gnewlistid']); // add a new group to the layout, with the defined field sqlStatement("INSERT INTO layout_options (" . " form_id, source, field_id, title, group_name, seq, uor, fld_length, fld_rows" . ", titlecols, datacols, data_type, edit_options, default_value, description" . ", max_length, list_id, list_backup_id " . ") VALUES ( " . "'" . formTrim($_POST['layout_id'] ) . "'" . ",'" . formTrim($_POST['gnewsource'] ) . "'" . ",'" . formTrim($_POST['gnewid'] ) . "'" . ",'" . formTrim($_POST['gnewtitle'] ) . "'" . ",'" . formTrim($maxnum . $_POST['newgroupname']) . "'" . ",'" . formTrim($_POST['gnewseq'] ) . "'" . ",'" . formTrim($_POST['gnewuor'] ) . "'" . ",'" . formTrim($_POST['gnewlengthWidth'] ) . "'" . ",'" . formTrim($_POST['gnewlengthHeight'] ) . "'" . ",'" . formTrim($_POST['gnewtitlecols'] ) . "'" . ",'" . formTrim($_POST['gnewdatacols'] ) . "'" . ",'$data_type'" . ",'" . formTrim($_POST['gnewedit_options']) . "'" . ",'" . formTrim($_POST['gnewdefault'] ) . "'" . ",'" . formTrim($_POST['gnewdesc'] ) . "'" . ",'" . formTrim($_POST['gnewmaxSize']) . "'" . ",'" . $listval . "'" . ",'" . formTrim($_POST['gnewbackuplistid'] ) . "'" . " )"); addOrDeleteColumn($layout_id, formTrim($_POST['gnewid']), TRUE); } else if ($_POST['formaction'] == "deletegroup" && $layout_id) { // drop the fields from the related table (this is critical) $res = sqlStatement("SELECT field_id FROM layout_options WHERE " . "form_id = '" . $_POST['layout_id'] . "' ". "AND group_name = '" . $_POST['deletegroupname'] . "'"); while ($row = sqlFetchArray($res)) { addOrDeleteColumn($layout_id, $row['field_id'], FALSE); } // Delete an entire group from the form sqlStatement("DELETE FROM layout_options WHERE ". " form_id = '".$_POST['layout_id']."' ". " AND group_name = '".$_POST['deletegroupname']."'" ); } else if ($_POST['formaction'] == "movegroup" && $layout_id) { $results = sqlStatement("SELECT DISTINCT(group_name) AS gname " . "FROM layout_options WHERE form_id = '$layout_id' " . "ORDER BY gname"); $garray = array(); $i = 0; while ($result = sqlFetchArray($results)) { if ($result['gname'] == $_POST['movegroupname']) { if ($_POST['movedirection'] == 'up') { // moving up if ($i > 0) { $garray[$i] = $garray[$i - 1]; $garray[$i - 1] = $result['gname']; $i++; } else { $garray[$i++] = $result['gname']; } } else { // moving down $garray[$i++] = ''; $garray[$i++] = $result['gname']; } } else if ($i > 1 && $garray[$i - 2] == '') { $garray[$i - 2] = $result['gname']; } else { $garray[$i++] = $result['gname']; } } $nextord = '1'; foreach ($garray as $value) { if ($value === '') continue; $newname = $nextord . substr($value, 1); sqlStatement("UPDATE layout_options SET " . "group_name = '$newname' WHERE " . "form_id = '$layout_id' AND " . "group_name = '$value'"); $nextord = nextGroupOrder($nextord); } } else if ($_POST['formaction'] == "renamegroup" && $layout_id) { $currpos = substr($_POST['renameoldgroupname'], 0, 1); // update the database rows sqlStatement("UPDATE layout_options SET " . "group_name = '" . $currpos . $_POST['renamegroupname'] . "' ". "WHERE form_id = '$layout_id' AND ". "group_name = '" . $_POST['renameoldgroupname'] . "'"); } // Get the selected form's elements. if ($layout_id) { $res = sqlStatement("SELECT * FROM layout_options WHERE " . "form_id = '$layout_id' ORDER BY group_name, seq"); } // global counter for field numbers $fld_line_no = 0; $extra_html = ''; // This is called to generate a select option list for fields within this form. // Used for selecting a field for testing in a skip condition. // function genFieldOptionList($current='') { global $layout_id; $option_list = ""; if ($layout_id) { $query = "SELECT field_id FROM layout_options WHERE form_id = ? ORDER BY group_name, seq"; $res = sqlStatement($query, array($layout_id)); while ($row = sqlFetchArray($res)) { $field_id = $row['field_id']; $option_list .= "