PHP Warning: substr() expects parameter 1 to be string, array given in /var/www/openemr/library/classes/Installer.class.php on line 311, referer: http://openemr.example.com/setup.php?site=default
The fix:
Installer time array failure fix patch:
--- old/var/www/openemr/library/classes/Installer.class.php Tue Apr 02 02:47:00 2013
+++ new/var/www/openemr/library/classes/Installer.class.php Sun Apr 07 13:33:47 2013
@@ -308,7 +308,7 @@
foreach ($GLOBALS_METADATA as $grpname => $grparr) {
foreach ($grparr as $fldid => $fldarr) {
list($fldname, $fldtype, $flddef, $flddesc) = $fldarr;
- if (substr($fldtype, 0, 2) !== 'm_') {
+ if (is_array($fldtype) || substr($fldtype, 0, 2) !== 'm_') {
$res = $this->execute_sql("SELECT count(*) AS count FROM globals WHERE gl_name = '$fldid'");
$row = @mysql_fetch_array($res, MYSQL_ASSOC);
if (empty($row['count'])) {
Your fix makes sense, but can you describe how to reproduce this issue and what the actual problem is beside just a notice in the log?
if $fldtype is an array instead of a string as this code expects, that may be the sign of a deeper problem/bug.
Line 308 in library/classes/Installer.class.php refers to $GLOBALS_METADATA array
taken in the previous line from library/globals.inc.php.
It’s elements are arrays, one for each tab:
Appearance, Locale, Features, Documents, Calendar, Security,
Notifications, CDR, Logging, Miscellaneous, Portal, Connectors, Rx.
The following lists the arrays (of the Appearances tab array)
which can have the $fldtype (subscript [1]) as an array as well.
Only in the first such array, the $fldtype has non numeric subscripts for itself.
When the $fldtype is an array it is a select box with choices as the elements.
The subscript[2] is the default choice / value.
The subscript[3] is a tool tip / help or info header for the select box.
Line 316 of library/classes/Installer.class.php hardcodes the index of the default entry as 0
and prevents other elements of the same array from being populated.
Therefore my patch is valid without any effect of the $fldtype being an array.
Array
(
[default_top_pane] => Array
(
[0] => Main Top Pane Screen
[1] => Array
(
[main_info.php] => Calendar Screen
[../new/new.php] => Patient Search/Add Screen
)
[2] => main_info.php
[3] => Type of screen layout
)
[concurrent_layout] => Array
(
[0] => Layout Style
[1] => Array
(
[0] => Old style layout with no left menu
[1] => Navigation menu consists of pairs of radio buttons
[2] => Navigation menu is a tree view
[3] => Navigation uses a sliding menu
)
[2] => 3
[3] => Type of screen layout
)
[css_header] => Array
(
[0] => Theme
[1] => css
[2] => style_oemr.css
[3] => Pick a CSS theme.
)
[gbl_nav_area_width] => Array
(
[0] => Navigation Area Width
[1] => num
[2] => 150
[3] => Width in pixels of the left navigation frame.
)
[openemr_name] => Array
(
[0] => Application Title
[1] => text
[2] => OpenEMR
[3] => Application name for login page and main window title.
)
[full_new_patient_form] => Array
(
[0] => New Patient Form
[1] => Array
(
[0] => Old-style static form without search or duplication check
[1] => All demographics fields, with search and duplication check
[2] => Mandatory or specified fields only, search and dup check
[3] => Mandatory or specified fields only, dup check, no search
)
[2] => 1
[3] => Style of form used for adding new patients
)
[patient_search_results_style] => Array
(
[0] => Patient Search Results Style
[1] => Array
(
[0] => Encounter statistics
[1] => Mandatory and specified fields
)
[2] => 0
[3] => Type of columns displayed for patient search results
)
[gbl_tall_nav_area] => Array
(
[0] => Tall Navigation Area
[1] => bool
[2] => 0
[3] => Navigation area uses full height of frameset
)
[gbl_nav_visit_forms] => Array
(
[0] => Navigation Area Visit Forms
[1] => bool
[2] => 1
[3] => Navigation area includes encounter forms
)
[simplified_demographics] => Array
(
[0] => Simplified Demographics
[1] => bool
[2] => 0
[3] => Omit insurance and some other things from the demographics form
)
[simplified_prescriptions] => Array
(
[0] => Simplified Prescriptions
[1] => bool
[2] => 0
[3] => Omit form, route and interval which then become part of dosage
)
[simplified_copay] => Array
(
[0] => Simplified Co-Pay
[1] => bool
[2] => 0
[3] => Omit method of payment from the co-pay panel
)
[use_charges_panel] => Array
(
[0] => Use Charges Panel
[1] => bool
[2] => 0
[3] => Enables the old Charges panel for entering billing codes and payments. Not recommended, use the Fee Sheet instead.
)
[enable_fees_in_left_menu] => Array
(
[0] => Enable Fees In Left Menu
[1] => bool
[2] => 1
[3] => Enable Fees In Left Menu
)
[enable_edihistory_in_left_menu] => Array
(
[0] => Enable EDI History In Left Menu
[1] => bool
[2] => 1
[3] => EDI History (under Fees) for storing and interpreting EDI claim response files
)
[online_support_link] => Array
(
[0] => Online Support Link
[1] => text
[2] => http://open-emr.org/
[3] => URL for OpenEMR support.
)
[encounter_page_size] => Array
(
[0] => Encounter Page Size
[1] => Array
(
[0] => Show All
[5] => 5
[10] => 10
[15] => 15
[20] => 20
[25] => 25
[50] => 50
)
[2] => 20
[3] => Number of encounters to display per page.
)
[gbl_pt_list_page_size] => Array
(
[0] => Patient List Page Size
[1] => Array
(
[10] => 10
[25] => 25
[50] => 50
[100] => 100
)
[2] => 10
[3] => Number of patients to display per page in the patient list.
)
[gbl_pt_list_new_window] => Array
(
[0] => Patient List New Window
[1] => bool
[2] => 0
[3] => Default state of New Window checkbox in the patient list.
)
[gbl_vitals_options] => Array
(
[0] => Vitals Form Options
[1] => Array
(
[0] => Standard
[1] => Omit circumferences
)
[2] => 0
[3] => Special treatment for the Vitals form
)
)
It looks like the only global variable that uses this “m_” convention is
'language_menu_other' => array(
xl('Allowed Languages'),
'm_lang', // data type
'', // default = none
xl('Select which languages, if any, may be chosen at login. (only pertinent if above All Languages Allowed is turned off)')
),
I am wondering whether that if clause should even be there at all.
Brady is more familiar with the installer code than I am, perhaps he could chime in.
Hi,
Guessing that having the language_menu_other token in the globals table will break things on the login screen if no langauges are selected. So, Rod likely placed code to skip it, so the token isn’t placed into the globals table (note this token holds languages (numbered via the gl_index column) if want to limit offered languages to a set of languages; when none are chosen, then all languages will be offered on the login screen).
-brady OpenEMR
Hi,
I pushed this code to the official codebase. Note that it probably makes sense to fix this in the sql_upgrade.php and sql_patch.php scripts also.
Thank you for the contribution,
-brady OpenEMR