*/
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'])) {
/**
* 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);
}
.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();
check_callback: true
},
'search': {
- 'case_insensitive' : true,
+ 'ajax' : {
+ url : CRM.url('civicrm/ajax/tagTree')
+ },
'show_only_matches': true
},
plugins: plugins,
});
$('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());
+ }
});
}
$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));