Ejemplo n.º 1
3
 /**
  * Reset contents of all database tables to initial values, reset caches, etc.
  *
  * Note: this is relatively slow (cca 2 seconds for pg and 7 for mysql) - please use with care!
  *
  * @static
  * @param bool $detectchanges
  *      true  - changes in global state and database are reported as errors
  *      false - no errors reported
  *      null  - only critical problems are reported as errors
  * @return void
  */
 public static function reset_all_data($detectchanges = false)
 {
     global $DB, $CFG, $USER, $SITE, $COURSE, $PAGE, $OUTPUT, $SESSION;
     // Stop any message redirection.
     phpunit_util::stop_message_redirection();
     // Stop any message redirection.
     phpunit_util::stop_phpmailer_redirection();
     // Stop any message redirection.
     phpunit_util::stop_event_redirection();
     // We used to call gc_collect_cycles here to ensure desctructors were called between tests.
     // This accounted for 25% of the total time running phpunit - so we removed it.
     // Show any unhandled debugging messages, the runbare() could already reset it.
     self::display_debugging_messages();
     self::reset_debugging();
     // reset global $DB in case somebody mocked it
     $DB = self::get_global_backup('DB');
     if ($DB->is_transaction_started()) {
         // we can not reset inside transaction
         $DB->force_transaction_rollback();
     }
     $resetdb = self::reset_database();
     $warnings = array();
     if ($detectchanges === true) {
         if ($resetdb) {
             $warnings[] = 'Warning: unexpected database modification, resetting DB state';
         }
         $oldcfg = self::get_global_backup('CFG');
         $oldsite = self::get_global_backup('SITE');
         foreach ($CFG as $k => $v) {
             if (!property_exists($oldcfg, $k)) {
                 $warnings[] = 'Warning: unexpected new $CFG->' . $k . ' value';
             } else {
                 if ($oldcfg->{$k} !== $CFG->{$k}) {
                     $warnings[] = 'Warning: unexpected change of $CFG->' . $k . ' value';
                 }
             }
             unset($oldcfg->{$k});
         }
         if ($oldcfg) {
             foreach ($oldcfg as $k => $v) {
                 $warnings[] = 'Warning: unexpected removal of $CFG->' . $k;
             }
         }
         if ($USER->id != 0) {
             $warnings[] = 'Warning: unexpected change of $USER';
         }
         if ($COURSE->id != $oldsite->id) {
             $warnings[] = 'Warning: unexpected change of $COURSE';
         }
     }
     if (ini_get('max_execution_time') != 0) {
         // This is special warning for all resets because we do not want any
         // libraries to mess with timeouts unintentionally.
         // Our PHPUnit integration is not supposed to change it either.
         if ($detectchanges !== false) {
             $warnings[] = 'Warning: max_execution_time was changed to ' . ini_get('max_execution_time');
         }
         set_time_limit(0);
     }
     // restore original globals
     $_SERVER = self::get_global_backup('_SERVER');
     $CFG = self::get_global_backup('CFG');
     $SITE = self::get_global_backup('SITE');
     $_GET = array();
     $_POST = array();
     $_FILES = array();
     $_REQUEST = array();
     $COURSE = $SITE;
     // reinitialise following globals
     $OUTPUT = new bootstrap_renderer();
     $PAGE = new moodle_page();
     $FULLME = null;
     $ME = null;
     $SCRIPT = null;
     // Empty sessison and set fresh new not-logged-in user.
     \core\session\manager::init_empty_session();
     // reset all static caches
     \core\event\manager::phpunit_reset();
     accesslib_clear_all_caches(true);
     get_string_manager()->reset_caches(true);
     reset_text_filters_cache(true);
     events_get_handlers('reset');
     core_text::reset_caches();
     get_message_processors(false, true);
     filter_manager::reset_caches();
     // Reset internal users.
     core_user::reset_internal_users();
     //TODO MDL-25290: add more resets here and probably refactor them to new core function
     // Reset course and module caches.
     if (class_exists('format_base')) {
         // If file containing class is not loaded, there is no cache there anyway.
         format_base::reset_course_cache(0);
     }
     get_fast_modinfo(0, 0, true);
     // Reset other singletons.
     if (class_exists('core_plugin_manager')) {
         core_plugin_manager::reset_caches(true);
     }
     if (class_exists('\\core\\update\\checker')) {
         \core\update\checker::reset_caches(true);
     }
     if (class_exists('\\core\\update\\deployer')) {
         \core\update\deployer::reset_caches(true);
     }
     // purge dataroot directory
     self::reset_dataroot();
     // restore original config once more in case resetting of caches changed CFG
     $CFG = self::get_global_backup('CFG');
     // inform data generator
     self::get_data_generator()->reset();
     // fix PHP settings
     error_reporting($CFG->debug);
     // verify db writes just in case something goes wrong in reset
     if (self::$lastdbwrites != $DB->perf_get_writes()) {
         error_log('Unexpected DB writes in phpunit_util::reset_all_data()');
         self::$lastdbwrites = $DB->perf_get_writes();
     }
     if ($warnings) {
         $warnings = implode("\n", $warnings);
         trigger_error($warnings, E_USER_WARNING);
     }
 }
