Test Setup Failed
Push — master ( f71949...6c6bd7 )
by Julito
55:21
created

HomeController::render2ColumnView()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CourseBundle\Controller\Home;
5
6
use Chamilo\CourseBundle\Controller\ToolBaseController;
7
use Symfony\Component\HttpFoundation\Response;
8
use Symfony\Component\Routing\Annotation\Route;
9
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
10
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
11
use Chamilo\CourseBundle\Entity\CTool;
12
use Display;
13
use CourseHome;
14
use Symfony\Component\HttpFoundation\Request;
15
16
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
17
18
/**
19
 * Class HomeController
20
 * @package Chamilo\CourseBundle\Controller\Home
21
 * @author Julio Montoya <[email protected]>
22
 * @Route("/")
23
 */
24
class HomeController extends ToolBaseController
25
{
26
    /**
27
     * @Route("/", name="course_home")
28
     * @Route("/index.php")
29
     * @Method({"GET"})
30
     *
31
     * @param Request $request
32
     * @return Response
33
     */
34
    public function indexAction(Request $request)
35
    {
36
        $sessionId = api_get_session_id();
37
        $course = $this->getCourse();
38
        $courseCode = $course->getId();
39
        $result = $this->autoLaunch();
40
41
        $showAutoLaunchLpWarning = $result['show_autolaunch_lp_warning'];
42
        $showAutoLaunchExerciseWarning = $result['show_autolaunch_exercise_warning'];
43
44
        if ($showAutoLaunchLpWarning) {
45
            $this->addFlash(
46
                'warning',
47
                $this->trans('TheLPAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificLP')
48
            );
49
        }
50
51
        if ($showAutoLaunchExerciseWarning) {
52
            $this->addFlash(
53
                'warning',
54
                $this->trans('TheExerciseAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificExercise')
55
            );
56
        }
57
58
        if (true) {
0 ignored issues
show
Bug introduced by
Avoid IF statements that are always true or false
Loading history...
59
            $editIcons = Display::url(
60
                Display::return_icon('edit.png'),
61
                $this->generateUrl(
62
                    'chamilo_course_home_home_iconlist',
63
                    array(
64
                        'course' => api_get_course_id(),
65
                    )
66
                )
67
            );
68
        }
69
70
        $isSpecialCourse = \CourseManager::isSpecialCourse($courseCode);
71
72
        if ($isSpecialCourse) {
73
            $user = $this->getUser();
74
            if (!empty($user)) {
75
                $userId = $this->getUser()->getId();
76
                $autoreg = $request->get('autoreg');
77
                if ($autoreg == 1) {
78
                    \CourseManager::subscribe_user(
79
                        $userId,
80
                        $courseCode,
81
                        STUDENT
82
                    );
83
                }
84
            }
85
        }
86
87
        $homeView = api_get_setting('course.homepage_view');
88
89
        if ($homeView == 'activity' || $homeView == 'activity_big') {
90
            $result = $this->renderActivityView();
91
        } elseif ($homeView == '2column') {
92
            $result = $this->render2ColumnView();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $this->render2ColumnView() (which targets Chamilo\CourseBundle\Con...er::render2ColumnView()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
93
        } elseif ($homeView == '3column') {
94
            $result = $this->render3ColumnView();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $this->render3ColumnView() (which targets Chamilo\CourseBundle\Con...er::render3ColumnView()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
95
        } elseif ($homeView == 'vertical_activity') {
96
            $result = $this->renderVerticalActivityView();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $this->renderVerticalActivityView() (which targets Chamilo\CourseBundle\Con...rVerticalActivityView()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
97
        }
98
99
        $toolList = $result['tool_list'];
100
101
        $introduction = Display::return_introduction_section(
102
            TOOL_COURSE_HOMEPAGE,
103
            $toolList
104
        );
105
106
        $sessionInfo = null;
107
        if (api_get_setting('session.show_session_data') == 'true' && $sessionId) {
108
            $sessionInfo = CourseHome::show_session_data($sessionId);
109
        }
110
111
        return $this->render(
112
            'ChamiloCourseBundle:Home:index.html.twig',
113
            array(
114
                'course' => $course,
115
                'session_info' => $sessionInfo,
116
                'icons' => $result['content'],
117
                'edit_icons' => $editIcons,
118
                'introduction_text' => $introduction,
119
                'exercise_warning' => null,
120
                'lp_warning' => null
121
            )
122
        );
123
    }
124
125
    /**
126
     * @param string $title
127
     * @param string $content
128
     * @param string $class
129
     * @return string
130
     */
131 View Code Duplication
    private function return_block($title, $content, $class = null)
132
    {
133
        $html = '<div class="row">
134
                <div class="col-xs-12 col-md-12">
135
                    <div class="title-tools">'.$title.'</div>
136
                </div>
137
            </div>
138
            <div class="row '.$class.'">'.$content.'</div>';
139
140
        return $html;
141
    }
142
143
    /**
144
     * @return array
145
     */
146
    private function renderActivityView()
147
    {
148
        $session_id = api_get_session_id();
149
        $urlGenerator = $this->get('router');
150
        $content = '';
151
152
        // Start of tools for CourseAdmins (teachers/tutors)
153
        $totalList = array();
154
155
        if ($session_id == 0 &&
156
            api_is_course_admin() &&
157
            api_is_allowed_to_edit(null, true)
158
        ) {
159
            $list = CourseHome::get_tools_category(TOOL_AUTHORING);
160
            $result = CourseHome::show_tools_category($urlGenerator, $list);
161
162
            $content .= $this->return_block(get_lang('Authoring'), $result['content']);
163
164
            $totalList = $result['tool_list'];
165
166
            $list = CourseHome::get_tools_category(TOOL_INTERACTION);
167
            $list2 = CourseHome::get_tools_category(TOOL_COURSE_PLUGIN);
168
            $list = array_merge($list, $list2);
169
            $result =  CourseHome::show_tools_category($urlGenerator, $list);
170
            $totalList = array_merge($totalList, $result['tool_list']);
171
172
            $content .= $this->return_block(get_lang('Interaction'), $result['content']);
173
174
            $list = CourseHome::get_tools_category(TOOL_ADMIN_PLATFORM);
175
            $totalList = array_merge($totalList, $list);
176
            $result = CourseHome::show_tools_category($urlGenerator, $list);
177
            $totalList = array_merge($totalList, $result['tool_list']);
178
179
            $content .= $this->return_block(get_lang('Administration'), $result['content']);
180
181
        } elseif (api_is_coach()) {
182
            $content .=  '<div class="row">';
183
            $list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
184
            $result = CourseHome::show_tools_category($urlGenerator, $list);
185
            $content .= $result['content'];
186
            $totalList = array_merge($totalList, $result['tool_list']);
187
            $content .= '</div>';
188
        } else {
189
            $list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
190
            if (count($list) > 0) {
191
                $content .= '<div class="row">';
192
                $result = CourseHome::show_tools_category($urlGenerator, $list);
193
                $content .= $result['content'];
194
                $totalList = array_merge($totalList, $result['tool_list']);
195
                $content .= '</div>';
196
            }
197
        }
198
199
        return array(
200
            'content' => $content,
201
            'tool_list' => $totalList
202
        );
203
    }
204
205
    private function render2ColumnView()
206
    {
207
208
    }
209
210
    private function render3ColumnView()
211
    {
212
213
    }
214
215
    private function renderVerticalActivityView()
216
    {
217
218
    }
219
220
    /**
221
     * @return array
222
     */
223
    private function autoLaunch()
224
    {
225
        return;
226
        $showAutoLaunchExerciseWarning = false;
0 ignored issues
show
Unused Code introduced by
$showAutoLaunchExerciseWarning = false; does not seem to be 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...
227
228
        // Exercise auto-launch
229
        $auto_launch = api_get_course_setting('enable_exercise_auto_launch');
230
231 View Code Duplication
        if (!empty($auto_launch)) {
232
            $session_id = api_get_session_id();
233
            //Exercise list
234
            if ($auto_launch == 2) {
235
                if (api_is_platform_admin() || api_is_allowed_to_edit()) {
236
                    $showAutoLaunchExerciseWarning = true;
237
                } else {
238
                    $session_key = 'exercise_autolunch_'.$session_id.'_'.api_get_course_int_id().'_'.api_get_user_id();
239
                    $sessionData = Session::read($session_key);
240
                    if (!isset($sessionData)) {
241
                        //redirecting to the Exercise
242
                        $url = api_get_path(WEB_CODE_PATH).'exercise/exercice.php?'.api_get_cidreq().'&id_session='.$session_id;
243
                        $_SESSION[$session_key] = true;
244
245
                        header("Location: $url");
246
                        exit;
247
                    }
248
                }
249
            } else {
250
                $table = \Database::get_course_table(TABLE_QUIZ_TEST);
251
                $course_id = api_get_course_int_id();
252
                $condition = '';
253
                if (!empty($session_id)) {
254
                    $condition =  api_get_session_condition($session_id);
255
                    $sql = "SELECT iid FROM $table
256
                            WHERE c_id = $course_id AND autolaunch = 1 $condition
257
                            LIMIT 1";
258
                    $result = \Database::query($sql);
259
                    //If we found nothing in the session we just called the session_id =  0 autolaunch
260
                    if (\Database::num_rows($result) ==  0) {
261
                        $condition = '';
262
                    } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
263
                        //great, there is an specific auto lunch for this session we leave the $condition
264
                    }
265
                }
266
267
                $sql = "SELECT iid FROM $table
268
                        WHERE c_id = $course_id AND autolaunch = 1 $condition
269
                        LIMIT 1";
270
                $result = \Database::query($sql);
271
                if (\Database::num_rows($result) >  0) {
272
                    $data = \Database::fetch_array($result, 'ASSOC');
273
                    if (!empty($data['iid'])) {
274
                        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
275
                            $showAutoLaunchExerciseWarning = true;
276
                        } else {
277
                            $session_key = 'exercise_autolunch_'.$session_id.'_'.api_get_course_int_id().'_'.api_get_user_id();
278
                            if (!isset($_SESSION[$session_key])) {
279
                                //redirecting to the LP
280
                                $url = api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.api_get_cidreq().'&exerciseId='.$data['iid'];
281
282
                                $_SESSION[$session_key] = true;
283
                                header("Location: $url");
284
                                exit;
285
                            }
286
                        }
287
                    }
288
                }
289
            }
290
        }
291
292
        /* Auto launch code */
293
        $showAutoLaunchLpWarning = false;
294
        $auto_launch = api_get_course_setting('enable_lp_auto_launch');
295 View Code Duplication
        if (!empty($auto_launch)) {
296
            $session_id = api_get_session_id();
297
            //LP list
298
            if ($auto_launch == 2) {
299
                if (api_is_platform_admin() || api_is_allowed_to_edit()) {
300
                    $showAutoLaunchLpWarning = true;
301
                } else {
302
                    $session_key = 'lp_autolunch_'.$session_id.'_'.api_get_course_int_id().'_'.api_get_user_id();
303
                    if (!isset($_SESSION[$session_key])) {
304
                        //redirecting to the LP
305
                        $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.api_get_cidreq().'&id_session='.$session_id;
306
                        $_SESSION[$session_key] = true;
307
                        header("Location: $url");
308
                        exit;
309
                    }
310
                }
311
            } else {
312
                $lp_table = \Database::get_course_table(TABLE_LP_MAIN);
313
                $course_id = api_get_course_int_id();
314
                $condition = '';
315
                if (!empty($session_id)) {
316
                    $condition =  api_get_session_condition($session_id);
317
                    $sql = "SELECT id FROM $lp_table WHERE c_id = $course_id AND autolunch = 1 $condition LIMIT 1";
318
                    $result = \Database::query($sql);
319
                    //If we found nothing in the session we just called the session_id =  0 autolunch
320
                    if (\Database::num_rows($result) ==  0) {
321
                        $condition = '';
322
                    } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
323
                        //great, there is an specific auto lunch for this session we leave the $condition
324
                    }
325
                }
326
327
                $sql = "SELECT id FROM $lp_table
328
                        WHERE c_id = $course_id AND autolunch = 1 $condition
329
                        LIMIT 1";
330
                $result = \Database::query($sql);
331
                if (\Database::num_rows($result) >  0) {
332
                    $lp_data = \Database::fetch_array($result, 'ASSOC');
333
                    if (!empty($lp_data['id'])) {
334
                        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
335
                            $showAutoLaunchLpWarning = true;
336
                        } else {
337
                            $session_key = 'lp_autolunch_'.$session_id.'_'.api_get_course_int_id().'_'.api_get_user_id();
338
                            if (!isset($_SESSION[$session_key])) {
339
                                //redirecting to the LP
340
                                $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$lp_data['id'];
341
342
                                $_SESSION[$session_key] = true;
343
                                header("Location: $url");
344
                                exit;
345
                            }
346
                        }
347
                    }
348
                }
349
            }
350
        }
351
352
        return array(
353
            'show_autolaunch_exercise_warning' => $showAutoLaunchExerciseWarning,
354
            'show_autolaunch_lp_warning' => $showAutoLaunchLpWarning
355
        );
356
    }
