Completed
Push — master ( 1c08c9...189151 )
by Roberto
03:20
created

lib.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17
/**
18
 * This file contains the relationship API functions used to interact with the data
19
 * and other Moodle hooks
20
 *
21
 * @package local_relationship
22
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
25
defined('MOODLE_INTERNAL') || die();
26
27
function local_relationship_extend_settings_navigation(navigation_node $navigation) {
28
    global $PAGE;
29
30
    if (is_a($PAGE->context, 'context_coursecat') && has_capability('local/relationship:manage', $PAGE->context)) {
31
        $category_node = $navigation->get('categorysettings');
32
        if ($category_node) {
33
            $category_node->add(
34
                    get_string('pluginname', 'local_relationship'),
35
                    new moodle_url('/local/relationship/index.php', array('contextid' => $PAGE->context->id)),
36
                    navigation_node::TYPE_SETTING,
37
                    null,
38
                    null,
39
                    new pix_icon('relationship', '', 'local_relationship')
40
            );
41
        }
42
    }
43
}
44
45
function local_relationship_cron() {
46
    relationship_uniformly_distribute_members();
47
48
    return true;
49
}
50
51
52
//
53
// TODO: Refactory to "relationship class"
54
//
55
56
function relationship_uniformly_distribute_members($relationshipid = null) {
57
    global $DB;
58
59
    $params = array();
60
    $cond = '';
61
    if (!empty($relationshipid)) {
62
        $params['id'] = $relationshipid;
63
        $cond = 'WHERE rl.id = :id';
64
    }
65
66
    $sql = "SELECT DISTINCT rc.*
67
              FROM {relationship} rl
68
              JOIN {relationship_cohorts} rc
69
                ON (rc.relationshipid = rl.id AND rc.uniformdistribution = 1)
70
              JOIN {relationship_groups} rg
71
                ON (rg.relationshipid = rl.id AND rc.uniformdistribution = 1)
72
              {$cond}";
73
    $rcs = $DB->get_records_sql($sql, $params);
74
    foreach ($rcs AS $rc) {
75
        $params = array('relationshipid' => $rc->relationshipid, 'relationshipcohortid' => $rc->id);
76
        $sql = " SELECT cm.userid
77
                   FROM {relationship_cohorts} rc
78
                   JOIN {cohort} ch
79
                     ON (ch.id = rc.cohortid)
80
                   JOIN {cohort_members} cm
81
                     ON (cm.cohortid = ch.id)
82
              LEFT JOIN {relationship_members} rm
83
                     ON (rm.relationshipcohortid = rc.id AND rm.userid = cm.userid)
84
                  WHERE rc.id = :relationshipcohortid
85
                    AND ISNULL(rm.userid)";
86
        $users = $DB->get_records_sql($sql, $params);
87
88
        relationship_uniformly_distribute_users($rc, array_keys($users));
89
    }
90
}
91
92
function relationship_uniformly_distribute_users($relationshipcohort, $userids) {
93
    global $DB;
94
95
    if (empty($userids)) {
96
        return;
97
    }
98
    $sql = "SELECT rg.id, rg.userlimit, count(DISTINCT rm.userid) as count
99
              FROM {relationship_cohorts} rc
100
              JOIN {relationship_groups} rg
101
                ON (rg.relationshipid = rc.relationshipid AND rg.uniformdistribution = 1)
102
         LEFT JOIN {relationship_members} rm
103
                ON (rm.relationshipgroupid = rg.id AND rm.relationshipcohortid = rc.id)
104
             WHERE rc.id = :relationshipcohortid
105
          GROUP BY rg.id";
106
    $groups = $DB->get_records_sql($sql, array('relationshipcohortid' => $relationshipcohort->id));
107
    if (!empty($groups)) {
108
        foreach ($userids AS $userid) {
109
            $min = 99999999;
110
            $gmin = 0;
111
            foreach ($groups AS $grpid => $grp) {
112
                if ($grp->count < $min && ($grp->userlimit == 0 || $grp->count < $grp->userlimit)) {
113
                    $min = $grp->count;
114
                    $gmin = $grpid;
115
                }
116
            }
117
            if ($gmin == 0) {
118
                break; // there is no group to add member
119
            } else {
120
                relationship_add_member($gmin, $relationshipcohort->id, $userid);
121
                $groups[$gmin]->count++;
122
            }
123
        }
124
    }
125
}
126
127
/**
128
 * Add relationship member
129
 *
130
 * @param $relationshipgroupid
131
 * @param $relationshipcohortid
132
 * @param $userid
133
 * @return int|bool relationship_members id of added member or false if any error occours
134
 * @throws coding_exception
135
 */
