1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8/**
9 * Handler class for UserGroups
10 *
11 * Letter key: ~usergroups~
12 *
13 */
14class Tracker_Field_UserGroups extends Tracker_Field_Abstract implements Tracker_Field_Filterable
15{
16	public static function getTypes()
17	{
18		return [
19			'usergroups' => [
20				'name' => tr('User Groups'),
21				'description' => tr('Display the list of groups for the user associated with the tracker items.'),
22				'help' => 'User Groups',
23				'prefs' => ['trackerfield_usergroups'],
24				'tags' => ['advanced'],
25				'default' => 'n',
26				'params' => [
27					'directOnly' => [
28						'name' => tr('Show direct groups memberships only'),
29						'description' => tr('Do not show inherited/included groups'),
30						'filter' => 'int',
31						'options' => [
32							0 => tr('No'),
33							1 => tr('Yes'),
34						],
35						'default' => 0,
36					],
37					'specifyFields' => [
38						'name' => tr('Specify Fields'),
39						'description' => tr('Get the groups for users from these fields, not the "owner" user fields.'),
40						'separator' => '|',
41						'filter' => 'int',
42						'profile_reference' => 'tracker_field',
43						'parent' => 'input[name=trackerId]',
44						'parentkey' => 'tracker_id',
45						'sort_order' => 'position_nasc',
46					],
47				],
48			],
49		];
50	}
51
52	function getFieldData(array $requestData = [])
53	{
54		$itemId = $this->getItemId();
55
56		$value = [];
57
58		if ($itemId) {
59			$fields = $this->getOption('specifyFields');
60
61			if (empty(array_filter($fields))) {
62				$itemUsers = $this->getTrackerDefinition()->getItemUsers($itemId);
63			} else {
64				$trackerId = $this->getConfiguration('trackerId');
65				$trackerlib = TikiLib::lib('trk');
66				$itemUsers = array_map(
67					function ($fieldId) use ($trackerId, $itemId, $trackerlib) {
68						$owners = $trackerlib->get_item_value($trackerId, $itemId, $fieldId);
69						return $trackerlib->parse_user_field($owners);
70					}, $fields);
71
72				$itemUsers = call_user_func_array('array_merge', $itemUsers);
73			}
74
75			if (! empty($itemUsers)) {
76				$tikilib = TikiLib::lib('tiki');
77				foreach ($itemUsers as $itemUser) {
78					$value = array_merge($value, array_diff(
79						$tikilib->get_user_groups($itemUser, ! $this->getOption('directOnly')),
80						['Registered', 'Anonymous']
81					));
82				}
83			}
84			$value = array_unique(array_filter($value));
85			natcasesort($value);
86		}
87
88		return [
89			'value' => implode(',', $value),
90			'groups' => $value
91		];
92	}
93
94	function renderInput($context = [])
95	{
96		return $this->renderOutput($context);
97	}
98
99	function renderOutput($context = [])
100	{
101		return $this->renderTemplate('trackeroutput/usergroups.tpl', $context);
102	}
103
104	function renderDiff($context = [])
105	{
106		if (isset($context['oldValue'])) {
107			$context['renderedOldValue'] = $context['oldValue'];
108		}
109		return parent::renderDiff($context);
110	}
111
112	public function watchCompare($old, $new)
113	{
114		// TODO properly
115		return '';
116	}
117
118	function getDocumentPart(Search_Type_Factory_Interface $typeFactory)
119	{
120		$baseKey = $this->getBaseKey();
121		$data = $this->getFieldData();
122		$listtext = implode(' ', $data['groups']);
123
124		return [
125			$baseKey => $typeFactory->multivalue($data['groups']),
126			"{$baseKey}_text" => $typeFactory->plaintext($listtext),
127		];
128	}
129
130	function getProvidedFields()
131	{
132		$baseKey = $this->getBaseKey();
133		return [$baseKey];
134	}
135
136	function getGlobalFields()
137	{
138		$baseKey = $this->getBaseKey();
139		return [$baseKey => true];
140	}
141
142	function getFilterCollection()
143	{
144		$userlib = TikiLib::lib('user');
145		$groups = $userlib->list_all_groups_with_permission();
146		$groups = $userlib->get_group_info($groups);
147
148		$possibilities = [];
149		foreach ($groups as $group) {
150			$possibilities[$group['groupName']] = $group['groupName'];
151		}
152		$possibilities['-Blank (no data)-'] = tr('-Blank (no data)-');
153
154		$filters = new Tracker\Filter\Collection($this->getTrackerDefinition());
155		$permName = $this->getConfiguration('permName');
156		$name = $this->getConfiguration('name');
157		$baseKey = $this->getBaseKey();
158
159		$filters->addNew($permName, 'dropdown')
160			->setLabel($name)
161			->setControl(new Tracker\Filter\Control\DropDown("tf_{$permName}_dd", $possibilities))
162			->setApplyCondition(function ($control, Search_Query $query) use ($baseKey) {
163				$value = $control->getValue();
164
165				if ($value === '-Blank (no data)-') {
166					$query->filterIdentifier('', $baseKey . '_text');
167				} elseif ($value) {
168					$query->filterMultivalue((string) $value, $baseKey);
169				}
170			});
171
172		$filters->addNew($permName, 'multiselect')
173			->setLabel($name)
174			->setControl(new Tracker\Filter\Control\MultiSelect("tf_{$permName}_ms", $possibilities))
175			->setApplyCondition(function ($control, Search_Query $query) use ($permName, $baseKey) {
176				$values = $control->getValues();
177
178				if (! empty($values)) {
179					$sub = $query->getSubQuery("ms_$permName");
180
181					foreach ($values as $v) {
182						if ($v === '-Blank (no data)-') {
183							$sub->filterIdentifier('', $baseKey . '_text');
184						} elseif ($v) {
185							$sub->filterMultivalue((string) $v, $baseKey);
186						}
187					}
188				}
189			});
190
191		return $filters;
192	}
193}
194