Skip to content

Commit

Permalink
Merge pull request #107 from TripalCultivate/g5.105-loggerInValidators
Browse files Browse the repository at this point in the history
g5.105 Implement TripalLogger to allow validators/traits to log their own messages
  • Loading branch information
laceysanderson authored Sep 11, 2024
2 parents 74da905 + 5699f5d commit 535aa1d
Show file tree
Hide file tree
Showing 9 changed files with 470 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ public function configureValidators($form_values) {
'Unit' => $header_index['Unit']
];
$instance->context = $context;
// Set the logger since this validator uses a setter (setConfiguredGenus)
// which may log messages
$instance->setLogger($this->logger);
$validators['data-row']['duplicate_traits'] = $instance;

//$this->validatorObjects = $validators;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Drupal\trpcultivate_phenotypes\TripalCultivateValidator;

use Drupal\Component\Plugin\PluginBase;
use Drupal\tripal\Services\TripalLogger;

abstract class TripalCultivatePhenotypesValidatorBase extends PluginBase implements TripalCultivatePhenotypesValidatorInterface {

Expand Down Expand Up @@ -265,7 +266,7 @@ public function getConfigAllowNew() {
* on a delimiter value.
*/
public static function splitRowIntoColumns(string $row, string $mime_type) {

$mime_to_delimiter_mapping = self::$mime_to_delimiter_mapping;

// Ensure that the mime type is in our delimiter mapping...
Expand Down Expand Up @@ -367,4 +368,44 @@ public static function getFileDelimiters(string $mime_type) {
throw new \Exception('Cannot retrieve file delimiters for the mime-type provided: ' . $mime_type);
}
}

/**
* The TripalLogger service is used to report status and errors to both site users
* and administrators through the server log.
*
* @var TripalLogger
*/
public TripalLogger $logger;

/**
* Sets the TripalLogger instance for the importer using this validator.
*
* @param TripalLogger $logger
* The TripalLogger instance. In the case of validation done on the form
* the job will not be set but in the case of any validation done in the
* import run job, the job will be set.
*/
public function setLogger(TripalLogger $logger) {
$this->logger = $logger;
}

/**
* Provides a configured TripalLogger instance for reporting things to
* site maintainers.
*
* @return TripalLogger
* An instance of the Tripal logger.
*
* @throws \Exception
* If the $logger property has not been set by the setLogger() method.
*/
public function getLogger() {
if(!empty($this->logger)) {
return $this->logger;
}
else {
throw new \Exception('Cannot retrieve the Tripal Logger property as one has not been set for this validator using the setLogger() method.');
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,17 @@ public function setFileMimeType(string $mime_type) {
throw new \Exception("The setFileMimeType() setter requires a string of the input file's mime-type and must not be empty.");
}

/** @TODO: Log the below message instead of throwing an exception
* This check should occur in the DataFile validator
// Check if mime-type is in our mapping array
if (!isset(self::$mime_to_delimiter_mapping[ $mime_type ])) {
throw new \Exception('The FileTypes Trait requires a supported mime-type but ' . $mime_type . ' is unsupported.');
// Since this is checking a user-provided value, the error is going to be
// logged and then checked by a validator so that the error can be passed
// to the user in a friendly way.
$this->logger->error("The setFileMimeType() setter requires a supported mime-type but '$mime_type' is unsupported.");
}
else {
// Set the mime-type
$this->context['file_mime_type'] = $mime_type;
}
*/

// Set the mime-type
$this->context['file_mime_type'] = $mime_type;
}

/**
Expand Down Expand Up @@ -148,7 +150,7 @@ public function getSupportedMimeTypes() {
/**
* Gets the file mime-type of the input file.
*
* @return array
* @return string
* The file mime-type set by the setFileMimeType() setter method.
*
* @throws \Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,38 @@ public function setConfiguredGenus(string $genus) {
}

// Check that the genus is present in at least one chado organism.
$genus_exists = FALSE;
$query = $this->chado_connection->select('1:organism', 'o')
->fields('o', ['organism_id'])
->condition('o.genus', $genus);
$exists = $query->execute()->fetchObject();
if (!is_object($exists)) {
throw new \Exception("The genus '$genus' does not exist in chado and GenusConfigured Trait requires it both exist and be configured to work with phenotypes. The validators using this trait should not be called if previous validators checking for a configured genus fail.");
// Since this is a user-provided value, the error is going to be logged
// instead of thrown as an exception and then checked by a validator so
// that the error can be passed to the user in a friendly way.
$this->logger->error("The genus '$genus' does not exist in chado and GenusConfigured Trait requires it both exist and be configured to work with phenotypes. The validators using this trait should not be called if previous validators checking for a configured genus fail.");
} else {
$genus_exists = TRUE;
}

// Check that the genus is configured + get that configuration while we are at it.
$configuration_values = $this->service_PhenoGenusOntology->getGenusOntologyConfigValues($genus);
if (!is_array($configuration_values) OR empty($configuration_values)) {

// @TODO: This is a user provided value, should be logged message
// and checked by a validator.

throw new \Exception("The genus '$genus' is not configured and GenusConfigured Trait requires it both exist and be configured to work with phenotypes. The validators using this trait should not be called if previous validators checking for a configured genus fail.");
// Since this is a user-provided value, the error is going to be logged
// instead of thrown as an exception and then checked by a validator so
// that the error can be passed to the user in a friendly way.
$this->logger->error("The genus '$genus' is not configured and GenusConfigured Trait requires it both exist and be configured to work with phenotypes. The validators using this trait should not be called if previous validators checking for a configured genus fail.");
}
// Only set the context array if we know that both:
// - configuration_values exists
// - genus exists
else if ($genus_exists) {
// Set configured values
$this->context['genus']['ontology_terms'] = $configuration_values;

// Set the configured genus
$this->context['genus']['name'] = $genus;
}

// Now we finally get to set things up for the validator!
// Set configured values
$this->context['genus']['ontology_terms'] = $configuration_values;

// Set the configured genus
$this->context['genus']['name'] = $genus;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
/**
* Provides setters focused for setting a project used by the importer
* to package datasets, and getter to retrieve the set value.
*/
*/
trait Project {
/**
* The key used by the setter method to create a project element
* in the context array, as well as the key used by the getter method
* The key used by the setter method to create a project element
* in the context array, as well as the key used by the getter method
* to reference and retrieve the project element value.
*
*
* @var string
*/
private string $context_key = 'project';
Expand All @@ -27,30 +27,29 @@ trait Project {
* @param string|int $project
* A string value is a project name (project.name), whereas an integer value
* is a project id number (project.project_id).
*
*
* @return void
*
*
* @throws \Exception
* - Project name is an empty string value if project name is provided (string data type parameter).
* - Project id is 0 if project id is provided (integer data type parameter).
*/
public function setProject(string|int $project) {

// Determine if the value provided to the parameter is a project name (string)
// or a project id number (integer).
if (is_numeric($project)) {
// Project id number.
if ($project <= 0) {

// @TODO: This is a user provided value, should be logged message
// and checked by a validator.

throw new \Exception('The Project Trait requires project id number to be a number greater than 0.');
// Since this is a user-provided value, the error is going to be logged
// and then checked by a validator so that the error can be passed to the
// user in a friendly way.
$this->logger->error('The Project Trait requires project id number to be a number greater than 0.');
}

// Look up the project id to retrieve the project name.
$project_rec = ChadoProjectAutocompleteController::getProjectName($project);

$set_project = [
'project_id' => $project, // Project Id
'name' => $project_rec, // Name
Expand All @@ -59,13 +58,12 @@ public function setProject(string|int $project) {
else {
// Project name.
if (trim($project) === '') {

// @TODO: This is a user provided value, should be logged message
// and checked by a validator.

throw new \Exception('The Project Trait requires project name to be a non-empty string value.');
// Since this is a user-provided value, the error is going to be logged
// and then checked by a validator so that the error can be passed to the
// user in a friendly way.
$this->logger->error('The Project Trait requires project name to be a non-empty string value.');
}

// Look up the project name to retrieve the project id number.
$project_rec = ChadoProjectAutocompleteController::getProjectId($project);

Expand All @@ -74,32 +72,35 @@ public function setProject(string|int $project) {
'name' => $project, // Name
];
}

if ($set_project['project_id'] <= 0 || empty($set_project['name'])) {

// @TODO: This is a user provided value, should be logged message
// and checked by a validator.

throw new \Exception('The Project Trait requires a project that exists in the database.');
// Check if $set_project is set before setting the context array, and log an
// error if the project can't be found in the database.
if ($set_project['project_id'] <= 0 || empty($set_project['name'])) {
// Since this is a user-provided value, the error is going to be logged
// and then checked by a validator so that the error can be passed to the
// user in a friendly way.
$this->logger->error('The Project Trait requires a project that exists in the database.');
}
else {
$this->context[$this->context_key] = $set_project;
}

$this->context[ $this->context_key ] = $set_project;
}

/**
* Returns a single project which has been verified to exist by the setter for use
* by a validator.
*
* @return array
* The project set by the setter method. The project includes the project id number
* The project set by the setter method. The project includes the project id number
* and project name keyed by project_id and name, respectively.
*
*
* @throws \Exception
* - If the 'project' key does not exist in the context array
* - If the 'project' key does not exist in the context array
* (ie. the project element has NOT been set).
*/
public function getProject() {

if (array_key_exists($this->context_key, $this->context)) {
return $this->context[ $this->context_key ];
}
Expand Down
Loading

0 comments on commit 535aa1d

Please sign in to comment.