*/ class CategoryService extends ConfigurableService { const SERVICE_ID = 'taoItems/Category'; const ITEM_CLASS_URI = 'http://www.tao.lu/Ontologies/TAOItem.rdf#Item'; const EXPOSE_PROP_URI = 'http://www.tao.lu/Ontologies/TAOItem.rdf#ExposeCategory'; public static $supportedWidgetUris = [ 'http://www.tao.lu/datatypes/WidgetDefinitions.rdf#TextBox', 'http://www.tao.lu/datatypes/WidgetDefinitions.rdf#CheckBox', 'http://www.tao.lu/datatypes/WidgetDefinitions.rdf#RadioBox', 'http://www.tao.lu/datatypes/WidgetDefinitions.rdf#ComboBox', 'http://www.tao.lu/datatypes/WidgetDefinitions.rdf#TreeBox' ]; public static $excludedPropUris = [ 'http://www.tao.lu/Ontologies/TAOItem.rdf#ItemModel' ]; /** * @var taoItems_models_classes_ItemsService */ protected $itemService; /** * Get the categories link to the list of items in parameter. * Theses categories come from a configurable list of properties. * The category label is also set in a configurable list * * @param RdfResource[] $items the list of items * * @return array of categories for specified items * ['itemUri' => ['CATEGORY1', 'CATEGORY2']] */ public function getItemsCategories(array $items) { $categories = []; foreach ($items as $item) { $itemCategories = $this->getItemCategories($item); if (count($itemCategories) > 0) { $categories[$item->getUri()] = $itemCategories; } } return $categories; } /** * Get the categories of an item * * @param RdfResource $item the item * * @return string[] the list of categories */ public function getItemCategories(RdfResource $item) { $categories = []; foreach ($item->getTypes() as $class) { $eligibleProperties = array_filter($this->getElligibleProperties($class), [$this, 'doesExposeCategory']); $propertiesValues = $item->getPropertiesValues(array_keys($eligibleProperties)); foreach ($propertiesValues as $propertyValues) { foreach ($propertyValues as $value) { if ($value instanceof RdfResource) { $sanitizedIdentifier = self::sanitizeCategoryName($value->getLabel()); } else { $sanitizedIdentifier = self::sanitizeCategoryName((string)$value); } if ($sanitizedIdentifier) { $categories[] = $sanitizedIdentifier; } } } } return $categories; } /** * Sanitize the name of the category : * Remove special chars, allowing unicode ones, replace spaces by dashes * and trim the beginning if it's not a letter. * * @param string $value the input value * * @return string the sanitized value */ public static function sanitizeCategoryName($value) { $output = preg_replace('/\s+/', '-', trim($value)); $output = preg_replace('/[^\p{L}0-9\-]/u', '', mb_strtolower($output)); $output = preg_replace('/^[0-9\-_]+/', '', $output); return mb_substr($output, 0, 32); } /** * Get the properties from a class that can be exposed * * @param RdfClass $class the $class * * @return RdfProperty[] the list of eligible properties */ public function getElligibleProperties(RdfClass $class) { $properties = $this->getItemService()->getClazzProperties($class, new RdfClass(self::ITEM_CLASS_URI)); return array_filter( $properties, static function (RdfProperty $property) { if (in_array($property->getUri(), self::$excludedPropUris, true)) { return false; } $widget = $property->getWidget(); return null !== $widget && in_array($widget->getUri(), self::$supportedWidgetUris, true); } ); } /** * Check if a property is exposed * * @param RdfProperty $property the property to check * * @return bool true if exposed */ public function doesExposeCategory(RdfProperty $property) { $exposeProperty = new RdfProperty(self::EXPOSE_PROP_URI); $expose = $property->getOnePropertyValue($exposeProperty); return !is_null($expose) && $expose->getUri() === GenerisRdf::GENERIS_TRUE; } /** * Expose or not a property * * @param RdfProperty $property the property to check * @param bool $value true if exposed * * @return void */ public function exposeCategory(RdfProperty $property, $value) { $exposeProperty = new RdfProperty(self::EXPOSE_PROP_URI); if ($value == true) { $property->setPropertyValue($exposeProperty, GenerisRdf::GENERIS_TRUE); } else { $property->removePropertyValue($exposeProperty, GenerisRdf::GENERIS_TRUE); } } /** * Service getter and initializer. * * @return taoItems_models_classes_ItemsService the service */ public function getItemService() { if (is_null($this->itemService)) { $this->itemService = taoItems_models_classes_ItemsService::singleton(); } return $this->itemService; } /** * Service setter * * @param taoItems_models_classes_ItemsService $itemService the service * * @return void */ public function setItemService(taoItems_models_classes_ItemsService $itemService) { $this->itemService = $itemService; } }