357
358
    /**
359
     * @param string $courseCode
360
     * @param string $fileName
361
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
362
     */
363
    public function getFileAction($courseCode, $fileName)
364
    {
365
        $courseInfo = api_get_course_info($courseCode);
366
        $sessionId = $this->getRequest()->get('id_session');
367
368
        $docId = \DocumentManager::get_document_id($courseInfo, "/".$fileName);
369
370
        $filePath = null;
371
372
        if ($docId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $docId of type integer|false is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
373
            $isVisible = \DocumentManager::is_visible_by_id($docId, $courseInfo, $sessionId, api_get_user_id());
374
            $documentData = \DocumentManager::get_document_data_by_id($docId, $courseCode);
375
            $filePath = $documentData['absolute_path'];
376
            event_download($filePath);
377
        }
378
379
        if (!api_is_allowed_to_edit() && !$isVisible) {
380
            $this->abort(500);
381
        }
382
        return $this->sendFile($filePath);
383
    }
384
385
    /**
386
     * @Route("/show/{iconId}")
387
     * @Method({"GET"})
388
     * @param $iconId
389
     * @return null|string
390
     */
391
    public function showIconAction($iconId)
392
    {
393
        $entityManager = $this->getDoctrine()->getManager();
394
        $criteria = array('cId' => api_get_course_int_id(), 'id' => $iconId);
395
        $tool = $this->getRepository(
396
            'Chamilo\CourseBundle\Entity\CTool'
397
        )->findOneBy($criteria);
398
        if ($tool) {
399
            $tool->setVisibility(1);
400
        }
401
        $entityManager->persist($tool);
402
        //$entityManager->flush();
403
        return Display::return_message(get_lang('Visible'), 'confirmation');
404
    }
