Passed
Pull Request — 1.11.x (#4441)
by Angel Fernando Quiroz
08:17
created

XApiPlugin::create()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 5
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\PluginBundle\Entity\XApi\ActivityProfile;
6
use Chamilo\PluginBundle\Entity\XApi\ActivityState;
7
use Chamilo\PluginBundle\Entity\XApi\Cmi5Item;
8
use Chamilo\PluginBundle\Entity\XApi\InternalLog;
9
use Chamilo\PluginBundle\Entity\XApi\LrsAuth;
10
use Chamilo\PluginBundle\Entity\XApi\SharedStatement;
11
use Chamilo\PluginBundle\Entity\XApi\ToolLaunch;
12
use Doctrine\ORM\EntityManager;
13
use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
14
use Doctrine\ORM\ORMException;
15
use Doctrine\ORM\Tools\SchemaTool;
16
use GuzzleHttp\RequestOptions;
17
use Http\Adapter\Guzzle6\Client;
18
use Http\Message\MessageFactory\GuzzleMessageFactory;
19
use Ramsey\Uuid\Uuid;
20
use Xabbuh\XApi\Client\Api\StatementsApiClientInterface;
21
use Xabbuh\XApi\Client\XApiClientBuilder;
22
use Xabbuh\XApi\Model\Agent;
23
use Xabbuh\XApi\Model\IRI;
24
use Xabbuh\XApi\Serializer\Symfony\Serializer;
25
26
/**
27
 * Class XApiPlugin.
28
 */
29
class XApiPlugin extends Plugin implements HookPluginInterface
30
{
31
    public const SETTING_LRS_URL = 'lrs_url';
32
    public const SETTING_LRS_AUTH_USERNAME = 'lrs_auth_username';
33
    public const SETTING_LRS_AUTH_PASSWORD = 'lrs_auth_password';
34
    public const SETTING_CRON_LRS_URL = 'cron_lrs_url';
35
    public const SETTING_CRON_LRS_AUTH_USERNAME = 'cron_lrs_auth_username';
36
    public const SETTING_CRON_LRS_AUTH_PASSWORD = 'cron_lrs_auth_password';
37
    public const SETTING_UUID_NAMESPACE = 'uuid_namespace';
38
    public const SETTING_LRS_LP_ITEM_ACTIVE = 'lrs_lp_item_viewed_active';
39
    public const SETTING_LRS_LP_ACTIVE = 'lrs_lp_end_active';
40
    public const SETTING_LRS_QUIZ_ACTIVE = 'lrs_quiz_active';
41
    public const SETTING_LRS_QUIZ_QUESTION_ACTIVE = 'lrs_quiz_question_active';
42
    public const SETTING_LRS_PORTFOLIO_ACTIVE = 'lrs_portfolio_active';
43
44
    public const STATE_FIRST_LAUNCH = 'first_launch';
45
    public const STATE_LAST_LAUNCH = 'last_launch';
46
47
    /**
48
     * XApiPlugin constructor.
49
     */
50
    protected function __construct()
51
    {
52
        $version = '0.3 (beta)';
53
        $author = [
54
            'Angel Fernando Quiroz Campos <[email protected]>',
55
        ];
56
        $settings = [
57
            self::SETTING_UUID_NAMESPACE => 'text',
58
59
            self::SETTING_LRS_URL => 'text',
60
            self::SETTING_LRS_AUTH_USERNAME => 'text',
61
            self::SETTING_LRS_AUTH_PASSWORD => 'text',
62
63
            self::SETTING_CRON_LRS_URL => 'text',
64
            self::SETTING_CRON_LRS_AUTH_USERNAME => 'text',
65
            self::SETTING_CRON_LRS_AUTH_PASSWORD => 'text',
66
67
            self::SETTING_LRS_LP_ITEM_ACTIVE => 'boolean',
68
            self::SETTING_LRS_LP_ACTIVE => 'boolean',
69
            self::SETTING_LRS_QUIZ_ACTIVE => 'boolean',
70
            self::SETTING_LRS_QUIZ_QUESTION_ACTIVE => 'boolean',
71
            self::SETTING_LRS_PORTFOLIO_ACTIVE => 'boolean',
72
        ];
73
74
        parent::__construct(
75
            $version,
76
            implode(', ', $author),
77
            $settings
78
        );
79
    }
80
81
    /**
82
     * @return \XApiPlugin
83
     */
84
    public static function create()
85
    {
86
        static $result = null;
87
88
        return $result ? $result : $result = new self();
89
    }
90
91
    /**
92
     * Process to install plugin.
93
     */
94
    public function install()
95
    {
96
        $em = Database::getManager();
97
98
        $tablesExists = $em->getConnection()->getSchemaManager()->tablesExist(
99
            [
100
                'xapi_shared_statement',
101
                'xapi_tool_launch',
102
                'xapi_lrs_auth',
103
                'xapi_cmi5_item',
104
                'xapi_activity_state',
105
                'xapi_activity_profile',
106
                'xapi_internal_log',
107
108
                'xapi_attachment',
109
                'xapi_object',
110
                'xapi_result',
111
                'xapi_verb',
112
                'xapi_extensions',
113
                'xapi_context',
114
                'xapi_actor',
115
                'xapi_statement',
116
            ]
117
        );
118
119
        if ($tablesExists) {
120
            return;
121
        }
122
123
        $this->installPluginDbTables();
124
        $this->installInitialConfig();
125
        $this->addCourseTools();
126
        $this->installHook();
127
    }
128
129
    /**
130
     * Process to uninstall plugin.
131
     */
132
    public function uninstall()
133
    {
134
        $this->uninstallHook();
135
        $this->uninstallPluginDbTables();
136
        $this->deleteCourseTools();
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142
    public function uninstallHook()
143
    {
144
        $learningPathItemViewedHook = XApiLearningPathItemViewedHookObserver::create();
145
        $learningPathEndHook = XApiLearningPathEndHookObserver::create();
146
        $quizQuestionAnsweredHook = XApiQuizQuestionAnsweredHookObserver::create();
147
        $quizEndHook = XApiQuizEndHookObserver::create();
148
        $createCourseHook = XApiCreateCourseHookObserver::create();
149
        $portfolioItemAddedHook = XApiPortfolioItemAddedHookObserver::create();
150
        $portfolioItemCommentedHook = XApiPortfolioItemCommentedHookObserver::create();
151
152
        HookLearningPathItemViewed::create()->detach($learningPathItemViewedHook);
153
        HookLearningPathEnd::create()->detach($learningPathEndHook);
154
        HookQuizQuestionAnswered::create()->detach($quizQuestionAnsweredHook);
155
        HookQuizEnd::create()->detach($quizEndHook);
156
        HookCreateCourse::create()->detach($createCourseHook);
157
        HookPortfolioItemAdded::create()->detach($portfolioItemAddedHook);
158
        HookPortfolioItemCommented::create()->detach($portfolioItemCommentedHook);
159
160
        return 1;
161
    }
162
163
    public function uninstallPluginDbTables()
164
    {
165
        $em = Database::getManager();
166
        $pluginEm = self::getEntityManager();
167
168
        $schemaTool = new SchemaTool($em);
169
        $schemaTool->dropSchema(
170
            [
171
                $em->getClassMetadata(ActivityProfile::class),
172
                $em->getClassMetadata(ActivityState::class),
173
                $em->getClassMetadata(SharedStatement::class),
174
                $em->getClassMetadata(ToolLaunch::class),
175
                $em->getClassMetadata(LrsAuth::class),
176
                $em->getClassMetadata(Cmi5Item::class),
177
                $em->getClassMetadata(InternalLog::class),
178
            ]
179
        );
180
181
        $pluginSchemaTool = new SchemaTool($pluginEm);
182
        $pluginSchemaTool->dropSchema(
183
            [
184
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Attachment::class),
185
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\StatementObject::class),
186
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Result::class),
187
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Verb::class),
188
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Extensions::class),
189
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Context::class),
190
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Actor::class),
191
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Statement::class),
192
            ]
