Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Provides the class that defines the form for the H5P authoring tool.
19
 *
20
 * @package    contenttype_h5p
21
 * @copyright  2020 Victor Deniz <victor@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace contenttype_h5p\form;
26
 
27
use contenttype_h5p\content;
28
use contenttype_h5p\contenttype;
29
use core_contentbank\form\edit_content;
30
use core_h5p\api;
31
use core_h5p\editor as h5peditor;
32
use core_h5p\factory;
33
use core_h5p\helper;
34
use stdClass;
35
 
36
/**
37
 * Defines the form for editing an H5P content.
38
 *
39
 * @copyright 2020 Victor Deniz <victor@moodle.com>
40
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 */
42
class editor extends edit_content {
43
 
44
    /** @var $h5peditor H5P editor object */
45
    private $h5peditor;
46
 
47
    /** @var $content The content being edited */
48
    private $content;
49
 
50
    /**
51
     * Defines the form fields.
52
     */
53
    protected function definition() {
54
        global $DB, $OUTPUT;
55
 
56
        $mform = $this->_form;
57
        $errors = [];
58
        $notifications = [];
59
 
60
        // Id of the content to edit.
61
        $id = $this->_customdata['id'];
62
        // H5P content type to create.
63
        $library = optional_param('library', null, PARAM_TEXT);
64
 
65
        if (empty($id) && empty($library)) {
66
            $returnurl = new \moodle_url('/contentbank/index.php', ['contextid' => $this->_customdata['contextid']]);
67
            throw new \moodle_exception('invalidcontentid', 'error', $returnurl);
68
        }
69
 
70
        $this->h5peditor = new h5peditor();
71
 
72
        $this->set_display_vertical();
73
        $mform->addElement('html', $OUTPUT->heading($this->_customdata['heading'], 2));
74
 
75
        if ($id) {
76
            // The H5P editor needs the H5P content id (h5p table).
77
            $record = $DB->get_record('contentbank_content', ['id' => $id]);
78
            $this->content = new content($record);
79
            $file = $this->content->get_file();
80
 
81
            $h5p = api::get_content_from_pathnamehash($file->get_pathnamehash());
82
            if (!$h5p) {
83
                // H5P content has not been deployed yet. Let's check why.
84
                $factory = new \core_h5p\factory();
85
                $factory->get_framework()->set_file($file);
86
 
87
                $h5pid = helper::save_h5p($factory, $file, new stdClass());
88
                $errors = $factory->get_framework()->getMessages('error');
89
                $notifications = $factory->get_framework()->getMessages('info');
90
            } else {
91
                $h5pid = $h5p->id;
92
            }
93
            if ($h5pid) {
94
                $mform->addElement('hidden', 'h5pid', $h5pid);
95
                $mform->setType('h5pid', PARAM_INT);
96
                $this->h5peditor->set_content($h5pid);
97
            }
98
        } else {
99
            // The H5P editor needs the H5P content type library name for a new content.
100
            $mform->addElement('hidden', 'library', $library);
101
            $mform->setType('library', PARAM_TEXT);
102
            $this->h5peditor->set_library($library, $this->_customdata['contextid'], 'contentbank', 'public');
103
        }
104
 
105
        $mformid = 'coolh5peditor';
106
        $mform->setAttributes(array('id' => $mformid) + $mform->getAttributes());
107
 
108
        if ($errors || $notifications) {
109
            // Show the error messages and a Cancel button.
110
            foreach ($errors as $error) {
111
                $mform->addElement('warning', $error->code, 'notify', $error->message);
112
            }
113
            foreach ($notifications as $key => $notification) {
114
                $mform->addElement('warning', 'notification_'.$key, 'notify', $notification);
115
            }
116
            $mform->addElement('cancel', 'cancel', get_string('back'));
117
        } else {
118
            $this->h5peditor->add_editor_to_form($mform);
119
            $this->add_action_buttons();
120
        }
121
    }
122
 
123
    /**
124
     * Modify or create an H5P content from the form data.
125
     *
126
     * @param stdClass $data Form data to create or modify an H5P content.
127
     *
128
     * @return int The id of the edited or created content.
129
     */
130
    public function save_content(stdClass $data): int {
131
        global $DB;
132
 
133
        // The H5P libraries expect data->id as the H5P content id.
134
        // The method H5PCore::saveContent throws an error if id is set but empty.
135
        if (empty($data->id)) {
136
            unset($data->id);
137
        } else {
138
            // The H5P libraries save in $data->id the H5P content id (h5p table), so the content id is saved in another var.
139
            $contentid = $data->id;
140
        }
141
 
142
        $h5pcontentid = $this->h5peditor->save_content($data);
143
 
144
        $factory = new factory();
145
        $h5pfs = $factory->get_framework();
146
 
147
        // Needs the H5P file id to create or update the content bank record.
148
        $h5pcontent = $h5pfs->loadContent($h5pcontentid);
149
        $fs = get_file_storage();
150
        $file = $fs->get_file_by_hash($h5pcontent['pathnamehash']);
151
        // Creating new content.
152
        if (!isset($data->h5pid)) {
153
            // The initial name of the content is the title of the H5P content.
154
            $cbrecord = new stdClass();
155
            $cbrecord->name = json_decode($data->h5pparams)->metadata->title;
156
            $context = \context::instance_by_id($data->contextid, MUST_EXIST);
157
            // Create entry in content bank.
158
            $contenttype = new contenttype($context);
159
            $newcontent = $contenttype->create_content($cbrecord);
160
            if ($file && $newcontent) {
161
                $updatedfilerecord = new stdClass();
162
                $updatedfilerecord->id = $file->get_id();
163
                $updatedfilerecord->itemid = $newcontent->get_id();
164
                // As itemid changed, the pathnamehash has to be updated in the file table.
165
                $pathnamehash = \file_storage::get_pathname_hash($file->get_contextid(), $file->get_component(),
166
                    $file->get_filearea(), $updatedfilerecord->itemid, $file->get_filepath(), $file->get_filename());
167
                $updatedfilerecord->pathnamehash = $pathnamehash;
168
                $DB->update_record('files', $updatedfilerecord);
169
                // The pathnamehash in the h5p table must match the file pathnamehash.
170
                $h5pfs->updateContentFields($h5pcontentid, ['pathnamehash' => $pathnamehash]);
171
            }
172
        } else {
173
            // Update content.
174
            $this->content->update_content();
175
        }
176
 
177
        return $contentid ?? $newcontent->get_id();
178
    }
179
}