136
function relationship_add_member($relationshipgroupid, $relationshipcohortid, $userid) {
137
    global $DB;
138
139
    $params = array('relationshipgroupid' => $relationshipgroupid, 'userid' => $userid, 'relationshipcohortid' => $relationshipcohortid);
140
    if ($DB->record_exists('relationship_members', $params)) {
141
        // No duplicates!
142
        return false;
143
    }
144
145
    $relationshipgroup = $DB->get_record('relationship_groups', array('id' => $relationshipgroupid), '*', MUST_EXIST);
146
    $relationshipcohort = $DB->get_record('relationship_cohorts', array('id' => $relationshipcohortid), '*', MUST_EXIST);
147
    $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
148
149
    $record = new stdClass();
150
    $record->relationshipgroupid = $relationshipgroupid;
151
    $record->relationshipcohortid = $relationshipcohortid;
152
    $record->userid = $userid;
153
    $record->timeadded = time();
154
155
    $result = $DB->insert_record('relationship_members', $record);
156
157
    if ($result) {
158
        $record->id = $result;
159
160
        $event = \local_relationship\event\relationshipgroup_member_added::create(array(
161
                'context' => context::instance_by_id($relationship->contextid),
162
                'objectid' => $relationshipgroupid,
163
                'relateduserid' => $userid,
164
                'other' => $relationshipcohort->roleid,
165
        ));
166
        $event->add_record_snapshot('relationship_groups', $relationshipgroup);
167
        $event->add_record_snapshot('relationship', $relationship);
168
        $event->trigger();
169
170
        return $record->id;
171
    }
172
173
    return false;
174
}
175
176
/**
177
 * Remove member from a relationship
178
 *
179
 * @param int $relationshipgroupid
180
 * @param int $relationshipcohortid
181
 * @param int $userid
182
 * @return bool
183
 * @throws coding_exception
184
 */
185
function relationship_remove_member($relationshipgroupid, $relationshipcohortid, $userid) {
186
    global $DB;
187
188
    $params = array('relationshipgroupid' => $relationshipgroupid, 'userid' => $userid, 'relationshipcohortid' => $relationshipcohortid);
189
    $result = $DB->delete_records('relationship_members', $params);
190
191
    if ($result) {
192
        $relationshipgroup = $DB->get_record('relationship_groups', array('id' => $relationshipgroupid), '*', MUST_EXIST);
193
        $relationshipcohort = $DB->get_record('relationship_cohorts', array('id' => $relationshipcohortid), '*', MUST_EXIST);
194
        $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
195
196
        $event = \local_relationship\event\relationshipgroup_member_removed::create(array(
197
                'context' => context::instance_by_id($relationship->contextid),
198
                'objectid' => $relationshipgroupid,
199
                'relateduserid' => $userid,
200
                'other' => $relationshipcohort->roleid,
201
        ));
202
        $event->add_record_snapshot('relationship_groups', $relationshipgroup);
203
        $event->add_record_snapshot('relationship', $relationship);
204
        $event->trigger();
205
206
        return true;
207
    }
208
209
    return false;
210
}
211
212
/**
213
 * @param $relationshipid
214
 * @return stdClass $relationship
215
 */