193
        );
194
    }
195
196
    /**
197
     * @param string|null $lrsUrl
198
     * @param string|null $lrsAuthUsername
199
     * @param string|null $lrsAuthPassword
200
     *
201
     * @return \Xabbuh\XApi\Client\Api\StateApiClientInterface
202
     */
203
    public function getXApiStateClient($lrsUrl = null, $lrsAuthUsername = null, $lrsAuthPassword = null)
204
    {
205
        return $this
206
            ->createXApiClient($lrsUrl, $lrsAuthUsername, $lrsAuthPassword)
207
            ->getStateApiClient();
208
    }
209
210
    public function getXApiStatementClient(): StatementsApiClientInterface
211
    {
212
        return $this->createXApiClient()->getStatementsApiClient();
213
    }
214
215
    public function getXapiStatementCronClient(): StatementsApiClientInterface
216
    {
217
        $lrsUrl = $this->get(self::SETTING_CRON_LRS_URL);
218
        $lrsUsername = $this->get(self::SETTING_CRON_LRS_AUTH_USERNAME);
219
        $lrsPassword = $this->get(self::SETTING_CRON_LRS_AUTH_PASSWORD);
220
221
        return $this
222
            ->createXApiClient(
223
                empty($lrsUrl) ? null : $lrsUrl,
224
                empty($lrsUsername) ? null : $lrsUsername,
225
                empty($lrsPassword) ? null : $lrsPassword
226
            )
227
            ->getStatementsApiClient();
228
    }
