Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
// This file is part of Moodle - http://moodle.org/
4
//
5
// Moodle is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// Moodle is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
/**
19
 * Provides support for the conversion of moodle1 backup to the moodle2 format
20
 *
21
 * @package    mod_resource
22
 * @copyright  2011 Andrew Davis <andrew@moodle.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
/**
29
 * Resource conversion handler
30
 */
31
class moodle1_mod_resource_handler extends moodle1_mod_handler {
32
 
33
    /** @var moodle1_file_manager instance */
34
    protected $fileman = null;
35
 
36
    /** @var array of resource successors handlers */
37
    private $successors = array();
38
 
39
    /**
40
     * Declare the paths in moodle.xml we are able to convert
41
     *
42
     * The method returns list of {@link convert_path} instances.
43
     * For each path returned, the corresponding conversion method must be
44
     * defined.
45
     *
46
     * Note that the paths /MOODLE_BACKUP/COURSE/MODULES/MOD/RESOURCE do not
47
     * actually exist in the file. The last element with the module name was
48
     * appended by the moodle1_converter class.
49
     *
50
     * @return array of {@link convert_path} instances
51
     */
52
    public function get_paths() {
53
        return array(
54
            new convert_path(
55
                'resource', '/MOODLE_BACKUP/COURSE/MODULES/MOD/RESOURCE',
56
                array(
57
                    'renamefields' => array(
58
                        'summary' => 'intro',
59
                    ),
60
                    'newfields' => array(
61
                        'introformat' => 0,
62
                    ),
63
                    'dropfields' => array(
64
                        'modtype',
65
                    ),
66
                )
67
            )
68
        );
69
    }
70
 
71
    /**
72
     * Converts /MOODLE_BACKUP/COURSE/MODULES/MOD/RESOURCE data
73
     *
74
     * This methods detects the resource type and eventually re-dispatches it to the
75
     * corresponding resource successor (url, forum, page, imscp).
76
     */
77
    public function process_resource(array $data, array $raw) {
78
        global $CFG;
79
        require_once("$CFG->libdir/resourcelib.php");
80
 
81
        // replay the upgrade step 2009042001
82
        if ($CFG->texteditors !== 'textarea') {
83
            $data['intro']       = text_to_html($data['intro'], false, false, true);
84
            $data['introformat'] = FORMAT_HTML;
85
        }
86
 
87
        // fix invalid null popup and options data
88
        if (!array_key_exists('popup', $data) or is_null($data['popup'])) {
89
            $data['popup'] = '';
90
        }
91
        if (!array_key_exists ('options', $data) or is_null($data['options'])) {
92
            $data['options'] = '';
93
        }
94
 
95
        // decide if the legacy resource should be handled by a successor module
96
        if ($successor = $this->get_successor($data['type'], $data['reference'])) {
97
            // the instance id will be kept
98
            $instanceid = $data['id'];
99
 
100
            // move the instance from the resource's modinfo stash to the successor's
101
            // modinfo stash
102
            $resourcemodinfo  = $this->converter->get_stash('modinfo_resource');
103
            $successormodinfo = $this->converter->get_stash('modinfo_'.$successor->get_modname());
104
            $successormodinfo['instances'][$instanceid] = $resourcemodinfo['instances'][$instanceid];
105
            unset($resourcemodinfo['instances'][$instanceid]);
106
            $this->converter->set_stash('modinfo_resource', $resourcemodinfo);
107
            $this->converter->set_stash('modinfo_'.$successor->get_modname(), $successormodinfo);
108
 
109
            // get the course module information for the legacy resource module
110
            $cminfo = $this->get_cminfo($instanceid);
111
 
112
            // use the version of the successor instead of the current mod/resource
113
            // beware - the version.php declares info via $module object, do not use
114
            // a variable of such name here
115
            $plugin = new stdClass();
116
            $plugin->version = null;
117
            $module = $plugin;
118
            include $CFG->dirroot.'/mod/'.$successor->get_modname().'/version.php';
119
            $cminfo['version'] = $plugin->version;
120
 
121
            // stash the new course module information for this successor
122
            $cminfo['modulename'] = $successor->get_modname();
123
            $this->converter->set_stash('cminfo_'.$cminfo['modulename'], $cminfo, $instanceid);
124
 
125
            // rewrite the coursecontents stash
126
            $coursecontents = $this->converter->get_stash('coursecontents');
127
            $coursecontents[$cminfo['id']]['modulename'] = $successor->get_modname();
128
            $this->converter->set_stash('coursecontents', $coursecontents);
129
 
130
            // delegate the processing to the successor handler
131
            return $successor->process_legacy_resource($data, $raw);
132
        }
133
 
134
        // no successor is interested in this record, convert it to the new mod_resource (aka File module)
135
 
136
        $resource = array();
137
        $resource['id']              = $data['id'];
138
        $resource['name']            = $data['name'];
139
        $resource['intro']           = $data['intro'];
140
        $resource['introformat']     = $data['introformat'];
141
        $resource['tobemigrated']    = 0;
142
        $resource['legacyfiles']     = RESOURCELIB_LEGACYFILES_ACTIVE;
143
        $resource['legacyfileslast'] = null;
144
        $resource['filterfiles']     = 0;
145
        $resource['revision']        = 1;
146
        $resource['timemodified']    = $data['timemodified'];
147
 
148
        // populate display and displayoptions fields
149
        $options = array('printintro' => 1);
150
        if ($data['options'] == 'frame') {
151
            $resource['display'] = RESOURCELIB_DISPLAY_FRAME;
152
 
153
        } else if ($data['options'] == 'objectframe') {
154
            $resource['display'] = RESOURCELIB_DISPLAY_EMBED;
155
 
156
        } else if ($data['options'] == 'forcedownload') {
157
            $resource['display'] = RESOURCELIB_DISPLAY_DOWNLOAD;
158
 
159
        } else if ($data['popup']) {
160
            $resource['display'] = RESOURCELIB_DISPLAY_POPUP;
161
            $rawoptions = explode(',', $data['popup']);
162
            foreach ($rawoptions as $rawoption) {
163
                list($name, $value) = explode('=', trim($rawoption), 2);
164
                if ($value > 0 and ($name == 'width' or $name == 'height')) {
165
                    $options['popup'.$name] = $value;
166
                    continue;
167
                }
168
            }
169
 
170
        } else {
171
            $resource['display'] = RESOURCELIB_DISPLAY_AUTO;
172
        }
173
        $resource['displayoptions'] = serialize($options);
174
 
175
        // get the course module id and context id
176
        $instanceid     = $resource['id'];
177
        $currentcminfo  = $this->get_cminfo($instanceid);
178
        $moduleid       = $currentcminfo['id'];
179
        $contextid      = $this->converter->get_contextid(CONTEXT_MODULE, $moduleid);
180
 
181
        // get a fresh new file manager for this instance
182
        $this->fileman = $this->converter->get_file_manager($contextid, 'mod_resource');
183
 
184
        // convert course files embedded into the intro
185
        $this->fileman->filearea = 'intro';
186
        $this->fileman->itemid   = 0;
187
        $resource['intro'] = moodle1_converter::migrate_referenced_files($resource['intro'], $this->fileman);
188
 
189
        // convert the referenced file itself as a main file in the content area
190
        $reference = $data['reference'];
191
        if (strpos($reference, '$@FILEPHP@$') === 0) {
192
            $reference = str_replace(array('$@FILEPHP@$', '$@SLASH@$', '$@FORCEDOWNLOAD@$'), array('', '/', ''), $reference);
193
        }
194
        $this->fileman->filearea = 'content';
195
        $this->fileman->itemid   = 0;
196
 
197
        // Rebuild the file path.
198
        $curfilepath = '/';
199
        if ($reference) {
200
            $curfilepath = pathinfo('/'.$reference, PATHINFO_DIRNAME);
201
            if ($curfilepath != '/') {
202
                $curfilepath .= '/';
203
            }
204
        }
205
        try {
206
            $this->fileman->migrate_file('course_files/'.$reference, $curfilepath, null, 1);
207
        } catch (moodle1_convert_exception $e) {
208
            // the file probably does not exist
209
            $this->log('error migrating the resource main file', backup::LOG_WARNING, 'course_files/'.$reference);
210
        }
211
 
212
        // write resource.xml
213
        $this->open_xml_writer("activities/resource_{$moduleid}/resource.xml");
214
        $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $moduleid,
215
            'modulename' => 'resource', 'contextid' => $contextid));