Ejemplo n.º 2
0
 /**
  * Save the new setting
  *
  * @param string $data The new value to save
  * @return string empty or error message
  */
 public function write_setting($data)
 {
     global $DB, $SITE, $COURSE;
     $record = new stdClass();
     $record->id = $SITE->id;
     $record->{$this->name} = $data;
     $record->timemodified = time();
     course_get_format($SITE)->update_course_format_options($record);
     $DB->update_record('course', $record);
     // Reset caches.
     $SITE = $DB->get_record('course', array('id' => $SITE->id), '*', MUST_EXIST);
     if ($SITE->id == $COURSE->id) {
         $COURSE = $SITE;
     }
     format_base::reset_course_cache($SITE->id);
     return '';
 }
Ejemplo n.º 3
0
/**
 * Delete a course, including all related data from the database, and any associated files.
 *
 * @param mixed $courseorid The id of the course or course object to delete.
 * @param bool $showfeedback Whether to display notifications of each action the function performs.
 * @return bool true if all the removals succeeded. false if there were any failures. If this
 *             method returns false, some of the removals will probably have succeeded, and others
 *             failed, but you have no way of knowing which.
 */
function delete_course($courseorid, $showfeedback = true)
{
    global $DB;
    if (is_object($courseorid)) {
        $courseid = $courseorid->id;
        $course = $courseorid;
    } else {
        $courseid = $courseorid;
        if (!($course = $DB->get_record('course', array('id' => $courseid)))) {
            return false;
        }
    }
    $context = context_course::instance($courseid);
    // Frontpage course can not be deleted!!
    if ($courseid == SITEID) {
        return false;
    }
    // Allow plugins to use this course before we completely delete it.
    if ($pluginsfunction = get_plugins_with_function('pre_course_delete')) {
        foreach ($pluginsfunction as $plugintype => $plugins) {
            foreach ($plugins as $pluginfunction) {
                $pluginfunction($course);
            }
        }
    }
    // Make the course completely empty.
    remove_course_contents($courseid, $showfeedback);
    // Delete the course and related context instance.
    context_helper::delete_instance(CONTEXT_COURSE, $courseid);
    $DB->delete_records("course", array("id" => $courseid));
    $DB->delete_records("course_format_options", array("courseid" => $courseid));
    // Reset all course related caches here.
    if (class_exists('format_base', false)) {
        format_base::reset_course_cache($courseid);
    }
    // Trigger a course deleted event.
    $event = \core\event\course_deleted::create(array('objectid' => $course->id, 'context' => $context, 'other' => array('shortname' => $course->shortname, 'fullname' => $course->fullname, 'idnumber' => $course->idnumber)));
    $event->add_record_snapshot('course', $course);
    $event->trigger();
    return true;
}
Ejemplo n.º 4
0
 /**
  * Reset contents of all database tables to initial values, reset caches, etc.
  */
 public static function reset_all_data()
 {
     // Reset database.
     self::reset_database();
     // Purge dataroot directory.
     self::reset_dataroot();
     // Reset all static caches.
     accesslib_clear_all_caches(true);
     // Reset the nasty strings list used during the last test.
     nasty_strings::reset_used_strings();
     filter_manager::reset_caches();
     // Reset course and module caches.
     if (class_exists('format_base')) {
         // If file containing class is not loaded, there is no cache there anyway.
         format_base::reset_course_cache(0);
     }
     get_fast_modinfo(0, 0, true);
     // Inform data generator.
     self::get_data_generator()->reset();
     // Initialise $CFG with default values. This is needed for behat cli process, so we don't have modified
     // $CFG values from the old run. @see set_config.
     initialise_cfg();
 }