229
230
    /**
231
     * Perform actions after save the plugin configuration.
232
     *
233
     * @return \XApiPlugin
234
     */
235
    public function performActionsAfterConfigure()
236
    {
237
        $learningPathItemViewedHook = XApiLearningPathItemViewedHookObserver::create();
238
        $learningPathEndHook = XApiLearningPathEndHookObserver::create();
239
        $quizQuestionAnsweredHook = XApiQuizQuestionAnsweredHookObserver::create();
240
        $quizEndHook = XApiQuizEndHookObserver::create();
241
        $portfolioItemAddedHook = XApiPortfolioItemAddedHookObserver::create();
242
        $portfolioItemCommentedHook = XApiPortfolioItemCommentedHookObserver::create();
243
        $portfolioItemViewedHook = XApiPortfolioItemViewedHookObserver::create();
244
245
        $learningPathItemViewedEvent = HookLearningPathItemViewed::create();
246
        $learningPathEndEvent = HookLearningPathEnd::create();
247
        $quizQuestionAnsweredEvent = HookQuizQuestionAnswered::create();
248
        $quizEndEvent = HookQuizEnd::create();
249
        $portfolioItemAddedEvent = HookPortfolioItemAdded::create();
250
        $portfolioItemCommentedEvent = HookPortfolioItemCommented::create();
251
        $portfolioItemViewedEvent = HookPortfolioItemViewed::create();
252
253
        if ('true' === $this->get(self::SETTING_LRS_LP_ITEM_ACTIVE)) {
254
            $learningPathItemViewedEvent->attach($learningPathItemViewedHook);
255
        } else {
256
            $learningPathItemViewedEvent->detach($learningPathItemViewedHook);
257
        }
258
259
        if ('true' === $this->get(self::SETTING_LRS_LP_ACTIVE)) {
260
            $learningPathEndEvent->attach($learningPathEndHook);
261
        } else {
262
            $learningPathEndEvent->detach($learningPathEndHook);
263
        }
264
265
        if ('true' === $this->get(self::SETTING_LRS_QUIZ_ACTIVE)) {
266
            $quizQuestionAnsweredEvent->attach($quizQuestionAnsweredHook);
267
        } else {
268
            $quizQuestionAnsweredEvent->detach($quizQuestionAnsweredHook);
269
        }
270
271
        if ('true' === $this->get(self::SETTING_LRS_QUIZ_QUESTION_ACTIVE)) {
272
            $quizEndEvent->attach($quizEndHook);
273
        } else {
274
            $quizEndEvent->detach($quizEndHook);
275
        }
276
277
        if ('true' === $this->get(self::SETTING_LRS_PORTFOLIO_ACTIVE)) {
278
            $portfolioItemAddedEvent->attach($portfolioItemAddedHook);
279
            $portfolioItemCommentedEvent->attach($portfolioItemCommentedHook);
280
            $portfolioItemViewedEvent->attach($portfolioItemViewedHook);
281
        } else {
282
            $portfolioItemAddedEvent->detach($portfolioItemAddedHook);
283
            $portfolioItemCommentedEvent->detach($portfolioItemCommentedHook);
284
            $portfolioItemViewedEvent->detach($portfolioItemViewedHook);
285
        }
286
287
        return $this;
288
    }
