<commit_before><?php
// (c) Copyright 2002-2013 by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$

/**
 * Handler class for ItemsList
 *
 * Letter key: ~l~
 *
 */
class Tracker_Field_ItemsList extends Tracker_Field_Abstract
{
	public static function getTypes()
	{
		return array(
			'l' => array(
				'name' => tr('Items List'),
				'description' => tr('Displays a list of field values from another tracker that has a relation with this tracker.'),
				'readonly' => true,
				'help' => 'Items List and Item Link Tracker Fields',
				'prefs' => array('trackerfield_itemslist'),
				'tags' => array('advanced'),
				'default' => 'n',
				'params' => array(
					'trackerId' => array(
						'name' => tr('Tracker ID'),
						'description' => tr('Tracker to list items from'),
						'filter' => 'int',
						'legacy_index' => 0,
						'profile_reference' => 'tracker',
					),
					'fieldIdThere' => array(
						'name' => tr('Link Field ID'),
						'description' => tr('Field ID from the other tracker containing an item link pointing to the item in this tracker or some other value to be matched.'),
						'filter' => 'int',
						'legacy_index' => 1,
						'profile_reference' => 'tracker_field',
					),
					'fieldIdHere' => array(
						'name' => tr('Value Field ID'),
						'description' => tr('Field ID from this tracker matching the value in the link field ID from the other tracker if the field above is not an item link.'),
						'filter' => 'int',
						'legacy_index' => 2,
						'profile_reference' => 'tracker_field',
					),
					'displayFieldIdThere' => array(
						'name' => tr('Fields to display'),
						'description' => tr('Display alternate fields from the other tracker instead of the item title'),
						'filter' => 'int',
						'separator' => '|',
						'legacy_index' => 3,
						'profile_reference' => 'tracker_field',
					),
					'linkToItems' => array(
						'name' => tr('Display'),
						'description' => tr('How the link to the items should be rendered'),
						'filter' => 'int',
						'options' => array(
							0 => tr('Value'),
							1 => tr('Link'),
						),
						'legacy_index' => 4,
					),
					'status' => array(
						'name' => tr('Status Filter'),
						'description' => tr('Limit the available items to a selected set'),
						'filter' => 'alpha',
						'options' => array(
							'opc' => tr('all'),
							'o' => tr('open'),
							'p' => tr('pending'),
							'c' => tr('closed'),
							'op' => tr('open, pending'),
							'pc' => tr('pending, closed'),
						),
						'legacy_index' => 5,
					),
				),
			),
		);
	}

	function getFieldData(array $requestData = array())
	{
		$items = $this->getItemIds();
		$list = $this->getItemLabels($items);
		return array(
			'value' => '',
			'items' => $list,
		);
	}

	function renderInput($context = array())
	{
		return tr('Read Only');
	}

	function renderOutput( $context = array() )
	{
		if (isset($context['search_render']) && $context['search_render'] == 'y') {
			$items = $this->getData($this->getConfiguration('fieldId'));
		} else {
			$items = $this->getItemIds();
		}

		$list = $this->getItemLabels($items, $context);

		if ($context['list_mode'] === 'csv') {
			return implode('%%%', $list);
		} else {
			return $this->renderTemplate(
				'trackeroutput/itemslist.tpl',
				$context,
				array(
					'links' => (bool) $this->getOption('linkToItems'),
					'raw' => (bool) $this->getOption('displayFieldIdThere'),
					'itemIds' => implode(',', $items),
					'items' => $list,
					'num' => count($list),
				)
			);
		}
	}

	function getDocumentPart(Search_Type_Factory_Interface $typeFactory)
	{
		$baseKey = $this->getBaseKey();
		$items = $this->getItemIds();

		$list = $this->getItemLabels($items);
		$listtext = implode(' ', $list);

		return array(
			$baseKey => $typeFactory->multivalue($items),
			"{$baseKey}_text" => $typeFactory->sortable($listtext),
		);
	}

	function getProvidedFields()
	{
		$baseKey = $this->getBaseKey();
		return array(
			$baseKey,
			"{$baseKey}_text",
		);
	}

