Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 204... Línea 204...
204
    foreach ($courses as $course) {
204
    foreach ($courses as $course) {
205
        $possiblecourseids[$course->id] = $course->id;
205
        $possiblecourseids[$course->id] = $course->id;
206
    }
206
    }
Línea 207... Línea 207...
207
 
207
 
208
    if (!empty($possiblecourseids)) {
208
    if (!empty($possiblecourseids)) {
209
        list($sql, $params) = $DB->get_in_or_equal($possiblecourseids);
209
        [$sql, $params] = $DB->get_in_or_equal($possiblecourseids);
210
        // A calculated grade item grade min != 0 and grade max != 100 and the course setting is set to
210
        // A calculated grade item grade min != 0 and grade max != 100 and the course setting is set to
211
        // "Initial min and max grades".
211
        // "Initial min and max grades".
212
        $coursesql = "SELECT DISTINCT courseid
212
        $coursesql = "SELECT DISTINCT courseid
213
                        FROM {grade_items}
213
                        FROM {grade_items}
Línea 236... Línea 236...
236
        foreach ($calculatedgradecategories as $key => $gradecategory) {
236
        foreach ($calculatedgradecategories as $key => $gradecategory) {
237
            $categoryids[$key] = $gradecategory->id;
237
            $categoryids[$key] = $gradecategory->id;
238
        }
238
        }
Línea 239... Línea 239...
239
 
239
 
240
        if (!empty($categoryids)) {
240
        if (!empty($categoryids)) {
241
            list($sql, $params) = $DB->get_in_or_equal($categoryids);
241
            [$sql, $params] = $DB->get_in_or_equal($categoryids);
242
            // A category with a calculation where the raw grade min and the raw grade max don't match the grade min and grade max
242
            // A category with a calculation where the raw grade min and the raw grade max don't match the grade min and grade max
243
            // for the category.
243
            // for the category.
244
            $coursesql = "SELECT DISTINCT gi.courseid
244
            $coursesql = "SELECT DISTINCT gi.courseid
245
                            FROM {grade_grades} gg, {grade_items} gi
245
                            FROM {grade_grades} gg, {grade_items} gi
Línea 268... Línea 268...
268
    }
268
    }
269
}
269
}
Línea 270... Línea 270...
270
 
270
 
271
/**
271
/**
272
 * This function creates a default separated/connected scale
272
 * This function creates a default separated/connected scale
273
 * so there's something in the database.  The locations of
-
 
274
 * strings and files is a bit odd, but this is because we
-
 
275
 * need to maintain backward compatibility with many different
-
 
276
 * existing language translations and older sites.
273
 * so there's something in the database.
277
 *
274
 *
278
 * @global object
275
 * @global object
279
 * @return void
276
 * @return void
280
 */
277
 */
Línea 284... Línea 281...
284
    $defaultscale = new stdClass();
281
    $defaultscale = new stdClass();
285
    $defaultscale->courseid = 0;
282
    $defaultscale->courseid = 0;
286
    $defaultscale->userid = 0;
283
    $defaultscale->userid = 0;
287
    $defaultscale->name  = get_string('separateandconnected');
284
    $defaultscale->name  = get_string('separateandconnected');
288
    $defaultscale->description = get_string('separateandconnectedinfo');
285
    $defaultscale->description = get_string('separateandconnectedinfo');
289
    $defaultscale->scale = get_string('postrating1', 'forum').','.
286
    $defaultscale->scale = get_string('separateandconnected1') . ',' .
290
                           get_string('postrating2', 'forum').','.
287
        get_string('separateandconnected2') . ',' .
291
                           get_string('postrating3', 'forum');
288
        get_string('separateandconnected3');
292
    $defaultscale->timemodified = time();
289
    $defaultscale->timemodified = time();
Línea 293... Línea 290...
293
 
290
 
294
    $defaultscale->id = $DB->insert_record('scale', $defaultscale);
291
    $defaultscale->id = $DB->insert_record('scale', $defaultscale);
295
    return $defaultscale;
292
    return $defaultscale;
Línea 630... Línea 627...
630
        '3.11dev' => '2021042100.02',
627
        '3.11dev' => '2021042100.02',
631
        '4.0dev'  => '2021052500.85',
