Skip to content

Commit

Permalink
Merge pull request #10441 from JMAConsulting/CRM-20621
Browse files Browse the repository at this point in the history
CRM-20621 : manage tags: the tag usage count is not accurate
  • Loading branch information
monishdeb authored Jun 17, 2017
2 parents bf55f23 + 5e3e44a commit 8229b3b
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 11 deletions.
33 changes: 22 additions & 11 deletions CRM/Admin/Page/AJAX.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,20 +304,24 @@ public static function getTagTree() {
$parent = CRM_Utils_Type::escape(CRM_Utils_Array::value('parent_id', $_GET, 0), 'Integer');
$result = array();

$parentClause = $parent ? "AND tag.parent_id = $parent" : 'AND tag.parent_id IS NULL';
$sql = "SELECT tag.*, child.id AS child, COUNT(et.id) as usages
FROM civicrm_tag tag
LEFT JOIN civicrm_entity_tag et ON et.tag_id = tag.id
LEFT JOIN civicrm_tag child ON child.parent_id = tag.id
WHERE tag.is_tagset <> 1 $parentClause
GROUP BY tag.id
ORDER BY tag.name";
$parentClause = $parent ? "AND parent_id = $parent" : 'AND parent_id IS NULL';
$sql = "SELECT *
FROM civicrm_tag
WHERE is_tagset <> 1 $parentClause
GROUP BY id
ORDER BY name";

// fetch all child tags in Array('parent_tag' => array('child_tag_1', 'child_tag_2', ...)) format
$childTagIDs = CRM_Core_BAO_Tag::getChildTags();

$dao = CRM_Core_DAO::executeQuery($sql);
while ($dao->fetch()) {
$style = '';
if ($dao->color) {
$style = "background-color: {$dao->color}; color: " . CRM_Utils_Color::getContrast($dao->color);
}
$hasChildTags = empty($childTagIDs[$dao->id]) ? FALSE : TRUE;
$usedFor = (array) explode(',', $dao->used_for);
$result[] = array(
'id' => $dao->id,
'text' => $dao->name,
Expand All @@ -330,18 +334,25 @@ public static function getTagTree() {
'style' => $style,
'class' => 'crm-tag-item',
),
'children' => (bool) $dao->child,
'children' => $hasChildTags,
'data' => array(
'description' => (string) $dao->description,
'is_selectable' => (bool) $dao->is_selectable,
'is_reserved' => (bool) $dao->is_reserved,
'used_for' => $dao->used_for ? explode(',', $dao->used_for) : array(),
'used_for' => $usedFor,
'color' => $dao->color ? $dao->color : '#ffffff',
'usages' => (int) $dao->usages,
'usages' => civicrm_api3('EntityTag', 'getcount', array(
'entity_table' => array('IN' => $usedFor),
'tag_id' => $dao->id,
)),
),
);
}

if (!empty($_REQUEST['is_unit_test'])) {
return $result;
}

CRM_Utils_JSON::output($result);
}

Expand Down
36 changes: 36 additions & 0 deletions CRM/Core/BAO/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -531,4 +531,40 @@ public static function getTagsNotInTagset() {
return $tags;
}

