Page MenuHomePhabricator

Useragreement Special page to view who has agreen and when.
Open, Needs TriagePublicFeature

Description

Feature summary (what you would like to be able to do and where):
Add a special page to view who has signed the agreement

Use case(s) (list the steps that you performed to discover that problem, and describe the actual underlying problem which you want to solve. Do not describe only a solution):
See below how I have done this on my Wiki

Benefits (why should this be implemented?):
Allows Wiki admins to be able to see when the useragreement has been agreed to by the user, therefore being able to provide evidence if the case arises when action is taken against a user.

Directions on how I have implemented this

I have made some changes to the Useragreement extension, this allows bureaucrats to to be able to view who has agreed to the useragreement and when.

This creates a Special Page:

Special:UserAgreementAudit

In LocalSettings.php the following needs to be added:

$wgGroupPermissions['bureaucrat']['useragreement-audit'] = true;

I am struggling to get the UserAgreementAudit page on the Special Pages page

A new file has been produced:

includes/SpecialUserAgreementAudit.php

<?php
/*

  • Permission is hereby granted, free of charge, to any person obtaining a
  • copy of this software and associated documentation files (the "Software"),
  • to deal in the Software without restriction, including without limitation
  • the rights to use, copy, modify, merge, publish, distribute, sublicense,
  • and/or sell copies of the Software, and to permit persons to whom the
  • Software is furnished to do so, subject to the following conditions: *
  • The above copyright notice and this permission notice shall be included in
  • all copies or substantial portions of the Software. *
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  • IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  • FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  • AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  • LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  • FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  • DEALINGS IN THE SOFTWARE. */

namespace MediaWiki\Extension\UserAgreement;

use SpecialPage;
use Html;
use MediaWiki\MediaWikiServices;

class SpecialUserAgreementAudit extends SpecialPage {

public function __construct() {
    parent::__construct( 'UserAgreementAudit', 'useragreement-audit' );
}

/**
 * @inheritDoc
 */
public function doesWrites() {
    return false;
}

/**
 * @inheritDoc
 */
public function isListed() {
    return true;
}

/**
 * @inheritDoc
 */
public function execute( $par ) {
    $this->setHeaders();
    $output = $this->getOutput();
    $this->checkPermissions();

    $output->addWikiMsg( 'useragreement-audit-intro' );

    $this->showAuditTable();
}

private function showAuditTable() {
    $output = $this->getOutput();
    $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
    $dbr = $lb->getConnectionRef( DB_REPLICA );

    $res = $dbr->newSelectQueryBuilder()
        ->select( [
            'ua_user',
            'ua_user_accepted_timestamp',
        ] )
        ->from( 'useragreement' )
        ->orderBy( 'ua_user_accepted_timestamp', 'DESC' )
        ->fetchResultSet();

    // Use $res->valid() to check if there are any rows
    if ( !$res->valid() ) {
        $output->addWikiMsg( 'useragreement-audit-empty' );
        return;
    }

    $table = Html::openElement( 'table', [ 'class' => 'wikitable' ] );
    $table .= Html::openElement( 'tr' );
    $table .= Html::element( 'th', [], $this->msg( 'useragreement-audit-header-user' )->text() );
    $table .= Html::element( 'th', [], $this->msg( 'useragreement-audit-header-email' )->text() );
    $table .= Html::element( 'th', [], $this->msg( 'useragreement-audit-header-timestamp' )->text() );
    $table .= Html::closeElement( 'tr' );

    // Rewind the result set to the beginning
    $res->rewind();

    foreach ( $res as $row ) {
        $user = \User::newFromId( $row->ua_user );
        $username = $user->getName();
        $email = $user->getEmail();
        $timestamp = $row->ua_user_accepted_timestamp;

        $table .= Html::openElement( 'tr' );
        $table .= Html::rawElement( 'td', [], htmlspecialchars( $username ) );
        $table .= Html::rawElement( 'td', [], htmlspecialchars( $email ) );
        $table .= Html::rawElement( 'td', [],  $this->getLanguage()->timeanddate( $timestamp, true ) );
        $table .= Html::closeElement( 'tr' );
    }

    $table .= Html::closeElement( 'table' );
    $output->addHTML( $table );
}

}

// Register the special page
$wgSpecialPages['UserAgreementAudit'] = [

'class' => MediaWiki\Extension\UserAgreement\SpecialUserAgreementAudit::class,
'file' => __DIR__ . '/includes/SpecialUserAgreementAudit.php',
'services' => [
    'UserAgreementStore'
]

];

// Register the special page
$wgSpecialPages['UserAgreementAudit'] = [

'class' => MediaWiki\Extension\UserAgreement\SpecialUserAgreementAudit::class,
'file' => __DIR__ . '/includes/SpecialUserAgreementAudit.php',
'services' => [
    'UserAgreementStore'
]

];

The following to the i18n file (I have only done English given that is my Wikis language)

"useragreementaudit": "User Agreement Audit",
"useragreement-audit-intro": "This page shows a list of users who have accepted the user agreement.",
"useragreement-audit-empty": "No users have accepted the user agreement yet.",
"useragreement-audit-header-user": "Username",
"useragreement-audit-header-email": "Email",
"useragreement-audit-header-timestamp": "Acceptance Date"

And extension.json

"SpecialPages": {
    "UserAgreementAudit": "MediaWiki\\Extension\\UserAgreement\\SpecialUserAgreementAudit"
},
"MessagesDirs": {
    "UserAgreement": [
        "i18n"
    ]
},
"AutoloadClasses": {
    "MediaWiki\\Extension\\UserAgreement\\SpecialUserAgreementAudit": "includes/SpecialUserAgreementAudit.php"
},
"Permissions": {
    "useragreement-audit": {
        "right": "useragreement-audit",
        "read": true,
        "groups": [ "sysop" ]
    }
},
"AvailableRights": [
    "useragreement-audit"
],

I haven't coded this yet, but on the special page it will also be useful to have the date and time that the page is created as a time stamp if the content needs to be printed/saved as PDF.