405
406
    /**
407
     * @Route("/hide/{iconId}")
408
     * @Method({"GET"})
409
     * @param $iconId
410
     * @return null|string
411
     */
412 View Code Duplication
    public function hideIconAction($iconId)
413
    {
414
        if (!$this->isCourseTeacher()) {
415
            return $this->abort(404);
416
        }
417
418
        $entityManager = $this->getDoctrine()->getManager();
419
        $criteria = array('cId' => api_get_course_int_id(), 'id' => $iconId);
420
        $tool = $this->getRepository(
421
            'Chamilo\CourseBundle\Entity\CTool'
422
        )->findOneBy($criteria);
423
        if ($tool) {
424
            $tool->setVisibility(0);
425
        }
426
        $entityManager->persist($tool);
427
        //$entityManager->flush();
428
        return Display::return_message(get_lang('ToolIsNowHidden'), 'confirmation');
429
    }
430
431
    /**
432
     * @Route("/delete/{iconId}")
433
     * @Method({"GET"})
434
     * @param $iconId
435
     * @return null|string
436
     */
437 View Code Duplication
    public function deleteIcon($iconId)
438
    {
439
        if (!$this->isCourseTeacher()) {
440
            return $this->abort(404);
441
        }
442
443
        $entityManager = $this->getDoctrine()->getManager();
444
        $criteria = array('cId' => api_get_course_int_id(), 'id' => $iconId, 'added_tool' => 1);
445
        $tool = $this->getRepository(
446
            'Chamilo\CourseBundle\Entity\CTool'
447
        )->findOneBy($criteria);
448
        $entityManager->remove($tool);
449
        //$entityManager->flush();
450
        return Display::return_message(get_lang('Deleted'), 'confirmation');
451
    }