/**
* Get child tags IDs
*
* @return array $childTagIDs
* associated array of child tags in Array('Parent Tag ID' => Array('Child Tag 1', ...)) format
*/
public static function getChildTags() {
$childTagIDs = array();

// only fetch those tags which has child tags
$getChildGroupSQL = "SELECT parent.id as parent_id, GROUP_CONCAT(child.id) as child_id
FROM civicrm_tag parent,
civicrm_tag child
WHERE parent.is_tagset <> 1 AND child.parent_id = parent.id
GROUP BY parent.id
";
$dao = CRM_Core_DAO::executeQuery($getChildGroupSQL);
while ($dao->fetch()) {
$childTagIDs[$dao->parent_id] = (array) explode(',', $dao->child_id);
}

// check if child tag has any childs, if found then include those child tags inside parent tag
// i.e. format Array('parent_tag' => array('child_tag_1', ...), 'child_tag_1' => array(child_tag_1_1, ..), ..)
// to Array('parent_tag' => array('child_tag_1', 'child_tag_1_1'...), ..)
foreach ($childTagIDs as $parentTagID => $childTags) {
foreach ($childTags as $childTag) {
// if $childTag has any child tag of its own
if (array_key_exists($childTag, $childTagIDs)) {
$childTagIDs[$parentTagID] = array_merge($childTagIDs[$parentTagID], $childTagIDs[$childTag]);
}
}
}

return $childTagIDs;
}

}
83 changes: 83 additions & 0 deletions tests/phpunit/CRM/Contact/Page/AjaxTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,89 @@ public function testGetDedupesPostCode() {
$this->assertEquals(array('data' => array(), 'recordsTotal' => 0, 'recordsFiltered' => 0), $result);
}

/**
* CRM-20621 : Test to check usage count of Tag tree
*/
public function testGetTagTree() {
$contacts = array();
// create three contacts
for ($i = 0; $i < 3; $i++) {
$contacts[] = $this->individualCreate();
}

// Create Tag called as 'Parent Tag'
$parentTag = $this->tagCreate(array(
'name' => 'Parent Tag',
'used_for' => 'civicrm_contact',
));
//assign first contact to parent tag
$params = array(
'entity_id' => $contacts[0],
'entity_table' => 'civicrm_contact',
'tag_id' => $parentTag['id'],
);
// TODO: EntityTag.create API is not working
CRM_Core_BAO_EntityTag::add($params);

// Create child Tag of $parentTag
$childTag1 = $this->tagCreate(array(
'name' => 'Child Tag Level 1',
'parent_id' => $parentTag['id'],
'used_for' => 'civicrm_contact',
));
//assign contact to this level 1 child tag
$params = array(
'entity_id' => $contacts[1],
'entity_table' => 'civicrm_contact',
'tag_id' => $childTag1['id'],
);
CRM_Core_BAO_EntityTag::add($params);

// Create child Tag of $childTag1
$childTag2 = $this->tagCreate(array(
'name' => 'Child Tag Level 2',
'parent_id' => $childTag1['id'],
'used_for' => 'civicrm_contact',
));
//assign contact to this level 2 child tag
$params = array(
'entity_id' => $contacts[2],
'entity_table' => 'civicrm_contact',
'tag_id' => $childTag2['id'],
);
CRM_Core_BAO_EntityTag::add($params);

// CASE I : check the usage count of parent tag which need to be 1
// as the one contact added
$_REQUEST['is_unit_test'] = TRUE;
$parentTagTreeResult = CRM_Admin_Page_AJAX::getTagTree();
foreach ($parentTagTreeResult as $result) {
if ($result['id'] == $parentTag['id']) {
$this->assertEquals(1, $result['data']['usages']);
}
}

// CASE 2 : check the usage count of level 1 child tag, which needs to be 1
// as it should include the count of added one contact
$_GET['parent_id'] = $parentTag['id'];
$childTagTree = CRM_Admin_Page_AJAX::getTagTree();
$this->assertEquals(1, $childTagTree[0]['data']['usages']);

// CASE 2 : check the usage count of child tag at level 2
//which needs to be 1 as it has no child tag
$_GET['parent_id'] = $childTag1['id'];
$childTagTree = CRM_Admin_Page_AJAX::getTagTree();
$this->assertEquals(1, $childTagTree[0]['data']['usages']);

//cleanup
foreach ($contacts as $id) {
$this->callAPISuccess('Contact', 'delete', array('id' => $id));
}
$this->callAPISuccess('Tag', 'delete', array('id' => $childTag2['id']));
$this->callAPISuccess('Tag', 'delete', array('id' => $childTag1['id']));
$this->callAPISuccess('Tag', 'delete', array('id' => $parentTag['id']));
}

/**
* Test to check contact reference field
*/
Expand Down

0 comments on commit 8229b3b

Please sign in to comment.