instance = $instance; return $this; } public function create(core_kernel_classes_Property $property): ?tao_helpers_form_FormElement { //create the element from the right widget $property->feed(); $widgetResource = $property->getWidget(); if (null === $widgetResource) { return null; } $widgetUri = $widgetResource->getUri(); $propertyUri = $property->getUri(); //authoring widget is not used in standalone mode if ( $widgetUri === Authoring::WIDGET_ID && tao_helpers_Context::check('STANDALONE_MODE') ) { return null; } // horrible hack to fix file widget if ($widgetUri === AsyncFile::WIDGET_ID) { $widgetResource = new core_kernel_classes_Resource(GenerisAsyncFile::WIDGET_ID); } $element = tao_helpers_form_FormFactory::getElementByWidget( tao_helpers_Uri::encode($propertyUri), $widgetResource ); if (null === $element) { return null; } $parentProperty = $this->getParentProperty($property); if ($parentProperty) { $element->addAttribute('data-depends-on-property', tao_helpers_Uri::encode($parentProperty->getUri())); } if ($element->getWidget() !== $widgetUri) { common_Logger::w(sprintf( 'Widget definition differs from implementation: %s != %s', $element->getWidget(), $widgetUri )); return null; } //use the property label as element description $propDesc = (trim($property->getLabel()) !== '') ? $property->getLabel() : str_replace(LOCAL_NAMESPACE, '', $propertyUri); $element->setDescription($propDesc); //multi elements use the property range as options if (method_exists($element, 'setOptions')) { $range = $property->getRange(); if ($range !== null) { $options = []; if ($element instanceof TreeAware) { $sortedOptions = $element->rangeToTree( $propertyUri === OntologyRdfs::RDFS_RANGE ? new core_kernel_classes_Class(OntologyRdfs::RDFS_RESOURCE) : $range ); } else { if ($this->isList($range)) { $values = $this->getListValues($property, $range, $parentProperty); foreach ($values as $value) { $encodedUri = tao_helpers_Uri::encode($value->getUri()); $options[$encodedUri] = [$encodedUri, $value->getLabel()]; } } else { foreach ($range->getInstances(true) as $rangeInstance) { $level = $rangeInstance->getOnePropertyValue( new core_kernel_classes_Property(TaoOntology::PROPERTY_LIST_LEVEL) ); if (null === $level) { $encodedUri = tao_helpers_Uri::encode($rangeInstance->getUri()); $options[$encodedUri] = [$encodedUri, $rangeInstance->getLabel()]; } else { $level = ($level instanceof core_kernel_classes_Resource) ? $level->getUri() : (string)$level; $options[$level] = [ tao_helpers_Uri::encode($rangeInstance->getUri()), $rangeInstance->getLabel() ]; } } } ksort($options); $sortedOptions = []; foreach ($options as $id => $values) { $sortedOptions[$values[0]] = $values[1]; } //set the default value to an empty space if (method_exists($element, 'setEmptyOption')) { $element->setEmptyOption(' '); } } //complete the options listing $element->setOptions($sortedOptions); } } foreach (ValidationRuleRegistry::getRegistry()->getValidators($property) as $validator) { $element->addValidator($validator); } return $element; } private function isList($range): bool { if (!$range->isClass()) { return false; } return $range->isSubClassOf( new core_kernel_classes_Class(TaoOntology::CLASS_URI_LIST) ); } private function getValueCollectionService(): ValueCollectionService { /** @noinspection PhpIncompatibleReturnTypeInspection */ return $this->getServiceLocator()->get(ValueCollectionService::class); } private function getParentProperty(core_kernel_classes_Property $property): ?core_kernel_classes_Property { $collection = $property->getDependsOnPropertyCollection(); return $collection->offsetExists(0) ? $collection->offsetGet(0) : null; } private function getListValues( core_kernel_classes_Property $property, core_kernel_classes_Resource $range, core_kernel_classes_Property $parentProperty = null ): ValueCollection { $searchRequest = (new ValueCollectionSearchRequest())->setValueCollectionUri($range->getUri()); if ($this->instance instanceof core_kernel_classes_Resource) { $selectedValue = $this->instance->getOnePropertyValue($property); if ($selectedValue instanceof core_kernel_classes_Literal && !empty($selectedValue->literal)) { $searchRequest->setSelectedValues($selectedValue->literal); } if ($parentProperty) { $parentPropertyValues = []; foreach ($this->instance->getPropertyValuesCollection($parentProperty) as $parentPropertyValue) { $parentPropertyValues[] = (string)$parentPropertyValue; } $searchRequest->setPropertyUri($property->getUri()); $searchRequest->setParentListValues(...$parentPropertyValues); } } return $this->getValueCollectionService() ->findAll(new ValueCollectionSearchInput($searchRequest)); } }