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
8function wikiplugin_trackeritemcopy_info()
9{
10	return [
11		'name' => tra('Copy Tracker Item'),
12		'documentation' => tra('PluginTrackerItemCopy'),
13		'description' => tra('Copy a tracker item'),
14		'prefs' => ['wikiplugin_trackeritemcopy', 'feature_trackers'],
15		'validate' => 'all',
16		'filter' => 'wikicontent',
17		'iconname' => 'copy',
18		'introduced' => 7,
19		'tags' => [ 'experimental' ],
20		'params' => [
21			'trackerId' => [
22				'required' => true,
23				'name' => tra('Tracker ID'),
24				'description' => tr(
25					'Tracker from which to copy item, joined tracker ids separated by %0:%1',
26					'<code>',
27					'</code>'
28				),
29				'since' => '7.0',
30				'filter' => 'text',
31				'default' => '',
32				'separator' => [':'],
33				'profile_reference' => 'tracker',
34			],
35			'linkFieldIds' => [
36				'required' => true,
37				'name' => tra('Link Field IDs'),
38				'description' => tr('Fields links that are related to this tracker that you would like to join on,
39					separated by %0:%1', '<code>', '</code>'),
40				'since' => '8.0',
41				'filter' => 'text',
42				'default' => '',
43				'separator' => [':'],
44				'profile_reference' => 'tracker_field',
45			],
46			'copyFieldIds' => [
47				'required' => true,
48				'name' => tra('Copy Field IDs'),
49				'description' => tr('Field IDs to copy old value of, separated by %0:%1, joined fields separated by
50					%0|%1', '<code>', '</code>'),
51				'since' => '7.0',
52				'filter' => 'text',
53				'default' => '',
54				'separator' => ['|', ':'],
55				'profile_reference' => 'tracker_field',
56			],
57			'updateFieldIds' => [
58				'required' => false,
59				'name' => tra('Update Field IDs'),
60				'description' => tr('Field IDs to update with new values specified, separated by %0:%1, joined fields
61					separated by %0|%1', '<code>', '</code>'),
62				'since' => '7.0',
63				'filter' => 'text',
64				'default' => '',
65				'separator' => ['|', ':'],
66				'profile_reference' => 'tracker_field',
67			],
68			'updateFieldValues' => [
69				'required' => false,
70				'name' => tra('New Values'),
71				'description' => tr('New values to replace for the field IDs specified, separated by %0:%1, joined
72					fields separated by %0|%1. %0randomstring%1 will generate random string; and %0f_xx%1 to use value of
73					field xx of itemId', '<code>', '</code>'),
74				'since' => '7.0',
75				'filter' => 'text',
76				'default' => '',
77				'separator' => ['|', ':'],
78				'profile_reference' => 'tracker_field',
79			],
80			'itemId' => [
81				'required' => false,
82				'name' => tra('Item ID'),
83				'description' => tra('ID of item to make copy of, otherwise input is asked for'),
84				'since' => '7.0',
85				'filter' => 'text',
86				'default' => '',
87				'profile_reference' => 'tracker_item',
88			],
89			'copies_on_load' => [
90				'required' => false,
91				'name' => tra('Make this number of copies on load'),
92				'description' => tra('Set the number of copies to make on load of plugin automatically'),
93				'since' => '7.0',
94				'filter' => 'int',
95				'default' => ''
96			],
97			'return_array' => [
98				'required' => false,
99				'name' => tra('Returns array non-interactively'),
100				'advanced' => true,
101				'description' => tr('If Yes (%0y%1), returns array of new information instead of displaying results
102					to screen, used in non-interactive mode', '<code>', '</code>'),
103				'since' => '7.0',
104				'filter' => 'text',
105				'default' => '',
106			],
107		],
108	];
109}
110
111function wikiplugin_trackeritemcopy($data, $params)
112{
113	$trklib = TikiLib::lib("trk");
114	$smarty = TikiLib::lib('smarty');
115
116	if (! isset($params["trackerId"]) || ! isset($params["copyFieldIds"])) {
117		return tra('Missing mandatory parameters');
118	} else {
119		$trackerId = $params["trackerId"];
120		if (is_array($trackerId) == false) {
121			$trackerId = [$trackerId];
122		}
123		$copyFieldIds = $params["copyFieldIds"];
124	}
125
126	$smarty->assign('itemIdSet', 'n');
127	$itemId = 0;
128
129	if (isset($params["itemId"])) {
130		$itemId = $params["itemId"];
131		$smarty->assign('itemIdSet', 'y');
132	} elseif (isset($_POST["itemIdToCopy"])) {
133		$itemId = $_POST["itemIdToCopy"];
134	}
135
136	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
137		$items_copy = function ($trackerId, $updateFieldIds, $updateFieldValues, $copyFieldIds, $itemIds, $linkFieldId, $itemLinkId, $copies) {
138			$trklib = TikiLib::lib('trk');
139
140			if (is_array($itemIds) == false) {
141				$itemIds = [$itemIds];
142			}
143
144			foreach ($itemIds as $itemId) {
145				$tracker_fields_info = $trklib->list_tracker_fields($trackerId);
146
147				$fieldTypes = [];
148				$fieldOptionsArray = [];
149
150				foreach ($tracker_fields_info['data'] as $t) {
151					$fieldTypes[$t['fieldId']] = $t['type'];
152					$fieldOptionsArray[$t['fieldId']] = $t['options_array'];
153				}
154
155				$ins_fields["data"] = [];
156
157				if (isset($linkFieldId) && isset($itemLinkId)) {
158					$updateFieldIds[] = $linkFieldId;
159					$updateFieldValues[] = $itemLinkId;
160				}
161
162				//print_r(array($trackerId, $updateFieldIds, $updateFieldValues, $copyFieldIds, $itemIds, $linkFieldId, $itemLinkId, $copies));
163
164				for ($i = 0, $count_updateFieldIds = count($updateFieldIds); $i < $count_updateFieldIds; $i++) {
165					$ins_fields["data"][] = [
166						'options_array' => $fieldOptionsArray[$updateFieldIds[$i]],
167						'type' => $fieldTypes[$updateFieldIds[$i]],
168						'fieldId' => $updateFieldIds[$i],
169						'value' => $updateFieldValues[$i]
170					];
171				}
172
173				// CUSTOM: this part is totally custom to store admin notes (how to generalize?)
174				if (! empty($_POST['admin_notes_for_copy'])) {
175					$ins_fields["data"][] = [
176						'type' => 'a',
177						'fieldId' => 118,
178						'value' => $_POST['admin_notes_for_copy']
179					];
180				}
181				// end totally CUSTOM part
182
183				$newitems = [];
184				for ($i = 0; $i < $copies; $i++) {
185					// Check for -randomstring- and f_xx
186					$ins_fields_final["data"] = [];
187					foreach ($ins_fields["data"] as $h) {
188						if ($h["value"] == '-randomstring-') {
189							$h["value"] = $trklib->genPass();
190						} elseif (substr($h["value"], 0, 2) == 'f_') {
191							$sourceFieldId = (int) trim(substr($h["value"], 2));
192							$h["value"] = $trklib->get_item_value($trackerId, $itemId, $sourceFieldId);
193						}
194						$ins_fields_final["data"][] = $h;
195					}
196					$newitemsdata[] = $ins_fields_final["data"];
197					$newitems[] = $trklib->replace_item($trackerId, 0, $ins_fields_final);
198				}
199
200				foreach ($newitems as $n) {
201					$trklib->copy_item($itemId, $n, null, $copyFieldIds);
202					$newitemslist .= '  ' . $n;
203				}
204			}
205
206			return [
207				"items" => $newitems,
208				"data" => $newitemsdata,
209				"list" => $newitemslist
210			];
211		};
212
213		$return_array = [];
214		$itemIds = [];
215
216		foreach ($trackerId as $key => $trackerIdLeft) {
217			//ensure that the fields are set and usable
218			if (isset($params["updateFieldIds"]) || isset($params["updateFieldValues"])) {
219				$updateFieldIds = $params["updateFieldIds"];
220				$updateFieldValues = $params["updateFieldValues"];
221
222				foreach ($updateFieldIds as $key => $updateFieldId) {
223					if (count($updateFieldIds[$key]) != count($updateFieldValues[$key])) {
224						return tra('Number of update fields do not match new values');
225					}
226				}
227
228				$copyFieldIds[$key] = array_diff($copyFieldIds[$key], $updateFieldIds);
229			}
230
231			if ($_SERVER['REQUEST_METHOD'] == 'POST' && $itemId && isset($_POST['copytrackeritem']) && isset($_POST['numberofcopies'])) {
232				$copies = (int) $_POST['numberofcopies'];
233			} elseif (isset($params['copies_on_load'])) {
234				$copies = (int) $params['copies_on_load'];
235			} else {
236				$copies = 0;
237			}
238
239			if ($copies > 0) {
240				if ($key > 0) {
241					$qry = Tracker_Query::tracker($trackerIdLeft)
242						->fields($params["linkFieldIds"][0])
243						->equals([$itemId]);
244
245					$itemIds = [];
246					foreach ($qry as $linkedItemIds => $item) {
247						$itemIds[] = $linkedItemIds;
248					}
249				}
250
251				$return_array[] = $items_copy(
252					$trackerId[$key],
253					$updateFieldIds[$key],
254					$updateFieldValues[$key],
255					$copyFieldIds[$key],
256					(
257						$key == 0 ? $itemId : $itemIds
258					),
259					(
260						$key == 0 ? null : $params["linkFieldIds"][$key - 1]
261					),
262					(
263						$key == 0 ? null : $return_array[0]['items'][0]
264					),
265					$copies
266				);
267			}
268		}
269
270		$smarty->assign('newitemslist', $return_array['list']);
271
272		if ($params['return_array'] == 'y') {
273			if (count($return_array) == 1) { //backward compatible
274				return $return_array[0];
275			} else {
276				return $return_array;
277			}
278		}
279	}
280
281	return $smarty->fetch('wiki-plugins/wikiplugin_trackeritemcopy.tpl');
282}
283