452
453
    /**
454
     * @Route("/icon_list")
455
     * @Method({"GET"})
456
     * @param Request $request
457
     */
458
    public function iconListAction(Request $request)
459
    {
460
        $em = $this->getDoctrine()->getManager();
461
        $repo = $this->getDoctrine()->getRepository(
462
            'ChamiloCourseBundle:CTool'
463
        );
464
465
        $sessionId = intval($request->get('id_session'));
466
        $itemsFromSession = array();
467
        if (!empty($sessionId)) {
468
            $query = $repo->createQueryBuilder('a');
469
            $query->select('s');
470
            $query->from('Chamilo\CourseBundle\Entity\CTool', 's');
471
            $query->where('s.cId  = :courseId AND s.sessionId = :sessionId')
472
                ->setParameters(
473
                    array(
474
                        'courseId' => $this->getCourse()->getId(),
475
                        'sessionId' => $sessionId
476
                    )
477
                );
478
            $itemsFromSession = $query->getQuery()->getResult();
479
480
            $itemNameList = array();
481
            foreach ($itemsFromSession as $item) {
482
                $itemNameList[] = $item->getName();
483
            }
484
485
            //$itemsFromSession = $this->getRepository()->findBy($criteria);
486
            $query = $repo->createQueryBuilder('a');
487
            $query->select('s');
488
            $query->from('Chamilo\CourseBundle\Entity\CTool', 's');
489
            $query->where('s.cId  = :courseId AND s.sessionId = 0')
490
                ->setParameters(
491
                    array(
492
                        'courseId' => $this->getCourse()->getId()
493
                    )
494
                );
495
            if (!empty($itemNameList)) {
496
                $query->andWhere($query->expr()->notIn('s.name', $itemNameList));
497
            }
498
            $itemsFromCourse = $query->getQuery()->getResult();
499
        } else {
500
            $criteria = array('cId' => $this->getCourse()->getId(), 'sessionId' => 0);
501
            $itemsFromCourse = $repo->findBy($criteria);
502
        }
503
504
505
        return $this->render(
506
            '@ChamiloCourse/Home/list.html.twig',
507
            [
508
                'items_from_course' => $itemsFromCourse,
509
                'items_from_session' => $itemsFromSession,
510
                'links' => '',
511
            ]
512
        );
513
    }
