Download & Extend

API: Get just term ID by name

Project:Drupal core
Version:8.x-dev
Component:taxonomy.module
Category:feature request
Priority:normal
Assigned:Unassigned
Status:needs review
Issue tags:API addition, Needs tests

Issue Summary

Taxonomy module provides the function taxonomy_get_term_by_name(), which lets you retrieve an array of term objects matching a given term name.

However, I've found several instances where I'm using either only one free-tagging vocabulary, a collection of hand-crafted vocabularies, where I know terms don't have repeats. And I'm only interested in grabbing the term ID of the first result so that I can monkey with it elsewhere in my script.

So here's a new function, taxonomy_get_tid_by_name()...

<?php
var_dump
(taxonomy_get_tid_by_name('Drupal project')); // Found, one result... returns that term's ID.
var_dump(taxonomy_get_tid_by_name('adsasdasd'));  // Not found... returns FALSE.
var_dump(taxonomy_get_tid_by_name('Modules')); // Found, two results... returns the *first* term's ID.
?>
AttachmentSizeStatusTest resultOperations
taxonomy_get_tid_by_name.patch1.11 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch taxonomy_get_tid_by_name.patch. See the log in the details link for more information.View details | Re-test

Comments

#1

Status:needs review» needs work

A look and me thinks there is a parse error, single quote at beg.

