Tags
Overview
The tagging feature allows a user to apply as many "tags" as they choose on any record they want to categorize. This allows the user to effectively group records together from any source within the application and relate them together. Please note that the tag
field and Tags module do not support customization at this time.
The Tags Module
The Tags module is a very simple module based on the Basic SugarObject
template. It is not studio editable, is part of the default module list, and is available to the application upon installation. By default, the Tags module is set up such that only an Administrator can perform any administrative tasks with the Tags module. In other words, a regular user will have a very restrictive set of permissions inside the Tags module, namely: create, export, view, and share. All other actions within the Tags modules must be carried out by an Administrative user.
The "tag" Field Type
The back end utilizes two new field types: the relatecollection
field and the tag field. The tag field is a relatecollection
type field with a few added enhancements specific to the tagging implementation:
- Enforces uniqueness of a tag when created
- Establishes the necessary relationship between the Tags module and the module record being tagged
- Collects and formats a tag collection in a way the client understands
- Format the tag field for consumption by and from the import process
- Handles proper query setting for a search that is filtered by tags
The Taggable Implementation
The taggable
implementation is applied to all SugarObject
templates so that it is available on all custom modules created and is also applied to all sidecar enabled modules. Any module that implements a SugarObject
template will be taggable by default. Any module that doesn't implement a SugarObject
template can easily apply it using the uses
property of the module vardefs:
$dictionary[$module] = array(
...
'uses' => array(
'taggable',
),
...
);
There may be instances where a module should not implement tagging
yet implements the SugarObject
template. To remove tagging from a module you can use the module vardefs ignore_templates
property:
$dictionary[$module] = array(
...
'ignore_templates' => array(
'taggable',
),
...
);
The Tagging Relationship Structure
The tagging
relationship schema is similar in nature to the email_addresses
relationship schema in that it is used to represent a collection of 0-N Tags module records related to a module:
Column | Description |
---|---|
id | The GUID for the relationship between the tag record and the module record |
tag_id | The id of the tag record used in this relationship |
bean_id | The id of the module record used in this relationship |
bean_module | The module for the record being tagged |
date_modified | The date the relationship was created/modified |
deleted | A tinyint(1) boolean value that indicates whether this relationship is deleted |
Tagging in Action
For adding tags from the UI, please refer to the Tags documentation.
Tagging Records from the API
Tagging a record via the API is done by sending a PUT request to the /<module>/<record> API endpoint with a tag property set to an array of key/value pairs that include a tag id (optional) and a tag name:
{
"name": "Record Name",
"tag": [
{"id": "Test Tag", "name": "Test Tag"},
{"name": "Test Tag 2"},
{"id": "1234-56-7890", "name": "Test Tag 3"}
]
}
After the record is created/modified and the tag values are applied, the response will contain the returned collection of tags for that record complete with their ids:
{
"name": "Record Name",
"tag": [
{"id": "9876-54-3210", "name": "Test Tag"},
{"id": "4321-56-0987", "name": "Test Tag 2"},
{"id": "1234-56-7890", "name": "Test Tag 3"}
]
}
You can visit How to Manipulate Tags (CRUD) for a full example demonstrating CRUD actions for tags.
Mass Updating Tags on Records Via the API
Mass updating records with tags are as simple as sending a MassUpdate PUT request to /<module>/MassUpdate
with a payload similar to:
{
"massupdate_params": {
"uid": ["12345-67890", "09876-54321"],
"tag": [
{ "id": "23456-78901", "name": "MyTag1" },
{ "id": "34567-89012", "name": "MyTag2" }
]
}
}
This request will override all existing tags on the named records. To append tags to a record, send the "tag_type" request argument set to a value of 1:
{
"massupdate_params": {
"uid": ["12345-67890", "09876-54321"],
"tag": [
{ "id": "23456-78901", "name": "MyTag1" },
{ "id": "34567-89012", "name": "MyTag2" }
],
"tag_type": "1"
}
}
More information on this API endpoint can be found in the /<module>/MassUpdate PUT documentation.
Fetching Tags on a Record
By default, the tag field is added to all Sidecar module record views. That means when a request is made for a single record through the API, that single record will return the "tag" field, which will be a collection of key:value pair objects.
For example, when a request is made to the /Accounts/:record GET endpoint, the tags associated with the Accountrecord will be returned in the tag field as an array of objects:
{
"id": "<record>",
"name": "Record Name",
"tag": [
{ "id": "9876-54-3210", "name": "Test Tag" },
{ "id": "4321-56-0987", "name": "Test Tag 2" },
{ "id": "1234-56-7890", "name": "Test Tag 3" }
]
}
Filtering a Record List by Tags
Filtering a list of records by tags can be done simply by sending a filter request to the ModuleApi endpoint for a module. For example, to filter the Accounts list where the tag field has a tag by the name of "Tradeshow", you can send a request to the /Accounts GET endpoint with the following request arguments:
{
"view": "list",
"filter": [
{
"tag": {
"$in": [
{
"name": "Tradeshow"
}
]
}
}
]
}
Currently, the tag field filter definitions support the following filter operators:
- Is any of ($in)
- Is not any of ($not_in)
- Is empty ($empty)
- Is not empty ($not_empty)
Fetching a list of Tags from the Tags module
Fetch a list of tag records from the Tags module is done the same way as fetch a list of records from any other module, namely by sending a GET request to the /Tags ModuleApi endpoint. More information can be found in the /<module> GET documentation.
Manipulating Tags Programmatically
Getting Tags Related to a Record
Here is an example that demonstrates how to get all the tags and its ids related to a contact record:
// Creating a Bean for Contacts
$bean = BeanFactory::getBean("Contacts");
// Creating a Bean for Tags
$tagBean = BeanFactory::newBean('Tags');
// Get all the tags related to Contacts Bean by givin Contact ID. You can provide more than one Record ID.
$tags = $tagBean->getRelatedModuleRecords($bean, ["<CONTACT_RECORD_ID>"]);
Creating a New Tag and Adding to a Record
Here is an example that demonstrates how to add create a tag and add to a contact record.
In order to add a new tag first, we will create the tag bean. Then using load_relationship function we will add the newly created tag id to the contacts
// Creating new Tag Bean
$tagBean = BeanFactory::newBean("Tags");
// Setting its name
$tagBean->name = "New Tag";
$tagBean->save();
// Retrieving the Contacts Bean
$bean = BeanFactory::getBean("Contacts", "<RECORD_ID>");
// Getting tag field and its properties
$tagField = $bean->getTagField();
$tagFieldProperties = $bean->field_defs[$tagField];
// Identifying relation link
$link = $tagFieldProperties['link'];
// Loading relationship
if ($bean->load_relationship($link)) {
// Adding newly created Tag Bean
$bean->$link->add($tagBean->id);
}
Removing Tags from a Record
Here is an example that demonstrates how to remove a tag from a contact record:
// Getting the Contacts Bean
$bean = BeanFactory::getBean("Contacts", "<RECORD_ID>");
// Getting tag field and its properties
$tagField = $bean->getTagField();
$tagFieldProperties = $bean->field_defs[$tagField];
// Identifying relation link
$link = $tagFieldProperties['link'];
// Loading relationship
if($bean->load_relationship($link)){
// Removing the Tag ID
$bean->$link->delete($bean->id, "<TAG_RECORD_ID>");
}
Synchronizing Tags by Name With API Helpers
If you have multiple tags that you need to add and delete at the same time, then you can use SugarFieldTag->apiSave
method. Here is an example that demonstrates how to sync tags by using SugarFieldTag
Class for a Contact record.
It is important to know that since this is a sync; you will need to keep the existing tags if you want them to still exist in the record.
// Getting the Contacts Bean
$bean = BeanFactory::getBean("Contacts", "<RECORD_ID>");
// Getting Tag Field ID
$tagField = $bean->getTagField();
// Getting Tag Field Properties
$tagFieldProperties = $bean->field_defs[$tagField];
// Preparing the latest Tags to be sync with the record
$tags = [
// Note: Already attached tags will be automatically removed from the record
// If you want to keep some of the existing tags then you will need to keep them in the array
"tag" => [
// Since this tag is already added, it will be preserved
'already added tag' => 'Already Added Tag',
// The new tags to add - All other tags that previously existed will be deleted
'new tag' => 'New Tag',
'new tag2' => 'New Tag2',
],
];
// Building SugarFieldTag instance
$SugarFieldTag = new SugarFieldTag();
// Passing the arguments to save the Tags
$SugarFieldTag->apiSave($bean, $tags, $tagField, $tagFieldProperties);