aboutsummaryrefslogtreecommitdiff
path: root/lib/models/UserDomain.php
blob: 08deb49189884e518278f13fa4a99e78ee7453b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
<?php
/**
 * Class representing a user domain in Stud.IP
 *
 * @author Elmar Ludwig <ludwig@uos.de>
 * @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
 * @copyright 2008
 * @license GPL2 or any later version
 */
class UserDomain extends SimpleORMap
{
    const REGEXP = '^[\\w\.\-]{1,32}$';

    protected static function configure($config = [])
    {
        $config['db_table'] = 'userdomains';

        $config['has_and_belongs_to_many']['users'] = [
            'class_name'        => 'User',
            'thru_table'        => 'user_userdomains',
            'assoc_foreign_key' => 'user_id',
            'on_delete'          => 'delete',
            'on_store'           => 'store',
        ];

        $config['has_and_belongs_to_many']['courses'] = [
            'class_name'        => 'Course',
            'thru_table'        => 'seminar_userdomains',
            'on_delete'          => 'delete',
            'on_store'           => 'store',
        ];

        $config['registered_callbacks']['before_store'][] = function ($domain) {
            if (!preg_match('/' . self::REGEXP . '/', $domain->id)) {
                throw new Exception(_('Ungültige ID für Nutzerdomäne') . ': ' . $domain->id);
            }
        };

        parent::configure($config);
    }

    /**
     * Get an array of all defined user domains.
     * Returns an array of UserDomain objects.
     */
    public static function getUserDomains ()
    {
        return self::findBySQL('1 ORDER BY name');
    }

    /**
     * Add a user to this user domain.
     */
    public function addUser ($user_id)
    {
        $query = "INSERT IGNORE INTO user_userdomains (user_id, userdomain_id)
                  VALUES (:user_id, :id)";
        $statement = DBManager::get()->prepare($query);
        $statement->execute([
            ':user_id' => $user_id,
            ':id'      => $this->id,
        ]);
        NotificationCenter::postNotification('UserDomainUserDidCreate', $this->id, $user_id);
    }

    /**
     * Remove a user from this user domain.
     */
    public function removeUser ($user_id)
    {
        $query = "DELETE FROM user_userdomains
                  WHERE user_id = :user_id
                    AND userdomain_id = :id";
        $statement = DBManager::get()->prepare($query);
        $statement->execute([
            ':user_id' => $user_id,
            ':id'      => $this->id,
        ]);
        NotificationCenter::postNotification('UserDomainUserDidDelete', $this->id, $user_id);
    }

    /**
     * Get an array of all user domains for a specific user.
     * Returns an array of UserDomain objects.
     */
    public static function getUserDomainsForUser ($user_id)
    {
        $domains = User::find($user_id)->domains;
        return $domains ? $domains->getArrayCopy() : [];
    }

    /**
     * Remove all user domains for a specific user.
     */
    public static function removeUserDomainsForUser ($user_id)
    {
        $query = "DELETE FROM user_userdomains
                  WHERE user_id = :user_id";
        $statement = DBManager::get()->prepare($query);
        $statement->execute([
            ':user_id' => $user_id,
        ]);
        NotificationCenter::postNotification('UserDomainUserDidDelete', 'all', $user_id);
    }

    /**
     * Add a seminar to this user domain.
     */
    public function addSeminar ($seminar_id)
    {
        $query = "INSERT IGNORE INTO seminar_userdomains (seminar_id, userdomain_id)
                  VALUES (:seminar_id, :id)";
        $statement = DBManager::get()->prepare($query);
        $statement->execute([
            ':seminar_id' => $seminar_id,
            ':id'         => $this->id,
        ]);
        NotificationCenter::postNotification('UserDomainSeminarDidCreate', $this->id, $seminar_id);
    }