Ejemplo n.º 5
0
/**
 * Set highlighted section. Only one section can be highlighted at the time.
 *
 * @param int $courseid course id
 * @param int $marker highlight section with this number, 0 means remove higlightin
 * @return void
 */
function course_set_marker($courseid, $marker)
{
    global $DB;
    $DB->set_field("course", "marker", $marker, array('id' => $courseid));
    format_base::reset_course_cache($courseid);
}
Ejemplo n.º 6
0
/**
 * Rebuilds or resets the cached list of course activities stored in MUC.
 *
 * rebuild_course_cache() must NEVER be called from lib/db/upgrade.php.
 * At the same time course cache may ONLY be cleared using this function in
 * upgrade scripts of plugins.
 *
 * During the bulk operations if it is necessary to reset cache of multiple
 * courses it is enough to call {@link increment_revision_number()} for the
 * table 'course' and field 'cacherev' specifying affected courses in select.
 *
 * Cached course information is stored in MUC core/coursemodinfo and is
 * validated with the DB field {course}.cacherev
 *
 * @global moodle_database $DB
 * @param int $courseid id of course to rebuild, empty means all
 * @param boolean $clearonly only clear the cache, gets rebuild automatically on the fly.
 *     Recommended to set to true to avoid unnecessary multiple rebuilding.
 */
function rebuild_course_cache($courseid=0, $clearonly=false) {
    global $COURSE, $SITE, $DB, $CFG;

    // Function rebuild_course_cache() can not be called during upgrade unless it's clear only.
    if (!$clearonly && !upgrade_ensure_not_running(true)) {
        $clearonly = true;
    }

    // Destroy navigation caches
    navigation_cache::destroy_volatile_caches();

    if (class_exists('format_base')) {
        // if file containing class is not loaded, there is no cache there anyway
        format_base::reset_course_cache($courseid);
    }

    $cachecoursemodinfo = cache::make('core', 'coursemodinfo');
    if (empty($courseid)) {
        // Clearing caches for all courses.
        increment_revision_number('course', 'cacherev', '');
        $cachecoursemodinfo->purge();
        course_modinfo::clear_instance_cache();
        // Update global values too.
        $sitecacherev = $DB->get_field('course', 'cacherev', array('id' => SITEID));
        $SITE->cachrev = $sitecacherev;
        if ($COURSE->id == SITEID) {
            $COURSE->cacherev = $sitecacherev;
        } else {
            $COURSE->cacherev = $DB->get_field('course', 'cacherev', array('id' => $COURSE->id));
        }
    } else {
        // Clearing cache for one course, make sure it is deleted from user request cache as well.
        increment_revision_number('course', 'cacherev', 'id = :id', array('id' => $courseid));
        $cachecoursemodinfo->delete($courseid);
        course_modinfo::clear_instance_cache($courseid);
        // Update global values too.
        if ($courseid == $COURSE->id || $courseid == $SITE->id) {
            $cacherev = $DB->get_field('course', 'cacherev', array('id' => $courseid));
            if ($courseid == $COURSE->id) {
                $COURSE->cacherev = $cacherev;
            }
            if ($courseid == $SITE->id) {
                $SITE->cachrev = $cacherev;
            }
        }
    }

    if ($clearonly) {
        return;
    }

    if ($courseid) {
        $select = array('id'=>$courseid);
    } else {
        $select = array();
        core_php_time_limit::raise();  // this could take a while!   MDL-10954
    }

    $rs = $DB->get_recordset("course", $select,'','id,'.join(',', course_modinfo::$cachedfields));
    // Rebuild cache for each course.
    foreach ($rs as $course) {
        course_modinfo::build_course_cache($course);
    }
    $rs->close();
}
Ejemplo n.º 7
0
 /**
  * Reset contents of all database tables to initial values, reset caches, etc.
  */
 public static function reset_all_data()
 {
     // Reset database.
     self::reset_database();
     // Purge dataroot directory.
     self::reset_dataroot();
     // Reset all static caches.
     accesslib_clear_all_caches(true);
     // Reset the nasty strings list used during the last test.
     nasty_strings::reset_used_strings();
     filter_manager::reset_caches();
     // Reset course and module caches.
     if (class_exists('format_base')) {
         // If file containing class is not loaded, there is no cache there anyway.
         format_base::reset_course_cache(0);
     }
     get_fast_modinfo(0, 0, true);
     // Inform data generator.
     self::get_data_generator()->reset();
 }
