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
8class Search_GlobalSource_RelationSource implements Search_GlobalSource_Interface
9{
10	private $relationlib;
11	private $contentSources;
12
13	function __construct()
14	{
15		$this->relationlib = TikiLib::lib('relation');
16	}
17
18	function setContentSources($contentSources)
19	{
20		$this->contentSources = $contentSources;
21	}
22
23	function getProvidedFields()
24	{
25		return [
26			'relations',
27			'relation_types',
28		];
29	}
30
31	function getGlobalFields()
32	{
33		return [];
34	}
35
36	function getData($objectType, $objectId, Search_Type_Factory_Interface $typeFactory, array $data = [])
37	{
38		global $prefs;
39		if (isset($data['relations']) || isset($data['relation_types'])) {
40			return [];
41		}
42
43		$relations = [];
44		$relation_objects = [];
45		$types = [];
46
47		$relation_objects_to_index = [];
48		if ($prefs['unified_engine'] == 'elastic') { // only index full objects in elasticsearch
49			$relation_objects_to_index = array_map('trim', explode(',', $prefs['unified_relation_object_indexing']));
50		}
51
52		$from = $this->relationlib->get_relations_from($objectType, $objectId);
53		foreach ($from as $rel) {
54			$relations[] = Search_Query_Relation::token($rel['relation'], $rel['type'], $rel['itemId']);
55			$types[] = $rel['relation'];
56
57			if (in_array($rel['relation'], $relation_objects_to_index)) {
58				$contentSource = $this->contentSources[$rel['type']]; //new Search_ContentSource_TrackerItemSource();
59				$data = $contentSource->getDocument($rel['itemId'], $typeFactory);
60				$permissionSource = new Search_GlobalSource_PermissionSource(Perms::getInstance());
61				$data = array_merge(
62					$data,
63					$permissionSource->getData($rel['type'], $rel['itemId'], $typeFactory, $data)
64				);
65				foreach ($data as &$item) {
66					if ($item instanceof Search_Type_Interface) {
67						$item = $item->getValue();
68					}
69				}
70				$data['relation'] = $rel['relation'];
71				$data['object_type'] = $rel['type'];
72				$data['object_id'] = $rel['itemId'];
73				$relation_objects[] = $data;
74			}
75		}
76
77		$to = $this->relationlib->get_relations_to($objectType, $objectId);
78		foreach ($to as $rel) {
79			$relations[] = Search_Query_Relation::token($rel['relation'] . '.invert', $rel['type'], $rel['itemId']);
80			$rel_type = $rel['relation'] . '.invert';
81			$types[] = $rel_type;
82
83			if (in_array($rel_type, $relation_objects_to_index)) {
84				$contentSource = $this->contentSources[$rel['type']]; //new Search_ContentSource_TrackerItemSource();
85				$data = $contentSource->getDocument($rel['itemId'], $typeFactory);
86				$permissionSource = new Search_GlobalSource_PermissionSource(Perms::getInstance());
87				$data = array_merge(
88					$data,
89					$permissionSource->getData($rel['type'], $rel['itemId'], $typeFactory, $data)
90				);
91				foreach ($data as &$item) {
92					if ($item instanceof Search_Type_Interface) {
93						$item = $item->getValue();
94					}
95				}
96				$data['relation'] = $rel['relation'];
97				$data['object_type'] = $rel['type'];
98				$data['object_id'] = $rel['itemId'];
99				$relation_objects[] = $data;
100			}
101		}
102
103		//take the type array and get a count of each indiv. type
104		$type_count = array_count_values($types);
105		$rel_count = [];
106		foreach ($type_count as $key => $val) {
107			//instead of returning an assoc. array, format to "relation:count" format for input in index
108			$rel_count[] = $key . ":" . $val;
109		}
110
111		return [
112			'relations' => $typeFactory->multivalue($relations),
113			'relation_objects' => $typeFactory->nested($relation_objects),
114			'relation_types' => $typeFactory->multivalue(array_unique($types)),
115			'relation_count' => $typeFactory->multivalue($rel_count),
116		];
117	}
118}
119