From 6e80ee1152ed389121de68b8354eb877042de92e Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Fri, 15 Dec 2017 13:49:27 +0530 Subject: [PATCH] CRM-21563: Cannot search child tags on 'Manage Tag' page --- CRM/Admin/Page/AJAX.php | 96 +++++++++++++-------- CRM/Core/BAO/Tag.php | 22 +++-- templates/CRM/Tag/Page/Tag.tpl | 14 ++- tests/phpunit/CRM/Contact/Page/AjaxTest.php | 15 ++++ 4 files changed, 99 insertions(+), 48 deletions(-) diff --git a/CRM/Admin/Page/AJAX.php b/CRM/Admin/Page/AJAX.php index 1aa2d5c0ad..6a326c5904 100644 --- a/CRM/Admin/Page/AJAX.php +++ b/CRM/Admin/Page/AJAX.php @@ -302,51 +302,71 @@ class CRM_Admin_Page_AJAX { */ public static function getTagTree() { $parent = CRM_Utils_Type::escape(CRM_Utils_Array::value('parent_id', $_GET, 0), 'Integer'); + $substring = CRM_Utils_Type::escape(CRM_Utils_Array::value('str', $_GET), 'String'); $result = array(); - $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"; + $whereClauses = array( + 'is_tagset <> 1', + $parent ? "parent_id = $parent" : 'parent_id IS NULL', + ); // fetch all child tags in Array('parent_tag' => array('child_tag_1', 'child_tag_2', ...)) format - $childTagIDs = CRM_Core_BAO_Tag::getChildTags(); + $childTagIDs = CRM_Core_BAO_Tag::getChildTags($substring); + $parentIDs = array_keys($childTagIDs); + + if ($substring) { + $whereClauses['substring'] = " name LIKE '%$substring%' "; + if (!empty($parentIDs)) { + $whereClauses['substring'] = sprintf("( %s OR id IN (%s) )", $whereClauses['substring'], implode(',', $parentIDs)); + } + } + + $dao = CRM_Utils_SQL_Select::from('civicrm_tag') + ->where($whereClauses) + ->groupBy('id') + ->orderBy('name') + ->execute(); - $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); + if (!empty($substring)) { + $result[] = $dao->id; + if (!empty($childTagIDs[$dao->id])) { + $result = array_merge($result, $childTagIDs[$dao->id]); + } + } + else { + $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, + 'icon' => FALSE, + 'li_attr' => array( + 'title' => ((string) $dao->description) . ($dao->is_reserved ? ' (*' . ts('Reserved') . ')' : ''), + 'class' => $dao->is_reserved ? 'is-reserved' : '', + ), + 'a_attr' => array( + 'style' => $style, + 'class' => 'crm-tag-item', + ), + 'children' => $hasChildTags, + 'data' => array( + 'description' => (string) $dao->description, + 'is_selectable' => (bool) $dao->is_selectable, + 'is_reserved' => (bool) $dao->is_reserved, + 'used_for' => $usedFor, + 'color' => $dao->color ? $dao->color : '#ffffff', + 'usages' => civicrm_api3('EntityTag', 'getcount', array( + 'entity_table' => array('IN' => $usedFor), + 'tag_id' => $dao->id, + )), + ), + ); } - $hasChildTags = empty($childTagIDs[$dao->id]) ? FALSE : TRUE; - $usedFor = (array) explode(',', $dao->used_for); - $result[] = array( - 'id' => $dao->id, - 'text' => $dao->name, - 'icon' => FALSE, - 'li_attr' => array( - 'title' => ((string) $dao->description) . ($dao->is_reserved ? ' (*' . ts('Reserved') . ')' : ''), - 'class' => $dao->is_reserved ? 'is-reserved' : '', - ), - 'a_attr' => array( - 'style' => $style, - 'class' => 'crm-tag-item', - ), - 'children' => $hasChildTags, - 'data' => array( - 'description' => (string) $dao->description, - 'is_selectable' => (bool) $dao->is_selectable, - 'is_reserved' => (bool) $dao->is_reserved, - 'used_for' => $usedFor, - 'color' => $dao->color ? $dao->color : '#ffffff', - 'usages' => civicrm_api3('EntityTag', 'getcount', array( - 'entity_table' => array('IN' => $usedFor), - 'tag_id' => $dao->id, - )), - ), - ); } if (!empty($_REQUEST['is_unit_test'])) { diff --git a/CRM/Core/BAO/Tag.php b/CRM/Core/BAO/Tag.php index 51ab59370f..8303bc9135 100644 --- a/CRM/Core/BAO/Tag.php +++ b/CRM/Core/BAO/Tag.php @@ -551,20 +551,26 @@ class CRM_Core_BAO_Tag extends CRM_Core_DAO_Tag { /** * Get child tags IDs * + * @param string $searchString + * * @return array $childTagIDs * associated array of child tags in Array('Parent Tag ID' => Array('Child Tag 1', ...)) format */ - public static function getChildTags() { + public static function getChildTags($searchString = NULL) { $childTagIDs = array(); + $whereClauses = array('parent.is_tagset <> 1'); + if ($searchString) { + $whereClauses[] = " child.name LIKE '%$searchString%' "; + } + // 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); + $dao = CRM_Utils_SQL_Select::from('civicrm_tag parent') + ->join('child', 'INNER JOIN civicrm_tag child ON child.parent_id = parent.id ') + ->select('parent.id as parent_id, GROUP_CONCAT(child.id) as child_id') + ->where($whereClauses) + ->groupBy('parent.id') + ->execute(); while ($dao->fetch()) { $childTagIDs[$dao->parent_id] = (array) explode(',', $dao->child_id); } diff --git a/templates/CRM/Tag/Page/Tag.tpl b/templates/CRM/Tag/Page/Tag.tpl index ed4b5e41bc..58ff255bc9 100644 --- a/templates/CRM/Tag/Page/Tag.tpl +++ b/templates/CRM/Tag/Page/Tag.tpl @@ -243,6 +243,9 @@ .on('click', '.used-for-toggle', function() { $(this).attr('style', 'display: none !important;').next().show(); }) + .on('click', 'a.crm-clear-link', function() { + $('.tag-tree', $panel).jstree(true).refresh(); + }) .on('crmPopupFormSuccess crmFormSuccess', function(e, cts, data) { if ($(e.target).hasClass('tagset-action-delete')) { deleteTagset(); @@ -273,7 +276,9 @@ check_callback: true }, 'search': { - 'case_insensitive' : true, + 'ajax' : { + url : CRM.url('civicrm/ajax/tagTree') + }, 'show_only_matches': true }, plugins: plugins, @@ -283,7 +288,12 @@ }); $('input[name=filter_tag_tree]', $panel).on('keyup change', function() { - $(".tag-tree", $panel).jstree("search", $(this).val()); + if ($(this).val() == null) { + $('.tag-tree', $panel).jstree(true).refresh(); + } + else { + $(".tag-tree", $panel).jstree("search", $(this).val()); + } }); } diff --git a/tests/phpunit/CRM/Contact/Page/AjaxTest.php b/tests/phpunit/CRM/Contact/Page/AjaxTest.php index acc0eb8cfe..488fed60c3 100644 --- a/tests/phpunit/CRM/Contact/Page/AjaxTest.php +++ b/tests/phpunit/CRM/Contact/Page/AjaxTest.php @@ -284,6 +284,21 @@ class CRM_Contact_Page_AjaxTest extends CiviUnitTestCase { $childTagTree = CRM_Admin_Page_AJAX::getTagTree(); $this->assertEquals(1, $childTagTree[0]['data']['usages']); + // CASE 3 : check the tag IDs returned on searching with 'Level' + // which needs to array('parent tag id', 'level 1 child tag id', 'level 2 child tag id') + unset($_GET['parent_id']); + $_GET['str'] = 'Level'; + $tagIDs = CRM_Admin_Page_AJAX::getTagTree(); + $expectedTagIDs = array($parentTag['id'], $childTag1['id'], $childTag2['id']); + $this->checkArrayEquals($tagIDs, $expectedTagIDs); + + // CASE 4 : check the tag IDs returned on searching with 'Level 1' + // which needs to array('parent tag id', 'level 1 child tag id') + $_GET['str'] = 'Level 1'; + $tagIDs = CRM_Admin_Page_AJAX::getTagTree(); + $expectedTagIDs = array($parentTag['id'], $childTag1['id']); + $this->checkArrayEquals($tagIDs, $expectedTagIDs); + //cleanup foreach ($contacts as $id) { $this->callAPISuccess('Contact', 'delete', array('id' => $id)); -- 2.25.1