Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * Module to export parts of the state and transform them to be used in templates
18
 * and as draggable data.
19
 *
20
 * @module     core_courseformat/local/courseeditor/exporter
21
 * @class      core_courseformat/local/courseeditor/exporter
22
 * @copyright  2021 Ferran Recio <ferran@moodle.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
export default class {
26
 
27
    /**
28
     * Class constructor.
29
     *
30
     * @param {CourseEditor} reactive the course editor object
31
     */
32
    constructor(reactive) {
33
        this.reactive = reactive;
34
 
35
        // Completions states are defined in lib/completionlib.php. There are 4 different completion
36
        // state values, however, the course index uses the same state for complete and complete_pass.
37
        // This is the reason why completed appears twice in the array.
38
        this.COMPLETIONS = ['incomplete', 'complete', 'complete', 'fail'];
39
    }
40
 
41
    /**
42
     * Generate the course export data from the state.
43
     *
44
     * @param {Object} state the current state.
45
     * @returns {Object}
46
     */
47
    course(state) {
48
        // Collect section information from the state.
49
        const data = {
50
            sections: [],
51
            editmode: this.reactive.isEditing,
52
            highlighted: state.course.highlighted ?? '',
53
        };
54
        const sectionlist = this.listedSectionIds(state);
55
        sectionlist.forEach(sectionid => {
56
            const sectioninfo = state.section.get(sectionid) ?? {};
57
            const section = this.section(state, sectioninfo);
58
            data.sections.push(section);
59
        });
60
        data.hassections = (data.sections.length != 0);
61
 
62
        return data;
63
    }
64
 
65
    /**
66
     * Get the IDs of the sections that are listed as regular sections.
67
     * @param {Object} state the current state.
68
     * @returns {Number[]} the list of section ids that are listed.
69
     */
70
    listedSectionIds(state) {
71
        const fullSectionList = state.course.sectionlist ?? [];
72
        return fullSectionList.filter(sectionid => {
73
            const sectioninfo = state.section.get(sectionid) ?? {};
74
            // Delegated sections (controlled by a component) are not listed in course.
75
            return sectioninfo.component === null;
76
        });
77
    }
78
 
79
    /**
80
     * Generate a section export data from the state.
81
     *
82
     * @param {Object} state the current state.
83
     * @param {Object} sectioninfo the section state data.
84
     * @returns {Object}
85
     */
86
    section(state, sectioninfo) {
87
        const section = {
88
            ...sectioninfo,
89
            highlighted: state.course.highlighted ?? '',
90
            cms: [],
91
        };
92
        const cmlist = sectioninfo.cmlist ?? [];
93
        cmlist.forEach(cmid => {
94
            const cminfo = state.cm.get(cmid);
95
            const cm = this.cm(state, cminfo);
96
            section.cms.push(cm);
97
        });
98
        section.hascms = (section.cms.length != 0);
99
 
100
        return section;
101
    }
102
 
103
    /**
104
     * Generate a cm export data from the state.
105
     *
106
     * @param {Object} state the current state.
107
     * @param {Object} cminfo the course module state data.
108
     * @returns {Object}
109
     */
110
    cm(state, cminfo) {
111
        const cm = {
112
            ...cminfo,
113
            isactive: false,
114
        };
115
        return cm;
116
    }
117
 
118
    /**
119
     * Generate a dragable cm data structure.
120
     *
121
     * This method is used by any draggable course module element to generate drop data
122
     * for its reactive/dragdrop instance.
123
     *
124
     * @param {*} state the state object
125
     * @param {*} cmid the cours emodule id
126
     * @returns {Object|null}
127
     */
128
    cmDraggableData(state, cmid) {
129
        const cminfo = state.cm.get(cmid);
130
        if (!cminfo) {
131
            return null;
132
        }
133
 
134
        // Drop an activity over the next activity is the same as doing anything.
135
        let nextcmid;
136
        const section = state.section.get(cminfo.sectionid);
137
        const currentindex = section?.cmlist.indexOf(cminfo.id);
138
        if (currentindex !== undefined) {
139
            nextcmid = section?.cmlist[currentindex + 1];
140
        }
141
 
142
        return {
143
            type: 'cm',
144
            id: cminfo.id,
145
            name: cminfo.name,
146
            sectionid: cminfo.sectionid,
147
            delegatesection: cminfo.delegatesection,
148
            nextcmid,
149
        };
150
    }
151
 
152
    /**
153
     * Generate a dragable cm data structure.
154
     *
155
     * This method is used by any draggable section element to generate drop data
156
     * for its reactive/dragdrop instance.
157
     *
158
     * @param {*} state the state object
159
     * @param {*} sectionid the cours section id
160
     * @returns {Object|null}
161
     */
162
    sectionDraggableData(state, sectionid) {
163
        const sectioninfo = state.section.get(sectionid);
164
        if (!sectioninfo) {
165
            return null;
166
        }
167
        return {
168
            type: 'section',
169
            id: sectioninfo.id,
170
            name: sectioninfo.name,
171
            number: sectioninfo.number,
172
        };
173
    }
174
 
175
    /**
176
     * Generate a file draggable structure.
177
     *
178
     * This method is used when files are dragged on the browser.
179
     *
180
     * @param {*} state the state object
181
     * @param {*} dataTransfer the current data tranfer data
182
     * @returns {Object|null}
183
     */
184
    fileDraggableData(state, dataTransfer) {
185
        const files = [];
186
        // Browsers do not provide the file list until the drop event.
187
        if (dataTransfer.files?.length > 0) {
188
            dataTransfer.files.forEach(file => {
189
                files.push(file);
190
            });
191
        }
192
        return {
193
            type: 'files',
194
            files,
195
        };
196
    }
197
 
198
    /**
199
     * Generate a completion export data from the cm element.
200
     *
201
     * @param {Object} state the current state.
202
     * @param {Object} cminfo the course module state data.
203
     * @returns {Object}
204
     */
205
    cmCompletion(state, cminfo) {
206
        const data = {
207
            statename: '',
208
            state: 'NaN',
209
        };
210
        if (cminfo.completionstate !== undefined) {
211
            data.state = cminfo.completionstate;
212
            data.hasstate = true;
213
            let statename = this.COMPLETIONS[cminfo.completionstate] ?? 'NaN';
214
            if (cminfo.isoverallcomplete !== undefined && cminfo.isoverallcomplete === true) {
215
                statename = 'complete';
216
            }
217
            data[`is${statename}`] = true;
218
        }
219
        return data;
220
    }
221
 
222
    /**
223
     * Return a sorted list of all sections and cms items in the state.
224
     *
225
     * @param {Object} state the current state.
226
     * @returns {Array} all sections and cms items in the state.
227
     */
228
    allItemsArray(state) {
229
        const items = [];
230
        const sectionlist = state.course.sectionlist ?? [];
231
        // Add sections.
232
        sectionlist.forEach(sectionid => {
233
            const sectioninfo = state.section.get(sectionid);
234
            items.push({type: 'section', id: sectioninfo.id, url: sectioninfo.sectionurl});
235
            // Add cms.
236
            const cmlist = sectioninfo.cmlist ?? [];
237
            cmlist.forEach(cmid => {
238
                const cminfo = state.cm.get(cmid);
239
                items.push({type: 'cm', id: cminfo.id, url: cminfo.url});
240
            });
241
        });
242
        return items;
243
    }
244
 
245
    /**
246
     * Check is some activities of a list can be stealth.
247
     *
248
     * @param {Object} state the current state.
249
     * @param {Number[]} cmIds the module ids to check
250
     * @returns {Boolean} if any of the activities can be stealth.
251
     */
252
    canUseStealth(state, cmIds) {
253
        return cmIds.some(cmId => {
254
            const cminfo = state.cm.get(cmId);
255
            return cminfo?.allowstealth ?? false;
256
        });
257
    }
258
}