Passed
Push — MOODLE_35_STABLE ( 61b49b )
by Roberto
06:41
created

lib.php ➔ relationship_delete_relationship()   A

Complexity

Conditions 4
Paths 11

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 11
nop 1
dl 0
loc 40
rs 9.28
c 0
b 0
f 0
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 = core_tag_tag::get_item_tags_array('local_relationship', '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
        core_tag_tag::set_item_tags('local_relationship',
269
            'relationship',
270
            $relationship->id,
271
            context::instance_by_id($relationship->contextid),
272
            $relationship->tags) ;
273
274
        $event = \local_relationship\event\relationship_created::create(array(
275
                'context' => context::instance_by_id($relationship->contextid),
276
                'objectid' => $relationship->id,
277
        ));
278
        $event->add_record_snapshot('relationship', $relationship);
279
        $event->trigger();
280
281
        return $relationship->id;
282
    }
283
284
    return false;
285
}
286
287
/**
288
 * Update existing relationship
289
 *
290
 * @param sstdClass $relationship
291
 * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be 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...
292
 */
293
function relationship_update_relationship($relationship) {
294
    global $DB;
295
296
    $relationship->timemodified = time();
297
    $result = $DB->update_record('relationship', $relationship);
298
299
    if ($result) {
300
        core_tag_tag::set_item_tags('local_relationship',
301
            'relationship',
302
            $relationship->id,
303
            context::instance_by_id($relationship->contextid),
304
            $relationship->tags) ;
305
306
        $event = \local_relationship\event\relationship_updated::create(array(
307
                'context' => context::instance_by_id($relationship->contextid),
308
                'objectid' => $relationship->id,
309
        ));
310
        $event->add_record_snapshot('relationship', $relationship);
311
        $event->trigger();
312
313
        return true;
314
    }
315
316
    return false;
317
}
318
319
/**
320
 * Delete relationship
321
 * @param stdClass $relationship
322
 * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer?

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...
323
 * @throws coding_exception
324
 * @throws dml_transaction_exception
325
 */
326
function relationship_delete_relationship($relationship) {
327
    global $DB;
328
329
    $cohorts = $DB->get_records('relationship_cohorts', array('relationshipid' => $relationship->id));
330
331
    if(count($cohorts) == 0) {
332
333
        $relationshipgroups = $DB->get_records('relationship_groups', array('relationshipid' => $relationship->id));
334
        foreach ($relationshipgroups AS $g) {
335
            relationship_delete_group($g);
336
        }
337
338
        try {
339
            $transaction = $DB->start_delegated_transaction();
340
341
342
343
            $DB->delete_records('relationship_cohorts', array('relationshipid' => $relationship->id));
344
345
            $DB->delete_records('relationship', array('id' => $relationship->id));
346
347
            $transaction->allow_commit();
348
        } catch (Exception $e) {
349
            $transaction->rollback($e);
350
351
            return false;
352
        }
353
354
        $event = \local_relationship\event\relationship_deleted::create(array(
355
            'context' => context::instance_by_id($relationship->contextid),
356
            'objectid' => $relationship->id,
357
        ));
358
        $event->add_record_snapshot('relationship', $relationship);
359
        $event->trigger();
360
361
        return true;
362
    } else {
363
        return -1;
364
    }
365
}
366
367
//
368
// Relationship Cohorts
369
//
370
371
/**
372
 * Cohorts related to a relationship
373
 *
374
 * @param $relationshipid
375
 * @param bool $full load full cohort and roles data
376
 * @return array
377
 * @throws coding_exception
378
 */
379
function relationship_get_cohorts($relationshipid, $full = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
380
    global $DB;
381
382
    $cohorts = $DB->get_records('relationship_cohorts', array('relationshipid' => $relationshipid));
383
    if ($full) {
384
        foreach ($cohorts AS $ch) {
385
            $ch->cohort = $DB->get_record('cohort', array('id' => $ch->cohortid));
386
            if ($role = $DB->get_record('role', array('id' => $ch->roleid))) {
387
                $ch->role_name = role_get_name($role);
388
            } else {
389
                $ch->role_name = false;
390
            }
391
        }
392
    }
393
394
    return $cohorts;
395
}
396
397
/**
398
 * Get a specific relationshipcohort by ID
399
 *
400
 * @param $relationshipcohortid
401
 * @param bool $full load full cohort and roles data
402
 * @return mixed
403
 * @throws coding_exception
404
 */
405
function relationship_get_cohort($relationshipcohortid, $full = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
406
    global $DB;
407
408
    $cohort = $DB->get_record('relationship_cohorts', array('id' => $relationshipcohortid), '*', MUST_EXIST);
409
    if ($full) {
410
        $cohort->cohort = $DB->get_record('cohort', array('id' => $cohort->cohortid));
411
        if ($role = $DB->get_record('role', array('id' => $cohort->roleid))) {
412
            $cohort->role_name = role_get_name($role);
413
        } else {
414
            $cohort->role_name = false;
415
        }
416
    }
417
418
    return $cohort;
419
}
420
421
/**
422
 * Add a relationshipcohort
423
 *
424
 * @param $relationshipcohort
425
 * @return bool|int
426
 */
