Skip to content
Snippets Groups Projects
Select Git revision
  • 9c3178facc4eeaa6da6e7034f9d421a6f2593bb4
  • main default protected
  • studip-rector
  • ci-opt
  • course-members-export-as-word
  • data-vue-app
  • pipeline-improvements
  • webpack-optimizations
  • rector
  • icon-renewal
  • http-client-and-factories
  • jsonapi-atomic-operations
  • vueify-messages
  • tic-2341
  • 135-translatable-study-areas
  • extensible-sorm-action-parameters
  • sorm-configuration-trait
  • jsonapi-mvv-routes
  • docblocks-for-magic-methods
19 results

CoursewareCollapsibleBox.vue

Blame
  • Forked from Stud.IP / Stud.IP
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    StructuralElement.php 11.91 KiB
    <?php
    
    namespace JsonApi\Schemas\Courseware;
    
    use JsonApi\Schemas\SchemaProvider;
    use Neomerx\JsonApi\Document\Link;
    
    class StructuralElement extends SchemaProvider
    {
        const TYPE = 'courseware-structural-elements';
    
        const REL_ANCESTORS = 'ancestors';
        const REL_CHILDREN = 'children';
        const REL_CONTAINERS = 'containers';
        const REL_COURSE = 'course';
        const REL_DESCENDANTS = 'descendants';
        const REL_EDITBLOCKER = 'edit-blocker';
        const REL_EDITOR = 'editor';
        const REL_IMAGE = 'image';
        const REL_OWNER = 'owner';
        const REL_PARENT = 'parent';
        const REL_USER = 'user';
    
        protected $resourceType = self::TYPE;
    
        /**
         * {@inheritdoc}
         */
        public function getId($resource)
        {
            return $resource->id;
        }
    
        /**
         * {@inheritdoc}
         */
        public function getAttributes($resource)
        {
            $user = $this->getDiContainer()->get('studip-current-user');
    
            return [
                'position' => (int) $resource['position'],
                'title' => (string) $resource['title'],
                'purpose' => (string) $resource['purpose'],
                'payload' => $resource['payload']->getIterator(),
                'public' => (int) $resource['public'],
                'release-date' => $resource['release_date'] ? date('Y-m-d', (int) $resource['release_date']) : null,
                'withdraw-date' => $resource['withdraw_date'] ? date('Y-m-d', (int) $resource['withdraw_date']) : null,
                'read-approval' => $resource['read_approval']->getIterator(),
                'write-approval' => $resource['write_approval']->getIterator(),
                'copy-approval' => $resource['copy_approval']->getIterator(),
                'can-edit' => $resource->canEdit($user),
    
                'external-relations' => $resource['external_relations']->getIterator(),
                'mkdate' => date('c', $resource['mkdate']),
                'chdate' => date('c', $resource['chdate']),
            ];
        }
    
        /**
         * {@inheritdoc}
         *
         * @param \Courseware\Models\StructuralElement $resource
         * @param bool                                 $isPrimary
         * @param array                                $includeList
         */
        public function getRelationships($resource, $isPrimary, array $includeList)
        {
            $relationships = [];
    
            $shouldInclude = function ($key) use ($includeList) {
                return in_array($key, $includeList);
            };
    
            $relationships = $this->addChildrenRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_CHILDREN)
            );
    
            $relationships = $this->addContainersRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_CONTAINERS)
            );
    
            $relationships = $this->addRangeRelationship(
                $relationships,
                $resource,
                $includeList
            );
    
            $relationships = $this->addOwnerRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_OWNER)
            );
    
            $relationships = $this->addEditorRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_EDITOR)
            );
    
            $relationships = $this->addEditBlockerRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_EDITBLOCKER)
            );
    
            $relationships = $this->addParentRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_PARENT)
            );
    
            $relationships = $this->addAncestorsRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_ANCESTORS)
            );
    
            $relationships = $this->addDescendantsRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_DESCENDANTS)
            );
    
            $relationships = $this->addImageRelationship(
                $relationships,
                $resource,
                $shouldInclude(self::REL_IMAGE)
            );
    
            return $relationships;
        }
    
        private function addAncestorsRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [
                self::LINKS => [
                    Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_ANCESTORS),
                ],
            ];
    
            if ($includeData) {
                $user = $this->getDiContainer()->get('studip-current-user');
                $related = $resource->findAncestors($user);
                $relation[self::DATA] = $related;
            }
    
            $relationships[self::REL_ANCESTORS] = $relation;
    
            return $relationships;
        }
    
        private function addChildrenRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [
                self::LINKS => [
                    Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_CHILDREN),
                ]
            ];
    
            if ($includeData) {
                $user = $this->getDiContainer()->get('studip-current-user');
                $relation[self::DATA] = array_filter(
                    $resource->children,
                    function ($child) use ($user) {
                        return $child->canRead($user);
                    }
                );
            }
    
            $relationships[self::REL_CHILDREN] = $relation;
    
            return $relationships;
        }
    
        private function addContainersRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [
                self::LINKS => [
                    Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_CONTAINERS),
                ],
            ];
    
            if ($includeData) {
                $relation[self::DATA] = $resource->containers;
            } else {
                $sql = 'SELECT id FROM cw_containers WHERE structural_element_id = ?';
                $containers = \DBManager::get()->fetchAll($sql, [$resource->id], function ($container) {
                    return \Courseware\Container::build(['id' => $container['id']], false);
                });
                $relation[self::DATA] = $containers;
            }
            $relationships[self::REL_CONTAINERS] = $relation;
    
            return $relationships;
        }
    
        private function addDescendantsRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [
                self::LINKS => [
                    Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_DESCENDANTS),
                ],
            ];
    
            if ($includeData) {
                $user = $this->getDiContainer()->get('studip-current-user');
                $related = $resource->findDescendants($user);
                $relation[self::DATA] = $related;
            }
    
            $relationships[self::REL_DESCENDANTS] = $relation;
    
            return $relationships;
        }
    
        private function addEditBlockerRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [
                self::SHOW_SELF => true,
            ];
            if ($resource['edit_blocker_id']) {
                $relation[self::LINKS] = [
                    Link::RELATED => $this->createLinkToUser($resource['edit_blocker_id']),
                ];
                $relation[self::DATA] = $includeData ? $resource->edit_blocker : \User::build(['id' => $resource['edit_blocker_id']], false);
            } else {
                $relation[self::DATA] = null;
            }
            $relationships[self::REL_EDITBLOCKER] = $relation;
    
            return $relationships;
        }
    
        private function addEditorRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [];
            if ($resource['editor_id']) {
                $relation[self::LINKS] = [
                    Link::RELATED => $this->createLinkToUser($resource['editor_id']),
                ];
                $relation[self::DATA] = $includeData ? $resource->editor : \User::build(['id' => $resource['editor_id']], false);
            } else {
                $relation[self::DATA] = null;
            }
            $relationships[self::REL_EDITOR] = $relation;
    
            return $relationships;
        }
    
        private function addImageRelationship(array $relationships, $resource, $includeData)
        {
            $image = $resource->image;
            $relation = [
                self::DATA => $image ?: null,
            ];
    
            if ($image) {
                $relation[self::META] = [
                    'download-url' => $resource->getImageUrl(),
                ];
            }
    
            $relationships[self::REL_IMAGE] = $relation;
    
            return $relationships;
        }
    
        private function addOwnerRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [];
            if ($resource['owner_id']) {
                $relation[self::LINKS] = [
                    Link::RELATED => $this->createLinkToUser($resource['owner_id']),
                ];
                $relation[self::DATA] = $includeData ? $resource->owner :  \User::build(['id' => $resource['owner_id']], false);
            } else {
                $relation[self::DATA] = null;
            }
            $relationships[self::REL_OWNER] = $relation;
    
            return $relationships;
        }
    
        private function addParentRelationship(array $relationships, $resource, $includeData)
        {
            $relation = [];
    
            if ($resource['parent_id']) {
                $relation[self::LINKS] = [
                    Link::RELATED => $this->createLinkToStructuralElement($resource['parent_id']),
                ];
                $relation[self::DATA] = $includeData ? $resource->parent : \Courseware\StructuralElement::build(['id' => $resource['parent_id']], false);
            } else {
                $relation[self::DATA] = null;
            }
            $relationships[self::REL_PARENT] = $relation;
    
            return $relationships;
        }
    
        private function addRangeRelationship(array $relationships, $resource, $includeList)
        {
            if ($resource['range_type'] === 'course') {
                $includeData = in_array(self::REL_COURSE, $includeList);
                $relationships[self::REL_COURSE] = [
                    self::LINKS => [
                        Link::RELATED => $this->createLinkToCourse($resource['range_id']),
                    ],
                    self::DATA => $includeData ? $resource->course : \Course::build(['id' => $resource['range_id']], false),
                ];
            } elseif ($resource['range_type'] === 'user') {
                $includeData = in_array(self::REL_USER, $includeList);
                $relationships[self::REL_USER] = [
                    self::LINKS => [
                        Link::RELATED => $this->createLinkToUser($resource['range_id']),
                    ],
                    self::DATA => $includeData ? $resource->user : \Course::build(['id' => $resource['range_id']], false),
                ];
            }
    
            return $relationships;
        }
    
        private static $memo = [];
    
        private function createLinkToCourse($rangeId)
        {
            if (isset(self::$memo['course' . $rangeId])) {
                return self::$memo['course' . $rangeId];
            }
    
            $course = \Course::build(['id' => $rangeId], false);
            $link = $this->getSchemaContainer()
                ->getSchema($course)
                ->getSelfSubLink($course);
            self::$memo['course' . $rangeId] = $link;
    
            return $link;
        }
    
        private function createLinkToStructuralElement($structuralElementId)
        {
            if (isset(self::$memo['structuralelement' . $structuralElementId])) {
                return self::$memo['structuralelement' . $structuralElementId];
            }
    
            $structuralElement = \Courseware\StructuralElement::build(['id' => $structuralElementId], false);
            $link = $this->getSchemaContainer()
                ->getSchema($structuralElement)
                ->getSelfSubLink($structuralElement);
            self::$memo['structuralelement' . $structuralElementId] = $link;
    
            return $link;
        }
    
        private function createLinkToUser($rangeId)
        {
            if (isset(self::$memo['user' . $rangeId])) {
                return self::$memo['user' . $rangeId];
            }
    
            $user = \User::build(['id' => $rangeId], false);
            $link = $this->getSchemaContainer()
                ->getSchema($user)
                ->getSelfSubLink($user);
            self::$memo['user' . $rangeId] = $link;
    
            return $link;
        }
    }