Completed
Push — master ( ae5621...ef667c )
by Julito
13:23
created

StudentPublicationLink::needs_max()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Gradebook link to student publication item.
6
 *
7
 * @author Bert Steppé
8
 *
9
 * @package chamilo.gradebook
10
 */
11
class StudentPublicationLink extends AbstractLink
12
{
13
    private $studpub_table = null;
14
    private $itemprop_table = null;
15
16
    /**
17
     * Constructor.
18
     */
19
    public function __construct()
20
    {
21
        parent::__construct();
22
        $this->set_type(LINK_STUDENTPUBLICATION);
23
    }
24
25
    /**
26
     * Returns the URL of a document
27
     * This function is loaded when using a gradebook as a tab (gradebook = -1)
28
     * see issue #2705.
29
     */
30
    public function get_view_url($stud_id)
31
    {
32
        return null;
33
        // find a file uploaded by the given student,
34
        // with the same title as the evaluation name
35
36
        $eval = $this->get_evaluation();
0 ignored issues
show
Unused Code introduced by
$eval = $this->get_evaluation() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
37
        $stud_id = intval($stud_id);
38
        $itemProperty = $this->get_itemprop_table();
39
        $workTable = $this->get_studpub_table();
40
        $courseId = $this->course_id;
41
42
        $sql = "SELECT pub.url
43
                FROM $itemProperty prop INNER JOIN $workTable pub
44
                ON (prop.c_id = pub.c_id AND prop.ref = pub.id)
45
                WHERE
46
                    prop.c_id = ".$courseId." AND
47
                    pub.c_id = ".$courseId." AND
48
                    prop.tool = 'work' AND 
49
                    prop.insert_user_id = $stud_id AND                     
50
                    pub.title = '".Database::escape_string($eval->get_name())."' AND 
51
                    pub.session_id=".api_get_session_id();
52
53
        $result = Database::query($sql);
54
        if ($fileurl = Database::fetch_row($result)) {
55
            return null;
56
        } else {
57
            return null;
58
        }
59
    }
60
61
    /**
62
     * @return string
63
     */
64
    public function get_type_name()
65
    {
66
        return get_lang('Works');
67
    }
68
69
    public function is_allowed_to_change_name()
70
    {
71
        return false;
72
    }
73
74
    /**
75
     * Generate an array of all exercises available.
76
     *
77
     * @return array 2-dimensional array - every element contains 2 subelements (id, name)
78
     */
79
    public function get_all_links()
80
    {
81
        if (empty($this->course_code)) {
82
            return [];
83
        }
84
        $em = Database::getManager();
85
        $session = $em->find('ChamiloCoreBundle:Session', api_get_session_id());
86
        /*
87
        if (empty($session_id)) {
88
            $session_condition = api_get_session_condition(0, true);
89
        } else {
90
            $session_condition = api_get_session_condition($session_id, true, true);
91
        }
92
        $sql = "SELECT id, url, title FROM $tbl_grade_links
93
                WHERE c_id = {$this->course_id}  AND filetype='folder' AND active = 1 $session_condition ";*/
94
95
        //Only show works from the session
96
        //AND has_properties != ''
97
        $links = $em
98
            ->getRepository('ChamiloCourseBundle:CStudentPublication')
99
            ->findBy([
100
                'cId' => $this->course_id,
101
                'active' => true,
102
                'filetype' => 'folder',
103
                'session' => $session,
104
            ]);
105
106
        foreach ($links as $data) {
107
            $work_name = $data->getTitle();
108
            if (empty($work_name)) {
109
                $work_name = basename($data->getUrl());
110
            }
111
            $cats[] = [$data->getId(), $work_name];
112
        }
113
        $cats = isset($cats) ? $cats : [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $cats seems to be defined by a foreach iteration on line 106. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
114
115
        return $cats;
116
    }
117
118
    /**
119
     * Has anyone done this exercise yet ?
120
     */
121
    public function has_results()
122
    {
123
        $data = $this->get_exercise_data();
124
125
        if (empty($data)) {
126
            return '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '' returns the type string which is incompatible with the return type mandated by AbstractLink::has_results() of boolean.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
127
        }
128
        $id = $data['id'];
129
130
        $em = Database::getManager();
131
        $session = $em->find('ChamiloCoreBundle:Session', api_get_session_id());
132
        $results = $em
133
            ->getRepository('ChamiloCourseBundle:CStudentPublication')
134
            ->findBy([
135
                'cId' => $this->course_id,
136
                'parentId' => $id,
137
                'session' => $session,
138
            ]);
139
140
        return count($results) != 0;
141
    }
142
143
    /**
144
     * @param null $stud_id
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $stud_id is correct as it would always require null to be passed?
Loading history...
145
     *
146
     * @return array
147
     */
148
    public function calc_score($stud_id = null, $type = null)
149
    {
150
        $stud_id = (int) $stud_id;
151
        $em = Database::getManager();
152
        $data = $this->get_exercise_data();
153
154
        if (empty($data)) {
155
            return [];
156
        }
157
        $id = $data['id'];
158
        $session = $em->find('ChamiloCoreBundle:Session', api_get_session_id());
159
160
        $assignment = $em
161
            ->getRepository('ChamiloCourseBundle:CStudentPublication')
162
            ->findOneBy([
163
                'cId' => $this->course_id,
164
                'id' => $id,
165
                'session' => $session,
166
            ])
167
        ;
168
169
        $parentId = !$assignment ? 0 : $assignment->getId();
170
171
        if (empty($session)) {
172
            $dql = 'SELECT a FROM ChamiloCourseBundle:CStudentPublication a
173
                   WHERE
174
                        a.cId = :course AND
175
                        a.active = :active AND
176
                        a.parentId = :parent AND
177
                        a.session is null AND
178
                        a.qualificatorId <> 0
179
                    ';
180
181
            $params = [
182
                'course' => $this->course_id,
183
                'parent' => $parentId,
184
                'active' => true,
185
            ];
186
        } else {
187
            $dql = 'SELECT a FROM ChamiloCourseBundle:CStudentPublication a
188
                    WHERE
189
                        a.cId = :course AND
190
                        a.active = :active AND
191
                        a.parentId = :parent AND
192
                        a.session = :session AND
193
                        a.qualificatorId <> 0
194
                    ';
195
196
            $params = [
197
                'course' => $this->course_id,
198
                'parent' => $parentId,
199
                'session' => $session,
200
                'active' => true,
201
            ];
202
        }
203
204
        if (!empty($stud_id)) {
205
            $dql .= ' AND a.userId = :student ';
206
            $params['student'] = $stud_id;
207
        }
208
209
        $order = api_get_setting('student_publication_to_take_in_gradebook');
210
211
        switch ($order) {
212
            case 'last':
213
                // latest attempt
214
                $dql .= ' ORDER BY a.sentDate DESC';
215
                break;
216
            case 'first':
217
            default:
218
                // first attempt
219
                $dql .= ' ORDER BY a.id';
220
                break;
221
        }
222
223
        $scores = $em->createQuery($dql)->execute($params);
224
225
        // for 1 student
226
        if (!empty($stud_id)) {
227
            if (!count($scores)) {
228
                return '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '' returns the type string which is incompatible with the documented return type array.
Loading history...
229
            }
230
231
            $data = $scores[0];
232
233
            return [
234
                $data->getQualification(),
235
                $assignment->getQualification(),
236
            ];
237
        }
238
239
        $students = []; // user list, needed to make sure we only
240
        // take first attempts into account
241
        $rescount = 0;
242
        $sum = 0;
243
        $bestResult = 0;
244
        $weight = 0;
245
        $sumResult = 0;
246
247
        foreach ($scores as $data) {
248
            if (!(array_key_exists($data->getUserId(), $students))) {
249
                if ($assignment->getQualification() != 0) {
250
                    $students[$data->getUserId()] = $data->getQualification();
251
                    $rescount++;
252
                    $sum += $data->getQualification() / $assignment->getQualification();
253
                    $sumResult += $data->getQualification();
254
255
                    if ($data->getQualification() > $bestResult) {
256
                        $bestResult = $data->getQualification();
257
                    }
258
                    $weight = $assignment->getQualification();
259
                }
260
            }
261
        }
262
263
        if ($rescount == 0) {
264
            return null;
265
        }
266
267
        switch ($type) {
268
            case 'best':
269
                return [$bestResult, $weight];
270
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
271
            case 'average':
272
                return [$sumResult / $rescount, $weight];
273
                break;
274
            case 'ranking':
275
                return AbstractLink::getCurrentUserRanking($stud_id, $students);
276
                break;
277
            default:
278
                return [$sum, $rescount];
279
                break;
280
        }
281
    }
282
283
    public function needs_name_and_description()
284
    {
285
        return false;
286
    }
287
288
    public function get_name()
289
    {
290
        $this->get_exercise_data();
291
        $name = isset($this->exercise_data['title']) && !empty($this->exercise_data['title']) ? $this->exercise_data['title'] : get_lang('Untitled');
292
293
        return $name;
294
    }
295
296
    public function get_description()
297
    {
298
        $this->get_exercise_data();
299
300
        return isset($this->exercise_data['description']) ? $this->exercise_data['description'] : null;
301
    }
302
303
    public function get_link()
304
    {
305
        $session_id = api_get_session_id();
306
        $url = api_get_path(WEB_PATH).'main/work/work.php?'.api_get_cidreq_params($this->get_course_code(), $session_id).'&id='.$this->exercise_data['id'].'&gradebook=view';
307
308
        return $url;
309
    }
310
311
    public function needs_max()
312
    {
313
        return false;
314
    }
315
316
    public function needs_results()
317
    {
318
        return false;
319
    }
320
321
    public function is_valid_link()
322
    {
323
        $data = $this->get_exercise_data();
324
325
        if (empty($data)) {
326
            return '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '' returns the type string which is incompatible with the return type mandated by AbstractLink::is_valid_link() of boolean.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
327
        }
328
        $id = $data['id'];
329
        $sql = 'SELECT count(id) FROM '.$this->get_studpub_table().'
330
                WHERE 
331
                    c_id = "'.$this->course_id.'" AND 
332
                    id = '.$id.'';
333
        $result = Database::query($sql);
334
        $number = Database::fetch_row($result);
335
336
        return $number[0] != 0;
337
    }
338
339
    public function get_icon_name()
340
    {
341
        return 'studentpublication';
342
    }
343
344
    public function save_linked_data()
345
    {
346
        $data = $this->get_exercise_data();
347
348
        if (empty($data)) {
349
            return '';
350
        }
351
        $id = $data['id'];
352
353
        $weight = api_float_val($this->get_weight());
354
        if (!empty($id)) {
355
            //Cleans works
356
            $sql = 'UPDATE '.$this->get_studpub_table().' 
357
                    SET weight= '.$weight.'
358
                    WHERE c_id = '.$this->course_id.' AND id ='.$id;
359
            Database::query($sql);
360
        }
361
    }
362
363
    /**
364
     * @return string
365
     */
366
    public function delete_linked_data()
367
    {
368
        $data = $this->get_exercise_data();
369
        if (empty($data)) {
370
            return '';
371
        }
372
373
        if (!empty($id)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $id seems to never exist and therefore empty should always be true.
Loading history...
374
            //Cleans works
375
            $sql = 'UPDATE '.$this->get_studpub_table().' 
376
                    SET weight = 0
377
                    WHERE c_id = '.$this->course_id.' AND id ='.$id;
378
            Database::query($sql);
379
        }
380
    }
381
382
    /**
383
     * Lazy load function to get the database table of the student publications.
384
     */
385
    private function get_studpub_table()
386
    {
387
        return $this->studpub_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
388
    }
389
390
    /**
391
     * Lazy load function to get the database table of the item properties.
392
     */
393
    private function get_itemprop_table()
394
    {
395
        return $this->itemprop_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
396
    }
397
398
    /**
399
     * @return array
400
     */
401
    private function get_exercise_data()
402
    {
403
        $course_info = api_get_course_info($this->get_course_code());
404
        if (!isset($this->exercise_data)) {
405
            $sql = 'SELECT * FROM '.$this->get_studpub_table()."
406
                    WHERE
407
                        c_id ='".$course_info['real_id']."' AND
408
                        id = '".$this->get_ref_id()."' ";
409
            $query = Database::query($sql);
410
            $this->exercise_data = Database::fetch_array($query);
0 ignored issues
show
Bug Best Practice introduced by
The property exercise_data does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
411
412
            // Try with iid
413
            if (empty($this->exercise_data)) {
414
                $sql = 'SELECT * FROM '.$this->get_studpub_table()."
415
                        WHERE
416
                            c_id ='".$course_info['real_id']."' AND
417
                            iid = '".$this->get_ref_id()."' ";
418
                $query = Database::query($sql);
419
                $this->exercise_data = Database::fetch_array($query);
420
            }
421
        }
422
423
        return $this->exercise_data;
424
    }
425
}
426