216
function relationship_get_relationship($relationshipid) {
217
    global $DB;
218
219
    $relationship = $DB->get_record('relationship', array('id' => $relationshipid), '*', MUST_EXIST);
220
    $relationship->tags = tag_get_tags_array('relationship', $relationshipid);
221
222
    return $relationship;
223
}
224
225
/**
226
 * Add new relationship.
227
 *
228
 * @param stdClass $relationship
229
 * @return int|bool new relationship id or false if any error occours
230
 * @throws coding_exception
231
 */
232
function relationship_add_relationship($relationship) {
233
    global $DB;
234
235
    if (!isset($relationship->name)) {
236
        throw new coding_exception('Missing relationship name in relationship_add_relationship().');
237
    }
238
    $relationship->name = trim($relationship->name);
239
240
    if (!isset($relationship->idnumber)) {
241
        $relationship->idnumber = null;
242
    }
243
244
    if (!isset($relationship->description)) {
245
        $relationship->description = '';
246
    }
247
248
    if (!isset($relationship->descriptionformat)) {
249
        $relationship->descriptionformat = FORMAT_HTML;
250
    }
251
252
    if (empty($relationship->component)) {
253
        $relationship->component = '';
254
    }
255
256
    if (!isset($relationship->timecreated)) {
257
        $relationship->timecreated = time();
258
    }
259
260
    if (!isset($relationship->timemodified)) {
261
        $relationship->timemodified = $relationship->timecreated;
262
    }
263
264
    $result = $DB->insert_record('relationship', $relationship);
265
266
    if ($result) {
267
        $relationship->id = $result;
268
        tag_set('relationship', $relationship->id, $relationship->tags);
269
270
        $event = \local_relationship\event\relationship_created::create(array(
271
                'context' => context::instance_by_id($relationship->contextid),
272
                'objectid' => $relationship->id,
273
        ));
274
        $event->add_record_snapshot('relationship', $relationship);
275
        $event->trigger();
276
277
        return $relationship->id;
278
    }
279
280
    return false;
281
}
282
283
/**
284
 * Update existing relationship
285
 *
286
 * @param sstdClass $relationship
287
 * @return void
288
 */
289
function relationship_update_relationship($relationship) {
290
    global $DB;
291
292
    $relationship->timemodified = time();
293
    $result = $DB->update_record('relationship', $relationship);
294
295
    if ($result) {
296
        tag_set('relationship', $relationship->id, $relationship->tags);
297
298
        $event = \local_relationship\event\relationship_updated::create(array(
299
                'context' => context::instance_by_id($relationship->contextid),
300
                'objectid' => $relationship->id,
301
        ));
302
        $event->add_record_snapshot('relationship', $relationship);
303
        $event->trigger();
304
305
        return true;
306
    }
307
308
    return false;
309
}
310
311
/**
312
 * Delete relationship
313
 * @param stdClass $relationship
314
 * @return bool
0 ignored issues
show
Should the return type not be integer|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
315
 * @throws coding_exception
316
 * @throws dml_transaction_exception
317
 */
318
function relationship_delete_relationship($relationship) {
319
    global $DB;
320
321
    $relationshipgroups = $DB->get_records('relationship_groups', array('relationshipid' => $relationship->id));
322
    foreach ($relationshipgroups AS $g) {
323
        relationship_delete_group($g);
324
    }
325
326
    try {
327
        $transaction = $DB->start_delegated_transaction();
328
329
330
        $cohorts = $DB->get_records('relationship_cohorts', array('relationshipid' => $relationship->id));
331
332
        if(count($cohorts) == 0) {
333
            $DB->delete_records('relationship_cohorts', array('relationshipid' => $relationship->id));
334
335
            $tags = tag_get_tags_array('relationship', $relationship->id);
336
            tag_delete(array_keys($tags));
337
338
            $DB->delete_records('relationship', array('id' => $relationship->id));
339
340
            $transaction->allow_commit();
341
        } else {
342
            return -1;
343
        }
344
    } catch (Exception $e) {
345
        $transaction->rollback($e);
346
347
        return false;
348
    }
349
350
    $event = \local_relationship\event\relationship_deleted::create(array(
351
            'context' => context::instance_by_id($relationship->contextid),
352
            'objectid' => $relationship->id,
353
    ));
354
    $event->add_record_snapshot('relationship', $relationship);
355
    $event->trigger();
356
357
    return true;
358
}
359
360
//
361
// Relationship Cohorts
362
//
363
364
/**
365
 * Cohorts related to a relationship
366
 *
367
 * @param $relationshipid
368
 * @param bool $full load full cohort and roles data
369
 * @return array
370
 * @throws coding_exception
371
 */
