function recreateThumbnails()
{
    global $TABLE_PREFIX;
    $tableNameWithoutPrefix = getTablenameWithoutPrefix($_REQUEST['tablename']);
    // error checking
    $stopPrefix = "STOPJS:";
    // this tells javascript to stop creating thumbnails
    $requiredFields = array('tablename', 'fieldname', 'maxHeight', 'maxWidth');
    foreach ($requiredFields as $fieldname) {
        if (!@$_REQUEST[$fieldname]) {
            die($stopPrefix . "Required fieldname '{$fieldname}' not specified!");
        }
    }
    if (preg_match('/[^0-9\\_]/i', $_REQUEST['maxHeight'])) {
        die($stopPrefix . "Invalid value for max height!\n");
    }
    if (preg_match('/[^0-9\\_]/i', $_REQUEST['maxWidth'])) {
        die($stopPrefix . "Invalid value for max width!\n");
    }
    // get upload count
    static $count;
    if ($count == '') {
        $where = mysql_escapef("tableName = ? AND fieldName = ?", $tableNameWithoutPrefix, $_REQUEST['fieldname']);
        $totalUploads = mysql_count('uploads', $where);
    }
    // load upload
    $whereEtc = mysql_escapef("tableName = ? AND fieldname = ?", $tableNameWithoutPrefix, $_REQUEST['fieldname']);
    $whereEtc .= " LIMIT 1 OFFSET " . intval($_REQUEST['offset']);
    @(list($upload) = mysql_select('uploads', $whereEtc));
    //
    if ($upload) {
        // get uploadDir and uploadUrl
        $schema = loadSchema($upload['tableName']);
        list($uploadDir, $uploadUrl) = getUploadDirAndUrl($schema[$upload['fieldName']]);
        // get upload's absolute filepath
        $absoluteFilepath = addUploadPathPrefix($upload['filePath'], $uploadDir);
        // make path absolute
        // error checking
        if (!file_exists($absoluteFilepath)) {
            $error = "Upload doesn't exist '{$absoluteFilepath}'!<br/>\n";
            $error .= "Found in: {$upload['tableName']}, {$upload['fieldName']}, record {$upload['recordNum']}.";
            die($error);
        }
        ### resize image
        $isImage = preg_match("/\\.(gif|jpg|jpeg|png)\$/i", $absoluteFilepath);
        if ($isImage) {
            $thumbNum = $_REQUEST['thumbNum'];
            $thumbSavePath = preg_replace("|([^/]+)\$|", "thumb{$thumbNum}/\$1", $absoluteFilepath);
            $thumbUrlPath = preg_replace("|([^/]+)\$|", "thumb{$thumbNum}/\$1", $upload['urlPath']);
            // erase old thumbnail
            if (file_exists($thumbSavePath)) {
                @unlink($thumbSavePath) || die("Can't erase old thumbnail '{$thumbSavePath}': {$php_errormsg}");
            }
            // create new thumbnail
            list($thumbWidth, $thumbHeight) = saveResampledImageAs($thumbSavePath, $absoluteFilepath, $_REQUEST['maxWidth'], $_REQUEST['maxHeight']);
            doAction('upload_thumbnail_save', array($tableNameWithoutPrefix, $_REQUEST['fieldname'], $thumbNum, $thumbSavePath));
            // update upload database
            $query = "UPDATE `{$TABLE_PREFIX}uploads`\n";
            $query .= "   SET `thumbFilepath{$thumbNum}` = '" . mysql_escape(removeUploadPathPrefix($thumbSavePath, $uploadDir)) . "',\n";
            $query .= "       `thumbUrlPath{$thumbNum}`  = '" . mysql_escape(removeUploadPathPrefix($thumbUrlPath, $uploadUrl)) . "',\n";
            $query .= "       `thumbWidth{$thumbNum}`    = '" . mysql_escape($thumbWidth) . "',\n";
            $query .= "       `thumbHeight{$thumbNum}`   = '" . mysql_escape($thumbHeight) . "'\n";
            $query .= " WHERE num = '" . mysql_escape($upload['num']) . "'";
            mysql_query($query) or die("MySQL Error: " . htmlencode(mysql_error()) . "\n");
        }
    }
    // print status message
    $offset = $_REQUEST['offset'] + 1;
    if ($offset <= $totalUploads) {
        print "{$offset}/{$totalUploads}";
    } else {
        print "done";
    }
    exit;
}
function getTablenameErrors($tablename)
{
    // get used tablenames
    static $usedTableNamesLc = array();
    static $loadedTables;
    if (!$loadedTables++) {
        foreach (getMysqlTablesWithPrefix() as $usedTablename) {
            $withoutPrefixLc = strtolower(getTablenameWithoutPrefix($usedTablename));
            array_push($usedTableNamesLc, $withoutPrefixLc);
        }
        foreach (getSchemaTables() as $usedTableName) {
            $withoutPrefixLc = strtolower($usedTablename);
            array_push($usedTableNamesLc, $withoutPrefixLc);
        }
    }
    // get reserved tablenames
    $reservedTableNamesLc = array();
    array_push($reservedTableNamesLc, 'home', 'admin', 'database', 'accounts', 'license');
    // the are hard coded menu names
    array_push($reservedTableNamesLc, 'default');
    // can't be used because menu folder exists with default menu files
    array_push($reservedTableNamesLc, 'all');
    // can't be used because the "all" keyword gives access to all menus in user accounts
    // get error
    $error = null;
    $tablenameLc = strtolower(getTableNameWithoutPrefix($tablename));
    if ($tablenameLc == '') {
        $error = "No table name specified!\n";
    } else {
        if (!preg_match("/^[a-z]/", $tablenameLc)) {
            $error = "Table name must start with a letter!\n";
        } else {
            if (preg_match("/[A-Z]/", $tablename)) {
                $error = "Table name must be lowercase!\n";
            } else {
                if (preg_match("/[^a-z0-9\\-\\_]/", $tablename)) {
                    $error = "Table name can only contain these characters (\"a-z, 0-9, - and _\")!\n";
                }
            }
        }
    }
    if (in_array($tablenameLc, $usedTableNamesLc)) {
        $error = "That table name is already in use, please choose another.\n";
    }
    if (in_array($tablenameLc, $reservedTableNamesLc)) {
        $error = "That table name is not allowed, please choose another.\n";
    }
    //
    return $error;
}