/**
  * Moves a course into a category.
  * @param int $courseid the id of the course to move
  * @param int $categoryid the id of the target category to move the course to
  * @return bool success
  */
 public static function update_course_category($courseid, $categoryid)
 {
     global $USER;
     $params = self::validate_parameters(self::update_course_category_parameters(), array('courseid' => $courseid, 'categoryid' => $categoryid));
     $context = context_user::instance($USER->id);
     self::validate_context($context);
     if (!has_capability('local/webservice:local_ws_update_course_category', $context)) {
         throw new moodle_exception(nocapabilitytousethisservice);
     }
     if ($courseid == 1) {
         echo "Cannot move course 1 (site).\n";
         throw new moodle_exception(cannotmovecourses);
     }
     echo "Moving course {$courseid} to category {$categoryid}.\n";
     return move_courses(array($courseid), $categoryid);
 }
Esempio n. 2
0
     $courses = array();
     foreach ($data as $key => $value) {
         if (preg_match('/^c\\d+$/', $key)) {
             $courseid = substr($key, 1);
             array_push($courses, $courseid);
             // check this course's category
             if ($movingcourse = $DB->get_record('course', array('id' => $courseid))) {
                 if ($movingcourse->category != $id) {
                     print_error('coursedoesnotbelongtocategory');
                 }
             } else {
                 print_error('cannotfindcourse');
             }
         }
     }
     move_courses($courses, $data->moveto);
 }
 /// Hide or show a course
 if ((!empty($hide) or !empty($show)) and confirm_sesskey()) {
     if (!empty($hide)) {
         $course = $DB->get_record('course', array('id' => $hide));
         $visible = 0;
     } else {
         $course = $DB->get_record('course', array('id' => $show));
         $visible = 1;
     }
     if ($course) {
         $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
         require_capability('moodle/course:visibility', $coursecontext);
         $DB->set_field('course', 'visible', $visible, array('id' => $course->id));
         $DB->set_field('course', 'visibleold', $visible, array('id' => $course->id));
Esempio n. 3
0
/**
 * Delete category, but move contents to another category.
 * @param object $ccategory
 * @param int $newparentid category id
 * @return bool status
 */
function category_delete_move($category, $newparentid, $showfeedback = true)
{
    global $CFG, $DB, $OUTPUT;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/questionlib.php';
    require_once $CFG->dirroot . '/cohort/lib.php';
    if (!($newparentcat = $DB->get_record('course_categories', array('id' => $newparentid)))) {
        return false;
    }
    if ($children = $DB->get_records('course_categories', array('parent' => $category->id), 'sortorder ASC')) {
        foreach ($children as $childcat) {
            move_category($childcat, $newparentcat);
        }
    }
    if ($courses = $DB->get_records('course', array('category' => $category->id), 'sortorder ASC', 'id')) {
        if (!move_courses(array_keys($courses), $newparentid)) {
            echo $OUTPUT->notification("Error moving courses");
            return false;
        }
        echo $OUTPUT->notification(get_string('coursesmovedout', '', format_string($category->name)), 'notifysuccess');
    }
    // move or delete cohorts in this context
    cohort_delete_category($category);
    // now delete anything that may depend on course category context
    grade_course_category_delete($category->id, $newparentid, $showfeedback);
    if (!question_delete_course_category($category, $newparentcat, $showfeedback)) {
        echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $category), 'notifysuccess');
        return false;
    }
    // finally delete the category and it's context
    $DB->delete_records('course_categories', array('id' => $category->id));
    delete_context(CONTEXT_COURSECAT, $category->id);
    events_trigger('course_category_deleted', $category);
    echo $OUTPUT->notification(get_string('coursecategorydeleted', '', format_string($category->name)), 'notifysuccess');
    return true;
}
 /**
  * Deletes a category and moves all content (children, courses and questions) to the new parent
  *
  * Note that this function does not check capabilities, {@link coursecat::can_move_content_to()}
  * must be called prior
  *
  * @param int $newparentid
  * @param bool $showfeedback
  * @return bool
  */
 public function delete_move($newparentid, $showfeedback = false)
 {
     global $CFG, $DB, $OUTPUT;
     require_once $CFG->libdir . '/gradelib.php';
     require_once $CFG->libdir . '/questionlib.php';
     require_once $CFG->dirroot . '/cohort/lib.php';
     // Get all objects and lists because later the caches will be reset so.
     // We don't need to make extra queries.
     $newparentcat = self::get($newparentid, MUST_EXIST, true);
     $catname = $this->get_formatted_name();
     $children = $this->get_children();
     $params = array('category' => $this->id);
     $coursesids = $DB->get_fieldset_select('course', 'id', 'category = :category ORDER BY sortorder ASC', $params);
     $context = $this->get_context();
     if ($children) {
         foreach ($children as $childcat) {
             $childcat->change_parent_raw($newparentcat);
             // Log action.
             $event = \core\event\course_category_updated::create(array('objectid' => $childcat->id, 'context' => $childcat->get_context()));
             $event->set_legacy_logdata(array(SITEID, 'category', 'move', 'editcategory.php?id=' . $childcat->id, $childcat->id));
             $event->trigger();
         }
         fix_course_sortorder();
     }
     if ($coursesids) {
         if (!move_courses($coursesids, $newparentid)) {
             if ($showfeedback) {
                 echo $OUTPUT->notification("Error moving courses");
             }
             return false;
         }
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('coursesmovedout', '', $catname), 'notifysuccess');
         }
     }
     // Move or delete cohorts in this context.
     cohort_delete_category($this);
     // Now delete anything that may depend on course category context.
     grade_course_category_delete($this->id, $newparentid, $showfeedback);
     if (!question_delete_course_category($this, $newparentcat, $showfeedback)) {
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $catname), 'notifysuccess');
         }
         return false;
     }
     // Finally delete the category and it's context.
     $DB->delete_records('course_categories', array('id' => $this->id));
     $context->delete();
     // Trigger a course category deleted event.
     /* @var \core\event\course_category_deleted $event */
     $event = \core\event\course_category_deleted::create(array('objectid' => $this->id, 'context' => $context, 'other' => array('name' => $this->name)));
     $event->set_coursecat($this);
     $event->trigger();
     cache_helper::purge_by_event('changesincoursecat');
     if ($showfeedback) {
         echo $OUTPUT->notification(get_string('coursecategorydeleted', '', $catname), 'notifysuccess');
     }
     // If we deleted $CFG->defaultrequestcategory, make it point somewhere else.
     if ($this->id == $CFG->defaultrequestcategory) {
         set_config('defaultrequestcategory', $DB->get_field('course_categories', 'MIN(id)', array('parent' => 0)));
     }
     return true;
 }
