Skip to content
Snippets Groups Projects
User.class.php 61.2 KiB
Newer Older
<?php
/**
 * User.class.php
 * model class for combined auth_user_md5/user_info record
 * this class represents one user, the attributes from tables
 * auth_user_md5 and user_info were merged.
 *
 * @code
 * $a_user = User::find($id);
 * $another_users_email = User::findByUsername($username)->email;
 * $a_user->email = $another_users_email;
 * $a_user->store();
 * @endcode
 *
 * 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      André Noack <noack@data-quest.de>
 * @copyright   2011 Stud.IP Core-Group
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
 * @category    Stud.IP
 *
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
 * @property string $id alias column for user_id
 * @property string $user_id database column
 * @property string $username database column
 * @property string $password database column
 * @property string $perms database column
 * @property string $vorname database column
 * @property string $nachname database column
 * @property string $email database column
 * @property string $matriculation_number database column
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
 * @property string $validation_key database column
 * @property string|null $auth_plugin database column
 * @property int $locked database column
 * @property string|null $lock_comment database column
 * @property string|null $locked_by database column
 * @property string $visible database column
 * @property SimpleORMapCollection|CourseMember[] $course_memberships has_many CourseMember
 * @property SimpleORMapCollection|InstituteMember[] $institute_memberships has_many InstituteMember
 * @property SimpleORMapCollection|AdmissionApplication[] $admission_applications has_many AdmissionApplication
 * @property SimpleORMapCollection|ArchivedCourseMember[] $archived_course_memberships has_many ArchivedCourseMember
 * @property SimpleORMapCollection|DatafieldEntryModel[] $datafields has_many DatafieldEntryModel
 * @property SimpleORMapCollection|UserStudyCourse[] $studycourses has_many UserStudyCourse
 * @property SimpleORMapCollection|Statusgruppen[] $contactgroups has_many Statusgruppen
 * @property SimpleORMapCollection|ResourcePermission[] $resource_permissions has_many ResourcePermission
 * @property SimpleORMapCollection|ResourceTemporaryPermission[] $resource_temporary_permissions has_many ResourceTemporaryPermission
 * @property SimpleORMapCollection|ConsultationBlock[] $consultation_blocks has_many ConsultationBlock
 * @property SimpleORMapCollection|ConsultationBooking[] $consultation_bookings has_many ConsultationBooking
 * @property SimpleORMapCollection|ConsultationResponsibility[] $consultation_responsibilities has_many ConsultationResponsibility
 * @property SimpleORMapCollection|Kategorie[] $profile_categories has_many Kategorie
 * @property SimpleORMapCollection|MvvContact[] $mvv_assignments has_many MvvContact
 * @property SimpleORMapCollection|CourseMemberNotification[] $course_notifications has_many CourseMemberNotification
 * @property UserInfo $info has_one UserInfo
 * @property UserOnline $online has_one UserOnline
 * @property Courseware\Unit $courseware_units has_one Courseware\Unit
 * @property SimpleORMapCollection|User[] $contacts has_and_belongs_to_many User
 * @property SimpleORMapCollection|UserDomain[] $domains has_and_belongs_to_many UserDomain
 * @property-read mixed $config additional field
 * @property mixed $hobby additional field
 * @property mixed $lebenslauf additional field
 * @property mixed $publi additional field
 * @property mixed $schwerp additional field
 * @property mixed $home additional field
 * @property mixed $privatnr additional field
 * @property mixed $privatcell additional field
 * @property mixed $privadr additional field
 * @property mixed $score additional field
 * @property mixed $geschlecht additional field
 * @property mixed $mkdate additional field
 * @property mixed $chdate additional field
 * @property mixed $title_front additional field
 * @property mixed $title_rear additional field
 * @property mixed $preferred_language additional field
 * @property mixed $smsforward_copy additional field
 * @property mixed $smsforward_rec additional field
 * @property mixed $email_forward additional field
 * @property mixed $motto additional field
 * @property mixed $lock_rule additional field
 * @property mixed $oercampus_description additional field
class User extends AuthUserMd5 implements Range, PrivacyObject, Studip\Calendar\Owner
{
    /**
     *
     */
    protected static function configure($config = [])
    {
        $config['has_many']['course_memberships'] = [
            'class_name' => CourseMember::class,
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_many']['institute_memberships'] = [
            'class_name' => InstituteMember::class,
            'order_by'   => 'ORDER BY priority ASC',
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_many']['admission_applications'] = [
            'class_name' => AdmissionApplication::class,
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_many']['archived_course_memberships'] = [
            'class_name' => ArchivedCourseMember::class,
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_many']['datafields'] = [
            'class_name'  => DatafieldEntryModel::class,
            'foreign_key' => function ($user) {
                return [$user];
            },
            'assoc_foreign_key' => function ($model, $params) {
                $model->setValue('range_id', $params[0]->id);
            },
            'assoc_func' => 'findByModel',
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_many']['studycourses'] = [
            'class_name' => UserStudyCourse::class,
            'assoc_func' => 'findByUser',
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_and_belongs_to_many']['contacts'] = [
            'thru_table'     => 'contact',
            'thru_key'       => 'owner_id',
            'thru_assoc_key' => 'user_id',
            'order_by'       => 'ORDER BY Nachname, Vorname',
            'on_delete'      => 'delete',
            'on_store'       => 'store',
        ];
        $config['has_many']['contactgroups'] = [
            'class_name'        => Statusgruppen::class,
            'assoc_foreign_key' => 'range_id',
            'on_delete'         => 'delete',
            'on_store'          => 'store',
        ];
        $config['has_one']['info'] = [
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_one']['online'] = [
            'on_delete'  => 'delete',
            'on_store'   => 'store',
        ];
        $config['has_many']['resource_permissions'] = [
            'class_name' => ResourcePermission::class,
            'on_delete'  => 'delete',
            'on_store'   => 'store'
        ];
        $config['has_many']['resource_temporary_permissions'] = [
            'class_name' => ResourceTemporaryPermission::class,
            'on_delete'  => 'delete',
            'on_store'   => 'store'
        ];
        $config['has_many']['consultation_blocks'] = [
            'class_name'        => ConsultationBlock::class,
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
            'assoc_foreign_key' => 'range_id',
            'on_delete'         => 'delete',
        ];
        $config['has_many']['consultation_bookings'] = [
            'class_name' => ConsultationBooking::class,
            'on_delete'  => 'delete',
        ];
        $config['has_many']['consultation_responsibilities'] = [
            'class_name'        => ConsultationResponsibility::class,
            'assoc_func'        => 'findByUserId',
            'on_delete'         => 'delete',
        ];
        $config['has_many']['profile_categories'] = [
            'class_name'        => Kategorie::class,
            'assoc_foreign_key' => 'range_id',
            'on_delete'         => 'delete',
        ];


        $config['has_many']['mvv_assignments'] = [
            'class_name'        => MvvContact::class,
            'assoc_foreign_key' => 'contact_id',
        ];

        $config['has_and_belongs_to_many']['domains'] = [
            'thru_table'        => 'user_userdomains',
            'on_delete'         => 'delete',
            'on_store'          => 'store',
            'order_by'          => 'ORDER BY name',
        ];

        $config['has_many']['course_notifications'] = [
            'class_name'        => CourseMemberNotification::class,
            'on_delete'         => 'delete',
        ];

Peter Thienel's avatar
Peter Thienel committed
        $config['has_many']['extern_pages_configs'] = [
            'class_name' => ExternPageConfig::class,
            'assoc_foreign_key' => 'author_id'
        ];

        $config['additional_fields']['config']['get'] = function ($user) {
            return UserConfig::get($user->id);
        };

        $config['registered_callbacks']['after_delete'][] = 'cbRemoveFeedback';
        $config['registered_callbacks']['after_delete'][] = 'cbRemoveForumVisits';
        $config['registered_callbacks']['before_store'][] = 'cbClearCaches';
        $config['registered_callbacks']['before_store'][] = 'cbStudipLog';

        $info = new UserInfo();
        $info_meta = $info->getTableMetadata();
        foreach ($info_meta ['fields'] as $field => $meta) {
            if ($field !== $info_meta['pk'][0]) {
                $config['additional_fields'][$field] = [
                    'get'            => '_getAdditionalValueFromRelation',
                    'set'            => '_setAdditionalValueFromRelation',
                    'relation'       => 'info',
                    'relation_field' => $field,
                ];
            }
        }

        parent::configure($config);
    }

    /**
     * @param $type string type of callback
     */
    protected function cbStudipLog($type)
    {
        if ($type == 'before_store' && !$this->isNew()) {
            if ($this->isFieldDirty('locked') && $this->isFieldDirty('lock_comment')) {
                if ((int)$this->locked === 1) {
                    StudipLog::log('USER_LOCK',
                        $this->user_id,
                        null,
                        sprintf(
                            'Kommentar: %s',
                            $this->lock_comment
                        )
                    );
                } else {
                    StudipLog::log('USER_UNLOCK',
                        $this->user_id
                    );
                }
    /**
     * Returns the currently authenticated user.
     *
     */
    public static function findCurrent()
    {
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        if (isset($GLOBALS['user']) && is_object($GLOBALS['user'])) {
            return $GLOBALS['user']->getAuthenticatedUser();
        }
    }

    /**
     * build new object with given data
     *
     * @param $data array assoc array of record
     * @return User
     */
    public static function build($data, $is_new = true)
    {
        // Note: This should be used instead of `new static()` since PHPStan
        $class = get_called_class();
        $user = new $class();

        $user->info = new UserInfo();
        $user->setData($data);
        $user->setNew($is_new);
        foreach (array_keys($user->db_fields()) as $field) {
            $user->content_db[$field] = $user->content[$field];
        }
        $user->info = UserInfo::build($data, $is_new);
        return $user;
    }

    /**
     * Returns user object including user_info
     *
     * @param string $id
     */
    public static function findFull($id)
    {
        $sql = "SELECT *
                FROM auth_user_md5
                LEFT JOIN user_info USING (user_id)
                WHERE user_id = ?";
        $data = DBManager::get()->fetchOne($sql, [$id]);
            return static::buildExisting($data);
    }

    /**
     * Returns user objects including user_info
     *
     * @param array $ids
     * @param string $order_by
     * @return User[] User
     */
    public static function findFullMany($ids, $order_by = '')
    {
        $sql = "SELECT *
                FROM auth_user_md5
                LEFT JOIN user_info USING (user_id)
                WHERE user_id IN (?) " . $order_by;
        $data = DBManager::get()->fetchAll($sql, [$ids], [static::class, 'buildExisting']);
        return $data;
    }

    /**
     * return user object for given username
     *
     * @param string $username a username
     * @return User
     */
    public static function findByUsername($username)
    {
        return parent::findOneByUsername($username);
    }

    /**
     * returns an array of User-objects that have the given value in the
     * given datafield.
     * @param string $datafield_id
     * @param array of User
     */
    public static function findByDatafield($datafield_id, $value)
    {
            array_column(
                DatafieldEntryModel::findBySQL(
                    'datafield_id = :datafield_id AND content = :value',
                    compact('datafield_id', 'value')
Loading
Loading full blame...