427
function relationship_add_cohort($relationshipcohort) {
428
    global $DB;
429
430
    if (!isset($relationshipcohort->timecreated)) {
431
        $relationshipcohort->timecreated = time();
432
    }
433
    if (!isset($relationshipcohort->timemodified)) {
434
        $relationshipcohort->timemodified = $relationshipcohort->timecreated;
435
    }
436
437
    $relationshipcohort->id = $DB->insert_record('relationship_cohorts', $relationshipcohort);
438
439
    return $relationshipcohort->id;
440
}
441
442
/**
443
 * Update a specific relationshipcohort
444
 *
445
 * @param $relationshipcohort
446
 * @return bool
447
 */
448
function relationship_update_cohort($relationshipcohort) {
449
    global $DB;
450
451
    $relationshipcohort->timemodified = time();
452
453
    return $DB->update_record('relationship_cohorts', $relationshipcohort);
454
}
455
456
/**
457
 * Delete a specific relationshipcohort
458
 *
459
 * @param $relationshipcohort
460
 * @return bool
461
 */
462
function relationship_delete_cohort($relationshipcohort) {
463
    global $DB;
464
    $members = $DB->get_records('relationship_members', array('relationshipcohortid' => $relationshipcohort->id));
465
    foreach ($members as $m) {
466
        relationship_remove_member($m->relationshipgroupid, $m->relationshipcohortid, $m->userid);
467
    }
468
469
    return $DB->delete_records('relationship_cohorts', array('id' => $relationshipcohort->id));
470
}
471
472
//
473
// Relationship Groups
474
//
475
476
/**
477
 * Get groups from a relationship
478
 * @param $relationshipid
479
 * @return array
480
 */
481
function relationship_get_groups($relationshipid) {
482
    global $DB;
483
484
    $sql = "SELECT rg.*, (SELECT count(*)
485
                            FROM {relationship_members}
486
                           WHERE relationshipgroupid = rg.id) as size
487
              FROM {relationship_groups} rg
488
             WHERE rg.relationshipid = :relationshipid
489
          GROUP BY rg.id
490
          ORDER BY name";
491
492
    return $DB->get_records_sql($sql, array('relationshipid' => $relationshipid));
493
}
494
495
/**
496
 * Add a relationshipgroup
497
 *
498
 * @param $relationshipgroup
499
 * @return bool|int
500
 * @throws coding_exception
501
 */
502
function relationship_add_group($relationshipgroup) {
503
    global $DB;
504
505
    $relationshipgroup->name = trim($relationshipgroup->name);
506
    if (!isset($relationshipgroup->timecreated)) {
507
        $relationshipgroup->timecreated = time();
508
    }
509
    if (!isset($relationshipgroup->timemodified)) {
510
        $relationshipgroup->timemodified = $relationshipgroup->timecreated;
511
    }
512
513
    $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
514
    $result = $DB->insert_record('relationship_groups', $relationshipgroup);
515
516
    if ($result) {
517
        $relationshipgroup->id = $result;
518
519
        $event = \local_relationship\event\relationshipgroup_created::create(array(
520
                'context' => context::instance_by_id($relationship->contextid),
521
                'objectid' => $relationshipgroup->id,
522
        ));
523
        $event->add_record_snapshot('relationship_groups', $relationshipgroup);
524
        $event->add_record_snapshot('relationship', $relationship);
525
        $event->trigger();
526
    }
527
528
    return $result;
529
}
530
531
/**
532
 * Update a relationshipgroup
533
 *
534
 * @param $relationshipgroup
535
 * @return bool
536
 * @throws coding_exception
537
 */
538
function relationship_update_group($relationshipgroup) {
539
    global $DB;
540
541
    $relationshipgroup->timemodified = time();
542
    if (isset($relationshipgroup->name)) {
543
        $relationshipgroup->name = trim($relationshipgroup->name);
544
    }
545
    $result = $DB->update_record('relationship_groups', $relationshipgroup);
546
547
    if ($result) {
548
        $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
549
550
        $event = \local_relationship\event\relationshipgroup_updated::create(array(
551
                'context' => context::instance_by_id($relationship->contextid),
552
                'objectid' => $relationshipgroup->id,
553
        ));
554
        $event->add_record_snapshot('relationship_groups', $relationshipgroup);
555
        $event->add_record_snapshot('relationship', $relationship);
556
        $event->trigger();
557
    }
558
559
    return $result;
560
}
561
562
/**
563
 * @param $relationshipgroup
564
 * @return bool
565
 * @throws coding_exception
566
 * @throws dml_transaction_exception
567
 */
568
function relationship_delete_group($relationshipgroup) {
569
    global $DB;
570
571
    try {
572
        $transaction = $DB->start_delegated_transaction();
573
574
        $relationship = $DB->get_record('relationship', array('id' => $relationshipgroup->relationshipid), '*', MUST_EXIST);
575
        $DB->delete_records('relationship_members', array('relationshipgroupid' => $relationshipgroup->id));
576
        $DB->delete_records('relationship_groups', array('id' => $relationshipgroup->id));
577
578
        $transaction->allow_commit();
579
    } catch (Exception $e) {
580
        $transaction->rollback($e);
581
582
        return false;
583
    }
584
585
    $event = \local_relationship\event\relationshipgroup_deleted::create(array(
586
            'context' => context::instance_by_id($relationship->contextid),
587
            'objectid' => $relationshipgroup->id,
588
    ));
589
    $event->add_record_snapshot('relationship_groups', $relationshipgroup);
590
    $event->add_record_snapshot('relationship', $relationship);
591
    $event->trigger();
592
593
    return true;
594
}
595