diff options
Diffstat (limited to 'lib/models/resources/ResourceCategory.class.php')
| -rw-r--r-- | lib/models/resources/ResourceCategory.class.php | 806 |
1 files changed, 0 insertions, 806 deletions
diff --git a/lib/models/resources/ResourceCategory.class.php b/lib/models/resources/ResourceCategory.class.php deleted file mode 100644 index f4ae14d..0000000 --- a/lib/models/resources/ResourceCategory.class.php +++ /dev/null @@ -1,806 +0,0 @@ -<?php - -/** - * ResourceCategory.class.php - model class for resource categories - * - * The ResourceCategory class can be used as a Factory for - * Resource objects. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * @author Moritz Strohm <strohm@data-quest.de> - * @copyright 2017 - * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2 - * @category Stud.IP - * @package resources - * @since 4.1 - * - * @property string $id database column - * @property string $name database column - * @property string $description database column - * @property int $system database column - * @property int|null $iconnr database column - * @property string $class_name database column - * @property int $mkdate database column - * @property int $chdate database column - * @property SimpleORMapCollection|ResourceCategoryProperty[] $property_links has_many ResourceCategoryProperty - * @property SimpleORMapCollection|ResourcePropertyDefinition[] $property_definitions has_and_belongs_to_many ResourcePropertyDefinition - */ -class ResourceCategory extends SimpleORMap -{ - private static $cache; - - protected static function configure($config = []) - { - $config['db_table'] = 'resource_categories'; - - $config['has_and_belongs_to_many']['property_definitions'] = [ - 'class_name' => ResourcePropertyDefinition::class, - 'assoc_foreign_key' => 'property_id', - 'thru_table' => 'resource_category_properties', - 'thru_key' => 'category_id', - 'order_by' => 'ORDER BY name ASC' - ]; - - $config['has_many']['property_links'] = [ - 'class_name' => ResourceCategoryProperty::class, - 'assoc_func' => 'findByCategory_id', - 'foreign_key' => 'id', - 'on_delete' => 'delete' - ]; - - $config['registered_callbacks']['after_create'][] = function ($category) { - self::$cache[$category->id] = $category; - }; - $config['registered_callbacks']['after_store'][] = function ($category) { - self::$cache[$category->id] = $category; - }; - $config['registered_callbacks']['after_delete'][] = function ($category) { - unset(self::$cache[$category->id]); - }; - - parent::configure($config); - } - - /** - * Retrieves all resource categories from the database. - * @param bool $force_reload - * @return ResourceCategory[] An array of ResourceCategory objects - * or an empty array if no resource categories are defined. - */ - public static function findAll($force_reload = false) - { - if (!is_array(self::$cache) || $force_reload) { - self::$cache = []; - foreach (self::findBySql('1 ORDER BY name') as $one) { - self::$cache[$one->id] = $one; - } - } - return self::$cache; - } - - public static function find($id) - { - $all = self::findAll(); - return $all[$id] ?: null; - } - - /** - * "Converts" a category-ID to a class name by looking up the - * class name of a specified category. - * - * @param string $category_id The category-ID of the specified category. - * - * @return string The class name field of the category which is specified - * by $category_id. In case no category could be found, an empty - * string is returned. - */ - public static function getClassNameById($category_id) - { - $category = self::find($category_id); - if ($category) { - return $category->class_name; - } - return ''; - } - - public function hasResources() - { - $db = DBManager::get(); - $stmt = $db->prepare( - "SELECT 1 FROM resources WHERE category_id = :category_id LIMIT 1" - ); - $stmt->execute(['category_id' => $this->id]); - return $stmt->fetchColumn() !== false; - } - - /** - * Retrieves the definitions of all properties that are available - * for this resource category. - * - * @param string[] excluded_properties An array with the names - * of the properties that shall be excluded from the result set. - * - * @return ResourcePropertyDefinition[] An array of resource property - * definitions. - */ - public function getPropertyDefinitions($excluded_properties = []) - { - if (is_array($excluded_properties) && count($excluded_properties)) { - return ResourcePropertyDefinition::findBySql( - "INNER JOIN resource_category_properties rcp - ON resource_property_definitions.property_id = rcp.property_id - WHERE - rcp.category_id = :category_id - AND resource_property_definitions.name NOT IN ( - :excluded_properties - ) - ORDER BY resource_property_definitions.name ASC", - [ - 'category_id' => $this->id, - 'excluded_properties' => $excluded_properties - ] - ); - } - - //No excluded properties are specified. - //We can return all property definitions. - return ResourcePropertyDefinition::findBySql( - "INNER JOIN resource_category_properties rcp - ON resource_property_definitions.property_id = rcp.property_id - WHERE - rcp.category_id = :category_id - ORDER BY resource_property_definitions.name ASC", - [ - 'category_id' => $this->id - ] - ); - } - - /** - * This method returns the same properties as getPropertyDefinitions, - * but grouped and ordered by the property groups and the position of the - * property in that group. - * - * @return array An array with the group names as keys and the properties - * in the second array dimension. The structure of the array - * is as follows: - * [ - * group1 name => [ - * property1, - * property2, - * ... - * ], - * group2 name => [ - * ... - * ] - * ] - */ - public function getGroupedPropertyDefinitions($excluded_properties = []) - { - if (is_array($excluded_properties) && count($excluded_properties)) { - $definitions = ResourcePropertyDefinition::findBySql( - "INNER JOIN resource_category_properties rcp - ON resource_property_definitions.property_id = rcp.property_id - LEFT JOIN resource_property_groups rpg - ON resource_property_definitions.property_group_id = rpg.id - WHERE - rcp.category_id = :category_id - AND resource_property_definitions.name NOT IN ( - :excluded_properties - ) - ORDER BY - type DESC, rpg.position ASC, rpg.name ASC, - resource_property_definitions.property_group_pos, - resource_property_definitions.name ASC", - [ - 'category_id' => $this->id, - 'excluded_properties' => $excluded_properties - ] - ); - - $empty_index = _('Sonstige'); - $empty_property_group = [ - $empty_index => [] - ]; - $property_groups = []; - foreach ($definitions as $definition) { - if ($definition->group && $definition->group->name) { - $group_name = $definition->group->name; - if (!is_array($property_groups[$group_name])) { - $property_groups[$group_name] = []; - } - $property_groups[$group_name][] = $definition; - } else { - $empty_property_group[$empty_index][] = $definition; - } - } - if ($empty_property_group[$empty_index]) { - return array_merge($property_groups, $empty_property_group); - } else { - return $property_groups; - } - } - - //No excluded properties are specified. - //We can return all property definitions. - $definitions = ResourcePropertyDefinition::findBySql( - "INNER JOIN resource_category_properties rcp - ON resource_property_definitions.property_id = rcp.property_id - LEFT JOIN resource_property_groups rpg - ON resource_property_definitions.property_group_id = rpg.id - WHERE - rcp.category_id = :category_id - ORDER BY - rpg.position ASC, rpg.name ASC, - resource_property_definitions.property_group_pos, - resource_property_definitions.name ASC", - [ - 'category_id' => $this->id - ] - ); - - $empty_index = _('Sonstige'); - $empty_property_group = [ - $empty_index => [] - ]; - $property_groups = []; - foreach ($definitions as $definition) { - if ($definition->group->name) { - $group_name = $definition->group->name; - if (!is_array($property_groups[$group_name])) { - $property_groups[$group_name] = []; - } - $property_groups[$group_name][] = $definition; - } else { - $empty_property_group[$empty_index][] = $definition; - } - } - if ($empty_property_group[$empty_index]) { - return array_merge($property_groups, $empty_property_group); - } else { - return $property_groups; - } - } - - /** - * Adds a property to this category. If the property doesn't exist - * it will be created. - * - * @param string $name The name of the property. - * @param string $type The type of the property. - * @param bool $requestable Whether the property is requestable or not. - * Defaults to false. - * @param bool $protected Whether the property is protected or not. - * Defaults to false. - * @param string $write_permission_level - * @return ResourceCategoryProperty The created or updated - * resource category property. - * @throws ResourcePropertyDefinitionException If the property definition - * cannot be created. - * - * @throws ResourcePropertyException If the property cannot be created. - */ - public function addProperty( - $name = '', - $type = 'bool', - $requestable = false, - $protected = false, - $write_permission_level = 'autor' - ) - { - if (!$name) { - throw new ResourcePropertyException( - _('Es wurde kein Name für die Eigenschaft angegeben!') - ); - } - - $defined_types = ResourcePropertyDefinition::getDefinedTypes(); - - if (!in_array($type, $defined_types)) { - throw new ResourcePropertyException( - sprintf( - _('Der Eigenschaftstyp %s ist ungültig!'), - $type - ) - ); - } - - if (!in_array($write_permission_level, ['user', 'autor', 'tutor', 'admin'])) { - throw new ResourcePropertyException( - sprintf( - _('Die Rechtestufe %s ist ungültig!'), - $write_permission_level - ) - ); - } - - $existing_property = ResourceCategoryProperty::findOneBySql( - 'INNER JOIN resource_property_definitions rpd - ON resource_category_properties.property_id = rpd.property_id - WHERE - resource_category_properties.category_id = :category_id - AND - rpd.name = :name - AND - rpd.type = :type', - [ - 'category_id' => $this->id, - 'name' => $name, - 'type' => $type - ] - ); - - if ($existing_property) { - $existing_property->requestable = $requestable ? '1' : '0'; - $existing_property->protected = $protected ? '1' : '0'; - if ($existing_property->isDirty() && !$existing_property->store()) { - throw new ResourcePropertyException( - sprintf( - _('Fehler beim Aktualisieren der Eigenschaft %1$s (vom Typ %2$s)!'), - $name, - $type - ) - ); - } - return $existing_property; - } else { - $definition = ResourcePropertyDefinition::findOneBySql( - 'name = :name AND type = :type', - [ - 'name' => $name, - 'type' => $type - ] - ); - - if (!$definition) { - $definition = new ResourcePropertyDefinition(); - $definition->name = $name; - $definition->type = $type; - if (!$definition->store()) { - throw new ResourcePropertyDefinitionException( - sprintf( - _('Fehler beim Speichern der Definition der Eigenschaft %1$s (vom Typ %2$s)!'), - $name, - $type - ) - ); - } - } - - $property = new ResourceCategoryProperty(); - $property->property_id = $definition->id; - $property->category_id = $this->id; - $property->requestable = $requestable ? '1' : '0'; - $property->protected = $protected ? '1' : '0'; - - if ($property->store()) { - return $property; - } else { - throw new ResourcePropertyException( - sprintf( - _('Fehler beim Speichern der neuen Eigenschaft %1$s (vom Typ %2$s)!'), - $name, - $type - ) - ); - } - } - } - - /** - * Creates a resource object which belongs to this category. - * All properties which are mandatory for resources of this - * category are set to default values unless they are specified in the - * properties array. - * - * @param string $name The name of the new resource. - * @param string $description The description of the new resource. - * @param string $parent_id The parent resource's ID (if any). - * @param array $properties An associative array in the form [$key] = $value - * containing the defined properties which can be set to this resource. - * @param bool $ignore_invalid If set to true, invalid values or invalid - * property names are ignored and no exception is thrown if an invalid - * value or property name occurs. Instead an invalid valud will be replaced - * with a default value and an invalid property name will not result - * in a set property. - * - * @return Resource New Resource object which is a member of this resource category. - * @throws InvalidResourceException if the resource cannot be stored. - * @throws ResourcePropertyException If the name of the resource property - * is not defined for this resource category. - * @throws InvalidResourceCategoryException if the class_name attribute of - * the resource category contains a class name of a class which is not - * derived from the Resource class. - */ - public function createResource( - $name = '', - $description = '', - $parent_id = '', - $properties = [], - $ignore_invalid = false - ) - { - if (($this->class_name != 'Resource') and - !is_subclass_of($this->class_name, 'Resource')) { - //Invalid resource category specification: - //All class names for a resource category must be derived from the - //resource class! - throw new InvalidResourceCategoryException( - sprintf( - _('Die Ressourcenkategorie %1$s ist ungültig, da die dort angegebene Klasse %2$s nicht von der Klasse Resource abgeleitet ist!'), - $this->name, - $this->class_name - ) - ); - } - - $resource = new $this->class_name; - $resource->parent_id = $parent_id; - $resource->category_id = $this->id; - $resource->name = $name; - $resource->description = $description; - - if (!$resource->store()) { - throw new InvalidResourceException( - sprintf( - _('Fehler beim Speichern der Resource %1$s!'), - $resource->name - ) - ); - } - - //The resource is stored. We can now store its attributes: - if ($properties) { - foreach ($properties as $name => $state) { - try { - $resource->setProperty($name, $state); - } catch (ResourcePropertyException $e) { - if (!$ignore_invalid) { - throw $e; - } - } - } - } - - return $resource; - } - - /** - * Returns the default state for a resource property. - * Depending on the type of the resource property - * different state is returned. - * - * @param ResourcePropertyDefinition $definition The definition of a - * resource property whose default state shall be returned. - * - * @return mixed The default state for the property type, - * specified by the given property definition. - */ - protected function setPropertyDefaultState( - ResourcePropertyDefinition $definition - ) - { - switch ($definition->type) { - case 'bool': - return false; - case 'num': - return 0; - case 'select': - //Set the first option as default. - //For that, we have to split the option list first, - //since it containts semicolon separated values: - $options = explode(';', $definition->options); - return $options[0]; - case 'user': - //Return the ID of the current user: - return User::findCurrent()->id; - case 'position': - return '+0.0+0.0+0.0CRSWGS_84/'; - case 'institute': - case 'fileref': - case 'url': - case 'text': - return ''; - } - } - - /** - * Creates a ResourceProperty object for a specified Resource object. - * - * @param Resource $resource The resource for which the ResourceProperty - * object shall be built. - * @param string $name The name of the property. - * @param string $state The value of the property. - * - * @return ResourceProperty A ResourceProperty object - * for the given Resource object. - * @throws ResourcePropertyException If the name of the resource property - * is not defined for this resource category. - * - * @throws InvalidResourceCategoryException If this resource category - * doesn't match the category of the resource object. - */ - public function createDefinedResourceProperty(Resource $resource, $name, $state = null) - { - if ($resource->category_id != $this->id) { - throw new InvalidResourceCategoryException( - sprintf( - _('Die Ressource %1$s ist kein Mitglied der Ressourcenkategorie %2$s!'), - $resource->name, - $this->name - ) - ); - } - - if (!$resource->id) { - //The resource has no ID: probably it is a new resource. - if ($resource->isNew()) { - //We need an ID so we have to create one: - $resource->getNewId(); - } else { - throw new InvalidResourceException( - sprintf( - _('Die Ressource %1$s besitzt keine ID!'), - $resource->name - ) - ); - } - } - - - //get property definition: - $definition = ResourcePropertyDefinition::findOneBySql( - 'INNER JOIN resource_category_properties rcp - ON rcp.property_id = resource_property_definitions.property_id - WHERE category_id = :category_id - AND name = :name - LIMIT 1', - [ - 'category_id' => $this->id, - 'name' => $name - ] - ); - - if (!$definition) { - //Property is undefined for this resource category: - throw new ResourcePropertyException( - sprintf( - _('Die Eigenschaft %1$s ist für die Ressourcenkategorie %2$s nicht definiert!'), - $name, - $this->name - ) - ); - } - - $property = new ResourceProperty(); - $property->resource_id = $resource->id; - $property->property_id = $definition->id; - - //if state is not set we can set it to defined default values - //for some state types: - if ($state === null) { - $property->state = self::setPropertyDefaultState($definition); - } else { - $property->state = $state; - } - - return $property; - } - - /** - * Creates a ResourceRequestProperty object - * for a specified ResourceRequest object. - * - * @param ResourceRequest $request The resource request for which the - * ResourceRequestProperty object shall be built. - * @param string $name The name of the property. - * @param string $state The value of the property. - * - * @return ResourceRequestProperty A ResourceProperty object for the - * given Resource object. - * @throws ResourcePropertyException If the name of the resource property is - * not defined for the resource category of the resource request. - * - * @throws InvalidResourceCategoryException If this resource category - * doesn't match the resource category of the resource request object. - */ - public function createDefinedResourceRequestProperty( - ResourceRequest $request, - $name, - $state = null - ) - { - if ($request->category_id != $this->id) { - throw new InvalidResourceCategoryException( - sprintf( - _('Die Resourcenanfrage %1$s ist kein Mitglied der Ressourcenkategorie %2$s!'), - $request->name, - $this->name - ) - ); - } - - if (!$request->id) { - //The request has no ID: probably it is a new resource request. - if ($request->isNew()) { - //We need an ID so we have to create one: - $request->id = $request->getNewId(); - } else { - throw new InvalidResourceRequestException( - sprintf( - _('Die Ressourcenanfrage %1$s besitzt keine ID!'), - $request->name - ) - ); - } - } - - //get property definition: - $definition = ResourcePropertyDefinition::findOneBySql( - 'INNER JOIN resource_category_properties rcp - ON rcp.property_id = resource_property_definitions.property_id - WHERE category_id = :category_id - AND name = :name - LIMIT 1', - [ - 'category_id' => $this->id, - 'name' => $name - ] - ); - - if (!$definition) { - //Property is undefined for this resource category: - throw new ResourcePropertyException( - sprintf( - _('Die Eigenschaft %1$s ist für die Ressourcenkategorie %2$s nicht definiert!'), - $name, - $this->name - ) - ); - } - - $property = new ResourceRequestProperty(); - $property->request_id = $request->id; - $property->property_id = $definition->id; - - //if state is not set we can set it to defined default values - //for some state types: - if ($state === null) { - $property->state = self::setPropertyDefaultState($definition); - } else { - $property->state = $state; - } - - return $property; - } - - public function getRequestableProperties() - { - return ResourcePropertyDefinition::findBySql( - "INNER JOIN resource_category_properties - USING (property_id) - WHERE - resource_category_properties.category_id = :category_id - AND - resource_category_properties.requestable = '1' - ORDER BY type DESC, name ASC", - [ - 'category_id' => $this->id - ] - ); - } - - /** - * Determines if this resource category has a property with the - * specified name and type. - * - * @param string $name The requested property name. - * @param string $type The requested property type (optional). - * - * @return bool True, if a property with the specified name and type - * exists, false otherwise. - */ - public function hasProperty($name = '', $type = null) - { - if ($type) { - return ResourceCategoryProperty::countBySql( - 'INNER JOIN resource_property_definitions - USING (property_id) - WHERE - name = :name - AND - type = :type - AND - category_id = :category_id', - [ - 'name' => $name, - 'type' => $type, - 'category_id' => $this->id - ] - ) > 0; - } else { - return ResourceCategoryProperty::countBySql( - 'INNER JOIN resource_property_definitions - USING (property_id) - WHERE - name = :name - AND - category_id = :category_id', - [ - 'name' => $name, - 'category_id' => $this->id - ] - ) > 0; - } - } - - /** - * Determines if the user has write permissions for the - * resource property specified by its name. - * - * @param string The name of the resource property definition. - * @param User $user The user whose permissions shall be checked. - * @param Resource|null $resource An optional resource that shall be used - * to check for non-global permissions. - * - * @return bool True, if the user has write permissions, false otherwise. - * @throws ResourcePropertyDefinitionException If no property is found. - * - */ - public function userHasPropertyWritePermissions(string $name, User $user, $resource = null) - { - $property = ResourcePropertyDefinition::findOneBySql( - 'name = :name', - [ - 'name' => $name - ] - ); - - if (!$property) { - throw new ResourcePropertyDefinitionException( - sprintf( - _('Die Ressourceneigenschaft %s existiert nicht!'), - $name - ) - ); - } - - if ($property->write_permission_level == 'admin-global') { - return ResourceManager::userHasGlobalPermission( - $user, - 'admin' - ); - } elseif ($resource instanceof Resource) { - //It must be a permission for the specified resource. - return $resource->userHasPermission( - $user, - $property->write_permission_level - ); - } else { - //We cannot check permissions. - return false; - } - } - - /** - * Get the icon of a category - * @param string $role - * @return Icon - */ - public function getIcon($role = Icon::ROLE_INFO) - { - if ($this->iconnr == 0) { - //No special icon - return Icon::create('resources', $role); - } elseif ($this->iconnr == 1) { - return Icon::create('home', $role); - } else { - //No known icon - return Icon::create('resources', $role); - } - } -} |
