function getSearchFieldLabelsAndHTML()
{
    global $schema, $tableName;
    $searchFieldLabelsAndHtml = array();
    // display search fields
    $searchRows = _parseSearchFieldsFormat($schema['listPageSearchFields']);
    foreach ($searchRows as $searchRow) {
        list($label, $fieldnames, $displayAs, $searchFieldSuffix) = $searchRow;
        $isMulti = false;
        if (count($fieldnames) === 1 && preg_match('/^\\w+\\[\\]$/', $fieldnames[0])) {
            $fieldnames[0] = trim(@$fieldnames[0], '[]');
            $isMulti = true;
        }
        $fieldsAsCSV = join(',', $fieldnames);
        $name = "{$fieldsAsCSV}_{$searchFieldSuffix}";
        $lastValue = @$_REQUEST[$name];
        // get fieldschema for single field searches:
        $fieldSchema = @$schema[$fieldnames[0]];
        if ($fieldSchema) {
            $fieldSchema['name'] = $fieldnames[0];
        }
        // special case: add createdBy.fieldname search functionality
        if (preg_match("/^createdBy\\.(.*?)\$/i", $fieldsAsCSV, $matches)) {
            $name = 'createdByUserNum_match';
            $labelField = $matches[1];
            $lastValue = @$_REQUEST[$name];
            $displayAs = 'dropdown';
            $fieldSchema = array('name' => '_not_used_', 'optionsType' => 'table', 'optionsTablename' => 'accounts', 'optionsValueField' => 'num', 'optionsLabelField' => $matches[1]);
            // list all users who have records in this section
            $fieldSchema = array('name' => '_not_used_', 'optionsType' => 'query', 'optionsQuery' => "SELECT a.num, a.`{$labelField}`\n                                  FROM {$GLOBALS['TABLE_PREFIX']}accounts a\n                                  JOIN `{$GLOBALS['TABLE_PREFIX']}{$tableName}` f ON a.num = f.createdByUserNum\n                              ORDER BY a.`{$labelField}`");
            /*
              // list all users who have access to create records in this section
              $fieldSchema = array(
                'name'              => '_not_used_',
                'optionsType'       => 'query',
                'optionsQuery'      => "SELECT a.num, a.`$labelField`
                                          FROM {$GLOBALS['TABLE_PREFIX']}accounts a
                                          JOIN `{$GLOBALS['TABLE_PREFIX']}_accesslist` al ON a.num = al.userNum
                                         WHERE al.accessLevel > 1 AND al.tableName IN ('all','$tableName')
                                      ORDER BY a.`$labelField`",
              );
            */
        }
        // generate html
        $html = '';
        if ($displayAs == 'textfield') {
            $html .= "<input class='text-input' type='text' name='{$name}' value='" . htmlencode($lastValue) . "' size='30' />";
        } else {
            if ($displayAs == 'checkbox') {
                $checkedValue = getFirstDefinedValue(@$fieldSchema['checkedValue'], t('Checked'));
                $uncheckedValue = getFirstDefinedValue(@$fieldSchema['uncheckedValue'], t('Unchecked'));
                $optionValues = array('1', '0');
                $optionLabels = array($checkedValue, $uncheckedValue);
                $optionsHTML = getSelectOptions($lastValue, $optionValues, $optionLabels, false);
                $html .= "<select name='{$name}'>";
                $html .= "<option value=''>" . htmlencode(t("<any>")) . "</option>\n";
                $html .= $optionsHTML;
                $html .= "</select>";
            } else {
                if ($displayAs == 'dropdown') {
                    $optionsHTML = getSelectOptionsFromSchema($lastValue, $fieldSchema, false);
                    if ($isMulti) {
                        $html .= "<select name='{$name}[]' multiple>";
                    } else {
                        $html .= "<select name='{$name}'>";
                    }
                    $html .= "<option value=''>" . htmlencode(t("<any>")) . "</option>\n";
                    $html .= $optionsHTML;
                    $html .= "</select>";
                } else {
                    if ($displayAs == 'custom') {
                        $functionName = $searchFieldSuffix;
                        if (!function_exists($functionName)) {
                            die("Search function '" . htmlencode($functionName) . "' doesn't exist!<br/>Check: Admin &gt; Section Editors &gt; Search &gt; Search Fields");
                        }
                        $html .= call_user_func($functionName);
                        if (!$html) {
                            continue;
                        }
                        // return nothing from function to not display search field
                    } else {
                        die("Unknown search field type '" . htmlencode($displayAs) . "'!");
                    }
                }
            }
        }
        // add instructions for date search fields
        if (@$fieldSchema['type'] == 'date' && count($fieldnames) == 1) {
            $html .= ' &nbsp; ';
            $html .= t('Format:');
            $html .= ' YYYY-MM-DD ';
            if (@$fieldSchema['showTime']) {
                $html .= ' HH:MM:SS ';
            }
            // custom datepicker code - this is only called is jqueryUI datepicker is loaded
            $jsDateFormat = @$fieldSchema['showTime'] ? "yy-mm-dd 00:00:00" : "yy-mm-dd";
            $buttonImageUrl = CMS_ASSETS_URL . "/3rdParty/jqueryUI/calendar.gif";
            $html .= <<<__HTML__
        <script type='text/javascript'><!--
          \$(function() {
            if (\$.datepicker != undefined) {
              \$('[name={$name}]').datepicker({  // this is from: lib/menus/default/list_functions.php
                showOn: 'button',
                //buttonImage: '<?php echo CMS_ASSETS_URL ?>/3rdParty/jqueryUI/calendar.gif',
                buttonImage: '{$buttonImageUrl}',
                buttonImageOnly: true,
                dateFormat: '{$jsDateFormat}'
              });
            }
          });
        //--></script>
__HTML__;
        }
        //
        $searchFieldLabelsAndHtml[] = array($label, $html);
    }
    //
    return $searchFieldLabelsAndHtml;
}
function getRecords($options)
{
    $originalOptions = $options;
    //Save original options in case we need them later.
    global $VIEWER_NAME, $TABLE_PREFIX, $SETTINGS;
    $VIEWER_NAME = "getRecords(" . @$options['tableName'] . ")";
    // error checking
    _getRecords_errorChecking($options);
    // load schema
    $schema = loadSchema($options['tableName']);
    if (!$schema) {
        die("{$VIEWER_NAME}: Couldn't load schema for '" . htmlencode($options['tableName']) . "'!");
    }
    // set defaults
    if (!array_key_exists('orderBy', $options)) {
        $options['orderBy'] = getFirstDefinedValue(_getOrderByFromUrl($schema), $schema['listPageOrder']);
    }
    if (!array_key_exists('loadUploads', $options)) {
        $options['loadUploads'] = true;
    }
    if (!array_key_exists('allowSearch', $options)) {
        $options['allowSearch'] = true;
    }
    if (!array_key_exists('requireSearchMatch', $options)) {
        $options['requireSearchMatch'] = false;
    }
    if (!array_key_exists('loadCreatedBy', $options)) {
        $options['loadCreatedBy'] = true;
    }
    if (!array_key_exists('loadListDetails', $options)) {
        $options['loadListDetails'] = true;
    }
    if (!array_key_exists('loadPseudoFields', $options)) {
        $options['loadPseudoFields'] = true;
    }
    $options['perPage'] = intval(@$options['perPage']);
    $options['pageNum'] = intval(@$options['pageNum']) ? max(intval($options['pageNum']), 1) : max(intval(@$_REQUEST['page']), 1);
    $options['limit'] = intval(@$options['perPage']) ? intval($options['perPage']) : intval(@$options['limit']);
    $options['offset'] = intval(@$options['perPage']) ? ($options['pageNum'] - 1) * $options['perPage'] + @$options['offset'] : @$options['offset'];
    $options['offset'] = min($options['offset'], PHP_INT_MAX);
    // don't overflow php integers when casting to int later (can cause negative numbers which is harmless but causes mysql error)
    if ($options['offset'] && !$options['limit']) {
        $options['limit'] = 1000000;
    }
    // if offset and no limit set limit to high number as per MySQL docs
    // special behaviour if a "preview" is requested
    $isSingleMenuWithBlankWhere = !empty($schema['menuType']) && $schema['menuType'] == 'single' && @$options['where'] == '';
    // single record sections have blank where statements when generated by code generator
    $hasWhereWithPreviewNum = @$options['where'] == "num = '9999999999'";
    // and regular detail viewers have: //  'where'       => whereRecordNumberInUrl(0),
    if (@$_REQUEST['preview:menu'] == @$options['tableName'] && ($isSingleMenuWithBlankWhere || $hasWhereWithPreviewNum)) {
        // checking for 999... prevent an inifine loop
        return _getRecords_preview($schema, $options);
    }
    // get query
    $query = _getRecords_getQuery($options, $schema);
    // load from cache
    if (@$options['useCache']) {
        if (!function_exists('turboCache_load')) {
            die("Error: 'useCaching' enabled but no caching plugin found!<br/>Either disable 'useCaching' or install caching plugin.");
        }
        $results = turboCache_load($options['tableName'], $query);
        if ($results) {
            list($rows, $listDetails, $schema) = $results;
            $listDetails['fromCache'] = 1;
            return array($rows, $listDetails, $schema);
        }
    }
    // Get records
    list($rows, $totalRecords) = _getRecords_loadResults($query, $options, $schema);
    // Add _tableName key
    foreach ($rows as $key => $record) {
        $rows[$key]['_tableName'] = $options['tableName'];
    }
    // Add pseudo-fields
    if (@$options['loadPseudoFields']) {
        _getRecords_addPseudoFields($rows, $options, $schema);
    }
    // Add uploads
    if (@$options['loadUploads']) {
        _getRecords_addUploadFields($rows, $options, $schema);
    }
    // Add createdBy.fields to records
    // // v2.50 set fields for alternate accounts table, eg: otherTable.username
    if (@$options['loadCreatedBy'] && @$schema['createdByUserNum']) {
        $accountsTables = array_filter(array_unique(array('accounts', @$GLOBALS['WSM_ACCOUNTS_TABLE'])));
        foreach ($accountsTables as $accountsTable) {
            _getRecords_joinTable($rows, $options, $accountsTable);
        }
    }
    // Add joinTable fields
    if (@$options['joinTable']) {
        _getRecords_joinTable($rows, $options);
    }
    // get List Details
    $listDetails = array();
    if ($options['loadListDetails']) {
        $listDetails = _getRecords_getListDetails($options, count($rows), $totalRecords, $schema);
    }
    // See if pagenum is too high.  If so, call getRecords() again with an in-bounds page num
    if ($listDetails && $options['pageNum'] > $listDetails['totalPages']) {
        $originalOptions['pageNum'] = $listDetails['totalPages'];
        return getRecords($originalOptions);
    }
    // save to cache
    if (@$options['useCache']) {
        turboCache_save($options['tableName'], $query, array($rows, $listDetails, $schema));
    }
    //
    $rows = applyFilters('viewer_output_rows', $rows, $listDetails, $schema);
    //
    return array($rows, $listDetails, $schema);
}
_init_showServerRequirementsErrors();
_init_fixPhpConfig();
// call this _before_ anything else so we have reliable php values
_init_loadSettings();
// sets $SETTINGS global
_init_fixPreviewDnsDomains();
// security: hide PHP errors if requested
if ($GLOBALS['SETTINGS']['advanced']['phpHideErrors']) {
    ini_set('display_errors', '0');
    ini_set('display_startup_errors', '0');
}
// set globals
global $SETTINGS, $TABLE_PREFIX, $PROGRAM_DIR, $APP;
$_REQUEST = _init_createRequestGlobal();
// call AFTER _init_fixPhpConfig(): uses fixed PATH_INFO _and_ undo_magic_quotes
$TABLE_PREFIX = getFirstDefinedValue(@$SETTINGS["mysql:{$_SERVER['HTTP_HOST']}"]['tablePrefix'], $SETTINGS['mysql']['tablePrefix']);
$PROGRAM_DIR = SCRIPT_DIR;
$APP = array('version' => '2.65', 'build' => '1122', 'id' => '19', 'key' => '35809', 'alerts' => @$GLOBALS['APP']['alerts']);
define('PREFIX_URL', $SETTINGS['webPrefixUrl']);
// v2.53
define('CMS_ASSETS_URL', parse_url(dirname($SETTINGS['adminUrl']), PHP_URL_PATH));
// for more complicated path references: parse_url( realUrl('../cms-assets', $SETTINGS['adminUrl']), PHP_URL_PATH));
$GLOBALS['CMS_ASSETS_URL'] = CMS_ASSETS_URL;
// set timezone
_init_setTimezone();
// check for internet connectivity
if (!isInstalled()) {
    _init_showInternetConnectivityErrors();
}
// only run if software not installed yet
// connect to mysql
function _getMenuList()
{
    global $APP, $CURRENT_USER;
    $menus = array();
    $selectedMenu = getFirstDefinedValue(@$APP['selectedMenu'], @$_REQUEST['menu'], 'home');
    $menuOrder = 0;
    // get schema files
    foreach (getSchemaTables() as $tableName) {
        $schema = loadSchema($tableName);
        if (!@$schema['menuType']) {
            continue;
        }
        if (@$schema['menuHidden']) {
            continue;
        }
        $menuOrder = max($menuOrder, @$schema['menuOrder']);
        // add menu items
        $thisMenu = array();
        $thisMenu['schema'] = $schema;
        $thisMenu['menuType'] = $schema['menuType'];
        $thisMenu['menuName'] = $schema['menuName'];
        $thisMenu['menuOrder'] = $schema['menuOrder'];
        $thisMenu['tableName'] = $tableName;
        $thisMenu['isSelected'] = $selectedMenu == $tableName;
        $thisMenu['_indent'] = @$schema['_indent'];
        $thisMenu['_disableView'] = @$schema['_disableView'];
        $thisMenu['link'] = "?menu={$tableName}";
        $thisMenu['linkTarget'] = '';
        $thisMenu['linkMessage'] = '';
        if ($schema['menuType'] == 'link') {
            $isExternalLink = @$schema['_linkTarget'] != 'iframe';
            $setTargetBlank = $isExternalLink && (@$schema['_targetBlank'] || @$schema['_linkTarget'] == 'new');
            // _targetBlank is the old schema format
            if ($isExternalLink) {
                $thisMenu['link'] = $schema['_url'];
            }
            if ($setTargetBlank) {
                $thisMenu['linkTarget'] = 'target="_blank"';
            }
            if ($isExternalLink) {
                $thisMenu['linkMessage'] = @$schema['_linkMessage'];
            }
            // don't show js alert() for iframe links (show them at top of iframe page)
        }
        array_push($menus, $thisMenu);
    }
    // add admin menus
    $showAdminAtTop = false;
    if ($showAdminAtTop) {
        $menuOrder = -100;
    }
    $menus = array_merge($menus, _getAdminMenus($menuOrder));
    // sort menus by order value
    uasort($menus, '_sortMenusByOrder');
    $menus = array_values($menus);
    // re-index elements to match sort order (for operation below)
    // allow plugins to customize the menu while it's still an easily managable array
    $menus = applyFilters('menulinks_array', $menus);
    // set isSelected for menuGroups
    $groupChildSelected = false;
    for ($index = count($menus) - 1; $index >= 0; $index--) {
        $menu =& $menus[$index];
        if ($menu['menuType'] == 'menugroup') {
            if ($groupChildSelected) {
                $menu['isSelected'] = true;
                $groupChildSelected = false;
            }
        } else {
            if ($menu['isSelected']) {
                $groupChildSelected = true;
            }
        }
        unset($menu);
    }
    //
    return $menus;
}
function register()
{
    global $SETTINGS, $APP;
    # NOTE: Disabling or modifying licensing or registration code violates your license agreement and is willful copyright infringement.
    # NOTE: Copyright infringement can be very expensive: http://en.wikipedia.org/wiki/Statutory_damages_for_copyright_infringement
    # NOTE: Please do not steal our software.
    // get filepath
    $caller = array_pop(@debug_backtrace());
    $filepath = realpath($caller['file']);
    ### Build registration query
    $hostname = getFirstDefinedValue($_SERVER["HTTP_HOST"], $_SERVER["SERVER_NAME"], @$_SERVER["SERVER_ADDR"]);
    $url = $_SERVER["SCRIPT_NAME"];
    $reginfo = 'reg1=' . urlencode($SETTINGS['licenseCompanyName']);
    # Company Name
    $reginfo .= '&reg2=' . urlencode($SETTINGS['licenseDomainName']);
    # Domain Name
    $reginfo .= '&lnum=' . isValidProductId($SETTINGS['licenseProductId']);
    # License Number
    $reginfo .= '&prog=' . $APP['id'];
    # Program Id
    $reginfo .= '&ver=' . $APP['version'];
    # Program Version
    $reginfo .= '&url=' . urlencode("{$hostname}{$url}");
    # script url
    $reginfo .= '&filepath=' . urlencode($filepath);
    # script filepath
    # get license status
    list($response, $statusCode) = getPage("http://www.registerSoftware.to/register/register.cgi?{$reginfo}");
    if (preg_match('/license.invalid/', $response)) {
        $isDisabled = 1;
    } else {
        if (preg_match('/license.valid/', $response)) {
            $isDisabled = 0;
        } else {
            $isDisabled = $SETTINGS['isDisabled'];
        }
    }
    # on unrecognized response do nothing
    # save settings
    $SETTINGS['installPath'] = _getInstallPath();
    $SETTINGS['isDisabled'] = $isDisabled;
    $SETTINGS['dateRegistered'] = time();
    saveSettings();
    //
    return !$isDisabled;
}
function connectToMySQL($returnErrors = false)
{
    global $SETTINGS, $DBH;
    ### Get connection details
    $hostname = getFirstDefinedValue(@$SETTINGS["mysql:{$_SERVER['HTTP_HOST']}"]['hostname'], $SETTINGS['mysql']['hostname']);
    $username = getFirstDefinedValue(@$SETTINGS["mysql:{$_SERVER['HTTP_HOST']}"]['username'], $SETTINGS['mysql']['username']);
    $password = getFirstDefinedValue(@$SETTINGS["mysql:{$_SERVER['HTTP_HOST']}"]['password'], $SETTINGS['mysql']['password']);
    $database = getFirstDefinedValue(@$SETTINGS["mysql:{$_SERVER['HTTP_HOST']}"]['database'], $SETTINGS['mysql']['database']);
    $textOnlyErrors = coalesce(inCLI(), @$SETTINGS["mysql:{$_SERVER['HTTP_HOST']}"]['textOnlyErrors'], $SETTINGS['mysql']['textOnlyErrors']);
    ##  SLOW REMOTE CONNECTION
    ##  If you are connecting to a remote database that is intolerably slow, try
    ##  updating the mysql configuration file (often "/etc/my.cfg") by adding the
    ##  following option to the [mysqld] section:
    ##
    ##     skip-name-resolve
    ##
    ##  Here is the MySQL documentation for this option:
    ##
    ##    --skip-name-resolve
    ##    Do not resolve host names when checking client connections. Use only IP addresses.
    ##    If you use this option, all Host column values in the grant tables must be IP addresses or localhost.
    ### Connect to database
    $DBH = @mysql_connect($hostname, $username, $password);
    if (!$DBH) {
        $connectionError = mysql_error();
        if ($returnErrors) {
            return "Error connecting to MySQL:<br/>\n{$connectionError}";
        } elseif ($textOnlyErrors) {
            die("Error connecting to MySQL: {$connectionError}");
        } else {
            $libDir = pathinfo(__FILE__, PATHINFO_DIRNAME);
            // viewers may be in different dirs
            include "{$libDir}/menus/dbConnectionError.php";
        }
        exit;
    }
    // select db
    $isDbSelected = mysql_select_db($database);
    if (!$isDbSelected) {
        mysql_query("CREATE DATABASE `{$database}`") or die("MySQL Error: " . mysql_error() . "\n");
        mysql_select_db($database) or die("MySQL Error: " . mysql_error() . "\n");
    }
    ### check for required mysql version
    $currentVersion = preg_replace("/[^0-9\\.]/", '', mysql_get_server_info());
    if (version_compare(REQUIRED_MYSQL_VERSION, $currentVersion, '>')) {
        $error = "This program requires MySQL v" . REQUIRED_MYSQL_VERSION . " or newer. This server has v{$currentVersion} installed.<br/>\n";
        $error .= "Please ask your server administrator to install MySQL v" . REQUIRED_MYSQL_VERSION . " or newer.<br/>\n";
        if ($returnErrors) {
            return $error;
        }
        die($error);
    }
    ### Set Character Set
    # note: set through PHP 'set_charset' function so mysql_real_escape string() knows what charset to use. setting the charset
    # ... through mysql queries with 'set names' didn't cause mysql_client_encoding() to return a different value
    mysql_set_charset("utf8") or die("Error loading character set utf8: " . mysql_error() . '');
    # set MySQL strict mode - http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html
    mysqlStrictMode(true);
    # set MySQL timezone offset
    setMySqlTimezone();
    //
    return '';
}