Esempio n. 5
0
 /**
  * Test that triggering a course_updated event works as expected.
  */
 public function test_course_updated_event()
 {
     global $DB;
     $this->resetAfterTest();
     // Create a course.
     $course = $this->getDataGenerator()->create_course();
     // Create a category we are going to move this course to.
     $category = $this->getDataGenerator()->create_category();
     // Create a hidden category we are going to move this course to.
     $categoryhidden = $this->getDataGenerator()->create_category(array('visible' => 0));
     // Update course and catch course_updated event.
     $sink = $this->redirectEvents();
     update_course($course);
     $events = $sink->get_events();
     $sink->close();
     // Get updated course information from the DB.
     $updatedcourse = $DB->get_record('course', array('id' => $course->id), '*', MUST_EXIST);
     // Validate event.
     $event = array_shift($events);
     $this->assertInstanceOf('\\core\\event\\course_updated', $event);
     $this->assertEquals('course', $event->objecttable);
     $this->assertEquals($updatedcourse->id, $event->objectid);
     $this->assertEquals(context_course::instance($course->id), $event->get_context());
     $url = new moodle_url('/course/edit.php', array('id' => $event->objectid));
     $this->assertEquals($url, $event->get_url());
     $this->assertEquals($updatedcourse, $event->get_record_snapshot('course', $event->objectid));
     $this->assertEquals('course_updated', $event->get_legacy_eventname());
     $this->assertEventLegacyData($updatedcourse, $event);
     $expectedlog = array($updatedcourse->id, 'course', 'update', 'edit.php?id=' . $course->id, $course->id);
     $this->assertEventLegacyLogData($expectedlog, $event);
     // Move course and catch course_updated event.
     $sink = $this->redirectEvents();
     move_courses(array($course->id), $category->id);
     $events = $sink->get_events();
     $sink->close();
     // Return the moved course information from the DB.
     $movedcourse = $DB->get_record('course', array('id' => $course->id), '*', MUST_EXIST);
     // Validate event.
     $event = array_shift($events);
     $this->assertInstanceOf('\\core\\event\\course_updated', $event);
     $this->assertEquals('course', $event->objecttable);
     $this->assertEquals($movedcourse->id, $event->objectid);
     $this->assertEquals(context_course::instance($course->id), $event->get_context());
     $this->assertEquals($movedcourse, $event->get_record_snapshot('course', $movedcourse->id));
     $this->assertEquals('course_updated', $event->get_legacy_eventname());
     $this->assertEventLegacyData($movedcourse, $event);
     $expectedlog = array($movedcourse->id, 'course', 'move', 'edit.php?id=' . $movedcourse->id, $movedcourse->id);
     $this->assertEventLegacyLogData($expectedlog, $event);
     // Move course to hidden category and catch course_updated event.
     $sink = $this->redirectEvents();
     move_courses(array($course->id), $categoryhidden->id);
     $events = $sink->get_events();
     $sink->close();
     // Return the moved course information from the DB.
     $movedcoursehidden = $DB->get_record('course', array('id' => $course->id), '*', MUST_EXIST);
     // Validate event.
     $event = array_shift($events);
     $this->assertInstanceOf('\\core\\event\\course_updated', $event);
     $this->assertEquals('course', $event->objecttable);
     $this->assertEquals($movedcoursehidden->id, $event->objectid);
     $this->assertEquals(context_course::instance($course->id), $event->get_context());
     $this->assertEquals($movedcoursehidden, $event->get_record_snapshot('course', $movedcoursehidden->id));
     $this->assertEquals('course_updated', $event->get_legacy_eventname());
     $this->assertEventLegacyData($movedcoursehidden, $event);
     $expectedlog = array($movedcoursehidden->id, 'course', 'move', 'edit.php?id=' . $movedcoursehidden->id, $movedcoursehidden->id);
     $this->assertEventLegacyLogData($expectedlog, $event);
     $this->assertEventContextNotUsed($event);
 }
