Skip to content

Commit

Permalink
MetaData: implement vocab table data retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
schmitz-ilias committed Sep 26, 2024
1 parent 97df864 commit 37a4980
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 29 deletions.
1 change: 1 addition & 0 deletions Services/MetaData/classes/Services/InternalServices.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public function __construct(GlobalContainer $dic)
$this->data_helper_services
);
$this->vocabularies_services = new VocabulariesServices(
$this->dic,
$this->path_services,
$this->structure_services
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

namespace ILIAS\MetaData\Settings\Vocabularies\Import;

use ILIAS\MetaData\Vocabularies\Controlled\RepositoryInterface as ControlledVocabsRepository;
use ILIAS\MetaData\Vocabularies\Controlled\CreationRepositoryInterface as ControlledVocabsRepository;
use ILIAS\MetaData\Paths\PathInterface;
use ILIAS\MetaData\Paths\FactoryInterface as PathFactory;
use ILIAS\MetaData\Vocabularies\Slots\Identifier as SlotIdentifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,54 @@
use ILIAS\UI\Component\Table\DataRowBuilder;
use ILIAS\Data\Range;
use ILIAS\Data\Order;
use ILIAS\MetaData\Vocabularies\Manager\Manager as VocabManager;
use ILIAS\MetaData\Presentation\ElementsInterface as ElementsPresentation;
use ILIAS\MetaData\Presentation\UtilitiesInterface as PresentationUtilities;
use ILIAS\MetaData\Vocabularies\Dispatch\Presentation\PresentationInterface as VocabPresentation;
use ILIAS\MetaData\Vocabularies\VocabularyInterface;
use ILIAS\MetaData\Vocabularies\Type as VocabType;
use ILIAS\MetaData\Vocabularies\Slots\HandlerInterface as SlotHandler;
use ILIAS\MetaData\Vocabularies\Slots\Identifier as SlotIdentifier;
use ILIAS\MetaData\Elements\Structure\StructureSetInterface as Structure;
use ILIAS\MetaData\Paths\Navigator\NavigatorFactoryInterface as NavigatorFactory;
use ILIAS\MetaData\Paths\PathInterface;
use ILIAS\MetaData\Elements\Structure\StructureElementInterface;
use ILIAS\MetaData\Elements\Data\Type as DataType;
use ILIAS\MetaData\Vocabularies\Slots\Conditions\ConditionInterface;

class ilMDVocabulariesDataRetrieval implements DataRetrieval
{
protected const MAX_PREVIEW_VALUES = 5;

protected VocabManager $vocab_manager;
protected ElementsPresentation $elements_presentation;
protected PresentationUtilities $presentation_utils;
protected VocabPresentation $vocab_presentation;
protected SlotHandler $slot_handler;
protected Structure $structure;
protected NavigatorFactory $navigator_factory;

/**
* @var VocabularyInterface[]
*/
protected array $vocabs;

public function __construct(
VocabManager $vocab_manager,
ElementsPresentation $elements_presentation,
PresentationUtilities $presentation_utils,
VocabPresentation $vocab_presentation,
SlotHandler $slot_handler,
Structure $structure
) {
$this->vocab_manager = $vocab_manager;
$this->elements_presentation = $elements_presentation;
$this->presentation_utils = $presentation_utils;
$this->vocab_presentation = $vocab_presentation;
$this->slot_handler = $slot_handler;
$this->structure = $structure;
}

public function getRows(
DataRowBuilder $row_builder,
array $visible_column_ids,
Expand All @@ -33,11 +78,160 @@ public function getRows(
?array $filter_data,
?array $additional_parameters
): Generator {
yield from [];
$infos = $this->vocab_manager->infos();
foreach ($this->getVocabs($range) as $vocab) {
$record = [];

$record['element'] = $this->translateSlot($vocab->slot());
$record['type'] = $this->translateType($vocab->type());
$record['source'] = $vocab->source();
$record['preview'] = $this->buildValuesPreview($vocab);
$record['active'] = $vocab->isActive();
if ($infos->isCustomInputApplicable($vocab)) {
$record['custom_input'] = $vocab->allowsCustomInputs();
}

yield $row_builder->buildDataRow(
$vocab->id(),
$record
)->withDisabledAction(
'delete',
!$infos->canBeDeleted($vocab)
)->withDisabledAction(
'toggle_active',
$vocab->isActive() && !$infos->isDeactivatable($vocab)
)->withDisabledAction(
'toggle_custom_input',
$infos->canDisallowCustomInput($vocab)
);
};
}

public function getTotalRowCount(?array $filter_data, ?array $additional_parameters): ?int
{
return 0;
return count($this->getVocabs());
}

protected function translateType(VocabType $type): string
{
return match ($type) {
VocabType::STANDARD => $this->presentation_utils->txt('md_vocab_type_standard'),
VocabType::CONTROLLED_STRING => $this->presentation_utils->txt('md_vocab_type_controlled_string'),
VocabType::CONTROLLED_VOCAB_VALUE => $this->presentation_utils->txt('md_vocab_type_controlled_vocab_value'),
VocabType::COPYRIGHT => $this->presentation_utils->txt('md_vocab_type_copyright'),
default => '',
};
}

protected function translateSlot(SlotIdentifier $slot): string
{
//skip the name of the element if it does not add any information
$skip_data = [DataType::VOCAB_VALUE, DataType::STRING];

$element = $this->getStructureElementFromPath(
$this->slot_handler->pathForSlot($slot),
$this->structure->getRoot()
);
$element_name = $this->elements_presentation->nameWithParents(
$element,
null,
false,
in_array($element->getDefinition()->dataType(), $skip_data),
);

if (!$this->slot_handler->isSlotConditional($slot)) {
return $element_name;
}

$condition = $this->slot_handler->conditionForSlot($slot);

$condition_element = $this->getStructureElementFromPath(
$condition->path(),
$element
);
$condition_element_name = $this->elements_presentation->nameWithParents(
$element,
$this->findFirstCommonParent($element, $condition_element)->getSuperElement(),
false,
in_array($element->getDefinition()->dataType(), $skip_data),
);

return $this->presentation_utils->txtFill(
'md_vocab_element_with_condition',
$element_name,
$condition_element_name,
$this->translateConditionValue($condition)
);
}

protected function translateConditionValue(ConditionInterface $condition): string
{
$slot = $this->slot_handler->identiferFromPathAndCondition($condition->path(), null, null);
return (string) $this->vocab_presentation->presentableLabels(
$this->presentation_utils,
$slot,
false,
$condition->value()
)->current()?->label();
}

protected function findFirstCommonParent(
StructureElementInterface $a,
StructureElementInterface $b
): StructureElementInterface {
while ($a !== $b) {
$a = $a->getSuperElement();
$b = $b->getSuperElement();
}
return $a;
}

protected function getStructureElementFromPath(
PathInterface $path,
StructureElementInterface $start
): StructureElementInterface {
return $this->navigator_factory->structureNavigator(
$path,
$start
)->elementAtFinalStep();
}

protected function buildValuesPreview(VocabularyInterface $vocabulary): string
{
$presentable_values = [];
$i = 0;

$labelled_values = $this->vocab_presentation->labelsForVocabulary(
$this->presentation_utils,
$vocabulary
);
foreach ($labelled_values as $labelled_value) {
if ($i >= self::MAX_PREVIEW_VALUES) {
$presentable_values[] = '...';
break;
}

$presentable_value = $labelled_value->value();
if ($labelled_value->label() !== '') {
$presentable_value = $labelled_value->label() . ' (' . $presentable_value . ')';
}
$presentable_values[] = $presentable_value;
}

return implode(', ', $presentable_values);
}

protected function getVocabs(Range $range = null): array
{
if (isset($this->vocabs)) {
return $this->vocabs;
}

$vocabs = iterator_to_array($this->vocab_manager->getAllVocabularies());
if ($range) {
$vocabs = array_slice($vocabs, $range->getStart(), $range->getLength());
}

return $this->vocabs = $vocabs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
use ILIAS\Data\URI;
use ILIAS\FileUpload\MimeType;
use ILIAS\Filesystem\Filesystem;
use ILIAS\MetaData\Vocabularies\Controlled\RepositoryInterface as ControlledVocabsRepository;
use ILIAS\MetaData\Vocabularies\Manager\ManagerInterface as VocabManager;
use ILIAS\MetaData\Paths\FactoryInterface as PathFactory;
use ILIAS\MetaData\Settings\Vocabularies\Import\Importer;
use ILIAS\MetaData\Vocabularies\Slots\HandlerInterface as SlotHandler;
Expand All @@ -42,7 +42,7 @@ class ilMDVocabulariesGUI
protected ilCtrl $ctrl;
protected HTTP $http;
protected Filesystem $temp_files;
protected ControlledVocabsRepository $controlled_vocab_repo;
protected VocabManager $vocab_manager;
protected PathFactory $path_factory;
protected SlotHandler $slot_handler;
protected ilGlobalTemplateInterface $tpl;
Expand Down Expand Up @@ -156,7 +156,7 @@ public function importVocabulary(): void
if (!is_null($file_content)) {
$importer = new Importer(
$this->path_factory,
$this->controlled_vocab_repo,
$this->vocab_manager->controlledVocabularyCreator(),
$this->slot_handler
);
$result = $importer->import($file_content);
Expand Down
19 changes: 11 additions & 8 deletions Services/MetaData/classes/Vocabularies/Controlled/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ public function create(
if ($source === '') {
throw new \ilMDVocabulariesException('Source cannot be empty.');
}
$this->checkSlot($slot);
if (!$this->isSlotValid($slot)) {
throw new \ilMDVocabulariesException(
'Slot ' . $slot->value . ' is not available for controlled vocabularies.'
);
}

$id = $this->db->nextId('il_md_vocab_contr');

Expand Down Expand Up @@ -162,6 +166,10 @@ public function getLabelsForValues(
SlotIdentifier $slot,
string ...$values
): \Generator {
if (!$this->isSlotValid($slot)) {
return;
}

$result = $this->db->query(
'SELECT value, label FROM il_md_vocab_contr_values JOIN il_md_vocab_contr ON vocab_id
WHERE slot = ' . $this->db->quoteAsString($slot->value) . ' AND ' .
Expand Down Expand Up @@ -274,7 +282,7 @@ protected function readVocabularyValues(string $vocab_id): \Generator
}
}

protected function checkSlot(SlotIdentifier $slot): void
protected function isSlotValid(SlotIdentifier $slot): bool
{
$valid_slots = [
SlotIdentifier::NULL,
Expand Down Expand Up @@ -308,11 +316,6 @@ protected function checkSlot(SlotIdentifier $slot): void
SlotIdentifier::CLASSIFICATION_TAXON_ENTRY
];

if (in_array($slot, $valid_slots, true)) {
return;
}
throw new \ilMDVocabulariesException(
'Slot ' . $slot->value . ' is not available for controlled vocabularies.'
);
return in_array($slot, $valid_slots, true);
}
}
2 changes: 1 addition & 1 deletion Services/MetaData/classes/Vocabularies/Manager/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function actions(): ActionsInterface
return $this->actions;
}

public function createControlledVocabulary(): CreationRepositoryInterface
public function controlledVocabularyCreator(): CreationRepositoryInterface
{
return $this->creation_repo;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ public function infos(): InfosInterface;

public function actions(): ActionsInterface;

public function createControlledVocabulary(): CreationRepositoryInterface;
public function controlledVocabularyCreator(): CreationRepositoryInterface;
}
26 changes: 13 additions & 13 deletions Services/MetaData/classes/Vocabularies/Services/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ class Services
{
protected PresentationInterface $presentation;
protected ManagerInterface $manager;
protected SlotHandler $slot_handler;

protected ReaderInterface $reader;
protected CopyrightBridge $copyright_bridge;
protected FactoryInterface $factory;
protected SlotHandler $slot_handler;
protected ControlledRepositoryInterface $controlled_repository;
protected StandardRepositoryInterface $standard_repository;

Expand Down Expand Up @@ -106,6 +106,18 @@ public function manager(): ManagerInterface
);
}

public function slotHandler(): SlotHandler
{
if (isset($this->slot_handler)) {
return $this->slot_handler;
}
return $this->slot_handler = new SlotHandler(
$this->path_services->pathFactory(),
$this->path_services->navigatorFactory(),
$this->structure_services->structure(),
);
}

protected function reader(): ReaderInterface
{
if (isset($this->reader)) {
Expand Down Expand Up @@ -162,16 +174,4 @@ protected function factory(): FactoryInterface
}
return $this->factory = new Factory();
}

protected function slotHandler(): SlotHandler
{
if (isset($this->slot_handler)) {
return $this->slot_handler;
}
return $this->slot_handler = new SlotHandler(
$this->path_services->pathFactory(),
$this->path_services->navigatorFactory(),
$this->structure_services->structure(),
);
}
}

0 comments on commit 37a4980

Please sign in to comment.