Skip to content

Commit

Permalink
Merge pull request #1630 from tripal/tv4-issue1629-importer-file-vali…
Browse files Browse the repository at this point in the history
…dation

Importer file validation improvements
  • Loading branch information
dsenalik committed Sep 14, 2023
2 parents f96c909 + 5ad9c70 commit c34166d
Show file tree
Hide file tree
Showing 5 changed files with 463 additions and 34 deletions.
70 changes: 51 additions & 19 deletions tripal/src/Form/TripalImporterForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public function buildForm(array $form, FormStateInterface $form_state, $plugin_i
$importer = $importer_manager->createInstance($plugin_id);
$importer_def = $importer_manager->getDefinitions()[$plugin_id];

if (array_key_exists('cardinality', $importer_def) and $importer_def['cardinality'] != 1) {
\Drupal::messenger()->addError('Error in the definition of this importer. Tripal Importers'
. ' currently only support cardinality of 1, see Tripal issue #1635');
}

$form['#title'] = $importer_def['label'];

$form['importer_plugin_id'] = [
Expand Down Expand Up @@ -227,45 +232,72 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
$importer_def = $importer_manager->getDefinitions()[$plugin_id];

$file_local = NULL;
$file_upload = NULL;
$file_remote = NULL;
$file_upload = NULL;
$file_existing = NULL;

// Get the form values for the file.
// Determine which file source was specified.
if (array_key_exists('file_local', $importer_def) and $importer_def['file_local'] == TRUE) {
$file_local = trim($form_values['file_local']);
}
if (array_key_exists('file_upload', $importer_def) and $importer_def['file_upload'] == TRUE) {
$file_upload = trim($form_values['file_upload']);
if (array_key_exists('file_upload_existing', $form_values) and $form_values['file_upload_existing']) {
$file_existing = $form_values['file_upload_existing'];
}
}
if (array_key_exists('file_remote', $importer_def) and $importer_def['file_remote'] == TRUE) {
$file_remote = trim($form_values['file_remote']);
}

// How many methods were specified for the source of the file?
$n_methods = ($file_local?1:0) + ($file_remote?1:0) + (($file_upload or $file_existing)?1:0);
// The user must provide at least one file source method.
if ($n_methods == 0) {
$form_state->setErrorByName('file_local', t('You must provide a file location or upload a file.'));
}
// No more than one method can be specified.
elseif ($n_methods > 1) {
$field = $file_remote?'file_remote':'file_local';
$form_state->setErrorByName($field, t('You have specified more than one source option for'
. ' the file, only one may be used at a time.'));
}
// A single file source has been provided. If local or remote, check that it is valid.
else {
// If the file is local make sure it exists on the local filesystem.
if ($file_local) {
// check to see if the file is located local to Drupal
$file_local = trim($file_local);
$dfile = $_SERVER['DOCUMENT_ROOT'] . base_path() . $file_local;
$dfile = \Drupal::root() . '/' . $file_local;
if (!file_exists($dfile)) {
// if not local to Drupal, the file must be someplace else, just use
// the full path provided
$dfile = $file_local;
}
if (!file_exists($dfile)) {
// form_set_error('file_local', t("Cannot find the file on the system. Check that the file exists or that the web server has permissions to read the file."));
$form_state->setErrorByName('file_local', t("Cannot find the file on the system. Check that the file exists or that the web server has permissions to read the file."));
$form_state->setErrorByName('file_local', t('Cannot find the file on the system.'
. ' Check that the file exists or that the web server has permission to read the file.'));
}
}
}
if (array_key_exists('file_upload', $importer_def) and $importer_def['file_upload'] == TRUE) {
$file_upload = trim($form_values['file_upload']);
if (array_key_exists('file_upload_existing', $form_values) and $form_values['file_upload_existing']) {
$file_existing = $form_values['file_upload_existing'];
}
}
if (array_key_exists('file_remote', $importer_def) and $importer_def['file_remote'] == TRUE) {
$file_remote = trim($form_values['file_remote']);
}
elseif ($file_remote) {
// Validate that the remote URI is of the correct format.
if (filter_var($file_remote, FILTER_VALIDATE_URL) === false) {
$form_state->setErrorByName('file_remote', t('The Remote Path provided is not a valid URI.'));
}

// The user must provide at least an uploaded file or a local file path.
if ($importer_def['file_required'] == TRUE and !$file_upload and !$file_local and !$file_remote and !$file_existing) {
$form_state->setErrorByName('file_local', t("You must provide a file."));
// Validate a correct format remote URI to make sure it can be
// accessed, with successful HTTP response code 200.
else {
$headers = @get_headers($file_remote);
if (($headers === false) or (!is_array($headers)) or (!strpos($headers[0], '200'))) {
$form_state->setErrorByName('file_remote', t('The Remote Path provided cannot be accessed.'
. ' Check that it is correct.'));
}
}
}
}

// Now allow the loader to do validation of its form additions.
$importer->formValidate($form, $form_state);
}
}
}
11 changes: 5 additions & 6 deletions tripal/src/TripalImporter/TripalImporterBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,18 +327,17 @@ public function prepareFiles() {
for ($i = 0; $i < count($this->arguments['files']); $i++) {
if (!empty($this->arguments['files'][$i]['file_remote'])) {
$file_remote = $this->arguments['files'][$i]['file_remote'];
$this->logMessage('Download file: !file_remote...', ['!file_remote' => $file_remote]);
$this->logger->notice('Download file: %file_remote...', ['%file_remote' => $file_remote]);


// If this file is compressed then keepthe .gz extension so we can
// If this file is compressed then keep the .gz extension so we can
// uncompress it.
$ext = '';
if (preg_match('/^(.*?)\.gz$/', $file_remote)) {
$ext = '.gz';
}
// Create a temporary file.
$temp = tempnam("temporary://", 'import_') . $ext;
$this->logMessage("Saving as: !file", ['!file' => $temp]);
$this->logger->notice('Saving as: %file', ['%file' => $temp]);

$url_fh = fopen($file_remote, "r");
$tmp_fh = fopen($temp, "w");
Expand All @@ -359,7 +358,7 @@ public function prepareFiles() {
// Is this file compressed? If so, then uncompress it
$matches = [];
if (preg_match('/^(.*?)\.gz$/', $this->arguments['files'][$i]['file_path'], $matches)) {
$this->logMessage("Uncompressing: !file", ['!file' => $this->arguments['files'][$i]['file_path']]);
$this->logger->notice('Uncompressing: %file', ['%file' => $this->arguments['files'][$i]['file_path']]);
$buffer_size = 4096;
$new_file_path = $matches[1];
$gzfile = gzopen($this->arguments['files'][$i]['file_path'], 'rb');
Expand Down Expand Up @@ -403,7 +402,7 @@ public function cleanFile() {
for ($i = 0; $i < count($this->arguments['files']); $i++) {
if (!empty($this->arguments['files'][$i]['file_remote']) and
file_exists($this->arguments['files'][$i]['file_path'])) {
$this->logMessage('Removing downloaded file...');
$this->logger->notice('Removing downloaded file...');
unlink($this->arguments['files'][$i]['file_path']);
$this->is_prepared = FALSE;
}
Expand Down

0 comments on commit c34166d

Please sign in to comment.