* @package tao * @see core_kernel_classes_* packages */ class tao_helpers_form_GenerisFormFactory { // --- ASSOCIATIONS --- // --- ATTRIBUTES --- // --- OPERATIONS --- /** * Enable you to map an rdf property to a form element using the Widget * * @access public * @author Bertrand Chevrier, * * @param core_kernel_classes_Property $property * * @return tao_helpers_form_FormElement * * @throws common_Exception * @throws common_exception_Error * @throws core_kernel_persistence_Exception */ public static function elementMap(core_kernel_classes_Property $property): ?tao_helpers_form_FormElement { //create the element from the right widget $property->feed(); $widgetResource = $property->getWidget(); //authoring widget is not used in standalone mode if ( null === $widgetResource || $widgetResource->getUri() === Authoring::WIDGET_ID && tao_helpers_Context::check('STANDALONE_MODE') ) { return null; } // horrible hack to fix file widget if ($widgetResource->getUri() === AsyncFile::WIDGET_ID) { $widgetResource = new core_kernel_classes_Resource(GenerisAsyncFile::WIDGET_ID); } $element = tao_helpers_form_FormFactory::getElementByWidget(tao_helpers_Uri::encode($property->getUri()), $widgetResource); if (null === $element) { return null; } if ($element->getWidget() !== $widgetResource->getUri()) { common_Logger::w('Widget definition differs from implementation: ' . $element->getWidget() . ' != ' . $widgetResource->getUri()); return null; } //use the property label as element description $propDesc = trim($property->getLabel()) !== '' ? $property->getLabel() : str_replace(LOCAL_NAMESPACE, '', $property->getUri()); $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( $property->getUri() === OntologyRdfs::RDFS_RANGE ? new core_kernel_classes_Class(OntologyRdfs::RDFS_RESOURCE) : $range ); } else { foreach ($range->getInstances(true) as $rangeInstance) { $level = $rangeInstance->getOnePropertyValue(new core_kernel_classes_Property(TaoOntology::PROPERTY_LIST_LEVEL)); if (is_null($level)) { $options[tao_helpers_Uri::encode($rangeInstance->getUri())] = [tao_helpers_Uri::encode($rangeInstance->getUri()), $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; } /** * Enable you to get the properties of a class. * The advantage of this method is to limit the level of recusrivity in the * It get the properties up to the defined top class * * @access public * @author Bertrand Chevrier, * @param core_kernel_classes_Class $clazz * @param core_kernel_classes_Class $topLevelClazz * @return array */ public static function getClassProperties( core_kernel_classes_Class $clazz, core_kernel_classes_Class $topLevelClazz = null ): array { if (null === $topLevelClazz) { $topLevelClazz = new core_kernel_classes_Class(TaoOntology::CLASS_URI_OBJECT); } if ($clazz->getUri() === $topLevelClazz->getUri()) { return $clazz->getProperties(false); } //determine the parent path $parents = []; $top = false; do { if (!isset($lastLevelParents)) { $parentClasses = $clazz->getParentClasses(false); } else { $parentClasses = []; foreach ($lastLevelParents as $parent) { $parentClasses = array_merge($parentClasses, $parent->getParentClasses(false)); } } if (empty($parentClasses)) { break; } $lastLevelParents = []; foreach ($parentClasses as $parentClass) { if ($parentClass->getUri() === OntologyRdfs::RDFS_CLASS) { continue; } if ($parentClass->getUri() === $topLevelClazz->getUri()) { $parents[$parentClass->getUri()] = $parentClass; $top = true; break; } $allParentClasses = $parentClass->getParentClasses(true); if (array_key_exists($topLevelClazz->getUri(), $allParentClasses)) { $parents[$parentClass->getUri()] = $parentClass; } $lastLevelParents[$parentClass->getUri()] = $parentClass; } } while (!$top); $propertyChunks = [[]]; foreach ($parents as $parent) { $propertyChunks[] = $parent->getProperties(false); } $propertyChunks[] = $clazz->getProperties(false); return array_merge(...$propertyChunks); } /** * get the default properties to add to every forms * * @access public * @author Bertrand Chevrier, * @return array */ public static function getDefaultProperties(): array { return [ new core_kernel_classes_Property(OntologyRdfs::RDFS_LABEL) ]; } /** * Get the properties of the rdfs Property class * * @access public * @author Bertrand Chevrier, * @param string mode * @return array */ public static function getPropertyProperties($mode = 'simple'): array { $returnValue = []; switch ($mode) { case 'simple': $defaultUris = [GenerisRdf::PROPERTY_IS_LG_DEPENDENT]; break; case 'advanced': default: $defaultUris = [ OntologyRdfs::RDFS_LABEL, WidgetRdf::PROPERTY_WIDGET, OntologyRdfs::RDFS_RANGE, GenerisRdf::PROPERTY_IS_LG_DEPENDENT ]; break; } $resourceClass = new core_kernel_classes_Class(OntologyRdf::RDF_PROPERTY); foreach ($resourceClass->getProperties() as $property) { if (in_array($property->getUri(), $defaultUris, true)) { $returnValue[] = $property; } } return $returnValue; } /** * Return the map between the Property properties: range, widget, etc. to * shortcuts for the simplePropertyEditor * * @author Bertrand Chevrier, */ public static function getPropertyMap(): array { return [ 'text' => [ 'title' => __('Text - Short - Field'), 'widget' => TextBox::WIDGET_ID, 'range' => OntologyRdfs::RDFS_LITERAL, 'multiple' => GenerisRdf::GENERIS_FALSE, ], 'longtext' => [ 'title' => __('Text - Long - Box'), 'widget' => TextArea::WIDGET_ID, 'range' => OntologyRdfs::RDFS_LITERAL, 'multiple' => GenerisRdf::GENERIS_FALSE, ], 'html' => [ 'title' => __('Text - Long - HTML editor'), 'widget' => HtmlArea::WIDGET_ID, 'range' => OntologyRdfs::RDFS_LITERAL, 'multiple' => GenerisRdf::GENERIS_FALSE, ], 'list' => [ 'title' => __('List - Single choice - Radio button'), 'widget' => RadioBox::WIDGET_ID, 'range' => OntologyRdfs::RDFS_RESOURCE, 'multiple' => GenerisRdf::GENERIS_FALSE, 'depends-on-property' => GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY, ], 'multiplenodetree' => [ 'title' => __('Tree - Multiple node choice '), 'widget' => TreeBox::WIDGET_ID, 'range' => OntologyRdfs::RDFS_RESOURCE, 'multiple' => GenerisRdf::GENERIS_TRUE, ], 'longlist' => [ 'title' => __('List - Single choice - Drop down'), 'widget' => ComboBox::WIDGET_ID, 'range' => OntologyRdfs::RDFS_RESOURCE, 'multiple' => GenerisRdf::GENERIS_FALSE, 'depends-on-property' => GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY, ], 'multilist' => [ 'title' => __('List - Multiple choice - Check box'), 'widget' => Checkbox::WIDGET_ID, 'range' => OntologyRdfs::RDFS_RESOURCE, 'multiple' => GenerisRdf::GENERIS_TRUE, 'depends-on-property' => GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY, ], 'multisearchlist' => [ 'title' => __('List - Multiple choice - Search input'), 'widget' => SearchTextBox::WIDGET_ID, 'range' => OntologyRdfs::RDFS_RESOURCE, 'multiple' => GenerisRdf::GENERIS_TRUE, 'depends-on-property' => GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY, ], 'singlesearchlist' => [ 'title' => __('List - Single choice - Search input'), 'widget' => SearchDropdown::WIDGET_ID, 'range' => OntologyRdfs::RDFS_RESOURCE, 'multiple' => GenerisRdf::GENERIS_FALSE, 'depends-on-property' => GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY, ], 'calendar' => [ 'title' => __('Calendar'), 'widget' => Calendar::WIDGET_ID, 'range' => OntologyRdfs::RDFS_LITERAL, 'multiple' => GenerisRdf::GENERIS_FALSE, ], 'password' => [ 'title' => __('Password'), 'widget' => HiddenBox::WIDGET_ID, 'range' => OntologyRdfs::RDFS_LITERAL, 'multiple' => GenerisRdf::GENERIS_FALSE, ], 'file' => [ 'title' => __('File'), 'widget' => AsyncFile::WIDGET_ID, 'range' => GenerisRdf::CLASS_GENERIS_FILE, 'multiple' => GenerisRdf::GENERIS_FALSE, ], ]; } /** * Short description of method extractTreeData * * @access public * @author Bertrand Chevrier, * @param array $data * @return array */ public static function extractTreeData($data): array { $returnValue = []; if (isset($data['data'])) { $data = [$data]; } foreach ($data as $node) { $returnValue[$node['attributes']['id']] = $node['data']; if (isset($node['children'])) { $returnValue = array_merge($returnValue, self::extractTreeData($node['children'])); } } return $returnValue; } }