license: built full stack, test and documentation
This commit is contained in:
63
backend/database/factories/Lists/LicenseFactory.php
Normal file
63
backend/database/factories/Lists/LicenseFactory.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Lists;
|
||||
|
||||
use App\Enums\LicenseKind;
|
||||
use App\Models\Lists\License;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<License>
|
||||
*/
|
||||
class LicenseFactory extends Factory
|
||||
{
|
||||
protected $model = License::class;
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => ucfirst(fake()->unique()->words(3, true)),
|
||||
'acronym' => strtoupper(fake()->unique()->bothify('??-#.#')),
|
||||
'spdx_id' => null,
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => fake()->sentence(),
|
||||
'uri' => fake()->url(),
|
||||
'file' => null,
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => fake()->numberBetween(0, 100),
|
||||
'active' => true,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Licenza aperta ammessa anche per i record.
|
||||
*/
|
||||
public function forRecord(): static
|
||||
{
|
||||
return $this->state(fn () => ['for_record' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rights statement (nessun testo legale, nessun id SPDX).
|
||||
*/
|
||||
public function rightsStatement(): static
|
||||
{
|
||||
return $this->state(fn () => [
|
||||
'kind' => LicenseKind::RightsStatement,
|
||||
'spdx_id' => null,
|
||||
'file' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Licenza ritirata dagli admin (esclusa dalle select dei form).
|
||||
*/
|
||||
public function inactive(): static
|
||||
{
|
||||
return $this->state(fn () => ['active' => false]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Vocabolario delle licenze applicabili a record (artifact/model) e media.
|
||||
*
|
||||
* - `spdx_id`: identificatore SPDX ufficiale, NULL per marchi e rights
|
||||
* statement (che non stanno nella SPDX License List) — mai inventarne.
|
||||
* - `uri`: URI canonico della licenza (creativecommons.org /
|
||||
* rightsstatements.org), usato anche nel JSON-LD Linked Art.
|
||||
* - `file`: nome del testo legale in LICENSES/media/ da includere nello
|
||||
* zip di download; NULL dove un testo non esiste (mark/statement).
|
||||
* - `for_record`/`for_media`: scope della licenza, filtrano le select dei
|
||||
* form (i record ammettono solo licenze aperte, i media tutte).
|
||||
* - `active`: disattivazione soft da parte degli admin senza rompere le
|
||||
* FK dei contenuti già licenziati.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('licenses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name', 200)->unique();
|
||||
$table->string('acronym', 50)->unique();
|
||||
$table->string('spdx_id', 50)->nullable()->unique();
|
||||
$table->string('kind', 20)->default('license');
|
||||
$table->text('description')->nullable();
|
||||
$table->string('uri', 2000)->nullable();
|
||||
$table->string('file', 512)->nullable();
|
||||
$table->boolean('for_record')->default(false);
|
||||
$table->boolean('for_media')->default(true);
|
||||
$table->unsignedInteger('sort_order')->default(0);
|
||||
$table->boolean('active')->default(true);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('licenses');
|
||||
}
|
||||
};
|
||||
@@ -20,6 +20,7 @@ class DatabaseSeeder extends Seeder
|
||||
SystemUserSeeder::class,
|
||||
InstitutionCategorySeeder::class,
|
||||
UserPositionSeeder::class,
|
||||
LicenseSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
223
backend/database/seeders/LicenseSeeder.php
Normal file
223
backend/database/seeders/LicenseSeeder.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\LicenseKind;
|
||||
use App\Models\Lists\License;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* Vocabolario delle licenze. Idempotente, gira in installazione (la tabella
|
||||
* NON è popolata dall'ETL).
|
||||
*
|
||||
* Gli id 1-3 sono FISSI e coincidono con il DB legacy (v1: 1=Public Domain,
|
||||
* 2=CC0, 3=CC BY) così l'ETL mapperà le FK di artifact/media 1:1.
|
||||
*
|
||||
* Set iniziale: famiglia Creative Commons 4.0 + Public Domain Mark + i tre
|
||||
* rights statement più comuni (InC, InC-EDU, CNE). Gli altri statement di
|
||||
* RightsStatements.org (InC-NC, NoC-NC, NKC, UND, ...) si aggiungono al
|
||||
* bisogno dal pannello admin.
|
||||
*
|
||||
* `file` è il nome del testo legale in storage/app/public/licenses/ (incluso
|
||||
* nello zip di download dei media e servito al frontend via storage:link);
|
||||
* NULL per mark e rights statement, che non hanno un testo legale. I testi CC
|
||||
* sono dedicati al pubblico dominio da Creative Commons:
|
||||
* https://creativecommons.org/policies/#license
|
||||
*/
|
||||
class LicenseSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
foreach ($this->licenses() as $id => $license) {
|
||||
License::updateOrCreate(['id' => $id], $license);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function licenses(): array
|
||||
{
|
||||
return $this->openLicenses() + $this->rightsStatements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Public Domain Mark + famiglia Creative Commons 4.0.
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function openLicenses(): array
|
||||
{
|
||||
return [
|
||||
1 => [
|
||||
'name' => 'Public Domain Mark 1.0',
|
||||
'acronym' => 'PDM 1.0',
|
||||
'spdx_id' => null,
|
||||
'kind' => LicenseKind::Mark,
|
||||
'description' => 'Marks works that are already free of known copyright worldwide (for '
|
||||
.'instance because copyright has expired). It is not a license: it declares '
|
||||
.'an existing status and grants no new permission.',
|
||||
'uri' => 'https://creativecommons.org/publicdomain/mark/1.0/',
|
||||
'file' => null,
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 10,
|
||||
'active' => true,
|
||||
],
|
||||
2 => [
|
||||
'name' => 'CC0 1.0 Universal',
|
||||
'acronym' => 'CC0 1.0',
|
||||
'spdx_id' => 'CC0-1.0',
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => 'Public domain dedication: the rights holder waives all copyright and '
|
||||
.'related rights worldwide. The work can be copied, modified and reused for '
|
||||
.'any purpose, even commercially, without attribution.',
|
||||
'uri' => 'https://creativecommons.org/publicdomain/zero/1.0/',
|
||||
'file' => 'CC0-1.0.txt',
|
||||
'for_record' => true,
|
||||
'for_media' => true,
|
||||
'sort_order' => 20,
|
||||
'active' => true,
|
||||
],
|
||||
3 => [
|
||||
'name' => 'Attribution 4.0 International',
|
||||
'acronym' => 'CC BY 4.0',
|
||||
'spdx_id' => 'CC-BY-4.0',
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => 'Reuse, redistribution and modification allowed for any purpose, including '
|
||||
.'commercial, provided that credit is given to the creator.',
|
||||
'uri' => 'https://creativecommons.org/licenses/by/4.0/',
|
||||
'file' => 'CC-BY-4.0.txt',
|
||||
'for_record' => true,
|
||||
'for_media' => true,
|
||||
'sort_order' => 30,
|
||||
'active' => true,
|
||||
],
|
||||
4 => [
|
||||
'name' => 'Attribution-ShareAlike 4.0 International',
|
||||
'acronym' => 'CC BY-SA 4.0',
|
||||
'spdx_id' => 'CC-BY-SA-4.0',
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => 'Same permissions as CC BY, but derivative works must be distributed under '
|
||||
.'the same license (share-alike).',
|
||||
'uri' => 'https://creativecommons.org/licenses/by-sa/4.0/',
|
||||
'file' => 'CC-BY-SA-4.0.txt',
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 40,
|
||||
'active' => true,
|
||||
],
|
||||
5 => [
|
||||
'name' => 'Attribution-NonCommercial 4.0 International',
|
||||
'acronym' => 'CC BY-NC 4.0',
|
||||
'spdx_id' => 'CC-BY-NC-4.0',
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => 'Reuse and modification allowed with attribution, for non-commercial '
|
||||
.'purposes only.',
|
||||
'uri' => 'https://creativecommons.org/licenses/by-nc/4.0/',
|
||||
'file' => 'CC-BY-NC-4.0.txt',
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 50,
|
||||
'active' => true,
|
||||
],
|
||||
6 => [
|
||||
'name' => 'Attribution-NonCommercial-ShareAlike 4.0 International',
|
||||
'acronym' => 'CC BY-NC-SA 4.0',
|
||||
'spdx_id' => 'CC-BY-NC-SA-4.0',
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => 'Non-commercial reuse and modification with attribution; derivative works '
|
||||
.'must keep the same license.',
|
||||
'uri' => 'https://creativecommons.org/licenses/by-nc-sa/4.0/',
|
||||
'file' => 'CC-BY-NC-SA-4.0.txt',
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 60,
|
||||
'active' => true,
|
||||
],
|
||||
7 => [
|
||||
'name' => 'Attribution-NoDerivatives 4.0 International',
|
||||
'acronym' => 'CC BY-ND 4.0',
|
||||
'spdx_id' => 'CC-BY-ND-4.0',
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => 'Redistribution allowed, even commercially, with attribution, but the work '
|
||||
.'must remain unmodified: no derivative works.',
|
||||
'uri' => 'https://creativecommons.org/licenses/by-nd/4.0/',
|
||||
'file' => 'CC-BY-ND-4.0.txt',
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 70,
|
||||
'active' => true,
|
||||
],
|
||||
8 => [
|
||||
'name' => 'Attribution-NonCommercial-NoDerivatives 4.0 International',
|
||||
'acronym' => 'CC BY-NC-ND 4.0',
|
||||
'spdx_id' => 'CC-BY-NC-ND-4.0',
|
||||
'kind' => LicenseKind::License,
|
||||
'description' => 'The most restrictive CC license: the work can be shared with attribution, '
|
||||
.'but cannot be modified nor used commercially.',
|
||||
'uri' => 'https://creativecommons.org/licenses/by-nc-nd/4.0/',
|
||||
'file' => 'CC-BY-NC-ND-4.0.txt',
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 80,
|
||||
'active' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Statement di RightsStatements.org: etichettano lo stato dei diritti dei
|
||||
* media chiusi o incerti, non concedono permessi (nessun testo legale,
|
||||
* nessun id SPDX).
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function rightsStatements(): array
|
||||
{
|
||||
return [
|
||||
9 => [
|
||||
'name' => 'In Copyright',
|
||||
'acronym' => 'InC',
|
||||
'spdx_id' => null,
|
||||
'kind' => LicenseKind::RightsStatement,
|
||||
'description' => 'The item is protected by copyright and all rights are reserved. Any reuse '
|
||||
.'beyond legal exceptions requires permission from the rights holder.',
|
||||
'uri' => 'https://rightsstatements.org/vocab/InC/1.0/',
|
||||
'file' => null,
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 90,
|
||||
'active' => true,
|
||||
],
|
||||
10 => [
|
||||
'name' => 'In Copyright - Educational Use Permitted',
|
||||
'acronym' => 'InC-EDU',
|
||||
'spdx_id' => null,
|
||||
'kind' => LicenseKind::RightsStatement,
|
||||
'description' => 'The item is protected by copyright, but the rights holder allows reuse for '
|
||||
.'educational purposes without further permission.',
|
||||
'uri' => 'https://rightsstatements.org/vocab/InC-EDU/1.0/',
|
||||
'file' => null,
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 100,
|
||||
'active' => true,
|
||||
],
|
||||
11 => [
|
||||
'name' => 'Copyright Not Evaluated',
|
||||
'acronym' => 'CNE',
|
||||
'spdx_id' => null,
|
||||
'kind' => LicenseKind::RightsStatement,
|
||||
'description' => 'The copyright status of the item has not been evaluated yet. The item '
|
||||
.'should be treated as potentially protected: reuse may require permission.',
|
||||
'uri' => 'https://rightsstatements.org/vocab/CNE/1.0/',
|
||||
'file' => null,
|
||||
'for_record' => false,
|
||||
'for_media' => true,
|
||||
'sort_order' => 110,
|
||||
'active' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user