514
515
    /**
516
     *
517
     * @Route("/{itemName}/add")
518
     * @Method({"GET|POST"})
519
     * @param $itemName
520
     * @return mixed
521
     */
522
    public function addIconAction($itemName)
523
    {
524
        if (!$this->isCourseTeacher()) {
525
            return $this->abort(404);
526
        }
527
528
        $sessionId = intval($this->getRequest()->get('id_session'));
529
530
        if (empty($sessionId)) {
531
            return $this->abort(500);
532
        }
533
534
        $criteria = array('cId' => $this->getCourse()->getId(), 'sessionId' => 0, 'name' => $itemName);
535
        $itemFromDatabase = $this->getRepository()->findOneBy($criteria);
536
537
        if (!$itemFromDatabase) {
538
            $this->createNotFoundException();
539
        }
540
        /** @var CTool $item */
541
        $item = clone $itemFromDatabase;
542
        $item->setId(null);
543
        $item->setSessionId($sessionId);
544
        $form = $this->createForm($this->getFormType(), $item);
545
546
        $form->handleRequest($this->getRequest());
547
548
        if ($form->isValid()) {
549
550
            $query = $this->getDoctrine()->getManager()->createQueryBuilder('a');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Doctrine\Common\Persistence\ObjectManager as the method createQueryBuilder() does only exist in the following implementations of said interface: Doctrine\ORM\Decorator\EntityManagerDecorator, Doctrine\ORM\EntityManager.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
551
            $query->select('MAX(s.id) as id');
552
            $query->from('Chamilo\CourseBundle\Entity\CTool', 's');
553
            $query->where('s.cId  = :courseId')->setParameter('courseId', $this->getCourse()->getId());
554
            $result = $query->getQuery()->getArrayResult();
555
            $maxId = $result[0]['id'] + 1;
556
            $item->setId($maxId);
557
558
            $entityManager = $this->getDoctrine()->getManager();
559
            $entityManager->persist($item);
560
            $entityManager->flush();
561
            $customIcon = $item->getCustomIcon();
562
            if (!empty($customIcon)) {
563
                $item->createGrayIcon($this->get('imagine'));
564
            }
565
566
            $this->get('session')->getFlashBag()->add('success', "Added");
567
            $url = $this->generateUrl('course_home.controller:iconListAction', array('id_session' => $sessionId));
568
            return $this->redirect($url);
569
        }
570
571
        $this->getTemplate()->assign('item', $item);
572
        $this->getTemplate()->assign('form', $form->createView());
573
        $this->getTemplate()->assign('links', $this->generateLinks());
574
575
        return $this->render('@ChamiloCourse/Home/add.html.twig');
576
577
    }
