Skip to content

Commit

Permalink
Merge pull request #1585 from tripal/tv4g2-1571-cvtermAutocompleteFilter
Browse files Browse the repository at this point in the history
Cvterm autocomplete needs filter by cv
  • Loading branch information
laceysanderson committed Aug 10, 2023
2 parents 89adb84 + 40df178 commit a9d3aba
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 206 deletions.
114 changes: 74 additions & 40 deletions tripal_chado/src/Controller/ChadoCVTermAutocompleteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,61 @@
*/
class ChadoCVTermAutocompleteController extends ControllerBase {
/**
* Contoller method, autocomplete cvterm name.
*
* Controller method, autocomplete cvterm name.
*
* @param Request request
* @param int $cv
* @TODO: Limit the match of term to a CV.
*
* @param int $count
* Desired number of matching names to suggest.
* Default to 5 items.
*
* Zero will disable autocomplete.
*
* @param int $cv_id
* Limit the match of term to the CV with this cv_id.
* Zero, the default, will return matches to any CV.
*
* @return Json Object
* Matching cvterm rows where each row is formatted as string:
* cvterm.name (db.name:dbxref.accession) and is the value for
* the object keys label and value.
*/
public function handleAutocomplete(Request $request, int $count = 5) {
public function handleAutocomplete(Request $request, int $count = 5, int $cv_id = 0) {
// Array to hold matching cvterm names.
$response = [];

if ($request->query->get('q')) {
// Get typed in string input from the URL.
$string = trim($request->query->get('q'));

if (strlen($string) > 0 && $count > 0) {
// Proceed to autocomplete when string is at least a character
// long and result count is set to a value greater than 0.

// Transform string as a search keyword pattern.
$keyword = '%' . strtolower($string) . '%';
// Transform string as a case-insensitive search keyword pattern.
$keyword = strtolower($string) . '%';

// Query cvterm (joins: dbxref - accession and db - dn name) for names matching
// the keyword pattern and return each row in the format specified.
// Query cvterm (joins: dbxref - accession and db - dn name) for names matching
// the keyword pattern and return each row in the format specified.
// Tables indicate schema sequence number #1 to use default schema.
$sql = sprintf("
$sql = "
SELECT ct.name AS term, db.name AS dbname, dx.accession
FROM {1:cvterm} AS ct
LEFT JOIN {1:dbxref} AS dx USING(dbxref_id)
FROM {1:cvterm} AS ct
LEFT JOIN {1:dbxref} AS dx USING(dbxref_id)
LEFT JOIN {1:db} USING(db_id)
WHERE LOWER(ct.name) LIKE :keyword ORDER BY ct.name ASC LIMIT %d
", $count);
WHERE LOWER(ct.name) LIKE :keyword";
$args = [':keyword' => $keyword, ':limit' => $count];
// Limit terms to selected CV when this is specified.
if ($cv_id) {
$sql .= " AND ct.cv_id = :cv_id";
$args[':cv_id'] = $cv_id;
}
$sql .= " ORDER BY ct.name ASC LIMIT :limit";

// Prepare Chado database connection and execute sql query by providing value
// Prepare Chado database connection and execute sql query by providing value
// for :keyword placeholder text.
$connection = \Drupal::service('tripal_chado.database');
$results = $connection->query($sql, [':keyword' => $keyword]);
$results = $connection->query($sql, $args);

// Compose response result.
if ($results) {
foreach ($results as $record) {
Expand All @@ -68,65 +78,89 @@ public function handleAutocomplete(Request $request, int $count = 5) {
}
}
}

return new JsonResponse($response);
}

/**
* Fetch the cvterm.cvterm_id given a cvterm name (db.name:dbxref.accession)
* value returned by the handler method above.
*
*
* @param string $term
* String value returned by authocomplete handler method.
*
* String value returned by autocomplete handler method.
*
* @param string $cv_name
* Optional name of a controlled vocabulary. Can be used if user
* bypassed autocomplete and entered just a CV term name manually.
*
* @return integer
* Id number corresponding to chado.cvterm_id field of the matching term
* or 0 if no match was found.
*/
public static function getCVtermId(string $term): int {
public static function getCVtermId(string $term, $cv_name = ''): int {
$id = 0;

if (strlen($term) > 0) {
$sql = "
SELECT ct.cvterm_id FROM {1:cvterm} AS ct
LEFT JOIN {1:dbxref} AS dx USING(dbxref_id)
SELECT ct.cvterm_id FROM {1:cvterm} AS ct
LEFT JOIN {1:dbxref} AS dx USING(dbxref_id)
LEFT JOIN {1:db} USING(db_id)
WHERE CONCAT(ct.name, ' (', db.name, ':', dx.accession, ')') = :term
LIMIT 1
";

$connection = \Drupal::service('tripal_chado.database');
$result = $connection->query($sql, [':term' => $term]);
$result = $connection
->query($sql, [':term' => $term])
->fetchAll();

if($result) {
$id = $result->fetchField();
if(count($result) == 1) {
$id = $result[0]->cvterm_id;
}
}

// If no match, and if a disambiguating CV was specified,
// try again using only that CV. This happens if the user
// types in the term and doesn't let the autocomplete
// append the (DB:accession).
else if ($cv_name) {
$sql = "
SELECT ct.cvterm_id FROM {1:cvterm} AS ct
LEFT JOIN {1:cv} AS cv USING(cv_id)
WHERE ct.name = :term AND cv.name = :cvname
";

$result = $connection
->query($sql, [':term' => $term, ':cvname' => $cv_name])
->fetchAll();

if(count($result) == 1) {
$id = $result[0]->cvterm_id;
}
}
}
return $id;
}

/**
* Given a cvterm id number, return the matching cvterm record using
* the format cvterm name (db.name:dbxref.accession).
*
*
* @param integer $id
* Cvterm id number to match.
*
*
* @return string
* Cvterm record in cvterm name (db.name:dbxref.accession) format.
*/
public static function formatCVterm(int $id) {
$term = null;

if ($id > 0) {
$sql = "
SELECT CONCAT(ct.name, ' (', db.name, ':', dx.accession, ')')
FROM {1:cvterm} AS ct
LEFT JOIN {1:dbxref} AS dx USING(dbxref_id)
SELECT CONCAT(ct.name, ' (', db.name, ':', dx.accession, ')')
FROM {1:cvterm} AS ct
LEFT JOIN {1:dbxref} AS dx USING(dbxref_id)
LEFT JOIN {1:db} USING(db_id)
WHERE ct.cvterm_id = :cvterm_id
LIMIT 1
LIMIT 1
";

$connection = \Drupal::service('tripal_chado.database');
Expand Down
38 changes: 20 additions & 18 deletions tripal_chado/src/Controller/ChadoProjectAutocompleteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@
class ChadoProjectAutocompleteController extends ControllerBase {
/**
* Controller method, autocomplete project name.
*
*
* @param Request request
* @param int $type_id
* Project type set in projectprop.type_id to restrict projects to specific type.
* Default to 0, return projects regardless of type.
* Must be declared in autocomplete route parameter ie. ['type_id' => 0].
*
* @param int $count
* Desired number of matching names to suggest.
* Default to 5 items.
* Must be declared in autocomplete route parameter ie. [count => 5].
*
* Must be declared in autocomplete route parameter i.e. ['count' => 5].
*
* @param int $type_id
* Project type set in projectprop.type_id to restrict projects to specific type.
* Default to 0, return projects regardless of type.
* Must be declared in autocomplete route parameter i.e. ['type_id' => 0].
*
* @return Json Object
* Matching project rows in an array where project name
* is both the value to the array keys label and value.
*/
public function handleAutocomplete(Request $request, int $type_id = 0, int $count = 5) {
public function handleAutocomplete(Request $request, int $count = 5, int $type_id = 0) {
// Array to hold matching project records.
$response = [];

Expand All @@ -40,7 +42,7 @@ public function handleAutocomplete(Request $request, int $type_id = 0, int $coun
// long and result count is set to a value greater than 0.

// Transform string as a search keyword pattern.
$keyword = '%' . strtolower($string) . '%';
$keyword = strtolower($string) . '%';

if ($type_id > 0) {
// Restrict to type provided by type_id in the route parameter.
Expand All @@ -54,7 +56,7 @@ public function handleAutocomplete(Request $request, int $type_id = 0, int $coun
$args = [':keyword' => $keyword];
}

// Prepare Chado database connection and execute sql query by providing value
// Prepare Chado database connection and execute sql query by providing value
// to :keyword and/or :type_id placeholder text.
$connection = \Drupal::service('tripal_chado.database');
$query = sprintf($sql, $count);
Expand All @@ -69,18 +71,18 @@ public function handleAutocomplete(Request $request, int $type_id = 0, int $coun
];
}
}
}
}
}

return new JsonResponse($response);
}

/**
* Fetch the project id number, given a project name value.
*
*
* @param string $project
* Project name value.
*
*
* @return integer
* Project id number of the project name or 0 if no matching
* project record was found.
Expand All @@ -104,12 +106,12 @@ public static function getProjectId(string $project): int {

/**
* Fetch the project name, given a project id number.
*
*
* @param int $project
* Project id number value.
*
*
* @return string
* Corresponding project name of the project id number or
* Corresponding project name of the project id number or
* empty string if no matching project record was found.
*/
public static function getProjectName(int $project): string {
Expand All @@ -128,4 +130,4 @@ public static function getProjectName(int $project): string {

return $name;
}
}
}

0 comments on commit a9d3aba

Please sign in to comment.