    /**
     * Remove a seminar from this user domain.
     */
    public function removeSeminar ($seminar_id)
    {
        $query = "DELETE FROM seminar_userdomains
                  WHERE seminar_id = :seminar_id
                    AND userdomain_id = :id";
        $statement = DBManager::get()->prepare($query);
        $statement->execute([
            ':seminar_id' => $seminar_id,
            ':id'         => $this->id,
        ]);
        NotificationCenter::postNotification('UserDomainSeminarDidDelete', $this->id, $seminar_id);
    }

    /**
     * Get an array of all user domains for a specific seminar.
     * Returns an array of UserDomain objects.
     */
    public static function getUserDomainsForSeminar ($seminar_id)
    {
        return Course::find($seminar_id)->domains->getArrayCopy();
    }

    /**
     * Remove all user domains for a specific seminar.
     */
    public static function removeUserDomainsForSeminar ($seminar_id)
    {
        $query = "DELETE FROM seminar_userdomains
                  WHERE seminar_id = :seminar_id";
        $statement = DBManager::get()->prepare($query);
        $statement->execute([
            ':seminar_id' => $seminar_id,
        ]);
        NotificationCenter::postNotification('UserDomainSeminarDidDelete', 'all', $seminar_id);
    }

    /**
     * Check the visibility for two sets of domains. The visibility is only
     * given when any of the following cases is true:
     *
     * - both sets of domains are empty
     * - the check is not strict and no domains are owned
     * - any of the owned domains has no restricted access
     * - the check is not strict and any of the domains to check has no
     *   restricted access
     *  - the two sets of domains contain at least one same domain
     *
     * @param  array   $domains_owned    Domains owned by the object
     * @param  array   $domains_to_check Domains to check against
     * @param  boolean $strict           Perform a strict check;
     *                                   optional, default: false
     * @return bool indicating whether visibility is given or not
     */
    public static function checkUserVisibility($domains_owned, $domains_to_check)
    {
        if ($domains_owned instanceof StudipArrayObject) {
            $domains_owned = $domains_owned->getArrayCopy();
        } else {
            $domains_owned = (array) $domains_owned;
        }
        if ($domains_to_check instanceof StudipArrayObject) {
            $domains_to_check = $domains_to_check->getArrayCopy();
        } else {
            $domains_to_check = (array) $domains_to_check;
        }

        // Empty sets of domains on both sides
        if (count($domains_owned) === 0 && count($domains_to_check) === 0) {
            return true;
        }

        // No domains owned, visibility is given if any domain to check is
        // unrestricted
        if (count($domains_owned) === 0) {
            return (bool) array_filter($domains_to_check, function ($domain) {
                return !$domain->restricted_access;
            });
        }

        // No domains to check against, visibility is given if any domain owned
        // is unrestricted
        if (count($domains_to_check) === 0) {
            return (bool) array_filter($domains_owned, function ($domain) {
                return !$domain->restricted_access;
            });
        }

        foreach ($domains_owned as $owned) {
            foreach ($domains_to_check as $check) {
                // Domain is the same
                if ($owned->id === $check->id) {
                    return true;
                }

                // Both domains are not restricred
                if (!$owned->restricted_access && !$check->restricted_access) {
                    return true;
                }
            }
        }

        return false;
    }

    public static function checkCourseVisibility($domains_owned, $domains_to_check)
    {
        // No strict check and no owned domains
        if (count($domains_owned) === 0) {
            return true;
        }

        foreach ($domains_owned as $domain) {
            // Domain owned is not restricted
            if (!$domain->restricted_access) {
                return true;
            }

            foreach ($domains_to_check as $other) {
                // Domain are the same or domain to check is not restricted
                if ($domain->id === $other->id || !$other->restricted_access) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Converts the user domain into a string. This is required for array_diff()
     * purposes in order to check whether userdomains of users or user and
     * course match up.
     *
     * @return string representation of the user domain
     */
    public function __toString()
    {
        return $this->id;
    }
}