The problem
Learners lose their record when a course closes. Moodle's grade overview shows a learner one row per course while they are enrolled; Report builder gives administrators rows and CSV. Neither gives a learner a document they can hand to an employer, and neither survives the course being archived or deleted. The requirement came from moodle.org threads asking for exactly this, and a Marketplace search for "transcript" returned only video transcription plugins.
What it does
- A learner opens Transcript from their profile and sees one table: course, started, completed, grade, outcome.
- Download PDF produces an A4 document with the institution's name and logo, the learner's name, the rows, and a 24-character verification code. Every download issues a fresh code and freezes a snapshot of the rows as they stood.
- Anyone holding a code can open the verification page, enter it, and see exactly what was issued: name, date and rows. The snapshot does not change when a course is later renamed, archived or deleted.
- Managers can open and download any learner's transcript from that learner's profile.
| Grade overview (core) | Report builder (core) | Transcript | |
|---|---|---|---|
| Audience | The learner | Administrators | The learner, and managers |
| Shape | One row per course, grade only | Rows, any columns, CSV | One document per person |
| Dates and outcome | No | Dates only | Yes |
| Download | No | CSV | PDF, branded |
| Verifiable by a third party | No | No | Yes, by code |
| Survives course deletion | No | No | The issued snapshot does |
Rules that are easy to get wrong
- Which courses appear. Every completion record, whether or not the course is still visible or the learner is still enrolled: the completion record is the evidence. Courses in progress and courses without completion tracking are settings. The front page, excluded categories and courses where the learner's only roles are not graded roles (the gradebook's own rule) never appear, so a teacher's courses do not show on their transcript.
- Grades. The grade follows each course's own display type, and hidden grades stay hidden. Every branch of that logic has a unit test.
- Not a bulk export. Administrators wanting rows for many users already have Report builder, and the README gives the two-line recipe rather than duplicating core.
How it is built
- Separate, tested classes for the grade presenter, the transcript builder (inclusion and exclusion rules), the issuer (codes and snapshots) and the PDF renderer, each written tests first.
- One table for issued snapshots, so a transcript is a live view until the moment it is issued and a record from then on.
- Privacy provider covering the issued snapshots, capability checks for own, manager and verification access, language strings throughout.
Quality
- PHPUnit61 tests
- Behat5 scenarios
- CI16 jobs passing
- Moodle4.5 to 5.2
- PHP8.1 to 8.4
- DBPostgreSQL, MariaDB
- MarketplacePublished, plugin 4184
GitHub Actions runs the Moodle plugin CI suite on Moodle 4.5, 5.0, 5.1 and 5.2, on the PHP versions each branch supports, on both databases. PHPUnit covers every inclusion rule, every grade display branch including hidden grades, issuing and verification. Behat covers the learner viewing their own transcript, a learner without the capability being refused, the manager path and the verification page.
What the review found
Version 1.0.0 went into the Moodle Marketplace review queue on 14 September. On 2 October the reviewer returned two findings, and one of them was an approval blocker on security grounds. The finding was correct, and it is worth writing down rather than quietly fixing.
The transcript resolved a course total and printed it on the page, embedded it in the PDF and made it checkable on the public verification page. What it never asked was whether the course showed grades to learners at all. A teacher who had switched the gradebook off before releasing results still had that total published, and verifiable by anyone holding the code, on a page that needs no login. The second finding was smaller: courses without completion tracking came from an enrolment call that does not filter hidden courses, so a hidden course could be listed with its total while the in-progress rule already excluded one.
Both were fixed the same day in 1.0.1. The fix applies both halves of the test core makes in its own overview report, the course setting and the capability, and asks them of the learner rather than of whoever is reading the transcript, because the question a transcript has to answer is what the learner could see. Three tests cover the cases the reviewer named: a course with grades switched off, a learner whose capability was removed, and a hidden untracked course. The README claimed the transcript never reveals more than the learner’s own gradebook; that claim is now true.
Status
The reviewer passed version 1.0.1 on 8 October 2026, confirming every critical issue fixed and recommending the plugin for approval (ticket MMR-244). Both GitHub issues are closed against the commits that fixed them, and the full suite of 61 tests passes on all 16 CI jobs. It is now published in the plugins directory.