<?php
db_rewrite_sql
('SELECT t.tid FROM {term_data} t WHERE LOWER('%s') LIKE LOWER(t.name)", 't', 'tid')
?>

#2

Status:needs work» needs review

D'oh!! wrong patch. :( Thanks.

AttachmentSizeStatusTest resultOperations
taxonomy_get_tid_by_name_0.patch1.11 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch taxonomy_get_tid_by_name_0.patch. See the log in the details link for more information.View details | Re-test

#3

Version:6.x-dev» 7.x-dev

Thsi still applies with offset. Does it count as a performance improvement? Bumping to drupal 7 since it's marke as a feature anyway.

#4

This patch still applies. If it seems worthwhile, I could write up a test or two for this.

#5

I often need to do the same, and I like this. However, there are times where I only want the tids, but from any matching term. Weighing that with the possibly confusing function naming where both are singular (get_term and get_tid) and have complementary functions, yet the first returns multiple results and the latter returns only a single result, what about ..

taxonomy_get_terms_by_name($name, $limit = NULL)
and
taxonomy_get_tids_by_name($name, $limit = NULL)

Where if limit is NULL all results are returned, but if limit is specified that limit is applied to the query.

$term = taxonomy_get_terms_by_name('Drupal', 1) results in one term object
$tid = taxonomy_get_tids_by_name('Drupal', 1) results in one tid

#6

Status:needs review» needs work

Needs a re-roll for dbtng.

#7

Version:7.x-dev» 8.x-dev

#8

Hi, Will this function be possible in Drupal 6?
Otherwise, how can I get from termname to TID?
Thanks a lot for your reply in advance!
greetings, Martijn

#9

Status:needs work» needs review

Not sure if this is still desired, but re-rolled for dbtng anyway.

For the case mentioned in comment 5 I would say using taxonomy_term_load_multiple(), an EntityFieldQuery or a manual query would be OK.

AttachmentSizeStatusTest resultOperations
0001-Issue-143817-by-webchick-marvil07-Added-API-Get-just.patch1.41 KBIdlePASSED: [[SimpleTest]]: [MySQL] 33,642 pass(es).View details | Re-test

#10

Status:needs review» needs work

Oh man, when I think of all the overhead of all the term objects I load unnecessarily... +1 for this addition or something like it. I think there are also some related issues open about other taxonomy API functions.

Do we want to statically cache inside this function since we're not using the entity caching anymore?

+++ b/modules/taxonomy/taxonomy.moduleundefined
@@ -1072,6 +1072,28 @@ function taxonomy_get_term_by_name($name) {
+ * @return
+ *   The term ID of the given term, or FALSE if none was found.

Minor point, but we need a blank line above @return.

+++ b/modules/taxonomy/taxonomy.moduleundefined
@@ -1072,6 +1072,28 @@ function taxonomy_get_term_by_name($name) {
+
+
+/**

I think there's an extra linebreak here, too. :)

And, of course, the patch needs to be rerolled now.

#11

Status:needs work» needs review

Not sure about a static cache there.

Formatting errors fixed here(it rebased cleanly noticing the renaming, git++).

AttachmentSizeStatusTest resultOperations
0001-Issue-143817-by-webchick-marvil07-Added-API-Get-just.patch1.43 KBIdlePASSED: [[SimpleTest]]: [MySQL] 33,765 pass(es).View details | Re-test

#12

Cross-referencing #336697: Optional vid argument for taxonomy_get_term_by_name(). That arg would be desirable for this helper as well.

I think static caching so the query isn't run repeatedly would be a good idea. That's one reason to have this helper in core rather than just leaving it to taxonomy-dependent contrib to add their own helpers.

#13

Thanks for the suggestions.

I was not sure about which optional parameter to provide: vid or a vocabulary_machine_name, so I provided both.

This patch also adds static cache to the function results.

AttachmentSizeStatusTest resultOperations
0001-Issue-143817-by-webchick-marvil07-Added-API-Get-just.patch2.48 KBIdlePASSED: [[SimpleTest]]: [MySQL] 33,800 pass(es).View details | Re-test

#14

I would like to raise a problem here. May look minor to you.

Guessing if a parameter is either one thing or another thing is a bad practise. The initial task webchick described was of that kind. In the latest added patch, you try to guess if the parameter $vocabulary is an ID (= int) or a vocabulary name (= string).

A quick test in D7 showed me that you actually are not prevented from giving vocabularies INT looking internal names a "4444" went right through it and now the link looks like this admin/structure/taxonomy/4444/add. I cannot tell if that is an vid or a vocabulary_name.

You have either to make sure (accross drupal) that internal unique names follow the same rules as variables in PHP or someone will break your system, because he can.

I can tell you that this is a big problem. In Magento for example there is a CORE helper function which loads a product by either SKU (= alphanumerical) or ProductID (= int).

Small excurse:

<?php
   
/**
     * Return loaded product instance
     *
     * @param  int|string $productId (SKU or ID)
     * @param  int $store
     * @param  string $identifierType
     * @return Mage_Catalog_Model_Product
     */
   
public function getProduct($productId, $store, $identifierType = null)
    {
       
/** @var $product Mage_Catalog_Model_Product */
       
$product = Mage::getModel('catalog/product')->setStoreId(Mage::app()->getStore($store)->getId());

       
$expectedIdType = false;
        if (
$identifierType === null) {
            if (
is_string($productId) && !preg_match("/^[+-]?[1-9][0-9]*$|^0$/", $productId)) {
               
$expectedIdType = 'sku';
            }
        }

        if (
$identifierType == 'sku' || $expectedIdType == 'sku') {
           
$idBySku = $product->getIdBySku($productId);
            if (
$idBySku) {
               
$productId = $idBySku;
            } else if (
$identifierType == 'sku') {
               
// Return empty product because it was not found by originally specified SKU identifier
               
return $product;
            }
        }

        if (
$productId && is_numeric($productId)) {
           
$product->load((int) $productId);
        }

        return
$product;
    }
?>

They are trying to guess what is used by RegEx. Well our company uses numeric SKUs for like 15 years and we cannot use the SOAP API because for loading prodcucts the core uses this function.

Back to Drupal. I could "break" your code by taxonomy_get_tid_by_name('something', intval('4444')); (Try to imaging I'm someone who has only numeric internal uniquenames just because another external data system has the same IDs for tagging and it makes it easier for me to have them matched)

Btw. why using a "LIKE" when a ->condition('t.name', trim(strtolower($name))) could be better. LIKE indicated also guessing. I mean the whole function was initial like guessing, but that is not something I expect from core.

#15

Oh, I see this is from 2007. I have no idea why this caught my attention. I guess that is outdated anyway.

nobody click here