628
        '4.0dev'  => '2021052500.85',
632
    ];
629
    ];
Línea 633... Línea 630...
633
 
630
 
634
    $targetsteps = array_merge(array_values($badsteps), array_values( $fixsteps));
631
    $targetsteps = array_merge(array_values($badsteps), array_values( $fixsteps));
635
    list($insql, $inparams) = $DB->get_in_or_equal($targetsteps);
632
    [$insql, $inparams] = $DB->get_in_or_equal($targetsteps);
636
    $foundsteps = $DB->get_fieldset_sql("
633
    $foundsteps = $DB->get_fieldset_sql("
637
        SELECT DISTINCT version
634
        SELECT DISTINCT version
638
          FROM {upgrade_log}
635
          FROM {upgrade_log}
639
         WHERE plugin = 'core'
636
         WHERE plugin = 'core'
Línea 1424... Línea 1421...
1424
        $sql = <<<EOF
1421
        $sql = <<<EOF
1425
            UPDATE {block_instances} bi, {block_instance_context} bic
1422
            UPDATE {block_instances} bi, {block_instance_context} bic
1426
               SET bi.parentcontextid = bic.contextid
1423
               SET bi.parentcontextid = bic.contextid
1427
             WHERE bi.id = bic.instanceid
1424
             WHERE bi.id = bic.instanceid
1428
        EOF;
1425
        EOF;
1429
    } else if ($dbfamily === 'oracle') {
-
 
1430
        $sql = <<<EOF
-
 
1431
            UPDATE {block_instances} bi
-
 
1432
            SET (bi.parentcontextid) = (
-
 
1433
                SELECT bic.contextid
-
 
1434
                  FROM {block_instance_context} bic
-
 
1435
                 WHERE bic.instanceid = bi.id
-
 
1436
            ) WHERE EXISTS (
-
 
1437
                SELECT 'x'
-
 
1438
                  FROM {block_instance_context} bic
-
 
1439
                 WHERE bic.instanceid = bi.id
-
 
1440
            )
-
 
1441
        EOF;
-
 
1442
    } else {
1426
    } else {
1443
        // Postgres and sqlsrv.
1427
        // Postgres and sqlsrv.
1444
        $sql = <<<EOF
1428
        $sql = <<<EOF
1445
            UPDATE {block_instances}
1429
            UPDATE {block_instances}
1446
            SET parentcontextid = bic.contextid
1430
            SET parentcontextid = bic.contextid
Línea 1822... Línea 1806...
1822
    $table = new xmldb_table('payment_accounts');
1806
    $table = new xmldb_table('payment_accounts');
1823
    $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
1807
    $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
1824
    // Launch add key contextid.
1808
    // Launch add key contextid.
1825
    $dbman->add_key($table, $key);
1809
    $dbman->add_key($table, $key);
1826
}
1810
}
-
 
1811
 
-
 
1812
/**
-
 
1813
 * Upgrade helper to change a binary column to an integer column with a length of 1 in a consistent manner across databases.
-
 
1814
 *
-
 
1815
 * This function will
-
 
1816
 * - rename the existing column to a temporary name,
-
 
1817
 * - add a new column with the integer type,
-
 
1818
 * - copy the values from the old column to the new column,
-
 
1819
 * - and finally, drop the old column.
-
 
1820
 *
-
 
1821
 * This function will do nothing if the field is already an integer.
-
 
1822
 *
-
 
1823
 * The new column with the integer type will need to have a default value of 0.
-
 
1824
 * This is to avoid breaking the not null constraint, if it's set, especially if there are existing records.
-
 
1825
 * Please make sure that the column definition in install.xml also has the `DEFAULT` attribute value set to 0.
-
 
1826
 *
-
 
1827
 * @param string $tablename The name of the table.
-
 
1828
 * @param string $fieldname The name of the field to be converted.
-
 
1829
 * @param bool|null $notnull {@see XMLDB_NOTNULL} or null.
-
 
1830
 * @param string|null $previous The name of the field that this field should come after.
-
 
1831
 * @return bool
-
 
1832
 */
-
 
