function cg2_header($function, $name)
{
    // only send header once - v2.51
    static $alreadySent = false;
    if ($alreadySent) {
        return;
    }
    $alreadySent = true;
    // set title and button
    $title = sprintf("%s &gt; <a href='?menu=_codeGenerator'>%s</a> &gt; ", t('Admin'), t('Code Generator')) . htmlencode($name);
    $button = '';
    // <input class="button" type="button" name="null" value="Start Over &gt;&gt;" onclick="window.location=\'?menu=_codeGenerator\'"/>';
    // get header html
    $html = plugin_header('###TITLE###', $button, false);
    $html = preg_replace('/###TITLE###/', $title, $html);
    $html = preg_replace('/<form method="post"/', '<form method="get"', $html);
    // use get form so users can use browser back button with reposting form
    // add javascript (not yet needed or used)
    $oldHtml = $html;
    $jsPath = "lib/menus/_codeGenerator/generator_functions.js";
    $jsTag = "<script type='text/javascript' src='{$jsPath}?" . filemtime(SCRIPT_DIR . "/{$jsPath}") . "'></script>\n";
    // on file change browsers should no longer use cached versions
    $html = preg_replace("|^\\s*<!-- /javascript -->|m", "{$jsTag}\$0", $oldHtml);
    if ($oldHtml == $html) {
        dieAsCaller("Could insert javascript tag!");
    }
    // add hidden fields
    $html .= "<input type='hidden' name='menu' value='_codeGenerator' />\n";
    $html .= "<input type='hidden' name='_generator' value='{$function}' />\n";
    //
    return $html;
}
function userHasFieldAccess($fieldSchema)
{
    // args changed as of 2.16, used to be ($tableName, $accessRule) {
    global $CURRENT_USER;
    if (!array_key_exists('_tableName', $fieldSchema)) {
        dieAsCaller("Fieldschema missing '_tableName' value!");
    }
    if (!array_key_exists('name', $fieldSchema)) {
        dieAsCaller("Fieldschema missing 'name' value!");
    }
    // check if user has access to this field
    $hasAccess = false;
    $accessRule = @$fieldSchema['adminOnly'];
    // this schema key is a legacy fieldname that will be renamed in future
    $hasEditorAccess = userSectionAccess($fieldSchema['_tableName']) >= 9;
    if ($CURRENT_USER['isAdmin']) {
        $hasAccess = true;
    } elseif (!$accessRule) {
        $hasAccess = true;
    } elseif ($accessRule == 1 && $hasEditorAccess) {
        $hasAccess = true;
    } elseif ($accessRule == 2 && $CURRENT_USER['isAdmin']) {
        $hasAccess = true;
    }
    // requires admin access (ignored since admins can access all fields)
    $hasAccess = applyFilters('userHasFieldAccess', $hasAccess, $fieldSchema);
    return $hasAccess;
}
function mysql_insert($tableName, $colsToValues, $tempDisableMysqlStrictMode = false)
{
    //
    $tableName = getTableNameWithPrefix($tableName);
    $set = mysql_getMysqlSetValues($colsToValues);
    $insert = "INSERT INTO `{$tableName}` SET {$set}";
    //
    if ($tempDisableMysqlStrictMode) {
        mysqlStrictMode(false);
    }
    mysql_query($insert) or dieAsCaller("MySQL Error: " . mysql_error() . "\n");
    $recordNum = mysql_insert_id();
    if ($tempDisableMysqlStrictMode) {
        mysqlStrictMode(true);
    }
    return $recordNum;
}
function _dieAsCaller_onUnsupportedBooleanNot($ruleName, $booleanNot, $rulesString)
{
    if ($booleanNot) {
        $error = sprintf(t("%1\$s doesn't support boolean not (!) in rule string '%2\$s'."), $ruleName, $rulesString);
        dieAsCaller($error, 2);
    }
}
function pluginAction_addHandler($functionName, $requiredAccess = 'admins')
{
    if (!function_exists($functionName)) {
        die(__FUNCTION__ . ": Can't add plugin action handler, function '" . htmlencode($functionName) . "' doesn't exist!");
    }
    if (strtolower(@$_REQUEST['_pluginAction']) != strtolower($functionName)) {
        return;
    }
    // only run when plugin action is being called
    // error checking
    $validAccessTypes = array('admins', 'users', 'all');
    if (!in_array($requiredAccess, $validAccessTypes)) {
        $typesAsCSV = join(', ', $validAccessTypes);
        dieAsCaller(__FUNCTION__ . ": invalid 2nd argument for 'required access' must be one of ({$typesAsCSV}).  Please update your code!");
    }
    // default to showing plugin menu as highlighted - developers can change this in their function call
    $_REQUEST['menu'] = 'admin';
    $_REQUEST['action'] = 'plugins';
    // call function (we use a wrapper function so we can do this after user login when $CURRENT_USER is defined, otherwise we'd just add a handler for $functionName directly)
    $GLOBALS['PLUGIN_ACTION_FUNCTION_NAME'] = $functionName;
    $GLOBALS['PLUGIN_ACTION_REQUIRED_ACCESS'] = $requiredAccess;
    function _pluginAction_runHandler()
    {
        if ($GLOBALS['PLUGIN_ACTION_REQUIRED_ACCESS'] == 'admins' && !$GLOBALS['CURRENT_USER']['isAdmin']) {
            die("This action requires administrator access.");
        }
        if ($GLOBALS['PLUGIN_ACTION_REQUIRED_ACCESS'] == 'users' && !$GLOBALS['CURRENT_USER']) {
            die("This action you to be logged in.");
        }
        call_user_func($GLOBALS['PLUGIN_ACTION_FUNCTION_NAME']);
    }
    //
    if (defined('IS_CMS_ADMIN')) {
        $hookName = 'admin_postlogin';
    } else {
        $hookName = 'viewer_postinit';
    }
    // called after website membership runs, so $CURRENT_USER is defined and we can check access
    addAction($hookName, '_pluginAction_runHandler', 999, 0);
    // Set priority to 999 so this runs after all other plugins (such as website membership which defines $CURRENT_USER)
}
function cronExpression_getValidValuesForField($type, $expr)
{
    ### Get min/max values for each time increment
    if ($type == 'minute') {
        list($min, $max) = array(0, 59);
    } elseif ($type == 'hour') {
        list($min, $max) = array(0, 23);
    } elseif ($type == 'dayOfMonth') {
        list($min, $max) = array(1, 31);
    } elseif ($type == 'month') {
        list($min, $max) = array(1, 12);
    } elseif ($type == 'dayOfWeek') {
        list($min, $max) = array(0, 6);
    } else {
        dieAsCaller("Unknown time increment '{$type}'");
    }
    ### Get valid values for time increment expression
    if ($expr == '*') {
        return range($min, $max);
    }
    // * allows any value
    if (preg_match("/^\\d+\$/", $expr)) {
        return array(intval($expr));
    }
    // # a specific number
    if (preg_match("/^(\\d+\\,?)+\$/", $expr)) {
        return explode(',', $expr);
    }
    // #,#,# a list of value numbers
    if (preg_match("/^(\\d+)-(\\d+)\$/", $expr, $matches)) {
        // #-# a range of numbers
        return range($matches[1], $matches[2]);
    }
    // on error return empty array
    return array();
}
function disableAutocomplete($arg1 = '', $force = false)
{
    // skip if disabled by Admin Settings (meaning autocomplete is ENABLED now)
    if (!$force && !$GLOBALS['SETTINGS']['advanced']['disableAutocomplete']) {
        return '';
    }
    //
    $html = '';
    if ($arg1 == '') {
        return "autocomplete='off'";
    } elseif ($arg1 == 'form-headers') {
        $html .= "\n<!-- Attempt to disable autocomplete for browsers that ignore HTML5 autocomplete standard -->";
        $html .= "<input type='password' style='display:none'/>";
        // originally from: http://crbug.com/352347#c11
        $html .= "<input type='password' style='display:none'/>";
        // 3 password fields seems to prevent built in password functionality from activating (in Chrome)
        $html .= "<input type='password' style='display:none'/>";
        $html .= "\n";
    } else {
        dieAsCaller(__FUNCTION__ . ": Unknown argument '" . htmlencode($arg1) . "'!");
    }
    echo $html;
}
function getUploadPathPreview($dirOrUrl, $inputValue, $isCustomField, $forAjax = false)
{
    //
    $output = '';
    $fakeFieldSchema = array();
    // create fake field schema (only used for calculating custom upload field paths)
    if ($dirOrUrl == 'dir') {
        $settingsUploadDir = $inputValue;
        if ($isCustomField) {
            $settingsUploadDir = null;
            // use defaults so custom fields will be relative to that
            $fakeFieldSchema = array('useCustomUploadDir' => 1, 'customUploadDir' => $inputValue, 'customUploadUrl' => '');
        }
        list($absoluteDir, $absoluteUrl) = getUploadDirAndUrl($fakeFieldSchema, $settingsUploadDir, null, true);
        $output = $absoluteDir;
        if (!is_dir($absoluteDir)) {
            $output .= " (" . t("not found! check dir exists") . ")";
        }
    } elseif ($dirOrUrl == 'url') {
        $settingsUploadUrl = $inputValue;
        if ($isCustomField) {
            $settingsUploadUrl = null;
            // use defaults so custom fields will be relative to that
            $fakeFieldSchema = array('useCustomUploadDir' => 1, 'customUploadDir' => '', 'customUploadUrl' => $inputValue);
        }
        list($absoluteDir, $absoluteUrl) = getUploadDirAndUrl($fakeFieldSchema, null, $settingsUploadUrl, true);
        $output = $absoluteUrl;
    } else {
        dieAsCaller("Invalid value for \$dirOrUrl '" . htmlencode($dirOrUrl) . "'!");
    }
    //
    if ($forAjax) {
        die($output);
    }
    return $output;
}