Example #1
0
function handleFileUploads($uploadFile, $formVars)
{
    global $filesBaseDir;
    // these variables are defined in 'ini.inc.php'
    global $moveFilesIntoSubDirectories;
    global $dirNamingScheme;
    global $renameUploadedFiles;
    global $fileNamingScheme;
    global $handleNonASCIIChars;
    global $allowedFileNameCharacters;
    global $allowedDirNameCharacters;
    global $changeCaseInFileNames;
    global $changeCaseInDirNames;
    $tmpFilePath = $uploadFile["tmp_name"];
    // Generate file name:
    if ($renameUploadedFiles == "yes") {
        if (preg_match("/.+\\.[^.]+\$/i", $uploadFile["name"])) {
            // preserve any existing file name extension
            $fileNameExtension = preg_replace("/.+(\\.[^.]+)\$/i", "\\1", $uploadFile["name"]);
        } else {
            $fileNameExtension = "";
        }
        // auto-generate a file name according to the naming scheme given in '$fileNamingScheme':
        $newFileName = parsePlaceholderString($formVars, $fileNamingScheme, "<:serial:>");
        // function 'parsePlaceholderString()' is defined in 'include.inc.php'
        // handle non-ASCII and unwanted characters:
        $newFileName = handleNonASCIIAndUnwantedCharacters($newFileName, $allowedFileNameCharacters, $handleNonASCIIChars);
        // function 'handleNonASCIIAndUnwantedCharacters()' is defined in 'include.inc.php'
        // add original file name extension:
        $newFileName .= $fileNameExtension;
    } else {
        // take the file name as given by the user:
        $newFileName = $uploadFile["name"];
    }
    // Generate directory structure:
    if ($moveFilesIntoSubDirectories != "never") {
        // remove any slashes (i.e., directory delimiter(s)) from the beginning or end of '$dirNamingScheme':
        $dirNamingScheme = trimTextPattern($dirNamingScheme, "[\\/\\\\]+", true, true);
        // function 'trimTextPattern()' is defined in 'include.inc.php'
        $dirNamingSchemePartsArray = preg_split("#[/\\\\]+#", $dirNamingScheme);
        // split on slashes to separate between multiple sub-directories
        $subDirNamesArray = array();
        // initialize array variable which will hold the generated sub-directory names
        // auto-generate a directory name according to the naming scheme given in '$dirNamingScheme'
        // and handle non-ASCII chars plus unwanted characters:
        foreach ($dirNamingSchemePartsArray as $dirNamingSchemePart) {
            // parse given placeholder string:
            $subDirName = parsePlaceholderString($formVars, $dirNamingSchemePart, "");
            // function 'parsePlaceholderString()' is defined in 'include.inc.php'
            // handle non-ASCII and unwanted characters:
            $subDirName = handleNonASCIIAndUnwantedCharacters($subDirName, $allowedDirNameCharacters, $handleNonASCIIChars);
            // function 'handleNonASCIIAndUnwantedCharacters()' is defined in 'include.inc.php'
            if (!empty($subDirName)) {
                $subDirNamesArray[] = $subDirName;
            }
        }
        if (!empty($subDirNamesArray)) {
            $subDirName = implode("/", $subDirNamesArray) . "/";
        } else {
            $subDirName = "";
        }
    } else {
        $subDirName = "";
    }
    // Perform any case transformations:
    // change case of file name:
    if (preg_match("/^(lower|upper)\$/i", $changeCaseInFileNames)) {
        $newFileName = changeCase($changeCaseInFileNames, $newFileName);
    }
    // function 'changeCase()' is defined in 'include.inc.php'
    // change case of DIR name:
    if (preg_match("/^(lower|upper)\$/i", $changeCaseInDirNames) && !empty($subDirName)) {
        $subDirName = changeCase($changeCaseInDirNames, $subDirName);
    }
    // Generate full destination path:
    // - if '$moveFilesIntoSubDirectories = "existing"' and there's an existing sub-directory (within the default files directory '$filesBaseDir')
    //   whose name equals '$subDirName' we'll copy the new file into that sub-directory
    // - if '$moveFilesIntoSubDirectories = "always"' and '$subDirName' isn't empty, we'll generate an appropriately named sub-directory if it
    //   doesn't exist yet
    // - otherwise we just copy the file to the root-level of '$filesBaseDir':
    if (!empty($subDirName) && ($moveFilesIntoSubDirectories == "existing" and is_dir($filesBaseDir . $subDirName) or $moveFilesIntoSubDirectories == "always")) {
        $destFilePath = $filesBaseDir . $subDirName . $newFileName;
        // new file will be copied into sub-directory within '$filesBaseDir'...
        // copy the new subdir name & file name to the 'file' field variable:
        // Note: if a user uploads a file and there was already a file specified within the 'file' field, the old file will NOT get removed
        //       from the files directory! Automatic file removal is omitted on purpose since it's way more difficult to recover an
        //       inadvertently deleted file than to delete it manually. However, future versions should introduce a smarter way of handling
        //       orphaned files...
        $fileName = $subDirName . $newFileName;
        if ($moveFilesIntoSubDirectories == "always" and !is_dir($filesBaseDir . $subDirName)) {
            // make sure the directory we're moving the file to exists before proceeding:
            recursiveMkdir($filesBaseDir . $subDirName);
        }
    } else {
        $destFilePath = $filesBaseDir . $newFileName;
        // new file will be copied to root-level of '$filesBaseDir'...
        $fileName = $newFileName;
        // copy the new file name to the 'file' field variable (see note above!)
    }
    // Copy uploaded file from temporary location to the default file directory specified in '$filesBaseDir':
    // (for more on PHP file uploads see <http://www.php.net/manual/en/features.file-upload.php>)
    move_uploaded_file($tmpFilePath, $destFilePath);
    return $fileName;
}
Example #2
0
function findDuplicates($sqlQuery, $originalDisplayType)
{
    global $tableRefs, $tableUserData;
    // defined in 'db.inc.php'
    global $alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower, $print, $punct, $space, $upper, $word, $patternModifiers;
    // defined in 'transtab_unicode_charset.inc.php' and 'transtab_latin1_charset.inc.php'
    // re-assign the correct display type (i.e. the view that was active when the user clicked the 'dups' link in the header):
    if (!empty($originalDisplayType)) {
        $displayType = $originalDisplayType;
    }
    // Extract form variables provided by the 'duplicateSearch' form in 'duplicate_search.php':
    if (isset($_REQUEST['matchFieldsSelector'])) {
        if (is_string($_REQUEST['matchFieldsSelector'])) {
            // we accept a string containing a (e.g. comma delimited) list of field names
            $selectedFieldsArray = preg_split("/[^a-z_]+/", $_REQUEST['matchFieldsSelector'], -1, PREG_SPLIT_NO_EMPTY);
        } else {
            // the field list is already provided as array:
            $selectedFieldsArray = $_REQUEST['matchFieldsSelector'];
        }
    } else {
        $selectedFieldsArray = array();
    }
    if (isset($_REQUEST['ignoreWhitespace']) and $_REQUEST['ignoreWhitespace'] == "1") {
        $ignoreWhitespace = "1";
    } else {
        $ignoreWhitespace = "0";
    }
    if (isset($_REQUEST['ignorePunctuation']) and $_REQUEST['ignorePunctuation'] == "1") {
        $ignorePunctuation = "1";
    } else {
        $ignorePunctuation = "0";
    }
    if (isset($_REQUEST['ignoreCharacterCase']) and $_REQUEST['ignoreCharacterCase'] == "1") {
        $ignoreCharacterCase = "1";
    } else {
        $ignoreCharacterCase = "0";
    }
    if (isset($_REQUEST['ignoreAuthorInitials']) and $_REQUEST['ignoreAuthorInitials'] == "1") {
        $ignoreAuthorInitials = "1";
    } else {
        $ignoreAuthorInitials = "0";
    }
    if (isset($_REQUEST['nonASCIIChars'])) {
        $nonASCIIChars = $_REQUEST['nonASCIIChars'];
    } else {
        $nonASCIIChars = "keep";
    }
    // VALIDATE FORM DATA:
    $errors = array();
    // Validate the field selector:
    if (empty($selectedFieldsArray)) {
        $errors["matchFieldsSelector"] = "You must select at least one field:";
    }
    // Validate the 'SQL Query' field:
    if (empty($sqlQuery)) {
        $errors["sqlQuery"] = "You must specify a query string:";
    } elseif (!preg_match("/^SELECT/i", $sqlQuery)) {
        $errors["sqlQuery"] = "You can only execute SELECT queries:";
    }
    // Check if there were any errors:
    if (count($errors) > 0) {
        // In case of an error, we write all form variables back to the '$formVars' array
        // (which 'duplicate_search.php' requires to reload form values):
        foreach ($_REQUEST as $varname => $value) {
            $formVars[$varname] = $value;
        }
        // Since checkbox form fields do only get included in the '$_REQUEST' array if they were marked,
        // we have to add appropriate array elements for all checkboxes that weren't set:
        if (!isset($formVars["ignoreWhitespace"])) {
            $formVars["ignoreWhitespace"] = "0";
        }
        if (!isset($formVars["ignorePunctuation"])) {
            $formVars["ignorePunctuation"] = "0";
        }
        if (!isset($formVars["ignoreCharacterCase"])) {
            $formVars["ignoreCharacterCase"] = "0";
        }
        if (!isset($formVars["ignoreAuthorInitials"])) {
            $formVars["ignoreAuthorInitials"] = "0";
        }
        if (!isset($formVars["showLinks"])) {
            $formVars["showLinks"] = "0";
        }
        // Write back session variables:
        saveSessionVariable("errors", $errors);
        // function 'saveSessionVariable()' is defined in 'include.inc.php'
        saveSessionVariable("formVars", $formVars);
        // There are errors. Relocate back to 'duplicate_search.php':
        header("Location: duplicate_search.php");
        exit;
        // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> !EXIT! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    }
    // CONSTRUCT SQL QUERY (1. DUPLICATE SEARCH):
    // To identify any duplicates within the results of the original query, we build a new query based on the original SQL query:
    $query = $sqlQuery;
    // Replace SELECT list of columns with those from '$selectedFieldsArray' (plus the 'serial' column):
    $selectedFieldsString = implode(", ", $selectedFieldsArray);
    $query = newSELECTclause("SELECT " . $selectedFieldsString . ", serial", $query, false);
    // function 'newSELECTclause()' is defined in 'include.inc.php'
    // Replace any existing ORDER BY clause with the list of columns given in '$selectedFieldsArray':
    $query = newORDERclause("ORDER BY " . $selectedFieldsString, $query, false);
    // function 'newORDERclause()' is defined in 'include.inc.php'
    // Fix escape sequences within the SQL query:
    $query = stripSlashesIfMagicQuotes($query);
    // RUN the query on the database through the connection:
    $result = queryMySQLDatabase($query);
    // function 'queryMySQLDatabase()' is defined in 'include.inc.php'
    // PROCESS RESULTS:
    $recordSerialsArray = array();
    $duplicateRecordSerialsArray = array();
    $rowsFound = @mysql_num_rows($result);
    // Identify any records with matching field data:
    if ($rowsFound > 0) {
        // Count the number of fields:
        $fieldsFound = mysql_num_fields($result);
        // Loop over each row in the result set:
        for ($rowCounter = 0; $row = @mysql_fetch_array($result); $rowCounter++) {
            $recordIdentifier = "";
            // make sure our buffer variable is empty
            // For each row, loop over each field (except for the last one which is the 'serial' field):
            for ($i = 0; $i < $fieldsFound - 1; $i++) {
                // fetch the current attribute name:
                $fieldName = getMySQLFieldInfo($result, $i, "name");
                // function 'getMySQLFieldInfo()' is defined in 'include.inc.php'
                // normalize author names:
                if ($fieldName == "author" and $ignoreAuthorInitials == "1") {
                    // this is a stupid hack that maps the names of the '$row' array keys to those used
                    // by the '$formVars' array (which is required by function 'parsePlaceholderString()')
                    // (eventually, the '$formVars' array should use the MySQL field names as names for its array keys)
                    $formVars = buildFormVarsArray($row);
                    // function 'buildFormVarsArray()' is defined in 'include.inc.php'
                    // ignore initials in author names:
                    $row[$i] = parsePlaceholderString($formVars, "<:authors[0||]:>", "");
                    // function 'parsePlaceholderString()' is defined in 'include.inc.php'
                }
                $recordIdentifier .= $row[$i];
                // merge all field values to form a unique record identifier string
            }
            // Normalize record identifier string:
            if ($ignoreWhitespace == "1") {
                // ignore whitespace
                $recordIdentifier = preg_replace("/\\s+/", "", $recordIdentifier);
            }
            if ($ignorePunctuation == "1") {
                // ignore punctuation
                $recordIdentifier = preg_replace("/[{$punct}]+/{$patternModifiers}", "", $recordIdentifier);
            }
            if ($ignoreCharacterCase == "1") {
                // ignore character case
                $recordIdentifier = strtolower($recordIdentifier);
            }
            if ($nonASCIIChars == "strip") {
                // strip non-ASCII characters
                $recordIdentifier = handleNonASCIIAndUnwantedCharacters($recordIdentifier, "\\S\\s", "strip");
            } elseif ($nonASCIIChars == "transliterate") {
                // transliterate non-ASCII characters
                $recordIdentifier = handleNonASCIIAndUnwantedCharacters($recordIdentifier, "\\S\\s", "transliterate");
            }
            // Check whether the record identifier string has occurred already:
            if (isset($recordSerialsArray[$recordIdentifier])) {
                // this record identifier string has already been seen
                $recordSerialsArray[$recordIdentifier][] = $row["serial"];
            } else {
                // new record identifier string
                $recordSerialsArray[$recordIdentifier] = array($row["serial"]);
            }
            // add a new array element for this record's identifier string (and store its serial number as value within a sub-array)
        }
        // Collect all array elements from '$recordSerialsArray' where their sub-array contains more than one serial number:
        foreach ($recordSerialsArray as $recordSerials) {
            if (count($recordSerials) > 1) {
                foreach ($recordSerials as $recordSerial) {
                    $duplicateRecordSerialsArray[] = $recordSerial;
                }
            }
            // add this record's serial number to the array of duplicate record serials
        }
    } else {
        // TODO!
    }
    if (empty($duplicateRecordSerialsArray)) {
        $duplicateRecordSerialsArray[] = "0";
    }
    // if no duplicate records were found, the non-existing serial number '0' will result in a "nothing found" feedback
    // CONSTRUCT SQL QUERY (2. DUPLICATES DISPLAY):
    // To display any duplicates that were found within the results of the original query, we build again a new query based on the original SQL query:
    $query = $sqlQuery;
    // Replace WHERE clause:
    // TODO: maybe make this into a generic function? (compare with function 'extractWHEREclause()' in 'include.inc.php')
    $duplicateRecordSerialsString = implode("|", $duplicateRecordSerialsArray);
    $query = preg_replace("/(?<=WHERE )(.+?)(?= ORDER BY| LIMIT| GROUP BY| HAVING| PROCEDURE| FOR UPDATE| LOCK IN|[ ;]+(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|FILE)\\b|\$)/i", "serial RLIKE \"^(" . $duplicateRecordSerialsString . ")\$\"", $query);
    // Replace any existing ORDER BY clause with the list of columns given in '$selectedFieldsArray':
    $query = newORDERclause("ORDER BY " . $selectedFieldsString, $query, false);
    return array($query, $displayType);
}
Example #3
0
function generateCiteKey($formVars)
{
    global $defaultCiteKeyFormat;
    // defined in 'ini.inc.php'
    global $handleNonASCIICharsInCiteKeysDefault;
    global $userOptionsArray;
    // '$userOptionsArray' is made globally available in file 'import_modify.php' as well as by functions 'generateExport()' and 'generateCitations()' in 'search.php'
    // by default, we use any record-specific cite key that was entered manually by the user:
    if (isset($formVars['citeKeyName'])) {
        $citeKey = $formVars['citeKeyName'];
    } else {
        $citeKey = "";
    }
    // check if the user's options for auto-generation of cite keys command us to replace the manually entered cite key:
    if (!empty($userOptionsArray)) {
        if ($userOptionsArray['export_cite_keys'] == "yes") {
            if ($userOptionsArray['autogenerate_cite_keys'] == "yes") {
                if (empty($citeKey) or $userOptionsArray['prefer_autogenerated_cite_keys'] == "yes") {
                    if ($userOptionsArray['use_custom_cite_key_format'] == "yes") {
                        // if the user wants to use a custom cite key format
                        $citeKeyFormat = $userOptionsArray['cite_key_format'];
                    } else {
                        // use the default cite key format that was specified by the admin in 'ini.inc.php'
                        $citeKeyFormat = $defaultCiteKeyFormat;
                    }
                    // auto-generate a cite key according to the given naming scheme:
                    $citeKey = parsePlaceholderString($formVars, $citeKeyFormat, "<:authors:><:year:>");
                }
            }
        } else {
            $citeKey = "";
        }
        // by omitting a cite key Bibutils will take care of generation of cite keys for its export formats (BibTeX, Endnote, RIS)
    }
    // check how to handle non-ASCII characters:
    if (!empty($userOptionsArray) and !empty($userOptionsArray['nonascii_chars_in_cite_keys'])) {
        // use the user's own setting
        $handleNonASCIIChars = $userOptionsArray['nonascii_chars_in_cite_keys'];
    } else {
        $handleNonASCIIChars = $handleNonASCIICharsInCiteKeysDefault;
    }
    // use the default setting that was specified by the admin in 'ini.inc.php'
    // in addition to the handling of non-ASCII chars (given in '$handleNonASCIIChars') we'll
    // strip additional characters from the generated cite keys: for cite keys, we only allow
    // letters, digits, and the following characters: !$&*+-./:;<>?[]^_`|
    // see e.g. the discussion of cite keys at: <http://search.cpan.org/~gward/btparse-0.34/doc/bt_language.pod>
    if (!empty($citeKey)) {
        $citeKey = handleNonASCIIAndUnwantedCharacters($citeKey, "[:alnum:]" . preg_quote("!\$&*+-./:;<>?[]^_`|", "/"), $handleNonASCIIChars);
    }
    // ensure that each cite key is unique:
    if (!empty($citeKey) and !empty($userOptionsArray) and $userOptionsArray['export_cite_keys'] == "yes" and $userOptionsArray['uniquify_duplicate_cite_keys'] == "yes") {
        // if the generated cite key already exists in the global array of found cite keys
        // ('$citeKeysArray'), we'll uniquify it, otherwise we'll keep it as is:
        $citeKey = ensureUniqueCiteKey($citeKey);
    }
    return $citeKey;
}