Commit 408f13a5 authored by colemanw's avatar colemanw

Merge pull request #3070 from colemanw/tagset

CRM-13966 - Switch to entityRef for tagsets
parents 821d46b7 f326916f
......@@ -466,7 +466,7 @@ class CRM_Activity_BAO_Query {
}
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_activity');
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_activity', NULL, TRUE, FALSE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_activity', NULL, TRUE, TRUE);
$surveys = CRM_Campaign_BAO_Survey::getSurveys(TRUE, FALSE, FALSE, TRUE);
if ($surveys) $form->add('select', 'activity_survey_id', ts('Survey / Petition'),
......
......@@ -121,6 +121,8 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task {
protected $_values = array();
protected $unsavedWarn = TRUE;
/**
* The _fields var can be used by sub class to set/unset/edit the
* form fields based on their requirement
......@@ -726,7 +728,7 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task {
if (!in_array($this->_activityTypeName, $specialActivities)) {
// build tag widget
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_activity');
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', $this->_activityId, TRUE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', $this->_activityId);
}
// if we're viewing, we're assigning different buttons than for adding/editing
......
......@@ -67,7 +67,7 @@ class CRM_Activity_Form_Task_RemoveFromTag extends CRM_Activity_Form_Task {
}
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_activity');
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', NULL, TRUE, FALSE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', NULL, TRUE, FALSE);
$this->addDefaultButtons(ts('Remove Tags from activities'));
}
......
......@@ -252,44 +252,6 @@ class CRM_Admin_Page_AJAX {
CRM_Core_Page_AJAX::returnJsonResponse($ret);
}
static function getTagList() {
$name = CRM_Utils_Type::escape($_GET['name'], 'String');
$parentId = CRM_Utils_Type::escape($_GET['parentId'], 'Integer');
$isSearch = NULL;
if (isset($_GET['search'])) {
$isSearch = CRM_Utils_Type::escape($_GET['search'], 'Integer');
}
$tags = array();
// always add current search term as possible tag
// here we append :::value to determine if existing / new tag should be created
if (!$isSearch) {
$tags[] = array(
'name' => $name,
'id' => $name . ":::value",
);
}
$query = "SELECT id, name FROM civicrm_tag WHERE parent_id = {$parentId} and name LIKE '%{$name}%'";
$dao = CRM_Core_DAO::executeQuery($query);
while ($dao->fetch()) {
// make sure we return tag name entered by user only if it does not exists in db
if ($name == $dao->name) {
$tags = array();
}
// escape double quotes, which break results js
$tags[] = array('name' => addcslashes($dao->name, '"'),
'id' => $dao->id,
);
}
echo json_encode($tags);
CRM_Utils_System::civiExit();
}
static function mergeTagList() {
$name = CRM_Utils_Type::escape($_GET['term'], 'String');
$fromId = CRM_Utils_Type::escape($_GET['fromId'], 'Integer');
......@@ -339,92 +301,6 @@ LIMIT $limit";
CRM_Utils_System::civiExit();
}
static function processTags() {
$skipTagCreate = $skipEntityAction = $entityId = NULL;
$action = CRM_Utils_Type::escape($_POST['action'], 'String');
$parentId = CRM_Utils_Type::escape($_POST['parentId'], 'Integer');
if ($_POST['entityId']) {
$entityId = CRM_Utils_Type::escape($_POST['entityId'], 'Integer');
}
$entityTable = CRM_Utils_Type::escape($_POST['entityTable'], 'String');
if ($_POST['skipTagCreate']) {
$skipTagCreate = CRM_Utils_Type::escape($_POST['skipTagCreate'], 'Integer');
}
if ($_POST['skipEntityAction']) {
$skipEntityAction = CRM_Utils_Type::escape($_POST['skipEntityAction'], 'Integer');
}
// check if user has selected existing tag or is creating new tag
// this is done to allow numeric tags etc.
$tagValue = explode(':::', $_POST['tagID']);
$createNewTag = FALSE;
$tagID = $tagValue[0];
if (isset($tagValue[1]) && $tagValue[1] == 'value') {
$createNewTag = TRUE;
}
$tagInfo = array();
// if action is select
if ($action == 'select') {
// check the value of tagID
// if numeric that means existing tag
// else create new tag
if (!$skipTagCreate && $createNewTag) {
$params = array(
'name' => $tagID,
'parent_id' => $parentId,
);
$tagObject = CRM_Core_BAO_Tag::add($params, CRM_Core_DAO::$_nullArray);
$tagInfo = array(
'name' => $tagID,
'id' => $tagObject->id,
'action' => $action,
);
$tagID = $tagObject->id;
}
if (!$skipEntityAction && $entityId) {
// save this tag to contact
$params = array(
'entity_table' => $entityTable,
'entity_id' => $entityId,
'tag_id' => $tagID,
);
CRM_Core_BAO_EntityTag::add($params);
}
// if action is delete
}
elseif ($action == 'delete') {
if (!is_numeric($tagID)) {
$tagID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $tagID, 'id', 'name');
}
if (!$skipEntityAction && $entityId) {
// delete this tag entry for the entity
$params = array(
'entity_table' => $entityTable,
'entity_id' => $entityId,
'tag_id' => $tagID,
);
CRM_Core_BAO_EntityTag::del($params);
}
$tagInfo = array(
'id' => $tagID,
'action' => $action,
);
}
echo json_encode($tagInfo);
CRM_Utils_System::civiExit();
}
function mappingList() {
$params = array('mappingID');
foreach ($params as $param) {
......
......@@ -711,7 +711,7 @@ case_relation_type.id = case_relationship.relationship_type_id )";
}
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_case');
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_case', NULL, TRUE, FALSE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_case', NULL, TRUE, FALSE);
if (CRM_Core_Permission::check('administer CiviCRM')) {
$form->addElement('checkbox', 'case_deleted', ts('Deleted Cases'));
......
......@@ -275,7 +275,7 @@ class CRM_Case_Form_Case extends CRM_Core_Form {
// build tag widget
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_case');
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', NULL, TRUE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', NULL, FALSE, TRUE);
$this->addButtons(array(
array(
......
......@@ -436,7 +436,7 @@ class CRM_Case_Form_CaseView extends CRM_Core_Form {
else {
$this->assign('showTagsets', FALSE);
}
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', $this->_caseID, TRUE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', $this->_caseID, FALSE, TRUE);
$this->addButtons(array(
array(
......
......@@ -78,7 +78,7 @@ class CRM_Contact_Form_Search_Criteria {
}
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_contact');
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_contact', NULL, TRUE, FALSE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_contact', NULL, TRUE, FALSE);
$used_for = CRM_Core_OptionGroup::values('tag_used_for');
$tagsTypes = array();
......
......@@ -67,7 +67,7 @@ class CRM_Contact_Form_Task_RemoveFromTag extends CRM_Contact_Form_Task {
}
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_contact');
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_contact', NULL, TRUE, FALSE, TRUE);
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_contact', NULL, TRUE, FALSE);
$this->addDefaultButtons(ts('Remove Tags from Contacts'));
}
......
......@@ -383,17 +383,15 @@
'maxfilesize',
$maxFileSize * 1024 * 1024
);
$form->addElement('text', "attachDesc_$i", ts('Description'), 'size=40 maxlength=255');
$form->addElement('text', "attachDesc_$i", NULL, array('size' => 40, 'maxlength' => 255, 'placeholder' => ts('Description')));
if (!empty($tags)) {
$form->add('select', "tag_$i", ts('Tags'), $tags, FALSE,
array('id' => "tags_$i", 'multiple' => 'multiple', 'class' => 'crm-select2')
array('id' => "tags_$i", 'multiple' => 'multiple', 'class' => 'huge crm-select2', 'placeholder' => ts('- none -'))
);
}
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_file', NULL, FALSE, TRUE, "file_taglist_$i");
}
// build tagset widget
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_file', NULL, TRUE, TRUE, FALSE);
}
/**
......@@ -444,7 +442,7 @@
$attachName = "attachFile_$i";
$attachDesc = "attachDesc_$i";
$attachTags = "tag_$i";
$attachFreeTags = "attachment_taglist_$i";
$attachFreeTags = "file_taglist_$i";
if (isset($formValues[$attachName]) && !empty($formValues[$attachName])) {
// add static tags if selects
$tagParams = array();
......
......@@ -43,8 +43,8 @@ class CRM_Core_Form_Tag {
/**
* Function to build tag widget if correct parent is passed
*
* @param object $form form object
* @param string $parentName parent name ( tag name)
* @param CRM_Core_Form $form form object
* @param string $parentNames parent name ( tag name)
* @param string $entityTable entitytable 'eg: civicrm_contact'
* @param int $entityId entityid 'eg: contact id'
* @param boolean $skipTagCreate true if tag need be created using ajax
......@@ -57,165 +57,47 @@ class CRM_Core_Form_Tag {
* @static
*/
static function buildQuickForm(&$form, $parentNames, $entityTable, $entityId = NULL, $skipTagCreate = FALSE,
$skipEntityAction = FALSE, $searchMode = FALSE, $tagsetElementName = NULL ) {
$skipEntityAction = FALSE, $tagsetElementName = NULL ) {
$tagset = $form->_entityTagValues = array();
$form->assign("isTagset", FALSE);
$mode = NULL;
foreach ($parentNames as & $parentNameItem) {
foreach ($parentNames as &$parentNameItem) {
// get the parent id for tag list input for keyword
$parentId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $parentNameItem, 'id', 'name');
// check if parent exists
$entityTags = array();
if ($parentId) {
$tagsetItem = 'parentId_' . $parentId;
$tagset[$tagsetItem]['parentName'] = $parentNameItem;
$tagsetItem = $tagsetElementName . 'parentId_' . $parentId;
$tagset[$tagsetItem]['parentID'] = $parentId;
//tokeninput url
$qparams = "parentId={$parentId}";
if ($searchMode) {
$qparams .= '&search=1';
list(, $mode) = explode('_', $entityTable);
if (!$tagsetElementName) {
$tagsetElementName = $mode . "_taglist";
}
$tagUrl = CRM_Utils_System::url('civicrm/ajax/taglist', $qparams, FALSE, NULL, FALSE);
$tagset[$tagsetItem]['tagUrl'] = $tagUrl;
$tagset[$tagsetItem]['entityTable'] = $entityTable;
$tagset[$tagsetItem]['skipTagCreate'] = $skipTagCreate;
$tagset[$tagsetItem]['skipEntityAction'] = $skipEntityAction;
switch ($entityTable) {
case 'civicrm_activity':
$tagsetElementName = "activity_taglist";
$mode = 'activity';
break;
case 'civicrm_case':
$tagsetElementName = "case_taglist";
$mode = 'case';
break;
case 'civicrm_file':
$mode = 'attachment';
break;
default:
$tagsetElementName = "contact_taglist";
$mode = 'contact';
}
$tagset[$tagsetItem]['tagsetElementName'] = $tagsetElementName;
if ($tagsetElementName) {
$form->add('text', "{$tagsetElementName}[{$parentId}]", NULL);
}
$form->addEntityRef("{$tagsetElementName}[{$parentId}]", $parentNameItem, array(
'entity' => 'tag',
'multiple' => TRUE,
'create' => !$skipTagCreate,
'api' => array('params' => array('parent_id' => $parentId)),
'data-entity_table' => $entityTable,
'data-entity_id' => $entityId,
'class' => "crm-$mode-tagset",
));
if ($entityId) {
$tagset[$tagsetItem]['entityId'] = $entityId;
$entityTags = CRM_Core_BAO_EntityTag::getChildEntityTags($parentId, $entityId, $entityTable);
}
else {
switch ($entityTable) {
case 'civicrm_activity':
if (!empty($form->_submitValues['activity_taglist']) && !empty($form->_submitValues['activity_taglist'][$parentId])) {
$allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
$tagIds = explode(',', $form->_submitValues['activity_taglist'][$parentId]);
foreach ($tagIds as $tagId) {
if (is_numeric($tagId)) {
$tagName = $allTags[$tagId];
}
else {
$tagName = $tagId;
}
$entityTags[$tagId] = array(
'id' => $tagId,
'name' => $tagName,
);
}
}
break;
case 'civicrm_case':
if (!empty($form->_submitValues['case_taglist']) && !empty($form->_submitValues['case_taglist'][$parentId])) {
$allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
$tagIds = explode(',', $form->_submitValues['case_taglist'][$parentId]);
foreach ($tagIds as $tagId) {
if (is_numeric($tagId)) {
$tagName = $allTags[$tagId];
}
else {
$tagName = $tagId;
}
$entityTags[$tagId] = array(
'id' => $tagId,
'name' => $tagName,
);
}
}
break;
case 'civicrm_file':
$numAttachments = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'max_attachments');
for ($i = 1; $i <= $numAttachments; $i++) {
$tagset[$i] = $tagset[$tagsetItem];
$tagset[$i]['tagsetElementName'] = "attachment_taglist_$i";
$form->add('text', "attachment_taglist_{$i}[{$parentId}]", NULL);
if (!empty($form->_submitValues["attachment_taglist_$i"]) && !empty($form->_submitValues["attachment_taglist_$i"][$parentId])) {
$allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
$tagIds = explode(',', $form->_submitValues["attachment_taglist_$i"][$parentId]);
foreach ($tagIds as $tagId) {
if (is_numeric($tagId)) {
$tagName = $allTags[$tagId];
}
else {
$tagName = $tagId;
}
$entityTags[$tagId] = array(
'id' => $tagId,
'name' => $tagName,
);
}
}
}
unset($tagset[$tagsetItem]);
break;
default:
if (!empty($form->_formValues['contact_tags'])) {
$contactTags = CRM_Core_BAO_Tag::getTagsUsedFor('civicrm_contact', TRUE, FALSE, $parentId);
foreach (array_keys($form->_formValues['contact_tags']) as $tagId) {
if (!empty($contactTags[$tagId])) {
$tagName = $tagId;
if (is_numeric($tagId)) {
$tagName = $contactTags[$tagId];
}
$entityTags[$tagId] = array(
'id' => $tagId,
'name' => $tagName,
);
}
}
}
if ($entityTags) {
$form->setDefaults(array("{$tagsetElementName}[{$parentId}]" => implode(',', array_keys($entityTags))));
}
}
if (!empty($entityTags)) {
// assign as simple array for display in smarty
$tagset[$tagsetItem]['entityTagsArray'] = $entityTags;
// assign as json for js widget
$tagset[$tagsetItem]['entityTags'] = json_encode(array_values($entityTags));
if (!empty($form->_entityTagValues)) {
$form->_entityTagValues = CRM_Utils_Array::crmArrayMerge($entityTags, $form->_entityTagValues);
}
else {
$form->_entityTagValues = $entityTags;
}
else {
$skipEntityAction = TRUE;
}
$tagset[$tagsetItem]['skipEntityAction'] = $skipEntityAction;
}
}
......@@ -223,7 +105,13 @@ class CRM_Core_Form_Tag {
// assign current tagsets which is used in postProcess
$form->_tagsetInfo = $tagset;
$form->assign("tagsetType", $mode);
$form->assign("tagsetInfo_$mode", $tagset);
// Merge this tagset info with possibly existing info in the template
$tagsetInfo = (array) $form->get_template_vars("tagsetInfo");
if (empty($tagsetInfo[$mode])) {
$tagsetInfo[$mode] = array();
}
$tagsetInfo[$mode] = array_merge($tagsetInfo[$mode], $tagset);
$form->assign("tagsetInfo", $tagsetInfo);
$form->assign("isTagset", TRUE);
}
}
......
......@@ -691,22 +691,11 @@
<title>Price Field Options</title>
<page_callback>CRM_Price_Page_Option</page_callback>
</item>
<item>
<path>civicrm/ajax/taglist</path>
<page_callback>CRM_Admin_Page_AJAX::getTagList</page_callback>
<access_arguments>access CiviCRM</access_arguments>
</item>
<item>
<path>civicrm/ajax/mergeTagList</path>
<page_callback>CRM_Admin_Page_AJAX::mergeTagList</page_callback>
<access_arguments>access CiviCRM</access_arguments>
</item>
<item>
<path>civicrm/ajax/processTags</path>
<page_callback>CRM_Admin_Page_AJAX::processTags</page_callback>
<access_arguments>access CiviCRM</access_arguments>
<page_type>3</page_type>
</item>
<item>
<path>civicrm/admin/tplstrings/add</path>
<page_callback>CRM_Admin_Form_Persistent</page_callback>
......
......@@ -110,24 +110,6 @@ class CRM_Tag_Form_Tag extends CRM_Core_Form {
//build tag widget
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_contact');
CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, $this->_entityTable, $this->_entityID);
if ($this->_action & CRM_Core_Action::BROWSE) {
$this->freeze();
}
else {
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Update Tags'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
}
}
/**
......
......@@ -276,7 +276,7 @@ CRM.validate = CRM.validate || {
options.select = options.select || {};
return $(this).each(function() {
var
$el = $(this),
$el = $(this).off('.crmEntity'),
entity = options.entity || $el.data('api-entity') || 'contact',
selectParams = {};
$el.data('api-entity', entity);
......@@ -327,7 +327,7 @@ CRM.validate = CRM.validate || {
}
}
};
if ($el.data('create-links')) {
if ($el.data('create-links') && entity.toLowerCase() === 'contact') {
selectParams.formatInputTooShort = function() {
var txt = $el.data('select-params').formatInputTooShort || $.fn.select2.defaults.formatInputTooShort.call(this);
if ($el.data('create-links')) {
......@@ -339,7 +339,7 @@ CRM.validate = CRM.validate || {
var txt = $el.data('select-params').formatNoMatches || $.fn.select2.defaults.formatNoMatches;
return txt + '<br />' + formatSelect2CreateLinks($el);
};
$el.off('.createLinks').on('select2-open.createLinks', function() {
$el.on('select2-open.crmEntity', function() {
var $el = $(this);
$('#select2-drop').off('.crmEntity').on('click.crmEntity', 'a.crm-add-entity', function(e) {
$el.select2('close');
......@@ -361,7 +361,38 @@ CRM.validate = CRM.validate || {
});
});
}
$el.crmSelect2($.extend(settings, $el.data('select-params'), selectParams));
// Create new items inline - works for tags
else if ($el.data('create-links')) {
selectParams.createSearchChoice = function(term, data) {
if (!_.findKey(data, {label: term})) {
return {id: "0", term: term, label: term + ' (' + ts('new tag') + ')'};
}
};
selectParams.tokenSeparators = [','];
selectParams.createSearchChoicePosition = 'bottom';
}
$el.crmSelect2($.extend(settings, $el.data('select-params'), selectParams))
.on('select2-selecting.crmEntity', function(e) {
if (e.val === "0") {
e.object.label = e.object.term;
CRM.api3(entity, 'create', $.extend({name: e.object.term}, $el.data('api-params').params || {}))
.done(function(created) {
var
multiple = !!$el.data('select-params').multiple,
val = $el.select2('val'),
data = $el.select2('data'),
item = {id: created.id, label: e.object.term};
if (val === "0") {
$el.select2('data', item, true);
}
else if ($.isArray(val) && $.inArray("0", val) > -1) {
_.remove(data, {id: "0"});
data.push(item);
$el.select2('data', data, true);
}
});
}
});
});
};
......
......@@ -71,7 +71,8 @@
entity: 'api3',
action: 'call',
json: JSON.stringify(entity)
}
};
status = action;
}
var ajax = $.ajax({
url: CRM.url('civicrm/ajax/rest'),
......