Passed
Push — master ( 6f8cb0...cccadf )
by Julito
09:47
created

CoursesController   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 568
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 303
dl 0
loc 568
rs 6
c 0
b 0
f 0
wmc 55

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A search_courses() 0 43 4
B courses_categories() 0 64 9
A unsubscribe_user_from_course() 0 23 3
A getAlreadyRegisteredInSessionLabel() 0 9 1
A getSessionIcon() 0 7 1
B getRegisteredInSessionButton() 0 94 7
A sessionsListByCoursesTag() 0 31 5
F getFormattedSessionsBlock() 0 130 16
A sessionList() 0 40 5
A getLimitArray() 0 9 3

How to fix   Complexity   

Complex Class

Complex classes like CoursesController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CoursesController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\SequenceResource;
5
use Chamilo\CoreBundle\Entity\SessionRelCourse;
6
use Chamilo\CoreBundle\Entity\Tag;
7
use Chamilo\CoreBundle\Repository\SequenceRepository;
8
9
/**
10
 * Class CoursesController.
11
 *
12
 * This file contains class used like controller,
13
 * it should be included inside a dispatcher file (e.g: index.php)
14
 *
15
 * @author Christian Fasanando <[email protected]> - BeezNest
16
 *
17
 * @package chamilo.auth
18
 */
