From e09ed9c70a7dfeb47fed97d9b0e9456aae2164f1 Mon Sep 17 00:00:00 2001
From: Felip Manyer i Ballester <git@res-telae.cat>
Date: Tue, 9 Feb 2021 11:36:57 +0100
Subject: [PATCH] Name usage

---
 README.md       |  31 ++++++++++
 src/Species.php | 154 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 183 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 18eef36..063599d 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,37 @@ $species->nameLookup(['q' => 'mammalia', 'limit' => 1]);
 $species->nameLookup(['q' => 'mammalia', 'limit' => 1, 'offset' => 2]);
 ```
 
+#### Lookup details for specific names in all taxonomies in GBIF
+
+Lookup details for specific names:
+
+```
+<?php
+
+use ResTelae\Gbif\Species;
+
+$species = new Species();
+
+// All data for species #1;
+$species->nameUsage([], 'all', 1]);
+
+// Name usage for a taxonomic name.
+$species->nameUsage(['name' => 'Puma', rank' => 'GENUS'])
+```
+
+Lookup for a specific taxon name, knowing its key:
+
+```
+<?php
+
+use ResTelae\Gbif\Species;
+
+$species = new Species();
+
+// All data for species #2435099;
+$species->nameUsage(2435099]);
+```
+
 #### Name suggestions (autocomplete service)
 
 A quick and simple autocomplete service that returns up to 20 name usages by doing prefix matching against the scientific name. Results are ordered by relevance.
diff --git a/src/Species.php b/src/Species.php
index f104879..15c05e8 100644
--- a/src/Species.php
+++ b/src/Species.php
@@ -7,6 +7,156 @@ namespace ResTelae\Gbif;
  */
 class Species extends Gbif {
 
+  /**
+   * Lookup details for specific names in all taxonomies in GBIF.
+   *
+   * Usage:
+   * @code
+   *   use ResTelae\Gbif\Species;
+   *
+   *   $species = new Species();
+   *
+   *   // All data for species #1;
+   *   $species->nameUsage([], 'all', 1]);
+   *
+   *   // Name usage for a taxonomic name.
+   *   $species->nameUsage(['name' => 'Puma', rank' => 'GENUS'])
+   *
+   *   // All name usages.
+   *   $species->nameUsage();
+   *
+   *   // References for a name usage.
+   *   $species->nameUsage([], 'references', 2435099);
+   *
+   *   // Species profiles, descriptions.
+   *   $species->nameUsage([], 'speciesProfiles', 3119195);
+   *   $species->nameUsage([], 'descriptions', 3119195);
+   *   $species->nameUsage([], 'children', 2435099);
+   *
+   *   // Vernacular names for a name usage.
+   *   $species->nameUsage([], 'vernacularNames', 3119195);
+   *
+   *   // Limit number of results returned.
+   *   $species->nameUsage(['limit' => 3], 'vernacularNames', 3119195);
+   *
+   *   // Search for names by dataset with datasetKey parameter.
+   *   $species->nameUsage('[
+   *     datasetKey' => 'd7dddbf4-2cf0-4f39-9b2a-bb099caae36c',
+   *   ]);
+   *
+   *   // Search for a particular language.
+   *   $species->nameUsage(['language' => 'FRENCH'], 'vernacularNames', 3119195);
+   * @endcode
+   *
+   * @param array $args
+   *   An associative array, with the following elements:
+   *   - 'name' (string): filters by a case insensitive, canonical namestring,
+   *     e.g. 'Puma concolor'.
+   *   - 'language' (string): language, default is English.
+   *   - 'datasetKey' (string): filters by the dataset's key (a uuid).
+   *   - 'sourceId' (integer): filters by the source identifier.
+   *   - 'rank' (string): taxonomic rank. Filters by taxonomic rank as one of:
+   *     'CLASS', 'CULTIVAR', 'CULTIVAR_GROUP', 'DOMAIN', 'FAMILY', 'FORM',
+   *     'GENUS', 'INFORMAL', 'INFRAGENERIC_NAME', 'INFRAORDER',
+   *     'INFRASPECIFIC_NAME', 'INFRASUBSPECIFIC_NAME', 'KINGDOM', 'ORDER',
+   *     'PHYLUM', 'SECTION', 'SERIES', 'SPECIES', 'STRAIN', 'SUBCLASS',
+   *     'SUBFAMILY', 'SUBFORM', 'SUBGENUS', 'SUBKINGDOM', 'SUBORDER',
+   *     'SUBPHYLUM', 'SUBSECTION', 'SUBSERIES', 'SUBSPECIES', 'SUBTRIBE',
+   *     'SUBVARIETY', 'SUPERCLASS', 'SUPERFAMILY', 'SUPERORDER', 'SUPERPHYLUM',
+   *     'SUPRAGENERIC_NAME', 'TRIBE', 'UNRANKED', 'VARIETY'.
+   *   - 'limit' (integer): number of records to return. Default: 100. Maximum:
+   *     1000 (optional).
+   *   - 'offset' (integer): record number to start at (optional).
+   * @param string $data
+   *   The type of data to get. Default: 'all'. Options: 'all', 'verbatim',
+   *   'name', 'parents', 'children', 'related', 'synonyms', 'descriptions',
+   *   'distributions', 'media', 'references', 'speciesProfiles',
+   *   'vernacularNames', 'typeSpecimens', 'root'.
+   * @param int $key
+   *   A GBIF key for a taxon.
+   * @param string $uuid
+   *   A uuid for a dataset. Should give exact same results as datasetKey. Only
+   *   relevant when $data is 'root'.
+   * @param string $short_name
+   *   A short name. Only relevant when data is 'root', in which case either
+   *   $uuid or $short_name must be set. Taken into account if $uuid is NULL.
+   *
+   * @return array
+   *   An array of results.
+   *
+   * @see http://www.gbif.org/developer/species#nameUsages
+   */
+  public function nameUsage(array $args = [], $data = 'all', $key = NULL, $uuid = NULL, $short_name = NULL) {
+    // Default values.
+    $args += [
+      'limit' => 100,
+    ];
+
+    $data_choices = [
+      'all',
+      'verbatim',
+      'name',
+      'parents',
+      'children',
+      'related',
+      'synonyms',
+      'descriptions',
+      'distributions',
+      'media',
+      'references',
+      'speciesProfiles',
+      'vernacularNames',
+      'typeSpecimens',
+      'root',
+    ];
+
+    if (!in_array($data, $data_choices)) {
+      // TODO: raise exception.
+    }
+
+    if ($data != 'all' && !$key) {
+      // TODO: raise exception.
+    }
+
+    if ($data == 'all') {
+      $uri = $key ? 'species/' . $key : 'species';
+    }
+    elseif ($data == 'root') {
+      if (!$uuid && !$short_name) {
+        // TODO: raise exception.
+      }
+      $uri = $uuid ? 'species/' . $uuid : 'species/' . $short_name;
+    }
+    else {
+      $uri = 'species/' . $key . '/' . $data;
+    }
+
+    return $this->gbifGet($uri, $args);
+  }
+
+  /**
+   * Lookup for a specific taxon name.
+   *
+   * Usage:
+   * @code
+   *   use ResTelae\Gbif\Species;
+   *
+   *   $species = new Species();
+   *
+   *   // All data for species #2435099;
+   *   $species->nameUsage(2435099]);
+   * @endcode
+   *
+   * @param int $key
+   *   A GBIF key for a taxon.
+   *
+   * @return array
+   *   An array of results.
+   */
+  public function nameUsageByKey($key) {
+    return $this->nameUsage([], 'all', $key);
+  }
+
   /**
    * Lookup names in the GBIF backbone taxonomy.
    *
@@ -24,8 +174,6 @@ class Species extends Gbif {
    * If you don't get a match GBIF gives back a list of length 3 with slots
    * synonym, confidence, and ``matchType='NONE'``.
    *
-   * Reference: https://www.gbif.org/developer/species#searching
-   *
    * Usage:
    * @code
    *   use ResTelae\Gbif\Species;
@@ -100,6 +248,8 @@ class Species extends Gbif {
    *
    * @return array
    *   An array of results.
+   *
+   * @see https://www.gbif.org/developer/species#searching
    */
   public function nameBackbone(array $args) {
     if (isset($args['strict'])) {
-- 
GitLab