216
        $this->write_xml('resource', $resource, array('/resource/id'));
217
        $this->xmlwriter->end_tag('activity');
218
        $this->close_xml_writer();
219
 
220
        // write inforef.xml
221
        $this->open_xml_writer("activities/resource_{$currentcminfo['id']}/inforef.xml");
222
        $this->xmlwriter->begin_tag('inforef');
223
        $this->xmlwriter->begin_tag('fileref');
224
        foreach ($this->fileman->get_fileids() as $fileid) {
225
            $this->write_xml('file', array('id' => $fileid));
226
        }
227
        $this->xmlwriter->end_tag('fileref');
228
        $this->xmlwriter->end_tag('inforef');
229
        $this->close_xml_writer();
230
    }
231
 
232
    /**
233
     * Give succesors a chance to finish their job
234
     */
235
    public function on_resource_end(array $data) {
236
        if ($successor = $this->get_successor($data['type'], $data['reference'])) {
237
            $successor->on_legacy_resource_end($data);
238
        }
239
    }
240
 
241
    /// internal implementation details follow /////////////////////////////////
242
 
243
    /**
244
     * Returns the handler of the new 2.0 mod type according the given type of the legacy 1.9 resource
245
     *
246
     * @param string $type the value of the 'type' field in 1.9 resource
247
     * @param string $reference a file path. Necessary to differentiate files from web URLs
248
     * @throws moodle1_convert_exception for the unknown types
249
     * @return null|moodle1_mod_handler the instance of the handler, or null if the type does not have a successor
250
     */