578
579
    /**
580
     * @Route("/{itemId}/edit")
581
     * @Method({"GET"})
582
     */
583
    public function editIconAction($itemId)
584
    {
585
        if (!$this->isCourseTeacher()) {
586
            return $this->abort(404);
587
        }
588
589
        $sessionId = intval($this->getRequest()->get('id_session'));
590
591
        $criteria = array('cId' => $this->getCourse()->getId(), 'id' => $itemId);
592
        /** @var CTool $item */
593
        $item = $this->getRepository()->findOneBy($criteria);
594
595
        $form = $this->createForm($this->getFormType(), $item);
596
        $form->handleRequest($this->getRequest());
597
598
        if ($form->isValid()) {
599
            $entityManager = $this->getDoctrine()->getManager();
600
            $entityManager->persist($item);
601
            $entityManager->flush();
602
603
            $customIcon = $item->getCustomIcon();
604
            if (!empty($customIcon)) {
605
                $item->createGrayIcon($this->get('imagine'));
606
            }
607
608
            $this->get('session')->getFlashBag()->add('success', "Updated");
609
            $url = $this->generateUrl('course_home.controller:iconListAction', array('id_session' => $sessionId));
610
            return $this->redirect($url);
611
        }
612
613
        $this->getTemplate()->assign('item', $item);
614
        $this->getTemplate()->assign('form', $form->createView());
615
        $this->getTemplate()->assign('links', $this->generateLinks());
616
617
        return $this->render('@ChamiloCourse/Home/edit.html.twig');
618
    }
619
620
    /**
621
     * @Route("/{itemId}/delete")
622
     * @Method({"GET"})
623
     */
624
    public function deleteIconAction($itemId)
625
    {
626
        if (!$this->isCourseTeacher()) {
627
            return $this->abort(404);
628
        }
629
630
        $criteria = array('cId' => $this->getCourse()->getId(), 'id' => $itemId);
631
632
        /** @var CTool $item */
633
        $item = $this->getRepository()->findOneBy($criteria);
634
        $entityManager = $this->getDoctrine()->getManager();
635
        $sessionId = $item->getSessionId();
636
        if (!empty($sessionId)) {
637
            $entityManager->remove($item);
638
        } else {
639
            $item->setCustomIcon(null);
640
            $entityManager->persist($item);
641
        }
642
        $entityManager->flush();
643
        $this->get('session')->getFlashBag()->add('success', "Deleted");
644
645
        $this->getTemplate()->assign('links', $this->generateLinks());
646
        $url = $this->generateUrl('course_home.controller:iconListAction');
647
        return $this->redirect($url);
648
    }
649
}
650