	function getGlobalFields()
	{
		return array();
	}

	private function getItemIds()
	{
		$trackerId = (int) $this->getOption('trackerId');
		$remoteField = (int) $this->getOption('fieldIdThere');
		$localField = (int) $this->getOption('fieldIdHere');
		$localFieldDef = $this->getTrackerDefinition()->getField($localField);
		$displayFields = $this->getOption('displayFieldIdThere');
		$status = $this->getOption('status', 'opc');

		$tracker = Tracker_Definition::get($trackerId);
		$technique = 'value';

		if ($tracker && ($field = $tracker->getField($remoteField)) && !$this->getOption('fieldIdHere')) {
			if ($field['type'] == 'r') {
				$technique = 'id';
			}
		}
		if ($localFieldDef['type'] == 'q' && isset($localFieldDef['options_array'][3]) && $localFieldDef['options_array'][3] == 'itemId') {		
			$technique = 'id';
		}

		$trklib = TikiLib::lib('trk');
		if ($technique == 'id') {
			$items = $trklib->get_items_list($trackerId, $remoteField, $this->getItemId(), $status);
		} else {
			$localValue = $this->getData($localField);
			if (!$localValue) {
				// in some cases e.g. pretty tracker $this->getData($localField) is not reliable as the info is not there
				$localValue = $trklib->get_item_value($trackerId, $this->getItemId(), $localField);
			}
			if ($localFieldDef['type'] == 'r' && isset($localFieldDef['options_array'][0]) && isset($localFieldDef['options_array'][1])) {
				$localValue = $trklib->get_item_value($localFieldDef['options_array'][0], $localValue, $localFieldDef['options_array'][1]);
			}
			// Skip nulls
			if ($localValue) {
				$items = $trklib->get_items_list($trackerId, $remoteField, $localValue, $status);<commit_msg>[FIX] trackers: If " Value Field ID" option on an ItemsList is set (as is the case in upgrades often) then check if the remote field is an ItemsLink one and ignore that option if so (thanks eromneg)<commit_after><?php
// (c) Copyright 2002-2013 by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$

/**
 * Handler class for ItemsList
 *
 * Letter key: ~l~
 *
 */
class Tracker_Field_ItemsList extends Tracker_Field_Abstract
{
	public static function getTypes()
	{
		return array(
			'l' => array(
				'name' => tr('Items List'),
				'description' => tr('Displays a list of field values from another tracker that has a relation with this tracker.'),
				'readonly' => true,
				'help' => 'Items List and Item Link Tracker Fields',
				'prefs' => array('trackerfield_itemslist'),
				'tags' => array('advanced'),
				'default' => 'n',
				'params' => array(
					'trackerId' => array(
						'name' => tr('Tracker ID'),
						'description' => tr('Tracker to list items from'),
						'filter' => 'int',
						'legacy_index' => 0,
						'profile_reference' => 'tracker',
					),
					'fieldIdThere' => array(
						'name' => tr('Link Field ID'),
						'description' => tr('Field ID from the other tracker containing an item link pointing to the item in this tracker or some other value to be matched.'),
						'filter' => 'int',
						'legacy_index' => 1,
						'profile_reference' => 'tracker_field',
					),
					'fieldIdHere' => array(
						'name' => tr('Value Field ID'),
						'description' => tr('Field ID from this tracker matching the value in the link field ID from the other tracker if the field above is not an item link.'),
						'filter' => 'int',
						'legacy_index' => 2,
						'profile_reference' => 'tracker_field',
					),
					'displayFieldIdThere' => array(
						'name' => tr('Fields to display'),
						'description' => tr('Display alternate fields from the other tracker instead of the item title'),
						'filter' => 'int',
						'separator' => '|',
						'legacy_index' => 3,
						'profile_reference' => 'tracker_field',
					),
					'linkToItems' => array(
						'name' => tr('Display'),
						'description' => tr('How the link to the items should be rendered'),
						'filter' => 'int',
						'options' => array(
							0 => tr('Value'),
							1 => tr('Link'),
						),
						'legacy_index' => 4,
					),
					'status' => array(
						'name' => tr('Status Filter'),
						'description' => tr('Limit the available items to a selected set'),
						'filter' => 'alpha',
						'options' => array(
							'opc' => tr('all'),
							'o' => tr('open'),
							'p' => tr('pending'),
							'c' => tr('closed'),
							'op' => tr('open, pending'),
							'pc' => tr('pending, closed'),
						),
						'legacy_index' => 5,
					),
				),
			),
		);
	}

	function getFieldData(array $requestData = array())
	{
		$items = $this->getItemIds();
		$list = $this->getItemLabels($items);
		return array(
			'value' => '',
			'items' => $list,
		);
	}

	function renderInput($context = array())
	{
		return tr('Read Only');
	}

	function renderOutput( $context = array() )
	{
		if (isset($context['search_render']) && $context['search_render'] == 'y') {
			$items = $this->getData($this->getConfiguration('fieldId'));
		} else {
			$items = $this->getItemIds();
		}

		$list = $this->getItemLabels($items, $context);

		if ($context['list_mode'] === 'csv') {
			return implode('%%%', $list);
		} else {
			return $this->renderTemplate(
				'trackeroutput/itemslist.tpl',
				$context,
				array(
					'links' => (bool) $this->getOption('linkToItems'),
					'raw' => (bool) $this->getOption('displayFieldIdThere'),
					'itemIds' => implode(',', $items),
					'items' => $list,
					'num' => count($list),
				)
			);
		}
	}

	function getDocumentPart(Search_Type_Factory_Interface $typeFactory)
	{
		$baseKey = $this->getBaseKey();
		$items = $this->getItemIds();

		$list = $this->getItemLabels($items);
		$listtext = implode(' ', $list);

		return array(
			$baseKey => $typeFactory->multivalue($items),
			"{$baseKey}_text" => $typeFactory->sortable($listtext),
		);
	}

	function getProvidedFields()
	{
		$baseKey = $this->getBaseKey();
		return array(
			$baseKey,
			"{$baseKey}_text",
		);
	}

	function getGlobalFields()
	{
		return array();
	}

	private function getItemIds()
	{
		$trackerId = (int) $this->getOption('trackerId');
		$remoteField = (int) $this->getOption('fieldIdThere');
		$localField = (int) $this->getOption('fieldIdHere');
		$localFieldDef = $this->getTrackerDefinition()->getField($localField);
		$displayFields = $this->getOption('displayFieldIdThere');
		$status = $this->getOption('status', 'opc');

		$tracker = Tracker_Definition::get($trackerId);
		$technique = 'value';

		if ($tracker && ($field = $tracker->getField($remoteField)) && (!$localField || $field['type'] === 'r')) {
			if ($field['type'] == 'r') {
				$technique = 'id';
			}
		}
		if ($localFieldDef['type'] == 'q' && isset($localFieldDef['options_array'][3]) && $localFieldDef['options_array'][3] == 'itemId') {		
			$technique = 'id';
		}

		$trklib = TikiLib::lib('trk');
		if ($technique == 'id') {
			$items = $trklib->get_items_list($trackerId, $remoteField, $this->getItemId(), $status);
		} else {
			$localValue = $this->getData($localField);
			if (!$localValue) {
				// in some cases e.g. pretty tracker $this->getData($localField) is not reliable as the info is not there
				$localValue = $trklib->get_item_value($trackerId, $this->getItemId(), $localField);
			}
			if ($localFieldDef['type'] == 'r' && isset($localFieldDef['options_array'][0]) && isset($localFieldDef['options_array'][1])) {
				$localValue = $trklib->get_item_value($localFieldDef['options_array'][0], $localValue, $localFieldDef['options_array'][1]);
			}
			// Skip nulls
			if ($localValue) {
				$items = $trklib->get_items_list($trackerId, $remoteField, $localValue, $status);
{'fraction_non_alphanumeric': 0.187211546530167, 'fraction_numerical': 0.0036922044138625494, 'mean_word_length': 3.50586011342155, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 192, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7540643', 'n_tokens_mistral': 4791, 'n_tokens_neox': 3917, 'n_words': 951}