251
    protected function get_successor($type, $reference) {
252
 
253
        switch ($type) {
254
            case 'text':
255
            case 'html':
256
                $name = 'page';
257
                break;
258
            case 'directory':
259
                $name = 'folder';
260
                break;
261
            case 'ims':
262
                $name = 'imscp';
263
                break;
264
            case 'file':
265
                // if starts with $@FILEPHP@$ then it is URL link to a local course file
266
                // to be migrated to the new resource module
267
                if (strpos($reference, '$@FILEPHP@$') === 0) {
268
                    $name = null;
269
                    break;
270
                }
271
                // if http:// https:// ftp:// OR starts with slash need to be converted to URL
272
                if (strpos($reference, '://') or strpos($reference, '/') === 0) {
273
                    $name = 'url';
274
                } else {
275
                    $name = null;
276
                }
277
                break;
278
            default:
279
                throw new moodle1_convert_exception('unknown_resource_successor', $type);
280
        }
281
 
282
        if (is_null($name)) {
283
            return null;
284
        }
285
 
286
        if (!isset($this->successors[$name])) {
287
            $this->log('preparing resource successor handler', backup::LOG_DEBUG, $name);
288
            $class = 'moodle1_mod_'.$name.'_handler';
289
            $this->successors[$name] = new $class($this->converter, 'mod', $name);
290
 
291
            // add the successor into the modlist stash
292
            $modnames = $this->converter->get_stash('modnameslist');
293
            $modnames[] = $name;
294
            $modnames = array_unique($modnames); // should not be needed but just in case
295
            $this->converter->set_stash('modnameslist', $modnames);
296
 
297
            // add the successor's modinfo stash
298
            $modinfo = $this->converter->get_stash('modinfo_resource');
299
            $modinfo['name'] = $name;
300
            $modinfo['instances'] = array();
301
            $this->converter->set_stash('modinfo_'.$name, $modinfo);
302
        }
303
 
304
        return $this->successors[$name];
305
     }
306
}