diff --git a/admin/tool/licensemanager/tests/behat/license_manager.feature b/admin/tool/licensemanager/tests/behat/license_manager.feature index 5ab86353b30..e85890f6441 100644 --- a/admin/tool/licensemanager/tests/behat/license_manager.feature +++ b/admin/tool/licensemanager/tests/behat/license_manager.feature @@ -10,12 +10,12 @@ Feature: Licence manager Then I should see "Licence not specified" in the "unknown" "table_row" And I should see "All rights reserved" in the "allrightsreserved" "table_row" And I should see "Public domain" in the "public" "table_row" - And I should see "Creative Commons" in the "cc" "table_row" - And I should see "Creative Commons - NoDerivs" in the "cc-nd" "table_row" - And I should see "Creative Commons - No Commercial NoDerivs" in the "cc-nc-nd" "table_row" - And I should see "Creative Commons - No Commercial" in the "cc-nc" "table_row" - And I should see "Creative Commons - No Commercial ShareAlike" in the "cc-nc-sa" "table_row" - And I should see "Creative Commons - ShareAlike" in the "cc-sa" "table_row" + And I should see "Creative Commons - 4.0 International" in the "cc-4.0" "table_row" + And I should see "Creative Commons - NoDerivatives 4.0 International" in the "cc-nd-4.0" "table_row" + And I should see "Creative Commons - NonCommercial-NoDerivatives 4.0 International" in the "cc-nc-nd-4.0" "table_row" + And I should see "Creative Commons - NonCommercial-ShareAlike 4.0 International" in the "cc-nc-sa-4.0" "table_row" + And I should see "Creative Commons - ShareAlike 4.0 International" in the "cc-sa-4.0" "table_row" + And I should see "Creative Commons - NonCommercial 4.0 International" in the "cc-nc-4.0" "table_row" Scenario: I should be able to enable and disable licences Given I log in as "admin" @@ -25,25 +25,25 @@ Feature: Licence manager And I navigate to "Licence > Licence manager" in site administration Then "This is the site default licence" "icon" should exist in the "public" "table_row" And "Enable licence" "icon" should not exist in the "public" "table_row" - And "This is the site default licence" "icon" should not exist in the "cc" "table_row" + And "This is the site default licence" "icon" should not exist in the "cc-4.0" "table_row" And I navigate to "Licence > Licence settings" in site administration And I set the field "Default site licence" to "Creative Commons" And I press "Save changes" And I navigate to "Licence > Licence manager" in site administration - And "This is the site default licence" "icon" should exist in the "cc" "table_row" - And "Enable licence" "icon" should not exist in the "cc" "table_row" + And "This is the site default licence" "icon" should exist in the "cc-4.0" "table_row" + And "Enable licence" "icon" should not exist in the "cc-4.0" "table_row" And "This is the site default licence" "icon" should not exist in the "public" "table_row" @javascript @_file_upload Scenario Outline: User licence preference is remembered depending of setting value Given the following config values are set as admin: - | sitedefaultlicense | cc | + | sitedefaultlicense | cc-4.0 | | rememberuserlicensepref | | And I log in as "admin" And I follow "Private files" in the user menu And I follow "Add..." And I follow "Upload a file" - And the field with xpath "//select[@name='license']" matches value "Creative Commons" + And the field with xpath "//select[@name='license']" matches value "Creative Commons - 4.0 International" And I click on "Close" "button" in the "File picker" "dialogue" When I upload "lib/tests/fixtures/empty.txt" file to "Files" filemanager as: | Save as | empty_copy.txt | @@ -53,6 +53,6 @@ Feature: Licence manager Then the field with xpath "//select[@name='license']" matches value "" Examples: - | rememberuserlicensepref | expectedlicence | - | 0 | Creative Commons | - | 1 | Public domain | + | rememberuserlicensepref | expectedlicence | + | 0 | Creative Commons - 4.0 International | + | 1 | Public domain | diff --git a/admin/tool/licensemanager/tests/manager_test.php b/admin/tool/licensemanager/tests/manager_test.php index e86cf68d633..2b9763c4ed4 100644 --- a/admin/tool/licensemanager/tests/manager_test.php +++ b/admin/tool/licensemanager/tests/manager_test.php @@ -174,24 +174,24 @@ class manager_test extends advanced_testcase { $this->resetAfterTest(); $licenseorder = array_keys(license_manager::get_licenses()); - $initialposition = array_search('cc-nc', $licenseorder); + $initialposition = array_search('cc-nc-4.0', $licenseorder); $manager = new tool_licensemanager\manager(); // We're testing a private method, so we need to setup reflector magic. $method = new ReflectionMethod('\tool_licensemanager\manager', 'change_license_order'); $method->setAccessible(true); // Allow accessing of private method. - $method->invoke($manager, \tool_licensemanager\manager::ACTION_MOVE_UP, 'cc-nc'); + $method->invoke($manager, \tool_licensemanager\manager::ACTION_MOVE_UP, 'cc-nc-4.0'); $licenseorder = array_keys(license_manager::get_licenses()); - $newposition = array_search('cc-nc', $licenseorder); + $newposition = array_search('cc-nc-4.0', $licenseorder); $this->assertLessThan($initialposition, $newposition); $initialposition = array_search('allrightsreserved', $licenseorder); $method->invoke($manager, \tool_licensemanager\manager::ACTION_MOVE_DOWN, 'allrightsreserved'); $licenseorder = array_keys(license_manager::get_licenses()); - $newposition = array_search('cc-nc', $licenseorder); + $newposition = array_search('cc-nc-4.0', $licenseorder); $this->assertGreaterThan($initialposition, $newposition); } diff --git a/lang/en/license.php b/lang/en/license.php index f33e68718bd..8b6c1cada8a 100644 --- a/lang/en/license.php +++ b/lang/en/license.php @@ -21,18 +21,27 @@ * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - // Core licenses. $string['allrightsreserved'] = 'All rights reserved'; -$string['cc'] = 'Creative Commons'; -$string['cc-nc'] = 'Creative Commons - No Commercial'; -$string['cc-nc-nd'] = 'Creative Commons - No Commercial NoDerivs'; -$string['cc-nc-sa'] = 'Creative Commons - No Commercial ShareAlike'; -$string['cc-nd'] = 'Creative Commons - NoDerivs'; -$string['cc-sa'] = 'Creative Commons - ShareAlike'; $string['public'] = 'Public domain'; $string['unknown'] = 'Licence not specified'; +// Old cc-* 3.0 licenses that should be disabled and replaces by the 4.0 licenses from above. +$string['cc'] = 'Creative Commons - 3.0 International'; +$string['cc-nc'] = 'Creative Commons - NonCommercial 3.0 International'; +$string['cc-nc-nd'] = 'Creative Commons - NonCommercial-NoDerivatives 3.0 International'; +$string['cc-nc-sa'] = 'Creative Commons - NonCommercial-ShareAlike 3.0 International'; +$string['cc-nd'] = 'Creative Commons - NoDerivatives 3.0 International'; +$string['cc-sa'] = 'Creative Commons - ShareAlike 3.0 International'; + +// The new 4.0 licenses. +$string['cc-4.0'] = 'Creative Commons - 4.0 International'; +$string['cc-nc-4.0'] = 'Creative Commons - NonCommercial 4.0 International'; +$string['cc-nc-nd-4.0'] = 'Creative Commons - NonCommercial-NoDerivatives 4.0 International'; +$string['cc-nc-sa-4.0'] = 'Creative Commons - NonCommercial-ShareAlike 4.0 International'; +$string['cc-nd-4.0'] = 'Creative Commons - NoDerivatives 4.0 International'; +$string['cc-sa-4.0'] = 'Creative Commons - ShareAlike 4.0 International'; + // Error messages. $string['cannotdeletecore'] = 'Cannot delete a standard licence'; $string['cannotdeletelicenseinuse'] = 'Cannot delete a licence which is currently assigned to one or more files'; diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index c1689528a8e..a4294d044f9 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -3326,12 +3326,16 @@ privatefiles,moodle|/user/files.php'; $sql = 'UPDATE {external_tokens} SET name = ' . $DB->sql_concat( // We only need the prefix, so leave the third param with an empty string. - "'" . get_string('tokennameprefix', 'webservice', '') . "'", - "id"); + "'" . get_string('tokennameprefix', 'webservice', '') . "'", + "id"); $DB->execute($sql); // Main savepoint reached. upgrade_main_savepoint(true, 2023062700.01); } + if ($oldversion < 2023062700.06) { + upgrade_core_licenses(); + upgrade_main_savepoint(true, 2023062700.06); + } if ($oldversion < 2023062900.01) { diff --git a/lib/db/upgradelib.php b/lib/db/upgradelib.php index 1b97d02bfb7..60a0f62573c 100644 --- a/lib/db/upgradelib.php +++ b/lib/db/upgradelib.php @@ -537,105 +537,59 @@ function upgrade_delete_orphaned_file_records() { function upgrade_core_licenses() { global $CFG, $DB; - $corelicenses = []; + $expectedlicenses = json_decode(file_get_contents($CFG->dirroot . '/lib/licenses.json'))->licenses; + if (!is_array($expectedlicenses)) { + $expectedlicenses = []; + } + $corelicenses = $DB->get_records('license', ['custom' => 0]); - $license = new stdClass(); - $license->shortname = 'unknown'; - $license->fullname = 'Licence not specified'; - $license->source = ''; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; + // Disable core licenses which are no longer current. + $todisable = array_diff( + array_map(fn ($license) => $license->shortname, $corelicenses), + array_map(fn ($license) => $license->shortname, $expectedlicenses), + ); - $license = new stdClass(); - $license->shortname = 'allrightsreserved'; - $license->fullname = 'All rights reserved'; - $license->source = 'https://en.wikipedia.org/wiki/All_rights_reserved'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; + // Disable any old *core* license that does not exist in the licenses.json file. + if (count($todisable)) { + [$where, $params] = $DB->get_in_or_equal($todisable, SQL_PARAMS_NAMED); + $DB->set_field_select( + 'license', + 'enabled', + 0, + "shortname {$where}", + $params + ); + } - $license = new stdClass(); - $license->shortname = 'public'; - $license->fullname = 'Public domain'; - $license->source = 'https://en.wikipedia.org/wiki/Public_domain'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; - - $license = new stdClass(); - $license->shortname = 'cc'; - $license->fullname = 'Creative Commons'; - $license->source = 'https://creativecommons.org/licenses/by/3.0/'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; - - $license = new stdClass(); - $license->shortname = 'cc-nd'; - $license->fullname = 'Creative Commons - NoDerivs'; - $license->source = 'https://creativecommons.org/licenses/by-nd/3.0/'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; - - $license = new stdClass(); - $license->shortname = 'cc-nc-nd'; - $license->fullname = 'Creative Commons - No Commercial NoDerivs'; - $license->source = 'https://creativecommons.org/licenses/by-nc-nd/3.0/'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; - - $license = new stdClass(); - $license->shortname = 'cc-nc'; - $license->fullname = 'Creative Commons - No Commercial'; - $license->source = 'https://creativecommons.org/licenses/by-nc/3.0/'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; - - $license = new stdClass(); - $license->shortname = 'cc-nc-sa'; - $license->fullname = 'Creative Commons - No Commercial ShareAlike'; - $license->source = 'https://creativecommons.org/licenses/by-nc-sa/3.0/'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; - - $license = new stdClass(); - $license->shortname = 'cc-sa'; - $license->fullname = 'Creative Commons - ShareAlike'; - $license->source = 'https://creativecommons.org/licenses/by-sa/3.0/'; - $license->enabled = 1; - $license->version = '2010033100'; - $license->custom = 0; - $corelicenses[] = $license; - - foreach ($corelicenses as $corelicense) { - // Check for current license to maintain idempotence. - $currentlicense = $DB->get_record('license', ['shortname' => $corelicense->shortname]); - if (!empty($currentlicense)) { - $corelicense->id = $currentlicense->id; - // Remember if the license was enabled before upgrade. - $corelicense->enabled = $currentlicense->enabled; - $DB->update_record('license', $corelicense); - } else if (!isset($CFG->upgraderunning) || during_initial_install()) { - // Only install missing core licenses if not upgrading or during initial install. - $DB->insert_record('license', $corelicense); + // Add any new licenses. + foreach ($expectedlicenses as $expectedlicense) { + if (!$expectedlicense->enabled) { + // Skip any license which is no longer enabled. + continue; + } + if (!$DB->record_exists('license', ['shortname' => $expectedlicense->shortname])) { + // If the license replaces an older one, check whether this old license was enabled or not. + $isreplacement = false; + foreach (array_reverse($expectedlicense->replaces ?? []) as $item) { + foreach ($corelicenses as $corelicense) { + if ($corelicense->shortname === $item) { + $expectedlicense->enabled = $corelicense->enabled; + // Also, keep the old sort order. + $expectedlicense->sortorder = $corelicense->sortorder * 100; + $isreplacement = true; + break 2; + } + } + } + if (!isset($CFG->upgraderunning) || during_initial_install() || $isreplacement) { + // Only install missing core licenses if not upgrading or during initial installation. + $DB->insert_record('license', $expectedlicense); + } } } - // Add sortorder to all licenses. - $licenses = $DB->get_records('license'); + // Add/renumber sortorder to all licenses. + $licenses = $DB->get_records('license', null, 'sortorder'); $sortorder = 1; foreach ($licenses as $license) { $license->sortorder = $sortorder++; diff --git a/lib/licenses.json b/lib/licenses.json new file mode 100644 index 00000000000..e6e82792421 --- /dev/null +++ b/lib/licenses.json @@ -0,0 +1,82 @@ +{ + "licenses": [ + { + "shortname": "unknown", + "fullname": "Licence not specified", + "source": "", + "enabled": 1, + "version": "2010033100", + "custom": 0 + }, + { + "shortname": "allrightsreserved", + "fullname": "All rights reserved", + "source": "https://en.wikipedia.org/wiki/All_rights_reserved", + "enabled": 1, + "version": "2010033100", + "custom": 0 + }, + { + "shortname": "public", + "fullname": "Public domain", + "source": "https://en.wikipedia.org/wiki/Public_domain", + "enabled": 1, + "version": "2010033100", + "custom": 0 + }, + { + "shortname": "cc-4.0", + "fullname": "Creative Commons - 4.0 International", + "source": "https://creativecommons.org/licenses/by/4.0/", + "enabled": 1, + "version": "2022120100", + "custom": 0, + "replaces": ["cc"] + }, + { + "shortname": "cc-nc-4.0", + "fullname": "Creative Commons - NonCommercial 4.0 International", + "source": "https://creativecommons.org/licenses/by-nc/4.0/", + "enabled": 1, + "version": "2022120100", + "custom": 0, + "replaces": ["cc-nc"] + }, + { + "shortname": "cc-nd-4.0", + "fullname": "Creative Commons - NoDerivatives 4.0 International", + "source": "https://creativecommons.org/licenses/by-nd/4.0/", + "enabled": 1, + "version": "2022120100", + "custom": 0, + "replaces": ["cc-nd"] + }, + { + "shortname": "cc-nc-nd-4.0", + "fullname": "Creative Commons - NonCommercial-NoDerivatives 4.0 International", + "source": "https://creativecommons.org/licenses/by-nc-nd/4.0/", + "enabled": 1, + "version": "2022120100", + "custom": 0, + "replaces": ["cc-nc-nd"] + }, + { + "shortname": "cc-nc-sa-4.0", + "fullname": "Creative Commons - NonCommercial-ShareAlike 4.0 International", + "source": "https://creativecommons.org/licenses/by-nc-sa/4.0/", + "enabled": 1, + "version": "2022120100", + "custom": 0, + "replaces": ["cc-nc-sa"] + }, + { + "shortname": "cc-sa-4.0", + "fullname": "Creative Commons - ShareAlike 4.0 International", + "source": "https://creativecommons.org/licenses/by-sa/4.0/", + "enabled": 1, + "version": "2022120100", + "custom": 0, + "replaces": ["cc-sa"] + } + ] +} \ No newline at end of file diff --git a/lib/tests/licenselib_test.php b/lib/tests/licenselib_test.php index ad257fcc017..15c152f4c1d 100644 --- a/lib/tests/licenselib_test.php +++ b/lib/tests/licenselib_test.php @@ -50,12 +50,12 @@ class licenselib_test extends advanced_testcase { $this->assertArrayHasKey('unknown', $licenses); $this->assertArrayHasKey('allrightsreserved', $licenses); $this->assertArrayHasKey('public', $licenses); - $this->assertArrayHasKey('cc', $licenses); - $this->assertArrayHasKey('cc-nd', $licenses); - $this->assertArrayHasKey('cc-nc-nd', $licenses); - $this->assertArrayHasKey('cc-nc', $licenses); - $this->assertArrayHasKey('cc-nc-sa', $licenses); - $this->assertArrayHasKey('cc-sa', $licenses); + $this->assertArrayHasKey('cc-4.0', $licenses); + $this->assertArrayHasKey('cc-nd-4.0', $licenses); + $this->assertArrayHasKey('cc-nc-nd-4.0', $licenses); + $this->assertArrayHasKey('cc-nc-4.0', $licenses); + $this->assertArrayHasKey('cc-nc-sa-4.0', $licenses); + $this->assertArrayHasKey('cc-sa-4.0', $licenses); // Get the licenses from cache and check again. $licenses = license_manager::get_licenses(); @@ -63,12 +63,12 @@ class licenselib_test extends advanced_testcase { $this->assertArrayHasKey('unknown', $licenses); $this->assertArrayHasKey('allrightsreserved', $licenses); $this->assertArrayHasKey('public', $licenses); - $this->assertArrayHasKey('cc', $licenses); - $this->assertArrayHasKey('cc-nd', $licenses); - $this->assertArrayHasKey('cc-nc-nd', $licenses); - $this->assertArrayHasKey('cc-nc', $licenses); - $this->assertArrayHasKey('cc-nc-sa', $licenses); - $this->assertArrayHasKey('cc-sa', $licenses); + $this->assertArrayHasKey('cc-4.0', $licenses); + $this->assertArrayHasKey('cc-nd-4.0', $licenses); + $this->assertArrayHasKey('cc-nc-nd-4.0', $licenses); + $this->assertArrayHasKey('cc-nc-4.0', $licenses); + $this->assertArrayHasKey('cc-nc-sa-4.0', $licenses); + $this->assertArrayHasKey('cc-sa-4.0', $licenses); } /** @@ -93,13 +93,13 @@ class licenselib_test extends advanced_testcase { $this->assertEquals('mit', $license->shortname); // Attempting to update a core license should only update sortorder. - $license->shortname = 'cc'; + $license->shortname = 'cc-4.0'; $license->sortorder = 33; license_manager::save($license); $record = $DB->get_record('license', ['id' => $license->id]); $this->assertNotEquals('cc', $record->shortname); - $record = $DB->get_record('license', ['shortname' => 'cc']); + $record = $DB->get_record('license', ['shortname' => 'cc-4.0']); $this->assertEquals(33, $record->sortorder); // Adding a license with existing custom license shortname should update existing license. @@ -122,10 +122,10 @@ class licenselib_test extends advanced_testcase { */ public function test_get_license_by_shortname() { - $license = license_manager::get_license_by_shortname('cc-nc'); + $license = license_manager::get_license_by_shortname('cc-nc-4.0'); $actual = $license->fullname; - $this->assertEquals('Creative Commons - No Commercial', $actual); + $this->assertEquals('Creative Commons - NonCommercial 4.0 International', $actual); $this->assertNull(license_manager::get_license_by_shortname('somefakelicense')); } @@ -138,11 +138,11 @@ class licenselib_test extends advanced_testcase { $this->resetAfterTest(); // Manually set license record to enabled for testing. - $DB->set_field('license', 'enabled', license_manager::LICENSE_ENABLED, ['shortname' => 'cc-nc']); + $DB->set_field('license', 'enabled', license_manager::LICENSE_ENABLED, ['shortname' => 'cc-nc-4.0']); - $this->assertTrue(license_manager::disable('cc-nc')); + $this->assertTrue(license_manager::disable('cc-nc-4.0')); - $license = license_manager::get_license_by_shortname('cc-nc'); + $license = license_manager::get_license_by_shortname('cc-nc-4.0'); $actual = $license->enabled; $this->assertEquals(license_manager::LICENSE_DISABLED, $actual); @@ -157,11 +157,11 @@ class licenselib_test extends advanced_testcase { $this->resetAfterTest(); // Manually set license record to disabled for testing. - $DB->set_field('license', 'enabled', license_manager::LICENSE_DISABLED, ['shortname' => 'cc-nc']); + $DB->set_field('license', 'enabled', license_manager::LICENSE_DISABLED, ['shortname' => 'cc-nc-4.0']); - $this->assertTrue(license_manager::enable('cc-nc')); + $this->assertTrue(license_manager::enable('cc-nc-4.0')); - $license = license_manager::get_license_by_shortname('cc-nc'); + $license = license_manager::get_license_by_shortname('cc-nc-4.0'); $actual = $license->enabled; $this->assertEquals(license_manager::LICENSE_ENABLED, $actual); @@ -229,7 +229,7 @@ class licenselib_test extends advanced_testcase { public function test_delete_license_core() { // Should not be able to delete a standard/core license. $this->expectException(moodle_exception::class); - license_manager::delete('cc-nc'); + license_manager::delete('cc-nc-4.0'); } /** @@ -312,15 +312,15 @@ class licenselib_test extends advanced_testcase { $this->assertEquals($licenses, $cachedlicenses); // Manually delete a license to see if cache persists. - $DB->delete_records('license', ['shortname' => 'cc-nc']); + $DB->delete_records('license', ['shortname' => 'cc-nc-4.0']); $licenses = license_manager::get_licenses(); - $this->assertArrayHasKey('cc-nc', $licenses); + $this->assertArrayHasKey('cc-nc-4.0', $licenses); license_manager::reset_license_cache(); $licenses = license_manager::get_licenses(); - $this->assertArrayNotHasKey('cc-nc', $licenses); + $this->assertArrayNotHasKey('cc-nc-4.0', $licenses); } /** @@ -335,7 +335,10 @@ class licenselib_test extends advanced_testcase { license_manager::install_licenses(); - $expectedshortnames = ['allrightsreserved', 'cc', 'cc-nc', 'cc-nc-nd', 'cc-nc-sa', 'cc-nd', 'cc-sa', 'public', 'unknown']; + $expectedshortnames = [ + 'allrightsreserved', 'public', 'unknown', + 'cc-4.0', 'cc-nc-4.0', 'cc-nc-nd-4.0', 'cc-nc-sa-4.0', 'cc-nd-4.0', 'cc-sa-4.0', + ]; $actualshortnames = $DB->get_records_menu('license', null, '', 'id, shortname'); foreach ($expectedshortnames as $expectedshortname) { diff --git a/lib/tests/upgradelib_test.php b/lib/tests/upgradelib_test.php index f3dd010a1e9..edf91f2c211 100644 --- a/lib/tests/upgradelib_test.php +++ b/lib/tests/upgradelib_test.php @@ -910,7 +910,7 @@ class upgradelib_test extends advanced_testcase { upgrade_core_licenses(); - $expectedshortnames = ['allrightsreserved', 'cc', 'cc-nc', 'cc-nc-nd', 'cc-nc-sa', 'cc-nd', 'cc-sa', 'public']; + $expectedshortnames = ['allrightsreserved', 'cc-4.0', 'cc-nc-4.0', 'cc-nc-nd-4.0', 'cc-nc-sa-4.0', 'cc-nd-4.0', 'cc-sa-4.0', 'public']; $licenses = $DB->get_records('license'); foreach ($licenses as $license) {