Skip to content

Commit

Permalink
Merge pull request #3 from gsu-library/develop
Browse files Browse the repository at this point in the history
Code Reorganization
  • Loading branch information
vle91 authored Feb 1, 2023
2 parents 3b2f5c3 + 8977544 commit e4f376e
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 199 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2023-02-01
- Reorganize code.

## [1.1.0] - 2022-09-28
- Update .htaccess to use mod_authz_core directives.
- Change config.ini to config.php.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Code Repository: https://github.com/gsu-library/datacite-bulk-doi-creator-webapp
Author: Matt Brooks <[email protected]>
Date Created: 2022-06-29
License: [GPL3](LICENSE)
Version: 1.1.0
Version: 1.2.0

## Description
A PHP WebApp that bulk creates DataCite DOIs from a provided CSV file. DOIs are created in the findable state. If you are looking for the python version of this WebApp see [DataCite Bulk DOI Creator](https://github.com/gsu-library/datacite-bulk-doi-creator).
Expand Down
6 changes: 5 additions & 1 deletion config/config.sample.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<?php

/**
* Configuration.
*
* @var array [url, doiPrefix, username, password, maxSubmittedFiles, maxReportedFiles, maxUploadSize]
*/
const CONFIG = [
'url' => 'https://api.datacite.org/dois',
'doiPrefix' => '',
Expand Down
37 changes: 32 additions & 5 deletions includes/functions.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
<?php
// Go back to the index page.
/**
* Redirects browser to the index page.
*
* // TODO: check to see if this needs to be loaded on any pages or just on includes.
*
* @return void
*/
function go_home() {
header('location: .');
exit;
}


// Loads the configuration file.
/**
* Loads the configuration file.
*
* Configuration will be in a CONFIG variable.
*
* @return void
*/
function load_config_file() {
require_once('config'.DIRECTORY_SEPARATOR.'config.php');
}


// Lists out files in either the reports or uploads directories.
/**
* Lists out files in either the reports or uploads directories.
*
* @param string $type Folder to parse.
* @param integer $amount Number of results to return.
* @return void
*/
function list_files($type, $amount) {
$files = glob($type.DIRECTORY_SEPARATOR.'*.csv');

Expand All @@ -38,7 +56,12 @@ function list_files($type, $amount) {
}


// Prints the navigation, marking the current page as active.
/**
* Prints the navigation, marking the current page as active.
*
* @param string $currentPage Filename of the current page.
* @return void
*/
function print_header($currentPage) {
echo '
<header class="container my-3">
Expand Down Expand Up @@ -89,7 +112,11 @@ function print_header($currentPage) {
}


// Prints the footer.
/**
* Prints the footer.
*
* @return void
*/
function print_footer() {
echo '
<footer class="container my-3">
Expand Down
39 changes: 39 additions & 0 deletions includes/index_functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Prints the $output session variable.
*
* @return void
*/
function print_output() {
if(isset($_SESSION['output'])) {
echo implode('<br>', $_SESSION['output']);
}

$_SESSION['output'] = [];
}


/**
* Prints a link to the current report found in session variable $reportPath.
*
* @return void
*/
function print_report_link() {
if(isset($_SESSION['reportPath']) && $_SESSION['reportPath']) {
echo '<a href="'.htmlspecialchars($_SESSION['reportPath'], ENT_QUOTES).'" download>Download Report</a>';
}

unset($_SESSION['reportPath']);
}


/**
* Sets the CSRF token in session ($csrfToken).
*
* @return void
*/
function set_csrf_token() {
if(!isset($_SESSION['csrfToken'])) {
$_SESSION['csrfToken'] = bin2hex(random_bytes(32));
}
}
219 changes: 219 additions & 0 deletions includes/submit_functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
<?php
/**
* Check for PHP cURL and that both the reports and uploads directories are writable.
*
* @return void
*/
function check_capabilities() {
$go_home = false;

if(!function_exists('curl_init')) {
array_push($_SESSION['output'], 'Please install/enable the PHP cURL library.');
$go_home = true;
}

if(!is_writable('uploads')) {
array_push($_SESSION['output'], 'The uploads directory is not writable.');
$go_home = true;
}

if(!is_writable('reports')) {
array_push($_SESSION['output'], 'The reports directory is not writable.');
$go_home = true;
}

if($go_home) {
go_home();
}
}


/**
* Validates CSRF token.
*
* @return void
*/
function validate_csrf_token() {
if(!isset($_POST['csrfToken']) || !isset($_SESSION['csrfToken'])) {
array_push($_SESSION['output'], 'CSRF token not found.');
go_home();
}
else {
if($_POST['csrfToken'] !== $_SESSION['csrfToken']) {
array_push($_SESSION['output'], 'The CSRF token is invalid.');
go_home();
}
else {
unset($_SESSION['csrfToken']);
}
}
}


/**
* Check if all needles exist in haystack.
*
* @param array $needles Array of values to search for.
* @param array $haystack Array of values to search in.
* @return bool
*/
function in_array_all($needles, $haystack) {
return empty(array_diff($needles, $haystack));
}


/**
* Remove oldest files from directory.
*
* @param string $filePattern File name pattern to search for.
* @param integer $maxFileCount Max number of files to keep.
* @return void
*/
function remove_old_files($filePattern, $maxFileCount) {
if($maxFileCount < 1) {
$maxFileCount = 1;
}

$files = glob($filePattern);
$extraFiles = count($files) - $maxFileCount;

if($extraFiles > 0) {
// Sort by last modified ascending.
usort($files, function($x, $y) {
return filemtime($x) > filemtime($y);
});

for($i = 0; $i < $extraFiles; $i++) {
unlink($files[$i]);
}
}
}


/**
* Return a valid file name.
*
* @param string $fileName Desired file name.
* @return string|null A valid file name.
*/
function find_file_name($fileName) {
if(!file_exists($fileName)) {
return $fileName;
}

$fileParts = pathinfo($fileName);
$fileCount = count(glob($fileParts['dirname'] . DIRECTORY_SEPARATOR . "*"));

for($i = 1; $i <= $fileCount; $i++) {
$tempName = $fileParts['dirname'] . DIRECTORY_SEPARATOR . $fileParts['filename'] . " ($i)." . $fileParts['extension'];

if(!file_exists($tempName)) {
return $tempName;
}
}

return null;
}


/**
* Process uploaded file. Checks for upload file, file size, and file name.
*
* @return string Full file path of the uploaded file.
*/
function process_uploaded_file() {
// Check upload and move it to folder.
if($fileName = $_FILES['fileUpload']['name'] ?? null) {
if($_FILES['fileUpload']['size'] > CONFIG['maxUploadSize']){
array_push($_SESSION['output'], 'The uploaded file is too large.');
go_home();
}

if(!($filePath = find_file_name('uploads'.DIRECTORY_SEPARATOR.$fileName))) {
array_push($_SESSION['output'], 'There was an error saving the uploaded file.');
go_home();
}

move_uploaded_file($_FILES['fileUpload']['tmp_name'], $filePath);
remove_old_files('uploads'.DIRECTORY_SEPARATOR.'*.csv', CONFIG['maxSubmittedFiles']);

return $filePath;
}
else {
array_push($_SESSION['output'], 'Could not find uploaded file.');
go_home();
}
}


/**
* Processes the headers in the uploaded file. Checks to make sure all required headers are present.
*
* @param resource $uploadFp File pointer to upload file.
* @return array Array of normalized headers from the upload file.
*/
function process_upload_headers($uploadFp) {
// Headers required to process the upload file.
$requiredHeaders = [
'doi_suffix',
'title',
'year',
'type',
'description',
'publisher',
'source_url',
'creator1',
'creator1_type', // TODO: will depend on orchid id
// don't require and assume personal?
'creator1_given',
'creator1_family',
];

// Save file headers.
if(($headers = fgetcsv($uploadFp)) === false) {
array_push($_SESSION['output'], 'No data was found in the uploaded file.');
go_home();
}

// Trim and lowercase headers in CSV file.
$headers = array_map(function($header) {
return strtolower(trim($header));
}, $headers);

// Make sure CSV file has all required headers.
// TODO: specify missing headers
if(!in_array_all($requiredHeaders, $headers)) {
array_push($_SESSION['output'], 'The uploaded CSV file is missing required headers.');
go_home();
}

return $headers;
}


/**
* Opens up a file to create a report. The file name is based on the submitted file.
*
* @param string $uploadFullPath Full path of the uploaded file.
* @return resource File pointer of opened report file.
*/
function open_report_file($uploadFullPath) {
$fileParts = pathinfo($uploadFullPath);
$fileName = $fileParts['filename'];

// Open a file for the upload report.
if(!($reportFullPath = find_file_name('reports'.DIRECTORY_SEPARATOR.basename($fileName).' report.csv'))) {
array_push($_SESSION['output'], 'There was an error saving the report file.');
go_home();
}

if(!$reportFp = fopen($reportFullPath, 'w')) {
array_push($_SESSION['output'], 'Cannot write to the reports folder.');
go_home();
}

// Save report path to add link on index page.
$_SESSION['reportPath'] = $reportFullPath;

return $reportFp;
}
26 changes: 2 additions & 24 deletions index.php
Original file line number Diff line number Diff line change
@@ -1,31 +1,9 @@
<?php
session_start();
require_once('includes'.DIRECTORY_SEPARATOR.'functions.php');
require_once('includes'.DIRECTORY_SEPARATOR.'index_functions.php');
load_config_file();

// Print output session variable.
function print_output() {
if(isset($_SESSION['output'])) {
echo implode('<br>', $_SESSION['output']);
}

$_SESSION['output'] = [];
}


// Prints link to current report.
function print_report_link() {
if(isset($_SESSION['reportPath']) && $_SESSION['reportPath']) {
echo '<a href="'.htmlspecialchars($_SESSION['reportPath'], ENT_QUOTES).'" download>Download Report</a>';
}

unset($_SESSION['reportPath']);
}


if(!isset($_SESSION['csrfToken'])) {
$_SESSION['csrfToken'] = bin2hex(random_bytes(32));
}
set_csrf_token();
?>
<!DOCTYPE html>
<html lang="en">
Expand Down
Loading

0 comments on commit e4f376e

Please sign in to comment.