From 5a04a76557094c3396ddb59d9a2eaf80d55fc434 Mon Sep 17 00:00:00 2001 From: erseco Date: Mon, 28 Sep 2026 18:30:06 +0100 Subject: [PATCH 1/4] Use interactive content as the primary activity purpose Declare MOD_PURPOSE_INTERACTIVECONTENT as primary purpose and, on Moodle 5.1+, MOD_PURPOSE_ASSESSMENT as secondary purpose, like mod_h5pactivity and mod_lesson. FEATURE_MOD_OTHERPURPOSE is checked with defined() before the switch, since 4.5 and 5.0 do not define it. The branded icon keeps the purpose from tinting it. Supersedes DEC-37-01. Related to exelearning/exelearning#2454. --- docs/ARCHITECTURE.md | 14 ++-- docs/GRADEBOOK.md | 4 +- lib.php | 13 +++- ...EC-2454-01-proposito-interactivecontent.md | 73 +++++++++++++++++++ ...asificacion-funcional-archetype-purpose.md | 3 +- research/docs/indices/adrs.yaml | 1 + tests/supports_test.php | 20 ++++- 7 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index f28460d..da899b3 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -97,11 +97,15 @@ is **not** debt. ## Functional classification -`exelearning_supports()` declares `MOD_ARCHETYPE_ASSIGNMENT` + `MOD_PURPOSE_ASSESSMENT` -(`lib.php:52-79`). These are resolved per **module type**, not per instance, so they do -not vary with the per-activity `gradeenabled` switch ([[DEC-13-07]]); `gradeenabled = 0` -is a resource-like mode within an assessment-archetype module. Decision recorded in -[[DEC-37-01]]; see `docs/AUDIT_FOLLOWUP.md`. +`exelearning_supports()` declares `MOD_ARCHETYPE_ASSIGNMENT` with +`MOD_PURPOSE_INTERACTIVECONTENT` as primary purpose and, on Moodle 5.1+, +`MOD_PURPOSE_ASSESSMENT` as secondary purpose (`FEATURE_MOD_OTHERPURPOSE`, guarded +with `defined()` because 4.5 and 5.0 lack it). This matches core's own modules for +interactive content (`mod_h5pactivity`, `mod_lesson`). The purpose only places the +activity in the chooser: the icon is branded (`exelearning_is_branded()`), so it is +never tinted. These are resolved per **module type**, not per instance, so they do +not vary with the per-activity `gradeenabled` switch ([[DEC-13-07]]). Decision +recorded in [[DEC-2454-01]], which supersedes [[DEC-37-01]]. ## Global search diff --git a/docs/GRADEBOOK.md b/docs/GRADEBOOK.md index 19ab279..995cccb 100644 --- a/docs/GRADEBOOK.md +++ b/docs/GRADEBOOK.md @@ -160,7 +160,7 @@ History recorded while the activity **was** graded is untouched by all of this: **Caveat**: `FEATURE_GRADE_HAS_GRADE` is **static** — `exelearning_supports()` returns `true` unconditionally (`lib.php:66-67`), regardless of `gradeenabled`. So Moodle still classifies the activity type as gradable even when a given instance is not. This functional classification mismatch is tracked in the audit follow-up — see the new ADR -**DEC-37-01** (functional classification) and `docs/AUDIT_FOLLOWUP.md`. +**DEC-37-01**, superseded by **DEC-2454-01** (functional classification), and `docs/AUDIT_FOLLOWUP.md`. ## Worked example @@ -197,4 +197,4 @@ The Grading and Attempts sections of the activity form (`mod_form.php:78-227`), for the single-channel SCORM 1.2 pipeline). - `docs/PRIVACY_BACKUP_FILES.md` — backup/restore of `exelearning_grade_item` and attempt data (`backup/moodle2/backup_exelearning_stepslib.php`). -- `research/decisiones/adr/` — DEC-0-08, DEC-0-10, DEC-5-01, DEC-12-01, DEC-13-07, DEC-25-01, DEC-37-01, DEC-69-01. +- `research/decisiones/adr/` — DEC-0-08, DEC-0-10, DEC-5-01, DEC-12-01, DEC-13-07, DEC-25-01, DEC-37-01, DEC-69-01, DEC-2454-01. diff --git a/lib.php b/lib.php index 78feca8..7370063 100644 --- a/lib.php +++ b/lib.php @@ -50,6 +50,12 @@ * @return mixed */ function exelearning_supports($feature) { + // Moodle 5.1+ only: a secondary purpose also lists the activity under + // assessment (DEC-2454-01). Checked before the switch because evaluating the + // undefined constant as a case would throw on 4.5 and 5.0. + if (defined('FEATURE_MOD_OTHERPURPOSE') && $feature === FEATURE_MOD_OTHERPURPOSE) { + return MOD_PURPOSE_ASSESSMENT; + } switch ($feature) { case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_ASSIGNMENT; @@ -72,7 +78,9 @@ function exelearning_supports($feature) { case FEATURE_SHOW_DESCRIPTION: return true; case FEATURE_MOD_PURPOSE: - return MOD_PURPOSE_ASSESSMENT; + // Interactive content that may carry graded iDevices, like SCORM, H5P + // and Lesson (DEC-2454-01, supersedes DEC-37-01). + return MOD_PURPOSE_INTERACTIVECONTENT; default: return null; } @@ -82,8 +90,7 @@ function exelearning_supports($feature) { * Whether the activity icon is branded. * * Branded icons keep their own colours: Moodle skips the purpose colour filter - * that would otherwise tint the monologo pink for MOD_PURPOSE_ASSESSMENT - * (exelearning/exelearning issue 2453). The purpose itself stays unchanged. + * that would otherwise tint the monologo (exelearning/exelearning issue 2453). * * @return bool Always true, so pix/monologo.svg renders in the official colour. */ diff --git a/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md b/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md new file mode 100644 index 0000000..56a1fc2 --- /dev/null +++ b/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md @@ -0,0 +1,73 @@ +--- +id: DEC-2454-01 +title: "Propósito del módulo: MOD_PURPOSE_INTERACTIVECONTENT como primario y ASSESSMENT como secundario" +status: Accepted +date: 2026-09-28 +tracking_issue: 2454 +supersedes: [DEC-37-01] +deciders: + - erseco + - claude-code +sources: + - REPO-004 +related: + adrs: [DEC-13-07, DEC-0-15] +ai_assistance: + tool: claude-code + model: claude-opus-5-5 +--- + +# DEC-2454-01: Propósito del módulo: MOD_PURPOSE_INTERACTIVECONTENT como primario y ASSESSMENT como secundario + +## Contexto + +`DEC-37-01` mantuvo `MOD_PURPOSE_ASSESSMENT` comparándolo solo con `RESOURCE`/`CONTENT`. +No valoró `MOD_PURPOSE_INTERACTIVECONTENT`, que es el propósito que core usa para los +módulos más parecidos. Como efecto secundario, el propósito teñía el icono de rosa +(exelearning/exelearning issue 2453); `exelearning_is_branded()` ya lo evita, así que el +propósito solo decide dónde aparece la actividad en el selector y en su filtro por +propósito. El número de seguimiento es el issue 2454 del repositorio +`exelearning/exelearning`, donde se centralizan los issues del plugin. + +## Evidencia + +Consultado en `moodle/moodle` el 2026-09-28 (`gh api repos/moodle/moodle/contents/...`): + +- `FEATURE_MOD_OTHERPURPOSE` se define en `public/lib/moodlelib.php:488` de + `MOODLE_501_STABLE` y `lib/moodlelib.php:488` de `MOODLE_502_STABLE`; no existe en + `MOODLE_405_STABLE` ni en `MOODLE_500_STABLE`. +- `MOD_PURPOSE_INTERACTIVECONTENT` existe en todas las ramas soportadas (4.5–5.2). +- `public/mod/h5pactivity/lib.php:58-59` (`MOODLE_501_STABLE`) declara + `FEATURE_MOD_PURPOSE => MOD_PURPOSE_INTERACTIVECONTENT` y + `FEATURE_MOD_OTHERPURPOSE => MOD_PURPOSE_ASSESSMENT`, sin archetype propio. + +| Módulo | Propósito primario | Secundario (5.1+) | +|---|---|---| +| `mod_scorm` | `INTERACTIVECONTENT` | `CONTENT` | +| `mod_h5pactivity` | `INTERACTIVECONTENT` | `ASSESSMENT` | +| `mod_lesson` | `INTERACTIVECONTENT` | `ASSESSMENT` | + +## Decisión + +- Propósito primario: `MOD_PURPOSE_INTERACTIVECONTENT`. +- Propósito secundario: `MOD_PURPOSE_ASSESSMENT`, como H5P y Lesson. `CONTENT` (el de + SCORM) encaja peor: el plugin califica por iDevice y sincroniza con el gradebook. +- `FEATURE_MOD_OTHERPURPOSE` se comprueba con `defined()` antes del `switch` de + `exelearning_supports()`. Evaluar la constante como `case` lanzaría un `Error` en 4.5 + y 5.0 para cualquier feature no reconocida. +- Se mantiene `MOD_ARCHETYPE_ASSIGNMENT`. Cambiarlo no lo pide el issue y afecta a + valores por defecto (grupos, finalización) que `DEC-37-01` justificó; queda como + pregunta abierta separada. + +## Consecuencias + +- **Positivas:** la actividad aparece junto a SCORM y H5P, que es donde la buscan los + docentes; sigue la taxonomía de core; en 5.1+ también aparece bajo evaluación. +- **Negativas:** en 4.5 y 5.0 solo aparece como contenido interactivo. En sitios + existentes la actividad cambia de categoría en el selector. +- **Sin riesgo visual:** el icono es de marca y no se tiñe. + +## Validación + +`tests/supports_test.php` fija el propósito primario y, cuando la constante existe, el +secundario (en 4.5 y 5.0 ese caso se omite). La matriz de CI cubre 4.5–5.2. diff --git a/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md b/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md index 0ee3b4c..6e64bf8 100644 --- a/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md +++ b/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md @@ -1,7 +1,8 @@ --- id: DEC-37-01 title: "Clasificación funcional del módulo: mantener MOD_ARCHETYPE_ASSIGNMENT + MOD_PURPOSE_ASSESSMENT" -status: Accepted +status: Superseded +superseded_by: DEC-2454-01 date: 2026-06-11 tracking_issue: 37 legacy_id: DEC-0047 diff --git a/research/docs/indices/adrs.yaml b/research/docs/indices/adrs.yaml index ef13a38..32707b7 100644 --- a/research/docs/indices/adrs.yaml +++ b/research/docs/indices/adrs.yaml @@ -72,3 +72,4 @@ items: - id: 'DEC-124-03', titulo: 'DEC-124-03-lo-hecho-sin-calificacion-nunca-se-convierte-en-nota', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-124-03-lo-hecho-sin-calificacion-nunca-se-convierte-en-nota.md' - id: 'DEC-125-01', titulo: 'DEC-125-01-linea-base-de-cambio-por-objectid', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-125-01-linea-base-de-cambio-por-objectid.md' - id: 'DEC-126-01', titulo: 'DEC-126-01-con-la-calificacion-apagada-no-se-registra-nada', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-126-01-con-la-calificacion-apagada-no-se-registra-nada.md' + - id: 'DEC-2454-01', titulo: 'DEC-2454-01-proposito-interactivecontent', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-2454-01-proposito-interactivecontent.md' diff --git a/tests/supports_test.php b/tests/supports_test.php index 590f9cc..f7fd0e2 100644 --- a/tests/supports_test.php +++ b/tests/supports_test.php @@ -36,12 +36,13 @@ */ final class supports_test extends advanced_testcase { /** - * DEC-37-01: the module is an assessment-archetype activity. The classification - * is fixed per module type and must not silently change. + * DEC-2454-01: the module is interactive content (like SCORM, H5P and Lesson) + * that may carry graded iDevices. The classification is fixed per module type + * and must not silently change. */ - public function test_supports_reports_assessment_classification(): void { + public function test_supports_reports_interactive_content_classification(): void { $this->assertSame(MOD_ARCHETYPE_ASSIGNMENT, exelearning_supports(FEATURE_MOD_ARCHETYPE)); - $this->assertSame(MOD_PURPOSE_ASSESSMENT, exelearning_supports(FEATURE_MOD_PURPOSE)); + $this->assertSame(MOD_PURPOSE_INTERACTIVECONTENT, exelearning_supports(FEATURE_MOD_PURPOSE)); $this->assertTrue(exelearning_supports(FEATURE_GRADE_HAS_GRADE)); $this->assertTrue(exelearning_supports(FEATURE_BACKUP_MOODLE2)); $this->assertTrue(exelearning_supports(FEATURE_MOD_INTRO)); @@ -53,6 +54,17 @@ public function test_supports_reports_assessment_classification(): void { $this->assertNull(exelearning_supports('a_feature_that_does_not_exist')); } + /** + * DEC-2454-01: on Moodle 5.1+ the module is also listed under assessment, as a + * secondary purpose. Older branches do not define the feature at all. + */ + public function test_supports_reports_assessment_as_secondary_purpose(): void { + if (!defined('FEATURE_MOD_OTHERPURPOSE')) { + $this->markTestSkipped('FEATURE_MOD_OTHERPURPOSE exists from Moodle 5.1.'); + } + $this->assertSame(MOD_PURPOSE_ASSESSMENT, exelearning_supports(FEATURE_MOD_OTHERPURPOSE)); + } + /** * The icon is branded so Moodle does not tint it with the assessment purpose * colour, and the monologo carries the official colour. From 28e0204ad9b2268dc71c3a5cc0c657ead768a0be Mon Sep 17 00:00:00 2001 From: erseco Date: Mon, 28 Sep 2026 18:34:10 +0100 Subject: [PATCH 2/4] Use the default archetype so the chooser lists the module On Moodle 4.5 and 5.0 the activity chooser fills its Activities tab with archetype 0 (MOD_ARCHETYPE_OTHER) only. MOD_ARCHETYPE_ASSIGNMENT (2) kept eXeLearning out of it, visible under All only. Core uses the constant for nothing else, so drop it like SCORM, H5P and Lesson do. --- docs/ARCHITECTURE.md | 3 ++- lib.php | 4 ++-- .../DEC-2454-01-proposito-interactivecontent.md | 16 +++++++++++----- tests/supports_test.php | 4 +++- version.php | 2 +- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index da899b3..9436049 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -97,7 +97,8 @@ is **not** debt. ## Functional classification -`exelearning_supports()` declares `MOD_ARCHETYPE_ASSIGNMENT` with +`exelearning_supports()` keeps the default archetype (`MOD_ARCHETYPE_OTHER`, which the +4.5 and 5.0 activity chooser needs to list the module under "Activities") and declares `MOD_PURPOSE_INTERACTIVECONTENT` as primary purpose and, on Moodle 5.1+, `MOD_PURPOSE_ASSESSMENT` as secondary purpose (`FEATURE_MOD_OTHERPURPOSE`, guarded with `defined()` because 4.5 and 5.0 lack it). This matches core's own modules for diff --git a/lib.php b/lib.php index 7370063..68424bd 100644 --- a/lib.php +++ b/lib.php @@ -56,9 +56,9 @@ function exelearning_supports($feature) { if (defined('FEATURE_MOD_OTHERPURPOSE') && $feature === FEATURE_MOD_OTHERPURPOSE) { return MOD_PURPOSE_ASSESSMENT; } + // No FEATURE_MOD_ARCHETYPE: the default (MOD_ARCHETYPE_OTHER) is what lists the + // module under the chooser's "Activities" tab on 4.5 and 5.0 (DEC-2454-01). switch ($feature) { - case FEATURE_MOD_ARCHETYPE: - return MOD_ARCHETYPE_ASSIGNMENT; case FEATURE_GROUPS: return true; case FEATURE_GROUPINGS: diff --git a/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md b/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md index 56a1fc2..bbbd3f0 100644 --- a/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md +++ b/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md @@ -55,19 +55,25 @@ Consultado en `moodle/moodle` el 2026-09-28 (`gh api repos/moodle/moodle/content - `FEATURE_MOD_OTHERPURPOSE` se comprueba con `defined()` antes del `switch` de `exelearning_supports()`. Evaluar la constante como `case` lanzaría un `Error` en 4.5 y 5.0 para cualquier feature no reconocida. -- Se mantiene `MOD_ARCHETYPE_ASSIGNMENT`. Cambiarlo no lo pide el issue y afecta a - valores por defecto (grupos, finalización) que `DEC-37-01` justificó; queda como - pregunta abierta separada. +- Se retira `MOD_ARCHETYPE_ASSIGNMENT` y el módulo usa el archetype por defecto + (`MOD_ARCHETYPE_OTHER`), como SCORM, H5P, Lesson y la propia Tarea. En 4.5 y 5.0 el + selector reparte las pestañas por archetype: `course/amd/src/activitychooser.js:261-262` + (imagen `erseco/alpine-moodle:v5.0.7`) filtra "Actividades" con `archetype === 0` y + "Recursos" con `archetype === 1`. Con el valor 2 el módulo solo salía en "Todos". + Core no usa `MOD_ARCHETYPE_ASSIGNMENT` en ningún otro sitio (solo lo define en + `lib/moodlelib.php:481`), así que los valores por defecto de grupos y finalización + que citaba `DEC-37-01` vienen de sus propias features, no del archetype. ## Consecuencias - **Positivas:** la actividad aparece junto a SCORM y H5P, que es donde la buscan los - docentes; sigue la taxonomía de core; en 5.1+ también aparece bajo evaluación. + docentes; en 4.5 y 5.0 vuelve a salir en la pestaña "Actividades"; sigue la taxonomía + de core; en 5.1+ también aparece bajo evaluación. - **Negativas:** en 4.5 y 5.0 solo aparece como contenido interactivo. En sitios existentes la actividad cambia de categoría en el selector. - **Sin riesgo visual:** el icono es de marca y no se tiñe. ## Validación -`tests/supports_test.php` fija el propósito primario y, cuando la constante existe, el +`tests/supports_test.php` fija el archetype por defecto, el propósito primario y, cuando la constante existe, el secundario (en 4.5 y 5.0 ese caso se omite). La matriz de CI cubre 4.5–5.2. diff --git a/tests/supports_test.php b/tests/supports_test.php index f7fd0e2..6b934da 100644 --- a/tests/supports_test.php +++ b/tests/supports_test.php @@ -41,7 +41,9 @@ final class supports_test extends advanced_testcase { * and must not silently change. */ public function test_supports_reports_interactive_content_classification(): void { - $this->assertSame(MOD_ARCHETYPE_ASSIGNMENT, exelearning_supports(FEATURE_MOD_ARCHETYPE)); + // Default archetype: 4.5 and 5.0 list only MOD_ARCHETYPE_OTHER under "Activities". + $this->assertNull(exelearning_supports(FEATURE_MOD_ARCHETYPE)); + $this->assertSame(MOD_ARCHETYPE_OTHER, plugin_supports('mod', 'exelearning', FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER)); $this->assertSame(MOD_PURPOSE_INTERACTIVECONTENT, exelearning_supports(FEATURE_MOD_PURPOSE)); $this->assertTrue(exelearning_supports(FEATURE_GRADE_HAS_GRADE)); $this->assertTrue(exelearning_supports(FEATURE_BACKUP_MOODLE2)); diff --git a/version.php b/version.php index a90fa12..baed7e6 100644 --- a/version.php +++ b/version.php @@ -34,7 +34,7 @@ // in $plugin->release ('dev'); a release-preparation PR commits the final // version + semver release BEFORE the tag is created (see DEVELOPMENT.md, // "Versioning and releases"). -$plugin->version = 2026092610; +$plugin->version = 2026092613; $plugin->release = 'dev'; $plugin->requires = 2024100700; // Moodle 4.5 LTS+. $plugin->supported = [405, 502]; // Moodle 4.5 LTS through Moodle 5.2. From 9bfea226adabd92de9b10254b174d5c246e7ba01 Mon Sep 17 00:00:00 2001 From: erseco Date: Mon, 28 Sep 2026 18:41:55 +0100 Subject: [PATCH 3/4] Number the purpose ADR after its pull request The proposal lives in exelearning/exelearning#2454; this repository has no matching issue, so the decision takes the PR number (DEC-159-01). --- docs/ARCHITECTURE.md | 2 +- docs/GRADEBOOK.md | 4 ++-- lib.php | 6 +++--- ....md => DEC-159-01-proposito-interactivecontent.md} | 11 ++++++----- ...37-01-clasificacion-funcional-archetype-purpose.md | 2 +- research/docs/indices/adrs.yaml | 2 +- tests/supports_test.php | 4 ++-- 7 files changed, 16 insertions(+), 15 deletions(-) rename research/decisiones/adr/{DEC-2454-01-proposito-interactivecontent.md => DEC-159-01-proposito-interactivecontent.md} (91%) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 9436049..8e6a7b5 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -106,7 +106,7 @@ interactive content (`mod_h5pactivity`, `mod_lesson`). The purpose only places t activity in the chooser: the icon is branded (`exelearning_is_branded()`), so it is never tinted. These are resolved per **module type**, not per instance, so they do not vary with the per-activity `gradeenabled` switch ([[DEC-13-07]]). Decision -recorded in [[DEC-2454-01]], which supersedes [[DEC-37-01]]. +recorded in [[DEC-159-01]], which supersedes [[DEC-37-01]]. ## Global search diff --git a/docs/GRADEBOOK.md b/docs/GRADEBOOK.md index 995cccb..963c43a 100644 --- a/docs/GRADEBOOK.md +++ b/docs/GRADEBOOK.md @@ -160,7 +160,7 @@ History recorded while the activity **was** graded is untouched by all of this: **Caveat**: `FEATURE_GRADE_HAS_GRADE` is **static** — `exelearning_supports()` returns `true` unconditionally (`lib.php:66-67`), regardless of `gradeenabled`. So Moodle still classifies the activity type as gradable even when a given instance is not. This functional classification mismatch is tracked in the audit follow-up — see the new ADR -**DEC-37-01**, superseded by **DEC-2454-01** (functional classification), and `docs/AUDIT_FOLLOWUP.md`. +**DEC-37-01**, superseded by **DEC-159-01** (functional classification), and `docs/AUDIT_FOLLOWUP.md`. ## Worked example @@ -197,4 +197,4 @@ The Grading and Attempts sections of the activity form (`mod_form.php:78-227`), for the single-channel SCORM 1.2 pipeline). - `docs/PRIVACY_BACKUP_FILES.md` — backup/restore of `exelearning_grade_item` and attempt data (`backup/moodle2/backup_exelearning_stepslib.php`). -- `research/decisiones/adr/` — DEC-0-08, DEC-0-10, DEC-5-01, DEC-12-01, DEC-13-07, DEC-25-01, DEC-37-01, DEC-69-01, DEC-2454-01. +- `research/decisiones/adr/` — DEC-0-08, DEC-0-10, DEC-5-01, DEC-12-01, DEC-13-07, DEC-25-01, DEC-37-01, DEC-69-01, DEC-159-01. diff --git a/lib.php b/lib.php index 68424bd..e27eefe 100644 --- a/lib.php +++ b/lib.php @@ -51,13 +51,13 @@ */ function exelearning_supports($feature) { // Moodle 5.1+ only: a secondary purpose also lists the activity under - // assessment (DEC-2454-01). Checked before the switch because evaluating the + // assessment (DEC-159-01). Checked before the switch because evaluating the // undefined constant as a case would throw on 4.5 and 5.0. if (defined('FEATURE_MOD_OTHERPURPOSE') && $feature === FEATURE_MOD_OTHERPURPOSE) { return MOD_PURPOSE_ASSESSMENT; } // No FEATURE_MOD_ARCHETYPE: the default (MOD_ARCHETYPE_OTHER) is what lists the - // module under the chooser's "Activities" tab on 4.5 and 5.0 (DEC-2454-01). + // module under the chooser's "Activities" tab on 4.5 and 5.0 (DEC-159-01). switch ($feature) { case FEATURE_GROUPS: return true; @@ -79,7 +79,7 @@ function exelearning_supports($feature) { return true; case FEATURE_MOD_PURPOSE: // Interactive content that may carry graded iDevices, like SCORM, H5P - // and Lesson (DEC-2454-01, supersedes DEC-37-01). + // and Lesson (DEC-159-01, supersedes DEC-37-01). return MOD_PURPOSE_INTERACTIVECONTENT; default: return null; diff --git a/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md b/research/decisiones/adr/DEC-159-01-proposito-interactivecontent.md similarity index 91% rename from research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md rename to research/decisiones/adr/DEC-159-01-proposito-interactivecontent.md index bbbd3f0..94f7b4c 100644 --- a/research/decisiones/adr/DEC-2454-01-proposito-interactivecontent.md +++ b/research/decisiones/adr/DEC-159-01-proposito-interactivecontent.md @@ -1,9 +1,9 @@ --- -id: DEC-2454-01 +id: DEC-159-01 title: "Propósito del módulo: MOD_PURPOSE_INTERACTIVECONTENT como primario y ASSESSMENT como secundario" status: Accepted date: 2026-09-28 -tracking_issue: 2454 +tracking_issue: 159 supersedes: [DEC-37-01] deciders: - erseco @@ -17,7 +17,7 @@ ai_assistance: model: claude-opus-5-5 --- -# DEC-2454-01: Propósito del módulo: MOD_PURPOSE_INTERACTIVECONTENT como primario y ASSESSMENT como secundario +# DEC-159-01: Propósito del módulo: MOD_PURPOSE_INTERACTIVECONTENT como primario y ASSESSMENT como secundario ## Contexto @@ -26,8 +26,9 @@ No valoró `MOD_PURPOSE_INTERACTIVECONTENT`, que es el propósito que core usa p módulos más parecidos. Como efecto secundario, el propósito teñía el icono de rosa (exelearning/exelearning issue 2453); `exelearning_is_branded()` ya lo evita, así que el propósito solo decide dónde aparece la actividad en el selector y en su filtro por -propósito. El número de seguimiento es el issue 2454 del repositorio -`exelearning/exelearning`, donde se centralizan los issues del plugin. +propósito. La propuesta es el issue exelearning/exelearning#2454 (los issues del plugin +se centralizan allí); como no hay issue en este repositorio, el ADR usa el número del +PR 159. ## Evidencia diff --git a/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md b/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md index 6e64bf8..baa28b0 100644 --- a/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md +++ b/research/decisiones/adr/DEC-37-01-clasificacion-funcional-archetype-purpose.md @@ -2,7 +2,7 @@ id: DEC-37-01 title: "Clasificación funcional del módulo: mantener MOD_ARCHETYPE_ASSIGNMENT + MOD_PURPOSE_ASSESSMENT" status: Superseded -superseded_by: DEC-2454-01 +superseded_by: DEC-159-01 date: 2026-06-11 tracking_issue: 37 legacy_id: DEC-0047 diff --git a/research/docs/indices/adrs.yaml b/research/docs/indices/adrs.yaml index 32707b7..73a4b34 100644 --- a/research/docs/indices/adrs.yaml +++ b/research/docs/indices/adrs.yaml @@ -72,4 +72,4 @@ items: - id: 'DEC-124-03', titulo: 'DEC-124-03-lo-hecho-sin-calificacion-nunca-se-convierte-en-nota', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-124-03-lo-hecho-sin-calificacion-nunca-se-convierte-en-nota.md' - id: 'DEC-125-01', titulo: 'DEC-125-01-linea-base-de-cambio-por-objectid', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-125-01-linea-base-de-cambio-por-objectid.md' - id: 'DEC-126-01', titulo: 'DEC-126-01-con-la-calificacion-apagada-no-se-registra-nada', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-126-01-con-la-calificacion-apagada-no-se-registra-nada.md' - - id: 'DEC-2454-01', titulo: 'DEC-2454-01-proposito-interactivecontent', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-2454-01-proposito-interactivecontent.md' + - id: 'DEC-159-01', titulo: 'DEC-159-01-proposito-interactivecontent', estado: None, fecha: None, ruta: 'decisiones/adr/DEC-159-01-proposito-interactivecontent.md' diff --git a/tests/supports_test.php b/tests/supports_test.php index 6b934da..c94c49a 100644 --- a/tests/supports_test.php +++ b/tests/supports_test.php @@ -36,7 +36,7 @@ */ final class supports_test extends advanced_testcase { /** - * DEC-2454-01: the module is interactive content (like SCORM, H5P and Lesson) + * DEC-159-01: the module is interactive content (like SCORM, H5P and Lesson) * that may carry graded iDevices. The classification is fixed per module type * and must not silently change. */ @@ -57,7 +57,7 @@ public function test_supports_reports_interactive_content_classification(): void } /** - * DEC-2454-01: on Moodle 5.1+ the module is also listed under assessment, as a + * DEC-159-01: on Moodle 5.1+ the module is also listed under assessment, as a * secondary purpose. Older branches do not define the feature at all. */ public function test_supports_reports_assessment_as_secondary_purpose(): void { From 5ff8ea0ed51292442b816bcc2663d2f5ea46395a Mon Sep 17 00:00:00 2001 From: erseco Date: Mon, 28 Sep 2026 19:09:52 +0100 Subject: [PATCH 4/4] Resolve the secondary purpose on a line every branch runs The early return only ran on Moodle 5.1+, while coverage is measured on 5.0, so the patch showed an uncovered line. --- lib.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib.php b/lib.php index e27eefe..31053e9 100644 --- a/lib.php +++ b/lib.php @@ -51,11 +51,9 @@ */ function exelearning_supports($feature) { // Moodle 5.1+ only: a secondary purpose also lists the activity under - // assessment (DEC-159-01). Checked before the switch because evaluating the + // assessment (DEC-159-01). Resolved here, not as a switch case: evaluating the // undefined constant as a case would throw on 4.5 and 5.0. - if (defined('FEATURE_MOD_OTHERPURPOSE') && $feature === FEATURE_MOD_OTHERPURPOSE) { - return MOD_PURPOSE_ASSESSMENT; - } + $otherpurpose = defined('FEATURE_MOD_OTHERPURPOSE') ? constant('FEATURE_MOD_OTHERPURPOSE') : null; // No FEATURE_MOD_ARCHETYPE: the default (MOD_ARCHETYPE_OTHER) is what lists the // module under the chooser's "Activities" tab on 4.5 and 5.0 (DEC-159-01). switch ($feature) { @@ -82,7 +80,7 @@ function exelearning_supports($feature) { // and Lesson (DEC-159-01, supersedes DEC-37-01). return MOD_PURPOSE_INTERACTIVECONTENT; default: - return null; + return ($otherpurpose !== null && $feature === $otherpurpose) ? MOD_PURPOSE_ASSESSMENT : null; } }