Skip to content

Commit

Permalink
Inbox #1
Browse files Browse the repository at this point in the history
  • Loading branch information
it-spiderman authored and FantasticoFox committed Apr 2, 2024
1 parent 204d534 commit a76c022
Show file tree
Hide file tree
Showing 18 changed files with 978 additions and 8 deletions.
34 changes: 34 additions & 0 deletions extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@
"services": [
"TitleFactory", "RevisionStore", "DataAccountingVerificationEngine", "DataAccountingExporter"
]
},
"Inbox": {
"class": "DataAccounting\\SpecialInbox",
"services": [ "TitleFactory", "DataAccountingVerificationEngine" ]
}
},

Expand All @@ -116,6 +120,22 @@
"subpages": true,
"content": false,
"defaultcontentmodel": "wikitext"
},
{
"id": 6900,
"constant": "NS_INBOX",
"name": "Inbox",
"subpages": true,
"content": true,
"defaultcontentmodel": "wikitext"
},
{
"id": 6901,
"constant": "NS_INBOX_TALK",
"name": "Inbox_talk",
"subpages": true,
"content": false,
"defaultcontentmodel": "wikitext"
}
],
"Hooks": {
Expand Down Expand Up @@ -404,6 +424,20 @@
"scripts": [
"api.js"
]
},
"ext.DataAccounting.inbox.compare": {
"scripts": [
"ui/Inbox/ComparePanel.js",
"ui/Inbox/TreePanel.js",
"ui/Inbox/TreeNode.js",
"ext.DataAccounting.inbox.compare.js"
],
"styles": [
"ui/Inbox/style.less"
],
"dependencies": [
"oojs-ui"
]
}
},
"ServiceWiringFiles": [
Expand Down
17 changes: 15 additions & 2 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@
"da-ui-squash-revisions-notice": "Following revisions will be squashed into one:",
"da-ui-squash-revisions-no-revisions": "At least two revisions are needed for squashing",
"da-ui-delete-revisions-no-revisions": "Only one revision of this page available",
"dataaccounting-squash-revisions-comment": "Squashed {{PLURAL:$1|revision $2|revisions: $2}}"

"dataaccounting-squash-revisions-comment": "Squashed {{PLURAL:$1|revision $2|revisions: $2}}",
"inbox": "Inbox",
"da-specialimport-header-domain": "Last change made on domain",
"da-specialimport-header-page-title": "Page title",
"da-specialimport-action-compare-merge": "Import page",
"da-specialinbox-label-own-domain": "own domain",
"da-specialinbox-not-found": "Page not found in inbox",
"da-specialinbox-direct-merge": "Page \"'''$1'''\" does not exist on the wiki and can therefore be directly imported",
"da-specialinbox-compare": "Page \"'''$1'''\" already exists on the wiki. Review and resolve differences before importing.",
"da-specialinbox-do-import-title": "Import a page from inbox",
"da-specialinbox-merge-submit": "Import page",
"da-specialinbox-direct-merge-success": "Page imported to [[$1]]",
"da-specialinbox-merge-error-no-subject": "Page selected for import is invalid",
"da-specialinbox-merge-error-target-exists": "Attempted a direct import, but the target page already exists",
"da-specialinbox-merge-error-invalid target": "Cannot determine import target, or target title invalid"
}
2 changes: 1 addition & 1 deletion includes/API/ImportRevisionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function run() {
// TODO: Enable once user context becomes available
// throw new HttpException( 'User must have \"import\" permission', 401 );
}
$context = $this->transferEntityFactory->newTransferContextFromData(
$context = $this->transferEntityFactory->newTransferContextForImport(
$this->getBodyData( 'context' )
);
if ( !( $context instanceof TransferContext ) ) {
Expand Down
22 changes: 22 additions & 0 deletions includes/Hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static function onRegistration() {
$GLOBALS['wgParserCacheType'] = CACHE_NONE;

$GLOBALS['wgTweekiSkinSpecialElements']['NEWPAGE'] = static::class . '::createNewPageButton';
$GLOBALS['wgTweekiSkinSpecialElements']['INBOX'] = static::class . '::createInboxButton';
}

/**
Expand Down Expand Up @@ -100,6 +101,27 @@ public static function createNewPageButton( $skin, $context ) {
echo $button;
}

public static function createInboxButton( $skin, $context ) {
$pm = MediaWikiServices::getInstance()->getPermissionManager();
if ( !$pm->userHasAllRights( RequestContext::getMain()->getUser(), 'createpage', 'edit' ) ) {
return;
}
$specialInbox = MediaWikiServices::getInstance()->getSpecialPageFactory()->getPage( 'Inbox' );
$pendingCount = $specialInbox->getInboxCount();
$badge = '';
if ( $pendingCount > 0 ) {
$badge = Html::element( 'span', [
'style' => 'position: absolute;background: white;border-radius: 100px;color: black;width: 12px;height: 12px;font-size: 8px;'
], $pendingCount );
}
echo Html::rawElement( 'a', [
'class' => 'btn btn-link ',
'style' => 'color: white',
'id' => 'aqua-inbox-button',
'href' => $specialInbox->getPageTitle()->getLocalURL()
], Html::element( 'i', [ 'class' => 'fas fa-inbox' ] ) . $badge );
}

/**
* Customisations to OutputPage right before page display.
*
Expand Down
44 changes: 44 additions & 0 deletions includes/Inbox/InboxImporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace DataAccounting\Inbox;


use DataAccounting\Verification\Entity\VerificationEntity;
use DataAccounting\Verification\VerificationEngine;
use MediaWiki\MediaWikiServices;
use MediaWiki\User\UserIdentity;
use Status;
use Title;

class InboxImporter {

/** @var VerificationEngine */
private $verificationEngine;
/** @var TreeBuilder|null */
private $treeBuilder = null;

/**
* @param VerificationEngine $verificationEngine
*/
public function __construct( VerificationEngine $verificationEngine ) {
$this->verificationEngine = $verificationEngine;
}

public function importDirect( VerificationEntity $source, Title $target, UserIdentity $actor ): Status {
$movePage = MediaWikiServices::getInstance()->getMovePageFactory()->newMovePage(
$source->getTitle(),
$target
);
return $movePage->move( $actor, 'DataAccounting: Importing from inbox', false );
}

/**
* @return TreeBuilder
*/
public function getTreeBuilder(): TreeBuilder {
if ( $this->treeBuilder === null ) {
$this->treeBuilder = new TreeBuilder( $this->verificationEngine );
}
return $this->treeBuilder;
}
}
151 changes: 151 additions & 0 deletions includes/Inbox/Pager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

namespace DataAccounting\Inbox;

use DataAccounting\Verification\VerificationEngine;
use Html;
use IContextSource;
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\SpecialPage\SpecialPageFactory;
use TablePager;
use TitleFactory;

class Pager extends TablePager {
/** @var TitleFactory */
private $titleFactory;

/** @var VerificationEngine */
private $verificationEngine;

/** @var SpecialPageFactory */
private $spf;

/**
* @param IContextSource $context
* @param LinkRenderer $linkRenderer
* @param TitleFactory $titleFactory
* @param VerificationEngine $verificationEngine
* @param SpecialPageFactory $spf
*/
public function __construct(
IContextSource $context, LinkRenderer $linkRenderer,
TitleFactory $titleFactory, VerificationEngine $verificationEngine, SpecialPageFactory $spf
) {
parent::__construct( $context, $linkRenderer );
$this->titleFactory = $titleFactory;
$this->verificationEngine = $verificationEngine;
$this->spf = $spf;
}

/**
* @return int
*/
public function getCount(): int {
$row = $this->getDatabase()->selectRow(
'page',
[ 'COUNT(*) AS count' ],
[ 'page_namespace' => NS_INBOX ]
);

return $row ? (int)$row->count : 0;
}

public function getQueryInfo() {
return [
'tables' => [ 'p' => 'page', 'v' => 'revision_verification' ],
// All fields but afh_deleted on abuse_filter_history
'fields' => [
'p.page_id',
'p.page_title',
'v.domain_id',
],
'conds' => [
'p.page_namespace' => NS_INBOX,
'revision_verification_id=' .
'(SELECT MAX( revision_verification_id ) FROM revision_verification WHERE page_id=p.page_id )'
],
'join_conds' => [
'revision_verification' =>
[
'INNER JOIN',
'p.page_id=v.page_id',
],
],
'options' => [
'GROUP BY' => 'page_title'
]
];
}

protected function buildQueryInfo( $offset, $limit, $order ) {
list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
parent::buildQueryInfo( $offset, $limit, $order );

$options['ORDER BY'] = 'domain_id ASC, page_title ASC';
return [ $tables, $fields, $conds, $fname, $options, $join_conds ];
}

protected function isFieldSortable( $field ) {
return false;
}

public function formatValue( $name, $value ) {
if ( $name === 'page_title' ) {
$title = $this->titleFactory->makeTitle( NS_INBOX, $value );
return $this->getLinkRenderer()->makeLink( $title, $title->getText() );
}
if ( $name === 'domain_id' ) {
if ( $this->verificationEngine->getDomainId() === $value ) {
return $value . ' (' . $this->msg( 'da-specialinbox-label-own-domain' ) . ')';
}
}
return $value;
}

public function getDefaultSort() {
return '';
}

public function formatRow( $row ) {
$this->mCurrentRow = $row; // In case formatValue etc need to know
$s = Html::openElement( 'tr', $this->getRowAttrs( $row ) ) . "\n";
$fieldNames = $this->getFieldNames();

foreach ( $fieldNames as $field => $name ) {
$value = $row->$field ?? null;
$formatted = strval( $this->formatValue( $field, $value ) );

if ( $formatted == '' ) {
$formatted = "\u{00A0}";
}

$s .= Html::rawElement( 'td', $this->getCellAttrs( $field, $value ), $formatted ) . "\n";
}
$title = $this->spf->getPage( 'Inbox' )->getPageTitle( $row->page_title );
$link = $this->getLinkRenderer()->makeLink(
$title, $this->msg( 'da-specialimport-action-compare-merge' )->text()
);
$s .= Html::rawElement( 'td', [], $link ) . "\n";

$s .= Html::closeElement( 'tr' ) . "\n";

return $s;
}

protected function getCellAttrs( $field, $value ) {
if ( $field === 'domain_id' ) {
if ( $this->verificationEngine->getDomainId() === $value ) {
return [ 'width' => '200px', 'style' => 'background-color: #e6ffe6' ];
}
return [ 'width' => '200px' ];
}
return parent::getCellAttrs( $field, $value );
}

protected function getFieldNames() {
return [
'domain_id' => $this->msg( 'da-specialimport-header-domain' )->text(),
'page_title' => $this->msg( 'da-specialimport-header-page-title' )->text(),
];
}
}
Loading

0 comments on commit a76c022

Please sign in to comment.