1833
function upgrade_change_binary_column_to_int(
-
 
1834
    string $tablename,
-
 
1835
    string $fieldname,
-
 
1836
    ?bool $notnull = null,
-
 
1837
    ?string $previous = null,
-
 
1838
): bool {
-
 
1839
    global $DB;
-
 
1840
 
-
 
1841
    // Get the information about the field to be converted.
-
 
1842
    $columns = $DB->get_columns($tablename);
-
 
1843
    $toconvert = $columns[$fieldname];
-
 
1844
 
-
 
1845
    // Check if the field to be converted is already an integer-type column (`meta_type` property of 'I').
-
 
1846
    if ($toconvert->meta_type === 'I') {
-
 
1847
        // Nothing to do if the field is already an integer-type.
-
 
1848
        return false;
-
 
1849
    } else if (!$toconvert->binary) {
-
 
1850
        throw new \core\exception\coding_exception(
-
 
1851
            'This function is only used to convert XMLDB_TYPE_BINARY fields to XMLDB_TYPE_INTEGER fields. '
-
 
1852
            . 'For other field types, please check out \database_manager::change_field_type()'
-
 
1853
        );
-
 
1854
    }
-
 
1855
 
-
 
1856
    $dbman = $DB->get_manager();
-
 
1857
    $table = new xmldb_table($tablename);
-
 
1858
    // Temporary rename the field. We'll drop this later.
-
 
1859
    $tmpfieldname = "tmp$fieldname";
-
 
1860
    $field = new xmldb_field($fieldname, XMLDB_TYPE_BINARY);
-
 
1861
    $dbman->rename_field($table, $field, $tmpfieldname);
-
 
1862
 
-
 
1863
    // Add the new field wih the integer type.
-
 
1864
    $field = new xmldb_field($fieldname, XMLDB_TYPE_INTEGER, '1', null, $notnull, null, '0', $previous);
-
 
1865
    $dbman->add_field($table, $field);
-
 
1866
 
-
 
1867
    // Copy the 'true' values from the old field to the new field.
-
 
1868
    $sql = 'UPDATE {' . $tablename . '}
-
 
1869
               SET ' . $fieldname . ' = 1
-
 
1870
             WHERE ' . $tmpfieldname . ' = ?';
-
 
1871
    $DB->execute($sql, [1]);
-
 
1872
 
-
 
1873
    // Drop the old field.
-
 
1874
    $oldfield = new xmldb_field($tmpfieldname);
-
 
1875
    $dbman->drop_field($table, $oldfield);
-
 
1876
 
-
 
1877
    return true;
-
 
1878
}
-
 
1879
 
-
 
1880
/**
-
 
1881
 * Upgrade script replacing absolute URLs in defaulthomepage setting with relative URLs
-
 
1882
 */
-
 
1883
function upgrade_store_relative_url_sitehomepage() {
-
 
1884
    global $CFG, $DB;
-
 
1885
 
-
 
1886
    if (str_starts_with((string)$CFG->defaulthomepage, $CFG->wwwroot . '/')) {
-
 
1887
        set_config('defaulthomepage', substr((string)$CFG->defaulthomepage, strlen($CFG->wwwroot)));
-
 
1888
    }
-
 
1889
 
-
 
1890
    $records = $DB->get_records_select('user_preferences', "name = :name AND " . $DB->sql_like('value', ':pattern'),
-
 
1891
        ['name' => 'user_home_page_preference', 'pattern' => 'http%']);
-
 
1892
    foreach ($records as $record) {
-
 
1893
        if (str_starts_with($record->value, $CFG->wwwroot . '/')) {
-
 
1894
            $DB->update_record('user_preferences', [
-
 
1895
                'id' => $record->id,
-
 
1896
                'value' => substr($record->value, strlen($CFG->wwwroot)),
-
 
1897
            ]);
-
 
1898
        }
-
 
1899
    }
-
 
1900
}
-
 
1901
 
-
 
1902
/**
-
 
1903
 * Upgrade script to convert existing AI providers to provider instances.
-
 
1904
 */
-
 