372
function relationship_get_cohorts($relationshipid, $full = true) {
373
    global $DB;
374
375
    $cohorts = $DB->get_records('relationship_cohorts', array('relationshipid' => $relationshipid));
376
    if ($full) {
377
        foreach ($cohorts AS $ch) {
378
            $ch->cohort = $DB->get_record('cohort', array('id' => $ch->cohortid));
379
            if ($role = $DB->get_record('role', array('id' => $ch->roleid))) {
380
                $ch->role_name = role_get_name($role);
381
            } else {
382
                $ch->role_name = false;
383
            }
384
        }
385
    }
386
387
    return $cohorts;
388
}
389
390
/**
391
 * Get a specific relationshipcohort by ID
392
 *
393
 * @param $relationshipcohortid
394
 * @param bool $full load full cohort and roles data
395
 * @return mixed
396
 * @throws coding_exception
397
 */
398
function relationship_get_cohort($relationshipcohortid, $full = true) {
399
    global $DB;
400
401
    $cohort = $DB->get_record('relationship_cohorts', array('id' => $relationshipcohortid), '*', MUST_EXIST);
402
    if ($full) {
403
        $cohort->cohort = $DB->get_record('cohort', array('id' => $cohort->cohortid));
404
        if ($role = $DB->get_record('role', array('id' => $cohort->roleid))) {
405
            $cohort->role_name = role_get_name($role);
406
        } else {
407
            $cohort->role_name = false;
408
        }
409
    }
410
411
    return $cohort;
412
}
413
414
/**
415
 * Add a relationshipcohort
416
 *
417
 * @param $relationshipcohort
418
 * @return bool|int
419
 */
420
function relationship_add_cohort($relationshipcohort) {
421
    global $DB;
422
423
    if (!isset($relationshipcohort->timecreated)) {
424
        $relationshipcohort->timecreated = time();
425
    }
426
    if (!isset($relationshipcohort->timemodified)) {
427
        $relationshipcohort->timemodified = $relationshipcohort->timecreated;
428
    }
429
430
    $relationshipcohort->id = $DB->insert_record('relationship_cohorts', $relationshipcohort);
431
432
    return $relationshipcohort->id;
433
}
434
435
/**
436
 * Update a specific relationshipcohort
437
 *
438
 * @param $relationshipcohort
439
 * @return bool
440
 */
441
function relationship_update_cohort($relationshipcohort) {
442
    global $DB;
443
444
    $relationshipcohort->timemodified = time();
445
446
    return $DB->update_record('relationship_cohorts', $relationshipcohort);
447
}
448
449
/**
450
 * Delete a specific relationshipcohort
451
 *
452
 * @param $relationshipcohort
453
 * @return bool
454
 */
455
function relationship_delete_cohort($relationshipcohort) {
456
    global $DB;
457
    $members = $DB->get_records('relationship_members', array('relationshipcohortid' => $relationshipcohort->id));
458
    foreach ($members as $m) {
459
        relationship_remove_member($m->relationshipgroupid, $m->relationshipcohortid, $m->userid);
460
    }
461
462
    return $DB->delete_records('relationship_cohorts', array('id' => $relationshipcohort->id));
463
}
464
465
//
466
// Relationship Groups
467
//
468
469
/**
470
 * Get groups from a relationship
471
 * @param $relationshipid
472
 * @return array
473
 */