19
class CoursesController
20
{
21
    private $toolname;
22
    private $view;
23
    private $model;
24
25
    /**
26
     * Constructor.
27
     */
28
    public function __construct()
29
    {
30
        $this->toolname = 'auth';
31
        //$actived_theme_path = api_get_template();
32
        $this->view = new View($this->toolname);
33
        $this->model = new Auth();
34
    }
35
36
    /**
37
     * It's used for listing courses with categories,
38
     * render to courses_categories view.
39
     *
40
     * @param string $action
41
     * @param string $category_code
42
     * @param string $message
43
     * @param string $error
44
     * @param string $content
45
     * @param array  $limit         will be used if $random_value is not set.
46
     *                              This array should contains 'start' and 'length' keys
47
     *
48
     * @internal param \action $string
49
     * @internal param \Category $string code (optional)
50
     */
51
    public function courses_categories(
52
        $action,
53
        $category_code = null,
54
        $message = '',
55
        $error = '',
56
        $content = null,
57
        $limit = []
58
    ) {
59
        $data = [];
60
        $listCategories = CoursesAndSessionsCatalog::getCourseCategoriesTree();
61
62
        $data['countCoursesInCategory'] = CourseCategory::countCoursesInCategory($category_code);
63
        if ($action === 'display_random_courses') {
64
            // Random value is used instead limit filter
65
            $data['browse_courses_in_category'] = CoursesAndSessionsCatalog::getCoursesInCategory(null, 12);
66
            $data['countCoursesInCategory'] = count($data['browse_courses_in_category']);
67
        } else {
68
            if (!isset($category_code)) {
69
                $category_code = $listCategories['ALL']['code']; // by default first category
70
            }
71
            $limit = isset($limit) ? $limit : self::getLimitArray();
72
            $listCourses = CoursesAndSessionsCatalog::getCoursesInCategory($category_code, null, $limit);
73
74
            $data['browse_courses_in_category'] = $listCourses;
75
        }
76
77
        $data['list_categories'] = $listCategories;
78
        $data['code'] = Security::remove_XSS($category_code);
79
80
        // getting all the courses to which the user is subscribed to
81
        $curr_user_id = api_get_user_id();
82
        $user_courses = $this->model->get_courses_of_user($curr_user_id);
83
        $user_coursecodes = [];
84
85
        // we need only the course codes as these will be used to match against the courses of the category
86
        if ($user_courses != '') {
87
            foreach ($user_courses as $key => $value) {
88
                $user_coursecodes[] = $value['code'];
89
            }
90
        }
91
92
        if (api_is_drh()) {
93
            $courses = CourseManager::get_courses_followed_by_drh(api_get_user_id());
94
            foreach ($courses as $course) {
95
                $user_coursecodes[] = $course['code'];
96
            }
97
        }
98
99
        $data['user_coursecodes'] = $user_coursecodes;
100
        $data['action'] = $action;
101
        $data['message'] = $message;
102
        $data['content'] = $content;
103
        $data['error'] = $error;
104
        $data['catalogShowCoursesSessions'] = 0;
105
        $showCoursesSessions = (int) api_get_setting('catalog_show_courses_sessions');
106
        if ($showCoursesSessions > 0) {
107
            $data['catalogShowCoursesSessions'] = $showCoursesSessions;
108
        }
109
110
        // render to the view
111
        $this->view->set_data($data);
112
        $this->view->set_layout('layout');
113
        $this->view->set_template('courses_categories');
114
        $this->view->render();
115
    }
116
117
    /**
118
     * @param string $search_term
119
     * @param string $message
120
     * @param string $error
121
     * @param string $content
122
     * @param array  $limit
123
     * @param bool   $justVisible Whether to search only in courses visibles in the catalogue
124
     */
125
    public function search_courses(
126
        $search_term,
127
        $message = '',
128
        $error = '',
129
        $content = null,
130
        $limit = [],
131
        $justVisible = false
132
    ) {
133
        $data = [];
134
        $limit = !empty($limit) ? $limit : self::getLimitArray();
135
        $browse_course_categories = CoursesAndSessionsCatalog::getCourseCategories();
136
        $data['countCoursesInCategory'] = CourseCategory::countCoursesInCategory('ALL', $search_term);
137
        $data['browse_courses_in_category'] = CoursesAndSessionsCatalog::search_courses(
138
            $search_term,
139
            $limit,
140
            $justVisible
141
        );
142
        $data['browse_course_categories'] = $browse_course_categories;
143
        $data['search_term'] = Security::remove_XSS($search_term); //filter before showing in template
144
145
        // getting all the courses to which the user is subscribed to
146
        $curr_user_id = api_get_user_id();
147
        $user_courses = $this->model->get_courses_of_user($curr_user_id);
148
        $user_coursecodes = [];
149
150
        // we need only the course codes as these will be used to match against the courses of the category
151
        if ($user_courses != '') {
152
            foreach ($user_courses as $value) {
153
                $user_coursecodes[] = $value['code'];
154
            }
155
        }
156
157
        $data['user_coursecodes'] = $user_coursecodes;
158
        $data['message'] = $message;
159
        $data['content'] = $content;
160
        $data['error'] = $error;
161
        $data['action'] = 'display_courses';
162
163
        // render to the view
164
        $this->view->set_data($data);
165
        $this->view->set_layout('catalog_layout');
166
        $this->view->set_template('courses_categories');
167
        $this->view->render();
168
    }
169
170
    /**
171
     * Unsubscribe user from a course
172
     * render to listing view.
173
     *
174
     * @param string $course_code
175
     * @param string $search_term
176
     * @param string $category_code
177
     */
178
    public function unsubscribe_user_from_course(
179
        $course_code,
180
        $search_term = null,
181
        $category_code = null
182
    ) {
183
        $result = $this->model->remove_user_from_course($course_code);
184
        $message = '';
185
        $error = '';
186
187
        if ($result) {
188
            Display::addFlash(
189
                Display::return_message(get_lang('YouAreNowUnsubscribed'))
190
            );
191
        }
192
193
        if (!empty($search_term)) {
194
            CoursesAndSessionsCatalog::search_courses($search_term, $message, $error);
195
        } else {
196
            $this->courses_categories(
197
                'subcribe',
198
                $category_code,
199
                $message,
200
                $error
201
            );
202
        }
203
    }
204
205
    /**
206
     * Get a HTML button for subscribe to session.
207
     *
208
     * @param int    $sessionId         The session ID
209
     * @param string $sessionName       The session name
210
     * @param bool   $checkRequirements Optional.
211
     *                                  Whether the session has requirement. Default is false
212
     * @param bool   $includeText       Optional. Whether show the text in button
213
     * @param bool   $btnBing
214
     *
215
     * @return string The button HTML
216
     */
217
    public function getRegisteredInSessionButton(
218
        $sessionId,
219
        $sessionName,
220
        $checkRequirements = false,
221
        $includeText = false,
222
        $btnBing = false
223
    ) {
224
        $sessionId = (int) $sessionId;
225
        if ($btnBing) {
226
            $btnBing = 'btn-lg btn-block';
227
        } else {
228
            $btnBing = 'btn-sm';
229
        }
230
        if ($checkRequirements) {
231
            $url = api_get_path(WEB_AJAX_PATH);
232
            $url .= 'sequence.ajax.php?';
233
            $url .= http_build_query([
234
                'a' => 'get_requirements',
235
                'id' => $sessionId,
236
                'type' => SequenceResource::SESSION_TYPE,
237
            ]);
238
239
            return Display::toolbarButton(
240
                get_lang('CheckRequirements'),
241
                $url,
242
                'shield',
243
                'info',
244
                [
245
                    'class' => $btnBing.' ajax',
246
                    'data-title' => get_lang('CheckRequirements'),
247
                    'data-size' => 'md',
248
                    'title' => get_lang('CheckRequirements'),
249
                ],
250
                $includeText
251
            );
252
        }
253
254
        $catalogSessionAutoSubscriptionAllowed = false;
255
        if (api_get_setting('catalog_allow_session_auto_subscription') === 'true') {
256
            $catalogSessionAutoSubscriptionAllowed = true;
257
        }
258
259
        $url = api_get_path(WEB_CODE_PATH);
260
261
        if ($catalogSessionAutoSubscriptionAllowed) {
262
            $url .= 'auth/courses.php?';
263
            $url .= http_build_query([
264
                'action' => 'subscribe_to_session',
265
                'session_id' => $sessionId,
266
            ]);
267
268
            $result = Display::toolbarButton(
269
                get_lang('Subscribe'),
270
                $url,
271
                'pencil',
272
                'primary',
273
                [
274
                    'class' => $btnBing.' ajax',
275
                    'data-title' => get_lang('AreYouSureToSubscribe'),
276
                    'data-size' => 'md',
277
                    'title' => get_lang('Subscribe'),
278
                ],
279
                $includeText
280
            );
281
        } else {
282
            $url .= 'inc/email_editor.php?';
283
            $url .= http_build_query([
284
                'action' => 'subscribe_me_to_session',
285
                'session' => Security::remove_XSS($sessionName),
286
            ]);
287
288
            $result = Display::toolbarButton(
289
                get_lang('SubscribeToSessionRequest'),
290
                $url,
291
                'pencil',
292
                'primary',
293
                ['class' => $btnBing],
294
                $includeText
295
            );
296
        }
297
298
        $hook = HookResubscribe::create();
299
        if (!empty($hook)) {
300
            $hook->setEventData([
301
                'session_id' => $sessionId,
302
            ]);
303
            try {
304
                $hook->notifyResubscribe(HOOK_EVENT_TYPE_PRE);
305
            } catch (Exception $exception) {
306
                $result = $exception->getMessage();
307
            }
308
        }
309
310
        return $result;
311
    }
312
313
    /**
314
     * Generate a label if the user has been  registered in session.
315
     *
316
     * @return string The label
317
     */
318
    public function getAlreadyRegisteredInSessionLabel()
319
    {
320
        $icon = '<em class="fa fa-graduation-cap"></em>';
321
322
        return Display::div(
323
            $icon,
324
            [
325
                'class' => 'btn btn-default btn-sm registered',
326
                'title' => get_lang("AlreadyRegisteredToSession"),
327
            ]
328
        );
329
    }
330
331
    /**
332
     * Get a icon for a session.
333
     *
334
     * @param string $sessionName The session name
335
     *
336
     * @return string The icon
337
     */
338
    public function getSessionIcon($sessionName)
339
    {
340
        return Display::return_icon(
341
            'window_list.png',
342
            $sessionName,
343
            null,
344
            ICON_SIZE_MEDIUM
345
        );
346
    }
347
348
    /**
349
     * Return Session catalog rendered view.
350
     *
351
     * @param string $action
352
     * @param string $nameTools
353
     * @param array  $limit
354
     */
355
    public function sessionList($action, $nameTools, $limit = [])
356
    {
357
        $date = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
358
        $hiddenLinks = isset($_GET['hidden_links']) ? $_GET['hidden_links'] == 1 : false;
359
        $limit = isset($limit) ? $limit : self::getLimitArray();
360
361
        $countSessions = CoursesAndSessionsCatalog::browseSessions($date, [], false, true);
362
        $sessions = CoursesAndSessionsCatalog::browseSessions($date, $limit);
363
364
        $pageTotal = ceil($countSessions / $limit['length']);
365
        // Do NOT show pagination if only one page or less
366
        $pagination = $pageTotal > 1 ? CourseCategory::getCatalogPagination($limit['current'], $limit['length'], $pageTotal) : '';
367
        $sessionsBlocks = $this->getFormattedSessionsBlock($sessions);
368
369
        // Get session search catalogue URL
370
        $courseUrl = CourseCategory::getCourseCategoryUrl(
371
            1,
372
            $limit['length'],
373
            null,
374
            0,
375
            'subscribe'
376
        );
377
378
        $tpl = new Template();
379
        $tpl->assign('show_courses', CoursesAndSessionsCatalog::showCourses());
380
        $tpl->assign('show_sessions', CoursesAndSessionsCatalog::showSessions());
381
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true');
382
        $tpl->assign('course_url', $courseUrl);
383
        $tpl->assign('catalog_pagination', $pagination);
384
        $tpl->assign('hidden_links', $hiddenLinks);
385
        $tpl->assign('search_token', Security::get_token());
386
        $tpl->assign('search_date', $date);
387
        $tpl->assign('web_session_courses_ajax_url', api_get_path(WEB_AJAX_PATH).'course.ajax.php');
388
        $tpl->assign('sessions', $sessionsBlocks);
389
        $tpl->assign('already_subscribed_label', $this->getAlreadyRegisteredInSessionLabel());
390
391
        $layout = $tpl->get_template('auth/session_catalog.html.twig');
392
        $content = $tpl->fetch($layout);
393
        $tpl->assign('content', $content);
394
        $tpl->display_one_col_template();
395
    }
396
397
    /**
398
     * Show the Session Catalogue with filtered session by course tags.
399
     *
400
     * @param array $limit Limit info
401
     */
402
    public function sessionsListByCoursesTag(array $limit)
403
    {
404
        $searchTag = isset($_POST['search_tag']) ? $_POST['search_tag'] : null;
405
        $searchDate = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
406
        $hiddenLinks = isset($_GET['hidden_links']) ? intval($_GET['hidden_links']) == 1 : false;
407
        $courseUrl = CourseCategory::getCourseCategoryUrl(
408
            1,
409
            $limit['length'],
410
            null,
411
            0,
412
            'subscribe'
413
        );
414
415
        $sessions = CoursesAndSessionsCatalog::browseSessionsByTags($searchTag, $limit);
416
        $sessionsBlocks = $this->getFormattedSessionsBlock($sessions);
417
418
        $tpl = new Template();
419
        $tpl->assign('show_courses', CoursesAndSessionsCatalog::showCourses());
420
        $tpl->assign('show_sessions', CoursesAndSessionsCatalog::showSessions());
421
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true' ? true : false);
422
        $tpl->assign('course_url', $courseUrl);
423
        $tpl->assign('already_subscribed_label', $this->getAlreadyRegisteredInSessionLabel());
424
        $tpl->assign('hidden_links', $hiddenLinks);
425
        $tpl->assign('search_token', Security::get_token());
426
        $tpl->assign('search_date', Security::remove_XSS($searchDate));
427
        $tpl->assign('search_tag', Security::remove_XSS($searchTag));
428
        $tpl->assign('sessions', $sessionsBlocks);
429
430
        $contentTemplate = $tpl->get_template('auth/session_catalog.tpl');
431
432
        $tpl->display($contentTemplate);
433
    }
434
435
    /**
436
     * @return array
437
     */
438
    public static function getLimitArray()
439
    {
440
        $pageCurrent = isset($_REQUEST['pageCurrent']) ? (int) $_GET['pageCurrent'] : 1;
441
        $pageLength = isset($_REQUEST['pageLength']) ? (int) $_GET['pageLength'] : CoursesAndSessionsCatalog::PAGE_LENGTH;
442
443
        return [
444
            'start' => ($pageCurrent - 1) * $pageLength,
445
            'current' => $pageCurrent,
446
            'length' => $pageLength,
447
        ];
448
    }
449
450
    /**
451
     * Get the formatted data for sessions block to be displayed on Session Catalog page.
452
     *
453
     * @param array $sessions The session list
454
     *
455
     * @return array
456
     */
457
    private function getFormattedSessionsBlock(array $sessions)
458
    {
459
        $extraFieldValue = new ExtraFieldValue('session');
460
        $userId = api_get_user_id();
461
        $sessionsBlocks = [];
462
        $entityManager = Database::getManager();
463
        $sessionRelCourseRepo = $entityManager->getRepository('ChamiloCoreBundle:SessionRelCourse');
464
        $extraFieldRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraField');
465
        $extraFieldRelTagRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
466
467
        $tagsField = $extraFieldRepo->findOneBy([
468
            'extraFieldType' => Chamilo\CoreBundle\Entity\ExtraField::COURSE_FIELD_TYPE,
469
            'variable' => 'tags',
470
        ]);
471
472
        /** @var \Chamilo\CoreBundle\Entity\Session $session */
473
        foreach ($sessions as $session) {
474
            $sessionDates = SessionManager::parseSessionDates([
475
                'display_start_date' => $session->getDisplayStartDate(),
476
                'display_end_date' => $session->getDisplayEndDate(),
477
                'access_start_date' => $session->getAccessStartDate(),
478
                'access_end_date' => $session->getAccessEndDate(),
479
                'coach_access_start_date' => $session->getCoachAccessStartDate(),
480
                'coach_access_end_date' => $session->getCoachAccessEndDate(),
481
            ]);
482
483
            $imageField = $extraFieldValue->get_values_by_handler_and_field_variable(
484
                $session->getId(),
485
                'image'
486
            );
487
            $sessionCourseTags = [];
488
            if (!is_null($tagsField)) {
489
                $sessionRelCourses = $sessionRelCourseRepo->findBy([
490
                    'session' => $session,
491
                ]);
492
                /** @var SessionRelCourse $sessionRelCourse */
493
                foreach ($sessionRelCourses as $sessionRelCourse) {
494
                    $courseTags = $extraFieldRelTagRepo->getTags(
495
                        $tagsField,
496
                        $sessionRelCourse->getCourse()->getId()
497
                    );
498
                    /** @var Tag $tag */
499
                    foreach ($courseTags as $tag) {
500
                        $sessionCourseTags[] = $tag->getTag();
501
                    }
502
                }
503
            }
504
505
            if (!empty($sessionCourseTags)) {
506
                $sessionCourseTags = array_unique($sessionCourseTags);
507
            }
508
509
            /** @var SequenceRepository $repo */
510
            $repo = $entityManager->getRepository('ChamiloCoreBundle:SequenceResource');
511
            $sequences = $repo->getRequirementsAndDependenciesWithinSequences(
512
                $session->getId(),
513
                SequenceResource::SESSION_TYPE
514
            );
515
516
            $hasRequirements = false;
517
            foreach ($sequences['sequences'] as $sequence) {
518
                if (count($sequence['requirements']) === 0) {
519
                    continue;
520
                }
521
                $hasRequirements = true;
522
                break;
523
            }
524
            $cat = $session->getCategory();
525
            if (empty($cat)) {
526
                $cat = null;
527
                $catName = '';
528
            } else {
529
                $catName = $cat->getName();
530
            }
531
532
            $generalCoach = $session->getGeneralCoach();
533
            $coachId = $generalCoach ? $generalCoach->getId() : 0;
534
            $coachName = $generalCoach ? UserManager::formatUserFullName($session->getGeneralCoach()) : '';
535
536
            $actions = null;
537
            if (api_is_platform_admin()) {
538
                $actions = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session->getId();
539
            }
540
541
            $plugin = \BuyCoursesPlugin::create();
542
            $isThisSessionOnSale = $plugin->getBuyCoursePluginPrice($session);
543
544
            $sessionsBlock = [
545
                'id' => $session->getId(),
546
                'name' => $session->getName(),
547
                'image' => isset($imageField['value']) ? $imageField['value'] : null,
548
                'nbr_courses' => $session->getNbrCourses(),
549
                'nbr_users' => $session->getNbrUsers(),
550
                'coach_id' => $coachId,
551
                'coach_url' => $generalCoach
552
                    ? api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_popup&user_id='.$coachId
553
                    : '',
554
                'coach_name' => $coachName,
555
                'coach_avatar' => UserManager::getUserPicture(
556
                    $coachId,
557
                    USER_IMAGE_SIZE_SMALL
558
                ),
559
                'is_subscribed' => SessionManager::isUserSubscribedAsStudent(
560
                    $session->getId(),
561
                    $userId
562
                ),
563
                'icon' => $this->getSessionIcon($session->getName()),
564
                'date' => $sessionDates['display'],
565
                'price' => !empty($isThisSessionOnSale['html']) ? $isThisSessionOnSale['html'] : '',
566
                'subscribe_button' => isset($isThisSessionOnSale['buy_button']) ? $isThisSessionOnSale['buy_button'] : $this->getRegisteredInSessionButton(
567
                    $session->getId(),
568
                    $session->getName(),
569
                    $hasRequirements
570
                ),
571
                'show_description' => $session->getShowDescription(),
572
                'description' => $session->getDescription(),
573
                'category' => $catName,
574
                'tags' => $sessionCourseTags,
575
                'edit_actions' => $actions,
576
                'duration' => SessionManager::getDayLeftInSession(
577
                    ['id' => $session->getId(), 'duration' => $session->getDuration()],
578
                    $userId
579
                ),
580
            ];
581
582
            $sessionsBlock = array_merge($sessionsBlock, $sequences);
583
            $sessionsBlocks[] = $sessionsBlock;
584
        }
585
586
        return $sessionsBlocks;
587
    }
588
}
589