1905
function upgrade_convert_ai_providers_to_instances() {
-
 
1906
    global $DB;
-
 
1907
    // Start with the azureai provider.
-
 
1908
    // Only migrate the provider if it is enabled.
-
 
1909
    $azureaiconfig = get_config('aiprovider_azureai');
-
 
1910
    if (!empty($azureaiconfig->enabled) || !empty($azureaiconfig->apikey)) {
-
 
1911
        // Create the instance config. We don't want everything from the provider config.
-
 
1912
        $instanceconfig = [
-
 
1913
            'aiprovider' => \aiprovider_azureai\provider::class,
-
 
1914
            'name' => get_string('pluginname', 'aiprovider_azureai'),
-
 
1915
            'apikey' => $azureaiconfig->apikey ?? '',
-
 
1916
            'endpoint' => $azureaiconfig->endpoint ?? '',
-
 
1917
            'enableglobalratelimit' => $azureaiconfig->enableglobalratelimit ?? 0,
-
 
1918
            'globalratelimit' => $azureaiconfig->globalratelimit ?? 100,
-
 
1919
            'enableuserratelimit' => $azureaiconfig->enableuserratelimit ?? 0,
-
 
1920
            'userratelimit' => $azureaiconfig->userratelimit ?? 10,
-
 
1921
        ];
-
 
1922
        $actionconfig = [
-
 
1923
            'core_ai\aiactions\generate_text' => [
-
 
1924
                'enabled' => $azureaiconfig->generate_text ?? true,
-
 
1925
                'settings' => [
-
 
1926
                    'deployment' => $azureaiconfig->action_generate_text_deployment ?? '',
-
 
1927
                    'apiversion' => $azureaiconfig->action_generate_text_apiversion ?? '2024-06-01',
-
 
1928
                    'systeminstruction' => $azureaiconfig->action_generate_text_systeminstruction
-
 
1929
                        ?? get_string('action_generate_text_instruction', 'core_ai'),
-
 
1930
                ],
-
 
1931
            ],
-
 
1932
            'core_ai\aiactions\generate_image' => [
-
 
1933
                'enabled' => $azureaiconfig->generate_image ?? true,
-
 
1934
                'settings' => [
-
 
1935
                    'deployment' => $azureaiconfig->action_generate_image_deployment ?? '',
-
 
1936
                    'apiversion' => $azureaiconfig->action_generate_image_apiversion ?? '2024-06-01',
-
 
1937
                ],
-
 
1938
            ],
-
 
1939
            'core_ai\aiactions\summarise_text' => [
-
 
1940
                'enabled' => $azureaiconfig->summarise_text ?? true,
-
 
1941
                'settings' => [
-
 
1942
                    'deployment' => $azureaiconfig->action_summarise_text_deployment ?? '',
-
 
1943
                    'apiversion' => $azureaiconfig->action_summarise_text_apiversion ?? '2024-06-01',
-
 
1944
                    'systeminstruction' => $azureaiconfig->action_generate_text_systeminstruction
-
 
1945
                        ?? get_string('action_summarise_text_instruction', 'core_ai'),
-
 
1946
                ],
-
 
1947
            ],
-
 
1948
        ];
-
 
1949
 
-
 
1950
        // Because of the upgrade code restrictions we insert directly into the database and don't use the AI manager class.
-
 
1951
        $record = new stdClass();
-
 
1952
        $record->name = get_string('pluginname', 'aiprovider_azureai');
-
 
1953
        $record->provider = \aiprovider_azureai\provider::class;
-
 
1954
        $record->enabled = $azureaiconfig->enabled ?? false;
-
 
1955
        $record->config = json_encode($instanceconfig);
-
 
1956
        $record->actionconfig = json_encode($actionconfig);
-
 
1957
 
-
 
1958
        $DB->insert_record('ai_providers', $record);
-
 
1959
    }
-
 
1960
 
-
 
1961
    // Now do the same for the openai provider.
-
 
1962
    $openaiconfig = get_config('aiprovider_openai');
-
 
1963
    if (!empty($openaiconfig->enabled) || !empty($openaiconfig->apikey)) {
-
 
1964
        // Create the instance config. We don't want everything from the provider config.
-
 
1965
        $instanceconfig = [
-
 
1966
            'aiprovider' => \aiprovider_openai\provider::class,
-
 
1967
            'name' => get_string('pluginname', 'aiprovider_openai'),
-
 
1968
            'apikey' => $openaiconfig->apikey ?? '',
-
 
1969
            'orgid' => $openaiconfig->orgid ?? '',
-
 
1970
            'enableglobalratelimit' => $openaiconfig->enableglobalratelimit ?? 0,
-
 
1971
            'globalratelimit' => $openaiconfig->globalratelimit ?? 100,
-
 
1972
            'enableuserratelimit' => $openaiconfig->enableuserratelimit ?? 0,
-
 
1973
            'userratelimit' => $openaiconfig->userratelimit ?? 10,
-
 
1974
        ];
-
 
1975
        $actionconfig = [
-
 
1976
            'core_ai\aiactions\generate_text' => [
-
 
1977
                'enabled' => $openaiconfig->generate_text ?? true,
-
 
1978
                'settings' => [
-
 
1979
                    'model' => $openaiconfig->action_generate_text_model ?? 'gpt-4o',
-
 
1980
                    'endpoint' => $openaiconfig->action_generate_text_endpoint ?? 'https://api.openai.com/v1/chat/completions',
-
 
1981
                    'systeminstruction' => $openaiconfig->action_generate_text_systeminstruction
-
 
1982
                        ?? get_string('action_generate_text_instruction', 'core_ai'),
-
 
1983
                ],
-
 
1984
            ],
-
 
1985
            'core_ai\aiactions\generate_image' => [
-
 
1986
                'enabled' => $openaiconfig->generate_image ?? true,
-
 
1987
                'settings' => [
-
 
1988
                    'model' => $openaiconfig->action_generate_text_model ?? 'dall-e-3',
-
 
1989
                    'endpoint' => $openaiconfig->action_generate_text_endpoint ?? 'https://api.openai.com/v1/images/generations',
-
 
1990
                ],
-
 
1991
            ],
-
 
1992
            'core_ai\aiactions\summarise_text' => [
-
 
1993
                'enabled' => $openaiconfig->summarise_text ?? true,
-
 
1994
                'settings' => [
-
 
1995
                    'model' => $openaiconfig->action_generate_text_model ?? 'gpt-4o',
-
 
1996
                    'endpoint' => $openaiconfig->action_generate_text_endpoint ?? 'https://api.openai.com/v1/chat/completions',
-
 
1997
                    'systeminstruction' => $openaiconfig->action_generate_text_systeminstruction
-
 
1998
                        ?? get_string('action_summarise_text_instruction', 'core_ai'),
-
 
1999
                ],
-
 
2000
            ],
-
 
2001
        ];
-
 
2002
 
-
 
2003
        $record = new stdClass();
-
 
2004
        $record->name = get_string('pluginname', 'aiprovider_openai');
-
 
2005
        $record->provider = \aiprovider_openai\provider::class;
-
 
2006
        $record->enabled = $openaiconfig->enabled ?? false;
-
 
2007
        $record->config = json_encode($instanceconfig);
-
 
2008
        $record->actionconfig = json_encode($actionconfig);
-
 
2009
 
-
 
2010
        $DB->insert_record('ai_providers', $record);
-
 
2011
    }
-
 
2012
 
-
 
2013
    // Finally remove the config settings from the plugin config table.
-
 
2014
    $azuresettings = ['enabled', 'apikey', 'endpoint', 'enableglobalratelimit', 'globalratelimit',
-
 
2015
        'enableuserratelimit', 'userratelimit', 'generate_text', 'action_generate_text_enabled', 'action_generate_text_deployment',
-
 
2016
        'action_generate_text_apiversion', 'action_generate_text_systeminstruction', 'generate_image',
-
 
2017
        'action_generate_image_enabled', 'action_generate_image_deployment', 'action_generate_image_apiversion',
-
 
2018
        'summarise_text', 'action_summarise_text_enabled', 'action_summarise_text_deployment', 'action_summarise_text_apiversion',
-
 
2019
        'action_summarise_text_systeminstruction'];
-
 
2020
    array_walk($azuresettings, static fn($setting) => unset_config($setting, 'aiprovider_azureai'));
-
 
2021
    $openaisettings = ['enabled', 'apikey', 'orgid', 'enableglobalratelimit', 'globalratelimit',
-
 
2022
        'enableuserratelimit', 'userratelimit', 'generate_text', 'action_generate_text_enabled', 'action_generate_text_model',
-
 
2023
        'action_generate_text_endpoint', 'action_generate_text_systeminstruction', 'generate_image',
-
 
2024
        'action_generate_image_enabled', 'action_generate_image_model', 'action_generate_image_endpoint',
-
 
2025
        'summarise_text', 'action_summarise_text_enabled', 'action_summarise_text_model', 'action_summarise_text_endpoint',
-
 
2026
        'action_summarise_text_systeminstruction'];
-
 
2027
    array_walk($openaisettings, static fn($setting) => unset_config($setting, 'aiprovider_openai'));
-
 
2028
}
-
 