474
function relationship_get_groups($relationshipid) {
475
    global $DB;
476
477
    $sql = "SELECT rg.*, (SELECT count(*)
478
                            FROM relationship_members
479
                           WHERE relationshipgroupid = rg.id) as size
480
              FROM {relationship_groups} rg
481
             WHERE rg.relationshipid = :relationshipid
482
          GROUP BY rg.id
483
          ORDER BY name";
484
485
    return $DB->get_records_sql($sql, array('relationshipid' => $relationshipid));
486
}
487
488
/**
489
 * Add a relationshipgroup
490
 *
491
 * @param $relationshipgroup
492
 * @return bool|int
493
 * @throws coding_exception
494
 */
495
function relationship_add_group($relationshipgroup) {
496
    global $DB;
497
498
    $relationshipgroup->name = trim($relationshipgroup->name);
499
    if (!isset($relationshipgroup->timecreated)) {
500
        $relationshipgroup->timecreated = time();
501
    }
502
    if (!isset($relationshipgroup->timemodified)) {
503
        $relationshipgroup->timemodified = $relationshipgroup->timecreated;
504
    }
505
506
    $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
507
    $result = $DB->insert_record('relationship_groups', $relationshipgroup);
508
509
    if ($result) {
510
        $relationshipgroup->id = $result;
511
512
        $event = \local_relationship\event\relationshipgroup_created::create(array(
513
                'context' => context::instance_by_id($relationship->contextid),
514
                'objectid' => $relationshipgroup->id,
515
        ));
516
        $event->add_record_snapshot('relationship_groups', $relationshipgroup);
517
        $event->add_record_snapshot('relationship', $relationship);
518
        $event->trigger();
519
    }
520
521
    return $result;
522
}
523
524
/**
525
 * Update a relationshipgroup
526
 *
527
 * @param $relationshipgroup
528
 * @return bool
529
 * @throws coding_exception
530
 */
531
function relationship_update_group($relationshipgroup) {
532
    global $DB;
533
534
    $relationshipgroup->timemodified = time();
535
    if (isset($relationshipgroup->name)) {
536
        $relationshipgroup->name = trim($relationshipgroup->name);
537
    }
538
    $result = $DB->update_record('relationship_groups', $relationshipgroup);
539
540
    if ($result) {
541
        $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
542
543
        $event = \local_relationship\event\relationshipgroup_updated::create(array(
544
                'context' => context::instance_by_id($relationship->contextid),
545
                'objectid' => $relationshipgroup->id,
546
        ));
547
        $event->add_record_snapshot('relationship_groups', $relationshipgroup);
548
        $event->add_record_snapshot('relationship', $relationship);
549
        $event->trigger();
550
    }
551
552
    return $result;
553
}
554
555
/**
556
 * @param $relationshipgroup
557
 * @return bool
558
 * @throws coding_exception
559
 * @throws dml_transaction_exception
560
 */
561
function relationship_delete_group($relationshipgroup) {
562
    global $DB;
563
564
    try {
565
        $transaction = $DB->start_delegated_transaction();
566
567
        $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
568
        $DB->delete_records('relationship_members', array('relationshipgroupid' => $relationshipgroup->id));
569
        $DB->delete_records('relationship_groups', array('id' => $relationshipgroup->id));
570
571
        $transaction->allow_commit();
572
    } catch (Exception $e) {
573
        $transaction->rollback($e);
574
575
        return false;
576
    }
577
578
    $event = \local_relationship\event\relationshipgroup_deleted::create(array(
579
            'context' => context::instance_by_id($relationship->contextid),
580
            'objectid' => $relationshipgroup->id,
581
    ));
582
    $event->add_record_snapshot('relationship_groups', $relationshipgroup);
583
    $event->add_record_snapshot('relationship', $relationship);
584
    $event->trigger();
585
586
    return true;
587
}
588