289
290
    /**
291
     * {@inheritdoc}
292
     */
293
    public function installHook()
294
    {
295
        $createCourseHook = XApiCreateCourseHookObserver::create();
296
297
        HookCreateCourse::create()->attach($createCourseHook);
298
    }
299
300
    /**
301
     * @param string $variable
302
     *
303
     * @return array
304
     */
305
    public function getLangMap($variable)
306
    {
307
        $platformLanguage = api_get_setting('platformLanguage');
308
        $platformLanguageIso = api_get_language_isocode($platformLanguage);
309
310
        $map = [];
311
        $map[$platformLanguageIso] = $this->getLangFromFile($variable, $platformLanguage);
312
313
        try {
314
            $interfaceLanguage = api_get_interface_language();
315
        } catch (Exception $e) {
316
            return $map;
317
        }
318
319
        if (!empty($interfaceLanguage) && $platformLanguage !== $interfaceLanguage) {
320
            $interfaceLanguageIso = api_get_language_isocode($interfaceLanguage);
321
322
            $map[$interfaceLanguageIso] = $this->getLangFromFile($variable, $interfaceLanguage);
323
        }
324
325
        return $map;
326
    }
327
328
    /**
329
     * @param string $value
330
     * @param string $type
331
     *
332
     * @return \Xabbuh\XApi\Model\IRI
333
     */
334
    public function generateIri($value, $type)
335
    {
336
        return IRI::fromString(
337
            api_get_path(WEB_PATH)."xapi/$type/$value"
338
        );
339
    }
340
341
    /**
342
     * @param int $courseId
343
     */
344
    public function addCourseToolForTinCan($courseId)
345
    {
346
        // The $link param is set to "../plugin" as a hack to link correctly to the plugin URL in course tool.
347
        // Otherwise, the link en the course tool will link to "/main/" URL.
348
        $this->createLinkToCourseTool(
349
            $this->get_lang('ToolTinCan'),
350
            $courseId,
351
            'sessions_category.png',
352
            '../plugin/xapi/start.php',
353
            0,
354
            'authoring'
355
        );
356
    }
357
358
    /**
359
     * @param string $language
360
     *
361
     * @return mixed|string
362
     */
363
    public static function extractVerbInLanguage(Xabbuh\XApi\Model\LanguageMap $languageMap, $language)
364
    {
365
        $iso = self::findLanguageIso($languageMap->languageTags(), $language);
366
367
        $text = current($languageMap);
368
369
        if (isset($languageMap[$iso])) {
370
            $text = trim($languageMap[$iso]);
371
        } elseif (isset($languageMap['und'])) {
372
            $text = $languageMap['und'];
373
        }
374
375
        return $text;
376
    }
377
378
    /**
379
     * @param string $needle
380
     *
381
     * @return string
382
     */
383
    public static function findLanguageIso(array $haystack, $needle)
384
    {
385
        if (in_array($needle, $haystack)) {
386
            return $needle;
387
        }
388
389
        foreach ($haystack as $language) {
390
            if (strpos($language, $needle) === 0) {
391
                return $language;
392
            }
393
        }
394
395
        return $haystack[0];
396
    }
