getHelperPluginManager(); $api = $plugins->get('api'); $escape = $plugins->get('escapeHtml'); $filterLocale = (bool) $this->siteSetting('filter_locale_values'); $lang = $filterLocale ? $this->lang() : null; $limitItemsByItemSet = 100; $types = [ 'items' => 'item', 'item_sets' => 'item-set', 'media' => 'media', 'annotations' => 'annotation', ]; // TODO Extract the table from the database in one or two sql queries. // TODO Use /api or /api/infos. // TODO Add links with the same values (like references or indexes). $relationTypes = $params['relations'] ?? ['objects', 'subjects', 'item_sets', 'items']; /** @var \Omeka\Api\Representation\AbstractResourceEntityRepresentation[] $resources */ $resources = []; foreach (array_filter(array_intersect_key($params, $types), 'is_array') as $resourceType => $query) { $resources[] = $api->search($resourceType, $query)->getContent(); } $resources = array_merge(...$resources); // The links sources and targets should be the keys of the nodes. $data = [ 'nodes' => [], 'links' => [], ]; $mapKeysToIds = []; foreach ($resources as $resource) { $resourceId = $resource->id(); $resourceName = $resource->resourceName(); $relations = [ 'objects' => [], 'subjects' => [], 'item_sets' => [], 'items' => [], ]; $relationItems = 0; foreach ($relationTypes as $relationType) switch ($relationType) { case 'objects': $relations['objects'] = $resource->objectValues(); break; case 'subjects': $relations['subjects'] = ($rsv = $resource->subjectValues()) ? array_merge(...array_values($rsv)) : []; break; case 'item_sets': if ($resourceName === 'items') { $relations['item_sets'] = $resource->itemSets(); } break; case 'items': if ($resourceName === 'item_sets') { $relationItems = $api->search('items', ['item_set_id' => $resourceId, 'limit' => 0])->getTotalResults(); $relations['items'] = $api->search('items', ['item_set_id' => $resourceId, 'limit' => $limitItemsByItemSet])->getContent(); } break; } $orderSource = array_search($resourceId, $mapKeysToIds); if ($orderSource === false) { $orderSource = array_push($mapKeysToIds, $resourceId) - 1; $type = $types[$resourceName]; $data['nodes'][$orderSource] = [ 'id' => $resourceId, 'title' => (string) $resource->displayTitle(null, $lang), 'type' => $type, // Not used for now. 'class' => $resource->resourceClass() ? $resource->resourceClass()->label() : null, 'total' => count($relations['objects']) + count($relations['subjects']) + count($relations['item_sets']) + $relationItems, ]; } foreach ($relations as $relationType => $rrelations) foreach ($rrelations as $relation) { $relation = $relation instanceof \Omeka\Api\Representation\AbstractResourceEntityRepresentation ? $relation : $relation->valueResource(); $relationId = $relation->id(); $orderTarget = array_search($relationId, $mapKeysToIds); if ($orderTarget === false) { $orderTarget = array_push($mapKeysToIds, $relationId) - 1; $relationResourceName = $relation->resourceName(); $type = $types[$relationResourceName]; $data['nodes'][$orderTarget] = [ 'id' => $relationId, 'title' => (string) $relation->displayTitle(null, $lang), 'type' => $type, 'class' => $relation->resourceClass() ? $relation->resourceClass()->label() : null, // TODO Fetch all totals in one sql query for all resources. 'total' => (in_array('objects', $relationTypes) ? count($relation->objectValues()) : 0) + (in_array('subjects', $relationTypes) && ($rsv = $relation->subjectValues()) ? count(array_merge(...array_values($rsv))) : 0) + (in_array('item_sets', $relationTypes) && $relationResourceName === 'item_sets' ? $api->search('items', ['item_set_id' => $relationId, 'limit' => 0])->getTotalResults() : 0) + (in_array('items', $relationTypes) && $relationResourceName === 'items' ? count($relation->itemSets()) : 0), ]; } $data['links'][] = [ 'source' => $orderSource, 'target' => $orderTarget, // TODO Compute value here? 'value' => 1, ]; } } $jsonUrlSite = json_encode($this->url('site', [], true), 320); $jsonData = json_encode($data, 448); $jsonConfig = json_encode($params['config'] ?? [], 448); $script = <<headScript()->appendScript($script); ?>