Jump to content

ICT:FinalConfig - AssetFileNormakizer extension

From Costa Sano MediaWiki
Revision as of 14:49, 18 February 2026 by Mngr (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Final Configuration for Extension: AssetFileNormalizer

Document revision: 2026-02-18 by Mngr

This document defines the private MediaWiki extension AssetFileNormalizer.

The extension enforces the archival invariant:

One Asset = one File, both sharing the same immutable identifier.

The extension is part of the Asset v2 architecture and must be considered normative infrastructure.


1. Purpose and Scope

The AssetFileNormalizer extension automatically renames uploaded files associated with Asset pages so that:

  • The file name matches the Asset identifier
  • The original upload filename is removed
  • No redirect is created
  • No user intervention is required

This extension applies only to:

  • newly created Asset pages
  • files uploaded through the Asset form

It does not affect:

  • existing files
  • non-Asset pages
  • manual file moves

2. Design Principles

The extension is designed according to the following principles:

  • Minimal responsibility (one job only)
  • No dependency on Cargo internals
  • No dependency on Page Forms internals
  • Server-side authority (no JavaScript enforcement)
  • Upgrade-safe MediaWiki APIs
  • Non-blocking behavior on failure

The extension intentionally performs no validation of identifiers. It assumes that Asset v2 numbering logic has already produced a valid identifier.


3. Functional Behavior

3.1 Trigger

The extension runs when:

  • a page is saved
  • the page is newly created
  • the page is in the Asset namespace

3.2 Conditions

The extension proceeds only if:

  • the page contains a File field
  • the referenced file exists
  • the file name does not already match the Asset identifier

3.3 Action

If all conditions are met:

  • the file is moved to <AssetIdentifier>.<extension>
  • file history is preserved
  • redirect creation is suppressed

3.4 Failure Policy

If the file move fails:

  • the Asset page remains valid
  • the file remains under its original name
  • a debug log entry is written

The extension never blocks page saving.


4. Directory Structure

The extension is installed as a private extension under:

extensions/AssetFileNormalizer/
 ├─ extension.json
 └─ AssetFileNormalizer.php

5. Extension Registration

5.1 extension.json

{
  "name": "AssetFileNormalizer",
  "version": "1.0",
  "author": "Costa Sano Research",
  "description": "Automatically renames Asset files to match Asset identifiers",
  "type": "extension",
  "Hooks": {
    "PageSaveComplete": "AssetFileNormalizer::onPageSaveComplete"
  },
  "AutoloadClasses": {
    "AssetFileNormalizer": "AssetFileNormalizer.php"
  },
  "ManifestVersion": 2
}

6. Core Implementation

6.1 AssetFileNormalizer.php

<?php
use MediaWiki\MediaWikiServices;

class AssetFileNormalizer {

    public static function onPageSaveComplete(
        WikiPage $wikiPage,
        UserIdentity $user,
        string $summary,
        int $flags,
        RevisionRecord $revisionRecord,
        EditResult $editResult
    ) {
        $title = $wikiPage->getTitle();

        // Only Asset namespace (ID must match local configuration)
        if ( $title->getNamespace() !== 3014 ) {
            return;
        }

        // Only act on page creation
        if ( !$editResult->isNewPage() ) {
            return;
        }

        // Extract wikitext content
        $content = $revisionRecord->getContent( SlotRecord::MAIN );
        if ( !$content instanceof WikitextContent ) {
            return;
        }

        $text = $content->getText();

        // Extract File field
        if ( !preg_match( '/\|\s*File\s*=\s*(File:[^\|\n]+)/', $text, $m ) ) {
            return;
        }

        $fileTitle = Title::newFromText( trim( $m[1] ) );
        if ( !$fileTitle || !$fileTitle->inNamespace( NS_FILE ) ) {
            return;
        }

        $repo = MediaWikiServices::getInstance()
            ->getRepoGroup()
            ->getLocalRepo();

        $file = $repo->newFile( $fileTitle );
        if ( !$file->exists() ) {
            return;
        }

        // Compute target filename
        $assetCode = $title->getText();
        $extension = $file->getExtension();

        $targetTitle = Title::makeTitle(
            NS_FILE,
            $assetCode . '.' . $extension
        );

        // Already normalized
        if ( $fileTitle->equals( $targetTitle ) ) {
            return;
        }

        // Move file without redirect
        $status = $file->move(
            $targetTitle,
            'Automatic Asset file normalization',
            /* suppressRedirect */ true,
            $user
        );

        if ( !$status->isOK() ) {
            wfDebugLog(
                'AssetFileNormalizer',
                'File move failed for ' . $fileTitle->getPrefixedText()
            );
        }
    }
}

7. Enabling the Extension

Add the following line to LocalSettings.php:

wfLoadExtension( 'AssetFileNormalizer' );

Optionally, the extension may be wrapped in a feature flag for emergency disablement.


8. Security and Permissions

  • The file move is executed under the saving user context
  • Users creating Assets must have:
    • upload rights
    • movefile rights (or equivalent)
  • The extension does not escalate privileges

Deletion of Asset/File couples remains a sysop-only operation.


9. Relationship to Asset v2

This extension is a mandatory component of Asset v2.

Without it:

  • Asset creation still works
  • File upload still works
  • The archival invariant (name equality) is not enforced

With it:

  • Asset and File identity are strictly aligned
  • The Asset–File couple is sealed at creation time

10. Status

AssetFileNormalizer is complete and ready for deployment.

No database changes are required. No migration of existing files is performed.


ICT: Installing a Private MediaWiki Extension (AssetFileNormalizer)

Document revision: 2026-02-18 by Mngr

This page documents how to install and organize the private MediaWiki extension AssetFileNormalizer.

The extension is part of the Asset v2 architecture and enforces automatic file renaming for newly created Asset pages.


1. Purpose

The AssetFileNormalizer extension enforces the invariant:

One Asset = one File, both sharing the same immutable identifier.

It automatically renames uploaded files to match the Asset identifier, without user intervention and without leaving redirects.

This document explains only the **technical installation and folder structure**. Functional behavior is documented in FinalConfig:Asset-v2.


2. Preconditions

The following conditions must be met:

  • Self-hosted MediaWiki installation
  • MediaWiki version ≥ 1.43
  • Access to the MediaWiki filesystem
  • Access to LocalSettings.php
  • Ability to edit files via SSH / VS Code
  • PHP execution enabled

No database access is required for this extension.


3. Extension Folder Structure

Private extensions are installed under the MediaWiki extensions/ directory.

For AssetFileNormalizer, create the following structure:

mediawiki/
└─ extensions/
   └─ AssetFileNormalizer/
      ├─ extension.json
      └─ AssetFileNormalizer.php

No additional subfolders are required.

This extension intentionally uses:

  • a single PHP class
  • a single hook
  • no internationalisation
  • no schema changes

4. Required Files

4.1 extension.json

This file registers the extension with MediaWiki.

{
  "name": "AssetFileNormalizer",
  "version": "1.0",
  "author": "Costa Sano Research",
  "description": "Automatically renames Asset files to match Asset identifiers",
  "type": "extension",
  "Hooks": {
    "PageSaveComplete": "AssetFileNormalizer::onPageSaveComplete"
  },
  "AutoloadClasses": {
    "AssetFileNormalizer": "AssetFileNormalizer.php"
  },
  "ManifestVersion": 2
}

4.2 AssetFileNormalizer.php

This file contains the implementation logic.

It:

  • listens for page save completion
  • detects newly created Asset pages
  • moves the uploaded file to match the Asset identifier
  • suppresses redirect creation
  • never blocks page saving

(Full code is documented in FinalConfig:AssetFileNormalizer.)


5. Enabling the Extension

To enable the extension, add the following line to LocalSettings.php:

wfLoadExtension( 'AssetFileNormalizer' );

After saving the file:

  • no database update is required
  • no maintenance scripts are required
  • simply reload the wiki

6. Logging (Recommended)

During testing and early production use, enable a dedicated debug log.

Add to LocalSettings.php:

$wgDebugLogGroups['AssetFileNormalizer']
    = '/var/log/mediawiki/asset-file-normalizer.log';

This log records:

  • failed file move attempts
  • unexpected conditions

The extension performs no user-facing error reporting.


7. Permissions

The file MOVE operation is executed under the context of the saving user.

Users creating Asset pages must have:

  • upload rights
  • movefile rights

No privilege escalation is performed by the extension.

Deletion of Asset/File couples remains a sysop-only operation.


8. Upgrade and Maintenance Notes

  • The extension is upgrade-safe
  • No core MediaWiki files are modified
  • Disabling the extension immediately stops automatic renaming
  • Existing Assets and Files are not affected

To disable:

  • comment out or remove the wfLoadExtension line
  • no cleanup is required

9. Status

The AssetFileNormalizer extension installation procedure is complete and validated.

This extension is mandatory for full compliance with Asset v2.