Esempio n. 6
0
 /**
  * Deletes a category and moves all content (children, courses and questions) to the new parent
  *
  * Note that this function does not check capabilities, {@link coursecat::can_move_content_to()}
  * must be called prior
  *
  * @param int $newparentid
  * @param bool $showfeedback
  * @return bool
  */
 public function delete_move($newparentid, $showfeedback = false)
 {
     global $CFG, $DB, $OUTPUT;
     require_once $CFG->libdir . '/gradelib.php';
     require_once $CFG->libdir . '/questionlib.php';
     require_once $CFG->dirroot . '/cohort/lib.php';
     // get all objects and lists because later the caches will be reset so
     // we don't need to make extra queries
     $newparentcat = self::get($newparentid, MUST_EXIST, true);
     $catname = $this->get_formatted_name();
     $children = $this->get_children();
     $coursesids = $DB->get_fieldset_select('course', 'id', 'category = :category ORDER BY sortorder ASC', array('category' => $this->id));
     $context = context_coursecat::instance($this->id);
     if ($children) {
         foreach ($children as $childcat) {
             $childcat->change_parent_raw($newparentcat);
             // Log action.
             add_to_log(SITEID, "category", "move", "editcategory.php?id={$childcat->id}", $childcat->id);
         }
         fix_course_sortorder();
     }
     if ($coursesids) {
         if (!move_courses($coursesids, $newparentid)) {
             if ($showfeedback) {
                 echo $OUTPUT->notification("Error moving courses");
             }
             return false;
         }
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('coursesmovedout', '', $catname), 'notifysuccess');
         }
     }
     // move or delete cohorts in this context
     cohort_delete_category($this);
     // now delete anything that may depend on course category context
     grade_course_category_delete($this->id, $newparentid, $showfeedback);
     if (!question_delete_course_category($this, $newparentcat, $showfeedback)) {
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $catname), 'notifysuccess');
         }
         return false;
     }
     // finally delete the category and it's context
     $DB->delete_records('course_categories', array('id' => $this->id));
     $context->delete();
     add_to_log(SITEID, "category", "delete", "index.php", "{$this->name} (ID {$this->id})");
     events_trigger('course_category_deleted', $this);
     cache_helper::purge_by_event('changesincoursecat');
     if ($showfeedback) {
         echo $OUTPUT->notification(get_string('coursecategorydeleted', '', $catname), 'notifysuccess');
     }
     // If we deleted $CFG->defaultrequestcategory, make it point somewhere else.
     if ($this->id == $CFG->defaultrequestcategory) {
         set_config('defaultrequestcategory', $DB->get_field('course_categories', 'MIN(id)', array('parent' => 0)));
     }
     return true;
 }