397
398
    public function generateLaunchUrl(
399
        $type,
400
        $launchUrl,
401
        $activityId,
402
        Agent $actor,
403
        $attemptId,
404
        $customLrsUrl = null,
405
        $customLrsUsername = null,
406
        $customLrsPassword = null,
407
        $viewSessionId = null
408
    ) {
409
        $lrsUrl = $customLrsUrl ?: $this->get(self::SETTING_LRS_URL);
410
        $lrsAuthUsername = $customLrsUsername ?: $this->get(self::SETTING_LRS_AUTH_USERNAME);
411
        $lrsAuthPassword = $customLrsPassword ?: $this->get(self::SETTING_LRS_AUTH_PASSWORD);
412
413
        $queryData = [
414
            'endpoint' => trim($lrsUrl, "/ \t\n\r\0\x0B"),
415
            'actor' => Serializer::createSerializer()->serialize($actor, 'json'),
416
            'registration' => $attemptId,
417
        ];
418
419
        if ('tincan' === $type) {
420
            $queryData['auth'] = 'Basic '.base64_encode(trim($lrsAuthUsername).':'.trim($lrsAuthPassword));
421
            $queryData['activity_id'] = $activityId;
422
        } elseif ('cmi5' === $type) {
423
            $queryData['fetch'] = api_get_path(WEB_PLUGIN_PATH).'xapi/cmi5/token.php?session='.$viewSessionId;
424
            $queryData['activityId'] = $activityId;
425
        }
426
427
        return $launchUrl.'?'.http_build_query($queryData, null, '&', PHP_QUERY_RFC3986);
428
    }
429
430
    /**
431
     * @return \Doctrine\ORM\EntityManager|null
432
     */
433
    public static function getEntityManager()
434
    {
435
        $em = Database::getManager();
436
437
        $prefixes = [
438
            __DIR__.'/../php-xapi/repository-doctrine-orm/metadata' => 'XApi\Repository\Doctrine\Mapping',
439
        ];
440
441
        $driver = new SimplifiedXmlDriver($prefixes);
442
        $driver->setGlobalBasename('global');
443
444
        $config = Database::getDoctrineConfig(api_get_configuration_value('root_sys'));
445
        $config->setMetadataDriverImpl($driver);
446
447
        try {
448
            return EntityManager::create($em->getConnection()->getParams(), $config);
449
        } catch (ORMException $e) {
450
            api_not_allowed(true, $e->getMessage());
451
        }
452
453
        return null;
454
    }
455
456
    /**
457
     * {@inheritdoc}
458
     */
459
    public function getAdminUrl()
460
    {
461
        $webPath = api_get_path(WEB_PLUGIN_PATH).$this->get_name();
462
463
        return "$webPath/admin.php";
464
    }
465
466
    public function getLpResourceBlock(int $lpId)
467
    {
468
        $cidReq = api_get_cidreq(true, true, 'lp');
469
        $webPath = api_get_path(WEB_PLUGIN_PATH).'xapi/';
470
        $course = api_get_course_entity();
471
        $session = api_get_session_entity();
472
473
        $tools = Database::getManager()
474
            ->getRepository(ToolLaunch::class)
475
            ->findByCourseAndSession($course, $session);
476
477
        $importIcon = Display::return_icon('import_scorm.png');
478
        $moveIcon = Display::url(
479
            Display::return_icon('move_everywhere.png', get_lang('Move'), [], ICON_SIZE_TINY),
480
            '#',
481
            ['class' => 'moved']
482
        );
483
484
        $return = '<ul class="lp_resource"><li class="lp_resource_element">'
485
            .$importIcon
486
            .Display::url(
487
                get_lang('Import'),
488
                $webPath."tool_import.php?$cidReq&".http_build_query(['lp_id' => $lpId])
489
            )
490
            .'</li>';
491
492
        /** @var ToolLaunch $tool */
493
        foreach ($tools as $tool) {
494
            $toolAnchor = Display::url(
495
                Security::remove_XSS($tool->getTitle()),
496
                api_get_self()."?$cidReq&"
497
                    .http_build_query(
498
                        ['action' => 'add_item', 'type' => TOOL_XAPI, 'file' => $tool->getId(), 'lp_id' => $lpId]
499
                    ),
500
                ['class' => 'moved']
501
            );
502
503
            $return .= Display::tag(
504
                'li',
505
                $moveIcon.$importIcon.$toolAnchor,
506
                [
507
                    'class' => 'lp_resource_element',
508
                    'data_id' => $tool->getId(),
509
                    'data_type' => TOOL_XAPI,
510
                    'title' => $tool->getTitle(),
511
                ]
512
            );
513
        }
514
515
        $return .= '</ul>';
516
517
        return $return;
518
    }
519
520
    /**
521
     * @throws \Doctrine\ORM\Tools\ToolsException
522
     */
