Passed
Push — 1.11.x ( 0dd652...0c2073 )
by Angel Fernando Quiroz
11:42 queued 14s
created

H5pImportPlugin::addCourseTools()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 8
rs 10
cc 2
nc 2
nop 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\PluginBundle\Entity\H5pImport\H5pImport;
5
use Chamilo\PluginBundle\Entity\H5pImport\H5pImportLibrary;
6
use Chamilo\PluginBundle\Entity\H5pImport\H5pImportResults;
7
use Doctrine\ORM\Tools\SchemaTool;
8
use Doctrine\ORM\Tools\ToolsException;
9
use Symfony\Component\Filesystem\Filesystem;
10
11
/**
12
 * Define the H5pImportPlugin class as an extension of Plugin
13
 * install/uninstall the plugin.
14
 */
15
class H5pImportPlugin extends Plugin implements HookPluginInterface
16
{
17
    public const TBL_H5P_IMPORT = 'plugin_h5p_import';
18
    public const TBL_H5P_IMPORT_LIBRARY = 'plugin_h5p_import_library';
19
    public const TBL_H5P_IMPORT_RESULTS = 'plugin_h5p_import_results';
20
21
    protected function __construct()
22
    {
23
        $settings = [
24
            'tool_enable' => 'boolean',
25
            'frame' => 'boolean',
26
            'embed' => 'boolean',
27
            'copyright' => 'boolean',
28
            'icon' => 'boolean',
29
        ];
30
31
        parent::__construct(
32
            '0.1',
33
            'Borja Sanchez',
34
            $settings
35
        );
36
    }
37
38
    public static function create(): ?H5pImportPlugin
39
    {
40
        static $result = null;
41
42
        return $result ? $result : $result = new self();
43
    }
44
45
    /**
46
     * Updates and returns the total duration in the view of an H5P learning path item in a course.
47
     *
48
     * @param int $lpItemId The ID of the learning path item
49
     * @param int $userId   The user ID
50
     *
51
     * @return int The updated total duration in the learning path item view
52
     */
53
    public static function fixTotalTimeInLpItemView(
54
        int $lpItemId,
55
        int $userId
56
    ): int {
57
        $lpItemViewTable = Database::get_course_table(TABLE_LP_ITEM_VIEW);
58
59
        $sql = "SELECT iid, score
60
            FROM $lpItemViewTable
61
            WHERE
62
                iid = $lpItemId
63
            ORDER BY view_count DESC
64
            LIMIT 1";
65
        $responseItemView = Database::query($sql);
66
        $lpItemView = Database::fetch_array($responseItemView);
67
68
        // Get the total execution duration of the user in the learning path item view
69
        $sql = 'SELECT SUM(total_time) AS exe_duration
70
            FROM plugin_h5p_import_results
71
            WHERE
72
                user_id = '.$userId.' AND
73
                c_lp_item_view_id = '.$lpItemView['iid'].
74
            ' ORDER BY total_time DESC';
75
        $sumScoreResult = Database::query($sql);
76
        $durationRow = Database::fetch_array($sumScoreResult, 'ASSOC');
77
78
        if (!empty($durationRow['exe_duration'])) {
79
            // Update the total duration in the learning path item view
80
            $sqlUpdate = 'UPDATE '.$lpItemViewTable.'
81
                SET total_time = '.$durationRow['exe_duration'].'
82
                WHERE iid = '.$lpItemView['iid'];
83
            Database::query($sqlUpdate);
84
85
            return (int) $durationRow['exe_duration'];
86
        } else {
87
            // Update c_lp_item_view status
88
            $sqlUpdate = 'UPDATE '.$lpItemViewTable.'
89
                SET status = "not attempted",
90
                total_time = 0
91
                WHERE iid = '.$lpItemView['iid'];
92
            Database::query($sqlUpdate);
93
94
            return 0;
95
        }
96
    }
97
98
    public function getToolTitle(): string
99
    {
100
        $title = $this->get_lang('plugin_title');
101
102
        if (!empty($title)) {
103
            return $title;
104
        }
105
106
        return $this->get_title();
107
    }
108
109
    /**
110
     * @throws ToolsException
111
     */
112
    public function install()
113
    {
114
        $em = Database::getManager();
115
        if ($em->getConnection()
116
            ->getSchemaManager()
117
            ->tablesExist(
118
                [
119
                    self::TBL_H5P_IMPORT,
120
                    self::TBL_H5P_IMPORT_LIBRARY,
121
                    self::TBL_H5P_IMPORT_RESULTS,
122
                ]
123
            )
124
        ) {
125
            return;
126
        }
127
128
        $schemaTool = new SchemaTool($em);
129
        $schemaTool->createSchema(
130
            [
131
                $em->getClassMetadata(H5pImport::class),
132
                $em->getClassMetadata(H5pImportLibrary::class),
133
                $em->getClassMetadata(H5pImportResults::class),
134
            ]
135
        );
136
        $this->addCourseTools();
137
        $this->installHook();
138
    }
139
140
    public function addCourseTool(int $courseId)
141
    {
142
        // The $link param is set to "../plugin" as a hack to link correctly to the plugin URL in course tool.
143
        // Otherwise, the link en the course tool will link to "/main/" URL.
144
        $this->createLinkToCourseTool(
145
            $this->get_lang('plugin_title'),
146
            $courseId,
147
            'plugin_h5p_import.png',
148
            '../plugin/h5pimport/start.php',
149
            0,
150
            'authoring'
151
        );
152
    }
153
154
    public function uninstall()
155
    {
156
        $this->uninstallHook();
157
158
        $em = Database::getManager();
159
160
        if (!$em->getConnection()
161
            ->getSchemaManager()
162
            ->tablesExist(
163
                [
164
                    self::TBL_H5P_IMPORT,
165
                    self::TBL_H5P_IMPORT_LIBRARY,
166
                    self::TBL_H5P_IMPORT_RESULTS,
167
                ]
168
            )
169
        ) {
170
            return;
171
        }
172
173
        $schemaTool = new SchemaTool($em);
174
        $schemaTool->dropSchema(
175
            [
176
                $em->getClassMetadata(H5pImport::class),
177
                $em->getClassMetadata(H5pImportLibrary::class),
178
                $em->getClassMetadata(H5pImportResults::class),
179
            ]
180
        );
181
        $this->deleteCourseToolLinks();
182
        $this->removeH5pDirectories();
183
    }
184
185
    /**
186
     * Perform actions after configuring the H5P import plugin.
187
     *
188
     * @return H5pImportPlugin The H5P import plugin instance.
189
     */
190
    public function performActionsAfterConfigure(): H5pImportPlugin
191
    {
192
        $this->deleteCourseToolLinks();
193
194
        if ('true' === $this->get('tool_enable')) {
195
            $this->addCourseTools();
196
        }
197
198
        return $this;
199
    }
200
201
    /**
202
     * Get the view URL for an H5P import.
203
     *
204
     * @param H5pImport $h5pImport The H5P import object.
205
     *
206
     * @return string The view URL for the H5P import.
207
     */
208
    public function getViewUrl(H5pImport $h5pImport): string
209
    {
210
        return api_get_path(WEB_PLUGIN_PATH).'h5pimport/view.php?id='.$h5pImport->getIid().'&'.api_get_cidreq();
211
    }
212
213
    /**
214
     * Generates the LP resource block for H5P imports.
215
     *
216
     * @param int $lpId The LP ID.
217
     *
218
     * @return string The HTML for the LP resource block.
219
     */
220
    public function getLpResourceBlock(int $lpId): string
221
    {
222
        $cidReq = api_get_cidreq(true, true, 'lp');
223
        $webPath = api_get_path(WEB_PLUGIN_PATH).'h5pimport/';
224
        $course = api_get_course_entity();
225
        $session = api_get_session_entity();
226
227
        $tools = Database::getManager()
228
            ->getRepository(H5pImport::class)
229
            ->findBy(['course' => $course, 'session' => $session]);
230
231
        $importIcon = Display::return_icon('plugin_h5p_import_upload.png');
232
        $moveIcon = Display::url(
233
            Display::return_icon('move_everywhere.png', get_lang('Move'), [], ICON_SIZE_TINY),
234
            '#',
235
            ['class' => 'moved']
236
        );
237
238
        $return = '<ul class="lp_resource">';
239
        $return .= '<li class="lp_resource_element">';
240
        $return .= $importIcon;
241
        $return .= Display::url(
242
            get_lang('Import'),
243
            $webPath."start.php?action=add&$cidReq&".http_build_query(['lp_id' => $lpId])
244
        );
245
        $return .= '</li>';
246
247
        /** @var H5pImport $tool */
248
        foreach ($tools as $tool) {
249
            $toolAnchor = Display::url(
250
                Security::remove_XSS($tool->getName()),
251
                api_get_self()."?$cidReq&"
252
                .http_build_query(
253
                    ['action' => 'add_item', 'type' => TOOL_H5P, 'file' => $tool->getIid(), 'lp_id' => $lpId]
254
                ),
255
                ['class' => 'moved']
256
            );
257
258
            $return .= Display::tag(
259
                'li',
260
                $moveIcon.$importIcon.$toolAnchor,
261
                [
262
                    'class' => 'lp_resource_element',
263
                    'data_id' => $tool->getIid(),
264
                    'data_type' => TOOL_H5P,
265
                    'title' => $tool->getName(),
266
                ]
267
            );
268
        }
269
270
        $return .= '</ul>';
271
272
        return $return;
273
    }
274
275
    /**
276
     * Add course tools for all courses.
277
     */
278
    private function addCourseTools(): void
279
    {
280
        $courses = Database::getManager()
281
            ->createQuery('SELECT c.id FROM ChamiloCoreBundle:Course c')
282
            ->getResult();
283
284
        foreach ($courses as $course) {
285
            $this->addCourseTool($course['id']);
286
        }
287
    }
288
289
    private function deleteCourseToolLinks()
290
    {
291
        Database::getManager()
292
            ->createQuery('DELETE FROM ChamiloCourseBundle:CTool t WHERE t.category = :category AND t.link LIKE :link')
293
            ->execute(['category' => 'authoring', 'link' => '../plugin/h5pimport/start.php%']);
294
    }
295
296
    /**
297
     * Removes H5P directories for all courses.
298
     */
299
    private function removeH5pDirectories(): void
300
    {
301
        $fs = new Filesystem();
302
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
303
        $sql = "SELECT id FROM $table ORDER BY id";
304
        $res = Database::query($sql);
305
        while ($row = Database::fetch_assoc($res)) {
306
            $courseInfo = api_get_course_info_by_id($row['id']);
307
            $fs->remove($courseInfo['course_sys_path'].'/h5p');
308
        }
309
    }
310
311
    public function installHook()
312
    {
313
        HookCreateCourse::create()->attach(
314
            H5pImportCreateCourseHookObserver::create()
315
        );
316
    }
317
318
    public function uninstallHook()
319
    {
320
        HookCreateCourse::create()->detach(
321
            H5pImportCreateCourseHookObserver::create()
322
        );
323
    }
324
}
325