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
|
<?php
/*
* VipsExerciseRef.php - Vips exercise reference class for Stud.IP
* Copyright (c) 2016 Elmar Ludwig
*
* 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.
*/
/**
* @license GPL2 or any later version
*
* @property array $id alias for pk
* @property int $test_id database column
* @property int $task_id database column
* @property int $position database column
* @property int $part database column
* @property float|null $points database column
* @property string $options database column
* @property int|null $mkdate database column
* @property int|null $chdate database column
* @property Exercise $exercise belongs_to Exercise
* @property VipsTest $test belongs_to VipsTest
*/
class VipsExerciseRef extends SimpleORMap
{
/**
* Configure the database mapping.
*/
protected static function configure($config = [])
{
$config['db_table'] = 'etask_test_tasks';
$config['belongs_to']['exercise'] = [
'class_name' => Exercise::class,
'foreign_key' => 'task_id'
];
$config['belongs_to']['test'] = [
'class_name' => VipsTest::class,
'foreign_key' => 'test_id'
];
parent::configure($config);
}
/**
* Set value for the "exercise" relation (to avoid SORM errors).
*/
public function setExercise(Exercise $exercise): void
{
$this->task_id = $exercise->id;
$this->relations['exercise'] = $exercise;
}
/**
* Delete entry from the database.
*/
public function delete()
{
$ref_count = self::countBySql('task_id = ?', [$this->task_id]);
if ($ref_count == 1) {
$this->exercise->delete();
}
return parent::delete();
}
/**
* Copy the referenced exercise into the given test at the specified
* position (or at the end). Returns the new exercise reference.
*
* @param string $test_id test id
* @param int $position exercise position (optional)
*/
public function copyIntoTest(string $test_id, ?int $position = null): VipsExerciseRef
{
$db = DBManager::get();
if ($position === null) {
$stmt = $db->prepare('SELECT MAX(position) FROM etask_test_tasks WHERE test_id = ?');
$stmt->execute([$test_id]);
$position = $stmt->fetchColumn() + 1;
}
$new_exercise = Exercise::create([
'type' => $this->exercise->type,
'title' => $this->exercise->title,
'description' => $this->exercise->description,
'task' => $this->exercise->task,
'options' => $this->exercise->options,
'user_id' => $GLOBALS['user']->id
]);
if ($this->exercise->folder) {
$folder = Folder::findTopFolder($new_exercise->id, 'ExerciseFolder', 'task');
foreach ($this->exercise->folder->file_refs as $file_ref) {
FileManager::copyFile($file_ref->getFileType(), $folder->getTypedFolder(), User::findCurrent());
}
}
return VipsExerciseRef::create([
'task_id' => $new_exercise->id,
'test_id' => $test_id,
'points' => $this->points,
'position' => $position
]);
}
/**
* Move the referenced exercise into the given test (at the end).
*
* @param string $test_id test id
*/
public function moveIntoTest(string $test_id): void
{
$db = DBManager::get();
$old_test_id = $this->test_id;
$old_position = $this->position;
if ($old_test_id != $test_id) {
$stmt = $db->prepare('SELECT MAX(position) FROM etask_test_tasks WHERE test_id = ?');
$stmt->execute([$test_id]);
$this->position = $stmt->fetchColumn() + 1;
$this->test_id = $test_id;
$this->store();
// renumber following exercises
$sql = 'UPDATE etask_test_tasks SET position = position - 1 WHERE test_id = ? AND position > ?';
$stmt = $db->prepare($sql);
$stmt->execute([$old_test_id, $old_position]);
}
}
}
|