Skip to content
Snippets Groups Projects
courseware.php 13.3 KiB
Newer Older
require_once __DIR__.'/../courseware_controller.php';

use Courseware\StructuralElement;

/**
 * @property ?string $entry_element_id
 * @property int $last_visitdate
Ron Lucke's avatar
Ron Lucke committed
 * @property mixed $course_id
 * @property mixed $courseware_progress_data
 * @property mixed $courseware_chapter_counter
 */
class Course_CoursewareController extends CoursewareController
{
    protected $_autobind = true;

    public function before_filter(&$action, &$args): void
    {
        parent::before_filter($action, $args);

        if (!Context::get()) {
            throw new CheckObjectException(_('Sie haben kein Objekt gewählt.'));
        }
        PageLayout::setTitle(Context::get()->getFullName() . ' - ' . _('Courseware'));
        PageLayout::setHelpKeyword('Basis.Courseware');

        checkObject();
        if (!Context::isCourse()) {
            throw new CheckObjectException(_('Es wurde keine passende Veranstaltung gefunden.'));
        }
        $this->studip_module = checkObjectModule('CoursewareModule', true);
        object_set_visit_module($this->studip_module->getPluginId());
        $this->last_visitdate = object_get_visit(Context::getId(), $this->studip_module->getPluginId());
Ron Lucke's avatar
Ron Lucke committed
        $this->licenses = $this->getLicenses();
        $this->oer_enabled = Config::get()->OERCAMPUS_ENABLED && $GLOBALS['perm']->have_perm(Config::get()->OER_PUBLIC_STATUS);
Ron Lucke's avatar
Ron Lucke committed
        $this->unitsNotFound = Unit::countBySql('range_id = ?', [Context::getId()]) === 0;
Ron Lucke's avatar
Ron Lucke committed

        $this->feedback_settings = json_encode([
            'activated' => \Feedback::isActivated(),
            'adminPerm' => \Feedback::hasAdminPerm(Context::getId()),
            'createPerm' => \Feedback::hasCreatePerm(Context::getId()),
        ]);
    public function index_action(): void
        Navigation::activateItem('course/courseware/shelf');
        $this->setIndexSidebar();
    }
    public function courseware_action($unit_id = null):  void
    {
Ron Lucke's avatar
Ron Lucke committed
        Navigation::activateItem('course/courseware/unit');
        if ($this->unitsNotFound) {
            PageLayout::postMessage(MessageBox::info(_('Es wurde kein Lernmaterial gefunden.')));
            return;
        }
David Siegfried's avatar
David Siegfried committed
        $user = User::findCurrent();
Ron Lucke's avatar
Ron Lucke committed
        $this->setCoursewareSidebar();
David Siegfried's avatar
David Siegfried committed
        $last = UserConfig::get($user->id)->getValue('COURSEWARE_LAST_ELEMENT');
Ron Lucke's avatar
Ron Lucke committed
        $lastStructuralElement = \Courseware\StructuralElement::findOneById($last);
David Siegfried's avatar
David Siegfried committed
            if (isset($lastStructuralElement) && $lastStructuralElement->canVisit($user)) {
Ron Lucke's avatar
Ron Lucke committed
                $this->redirectToFirstUnit('course', Context::getId(), $last);
            } else {
                $this->redirectToFirstUnit('course', Context::getId(), []);
            }
        $this->entry_element_id = null;
        $this->unit_id = null;
        $unit = Unit::find($unit_id);
        if (isset($unit)) {
            if (isset($lastStructuralElement) && $lastStructuralElement->canVisit($user)) {
Ron Lucke's avatar
Ron Lucke committed
                $this->setEntryElement('course', $unit, $last, Context::getId());
            } else {
                $rootElement = [Context::getId() => $unit->structural_element->id];
                $this->setEntryElement('course', $unit, $rootElement, Context::getId());
            }
    public function tasks_action($route = null): void
        $this->is_teacher = $GLOBALS['perm']->have_studip_perm(
            'tutor',
            Context::getId(),
            $GLOBALS['user']->id
        );

        Navigation::activateItem('course/courseware/tasks');
        PageLayout::setTitle(_('Courseware: Aufgaben'));
    public function activities_action(): void
        global $perm, $user;
        $this->is_teacher = $perm->have_studip_perm('tutor', Context::getId(), $user->id);
        Navigation::activateItem('course/courseware/activities');
        $this->setActivitiesSidebar();
    public function pdf_export_action($element_id, $with_children): void
Ron Lucke's avatar
Ron Lucke committed
    {
        $element = \Courseware\StructuralElement::findOneById($element_id);
Ron Lucke's avatar
Ron Lucke committed
        $user = User::find($GLOBALS['user']->id);
        $this->render_pdf($element->pdfExport($user, $with_children), trim($element->title).'.pdf');
Ron Lucke's avatar
Ron Lucke committed
    }

    public function comments_overview_action(): void
    {
        Navigation::activateItem('course/courseware/comments');
        $this->setCommentsOverviewSidebar();
    }

    public function comments_overview_data_action()
    {
        $user = User::findCurrent();
        $cid = Request::get('cid');
        $units = [];
        $elements = [];
        $containers = [];
        $blocks = [];
        $block_comments = [];
        $block_feedbacks = [];
        $element_comments = [];
        $element_feedbacks = [];

        $statement = DBManager::get()->prepare("
            SELECT elem.id AS elem_id, container.id AS container_id, block.id AS block_id, comment.id AS comment_id
            FROM `cw_block_comments` AS comment
            INNER JOIN `cw_blocks` AS block ON (block.id = comment.block_id)
            INNER JOIN `cw_containers` AS container ON (container.id = block.container_id)
            INNER JOIN `cw_structural_elements` AS elem ON (elem.id = container.structural_element_id)
            WHERE elem.range_type = 'course'
            AND elem.range_id = :range_id
        ");

        $statement->execute(['range_id' => $cid]);
        $cw_block_comments = $statement->fetchAll();

        foreach ($cw_block_comments as $row) {
            $element = \Courseware\StructuralElement::find($row['elem_id']);
            if (!$element->canRead($user)) {
                continue;
            }
            if (!$this->arrayHasDataForId($elements, $row['elem_id'])) {
                $elements[] = $element;
                $unit = $element->findUnit();
                $unitElement = $unit->structural_element;
                if (!$this->arrayHasDataForId($elements, $unitElement->id)) {
                    $elements[] = $unitElement;
                }
                if (!$this->arrayHasDataForId($units, $unit->id)) {
                    $units[] = $unit;
                }
            }
            if (!$this->arrayHasDataForId($containers, $row['container_id'])) {
                $containers[] = \Courseware\Container::find($row['container_id']);
            }
            if (!$this->arrayHasDataForId($blocks, $row['block_id'])) {
                $blocks[] = \Courseware\Block::find($row['block_id']);
            }
            if (!$this->arrayHasDataForId($block_comments, $row['comment_id'])) {
                $block_comments[] = \Courseware\BlockComment::find($row['comment_id']);
            }
        }

        $statement = DBManager::get()->prepare("
            SELECT elem.id AS elem_id, container.id AS container_id, block.id AS block_id, feedback.id AS feedback_id
            FROM `cw_block_feedbacks` AS feedback
            INNER JOIN `cw_blocks` AS block ON (block.id = feedback.block_id)
            INNER JOIN `cw_containers` AS container ON (container.id = block.container_id)
            INNER JOIN `cw_structural_elements` AS elem ON (elem.id = container.structural_element_id)
            WHERE elem.range_type = 'course'
            AND elem.range_id = :range_id
        ");

        $statement->execute(['range_id' => $cid]);
        $cw_block_feedbacks = $statement->fetchAll();

        foreach ($cw_block_feedbacks as $row) {
            $element = \Courseware\StructuralElement::find($row['elem_id']);
            if (!$element->canEdit($user)) {
                continue;
            }
            if (!$this->arrayHasDataForId($elements, $row['elem_id'])) {
                $elements[] = $element;
                $unit = $element->findUnit();
                $unitElement = $unit->structural_element;
                if (!$this->arrayHasDataForId($elements, $unitElement->id)) {
                    $elements[] = $unitElement;
                }
                if (!$this->arrayHasDataForId($units, $unit->id)) {
                    $units[] = $unit;
                }
            }
            if (!$this->arrayHasDataForId($containers, $row['container_id'])) {
                $containers[] = \Courseware\Container::find($row['container_id']);
            }
            if (!$this->arrayHasDataForId($blocks, $row['block_id'])) {
                $blocks[] = \Courseware\Block::find($row['block_id']);
            }
            if (!$this->arrayHasDataForId($block_feedbacks, $row['feedback_id'])) {
                $block_feedbacks[] = \Courseware\BlockFeedback::find($row['feedback_id']);
            }
        }

        $statement = DBManager::get()->prepare("
            SELECT elem.id AS elem_id, comment.id AS comment_id
            FROM `cw_structural_element_comments` AS comment
            INNER JOIN `cw_structural_elements` AS elem ON (elem.id = comment.structural_element_id)
            WHERE elem.range_type = 'course'
            AND elem.range_id = :range_id
        ");

        $statement->execute(['range_id' => $cid]);
        $cw_structural_element_comments = $statement->fetchAll();

        foreach ($cw_structural_element_comments as $row) {
            $element = \Courseware\StructuralElement::find($row['elem_id']);
            if (!$element->canRead($user)) {
                continue;
            }
            if (!$this->arrayHasDataForId($elements, $row['elem_id'])) {
                $elements[] = $element;
                $unit = $element->findUnit();
                $unitElement = $unit->structural_element;
                if (!$this->arrayHasDataForId($elements, $unitElement->id)) {
                    $elements[] = $unitElement;
                }
                if (!$this->arrayHasDataForId($units, $unit->id)) {
                    $units[] = $unit;
                }
            }
            if (!$this->arrayHasDataForId($element_comments, $row['comment_id'])) {
                $element_comments[] = \Courseware\StructuralElementComment::find($row['comment_id']);
            }
        }

        $statement = DBManager::get()->prepare("
            SELECT elem.id AS elem_id, feedback.id AS feedback_id
            FROM `cw_structural_element_feedbacks` AS feedback
            INNER JOIN `cw_structural_elements` AS elem ON (elem.id = feedback.structural_element_id)
            WHERE elem.range_type = 'course'
            AND elem.range_id = :range_id
        ");

        $statement->execute(['range_id' => $cid]);
        $cw_structural_element_feedbacks = $statement->fetchAll();

        foreach ($cw_structural_element_feedbacks as $row) {
            $element = \Courseware\StructuralElement::find($row['elem_id']);
            if (!$element->canEdit($user)) {
                continue;
            }
            if (!$this->arrayHasDataForId($elements, $row['elem_id'])) {
                $elements[] = $element;
                $unit = $element->findUnit();
                $unitElement = $unit->structural_element;
                if (!$this->arrayHasDataForId($elements, $unitElement->id)) {
                    $elements[] = $unitElement;
                }
                if (!$this->arrayHasDataForId($units, $unit->id)) {
                    $units[] = $unit;
                }
            }
            if (!$this->arrayHasDataForId($element_feedbacks, $row['feedback_id'])) {
                $element_feedbacks[] = \Courseware\StructuralElementFeedback::find($row['feedback_id']);
            }
        }

        $encoder = app(\Neomerx\JsonApi\Contracts\Encoder\EncoderInterface::class);

        $data = [
            'units' => $encoder->encodeData($units),
            'elements' => $encoder->encodeData($elements),
            'containers' => $encoder->encodeData($containers),
            'blocks' => $encoder->encodeData($blocks),
            'block_comments' => $encoder->encodeData($block_comments),
            'block_feedbacks' => $encoder->encodeData($block_feedbacks),
            'element_comments' => $encoder->encodeData($element_comments),
            'element_feedbacks' => $encoder->encodeData($element_feedbacks),
        ];
        $this->render_json($data);
    }

    private function arrayHasDataForId(array $array, $id): bool
    {
        $ids = array_column($array, null, 'id');
        return !empty($ids[$id]);
    }

Ron Lucke's avatar
Ron Lucke committed
    private function setIndexSidebar(): void
    {
        $sidebar = Sidebar::Get();
Viktoria Wiebe's avatar
Viktoria Wiebe committed
        $sidebar->addWidget(new VueWidget('courseware-action-widget'));
Ron Lucke's avatar
Ron Lucke committed
        SkipLinks::addIndex(_('Aktionen'), 'courseware-action-widget', 21);
Ron Lucke's avatar
Ron Lucke committed
    }

    private function setTasksSidebar(): void
Ron Lucke's avatar
Ron Lucke committed
    {
        $sidebar = Sidebar::Get();
        $sidebar->addWidget(new VueWidget('courseware-action-widget'));
Ron Lucke's avatar
Ron Lucke committed
        SkipLinks::addIndex(_('Aktionen'), 'courseware-action-widget', 21);
    private function setActivitiesSidebar(): void
        $sidebar = Sidebar::Get();
        $sidebar->addWidget(new VueWidget('courseware-activities-widget-filter-type'));
        $sidebar->addWidget(new VueWidget('courseware-activities-widget-filter-unit'));

    private function setCommentsOverviewSidebar(): void
    {
        $sidebar = Sidebar::Get();
        $sidebar->addWidget(new VueWidget('courseware-comments-overview-widget-filter-type'));
        $sidebar->addWidget(new VueWidget('courseware-comments-overview-widget-filter-created'));
        $sidebar->addWidget(new VueWidget('courseware-comments-overview-widget-filter-unit'));
    }