Esempio n. 7
0
    require_capability('moodle/course:create', context_coursecat::instance($moveto));
    foreach ($data as $key => $value) {
        if (preg_match('/^c\\d+$/', $key)) {
            $courseid = substr($key, 1);
            // user must have category:manage and course:create capability for the course to be moved.
            $coursecontext = context_course::instance($courseid);
            foreach ($capabilities as $capability) {
                // Require capability here will result in a fatal error should the user not
                // have the requried category ensuring that no moves occur if they are
                // trying to move multiple courses.
                require_capability($capability, $coursecontext);
                array_push($courses, $courseid);
            }
        }
    }
    move_courses($courses, $moveto);
}
// get list of courses containing blocks if required
if (!empty($blocklist) and confirm_sesskey()) {
    $blockname = $DB->get_field('block', 'name', array('id' => $blocklist));
    $courses = array();
    list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
    $sql = "SELECT c.* {$select} FROM {course} c\n            {$join} JOIN {block_instances} bi ON bi.parentcontextid = ctx.id\n            WHERE bi.blockname = ?";
    $courses = $DB->get_records_sql($sql, array($blockname));
    $totalcount = count($courses);
    // Keep only chunk of array which you want to display
    if ($totalcount > $perpage) {
        $courses = array_chunk($courses, $perpage, true);
        $courses = $courses[$page];
    }
    foreach ($courses as $course) {
Esempio n. 8
0
<?php

/*
 * SELECT *  FROM `mdl_context` WHERE `path` LIKE '/1/4862/4863%' and contextlevel=50
 * 
 */
define('CLI_SCRIPT', 1);
require_once 'config.php';
require_once $CFG->dirroot . '/course/lib.php';
$sql = "SELECT  *  \n        FROM    {context} \n        WHERE   path LIKE '/1/4862/4863%' AND \n                contextlevel=50";
$results = $DB->get_records_sql($sql);
echo 'found ' . count($results) . ' records';
// build array of courseids to move
$courses = array();
foreach ($results as $result) {
    $courses[] = $result->instanceid;
}
move_courses($courses, 66);
echo 'Done!';
Esempio n. 9
0
 /**
  * Moves one or more courses out of the category they are currently in and into a new category.
  *
  * This function works much the same way as action_category_move_courses_into however it allows courses from multiple
  * categories to be moved into a single category.
  *
  * @param int|\coursecat $categoryorid The category to move them into.
  * @param array|int $courseids An array of course id's or optionally just a single course id.
  * @return bool True on success or false on failure.
  * @throws \moodle_exception
  */
 public static function move_courses_into_category($categoryorid, $courseids = array())
 {
     global $DB;
     if (!is_array($courseids)) {
         // Just a single course ID.
         $courseids = array($courseids);
     }
     // Bulk move courses from one category to another.
     if (count($courseids) === 0) {
         return false;
     }
     if ($categoryorid instanceof \coursecat) {
         $moveto = $categoryorid;
     } else {
         $moveto = \coursecat::get($categoryorid);
     }
     if (!$moveto->can_move_courses_out_of() || !$moveto->can_move_courses_into()) {
         throw new \moodle_exception('cannotmovecourses');
     }
     list($where, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
     $sql = "SELECT c.id, c.category FROM {course} c WHERE c.id {$where}";
     $courses = $DB->get_records_sql($sql, $params);
     $checks = array();
     foreach ($courseids as $id) {
         if (!isset($courses[$id])) {
             throw new \moodle_exception('invalidcourseid');
         }
         $catid = $courses[$id]->category;
         if (!isset($checks[$catid])) {
             $coursecat = \coursecat::get($catid);
             $checks[$catid] = $coursecat->can_move_courses_out_of() && $coursecat->can_move_courses_into();
         }
         if (!$checks[$catid]) {
             throw new \moodle_exception('cannotmovecourses');
         }
     }
     return \move_courses($courseids, $moveto->id);
 }
Esempio n. 10
0
/**
 * Delete category, but move contents to another category.
 * @param object $ccategory
 * @param int $newparentid category id
 * @return bool status
 */
function category_delete_move($category, $newparentid, $showfeedback = true)
{
    global $CFG;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/questionlib.php';
    if (!($newparentcat = get_record('course_categories', 'id', $newparentid))) {
        return false;
    }
    if ($children = get_records('course_categories', 'parent', $category->id, 'sortorder ASC')) {
        foreach ($children as $childcat) {
            if (!move_category($childcat, $newparentcat)) {
                notify("Error moving category {$childcat->name}");
                return false;
            }
        }
    }
    if ($courses = get_records('course', 'category', $category->id, 'sortorder ASC', 'id')) {
        if (!move_courses(array_keys($courses), $newparentid)) {
            notify("Error moving courses");
            return false;
        }
        notify(get_string('coursesmovedout', '', format_string($category->name)), 'notifysuccess');
    }
    // now delete anything that may depend on course category context
    grade_course_category_delete($category->id, $newparentid, $showfeedback);
    if (!question_delete_course_category($category, $newparentcat, $showfeedback)) {
        notify(get_string('errordeletingquestionsfromcategory', 'question', $category), 'notifysuccess');
        return false;
    }
    // finally delete the category and it's context
    delete_records('course_categories', 'id', $category->id);
    delete_context(CONTEXT_COURSECAT, $category->id);
    events_trigger('course_category_deleted', $category);
    notify(get_string('coursecategorydeleted', '', format_string($category->name)), 'notifysuccess');
    return true;
}