2029
 
-
 
2030
/**
-
 
2031
 * Upgrade script to get all current AI providers and update their action config to include explain.
-
 
2032
 */
-
 
2033
function upgrade_add_explain_action_to_ai_providers() {
-
 
2034
    global $DB;
-
 
2035
    $currentrecords = $DB->get_recordset('ai_providers');
-
 
2036
 
-
 
2037
    foreach ($currentrecords as $currentrecord) {
-
 
2038
        $actionconfig = json_decode($currentrecord->actionconfig, true);
-
 
2039
        if ($currentrecord->provider === 'aiprovider_openai\provider') {
-
 
2040
            $explainconfig = [
-
 
2041
                'enabled' => true,
-
 
2042
                'settings' => [
-
 
2043
                    'model' => 'gpt-4o',
-
 
2044
                    'endpoint' => 'https://api.openai.com/v1/chat/completions',
-
 
2045
                    'systeminstruction' => get_string('action_explain_text_instruction', 'core_ai'),
-
 
2046
                ],
-
 
2047
            ];
-
 
2048
        } else if ($currentrecord->provider === 'aiprovider_azureai\provider') {
-
 
2049
            $explainconfig = [
-
 
2050
                'enabled' => true,
-
 
2051
                'settings' => [
-
 
2052
                    'deployment' => '',
-
 
2053
                    'apiversion' => '2024-06-01',
-
 
2054
                    'systeminstruction' => get_string('action_explain_text_instruction', 'core_ai'),
-
 
2055
                ],
-
 
2056
            ];
-
 
2057
        }
-
 
2058
 
-
 
2059
        // Update the record with the changes.
-
 
2060
        if (!empty($explainconfig)) {
-
 
2061
            $actionconfig['core_ai\aiactions\explain_text'] = $explainconfig;
-
 
2062
            $currentrecord->actionconfig = json_encode($actionconfig);
-
 
2063
            $DB->update_record('ai_providers', $currentrecord);
-
 
2064
        }
-
 
2065
    }
-
 
2066
 
-
 
2067
    $currentrecords->close();
-
 
2068
}
-
 