Ejemplo n.º 8
0
 /**
  * Reset contents of all database tables to initial values, reset caches, etc.
  *
  * Note: this is relatively slow (cca 2 seconds for pg and 7 for mysql) - please use with care!
  *
  * @static
  * @param bool $logchanges log changes in global state and database in error log
  * @return void
  */
 public static function reset_all_data($logchanges = false)
 {
     global $DB, $CFG, $USER, $SITE, $COURSE, $PAGE, $OUTPUT, $SESSION;
     // Stop any message redirection.
     phpunit_util::stop_message_redirection();
     // Release memory and indirectly call destroy() methods to release resource handles, etc.
     gc_collect_cycles();
     // Show any unhandled debugging messages, the runbare() could already reset it.
     self::display_debugging_messages();
     self::reset_debugging();
     // reset global $DB in case somebody mocked it
     $DB = self::get_global_backup('DB');
     if ($DB->is_transaction_started()) {
         // we can not reset inside transaction
         $DB->force_transaction_rollback();
     }
     $resetdb = self::reset_database();
     $warnings = array();
     if ($logchanges) {
         if ($resetdb) {
             $warnings[] = 'Warning: unexpected database modification, resetting DB state';
         }
         $oldcfg = self::get_global_backup('CFG');
         $oldsite = self::get_global_backup('SITE');
         foreach ($CFG as $k => $v) {
             if (!property_exists($oldcfg, $k)) {
                 $warnings[] = 'Warning: unexpected new $CFG->' . $k . ' value';
             } else {
                 if ($oldcfg->{$k} !== $CFG->{$k}) {
                     $warnings[] = 'Warning: unexpected change of $CFG->' . $k . ' value';
                 }
             }
             unset($oldcfg->{$k});
         }
         if ($oldcfg) {
             foreach ($oldcfg as $k => $v) {
                 $warnings[] = 'Warning: unexpected removal of $CFG->' . $k;
             }
         }
         if ($USER->id != 0) {
             $warnings[] = 'Warning: unexpected change of $USER';
         }
         if ($COURSE->id != $oldsite->id) {
             $warnings[] = 'Warning: unexpected change of $COURSE';
         }
     }
     // restore original globals
     $_SERVER = self::get_global_backup('_SERVER');
     $CFG = self::get_global_backup('CFG');
     $SITE = self::get_global_backup('SITE');
     $COURSE = $SITE;
     // reinitialise following globals
     $OUTPUT = new bootstrap_renderer();
     $PAGE = new moodle_page();
     $FULLME = null;
     $ME = null;
     $SCRIPT = null;
     $SESSION = new stdClass();
     $_SESSION['SESSION'] =& $SESSION;
     // set fresh new not-logged-in user
     $user = new stdClass();
     $user->id = 0;
     $user->mnethostid = $CFG->mnet_localhost_id;
     session_set_user($user);
     // reset all static caches
     accesslib_clear_all_caches(true);
     get_string_manager()->reset_caches(true);
     reset_text_filters_cache(true);
     events_get_handlers('reset');
     textlib::reset_caches();
     if (class_exists('repository')) {
         repository::reset_caches();
     }
     filter_manager::reset_caches();
     //TODO MDL-25290: add more resets here and probably refactor them to new core function
     // Reset course and module caches.
     if (class_exists('format_base')) {
         // If file containing class is not loaded, there is no cache there anyway.
         format_base::reset_course_cache(0);
     }
     get_fast_modinfo(0, 0, true);
     // Reset other singletons.
     if (class_exists('plugin_manager')) {
         plugin_manager::reset_caches(true);
     }
     if (class_exists('available_update_checker')) {
         available_update_checker::reset_caches(true);
     }
     if (class_exists('available_update_deployer')) {
         available_update_deployer::reset_caches(true);
     }
     // purge dataroot directory
     self::reset_dataroot();
     // restore original config once more in case resetting of caches changed CFG
     $CFG = self::get_global_backup('CFG');
     // inform data generator
     self::get_data_generator()->reset();
     // fix PHP settings
     error_reporting($CFG->debug);
     // verify db writes just in case something goes wrong in reset
     if (self::$lastdbwrites != $DB->perf_get_writes()) {
         error_log('Unexpected DB writes in phpunit_util::reset_all_data()');
         self::$lastdbwrites = $DB->perf_get_writes();
     }
     if ($warnings) {
         $warnings = implode("\n", $warnings);
         trigger_error($warnings, E_USER_WARNING);
     }
 }
