| Línea 231... |
Línea 231... |
| 231 |
* 1/ All questions are deleted for this question category.
|
231 |
* 1/ All questions are deleted for this question category.
|
| 232 |
* 2/ Any questions that can't be deleted are moved to a new category
|
232 |
* 2/ Any questions that can't be deleted are moved to a new category
|
| 233 |
* NOTE: this function is called from lib/db/upgrade.php
|
233 |
* NOTE: this function is called from lib/db/upgrade.php
|
| 234 |
*
|
234 |
*
|
| 235 |
* @param object|core_course_category $category course category object
|
235 |
* @param object|core_course_category $category course category object
|
| - |
|
236 |
* @param bool $coursedeletion Is the course this category is under being deleted? If so, move saved questions to the site course.
|
| 236 |
*/
|
237 |
*/
|
| 237 |
function question_category_delete_safe($category): void {
|
238 |
function question_category_delete_safe($category, bool $coursedeletion = false): void {
|
| 238 |
global $DB;
|
239 |
global $DB;
|
| 239 |
$criteria = ['questioncategoryid' => $category->id];
|
240 |
$criteria = ['questioncategoryid' => $category->id];
|
| 240 |
$context = context::instance_by_id($category->contextid, IGNORE_MISSING);
|
241 |
$context = context::instance_by_id($category->contextid, IGNORE_MISSING);
|
| 241 |
$rescue = null; // See the code around the call to question_save_from_deletion.
|
242 |
$rescue = null; // See the code around the call to question_save_from_deletion.
|
| Línea 264... |
Línea 265... |
| 264 |
foreach ($versions as $key => $version) {
|
265 |
foreach ($versions as $key => $version) {
|
| 265 |
$questionids[$key] = $version;
|
266 |
$questionids[$key] = $version;
|
| 266 |
}
|
267 |
}
|
| 267 |
}
|
268 |
}
|
| 268 |
if (!empty($questionids)) {
|
269 |
if (!empty($questionids)) {
|
| 269 |
$parentcontextid = SYSCONTEXTID;
|
- |
|
| 270 |
$name = get_string('unknown', 'question');
|
270 |
$name = get_string('unknown', 'question');
|
| 271 |
if ($context !== false) {
|
271 |
if ($context !== false) {
|
| 272 |
$name = $context->get_context_name();
|
272 |
$name = $context->get_context_name();
|
| 273 |
$parentcontext = $context->get_parent_context();
|
273 |
$parentcontext = $context->get_course_context(false);
|
| 274 |
if ($parentcontext) {
|
- |
|
| 275 |
$parentcontextid = $parentcontext->id;
|
274 |
$course = ($parentcontext && !$coursedeletion) ? get_course($parentcontext->instanceid) : get_site();
|
| 276 |
}
|
- |
|
| 277 |
}
|
275 |
}
|
| - |
|
276 |
$qbank = core_question\local\bank\question_bank_helper::get_default_open_instance_system_type($course, true);
|
| 278 |
question_save_from_deletion(array_keys($questionids), $parentcontextid, $name, $rescue);
|
277 |
question_save_from_deletion(array_keys($questionids), $qbank->context->id, $name, $rescue);
|
| 279 |
}
|
278 |
}
|
| 280 |
}
|
279 |
}
|
| Línea 281... |
Línea 280... |
| 281 |
|
280 |
|
| 282 |
// Now delete the category.
|
281 |
// Now delete the category.
|
| Línea 422... |
Línea 421... |
| 422 |
|
421 |
|
| 423 |
/**
|
422 |
/**
|
| 424 |
* All question categories and their questions are deleted for this context id.
|
423 |
* All question categories and their questions are deleted for this context id.
|
| 425 |
*
|
424 |
*
|
| - |
|
425 |
* @param int $contextid The contextid to delete question categories from
|
| 426 |
* @param int $contextid The contextid to delete question categories from
|
426 |
* @param bool $coursedeletion Are we calling this as part of deleting the course the context is under?
|
| 427 |
* @return array only returns an empty array for backwards compatibility.
|
427 |
* @return array only returns an empty array for backwards compatibility.
|
| 428 |
*/
|
428 |
*/
|
| 429 |
function question_delete_context($contextid): array {
|
429 |
function question_delete_context($contextid, bool $coursedeletion = false): array {
|
| Línea 430... |
Línea 430... |
| 430 |
global $DB;
|
430 |
global $DB;
|
| 431 |
|
431 |
|
| 432 |
$fields = 'id, parent, name, contextid';
|
432 |
$fields = 'id, parent, name, contextid';
|
| 433 |
if ($categories = $DB->get_records('question_categories', ['contextid' => $contextid], 'parent', $fields)) {
|
433 |
if ($categories = $DB->get_records('question_categories', ['contextid' => $contextid], 'parent', $fields)) {
|
| 434 |
// Sort categories following their tree (parent-child) relationships this will make the feedback more readable.
|
434 |
// Sort categories following their tree (parent-child) relationships this will make the feedback more readable.
|
| 435 |
$categories = sort_categories_by_tree($categories);
|
435 |
$categories = sort_categories_by_tree($categories);
|
| 436 |
foreach ($categories as $category) {
|
436 |
foreach ($categories as $category) {
|
| 437 |
question_category_delete_safe($category);
|
437 |
question_category_delete_safe($category, $coursedeletion);
|
| 438 |
}
|
438 |
}
|
| 439 |
}
|
439 |
}
|
| Línea 440... |
Línea 440... |
| 440 |
return [];
|
440 |
return [];
|
| 441 |
}
|
- |
|
| 442 |
|
- |
|
| 443 |
/**
|
- |
|
| 444 |
* All question categories and their questions are deleted for this course.
|
- |
|
| 445 |
*
|
- |
|
| 446 |
* @param stdClass $course an object representing the activity
|
- |
|
| 447 |
* @param bool $notused this argument is not used any more. Kept for backwards compatibility.
|
- |
|
| 448 |
* @return bool always true.
|
- |
|
| 449 |
*/
|
- |
|
| 450 |
function question_delete_course($course, $notused = false): bool {
|
- |
|
| 451 |
$coursecontext = context_course::instance($course->id);
|
- |
|
| 452 |
question_delete_context($coursecontext->id);
|
- |
|
| 453 |
return true;
|
- |
|
| 454 |
}
|
- |
|
| 455 |
|
- |
|
| 456 |
/**
|
- |
|
| 457 |
* Category is about to be deleted,
|
- |
|
| 458 |
* 1/ All question categories and their questions are deleted for this course category.
|
- |
|
| 459 |
* 2/ All questions are moved to new category
|
- |
|
| 460 |
*
|
- |
|
| 461 |
* @param stdClass|core_course_category $category course category object
|
- |
|
| 462 |
* @param stdClass|core_course_category $newcategory empty means everything deleted, otherwise id of
|
- |
|
| 463 |
* category where content moved
|
- |
|
| 464 |
* @param bool $notused this argument is no longer used. Kept for backwards compatibility.
|
- |
|
| 465 |
* @return boolean
|
- |
|
| 466 |
*/
|
- |
|
| 467 |
function question_delete_course_category($category, $newcategory, $notused=false): bool {
|
- |
|
| 468 |
global $DB;
|
- |
|
| 469 |
|
- |
|
| 470 |
$context = context_coursecat::instance($category->id);
|
- |
|
| 471 |
if (empty($newcategory)) {
|
- |
|
| 472 |
question_delete_context($context->id);
|
- |
|
| 473 |
|
- |
|
| 474 |
} else {
|
- |
|
| 475 |
// Move question categories to the new context.
|
- |
|
| 476 |
if (!$newcontext = context_coursecat::instance($newcategory->id)) {
|
- |
|
| 477 |
return false;
|
- |
|
| 478 |
}
|
- |
|
| 479 |
|
- |
|
| 480 |
// Only move question categories if there is any question category at all!
|
- |
|
| 481 |
if ($topcategory = question_get_top_category($context->id)) {
|
- |
|
| 482 |
$newtopcategory = question_get_top_category($newcontext->id, true);
|
- |
|
| 483 |
|
- |
|
| 484 |
question_move_category_to_context($topcategory->id, $context->id, $newcontext->id);
|
- |
|
| 485 |
$DB->set_field('question_categories', 'parent', $newtopcategory->id, ['parent' => $topcategory->id]);
|
- |
|
| 486 |
// Now delete the top category.
|
- |
|
| 487 |
$DB->delete_records('question_categories', ['id' => $topcategory->id]);
|
- |
|
| 488 |
}
|
- |
|
| 489 |
}
|
- |
|
| 490 |
|
- |
|
| 491 |
return true;
|
- |
|
| 492 |
}
|
441 |
}
|
| 493 |
|
442 |
|
| 494 |
/**
|
443 |
/**
|
| 495 |
* Creates a new category to save the questions in use.
|
444 |
* Creates a new category to save the questions in use.
|
| 496 |
*
|
445 |
*
|
| Línea 502... |
Línea 451... |
| 502 |
* @return mixed false on
|
451 |
* @return mixed false on
|
| 503 |
*/
|
452 |
*/
|
| 504 |
function question_save_from_deletion($questionids, $newcontextid, $oldplace, $newcategory = null) {
|
453 |
function question_save_from_deletion($questionids, $newcontextid, $oldplace, $newcategory = null) {
|
| 505 |
global $DB;
|
454 |
global $DB;
|
| Línea -... |
Línea 455... |
| - |
|
455 |
|
| - |
|
456 |
$newcontext = context::instance_by_id($newcontextid);
|
| - |
|
457 |
if ($newcontext->contextlevel !== CONTEXT_MODULE) {
|
| - |
|
458 |
throw new moodle_exception("Invalid contextlevel: {$newcontext->contextlevel} for \$newcontextid {$newcontextid}");
|
| - |
|
459 |
}
|
| 506 |
|
460 |
|
| 507 |
// Make a category in the parent context to move the questions to.
|
461 |
// Make a category in the parent context to move the questions to.
|
| 508 |
if (is_null($newcategory)) {
|
462 |
if (is_null($newcategory)) {
|
| 509 |
$newcategory = new stdClass();
|
463 |
$newcategory = new stdClass();
|
| 510 |
$newcategory->parent = question_get_top_category($newcontextid, true)->id;
|
464 |
$newcategory->parent = question_get_top_category($newcontextid, true)->id;
|
| Línea 527... |
Línea 481... |
| 527 |
/**
|
481 |
/**
|
| 528 |
* All question categories and their questions are deleted for this activity.
|
482 |
* All question categories and their questions are deleted for this activity.
|
| 529 |
*
|
483 |
*
|
| 530 |
* @param object $cm the course module object representing the activity
|
484 |
* @param object $cm the course module object representing the activity
|
| 531 |
* @param bool $notused the argument is not used any more. Kept for backwards compatibility.
|
485 |
* @param bool $notused the argument is not used any more. Kept for backwards compatibility.
|
| - |
|
486 |
* @param bool $coursedeletion Are we calling this as part of deleting the course the activity belongs to?
|
| 532 |
* @return boolean
|
487 |
* @return boolean
|
| 533 |
*/
|
488 |
*/
|
| 534 |
function question_delete_activity($cm, $notused = false): bool {
|
489 |
function question_delete_activity($cm, $notused = false, bool $coursedeletion = false): bool {
|
| 535 |
$modcontext = context_module::instance($cm->id);
|
490 |
$modcontext = context_module::instance($cm->id);
|
| 536 |
question_delete_context($modcontext->id);
|
491 |
question_delete_context($modcontext->id, $coursedeletion);
|
| 537 |
return true;
|
492 |
return true;
|
| 538 |
}
|
493 |
}
|
| Línea 539... |
Línea 494... |
| 539 |
|
494 |
|
| 540 |
/**
|
495 |
/**
|
| 541 |
* This function will handle moving all tag instances to a new context for a
|
496 |
* This function will handle moving all tag instances to a new context for a
|
| 542 |
* given list of questions.
|
497 |
* given list of questions.
|
| 543 |
*
|
- |
|
| 544 |
* Questions can be tagged in up to two contexts:
|
- |
|
| 545 |
* 1.) The context the question exists in.
|
- |
|
| 546 |
* 2.) The course context (if the question context is a higher context.
|
- |
|
| 547 |
* E.g. course category context or system context.
|
- |
|
| 548 |
*
|
- |
|
| 549 |
* This means a question that exists in a higher context (e.g. course cat or
|
- |
|
| 550 |
* system context) may have multiple groups of tags in any number of child
|
- |
|
| 551 |
* course contexts.
|
- |
|
| 552 |
*
|
- |
|
| 553 |
* Questions in the course category context can be move "down" a context level
|
- |
|
| 554 |
* into one of their child course contexts or activity contexts which affects the
|
- |
|
| 555 |
* availability of that question in other courses / activities.
|
- |
|
| 556 |
*
|
- |
|
| 557 |
* In this case it makes the questions no longer available in the other course or
|
- |
|
| 558 |
* activity contexts so we need to make sure that the tag instances in those other
|
- |
|
| 559 |
* contexts are removed.
|
- |
|
| 560 |
*
|
498 |
*
|
| 561 |
* @param stdClass[] $questions The list of question being moved (must include
|
499 |
* @param stdClass[] $questions The list of question being moved (must include
|
| 562 |
* the id and contextid)
|
500 |
* the id and contextid)
|
| 563 |
* @param context $newcontext The Moodle context the questions are being moved to
|
501 |
* @param context $newcontext The Moodle context the questions are being moved to, must be module context.
|
| 564 |
*/
|
502 |
*/
|
| 565 |
function question_move_question_tags_to_new_context(array $questions, context $newcontext): void {
|
- |
|
| - |
|
503 |
function question_move_question_tags_to_new_context(array $questions, context $newcontext): void {
|
| 566 |
// If the questions are moving to a new course/activity context then we need to
|
504 |
|
| 567 |
// find any existing tag instances from any unavailable course contexts and
|
505 |
if ($newcontext->contextlevel !== CONTEXT_MODULE) {
|
| 568 |
// delete them because they will no longer be applicable (we don't support
|
- |
|
| 569 |
// tagging questions across courses).
|
506 |
debugging("Invalid contextlevel: {$newcontext->contextlevel}", DEBUG_DEVELOPER);
|
| - |
|
507 |
}
|
| 570 |
$instancestodelete = [];
|
508 |
|
| 571 |
$instancesfornewcontext = [];
|
- |
|
| 572 |
$newcontextparentids = $newcontext->get_parent_context_ids();
|
509 |
$instancesfornewcontext = [];
|
| 573 |
$questionids = array_map(function($question) {
|
510 |
$questionids = array_map(function($question) {
|
| 574 |
return $question->id;
|
511 |
return $question->id;
|
| 575 |
}, $questions);
|
512 |
}, $questions);
|
| Línea 580... |
Línea 517... |
| 580 |
|
517 |
|
| 581 |
foreach ($tagobjects as $tagobject) {
|
518 |
foreach ($tagobjects as $tagobject) {
|
| 582 |
$tagid = $tagobject->taginstanceid;
|
519 |
$tagid = $tagobject->taginstanceid;
|
| 583 |
$tagcontextid = $tagobject->taginstancecontextid;
|
520 |
$tagcontextid = $tagobject->taginstancecontextid;
|
| 584 |
$istaginnewcontext = $tagcontextid == $newcontext->id;
|
- |
|
| Línea 585... |
Línea 521... |
| 585 |
$istaginquestioncontext = $tagcontextid == $question->contextid;
|
521 |
$istaginnewcontext = $tagcontextid == $newcontext->id;
|
| 586 |
|
522 |
|
| 587 |
if ($istaginnewcontext) {
|
523 |
if ($istaginnewcontext) {
|
| 588 |
// This tag instance is already in the correct context so we can
|
524 |
// This tag instance is already in the correct context so we can
|
| 589 |
// ignore it.
|
525 |
// ignore it.
|
| Línea 590... |
Línea -... |
| 590 |
continue;
|
- |
|
| 591 |
}
|
- |
|
| 592 |
|
- |
|
| 593 |
if ($istaginquestioncontext) {
|
- |
|
| 594 |
// This tag instance is in the question context so it needs to be
|
- |
|
| 595 |
// updated.
|
- |
|
| 596 |
$instancesfornewcontext[] = $tagid;
|
- |
|
| 597 |
continue;
|
- |
|
| 598 |
}
|
- |
|
| 599 |
|
- |
|
| 600 |
// These tag instances are in neither the new context nor the
|
- |
|
| 601 |
// question context so we need to determine what to do based on
|
- |
|
| 602 |
// the context they are in and the new question context.
|
- |
|
| 603 |
$tagcontext = context::instance_by_id($tagcontextid);
|
- |
|
| 604 |
$tagcoursecontext = $tagcontext->get_course_context(false);
|
- |
|
| 605 |
// The tag is in a course context if get_course_context() returns
|
- |
|
| 606 |
// itself.
|
- |
|
| 607 |
$istaginstancecontextcourse = !empty($tagcoursecontext)
|
- |
|
| 608 |
&& $tagcontext->id == $tagcoursecontext->id;
|
- |
|
| 609 |
|
- |
|
| 610 |
if ($istaginstancecontextcourse) {
|
- |
|
| 611 |
// If the tag instance is in a course context we need to add some
|
- |
|
| 612 |
// special handling.
|
- |
|
| 613 |
$tagcontextparentids = $tagcontext->get_parent_context_ids();
|
- |
|
| 614 |
$isnewcontextaparent = in_array($newcontext->id, $tagcontextparentids);
|
- |
|
| 615 |
$isnewcontextachild = in_array($tagcontext->id, $newcontextparentids);
|
- |
|
| 616 |
|
- |
|
| 617 |
if ($isnewcontextaparent) {
|
- |
|
| 618 |
// If the tag instance is a course context tag and the new
|
- |
|
| 619 |
// context is still a parent context to the tag context then
|
- |
|
| 620 |
// we can leave this tag where it is.
|
- |
|
| 621 |
continue;
|
- |
|
| 622 |
} else if ($isnewcontextachild) {
|
- |
|
| 623 |
// If the new context is a child context (e.g. activity) of this
|
- |
|
| 624 |
// tag instance then we should move all of this tag instance
|
- |
|
| 625 |
// down into the activity context along with the question.
|
- |
|
| 626 |
$instancesfornewcontext[] = $tagid;
|
- |
|
| 627 |
} else {
|
- |
|
| 628 |
// If the tag is in a course context that is no longer a parent
|
- |
|
| 629 |
// or child of the new context then this tag instance should be
|
- |
|
| 630 |
// removed.
|
- |
|
| 631 |
$instancestodelete[] = $tagid;
|
- |
|
| 632 |
}
|
- |
|
| 633 |
} else {
|
- |
|
| 634 |
// This is a catch all for any tag instances not in the question
|
- |
|
| 635 |
// context or a course context. These tag instances should be
|
526 |
continue;
|
| 636 |
// updated to the new context id. This will clean up old invalid
|
- |
|
| 637 |
// data.
|
527 |
}
|
| 638 |
$instancesfornewcontext[] = $tagid;
|
528 |
|
| Línea 639... |
Línea -... |
| 639 |
}
|
- |
|
| 640 |
}
|
- |
|
| 641 |
}
|
- |
|
| 642 |
|
- |
|
| 643 |
if (!empty($instancestodelete)) {
|
- |
|
| 644 |
// Delete any course context tags that may no longer be valid.
|
529 |
$instancesfornewcontext[] = $tagid;
|
| 645 |
core_tag_tag::delete_instances_by_id($instancestodelete);
|
530 |
}
|
| 646 |
}
|
531 |
}
|
| 647 |
|
532 |
|
| 648 |
if (!empty($instancesfornewcontext)) {
|
533 |
if (!empty($instancesfornewcontext)) {
|
| Línea 780... |
Línea 665... |
| 780 |
global $DB;
|
665 |
global $DB;
|
| Línea 781... |
Línea 666... |
| 781 |
|
666 |
|
| 782 |
if ($delete || $oldcontextid !== $newcontextid) {
|
667 |
if ($delete || $oldcontextid !== $newcontextid) {
|
| 783 |
$setreferences = $DB->get_recordset('question_set_references', ['questionscontextid' => $oldcontextid]);
|
668 |
$setreferences = $DB->get_recordset('question_set_references', ['questionscontextid' => $oldcontextid]);
|
| 784 |
foreach ($setreferences as $setreference) {
|
669 |
foreach ($setreferences as $setreference) {
|
| 785 |
$filter = json_decode($setreference->filtercondition);
|
670 |
$filter = json_decode($setreference->filtercondition, true);
|
| 786 |
if (isset($filter->questioncategoryid)) {
|
671 |
if (isset($filter['questioncategoryid'])) {
|
| - |
|
672 |
$filter = question_reference_manager::convert_legacy_set_reference_filter_condition($filter);
|
| 787 |
if ((int)$filter->questioncategoryid === $oldcategoryid) {
|
673 |
}
|
| 788 |
$setreference->questionscontextid = $newcontextid;
|
674 |
$setreference->questionscontextid = $newcontextid;
|
| 789 |
if ($oldcategoryid !== $newcatgoryid) {
|
675 |
if (
|
| 790 |
$filter->questioncategoryid = $newcatgoryid;
|
676 |
(int)$filter['filter']['category']['values'][0] === $oldcategoryid
|
| 791 |
$setreference->filtercondition = json_encode($filter);
|
677 |
&& $oldcategoryid !== $newcatgoryid
|
| 792 |
}
|
678 |
) {
|
| 793 |
$DB->update_record('question_set_references', $setreference);
|
679 |
$filter['filter']['category']['values'][0] = $newcatgoryid;
|
| 794 |
}
|
680 |
$setreference->filtercondition = json_encode($filter);
|
| - |
|
681 |
}
|
| 795 |
}
|
682 |
$DB->update_record('question_set_references', $setreference);
|
| 796 |
}
|
683 |
}
|
| 797 |
$setreferences->close();
|
684 |
$setreferences->close();
|
| 798 |
}
|
685 |
}
|
| Línea 807... |
Línea 694... |
| 807 |
* @param integer $newcontextid the new context id.
|
694 |
* @param integer $newcontextid the new context id.
|
| 808 |
*/
|
695 |
*/
|
| 809 |
function question_move_category_to_context($categoryid, $oldcontextid, $newcontextid): void {
|
696 |
function question_move_category_to_context($categoryid, $oldcontextid, $newcontextid): void {
|
| 810 |
global $DB;
|
697 |
global $DB;
|
| Línea -... |
Línea 698... |
| - |
|
698 |
|
| - |
|
699 |
$newcontext = context::instance_by_id($newcontextid);
|
| - |
|
700 |
if ($newcontext->contextlevel !== CONTEXT_MODULE) {
|
| - |
|
701 |
debugging("Invalid contextlevel: {$newcontext->contextlevel}, must use CONTEXT_MODULE", DEBUG_DEVELOPER);
|
| - |
|
702 |
}
|
| 811 |
|
703 |
|
| 812 |
$questions = [];
|
704 |
$questions = [];
|
| 813 |
$sql = "SELECT q.id, q.qtype
|
705 |
$sql = "SELECT q.id, q.qtype
|
| 814 |
FROM {question} q
|
706 |
FROM {question} q
|
| 815 |
JOIN {question_versions} qv ON qv.questionid = q.id
|
707 |
JOIN {question_versions} qv ON qv.questionid = q.id
|
| 816 |
JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
|
708 |
JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
|
| Línea 817... |
Línea 709... |
| 817 |
WHERE qbe.questioncategoryid = ?";
|
709 |
WHERE qbe.questioncategoryid = ?";
|
| 818 |
|
710 |
|
| - |
|
711 |
$questionids = $DB->get_records_sql_menu($sql, [$categoryid]);
|
| - |
|
712 |
foreach ($questionids as $questionid => $qtype) {
|
| - |
|
713 |
|
| - |
|
714 |
// If the question type is invalid, use "missingtype" so we have a valid qtype to call move_files() on.
|
| - |
|
715 |
if (!\question_bank::is_qtype_installed($qtype)) {
|
| - |
|
716 |
$qtype = 'missingtype';
|
| 819 |
$questionids = $DB->get_records_sql_menu($sql, [$categoryid]);
|
717 |
}
|
| 820 |
foreach ($questionids as $questionid => $qtype) {
|
718 |
|
| 821 |
question_bank::get_qtype($qtype)->move_files($questionid, $oldcontextid, $newcontextid);
|
719 |
question_bank::get_qtype($qtype)->move_files($questionid, $oldcontextid, $newcontextid);
|
| Línea 822... |
Línea 720... |
| 822 |
// Purge this question from the cache.
|
720 |
// Purge this question from the cache.
|
| 823 |
question_bank::notify_question_edited($questionid);
|
721 |
question_bank::notify_question_edited($questionid);
|
| 824 |
|
722 |
|
| 825 |
$questions[] = (object) [
|
723 |
$questions[] = (object) [
|
| 826 |
'id' => $questionid,
|
724 |
'id' => $questionid,
|
| Línea 827... |
Línea -... |
| 827 |
'contextid' => $oldcontextid
|
- |
|
| 828 |
];
|
725 |
'contextid' => $oldcontextid
|
| Línea 829... |
Línea 726... |
| 829 |
}
|
726 |
];
|
| 830 |
|
727 |
}
|
| - |
|
728 |
|
| 831 |
$newcontext = context::instance_by_id($newcontextid);
|
729 |
question_move_question_tags_to_new_context($questions, $newcontext);
|
| 832 |
question_move_question_tags_to_new_context($questions, $newcontext);
|
730 |
|
| 833 |
|
731 |
$subcatids = $DB->get_records_menu('question_categories', ['parent' => $categoryid], '', 'id,1');
|
| 834 |
$subcatids = $DB->get_records_menu('question_categories', ['parent' => $categoryid], '', 'id,1');
|
732 |
foreach ($subcatids as $subcatid => $notused) {
|
| Línea 935... |
Línea 833... |
| 935 |
* Private function to factor common code out of get_question_options().
|
833 |
* Private function to factor common code out of get_question_options().
|
| 936 |
*
|
834 |
*
|
| 937 |
* @param object $question the question to tidy.
|
835 |
* @param object $question the question to tidy.
|
| 938 |
* @param stdClass $category The question_categories record for the given $question.
|
836 |
* @param stdClass $category The question_categories record for the given $question.
|
| 939 |
* @param \core_tag_tag[]|null $tagobjects The tags for the given $question.
|
837 |
* @param \core_tag_tag[]|null $tagobjects The tags for the given $question.
|
| 940 |
* @param stdClass[]|null $filtercourses The courses to filter the course tags by.
|
838 |
* @param stdClass[]|null $filtercourses deprecated argument and should not be used
|
| 941 |
*/
|
839 |
*/
|
| 942 |
function _tidy_question($question, $category, array $tagobjects = null, array $filtercourses = null): void {
|
840 |
function _tidy_question($question, $category, ?array $tagobjects = null, ?array $filtercourses = null): void {
|
| - |
|
841 |
|
| - |
|
842 |
if ($filtercourses !== null) {
|
| - |
|
843 |
debugging("Filtercourses is a deprecated argument in " . __FUNCTION__, DEBUG_DEVELOPER);
|
| - |
|
844 |
}
|
| - |
|
845 |
|
| 943 |
// Convert numeric fields to float. This prevents these being displayed as 1.0000000.
|
846 |
// Convert numeric fields to float. This prevents these being displayed as 1.0000000.
|
| 944 |
$question->defaultmark += 0;
|
847 |
$question->defaultmark += 0;
|
| 945 |
$question->penalty += 0;
|
848 |
$question->penalty += 0;
|
| Línea 946... |
Línea 849... |
| 946 |
|
849 |
|
| Línea 953... |
Línea 856... |
| 953 |
|
856 |
|
| 954 |
// Add any tags we have been passed.
|
857 |
// Add any tags we have been passed.
|
| 955 |
if (!is_null($tagobjects)) {
|
858 |
if (!is_null($tagobjects)) {
|
| 956 |
$categorycontext = context::instance_by_id($category->contextid);
|
859 |
$categorycontext = context::instance_by_id($category->contextid);
|
| 957 |
$sortedtagobjects = question_sort_tags($tagobjects, $categorycontext, $filtercourses);
|
- |
|
| 958 |
$question->coursetagobjects = $sortedtagobjects->coursetagobjects;
|
- |
|
| 959 |
$question->coursetags = $sortedtagobjects->coursetags;
|
860 |
$sortedtagobjects = question_sort_tags($tagobjects, $categorycontext, $filtercourses);
|
| 960 |
$question->tagobjects = $sortedtagobjects->tagobjects;
|
861 |
$question->tagobjects = $sortedtagobjects->tagobjects;
|
| 961 |
$question->tags = $sortedtagobjects->tags;
|
862 |
$question->tags = $sortedtagobjects->tags;
|
| Línea 962... |
Línea 863... |
| 962 |
}
|
863 |
}
|
| Línea 978... |
Línea 879... |
| 978 |
* question object.
|
879 |
* question object.
|
| 979 |
*
|
880 |
*
|
| 980 |
* @param mixed $questions Either an array of question objects to be updated
|
881 |
* @param mixed $questions Either an array of question objects to be updated
|
| 981 |
* or just a single question object
|
882 |
* or just a single question object
|
| 982 |
* @param bool $loadtags load the question tags from the tags table. Optional, default false.
|
883 |
* @param bool $loadtags load the question tags from the tags table. Optional, default false.
|
| 983 |
* @param stdClass[] $filtercourses The courses to filter the course tags by.
|
884 |
* @param stdClass[] $filtercourses deprecated argument and should not be used
|
| 984 |
* @return bool Indicates success or failure.
|
885 |
* @return bool Indicates success or failure.
|
| 985 |
*/
|
886 |
*/
|
| 986 |
function get_question_options(&$questions, $loadtags = false, $filtercourses = null) {
|
887 |
function get_question_options(&$questions, $loadtags = false, $filtercourses = null) {
|
| 987 |
global $DB;
|
888 |
global $DB;
|
| Línea -... |
Línea 889... |
| - |
|
889 |
|
| - |
|
890 |
if ($filtercourses !== null) {
|
| - |
|
891 |
debugging("Filtercourses is a deprecated argument in " . __FUNCTION__, DEBUG_DEVELOPER);
|
| - |
|
892 |
}
|
| 988 |
|
893 |
|
| 989 |
$questionlist = is_array($questions) ? $questions : [$questions];
|
894 |
$questionlist = is_array($questions) ? $questions : [$questions];
|
| 990 |
$categoryids = [];
|
895 |
$categoryids = [];
|
| Línea 991... |
Línea 896... |
| 991 |
$questionids = [];
|
896 |
$questionids = [];
|
| Línea 1037... |
Línea 942... |
| 1037 |
* This function also search tag instances that may have a context id that don't match either a course or
|
942 |
* This function also search tag instances that may have a context id that don't match either a course or
|
| 1038 |
* question context and fix the data setting the correct context id.
|
943 |
* question context and fix the data setting the correct context id.
|
| 1039 |
*
|
944 |
*
|
| 1040 |
* @param \core_tag_tag[] $tagobjects The tags for the given $question.
|
945 |
* @param \core_tag_tag[] $tagobjects The tags for the given $question.
|
| 1041 |
* @param stdClass $categorycontext The question categories context.
|
946 |
* @param stdClass $categorycontext The question categories context.
|
| 1042 |
* @param stdClass[]|null $filtercourses The courses to filter the course tags by.
|
947 |
* @param stdClass[]|null $filtercourses deprecated argument and should not be used.
|
| 1043 |
* @return stdClass $sortedtagobjects Sorted tag objects.
|
948 |
* @return stdClass $sortedtagobjects Sorted tag objects.
|
| 1044 |
*/
|
949 |
*/
|
| 1045 |
function question_sort_tags($tagobjects, $categorycontext, $filtercourses = null): stdClass {
|
950 |
function question_sort_tags($tagobjects, $categorycontext, $filtercourses = null): stdClass {
|
| Línea 1046... |
Línea 951... |
| 1046 |
|
951 |
|
| 1047 |
// Questions can have two sets of tag instances. One set at the
|
952 |
if ($filtercourses !== null) {
|
| 1048 |
// course context level and another at the context the question
|
953 |
debugging("Filtercourses is a deprecated argument in " . __FUNCTION__, DEBUG_DEVELOPER);
|
| - |
|
954 |
}
|
| 1049 |
// belongs to (e.g. course category, system etc).
|
955 |
|
| 1050 |
$sortedtagobjects = new stdClass();
|
- |
|
| 1051 |
$sortedtagobjects->coursetagobjects = [];
|
- |
|
| 1052 |
$sortedtagobjects->coursetags = [];
|
956 |
$sortedtagobjects = new stdClass();
|
| 1053 |
$sortedtagobjects->tagobjects = [];
|
957 |
$sortedtagobjects->tagobjects = [];
|
| 1054 |
$sortedtagobjects->tags = [];
|
958 |
$sortedtagobjects->tags = [];
|
| 1055 |
$taginstanceidstonormalise = [];
|
- |
|
| 1056 |
$filtercoursecontextids = [];
|
- |
|
| 1057 |
$hasfiltercourses = !empty($filtercourses);
|
- |
|
| 1058 |
|
- |
|
| 1059 |
if ($hasfiltercourses) {
|
- |
|
| 1060 |
// If we're being asked to filter the course tags by a set of courses
|
- |
|
| 1061 |
// then get the context ids to filter below.
|
- |
|
| 1062 |
$filtercoursecontextids = array_map(function($course) {
|
- |
|
| 1063 |
$coursecontext = context_course::instance($course->id);
|
- |
|
| 1064 |
return $coursecontext->id;
|
- |
|
| 1065 |
}, $filtercourses);
|
- |
|
| Línea 1066... |
Línea 959... |
| 1066 |
}
|
959 |
$taginstanceidstonormalise = [];
|
| 1067 |
|
960 |
|
| 1068 |
foreach ($tagobjects as $tagobject) {
|
961 |
foreach ($tagobjects as $tagobject) {
|
| 1069 |
$tagcontextid = $tagobject->taginstancecontextid;
|
- |
|
| 1070 |
$tagcontext = context::instance_by_id($tagcontextid);
|
- |
|
| 1071 |
$tagcoursecontext = $tagcontext->get_course_context(false);
|
- |
|
| 1072 |
// This is a course tag if the tag context is a course context which
|
- |
|
| 1073 |
// doesn't match the question's context. Any tag in the question context
|
- |
|
| 1074 |
// is not considered a course tag, it belongs to the question.
|
- |
|
| 1075 |
$iscoursetag = $tagcoursecontext
|
- |
|
| 1076 |
&& $tagcontext->id == $tagcoursecontext->id
|
- |
|
| 1077 |
&& $tagcontext->id != $categorycontext->id;
|
- |
|
| 1078 |
|
- |
|
| 1079 |
if ($iscoursetag) {
|
- |
|
| 1080 |
// Any tag instance in a course context level is considered a course tag.
|
- |
|
| 1081 |
if (!$hasfiltercourses || in_array($tagcontextid, $filtercoursecontextids)) {
|
- |
|
| 1082 |
// Add the tag to the list of course tags if we aren't being
|
- |
|
| 1083 |
// asked to filter or if this tag is in the list of courses
|
- |
|
| 1084 |
// we're being asked to filter by.
|
- |
|
| 1085 |
$sortedtagobjects->coursetagobjects[] = $tagobject;
|
- |
|
| 1086 |
$sortedtagobjects->coursetags[$tagobject->id] = $tagobject->get_display_name();
|
- |
|
| 1087 |
}
|
- |
|
| 1088 |
} else {
|
962 |
$tagcontextid = $tagobject->taginstancecontextid;
|
| 1089 |
// All non course context level tag instances or tags in the question
|
963 |
$tagcontext = context::instance_by_id($tagcontextid);
|
| 1090 |
// context belong to the context that the question was created in.
|
964 |
// All tag instances belong to the context that the question was created in.
|
| Línea 1091... |
Línea 965... |
| 1091 |
$sortedtagobjects->tagobjects[] = $tagobject;
|
965 |
$sortedtagobjects->tagobjects[] = $tagobject;
|
| 1092 |
$sortedtagobjects->tags[$tagobject->id] = $tagobject->get_display_name();
|
966 |
$sortedtagobjects->tags[$tagobject->id] = $tagobject->get_display_name();
|
| Línea 1100... |
Línea 974... |
| 1100 |
$taginstanceidstonormalise[] = $tagobject->taginstanceid;
|
974 |
$taginstanceidstonormalise[] = $tagobject->taginstanceid;
|
| 1101 |
// Update the object properties to reflect the DB update that will
|
975 |
// Update the object properties to reflect the DB update that will
|
| 1102 |
// happen below.
|
976 |
// happen below.
|
| 1103 |
$tagobject->taginstancecontextid = $categorycontext->id;
|
977 |
$tagobject->taginstancecontextid = $categorycontext->id;
|
| 1104 |
}
|
978 |
}
|
| 1105 |
}
|
979 |
|
| 1106 |
}
|
980 |
}
|
| Línea 1107... |
Línea 981... |
| 1107 |
|
981 |
|
| 1108 |
if (!empty($taginstanceidstonormalise)) {
|
982 |
if (!empty($taginstanceidstonormalise)) {
|
| 1109 |
// If we found any tag instances with incorrect context id data then we can
|
983 |
// If we found any tag instances with incorrect context id data then we can
|
| Línea 1176... |
Línea 1050... |
| 1176 |
}
|
1050 |
}
|
| 1177 |
return $children;
|
1051 |
return $children;
|
| 1178 |
}
|
1052 |
}
|
| Línea 1179... |
Línea 1053... |
| 1179 |
|
1053 |
|
| 1180 |
/**
|
1054 |
/**
|
| 1181 |
* Get the default category for the context.
|
1055 |
* Get the default category for the context. Optionally create one if it does not exist.
|
| 1182 |
*
|
1056 |
*
|
| - |
|
1057 |
* @param int $contextid a context id.
|
| 1183 |
* @param integer $contextid a context id.
|
1058 |
* @param bool $createifnotexists create the default catagory if it does not exist.
|
| 1184 |
* @return object|bool the default question category for that context, or false if none.
|
1059 |
* @return stdClass|bool the default question category for that context, or false if none.
|
| 1185 |
*/
|
1060 |
*/
|
| 1186 |
function question_get_default_category($contextid) {
|
1061 |
function question_get_default_category($contextid, bool $createifnotexists = false) {
|
| - |
|
1062 |
global $DB;
|
| 1187 |
global $DB;
|
1063 |
|
| 1188 |
$category = $DB->get_records_select('question_categories', 'contextid = ? AND parent <> 0',
|
1064 |
$context = \core\context::instance_by_id($contextid);
|
| 1189 |
[$contextid], 'id', '*', 0, 1);
|
1065 |
if ($context->contextlevel !== CONTEXT_MODULE) {
|
| - |
|
1066 |
debugging(
|
| 1190 |
if (!empty($category)) {
|
1067 |
"Invalid context level {$context->contextlevel} for default category. Please use CONTEXT_MODULE",
|
| 1191 |
return reset($category);
|
1068 |
DEBUG_DEVELOPER
|
| 1192 |
} else {
|
1069 |
);
|
| 1193 |
return false;
|
1070 |
return false;
|
| - |
|
1071 |
}
|
| - |
|
1072 |
|
| - |
|
1073 |
$defaultcats = $DB->get_records_select('question_categories', 'contextid = ? AND parent <> 0', [$contextid], 'id', '*', 0, 1);
|
| - |
|
1074 |
|
| - |
|
1075 |
$defaultcat = reset($defaultcats);
|
| - |
|
1076 |
|
| - |
|
1077 |
if (empty($defaultcat) && $createifnotexists) {
|
| - |
|
1078 |
|
| - |
|
1079 |
// We need to make a top category first if it doesn't exist.
|
| - |
|
1080 |
$topcategory = question_get_top_category($context->id, true);
|
| - |
|
1081 |
|
| - |
|
1082 |
// We don't have one, so we need to make one.
|
| - |
|
1083 |
$defaultcat = new stdClass();
|
| - |
|
1084 |
$contextname = $context->get_context_name(false, true);
|
| - |
|
1085 |
// Max length of name field is 255.
|
| - |
|
1086 |
$defaultcat->name = shorten_text(get_string('defaultfor', 'question', $contextname), 255);
|
| - |
|
1087 |
$defaultcat->info = get_string('defaultinfofor', 'question', $contextname);
|
| - |
|
1088 |
$defaultcat->contextid = $context->id;
|
| - |
|
1089 |
$defaultcat->parent = $topcategory->id;
|
| - |
|
1090 |
// By default, all categories get this number, and are sorted alphabetically.
|
| - |
|
1091 |
$defaultcat->sortorder = 999;
|
| - |
|
1092 |
$defaultcat->stamp = make_unique_id_code();
|
| - |
|
1093 |
$defaultcat->id = $DB->insert_record('question_categories', $defaultcat);
|
| - |
|
1094 |
}
|
| - |
|
1095 |
|
| 1194 |
}
|
1096 |
return $defaultcat;
|
| Línea 1195... |
Línea 1097... |
| 1195 |
}
|
1097 |
}
|
| 1196 |
|
1098 |
|
| 1197 |
/**
|
1099 |
/**
|
| Línea 1204... |
Línea 1106... |
| 1204 |
*/
|
1106 |
*/
|
| 1205 |
function question_get_top_category($contextid, $create = false) {
|
1107 |
function question_get_top_category($contextid, $create = false) {
|
| 1206 |
global $DB;
|
1108 |
global $DB;
|
| 1207 |
$category = $DB->get_record('question_categories', ['contextid' => $contextid, 'parent' => 0]);
|
1109 |
$category = $DB->get_record('question_categories', ['contextid' => $contextid, 'parent' => 0]);
|
| Línea -... |
Línea 1110... |
| - |
|
1110 |
|
| - |
|
1111 |
$context = context::instance_by_id($contextid);
|
| - |
|
1112 |
if ($context->contextlevel !== CONTEXT_MODULE) {
|
| - |
|
1113 |
debugging(
|
| - |
|
1114 |
"Invalid context level: {$context->contextlevel} for question_get_top_category, must be CONTEXT_MODULE",
|
| - |
|
1115 |
DEBUG_DEVELOPER
|
| - |
|
1116 |
);
|
| - |
|
1117 |
return false;
|
| - |
|
1118 |
}
|
| 1208 |
|
1119 |
|
| 1209 |
if (!$category && $create) {
|
1120 |
if (!$category && $create) {
|
| 1210 |
// We need to make one.
|
1121 |
// We need to make one.
|
| 1211 |
$category = new stdClass();
|
1122 |
$category = new stdClass();
|
| 1212 |
$category->name = 'top'; // A non-real name for the top category. It will be localised at the display time.
|
1123 |
$category->name = 'top'; // A non-real name for the top category. It will be localised at the display time.
|
| Línea 1241... |
Línea 1152... |
| 1241 |
|
1152 |
|
| 1242 |
return $topcategories;
|
1153 |
return $topcategories;
|
| Línea 1243... |
Línea 1154... |
| 1243 |
}
|
1154 |
}
|
| 1244 |
|
- |
|
| 1245 |
/**
|
- |
|
| 1246 |
* Gets the default category in the most specific context.
|
- |
|
| 1247 |
* If no categories exist yet then default ones are created in all contexts.
|
- |
|
| 1248 |
*
|
- |
|
| 1249 |
* @param array $contexts The context objects for this context and all parent contexts.
|
- |
|
| 1250 |
* @return object The default category - the category in the course context
|
- |
|
| 1251 |
*/
|
- |
|
| 1252 |
function question_make_default_categories($contexts): object {
|
- |
|
| 1253 |
global $DB;
|
- |
|
| 1254 |
static $preferredlevels = array(
|
- |
|
| 1255 |
CONTEXT_COURSE => 4,
|
- |
|
| 1256 |
CONTEXT_MODULE => 3,
|
- |
|
| 1257 |
CONTEXT_COURSECAT => 2,
|
- |
|
| 1258 |
CONTEXT_SYSTEM => 1,
|
- |
|
| 1259 |
);
|
- |
|
| 1260 |
|
- |
|
| 1261 |
$toreturn = null;
|
- |
|
| 1262 |
$preferredness = 0;
|
- |
|
| 1263 |
// If it already exists, just return it.
|
- |
|
| 1264 |
foreach ($contexts as $key => $context) {
|
- |
|
| 1265 |
$topcategory = question_get_top_category($context->id, true);
|
- |
|
| 1266 |
if (!$exists = $DB->record_exists("question_categories",
|
- |
|
| 1267 |
array('contextid' => $context->id, 'parent' => $topcategory->id))) {
|
- |
|
| 1268 |
// Otherwise, we need to make one.
|
- |
|
| 1269 |
$category = new stdClass();
|
- |
|
| 1270 |
$contextname = $context->get_context_name(false, true);
|
- |
|
| 1271 |
// Max length of name field is 255.
|
- |
|
| 1272 |
$category->name = shorten_text(get_string('defaultfor', 'question', $contextname), 255);
|
- |
|
| 1273 |
$category->info = get_string('defaultinfofor', 'question', $contextname);
|
- |
|
| 1274 |
$category->contextid = $context->id;
|
- |
|
| 1275 |
$category->parent = $topcategory->id;
|
- |
|
| 1276 |
// By default, all categories get this number, and are sorted alphabetically.
|
- |
|
| 1277 |
$category->sortorder = 999;
|
- |
|
| 1278 |
$category->stamp = make_unique_id_code();
|
- |
|
| 1279 |
$category->id = $DB->insert_record('question_categories', $category);
|
- |
|
| 1280 |
} else {
|
- |
|
| 1281 |
$category = question_get_default_category($context->id);
|
- |
|
| 1282 |
}
|
- |
|
| 1283 |
$thispreferredness = $preferredlevels[$context->contextlevel];
|
- |
|
| 1284 |
if (has_any_capability(array('moodle/question:usemine', 'moodle/question:useall'), $context)) {
|
- |
|
| 1285 |
$thispreferredness += 10;
|
- |
|
| 1286 |
}
|
- |
|
| 1287 |
if ($thispreferredness > $preferredness) {
|
- |
|
| 1288 |
$toreturn = $category;
|
- |
|
| 1289 |
$preferredness = $thispreferredness;
|
- |
|
| 1290 |
}
|
- |
|
| 1291 |
}
|
- |
|
| 1292 |
|
- |
|
| 1293 |
if (!is_null($toreturn)) {
|
- |
|
| 1294 |
$toreturn = clone($toreturn);
|
- |
|
| 1295 |
}
|
- |
|
| 1296 |
return $toreturn;
|
- |
|
| 1297 |
}
|
- |
|
| 1298 |
|
1155 |
|
| 1299 |
/**
|
1156 |
/**
|
| 1300 |
* Get the list of categories.
|
1157 |
* Get the list of categories.
|
| 1301 |
*
|
1158 |
*
|
| 1302 |
* @param int $categoryid
|
1159 |
* @param int $categoryid
|
| Línea 1420... |
Línea 1277... |
| 1420 |
/**
|
1277 |
/**
|
| 1421 |
* Check capability on category.
|
1278 |
* Check capability on category.
|
| 1422 |
*
|
1279 |
*
|
| 1423 |
* @param int|stdClass|question_definition $questionorid object or id.
|
1280 |
* @param int|stdClass|question_definition $questionorid object or id.
|
| 1424 |
* If an object is passed, it should include ->contextid and ->createdby.
|
1281 |
* If an object is passed, it should include ->contextid and ->createdby.
|
| 1425 |
* @param string $cap 'add', 'edit', 'view', 'use', 'move' or 'tag'.
|
1282 |
* @param string $cap 'add', 'edit', 'view', 'use', 'move', or 'tag'.
|
| 1426 |
* @param int $notused no longer used.
|
1283 |
* @param int $notused no longer used.
|
| 1427 |
* @return bool this user has the capability $cap for this question $question?
|
1284 |
* @return bool this user has the capability $cap for this question $question?
|
| 1428 |
*/
|
1285 |
*/
|
| 1429 |
function question_has_capability_on($questionorid, $cap, $notused = -1): bool {
|
1286 |
function question_has_capability_on($questionorid, $cap, $notused = -1): bool {
|
| 1430 |
global $USER, $DB;
|
1287 |
global $USER, $DB;
|
| Línea 1511... |
Línea 1368... |
| 1511 |
function question_edit_url($context) {
|
1368 |
function question_edit_url($context) {
|
| 1512 |
global $CFG, $SITE;
|
1369 |
global $CFG, $SITE;
|
| 1513 |
if (!has_any_capability(question_get_question_capabilities(), $context)) {
|
1370 |
if (!has_any_capability(question_get_question_capabilities(), $context)) {
|
| 1514 |
return false;
|
1371 |
return false;
|
| 1515 |
}
|
1372 |
}
|
| - |
|
1373 |
|
| - |
|
1374 |
if ($context->contextlevel !== CONTEXT_MODULE) {
|
| - |
|
1375 |
debugging(
|
| - |
|
1376 |
"Invalid contextlevel: {$context->contextlevel} provided for question_edit_url, must be CONTEXT_MODULE",
|
| - |
|
1377 |
DEBUG_DEVELOPER
|
| - |
|
1378 |
);
|
| - |
|
1379 |
return false;
|
| - |
|
1380 |
}
|
| - |
|
1381 |
|
| 1516 |
$baseurl = $CFG->wwwroot . '/question/edit.php?';
|
1382 |
$baseurl = $CFG->wwwroot . '/question/edit.php?';
|
| 1517 |
$defaultcategory = question_get_default_category($context->id);
|
1383 |
$defaultcategory = question_get_default_category($context->id, true);
|
| 1518 |
if ($defaultcategory) {
|
1384 |
if ($defaultcategory) {
|
| 1519 |
$baseurl .= 'cat=' . $defaultcategory->id . ',' . $context->id . '&';
|
1385 |
$baseurl .= 'cat=' . $defaultcategory->id . ',' . $context->id . '&';
|
| 1520 |
}
|
1386 |
}
|
| 1521 |
switch ($context->contextlevel) {
|
1387 |
switch ($context->contextlevel) {
|
| 1522 |
case CONTEXT_SYSTEM:
|
1388 |
case CONTEXT_SYSTEM:
|
| Línea 1529... |
Línea 1395... |
| 1529 |
return $baseurl . 'courseid=' . $context->instanceid;
|
1395 |
return $baseurl . 'courseid=' . $context->instanceid;
|
| 1530 |
case CONTEXT_MODULE:
|
1396 |
case CONTEXT_MODULE:
|
| 1531 |
return $baseurl . 'cmid=' . $context->instanceid;
|
1397 |
return $baseurl . 'cmid=' . $context->instanceid;
|
| 1532 |
}
|
1398 |
}
|
| Línea -... |
Línea 1399... |
| - |
|
1399 |
|
| 1533 |
|
1400 |
return $baseurl . 'cmid=' . $context->instanceid;
|
| Línea 1534... |
Línea 1401... |
| 1534 |
}
|
1401 |
}
|
| 1535 |
|
1402 |
|
| 1536 |
/**
|
1403 |
/**
|
| Línea 1545... |
Línea 1412... |
| 1545 |
* @return navigation_node Returns the question branch that was added
|
1412 |
* @return navigation_node Returns the question branch that was added
|
| 1546 |
*/
|
1413 |
*/
|
| 1547 |
function question_extend_settings_navigation(navigation_node $navigationnode, $context, $baseurl = '/question/edit.php') {
|
1414 |
function question_extend_settings_navigation(navigation_node $navigationnode, $context, $baseurl = '/question/edit.php') {
|
| 1548 |
global $PAGE;
|
1415 |
global $PAGE;
|
| Línea 1549... |
Línea 1416... |
| 1549 |
|
1416 |
|
| - |
|
1417 |
$iscourse = $context->contextlevel === CONTEXT_COURSE;
|
| - |
|
1418 |
|
| 1550 |
if ($context->contextlevel == CONTEXT_COURSE) {
|
1419 |
if ($iscourse) {
|
| 1551 |
$params = ['courseid' => $context->instanceid];
|
1420 |
$params = ['courseid' => $context->instanceid];
|
| 1552 |
} else if ($context->contextlevel == CONTEXT_MODULE) {
|
1421 |
} else if ($context->contextlevel == CONTEXT_MODULE) {
|
| 1553 |
$params = ['cmid' => $context->instanceid];
|
1422 |
$params = ['cmid' => $context->instanceid];
|
| 1554 |
} else {
|
1423 |
} else {
|
| Línea 1557... |
Línea 1426... |
| 1557 |
|
1426 |
|
| 1558 |
if (($cat = $PAGE->url->param('cat')) && preg_match('~\d+,\d+~', $cat)) {
|
1427 |
if (($cat = $PAGE->url->param('cat')) && preg_match('~\d+,\d+~', $cat)) {
|
| 1559 |
$params['cat'] = $cat;
|
1428 |
$params['cat'] = $cat;
|
| Línea 1560... |
Línea 1429... |
| 1560 |
}
|
1429 |
}
|
| 1561 |
|
1430 |
|
| Línea 1562... |
Línea 1431... |
| 1562 |
$questionnode = $navigationnode->add(get_string('questionbank', 'question'),
|
1431 |
$questionnode = $navigationnode->add(get_string($iscourse ? 'questionbank_plural' : 'questionbank', 'question'),
|
| 1563 |
new moodle_url($baseurl, $params), navigation_node::TYPE_CONTAINER, null, 'questionbank');
|
1432 |
new moodle_url($baseurl, $params), navigation_node::TYPE_CONTAINER, null, 'questionbank');
|
| 1564 |
|
1433 |
|
| Línea 1690... |
Línea 1559... |
| 1690 |
* @param int $itemid item ID
|
1559 |
* @param int $itemid item ID
|
| 1691 |
* @param array $options options
|
1560 |
* @param array $options options
|
| 1692 |
* @return string
|
1561 |
* @return string
|
| 1693 |
*/
|
1562 |
*/
|
| 1694 |
function question_rewrite_question_urls($text, $file, $contextid, $component, $filearea,
|
1563 |
function question_rewrite_question_urls($text, $file, $contextid, $component, $filearea,
|
| 1695 |
array $ids, $itemid, array $options=null): string {
|
1564 |
array $ids, $itemid, ?array $options=null): string {
|
| Línea 1696... |
Línea 1565... |
| 1696 |
|
1565 |
|
| 1697 |
$idsstr = '';
|
1566 |
$idsstr = '';
|
| 1698 |
if (!empty($ids)) {
|
1567 |
if (!empty($ids)) {
|
| 1699 |
$idsstr .= implode('/', $ids);
|
1568 |
$idsstr .= implode('/', $ids);
|