22
22
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
23
*/
24
24
25
+ use core \exception \coding_exception ;
25
26
use core \output \mustache_engine ;
26
27
use core \output \mustache_string_helper ;
27
28
@@ -202,7 +203,7 @@ public static function get_mnet_localhost_wwwroot() {
202
203
* Default format is (see MDL-22145)
203
204
* backup word - format - type - name - date - info . mbz
204
205
* where name is variable (course shortname, section name/id, activity modulename + cmid)
205
- * and info can be (nu = no user info, an = anonymized). The last param $useidasname ,
206
+ * and info can be (nu = no user info, an = anonymized). The last param $useidonly ,
206
207
* defaulting to false, allows to replace the course shortname by the course id (used
207
208
* by automated backups, to avoid non-ascii chars in OS filesystem)
208
209
*
@@ -222,88 +223,87 @@ public static function get_default_backup_filename($format, $type, $id, $users,
222
223
$ time = time ();
223
224
}
224
225
225
- // Calculate backup word
226
- $ backupword = str_replace (' ' , '_ ' , core_text::strtolower (get_string ('backupfilename ' )));
227
- $ backupword = trim (clean_filename ($ backupword ), '_ ' );
228
-
229
- // Not $useidonly, lets fetch the name
230
- $ shortname = '' ;
231
- if (!$ useidonly ) {
232
- // Calculate proper name element (based on type)
233
- switch ($ type ) {
234
- case backup::TYPE_1COURSE :
235
- $ shortname = $ DB ->get_field ('course ' , 'shortname ' , array ('id ' => $ id ));
236
- $ context = context_course::instance ($ id );
237
- $ shortname = format_string ($ shortname , true , array ('context ' => $ context ));
238
- break ;
239
- case backup::TYPE_1SECTION :
240
- if (!$ shortname = $ DB ->get_field ('course_sections ' , 'name ' , array ('id ' => $ id ))) {
241
- $ shortname = $ DB ->get_field ('course_sections ' , 'section ' , array ('id ' => $ id ));
242
- }
243
- break ;
244
- case backup::TYPE_1ACTIVITY :
245
- $ cm = get_coursemodule_from_id (null , $ id );
246
- $ shortname = $ cm ->modname . $ id ;
247
- break ;
248
- }
249
- $ shortname = str_replace (' ' , '_ ' , $ shortname );
250
- $ shortname = core_text::strtolower (trim (clean_filename ($ shortname ), '_ ' ));
251
- }
252
-
253
- // The name will always contain the ID, but we append the course short name if requested.
254
- $ name = $ id ;
255
- if (!$ useidonly && $ shortname != '' ) {
256
- $ name .= '- ' . $ shortname ;
257
- }
258
-
259
- // Calculate date
260
226
$ backupdateformat = str_replace (' ' , '_ ' , get_string ('backupnameformat ' , 'langconfig ' ));
261
- $ date = userdate ($ time , $ backupdateformat , 99 , false );
262
- $ date = core_text::strtolower (trim (clean_filename ($ date ), '_ ' ));
263
-
264
- // Calculate info
265
- $ info = '' ;
266
- if (!$ users ) {
267
- $ info = '-nu ' ;
268
- } else if ($ anonymised ) {
269
- $ info = '-an ' ;
227
+ $ formatdate = function (int $ date ) use ($ backupdateformat ): string {
228
+ $ date = userdate ($ date , $ backupdateformat , 99 , false );
229
+ return core_text::strtolower (trim (clean_filename ($ date ), '_ ' ));
230
+ };
231
+
232
+ $ context = [
233
+ 'format ' => $ format ,
234
+ 'type ' => $ type ,
235
+ 'id ' => $ id ,
236
+ 'users ' => $ users ,
237
+ 'anonymised ' => $ anonymised ,
238
+ 'files ' => $ files ,
239
+ 'useidonly ' => $ useidonly ,
240
+ 'time ' => $ time ,
241
+ 'date ' => $ formatdate ($ time ),
242
+ ];
243
+
244
+ // Add extra context based on the type of backup.
245
+ // It is important to use array and not stdClass here, otherwise array_walk_recursive will not work.
246
+ switch ($ type ) {
247
+ case backup::TYPE_1COURSE :
248
+ $ context ['course ' ] = (array ) $ DB ->get_record ('course ' , ['id ' => $ id ], 'shortname,fullname,startdate,enddate ' , MUST_EXIST );
249
+ $ context ['course ' ]['startdate ' ] = $ formatdate ($ context ['course ' ]['startdate ' ]);
250
+ $ context ['course ' ]['enddate ' ] = $ formatdate ($ context ['course ' ]['enddate ' ]);
251
+ break ;
252
+ case backup::TYPE_1SECTION :
253
+ $ context ['section ' ] = (array ) $ DB ->get_record ('course_sections ' , ['id ' => $ id ], 'name,section ' , MUST_EXIST );
254
+ break ;
255
+ case backup::TYPE_1ACTIVITY :
256
+ $ cm = get_coursemodule_from_id (null , $ id , 0 , false , MUST_EXIST );
257
+ $ context ['activity ' ] = [
258
+ 'modname ' => $ cm ->modname ,
259
+ 'name ' => $ cm ->name ,
260
+ ];
261
+ break ;
262
+ default :
263
+ throw new coding_exception ('Unknown backup type - cannot get template context ' );
270
264
}
271
265
272
- // Indicate if backup doesn't contain files.
273
- if (!$ files ) {
274
- $ info .= '-nf ' ;
266
+ $ instancecontext = null ;
267
+ switch ($ type ) {
268
+ case backup::TYPE_1COURSE :
269
+ $ instancecontext = context_course::instance ($ id );
270
+ break ;
271
+ case backup::TYPE_1SECTION :
272
+ // A section is still course context, but needs an extra step to find the course id.
273
+ $ courseid = $ DB ->get_field ('course_sections ' , 'course ' , ['id ' => $ id ], MUST_EXIST );
274
+ $ instancecontext = context_course::instance ($ courseid );
275
+ break ;
276
+ case backup::TYPE_1ACTIVITY :
277
+ $ instancecontext = context_module::instance ($ id );
278
+ break ;
279
+ default :
280
+ throw new coding_exception ('Unknown backup type - cannot get instance context ' );
275
281
}
276
282
277
- $ original = $ backupword . '- ' . $ format . '- ' . $ type . '- ' .
278
- $ name . '- ' . $ date . $ info . '.mbz ' ;
279
-
280
- // NEW TESTING STUFF.
281
- $ template = "
282
- {{#str}}backupfilename{{/str}}-{{format}}-{{type}}-{{course.shortname}}{{section.name}}{{^section.name}}{{section.section}}{{/section.name}}{{module.modname}}{{id}}
283
- " ;
283
+ // Recursively format all the strings and trim any extra whitespace.
284
+ array_walk_recursive ($ context , function (&$ item ) use ($ instancecontext ) {
285
+ if (is_string ($ item )) {
286
+ // Update by reference.
287
+ $ item = trim (format_string ($ item , true , ['context ' => $ instancecontext ]));
288
+ }
289
+ });
290
+
291
+ $ templates = [
292
+ backup::TYPE_1COURSE => get_config ('backup ' , 'backup_default_filename_template_course ' ),
293
+ backup::TYPE_1SECTION => get_config ('backup ' , 'backup_default_filename_template_section ' ),
294
+ backup::TYPE_1ACTIVITY => get_config ('backup ' , 'backup_default_filename_template_activity ' ),
295
+ ];
296
+ $ template = $ templates [$ type ];
284
297
$ mustache = new mustache_engine ([
285
- 'escape ' => 's ' ,
286
298
'helpers ' => [
287
299
'str ' => [new mustache_string_helper (), 'str ' ],
288
300
],
289
- 'pragmas ' => [\Mustache_Engine::PRAGMA_BLOCKS ],
290
301
]);
291
- $ new = trim ($ mustache ->render ($ template , [
292
- 'format ' => $ format ,
293
- 'type ' => $ type ,
294
- 'course ' => [
295
- // 'shortname' => 'dummy'
296
- ],
297
- 'section ' => [
298
- // 'name' => '123',
299
- 'section ' => '567 '
300
- ],
301
- 'module ' => [
302
- 'modname ' => 'hvp ' ,
303
- 'id ' => $ id
304
- ]
305
- ]));
306
- return $ original ;
302
+ $ new = $ mustache ->render ($ template , $ context );
303
+
304
+ // Clean as filename, remove spaces, and trim to max 251 chars (filename limit, 255 including .mbz extension).
305
+ $ cleaned = substr (str_replace (' ' , '_ ' , clean_filename ($ new )),0 , 251 );
306
+ return $ cleaned . '.mbz ' ;
307
307
}
308
308
309
309
/**
@@ -324,7 +324,6 @@ public static function require_gradebook_backup($courseid, $backupid) {
324
324
AND bi.backupid = :backupid) " ;
325
325
$ params = array ('courseid ' =>$ courseid , 'backupid ' =>$ backupid );
326
326
327
-
328
327
$ count = $ DB ->count_records_sql ($ sql , $ params );
329
328
330
329
//if there are 0 activity grade items not already included in the backup
0 commit comments