523
    private function installPluginDbTables()
524
    {
525
        $em = Database::getManager();
526
        $pluginEm = self::getEntityManager();
527
528
        $schemaTool = new SchemaTool($em);
529
        $schemaTool->createSchema(
530
            [
531
                $em->getClassMetadata(SharedStatement::class),
532
                $em->getClassMetadata(ToolLaunch::class),
533
                $em->getClassMetadata(LrsAuth::class),
534
                $em->getClassMetadata(Cmi5Item::class),
535
                $em->getClassMetadata(ActivityState::class),
536
                $em->getClassMetadata(ActivityProfile::class),
537
                $em->getClassMetadata(InternalLog::class),
538
            ]
539
        );
540
541
        $pluginSchemaTool = new SchemaTool($pluginEm);
542
        $pluginSchemaTool->createSchema(
543
            [
544
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Attachment::class),
545
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\StatementObject::class),
546
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Result::class),
547
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Verb::class),
548
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Extensions::class),
549
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Context::class),
550
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Actor::class),
551
                $pluginEm->getClassMetadata(\XApi\Repository\Doctrine\Mapping\Statement::class),
552
            ]
553
        );
554
    }
555
556
    /**
557
     * @throws \Exception
558
     */
559
    private function installInitialConfig()
560
    {
561
        $uuidNamespace = Uuid::uuid1();
562
563
        $pluginName = $this->get_name();
564
        $urlId = api_get_current_access_url_id();
565
566
        api_add_setting(
567
            $uuidNamespace,
568
            $pluginName.'_'.self::SETTING_UUID_NAMESPACE,
569
            $pluginName,
570
            'setting',
571
            'Plugins',
572
            $pluginName,
573
            '',
574
            '',
575
            '',
576
            $urlId,
577
            1
578
        );
579
580
        api_add_setting(
581
            api_get_path(WEB_PATH).'plugin/xapi/lrs.php',
582
            $pluginName.'_'.self::SETTING_LRS_URL,
583
            $pluginName,
584
            'setting',
585
            'Plugins',
586
            $pluginName,
587
            '',
588
            '',
589
            '',
590
            $urlId,
591
            1
592
        );
593
    }
594
595
    /**
596
     * @param string|null $lrsUrl
597
     * @param string|null $lrsAuthUsername
598
     * @param string|null $lrsAuthPassword
599
     *
600
     * @return \Xabbuh\XApi\Client\XApiClientInterface
601
     */
602
    private function createXApiClient($lrsUrl = null, $lrsAuthUsername = null, $lrsAuthPassword = null)
603
    {
604
        $baseUrl = $lrsUrl ?: $this->get(self::SETTING_LRS_URL);
605
        $lrsAuthUsername = $lrsAuthUsername ?: $this->get(self::SETTING_LRS_AUTH_USERNAME);
606
        $lrsAuthPassword = $lrsAuthPassword ?: $this->get(self::SETTING_LRS_AUTH_PASSWORD);
607
608
        $clientBuilder = new XApiClientBuilder();
609
        $clientBuilder
610
            ->setHttpClient(Client::createWithConfig([RequestOptions::VERIFY => false]))
611
            ->setRequestFactory(new GuzzleMessageFactory())
612
            ->setBaseUrl(trim($baseUrl, "/ \t\n\r\0\x0B"))
613
            ->setAuth(trim($lrsAuthUsername), trim($lrsAuthPassword));
614
615
        return $clientBuilder->build();
616
    }
617
618
    private function addCourseTools()
619
    {
620
        $courses = Database::getManager()
621
            ->createQuery('SELECT c.id FROM ChamiloCoreBundle:Course c')
622
            ->getResult();
623
624
        foreach ($courses as $course) {
625
            $this->addCourseToolForTinCan($course['id']);
626
        }
627
    }
628
629
    private function deleteCourseTools()
630
    {
631
        Database::getManager()
632
            ->createQuery('DELETE FROM ChamiloCourseBundle:CTool t WHERE t.category = :category AND t.link LIKE :link')
633
            ->execute(['category' => 'authoring', 'link' => '../plugin/xapi/start.php%']);
634
    }
635
}
636