2069
 
-
 
2070
/**
-
 
2071
 * Creates a new ad-hoc task to upgrade the mime-type of files asynchronously.
-
 
2072
 * Thus, we can considerably reduce the time an upgrade takes.
-
 
2073
 *
-
 
2074
 * @param string $mimetype the desired mime-type
-
 
2075
 * @param string[] $extensions a list of file extensions, without the leading dot
-
 
2076
 * @return void
-
 
2077
 */
-
 
2078
function upgrade_create_async_mimetype_upgrade_task(string $mimetype, array $extensions): void {
-
 
2079
    global $DB;
-
 
2080
 
-
 
2081
    // Create adhoc task for upgrading of existing files. Due to a code restriction on the upgrade, invoking any core
-
 
2082
    // functions is not permitted. Thus we craft our own ad-hoc task that will process all existing files.
-
 
2083
    $record = new \stdClass();
-
 
2084
    $record->classname = '\core_files\task\asynchronous_mimetype_upgrade_task';
-
 
2085
    $record->component = 'core';
-
 
2086
    $record->customdata = json_encode([
-
 
2087
        'mimetype' => $mimetype,
-
 
2088
        'extensions' => $extensions,
-
 
2089
    ]);
-
 
2090
 
-
 
2091
    // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
-
 
2092
    $clock = \core\di::get(\core\clock::class);
-
 
2093
    $nextruntime = $clock->time() - 1;
-
 
2094
    $record->nextruntime = $nextruntime;
-
 
2095
 
-
 
2096
    $DB->insert_record('task_adhoc', $record);
-
 
2097
}