MDL-51580 upgradelib: Delete stuff used by removed upgrade steps
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Sun, 7 Feb 2016 23:23:01 +0000 (00:23 +0100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 15 Feb 2016 17:38:21 +0000 (18:38 +0100)
This commits removes stuff from different upgradelib files, used
exclusively by the already deleted upgrade steps. Given such
exclusivity it was not needed to proceed with a 2-phase deprecation
as far as the functions were 100% internal to upgrade.

This is the list of deleted functions, all them docummented in their
corresponding upgrade.txt files:

- repository_picasa_admin_upgrade_notification();
- repository_googledocs_admin_upgrade_notification();
- repository_boxnet_admin_upgrade_notification();
- repository_alfresco_admin_security_key_notice();
- qtype_essay_convert_to_html();
- portfolio_picasa_admin_upgrade_notification();
- portfolio_googledocs_admin_upgrade_notification();
- portfolio_boxnet_admin_upgrade_notification();
- mod_book_migrate_moddata_dir_to_legacy();
- mod_book_migrate_all_areas();
- mod_book_migrate_area();
- mod_assignment_pending_upgrades_notification();
- upgrade_mysql_fix_unsigned_and_lob_columns();
- upgrade_course_completion_remove_duplicates();
- upgrade_save_orphaned_questions();
- upgrade_rename_old_backup_files_using_shortname();
- upgrade_mssql_nvarcharmax();
- upgrade_mssql_varbinarymax();
- upgrade_fix_missing_root_folders();
- upgrade_course_modules_sequences();
- upgrade_grade_item_fix_sortorder();
- upgrade_availability_item();

17 files changed:
lib/db/upgradelib.php
lib/tests/upgradelib_test.php
lib/upgrade.txt
lib/upgradelib.php
mod/assignment/db/upgradelib.php [deleted file]
mod/book/db/upgradelib.php [deleted file]
mod/book/upgrade.txt
portfolio/boxnet/db/upgradelib.php [deleted file]
portfolio/googledocs/db/upgradelib.php [deleted file]
portfolio/picasa/db/upgradelib.php [deleted file]
portfolio/upgrade.txt
question/type/upgrade.txt
repository/alfresco/db/upgradelib.php [deleted file]
repository/boxnet/db/upgradelib.php [deleted file]
repository/googledocs/db/upgradelib.php [deleted file]
repository/picasa/db/upgradelib.php [deleted file]
repository/upgrade.txt

index 5b0c838..e6b29ab 100644 (file)
@@ -76,387 +76,6 @@ function upgrade_mysql_get_supported_tables() {
     return $tables;
 }
 
-/**
- * Remove all signed numbers from current database and change
- * text fields to long texts - mysql only.
- */
-function upgrade_mysql_fix_unsigned_and_lob_columns() {
-    // We are not using standard API for changes of column
-    // because everything 'signed'-related will be removed soon.
-
-    // If anybody already has numbers higher than signed limit the execution stops
-    // and tables must be fixed manually before continuing upgrade.
-
-    global $DB;
-
-    if ($DB->get_dbfamily() !== 'mysql') {
-        return;
-    }
-
-    $pbar = new progress_bar('mysqlconvertunsignedlobs', 500, true);
-
-    $prefix = $DB->get_prefix();
-    $tables = upgrade_mysql_get_supported_tables();
-
-    $tablecount = count($tables);
-    $i = 0;
-    foreach ($tables as $table) {
-        $i++;
-
-        $changes = array();
-
-        $sql = "SHOW COLUMNS FROM `{{$table}}`";
-        $rs = $DB->get_recordset_sql($sql);
-        foreach ($rs as $column) {
-            $column = (object)array_change_key_case((array)$column, CASE_LOWER);
-            if (stripos($column->type, 'unsigned') !== false) {
-                $maxvalue = 0;
-                if (preg_match('/^int/i', $column->type)) {
-                    $maxvalue = 2147483647;
-                } else if (preg_match('/^medium/i', $column->type)) {
-                    $maxvalue = 8388607;
-                } else if (preg_match('/^smallint/i', $column->type)) {
-                    $maxvalue = 32767;
-                } else if (preg_match('/^tinyint/i', $column->type)) {
-                    $maxvalue = 127;
-                }
-                if ($maxvalue) {
-                    // Make sure nobody is abusing our integer ranges - moodle int sizes are in digits, not bytes!!!
-                    $invalidcount = $DB->get_field_sql("SELECT COUNT('x') FROM `{{$table}}` WHERE `$column->field` > :maxnumber", array('maxnumber'=>$maxvalue));
-                    if ($invalidcount) {
-                        throw new moodle_exception('notlocalisederrormessage', 'error', new moodle_url('/admin/'), "Database table '{$table}'' contains unsigned column '{$column->field}' with $invalidcount values that are out of allowed range, upgrade can not continue.");
-                    }
-                }
-                $type = preg_replace('/unsigned/i', 'signed', $column->type);
-                $notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
-                $default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
-                $autoinc = (stripos($column->extra, 'auto_increment') !== false) ? 'AUTO_INCREMENT' : '';
-                // Primary and unique not necessary here, change_database_structure does not add prefix.
-                $changes[] = "MODIFY COLUMN `$column->field` $type $notnull $default $autoinc";
-
-            } else if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text') {
-                $notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
-                $default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
-                // Primary, unique and inc are not supported for texts.
-                $changes[] = "MODIFY COLUMN `$column->field` LONGTEXT $notnull $default";
-
-            } else if ($column->type === 'tinyblob' or $column->type === 'mediumblob' or $column->type === 'blob') {
-                $notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
-                $default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
-                // Primary, unique and inc are not supported for blobs.
-                $changes[] = "MODIFY COLUMN `$column->field` LONGBLOB $notnull $default";
-            }
-
-        }
-        $rs->close();
-
-        if ($changes) {
-            // Set appropriate timeout - 1 minute per thousand of records should be enough, min 60 minutes just in case.
-            $count = $DB->count_records($table, array());
-            $timeout = ($count/1000)*60;
-            $timeout = ($timeout < 60*60) ? 60*60 : (int)$timeout;
-            upgrade_set_timeout($timeout);
-
-            $sql = "ALTER TABLE `{$prefix}$table` ".implode(', ', $changes);
-            $DB->change_database_structure($sql);
-        }
-
-        $pbar->update($i, $tablecount, "Converted unsigned/lob columns in MySQL database - $i/$tablecount.");
-    }
-}
-
-/**
- * Migrate NTEXT to NVARCHAR(MAX).
- */
-function upgrade_mssql_nvarcharmax() {
-    global $DB;
-
-    if ($DB->get_dbfamily() !== 'mssql') {
-        return;
-    }
-
-    $pbar = new progress_bar('mssqlconvertntext', 500, true);
-
-    $prefix = $DB->get_prefix();
-    $tables = $DB->get_tables(false);
-
-    $tablecount = count($tables);
-    $i = 0;
-    foreach ($tables as $table) {
-        $i++;
-
-        $columns = array();
-
-        $sql = "SELECT column_name
-                  FROM INFORMATION_SCHEMA.COLUMNS
-                 WHERE table_name = '{{$table}}' AND UPPER(data_type) = 'NTEXT'";
-        $rs = $DB->get_recordset_sql($sql);
-        foreach ($rs as $column) {
-            $columns[] = $column->column_name;
-        }
-        $rs->close();
-
-        if ($columns) {
-            // Set appropriate timeout - 1 minute per thousand of records should be enough, min 60 minutes just in case.
-            $count = $DB->count_records($table, array());
-            $timeout = ($count/1000)*60;
-            $timeout = ($timeout < 60*60) ? 60*60 : (int)$timeout;
-            upgrade_set_timeout($timeout);
-
-            $updates = array();
-            foreach ($columns as $column) {
-                // Change the definition.
-                $sql = "ALTER TABLE {$prefix}$table ALTER COLUMN $column NVARCHAR(MAX)";
-                $DB->change_database_structure($sql);
-                $updates[] = "$column = $column";
-            }
-
-            // Now force the migration of text data to new optimised storage.
-            $sql = "UPDATE {{$table}} SET ".implode(', ', $updates);
-            $DB->execute($sql);
-        }
-
-        $pbar->update($i, $tablecount, "Converted NTEXT to NVARCHAR(MAX) columns in MS SQL Server database - $i/$tablecount.");
-    }
-}
-
-/**
- * Migrate IMAGE to VARBINARY(MAX).
- */
-function upgrade_mssql_varbinarymax() {
-    global $DB;
-
-    if ($DB->get_dbfamily() !== 'mssql') {
-        return;
-    }
-
-    $pbar = new progress_bar('mssqlconvertimage', 500, true);
-
-    $prefix = $DB->get_prefix();
-    $tables = $DB->get_tables(false);
-
-    $tablecount = count($tables);
-    $i = 0;
-    foreach ($tables as $table) {
-        $i++;
-
-        $columns = array();
-
-        $sql = "SELECT column_name
-                  FROM INFORMATION_SCHEMA.COLUMNS
-                 WHERE table_name = '{{$table}}' AND UPPER(data_type) = 'IMAGE'";
-        $rs = $DB->get_recordset_sql($sql);
-        foreach ($rs as $column) {
-            $columns[] = $column->column_name;
-        }
-        $rs->close();
-
-        if ($columns) {
-            // Set appropriate timeout - 1 minute per thousand of records should be enough, min 60 minutes just in case.
-            $count = $DB->count_records($table, array());
-            $timeout = ($count/1000)*60;
-            $timeout = ($timeout < 60*60) ? 60*60 : (int)$timeout;
-            upgrade_set_timeout($timeout);
-
-            foreach ($columns as $column) {
-                // Change the definition.
-                $sql = "ALTER TABLE {$prefix}$table ALTER COLUMN $column VARBINARY(MAX)";
-                $DB->change_database_structure($sql);
-            }
-
-            // Binary columns should not be used, do not waste time optimising the storage.
-        }
-
-        $pbar->update($i, $tablecount, "Converted IMAGE to VARBINARY(MAX) columns in MS SQL Server database - $i/$tablecount.");
-    }
-}
-
-/**
- * This upgrade script fixes the mismatches between DB fields course_modules.section
- * and course_sections.sequence. It makes sure that each module is included
- * in the sequence of at least one section.
- * Note that this script is different from admin/cli/fix_course_sortorder.php
- * in the following ways:
- * 1. It does not fix the cases when module appears several times in section(s) sequence(s) -
- *    it will be done automatically on the next viewing of the course.
- * 2. It does not remove non-existing modules from section sequences - administrator
- *    has to run the CLI script to do it.
- * 3. When this script finds an orphaned module it adds it to the section but makes hidden
- *    where CLI script does not change the visiblity specified in the course_modules table.
- */
-function upgrade_course_modules_sequences() {
-    global $DB;
-
-    // Find all modules that point to the section which does not point back to this module.
-    $sequenceconcat = $DB->sql_concat("','", "s.sequence", "','");
-    $moduleconcat = $DB->sql_concat("'%,'", "m.id", "',%'");
-    $sql = "SELECT m.id, m.course, m.section, s.sequence
-        FROM {course_modules} m LEFT OUTER JOIN {course_sections} s
-        ON m.course = s.course and m.section = s.id
-        WHERE s.sequence IS NULL OR ($sequenceconcat NOT LIKE $moduleconcat)
-        ORDER BY m.course";
-    $rs = $DB->get_recordset_sql($sql);
-    $sections = null;
-    foreach ($rs as $cm) {
-        if (!isset($sections[$cm->course])) {
-            // Retrieve all sections for the course (only once for each corrupt course).
-            $sections = array($cm->course =>
-                    $DB->get_records('course_sections', array('course' => $cm->course),
-                            'section', 'id, section, sequence, visible'));
-            if (empty($sections[$cm->course])) {
-                // Very odd - the course has a module in it but has no sections. Create 0-section.
-                $newsection = array('sequence' => '', 'section' => 0, 'visible' => 1);
-                $newsection['id'] = $DB->insert_record('course_sections',
-                        $newsection + array('course' => $cm->course, 'summary' => '', 'summaryformat' => FORMAT_HTML));
-                $sections[$cm->course] = array($newsection['id'] => (object)$newsection);
-            }
-        }
-        // Attempt to find the section that has this module in it's sequence.
-        // If there are several of them, pick the last because this is what get_fast_modinfo() does.
-        $sectionid = null;
-        foreach ($sections[$cm->course] as $section) {
-            if (!empty($section->sequence) && in_array($cm->id, preg_split('/,/', $section->sequence))) {
-                $sectionid = $section->id;
-            }
-        }
-        if ($sectionid) {
-            // Found the section. Update course_module to point to the correct section.
-            $params = array('id' => $cm->id, 'section' => $sectionid);
-            if (!$sections[$cm->course][$sectionid]->visible) {
-                $params['visible'] = 0;
-            }
-            $DB->update_record('course_modules', $params);
-        } else {
-            // No section in the course has this module in it's sequence.
-            if (isset($sections[$cm->course][$cm->section])) {
-                // Try to add module to the section it points to (if it is valid).
-                $sectionid = $cm->section;
-            } else {
-                // Section not found. Just add to the first available section.
-                reset($sections[$cm->course]);
-                $sectionid = key($sections[$cm->course]);
-            }
-            $newsequence = ltrim($sections[$cm->course][$sectionid]->sequence . ',' . $cm->id, ',');
-            $sections[$cm->course][$sectionid]->sequence = $newsequence;
-            $DB->update_record('course_sections', array('id' => $sectionid, 'sequence' => $newsequence));
-            // Make module invisible because it was not displayed at all before this upgrade script.
-            $DB->update_record('course_modules', array('id' => $cm->id, 'section' => $sectionid, 'visible' => 0, 'visibleold' => 0));
-        }
-    }
-    $rs->close();
-    unset($sections);
-
-    // Note that we don't need to reset course cache here because it is reset automatically after upgrade.
-}
-
-/**
- * Updates a single item (course module or course section) to transfer the
- * availability settings from the old to the new format.
- *
- * Note: We do not convert groupmembersonly for modules at present. If we did,
- * $groupmembersonly would be set to the groupmembersonly option for the
- * module. Since we don't, it will be set to 0 for modules, and 1 for sections
- * if they have a grouping.
- *
- * @param int $groupmembersonly 1 if activity has groupmembersonly option
- * @param int $groupingid Grouping id (0 = none)
- * @param int $availablefrom Available from time (0 = none)
- * @param int $availableuntil Available until time (0 = none)
- * @param int $showavailability Show availability (1) or hide activity entirely
- * @param array $availrecs Records from course_modules/sections_availability
- * @param array $fieldrecs Records from course_modules/sections_avail_fields
- */
-function upgrade_availability_item($groupmembersonly, $groupingid,
-        $availablefrom, $availableuntil, $showavailability,
-        array $availrecs, array $fieldrecs) {
-    global $CFG, $DB;
-    $conditions = array();
-    $shows = array();
-
-    // Group members only condition (if enabled).
-    if ($CFG->enablegroupmembersonly && $groupmembersonly) {
-        if ($groupingid) {
-            $conditions[] = '{"type":"grouping"' .
-                    ($groupingid ? ',"id":' . $groupingid : '') . '}';
-        } else {
-            // No grouping specified, so allow any group.
-            $conditions[] = '{"type":"group"}';
-        }
-        // Group members only condition was not displayed to students.
-        $shows[] = 'false';
-
-        // In the unlikely event that the site had enablegroupmembers only
-        // but NOT enableavailability, we need to turn this on now.
-        if (!$CFG->enableavailability) {
-            set_config('enableavailability', 1);
-        }
-    }
-
-    // Date conditions.
-    if ($availablefrom) {
-        $conditions[] = '{"type":"date","d":">=","t":' . $availablefrom . '}';
-        $shows[] = $showavailability ? 'true' : 'false';
-    }
-    if ($availableuntil) {
-        $conditions[] = '{"type":"date","d":"<","t":' . $availableuntil . '}';
-        // Until dates never showed to students.
-        $shows[] = 'false';
-    }
-
-    // Conditions from _availability table.
-    foreach ($availrecs as $rec) {
-        if (!empty($rec->sourcecmid)) {
-            // Completion condition.
-            $conditions[] = '{"type":"completion","cm":' . $rec->sourcecmid .
-                    ',"e":' . $rec->requiredcompletion . '}';
-        } else {
-            // Grade condition.
-            $minmax = '';
-            if (!empty($rec->grademin)) {
-                $minmax .= ',"min":' . sprintf('%.5f', $rec->grademin);
-            }
-            if (!empty($rec->grademax)) {
-                $minmax .= ',"max":' . sprintf('%.5f', $rec->grademax);
-            }
-            $conditions[] = '{"type":"grade","id":' . $rec->gradeitemid . $minmax . '}';
-        }
-        $shows[] = $showavailability ? 'true' : 'false';
-    }
-
-    // Conditions from _fields table.
-    foreach ($fieldrecs as $rec) {
-        if (isset($rec->userfield)) {
-            // Standard field.
-            $fieldbit = ',"sf":' . json_encode($rec->userfield);
-        } else {
-            // Custom field.
-            $fieldbit = ',"cf":' . json_encode($rec->shortname);
-        }
-        // Value is not included for certain operators.
-        switch($rec->operator) {
-            case 'isempty':
-            case 'isnotempty':
-                $valuebit = '';
-                break;
-
-            default:
-                $valuebit = ',"v":' . json_encode($rec->value);
-                break;
-        }
-        $conditions[] = '{"type":"profile","op":"' . $rec->operator . '"' .
-                $fieldbit . $valuebit . '}';
-        $shows[] = $showavailability ? 'true' : 'false';
-    }
-
-    // If there are some conditions, set them into database.
-    if ($conditions) {
-        return '{"op":"&","showc":[' . implode(',', $shows) . '],' .
-                '"c":[' . implode(',', $conditions) . ']}';
-    } else {
-        return null;
-    }
-}
-
 /**
  * Using data for a single course-module that has groupmembersonly enabled,
  * returns the new availability value that incorporates the correct
index ca40f86..1c4b707 100644 (file)
@@ -43,80 +43,6 @@ class core_upgradelib_testcase extends advanced_testcase {
         $this->assertFalse(upgrade_stale_php_files_present());
     }
 
-    /**
-     * Test the {@link upgrade_grade_item_fix_sortorder() function with
-     * faked duplicate sortorder data.
-     */
-    public function test_upgrade_grade_item_fix_sortorder() {
-        global $DB;
-
-        $this->resetAfterTest(true);
-
-        // The purpose of this test is to make sure that after upgrade script
-        // there is no duplicates in the field grade_items.sortorder (for each course)
-        // and the result of query "SELECT id FROM grade_items WHERE courseid=? ORDER BY sortorder, id" does not change.
-        $sequencesql = 'SELECT id FROM {grade_items} WHERE courseid=? ORDER BY sortorder, id';
-
-        // Each set is used for filling the db with fake data and will be representing the result of query:
-        // "SELECT sortorder from {grade_items} WHERE courseid=? ORDER BY id".
-        $testsets = array(
-            // Items that need no action.
-            array(1,2,3),
-            array(5,6,7),
-            array(7,6,1,3,2,5),
-            // Items with sortorder duplicates
-            array(1,2,2,3,3,4,5),
-            // Only one sortorder duplicate.
-            array(1,1),
-            array(3,3),
-            // Non-sequential sortorders with one or multiple duplicates.
-            array(3,3,7,5,6,6,9,10,8,3),
-            array(7,7,3),
-            array(3,4,5,3,5,4,7,1)
-        );
-        $origsequences = array();
-
-        // Generate the data and remember the initial sequence or items.
-        foreach ($testsets as $testset) {
-            $course = $this->getDataGenerator()->create_course();
-            foreach ($testset as $sortorder) {
-                $this->insert_fake_grade_item_sortorder($course->id, $sortorder);
-            }
-            $DB->get_records('grade_items');
-            $origsequences[$course->id] = $DB->get_fieldset_sql($sequencesql, array($course->id));
-        }
-
-        $duplicatedetectionsql = "SELECT courseid, sortorder
-                                    FROM {grade_items}
-                                GROUP BY courseid, sortorder
-                                  HAVING COUNT(id) > 1";
-
-        // Verify there are duplicates before we start the fix.
-        $dupes = $DB->record_exists_sql($duplicatedetectionsql);
-        $this->assertTrue($dupes);
-
-        // Do the work.
-        upgrade_grade_item_fix_sortorder();
-
-        // Verify that no duplicates are left in the database.
-        $dupes = $DB->record_exists_sql($duplicatedetectionsql);
-        $this->assertFalse($dupes);
-
-        // Verify that sequences are exactly the same as they were before upgrade script.
-        $idx = 0;
-        foreach ($origsequences as $courseid => $origsequence) {
-            if (count(($testsets[$idx])) == count(array_unique($testsets[$idx]))) {
-                // If there were no duplicates for this course verify that sortorders are not modified.
-                $newsortorders = $DB->get_fieldset_sql("SELECT sortorder from {grade_items} WHERE courseid=? ORDER BY id", array($courseid));
-                $this->assertEquals($testsets[$idx], $newsortorders);
-            }
-            $newsequence = $DB->get_fieldset_sql($sequencesql, array($courseid));
-            $this->assertEquals($origsequence, $newsequence,
-                    "Sequences do not match for test set $idx : ".join(',', $testsets[$idx]));
-            $idx++;
-        }
-    }
-
     /**
      * Populate some fake grade items into the database with specified
      * sortorder and course id.
@@ -150,57 +76,6 @@ class core_upgradelib_testcase extends advanced_testcase {
         return $DB->get_record('grade_items', array('id' => $item->id));
     }
 
-    public function test_upgrade_fix_missing_root_folders() {
-        global $DB, $SITE;
-
-        $this->resetAfterTest(true);
-
-        // Setup some broken data...
-        // Create two resources (and associated file areas).
-        $this->setAdminUser();
-        $resource1 = $this->getDataGenerator()->get_plugin_generator('mod_resource')
-            ->create_instance(array('course' => $SITE->id));
-        $resource2 = $this->getDataGenerator()->get_plugin_generator('mod_resource')
-            ->create_instance(array('course' => $SITE->id));
-
-        // Delete the folder record of resource1 to simulate broken data.
-        $context = context_module::instance($resource1->cmid);
-        $selectargs = array('contextid' => $context->id,
-                            'component' => 'mod_resource',
-                            'filearea' => 'content',
-                            'itemid' => 0);
-
-        // Verify file records exist.
-        $areafilecount = $DB->count_records('files', $selectargs);
-        $this->assertNotEmpty($areafilecount);
-
-        // Delete the folder record.
-        $folderrecord = $selectargs;
-        $folderrecord['filepath'] = '/';
-        $folderrecord['filename'] = '.';
-
-        // Get previous folder record.
-        $oldrecord = $DB->get_record('files', $folderrecord);
-        $DB->delete_records('files', $folderrecord);
-
-        // Verify the folder record has been removed.
-        $newareafilecount = $DB->count_records('files', $selectargs);
-        $this->assertSame($newareafilecount, $areafilecount - 1);
-
-        $this->assertFalse($DB->record_exists('files', $folderrecord));
-
-        // Run the upgrade step!
-        upgrade_fix_missing_root_folders();
-
-        // Verify the folder record has been restored.
-        $newareafilecount = $DB->count_records('files', $selectargs);
-        $this->assertSame($newareafilecount, $areafilecount);
-
-        $newrecord = $DB->get_record('files', $folderrecord, '*', MUST_EXIST);
-        // Verify the hash is correctly created.
-        $this->assertSame($oldrecord->pathnamehash, $newrecord->pathnamehash);
-    }
-
     public function test_upgrade_fix_missing_root_folders_draft() {
         global $DB, $SITE;
 
@@ -245,115 +120,6 @@ class core_upgradelib_testcase extends advanced_testcase {
         $this->assertEquals($originalhash, $newhash);
     }
 
-    /**
-     * Tests the upgrade of an individual course-module or section from the
-     * old to new availability system. (This test does not use the database
-     * so it can run any time.)
-     */
-    public function test_upgrade_availability_item() {
-        global $CFG;
-        $this->resetAfterTest();
-
-        // This function is in the other upgradelib.
-        require_once($CFG->libdir . '/db/upgradelib.php');
-
-        // Groupmembersonly (or nothing). Show option on but ignored.
-        // Note: This $CFG option doesn't exist any more but we are testing the
-        // upgrade function so it did exist then...
-        $CFG->enablegroupmembersonly = 0;
-        $this->assertNull(
-                upgrade_availability_item(1, 0, 0, 0, 1, array(), array()));
-        $CFG->enablegroupmembersonly = 1;
-        $this->assertNull(
-                upgrade_availability_item(0, 0, 0, 0, 1, array(), array()));
-        $this->assertEquals(
-                '{"op":"&","showc":[false],"c":[{"type":"group"}]}',
-                upgrade_availability_item(1, 0, 0, 0, 1, array(), array()));
-        $this->assertEquals(
-                '{"op":"&","showc":[false],"c":[{"type":"grouping","id":4}]}',
-                upgrade_availability_item(1, 4, 0, 0, 1, array(), array()));
-
-        // Dates (with show/hide options - until date always hides).
-        $this->assertEquals(
-                '{"op":"&","showc":[true],"c":[{"type":"date","d":">=","t":996}]}',
-                upgrade_availability_item(0, 0, 996, 0, 1, array(), array()));
-        $this->assertEquals(
-                '{"op":"&","showc":[false],"c":[{"type":"date","d":">=","t":997}]}',
-                upgrade_availability_item(0, 0, 997, 0, 0, array(), array()));
-        $this->assertEquals(
-                '{"op":"&","showc":[false],"c":[{"type":"date","d":"<","t":998}]}',
-                upgrade_availability_item(0, 0, 0, 998, 1, array(), array()));
-        $this->assertEquals(
-                '{"op":"&","showc":[true,false],"c":[' .
-                '{"type":"date","d":">=","t":995},{"type":"date","d":"<","t":999}]}',
-                upgrade_availability_item(0, 0, 995, 999, 1, array(), array()));
-
-        // Grade (show option works as normal).
-        $availrec = (object)array(
-                'sourcecmid' => null, 'requiredcompletion' => null,
-                'gradeitemid' => 13, 'grademin' => null, 'grademax' => null);
-        $this->assertEquals(
-                '{"op":"&","showc":[true],"c":[{"type":"grade","id":13}]}',
-                upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
-        $availrec->grademin = 4.1;
-        $this->assertEquals(
-                '{"op":"&","showc":[false],"c":[{"type":"grade","id":13,"min":4.10000}]}',
-                upgrade_availability_item(0, 0, 0, 0, 0, array($availrec), array()));
-        $availrec->grademax = 9.9;
-        $this->assertEquals(
-                '{"op":"&","showc":[true],"c":[{"type":"grade","id":13,"min":4.10000,"max":9.90000}]}',
-                upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
-        $availrec->grademin = null;
-        $this->assertEquals(
-                '{"op":"&","showc":[true],"c":[{"type":"grade","id":13,"max":9.90000}]}',
-                upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
-
-        // Completion (show option normal).
-        $availrec->grademax = null;
-        $availrec->gradeitemid = null;
-        $availrec->sourcecmid = 666;
-        $availrec->requiredcompletion = 1;
-        $this->assertEquals(
-                '{"op":"&","showc":[true],"c":[{"type":"completion","cm":666,"e":1}]}',
-                upgrade_availability_item(0, 0, 0, 0, 1, array($availrec), array()));
-        $this->assertEquals(
-                '{"op":"&","showc":[false],"c":[{"type":"completion","cm":666,"e":1}]}',
-                upgrade_availability_item(0, 0, 0, 0, 0, array($availrec), array()));
-
-        // Profile conditions (custom/standard field, values/not, show option normal).
-        $fieldrec = (object)array('userfield' => 'email', 'operator' => 'isempty',
-                'value' => '', 'shortname' => null);
-        $this->assertEquals(
-                '{"op":"&","showc":[true],"c":[{"type":"profile","op":"isempty","sf":"email"}]}',
-                upgrade_availability_item(0, 0, 0, 0, 1, array(), array($fieldrec)));
-        $fieldrec->value = '@';
-        $fieldrec->operator = 'contains';
-        $this->assertEquals(
-                '{"op":"&","showc":[true],"c":[{"type":"profile","op":"contains","sf":"email","v":"@"}]}',
-                upgrade_availability_item(0, 0, 0, 0, 1, array(), array($fieldrec)));
-        $fieldrec->operator = 'isnotempty';
-        $fieldrec->userfield = null;
-        $fieldrec->shortname = 'frogtype';
-        $this->assertEquals(
-                '{"op":"&","showc":[false],"c":[{"type":"profile","op":"isnotempty","cf":"frogtype"}]}',
-                upgrade_availability_item(0, 0, 0, 0, 0, array(), array($fieldrec)));
-
-        // Everything at once.
-        $this->assertEquals('{"op":"&","showc":[false,true,false,true,true,true],' .
-                '"c":[{"type":"grouping","id":13},' .
-                '{"type":"date","d":">=","t":990},' .
-                '{"type":"date","d":"<","t":991},' .
-                '{"type":"grade","id":665,"min":70.00000},' .
-                '{"type":"completion","cm":42,"e":2},' .
-                '{"type":"profile","op":"isempty","sf":"email"}]}',
-                upgrade_availability_item(1, 13, 990, 991, 1, array(
-                    (object)array('sourcecmid' => null, 'gradeitemid' => 665, 'grademin' => 70),
-                    (object)array('sourcecmid' => 42, 'gradeitemid' => null, 'requiredcompletion' => 2)
-                ), array(
-                    (object)array('userfield' => 'email', 'shortname' => null, 'operator' => 'isempty'),
-                )));
-    }
-
     /**
      * Test upgrade minmaxgrade step.
      */
@@ -488,6 +254,8 @@ class core_upgradelib_testcase extends advanced_testcase {
 
         $this->resetAfterTest(true);
 
+        require_once($CFG->libdir . '/db/upgradelib.php');
+
         $c = array();
         $a = array();
         $gi = array();
@@ -551,8 +319,11 @@ class core_upgradelib_testcase extends advanced_testcase {
      */
     public function test_upgrade_calculated_grade_items_freeze() {
         global $DB, $CFG;
+
         $this->resetAfterTest();
 
+        require_once($CFG->libdir . '/db/upgradelib.php');
+
         // Create a user.
         $user = $this->getDataGenerator()->create_user();
 
@@ -679,8 +450,11 @@ class core_upgradelib_testcase extends advanced_testcase {
 
     function test_upgrade_calculated_grade_items_regrade() {
         global $DB, $CFG;
+
         $this->resetAfterTest();
 
+        require_once($CFG->libdir . '/db/upgradelib.php');
+
         // Create a user.
         $user = $this->getDataGenerator()->create_user();
 
@@ -743,9 +517,12 @@ class core_upgradelib_testcase extends advanced_testcase {
     }
 
     public function test_upgrade_course_tags() {
-        global $DB;
+        global $DB, $CFG;
+
         $this->resetAfterTest();
 
+        require_once($CFG->libdir . '/db/upgradelib.php');
+
         // Running upgrade script when there are no tags.
         upgrade_course_tags();
         $this->assertFalse($DB->record_exists('tag_instance', array()));
index 255b764..50cc8da 100644 (file)
@@ -3,6 +3,19 @@ information provided here is intended especially for developers.
 
 === 3.1 ===
 
+* The following functions, previously used (exclusively) by upgrade steps are not available
+  anymore because of the upgrade cleanup performed for this version. See MDL-51580 for more info:
+    - upgrade_mysql_fix_unsigned_and_lob_columns()
+    - upgrade_course_completion_remove_duplicates()
+    - upgrade_save_orphaned_questions()
+    - upgrade_rename_old_backup_files_using_shortname()
+    - upgrade_mssql_nvarcharmax()
+    - upgrade_mssql_varbinarymax()
+    - upgrade_fix_missing_root_folders()
+    - upgrade_course_modules_sequences()
+    - upgrade_grade_item_fix_sortorder()
+    - upgrade_availability_item()
+
 * Plugins can extend the navigation for user by declaring the following callback:
   <frankenstyle>_extend_navigation_user(navigation_node $parentnode, stdClass $user,
                                         context_user $context, stdClass $course,
index 1771153..4f96d38 100644 (file)
@@ -1915,300 +1915,6 @@ function admin_mnet_method_profile(Zend_Server_Reflection_Function_Abstract $fun
     return $profile;
 }
 
-
-/**
- * This function finds duplicate records (based on combinations of fields that should be unique)
- * and then progamatically generated a "most correct" version of the data, update and removing
- * records as appropriate
- *
- * Thanks to Dan Marsden for help
- *
- * @param   string  $table      Table name
- * @param   array   $uniques    Array of field names that should be unique
- * @param   array   $fieldstocheck  Array of fields to generate "correct" data from (optional)
- * @return  void
- */
-function upgrade_course_completion_remove_duplicates($table, $uniques, $fieldstocheck = array()) {
-    global $DB;
-
-    // Find duplicates
-    $sql_cols = implode(', ', $uniques);
-
-    $sql = "SELECT {$sql_cols} FROM {{$table}} GROUP BY {$sql_cols} HAVING (count(id) > 1)";
-    $duplicates = $DB->get_recordset_sql($sql, array());
-
-    // Loop through duplicates
-    foreach ($duplicates as $duplicate) {
-        $pointer = 0;
-
-        // Generate SQL for finding records with these duplicate uniques
-        $sql_select = implode(' = ? AND ', $uniques).' = ?'; // builds "fieldname = ? AND fieldname = ?"
-        $uniq_values = array();
-        foreach ($uniques as $u) {
-            $uniq_values[] = $duplicate->$u;
-        }
-
-        $sql_order = implode(' DESC, ', $uniques).' DESC'; // builds "fieldname DESC, fieldname DESC"
-
-        // Get records with these duplicate uniques
-        $records = $DB->get_records_select(
-            $table,
-            $sql_select,
-            $uniq_values,
-            $sql_order
-        );
-
-        // Loop through and build a "correct" record, deleting the others
-        $needsupdate = false;
-        $origrecord = null;
-        foreach ($records as $record) {
-            $pointer++;
-            if ($pointer === 1) { // keep 1st record but delete all others.
-                $origrecord = $record;
-            } else {
-                // If we have fields to check, update original record
-                if ($fieldstocheck) {
-                    // we need to keep the "oldest" of all these fields as the valid completion record.
-                    // but we want to ignore null values
-                    foreach ($fieldstocheck as $f) {
-                        if ($record->$f && (($origrecord->$f > $record->$f) || !$origrecord->$f)) {
-                            $origrecord->$f = $record->$f;
-                            $needsupdate = true;
-                        }
-                    }
-                }
-                $DB->delete_records($table, array('id' => $record->id));
-            }
-        }
-        if ($needsupdate || isset($origrecord->reaggregate)) {
-            // If this table has a reaggregate field, update to force recheck on next cron run
-            if (isset($origrecord->reaggregate)) {
-                $origrecord->reaggregate = time();
-            }
-            $DB->update_record($table, $origrecord);
-        }
-    }
-}
-
-/**
- * Find questions missing an existing category and associate them with
- * a category which purpose is to gather them.
- *
- * @return void
- */
-function upgrade_save_orphaned_questions() {
-    global $DB;
-
-    // Looking for orphaned questions
-    $orphans = $DB->record_exists_select('question',
-            'NOT EXISTS (SELECT 1 FROM {question_categories} WHERE {question_categories}.id = {question}.category)');
-    if (!$orphans) {
-        return;
-    }
-
-    // Generate a unique stamp for the orphaned questions category, easier to identify it later on
-    $uniquestamp = "unknownhost+120719170400+orphan";
-    $systemcontext = context_system::instance();
-
-    // Create the orphaned category at system level
-    $cat = $DB->get_record('question_categories', array('stamp' => $uniquestamp,
-            'contextid' => $systemcontext->id));
-    if (!$cat) {
-        $cat = new stdClass();
-        $cat->parent = 0;
-        $cat->contextid = $systemcontext->id;
-        $cat->name = get_string('orphanedquestionscategory', 'question');
-        $cat->info = get_string('orphanedquestionscategoryinfo', 'question');
-        $cat->sortorder = 999;
-        $cat->stamp = $uniquestamp;
-        $cat->id = $DB->insert_record("question_categories", $cat);
-    }
-
-    // Set a category to those orphans
-    $params = array('catid' => $cat->id);
-    $DB->execute('UPDATE {question} SET category = :catid WHERE NOT EXISTS
-            (SELECT 1 FROM {question_categories} WHERE {question_categories}.id = {question}.category)', $params);
-}
-
-/**
- * Rename old backup files to current backup files.
- *
- * When added the setting 'backup_shortname' (MDL-28657) the backup file names did not contain the id of the course.
- * Further we fixed that behaviour by forcing the id to be always present in the file name (MDL-33812).
- * This function will explore the backup directory and attempt to rename the previously created files to include
- * the id in the name. Doing this will put them back in the process of deleting the excess backups for each course.
- *
- * This function manually recreates the file name, instead of using
- * {@link backup_plan_dbops::get_default_backup_filename()}, use it carefully if you're using it outside of the
- * usual upgrade process.
- *
- * @see backup_cron_automated_helper::remove_excess_backups()
- * @link http://tracker.moodle.org/browse/MDL-35116
- * @return void
- * @since Moodle 2.4
- */
-function upgrade_rename_old_backup_files_using_shortname() {
-    global $CFG;
-    $dir = get_config('backup', 'backup_auto_destination');
-    $useshortname = get_config('backup', 'backup_shortname');
-    if (empty($dir) || !is_dir($dir) || !is_writable($dir)) {
-        return;
-    }
-
-    require_once($CFG->dirroot.'/backup/util/includes/backup_includes.php');
-    $backupword = str_replace(' ', '_', core_text::strtolower(get_string('backupfilename')));
-    $backupword = trim(clean_filename($backupword), '_');
-    $filename = $backupword . '-' . backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-';
-    $regex = '#^'.preg_quote($filename, '#').'.*\.mbz$#';
-    $thirtyapril = strtotime('30 April 2012 00:00');
-
-    // Reading the directory.
-    if (!$files = scandir($dir)) {
-        return;
-    }
-    foreach ($files as $file) {
-        // Skip directories and files which do not start with the common prefix.
-        // This avoids working on files which are not related to this issue.
-        if (!is_file($dir . '/' . $file) || !preg_match($regex, $file)) {
-            continue;
-        }
-
-        // Extract the information from the XML file.
-        try {
-            $bcinfo = backup_general_helper::get_backup_information_from_mbz($dir . '/' . $file);
-        } catch (backup_helper_exception $e) {
-            // Some error while retrieving the backup informations, skipping...
-            continue;
-        }
-
-        // Make sure this a course backup.
-        if ($bcinfo->format !== backup::FORMAT_MOODLE || $bcinfo->type !== backup::TYPE_1COURSE) {
-            continue;
-        }
-
-        // Skip the backups created before the short name option was initially introduced (MDL-28657).
-        // This was integrated on the 2nd of May 2012. Let's play safe with timezone and use the 30th of April.
-        if ($bcinfo->backup_date < $thirtyapril) {
-            continue;
-        }
-
-        // Let's check if the file name contains the ID where it is supposed to be, if it is the case then
-        // we will skip the file. Of course it could happen that the course ID is identical to the course short name
-        // even though really unlikely, but then renaming this file is not necessary. If the ID is not found in the
-        // file name then it was probably the short name which was used.
-        $idfilename = $filename . $bcinfo->original_course_id . '-';
-        $idregex = '#^'.preg_quote($idfilename, '#').'.*\.mbz$#';
-        if (preg_match($idregex, $file)) {
-            continue;
-        }
-
-        // Generating the file name manually. We do not use backup_plan_dbops::get_default_backup_filename() because
-        // it will query the database to get some course information, and the course could not exist any more.
-        $newname = $filename . $bcinfo->original_course_id . '-';
-        if ($useshortname) {
-            $shortname = str_replace(' ', '_', $bcinfo->original_course_shortname);
-            $shortname = core_text::strtolower(trim(clean_filename($shortname), '_'));
-            $newname .= $shortname . '-';
-        }
-
-        $backupdateformat = str_replace(' ', '_', get_string('backupnameformat', 'langconfig'));
-        $date = userdate($bcinfo->backup_date, $backupdateformat, 99, false);
-        $date = core_text::strtolower(trim(clean_filename($date), '_'));
-        $newname .= $date;
-
-        if (isset($bcinfo->root_settings['users']) && !$bcinfo->root_settings['users']) {
-            $newname .= '-nu';
-        } else if (isset($bcinfo->root_settings['anonymize']) && $bcinfo->root_settings['anonymize']) {
-            $newname .= '-an';
-        }
-        $newname .= '.mbz';
-
-        // Final check before attempting the renaming.
-        if ($newname == $file || file_exists($dir . '/' . $newname)) {
-            continue;
-        }
-        @rename($dir . '/' . $file, $dir . '/' . $newname);
-    }
-}
-
-/**
- * Detect duplicate grade item sortorders and resort the
- * items to remove them.
- */
-function upgrade_grade_item_fix_sortorder() {
-    global $DB;
-
-    // The simple way to fix these sortorder duplicates would be simply to resort each
-    // affected course. But in order to reduce the impact of this upgrade step we're trying
-    // to do it more efficiently by doing a series of update statements rather than updating
-    // every single grade item in affected courses.
-
-    $sql = "SELECT DISTINCT g1.courseid
-              FROM {grade_items} g1
-              JOIN {grade_items} g2 ON g1.courseid = g2.courseid
-             WHERE g1.sortorder = g2.sortorder AND g1.id != g2.id
-             ORDER BY g1.courseid ASC";
-    foreach ($DB->get_fieldset_sql($sql) as $courseid) {
-        $transaction = $DB->start_delegated_transaction();
-        $items = $DB->get_records('grade_items', array('courseid' => $courseid), '', 'id, sortorder, sortorder AS oldsort');
-
-        // Get all duplicates in course order, highest sort order, and higest id first so that we can make space at the
-        // bottom higher end of the sort orders and work down by id.
-        $sql = "SELECT DISTINCT g1.id, g1.sortorder
-                FROM {grade_items} g1
-                JOIN {grade_items} g2 ON g1.courseid = g2.courseid
-                WHERE g1.sortorder = g2.sortorder AND g1.id != g2.id AND g1.courseid = :courseid
-                ORDER BY g1.sortorder DESC, g1.id DESC";
-
-        // This is the O(N*N) like the database version we're replacing, but at least the constants are a billion times smaller...
-        foreach ($DB->get_records_sql($sql, array('courseid' => $courseid)) as $duplicate) {
-            foreach ($items as $item) {
-                if ($item->sortorder > $duplicate->sortorder || ($item->sortorder == $duplicate->sortorder && $item->id > $duplicate->id)) {
-                    $item->sortorder += 1;
-                }
-            }
-        }
-        foreach ($items as $item) {
-            if ($item->sortorder != $item->oldsort) {
-                $DB->update_record('grade_items', array('id' => $item->id, 'sortorder' => $item->sortorder));
-            }
-        }
-
-        $transaction->allow_commit();
-    }
-}
-
-/**
- * Detect file areas with missing root directory records and add them.
- */
-function upgrade_fix_missing_root_folders() {
-    global $DB, $USER;
-
-    $transaction = $DB->start_delegated_transaction();
-
-    $sql = "SELECT contextid, component, filearea, itemid
-              FROM {files}
-             WHERE (component <> 'user' OR filearea <> 'draft')
-          GROUP BY contextid, component, filearea, itemid
-            HAVING MAX(CASE WHEN filename = '.' AND filepath = '/' THEN 1 ELSE 0 END) = 0";
-
-    $rs = $DB->get_recordset_sql($sql);
-    $defaults = array('filepath' => '/',
-        'filename' => '.',
-        'userid' => 0, // Don't rely on any particular user for these system records.
-        'filesize' => 0,
-        'timecreated' => time(),
-        'timemodified' => time(),
-        'contenthash' => sha1(''));
-    foreach ($rs as $r) {
-        $pathhash = sha1("/$r->contextid/$r->component/$r->filearea/$r->itemid/.");
-        $DB->insert_record('files', (array)$r + $defaults +
-            array('pathnamehash' => $pathhash));
-    }
-    $rs->close();
-    $transaction->allow_commit();
-}
-
 /**
  * Detect draft file areas with missing root directory records and add them.
  */
diff --git a/mod/assignment/db/upgradelib.php b/mod/assignment/db/upgradelib.php
deleted file mode 100644 (file)
index d245d35..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Assignment upgrade script.
- *
- * @package   mod_assignment
- * @copyright 2013 Damyon Wiese
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Inform admins about assignments that still need upgrading.
- */
-function mod_assignment_pending_upgrades_notification($count) {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-
-    $a = new stdClass;
-    $a->count = $count;
-    $a->docsurl = get_docs_url('Assignment_upgrade_tool');
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = \core_user::get_noreply_user();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('pendingupgrades_message_small', 'mod_assignment');
-        $message->subject           = get_string('pendingupgrades_message_subject', 'mod_assignment');
-        $message->fullmessage       = get_string('pendingupgrades_message_content', 'mod_assignment', $a);
-        $message->fullmessagehtml   = get_string('pendingupgrades_message_content', 'mod_assignment', $a);
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
diff --git a/mod/book/db/upgradelib.php b/mod/book/db/upgradelib.php
deleted file mode 100644 (file)
index 73d0a0a..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-// This file is part of Book module for Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Book module upgrade related helper functions
- *
- * @package    mod_book
- * @copyright  2010 Petr Skoda {@link http://skodak.org}
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die;
-
-/**
- * Migrate book files stored in moddata folders.
- *
- * Please note it was a big mistake to store the files there in the first place!
- *
- * @param stdClass $book
- * @param stdClass $context
- * @param string $path
- * @return void
- */
-function mod_book_migrate_moddata_dir_to_legacy($book, $context, $path) {
-    global $OUTPUT, $CFG;
-
-    $base = "$CFG->dataroot/$book->course/$CFG->moddata/book/$book->id";
-    $fulldir = $base.$path;
-
-    if (!is_dir($fulldir)) {
-        // does not exist
-        return;
-    }
-
-    $fs      = get_file_storage();
-    $items   = new DirectoryIterator($fulldir);
-
-    foreach ($items as $item) {
-        if ($item->isDot()) {
-            unset($item); // release file handle
-            continue;
-        }
-
-        if ($item->isLink()) {
-            // do not follow symlinks - they were never supported in moddata, sorry
-            unset($item); // release file handle
-            continue;
-        }
-
-        if ($item->isFile()) {
-            if (!$item->isReadable()) {
-                echo $OUTPUT->notification(" File not readable, skipping: ".$fulldir.$item->getFilename());
-                unset($item); // release file handle
-                continue;
-            }
-
-            $filepath = clean_param("/$CFG->moddata/book/$book->id".$path, PARAM_PATH);
-            $filename = clean_param($item->getFilename(), PARAM_FILE);
-
-            if ($filename === '') {
-                // unsupported chars, sorry
-                unset($item); // release file handle
-                continue;
-            }
-
-            if (core_text::strlen($filepath) > 255) {
-                echo $OUTPUT->notification(" File path longer than 255 chars, skipping: ".$fulldir.$item->getFilename());
-                unset($item); // release file handle
-                continue;
-            }
-
-            if (!$fs->file_exists($context->id, 'course', 'legacy', '0', $filepath, $filename)) {
-                $file_record = array('contextid'=>$context->id, 'component'=>'course', 'filearea'=>'legacy', 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename,
-                                     'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime());
-                $fs->create_file_from_pathname($file_record, $fulldir.$item->getFilename());
-            }
-            $oldpathname = $fulldir.$item->getFilename();
-            unset($item); // release file handle
-            @unlink($oldpathname);
-
-        } else {
-            // migrate recursively all subdirectories
-            $oldpathname = $base.$item->getFilename().'/';
-            $subpath     = $path.$item->getFilename().'/';
-            unset($item);  // release file handle
-            mod_book_migrate_moddata_dir_to_legacy($book, $context, $subpath);
-            @rmdir($oldpathname); // deletes dir if empty
-        }
-    }
-    unset($items); // release file handles
-}
-
-/**
- * Migrate legacy files in intro and chapters
- * @return void
- */
-function mod_book_migrate_all_areas() {
-    global $DB, $OUTPUT;
-
-    $rsbooks = $DB->get_recordset('book');
-    foreach($rsbooks as $book) {
-        upgrade_set_timeout(360); // set up timeout, may also abort execution
-        $cm = get_coursemodule_from_instance('book', $book->id);
-        if (empty($cm) || empty($cm->id)) {
-             echo $OUTPUT->notification("Course module not found, skipping: {$book->name}");
-             continue;
-        }
-        $context = context_module::instance($cm->id);
-        mod_book_migrate_area($book, 'intro', 'book', $book->course, $context, 'mod_book', 'intro', 0);
-
-        $rschapters = $DB->get_recordset('book_chapters', array('bookid'=>$book->id));
-        foreach ($rschapters as $chapter) {
-            mod_book_migrate_area($chapter, 'content', 'book_chapters', $book->course, $context, 'mod_book', 'chapter', $chapter->id);
-        }
-        $rschapters->close();
-    }
-    $rsbooks->close();
-}
-
-/**
- * Migrate one area, this should be probably part of moodle core...
- *
- * @param stdClass $record object to migrate files (book, chapter)
- * @param string $field field in the record we are going to migrate
- * @param string $table DB table containing the information to migrate
- * @param int $courseid id of the course the book module belongs to
- * @param context_module $context context of the book module
- * @param string $component component to be used for the migrated files
- * @param string $filearea filearea to be used for the migrated files
- * @param int $itemid id to be used for the migrated files
- * @return void
- */
-function mod_book_migrate_area($record, $field, $table, $courseid, $context, $component, $filearea, $itemid) {
-    global $CFG, $DB;
-
-    $fs = get_file_storage();
-
-    foreach(array(get_site()->id, $courseid) as $cid) {
-        $matches = null;
-        $ooldcontext = context_course::instance($cid);
-        if (preg_match_all("|$CFG->wwwroot/file.php(\?file=)?/$cid(/[^\s'\"&\?#]+)|", $record->$field, $matches)) {
-            $file_record = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid);
-            foreach ($matches[2] as $i=>$filepath) {
-                if (!$file = $fs->get_file_by_hash(sha1("/$ooldcontext->id/course/legacy/0".$filepath))) {
-                    continue;
-                }
-                try {
-                    if (!$newfile = $fs->get_file_by_hash(sha1("/$context->id/$component/$filearea/$itemid".$filepath))) {
-                        $fs->create_file_from_storedfile($file_record, $file);
-                    }
-                    $record->$field = str_replace($matches[0][$i], '@@PLUGINFILE@@'.$filepath, $record->$field);
-                } catch (Exception $ex) {
-                    // ignore problems
-                }
-                $DB->set_field($table, $field, $record->$field, array('id'=>$record->id));
-            }
-        }
-    }
-}
\ No newline at end of file
index 14dade6..53f766d 100644 (file)
@@ -1,5 +1,13 @@
 This files describes API changes in the book code.
 
+=== 3.1 ===
+
+* The following functions, previously used (exclusively) by upgrade steps are not available
+  anymore because of the upgrade cleanup performed for this version. See MDL-51580 for more info:
+    - mod_book_migrate_moddata_dir_to_legacy()
+    - mod_book_migrate_all_areas()
+    - mod_book_migrate_area()
+
 === 3.0 ===
 
 * External function mod_book_external::get_books_by_courses returned parameter "name" has been changed to PARAM_RAW,
@@ -8,4 +16,4 @@ This files describes API changes in the book code.
 === 2.7 ===
 
 * bogus legacy log calls were removed
-* \mod_book\event\chapter_deleted::set_legacy_logdata() was removed
\ No newline at end of file
+* \mod_book\event\chapter_deleted::set_legacy_logdata() was removed
diff --git a/portfolio/boxnet/db/upgradelib.php b/portfolio/boxnet/db/upgradelib.php
deleted file mode 100644 (file)
index fe87bd6..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Locallib.
- *
- * @package    portfolio_boxnet
- * @copyright  2013 Frédéric Massart
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Send a message to the admin in regard with the APIv1 migration.
- *
- * @return void
- */
-function portfolio_boxnet_admin_upgrade_notification() {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-    $a = new stdClass();
-    $a->docsurl = get_docs_url('Box.net_APIv1_migration');
-
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = get_admin();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('apiv1migration_message_small', 'portfolio_boxnet');
-        $message->subject           = get_string('apiv1migration_message_subject', 'portfolio_boxnet');
-        $message->fullmessage       = get_string('apiv1migration_message_content', 'portfolio_boxnet', $a);
-        $message->fullmessagehtml   = get_string('apiv1migration_message_content', 'portfolio_boxnet', $a);
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
diff --git a/portfolio/googledocs/db/upgradelib.php b/portfolio/googledocs/db/upgradelib.php
deleted file mode 100644 (file)
index 4658ed8..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Googledocs portfolio upgrade script.
- *
- * @package   portfolio_googledocs
- * @copyright 2013 Dan Poltawski <dan@moodle.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Inform admins about setup required for googledocs change.
- */
-function portfolio_googledocs_admin_upgrade_notification() {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-    $a = new stdClass;
-    $a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
-
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = get_admin();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('oauth2upgrade_message_small', 'portfolio_googledocs');
-        $message->subject           = get_string('oauth2upgrade_message_subject', 'portfolio_googledocs');
-        $message->fullmessage       = get_string('oauth2upgrade_message_content', 'portfolio_googledocs', $a);
-        $message->fullmessagehtml   = get_string('oauth2upgrade_message_content', 'portfolio_googledocs', $a);
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
diff --git a/portfolio/picasa/db/upgradelib.php b/portfolio/picasa/db/upgradelib.php
deleted file mode 100644 (file)
index a711cbf..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Picasa portfolio upgrade script.
- *
- * @package   portfolio_picasa
- * @copyright 2013 Dan Poltawski <dan@moodle.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Inform admins about setup required for picasa change.
- */
-function portfolio_picasa_admin_upgrade_notification() {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-    $a = new stdClass;
-    $a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
-
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = get_admin();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('oauth2upgrade_message_small', 'portfolio_picasa');
-        $message->subject           = get_string('oauth2upgrade_message_subject', 'portfolio_picasa');
-        $message->fullmessage       = get_string('oauth2upgrade_message_content', 'portfolio_picasa', $a);
-        $message->fullmessagehtml   = get_string('oauth2upgrade_message_content', 'portfolio_picasa', $a);
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
index 557a33b..49d4993 100644 (file)
@@ -1,6 +1,14 @@
 This files describes API changes in /portfolio/ portfolio system,
 information provided here is intended especially for developers.
 
+=== 3.1 ===
+
+* The following functions, previously used (exclusively) by upgrade steps are not available
+  anymore because of the upgrade cleanup performed for this version. See MDL-51580 for more info:
+    - portfolio_picasa_admin_upgrade_notification()
+    - portfolio_googledocs_admin_upgrade_notification()
+    - portfolio_boxnet_admin_upgrade_notification()
+
 === 2.4 ===
 
 The set_callback_options function's third parameter has been changed from a file path
index 2cd5513..470629c 100644 (file)
@@ -1,5 +1,11 @@
 This files describes API changes for question type plugins.
 
+=== 3.1 ===
+
+* The following functions, previously used (exclusively) by upgrade steps are not available
+  anymore because of the upgrade cleanup performed for this version. See MDL-51580 for more info:
+    - qtype_essay_convert_to_html()
+
 === 2.7 ===
   + We have added a new method to the question_type base class 'break_down_stats_and_response_analysis_by_variant'. By default it
    returns true. If your question type does not have variants of question instances then you can ignore this method as it only
diff --git a/repository/alfresco/db/upgradelib.php b/repository/alfresco/db/upgradelib.php
deleted file mode 100644 (file)
index 1a363e6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Locallib.
- *
- * @package    repository_alfresco
- * @copyright  2014 Frédéric Massart
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Send a message to the admin in regard with the APIv1 migration.
- *
- * @return void
- */
-function repository_alfresco_admin_security_key_notice() {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = get_admin();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('security_key_notice_message_small', 'repository_alfresco');
-        $message->subject           = get_string('security_key_notice_message_subject', 'repository_alfresco');
-        $message->fullmessage       = get_string('security_key_notice_message_content', 'repository_alfresco');
-        $message->fullmessagehtml   = get_string('security_key_notice_message_content', 'repository_alfresco');
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
diff --git a/repository/boxnet/db/upgradelib.php b/repository/boxnet/db/upgradelib.php
deleted file mode 100644 (file)
index c0cf9de..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Locallib.
- *
- * @package    repository_boxnet
- * @copyright  2013 Frédéric Massart
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Send a message to the admin in regard with the APIv1 migration.
- *
- * @return void
- */
-function repository_boxnet_admin_upgrade_notification() {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-    $a = new stdClass();
-    $a->docsurl = get_docs_url('Box.net_APIv1_migration');
-
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = get_admin();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('apiv1migration_message_small', 'repository_boxnet');
-        $message->subject           = get_string('apiv1migration_message_subject', 'repository_boxnet');
-        $message->fullmessage       = get_string('apiv1migration_message_content', 'repository_boxnet', $a);
-        $message->fullmessagehtml   = get_string('apiv1migration_message_content', 'repository_boxnet', $a);
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
diff --git a/repository/googledocs/db/upgradelib.php b/repository/googledocs/db/upgradelib.php
deleted file mode 100644 (file)
index c065bd0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Googledocs repository upgrade script.
- *
- * @package   repository_googledocs
- * @copyright 2013 Dan Poltawski <dan@moodle.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Inform admins about setup required for googledocs change.
- */
-function repository_googledocs_admin_upgrade_notification() {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-
-    $a = new stdClass;
-    $a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = get_admin();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('oauth2upgrade_message_small', 'repository_googledocs');
-        $message->subject           = get_string('oauth2upgrade_message_subject', 'repository_googledocs');
-        $message->fullmessage       = get_string('oauth2upgrade_message_content', 'repository_googledocs', $a);
-        $message->fullmessagehtml   = get_string('oauth2upgrade_message_content', 'repository_googledocs', $a);
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
diff --git a/repository/picasa/db/upgradelib.php b/repository/picasa/db/upgradelib.php
deleted file mode 100644 (file)
index 4d76af5..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Picasa repository upgrade script.
- *
- * @package   repository_picasa
- * @copyright 2013 Dan Poltawski <dan@moodle.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Inform admins about setup required for google picasa change.
- */
-function repository_picasa_admin_upgrade_notification() {
-    $admins = get_admins();
-
-    if (empty($admins)) {
-        return;
-    }
-    $a = new stdClass;
-    $a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
-
-    foreach ($admins as $admin) {
-        $message = new stdClass();
-        $message->component         = 'moodle';
-        $message->name              = 'notices';
-        $message->userfrom          = get_admin();
-        $message->userto            = $admin;
-        $message->smallmessage      = get_string('oauth2upgrade_message_small', 'repository_picasa');
-        $message->subject           = get_string('oauth2upgrade_message_subject', 'repository_picasa');
-        $message->fullmessage       = get_string('oauth2upgrade_message_content', 'repository_picasa', $a);
-        $message->fullmessagehtml   = get_string('oauth2upgrade_message_content', 'repository_picasa', $a);
-        $message->fullmessageformat = FORMAT_PLAIN;
-        $message->notification      = 1;
-        message_send($message);
-    }
-}
index e47ba3b..e190f81 100644 (file)
@@ -3,6 +3,15 @@ information provided here is intended especially for developers. Full
 details of the repository API are available on Moodle docs:
 http://docs.moodle.org/dev/Repository_API
 
+=== 3.1 ===
+
+* The following functions, previously used (exclusively) by upgrade steps are not available
+  anymore because of the upgrade cleanup performed for this version. See MDL-51580 for more info:
+    - repository_picasa_admin_upgrade_notification()
+    - repository_googledocs_admin_upgrade_notification()
+    - repository_boxnet_admin_upgrade_notification()
+    - repository_alfresco_admin_security_key_notice()
+
 === 2.8 ===
 
 * Repositories working with Moodle files must replace serialize() with json_encode() in the