Skip to content
Snippets Groups Projects
Select Git revision
1 result Searching

autoinsert.php

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    WikiPage.php 9.70 KiB
    <?php
    /**
     * WikiPage.php
     * model class for table wiki
     *
     * 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    mlunzena
     * @copyright (c) Authors
     *
     * @property int $id alias for pk
     * @property int $page_id database column
     * @property string $course_id database column
     * @property string|null $user_id database column
     * @property string $name database column
     * @property string $content database column
     * @property string|null $ancestor database column
     * @property int|null $chdate database column
     * @property int $version database column
     * @property int|null $mkdate database column
     * @property User|null $user belongs_to User
     * @property Course $course belongs_to Course
     * @property WikiVersion[]|SimpleORMapCollection $versions
     * @property WikiOnlineEditingUser[]|SimpleORMapCollection $onlineeditingusers
     * @property-read WikiPage $parent additional field
     * @property-read WikiPage[] $children additional field
     * @property-read WikiVersion|null $predecessor additional field
     * @property-read int $versionnumber additional field
     */
    class WikiPage extends SimpleORMap implements PrivacyObject
    {
        /**
         * Configures the model
         * @param  array  $config Configuration
         */
        protected static function configure($config = [])
        {
            $config['db_table'] = 'wiki_pages';
    
            $config['belongs_to']['user'] = [
                'class_name'  => User::class,
                'foreign_key' => 'user_id'
            ];
            $config['belongs_to']['course'] = [
                'class_name'  => Course::class,
                'foreign_key' => 'range_id',
            ];
            $config['has_many']['versions'] = [
                'class_name'  => WikiVersion::class,
                'foreign_key' => 'page_id',
                'order_by'    => 'ORDER BY mkdate DESC',
                'on_delete'   => 'delete',
            ];
            $config['has_many']['onlineeditingusers'] = [
                'class_name' => WikiOnlineEditingUser::class,
                'foreign_key' => 'page_id',
                'on_delete'   => 'delete',
            ];
    
            $config['additional_fields']['parent'] = [
                'get' => function (WikiPage $page): ?WikiPage {
                    return self::find($page->parent_id);
                }
            ];
    
            $config['additional_fields']['children'] = [
                'get' => function (WikiPage $page): array {
                    return self::findBySQL('parent_id = ?', [
                        $page->id
                    ]);
                }
            ];
            $config['additional_fields']['predecessor'] = [
                'get' => function (WikiPage $page): ?WikiVersion {
                    return $page->versions ? $page->versions[0] : null;
                }
            ];
            $config['additional_fields']['versionnumber'] = [
                'get' => function (WikiPage $page): int {
                    return count($page->versions) + 1;
                }
            ];
    
            $config['registered_callbacks']['before_store'][] = 'createVersion';
            $config['default_values']['last_author'] = 'nobody';
    
            parent::configure($config);
        }
    
    
        protected function createVersion()
        {
            $last_version = $this->versions[0];
            if (
                !$this->isNew()
                && $this->content['content'] !== $this->content_db['content']
                && (
                    $this->content_db['user_id'] !== $this->content['user_id']
                    || $this->content_db['chdate'] < time() - 60 * 30
                )
                && (!$last_version || $last_version['content'] !== $this['content'])
            ) {
                //Neue Version anlegen:
                WikiVersion::create([
                    'page_id' => $this->id,
                    'name'    => $this->content_db['name'],
                    'content' => $this->content_db['content'],
                    'user_id' => $this->content_db['user_id'],
                    'mkdate'  => $this->content_db['chdate'],
                ]);
            }
            return true;
        }
    
        public static function findByName($range_id, $name)
        {
            return self::findOneBySQL('BINARY name = :name AND range_id = :range_id', [
                'range_id' => $range_id,
                'name' => $name
            ]);
        }
    
    
        /**
         * Returns whether this page is visible to the given user.
         * @param  string|null $user_id User id
         * @return boolean indicating whether the page is visible
         */
        public function isReadable(?string $user_id = null): bool
        {
            if ($this->isNew()) {
                return true;
            }
            // anyone can see this page if it belongs to a free course
            if (
                $this->read_permission === 'all'
                && Config::get()->ENABLE_FREE_ACCESS
                && $this->course
                && !$this->course->lesezugriff
            ) {
                return true;
            }
            if ($user_id === null && User::findCurrent()) {
                $user_id = User::findCurrent()->id;
            }
    
            if (
                $this->read_permission === 'all'
                && $GLOBALS['perm']->have_studip_perm('user', $this->range_id, $user_id)
            ) {
                return true;
            }
    
            if ($GLOBALS['perm']->have_studip_perm(
                'dozent',
                $this->range_id,
                $user_id
            )) {
                return true;
            }
    
            if (in_array($this->read_permission, ['tutor', 'dozent'])) {
                return $GLOBALS['perm']->have_studip_perm($this->read_permission, $this->range_id, $user_id);
            } else {
                return StatusgruppeUser::exists([$this->read_permission, $user_id]);
            }
        }
    
        /**
         * Returns whether this page is editable to the given user.
         * @param  string|null  $user_id the ID of the user
         * @return boolean indicating whether the page is editable
         */
        public function isEditable(?string $user_id = null): bool
        {
            if ($user_id === null && User::findCurrent()) {
                $user_id = User::findCurrent()->id;
            }
            if ($GLOBALS['perm']->have_studip_perm(
                'dozent',
                $this->range_id,
                $user_id
            )) {
                return true;
            }
            if ($this->write_permission === 'all') {
                return true;
            }
            if (in_array($this->write_permission, ['tutor', 'dozent'])) {
                return $GLOBALS['perm']->have_studip_perm(
                    $this->write_permission,
                    $this->range_id,
                    $user_id
                );
            } else {
                return StatusgruppeUser::exists([$this->write_permission, $user_id]);
            }
        }
    
    
        /**
         * Returns the start page of a wiki for a given course. The start page has
         * the keyword 'WikiWikiWeb'.
         *
         * @param  string $range_id Course id
         * @return WikiPage
         */
        public static function getStartPage($range_id): WikiPage
        {
            $page_id = CourseConfig::get($range_id)->WIKI_STARTPAGE_ID;
    
            if ($page_id) {
                return self::find($page_id);
            }
    
            $page = new WikiPage();
            $page->content = _('Dieses Wiki ist noch leer.');
            if ($page->isEditable()) {
                $page->content .=  ' ' . _("Bearbeiten Sie es!\nNeue Seiten oder Links werden einfach durch Eingeben von [nop][[Wikinamen]][/nop] in doppelten eckigen Klammern angelegt.");
            }
            return $page;
        }
    
        /**
         * Export available data of a given user into a storage object
         * (an instance of the StoredUserData class) for that user.
         *
         * @param StoredUserData $storage object to store data into
         */
        public static function exportUserData(StoredUserData $storage)
        {
            $sorm = self::findBySQL("user_id = ?", [$storage->user_id]);
            if ($sorm) {
                $field_data = [];
                foreach ($sorm as $row) {
                    $field_data[] = $row->toRawArray();
                }
                if ($field_data) {
                    $storage->addTabularData(_('Wiki Einträge'), 'wiki', $field_data);
                }
            }
        }
    
    
        /**
         * Tests if a given Wikipage name (keyword) is a valid ancestor for this page.
         *
         * @param   string   $ancestor Wikipage name to be tested to be an ancestor
         * @return  boolean  true if ok, false if not
         *
         */
        public function isValidAncestor($ancestor): bool
        {
            if ($this->name === 'WikiWikiWeb' || $this->name === $ancestor) {
                return false;
            }
    
            $keywords = array_map(
                function ($descendant) {
                    return $descendant->name;
                },
                $this->getDescendants()
            );
    
            return !in_array($ancestor, $keywords);
        }
    
        /**
         * Retrieve an array of all descending WikiPages (recursive).
         *
         * @return WikiPage[] Array of all descendant WikiPages
         *
         */
        public function getDescendants(): array
        {
            $descendants = [];
    
            foreach ($this->children as $child) {
                array_push($descendants, $child, ...$child->getDescendants());
            }
    
            return $descendants;
        }
    
        /**
         * @return array
         */
        public function getOnlineUsers(): array
        {
            WikiOnlineEditingUser::purge($this);
            $this->resetRelation('onlineeditingusers');
    
            return $this->onlineeditingusers->map(function (WikiOnlineEditingUser $editing_user) {
                return [
                    'user_id' => $editing_user->user_id,
                    'username' => $editing_user->user->username,
                    'fullname' => $editing_user->user->getFullName(),
                    'avatar' => Avatar::getAvatar($editing_user->user_id)->getURL(Avatar::SMALL),
                    'editing' => (bool) $editing_user->editing,
                    'editing_request' => (bool) $editing_user->editing_request,
                ];
            });
        }
    }