few more fixes for tagset delete logic, CRM-14052
[civicrm-core.git] / CRM / Core / Form / Tag.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
232624b1 4 | CiviCRM version 4.4 |
6a488035
TO
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35
36/**
37 * This class generates form element for free tag widget
38 *
39 */
40class CRM_Core_Form_Tag {
41 public $_entityTagValues;
42
43 /**
44 * Function to build tag widget if correct parent is passed
45 *
46 * @param object $form form object
47 * @param string $parentName parent name ( tag name)
48 * @param string $entityTable entitytable 'eg: civicrm_contact'
49 * @param int $entityId entityid 'eg: contact id'
50 * @param boolean $skipTagCreate true if tag need be created using ajax
51 * @param boolean $skipEntityAction true if need to add entry in entry table via ajax
52 * @param boolean $searchMode true if widget is used in search eg: advanced search
53 * @param string $tagsetElementName if you need to create tagsetlist with specific name
54 *
55 * @return void
56 * @access public
57 * @static
58 */
59 static function buildQuickForm(&$form, $parentNames, $entityTable, $entityId = NULL, $skipTagCreate = FALSE,
60 $skipEntityAction = FALSE, $searchMode = FALSE, $tagsetElementName = NULL ) {
61 $tagset = $form->_entityTagValues = array();
62 $form->assign("isTagset", FALSE);
63 $mode = NULL;
64
65 foreach ($parentNames as & $parentNameItem) {
66 // get the parent id for tag list input for keyword
67 $parentId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $parentNameItem, 'id', 'name');
68
69 // check if parent exists
70 $entityTags = array();
71 if ($parentId) {
72 $tagsetItem = 'parentId_' . $parentId;
73 $tagset[$tagsetItem]['parentName'] = $parentNameItem;
74 $tagset[$tagsetItem]['parentID'] = $parentId;
75
76 //tokeninput url
77 $qparams = "parentId={$parentId}";
78
79 if ($searchMode) {
80 $qparams .= '&search=1';
81 }
82
83 $tagUrl = CRM_Utils_System::url('civicrm/ajax/taglist', $qparams, FALSE, NULL, FALSE);
84
85 $tagset[$tagsetItem]['tagUrl'] = $tagUrl;
86 $tagset[$tagsetItem]['entityTable'] = $entityTable;
87 $tagset[$tagsetItem]['skipTagCreate'] = $skipTagCreate;
88 $tagset[$tagsetItem]['skipEntityAction'] = $skipEntityAction;
89
90 switch ($entityTable) {
91 case 'civicrm_activity':
92 $tagsetElementName = "activity_taglist";
93 $mode = 'activity';
94 break;
95
96 case 'civicrm_case':
97 $tagsetElementName = "case_taglist";
98 $mode = 'case';
99 break;
100
101 case 'civicrm_file':
102 $mode = 'attachment';
103 break;
104
105 default:
106 $tagsetElementName = "contact_taglist";
107 $mode = 'contact';
108 }
109
110 $tagset[$tagsetItem]['tagsetElementName'] = $tagsetElementName;
111 if ($tagsetElementName) {
112 $form->add('text', "{$tagsetElementName}[{$parentId}]", NULL);
113 }
114
115 if ($entityId) {
116 $tagset[$tagsetItem]['entityId'] = $entityId;
117 $entityTags = CRM_Core_BAO_EntityTag::getChildEntityTags($parentId, $entityId, $entityTable);
118 }
119 else {
120
121 switch ($entityTable) {
122 case 'civicrm_activity':
123 if (!empty($form->_submitValues['activity_taglist']) &&
124 CRM_Utils_Array::value($parentId, $form->_submitValues['activity_taglist'])
125 ) {
cd43c5e3 126 $allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
127 $tagIds = explode(',', $form->_submitValues['activity_taglist'][$parentId]);
128 foreach ($tagIds as $tagId) {
129 if (is_numeric($tagId)) {
130 $tagName = $allTags[$tagId];
131 }
132 else {
133 $tagName = $tagId;
134 }
135 $entityTags[$tagId] = array(
136 'id' => $tagId,
137 'name' => $tagName,
138 );
139 }
140 }
141 break;
142
143 case 'civicrm_case':
144 if (!empty($form->_submitValues['case_taglist']) &&
145 CRM_Utils_Array::value($parentId, $form->_submitValues['case_taglist'])
146 ) {
cd43c5e3 147 $allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
148 $tagIds = explode(',', $form->_submitValues['case_taglist'][$parentId]);
149 foreach ($tagIds as $tagId) {
150 if (is_numeric($tagId)) {
151 $tagName = $allTags[$tagId];
152 }
153 else {
154 $tagName = $tagId;
155 }
156 $entityTags[$tagId] = array(
157 'id' => $tagId,
158 'name' => $tagName,
159 );
160 }
161 }
162 break;
163 case 'civicrm_file':
164 $numAttachments = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'max_attachments');
165 for ($i = 1; $i <= $numAttachments; $i++) {
166 $tagset[$i] = $tagset[$tagsetItem];
167 $tagset[$i]['tagsetElementName'] = "attachment_taglist_$i";
168 $form->add('text', "attachment_taglist_{$i}[{$parentId}]", NULL);
169 if (!empty($form->_submitValues["attachment_taglist_$i"]) &&
170 CRM_Utils_Array::value($parentId, $form->_submitValues["attachment_taglist_$i"])
171 ) {
cd43c5e3 172 $allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
173 $tagIds = explode(',', $form->_submitValues["attachment_taglist_$i"][$parentId]);
174 foreach ($tagIds as $tagId) {
175 if (is_numeric($tagId)) {
176 $tagName = $allTags[$tagId];
177 }
178 else {
179 $tagName = $tagId;
180 }
181 $entityTags[$tagId] = array(
182 'id' => $tagId,
183 'name' => $tagName,
184 );
185 }
186 }
187 }
188 unset($tagset[$tagsetItem]);
189 break;
190
191 default:
192 if (!empty($form->_formValues['contact_tags'])) {
193 $contactTags = CRM_Core_BAO_Tag::getTagsUsedFor('civicrm_contact', TRUE, FALSE, $parentId);
194
195 foreach (array_keys($form->_formValues['contact_tags']) as $tagId) {
196 if (CRM_Utils_Array::value($tagId, $contactTags)) {
197 $tagName = $tagId;
198 if (is_numeric($tagId)) {
199 $tagName = $contactTags[$tagId];
200 }
201
202 $entityTags[$tagId] = array(
203 'id' => $tagId,
204 'name' => $tagName,
205 );
206 }
207 }
208 }
209 }
210 }
211
212 if (!empty($entityTags)) {
213 // assign as simple array for display in smarty
214 $tagset[$tagsetItem]['entityTagsArray'] = $entityTags;
215 // assign as json for js widget
216 $tagset[$tagsetItem]['entityTags'] = json_encode(array_values($entityTags));
217
218 if (!empty($form->_entityTagValues)) {
219 $form->_entityTagValues = CRM_Utils_Array::crmArrayMerge($entityTags, $form->_entityTagValues);
220 }
221 else {
222 $form->_entityTagValues = $entityTags;
223 }
224 }
225 }
226 }
227
228 if (!empty($tagset)) {
2a6e33c8 229 $form->_tagsetInfo = $tagset;
6a488035
TO
230 $form->assign("tagsetInfo_$mode", $tagset);
231 $form->assign("isTagset", TRUE);
232 }
233 }
234
235 /**
236 * Function to save entity tags when it is not save used AJAX
237 *
6fd5424b 238 * @param array $params associated array
239 * @param int $entityId entity id, eg: contact id, activity id, case id, file id
240 * @param string $entityTable entity table
241 * @param object $form form object
6fd5424b 242 *
243 * @return void
244 * @access public
245 * @static
6a488035 246 */
ca4f7cc8 247 static function postProcess(&$params, $entityId, $entityTable = 'civicrm_contact', &$form) {
6fd5424b 248 if ($form && !empty($form->_entityTagValues)) {
249 $existingTags = $form->_entityTagValues;
250 }
251 else {
252 $existingTags = CRM_Core_BAO_EntityTag::getTag($entityId, $entityTable);
253 }
254
2a6e33c8 255 if ($form) {
256 // If the key is missing from the form response then all entity_tags were deleted
257 foreach ($form->_tagsetInfo as $tagsetName => $tagsetInfo) {
258 $tagsetId = substr($tagsetName, strlen('parentId_'));
259 if (empty($params[$tagsetId])) {
260 $params[$tagsetId] = '';
261 }
6a488035 262 }
2a6e33c8 263 }
6fd5424b 264
2a6e33c8 265 foreach ($params as $parentId => $value) {
63b69fae 266 $newTagIds = array();
267 $realTagIds = array();
268
2a6e33c8 269 if ($value) {
270 $tagsIDs = explode(',', $value);
6a488035 271 foreach ($tagsIDs as $tagId) {
0cc0faa9 272 if (!is_numeric($tagId)) {
273 // check if user has selected existing tag or is creating new tag
274 // this is done to allow numeric tags etc.
275 $tagValue = explode(':::', $tagId);
276
277 if (isset($tagValue[1]) && $tagValue[1] == 'value') {
6fd5424b 278 $tagParams = array(
0cc0faa9 279 'name' => $tagValue[0],
280 'parent_id' => $parentId,
281 );
6fd5424b 282 $tagObject = CRM_Core_BAO_Tag::add($tagParams, CRM_Core_DAO::$_nullArray);
0cc0faa9 283 $tagId = $tagObject->id;
6a488035
TO
284 }
285 }
0cc0faa9 286
63b69fae 287 $realTagIds[] = $tagId;
0cc0faa9 288 if ($form && $form->_action != CRM_Core_Action::UPDATE) {
63b69fae 289 $newTagIds[] = $tagId;
0cc0faa9 290 }
6fd5424b 291 elseif (!array_key_exists($tagId, $existingTags)) {
63b69fae 292 $newTagIds[] = $tagId;
0cc0faa9 293 }
6a488035 294 }
2a6e33c8 295 }
6a488035 296
2a6e33c8 297 // Any existing entity tags from this tagset missing from the $params should be deleted
298 $deleteSQL = "DELETE FROM civicrm_entity_tag
63b69fae 299 USING civicrm_entity_tag, civicrm_tag
300 WHERE civicrm_tag.id=civicrm_entity_tag.tag_id
301 AND civicrm_entity_tag.entity_table='{$entityTable}'
302 AND entity_id={$entityId} AND parent_id={$parentId}";
2a6e33c8 303 if (!empty($realTagIds)) {
304 $deleteSQL .= " AND tag_id NOT IN (" . implode(', ', $realTagIds) . ");";
305 }
63b69fae 306
2a6e33c8 307 CRM_Core_DAO::executeQuery($deleteSQL);
308
309 if (!empty($newTagIds)) {
310 // New tag ids can be inserted directly into the db table.
311 $insertValues = array();
312 foreach ($newTagIds as $tagId) {
313 $insertValues[] = "( {$tagId}, {$entityId}, '{$entityTable}' ) ";
6a488035 314 }
2a6e33c8 315 $insertSQL = 'INSERT INTO civicrm_entity_tag ( tag_id, entity_id, entity_table )
316 VALUES ' . implode(', ', $insertValues) . ';';
317 CRM_Core_DAO::executeQuery($insertSQL);
6a488035
TO
318 }
319 }
320 }
321}
322