Ejemplo n.º 9
0
/**
 * Rebuilds the cached list of course activities stored in the database
 * @param int $courseid - id of course to rebuild, empty means all
 * @param boolean $clearonly - only clear the modinfo fields, gets rebuild automatically on the fly
 */
function rebuild_course_cache($courseid = 0, $clearonly = false)
{
    global $COURSE, $SITE, $DB, $CFG;
    // Destroy navigation caches
    navigation_cache::destroy_volatile_caches();
    if (class_exists('format_base')) {
        // if file containing class is not loaded, there is no cache there anyway
        format_base::reset_course_cache($courseid);
    }
    if ($clearonly) {
        if (empty($courseid)) {
            $DB->set_field('course', 'modinfo', null);
            $DB->set_field('course', 'sectioncache', null);
        } else {
            // Clear both fields in one update
            $resetobj = (object) array('id' => $courseid, 'modinfo' => null, 'sectioncache' => null);
            $DB->update_record('course', $resetobj);
        }
        // update cached global COURSE too ;-)
        if ($courseid == $COURSE->id or empty($courseid)) {
            $COURSE->modinfo = null;
            $COURSE->sectioncache = null;
        }
        if ($courseid == $SITE->id) {
            $SITE->modinfo = null;
            $SITE->sectioncache = null;
        }
        // reset the fast modinfo cache
        get_fast_modinfo($courseid, 0, true);
        return;
    }
    require_once "{$CFG->dirroot}/course/lib.php";
    if ($courseid) {
        $select = array('id' => $courseid);
    } else {
        $select = array();
        @set_time_limit(0);
        // this could take a while!   MDL-10954
    }
    $rs = $DB->get_recordset("course", $select, '', 'id,fullname');
    foreach ($rs as $course) {
        $modinfo = serialize(get_array_of_activities($course->id));
        $sectioncache = serialize(course_modinfo::build_section_cache($course->id));
        $updateobj = (object) array('id' => $course->id, 'modinfo' => $modinfo, 'sectioncache' => $sectioncache);
        $DB->update_record("course", $updateobj);
        // update cached global COURSE too ;-)
        if ($course->id == $COURSE->id) {
            $COURSE->modinfo = $modinfo;
            $COURSE->sectioncache = $sectioncache;
        }
        if ($course->id == $SITE->id) {
            $SITE->modinfo = $modinfo;
            $SITE->sectioncache = $sectioncache;
        }
    }
    $rs->close();
    // reset the fast modinfo cache
    get_fast_modinfo($courseid, 0, true);
}
Ejemplo n.º 10
0
 /**
  * Save the new setting
  *
  * @param string $data The new value to save
  * @return string empty or error message
  */
 public function write_setting($data)
 {
     global $DB, $SITE;
     $record = new stdClass();
     $record->id = $SITE->id;
     $record->{$this->name} = $data;
     $record->timemodified = time();
     $SITE->{$this->name} = $data;
     course_get_format($SITE)->update_course_format_options($record);
     $DB->update_record('course', $record);
     // There is something wrong in cache updates somewhere, let's reset everything.
     format_base::reset_course_cache();
     return '';
 }