Skip to content

Commit

Permalink
feat: Add LinksTOPropertyAnnotator
Browse files Browse the repository at this point in the history
  • Loading branch information
octfx committed Jun 25, 2023
1 parent b5af401 commit 54b768f
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 20 deletions.
42 changes: 24 additions & 18 deletions data/definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -945,23 +945,29 @@
"alias": "sesp-exif-languagecode",
"label": "Exif:Language code"
},
"GPSLATITUDE": {
"id": "___EXIFGPSLATITUDE",
"type": "_txt",
"alias": "sesp-exif-gpslatitude",
"label": "Exif:GPSLatitude"
},
"GPSLONGITUDE": {
"id": "___EXIFGPSLONGITUDE",
"type": "_txt",
"alias": "sesp-exif-gpslongitude",
"label": "Exif:GPSLongitude"
},
"GPSALTITUDE": {
"id": "___EXIFGPSALTITUDE",
"type": "_txt",
"alias": "sesp-exif-gpsaltitude",
"label": "Exif:GPSAltitude"
}
"GPSLATITUDE": {
"id": "___EXIFGPSLATITUDE",
"type": "_txt",
"alias": "sesp-exif-gpslatitude",
"label": "Exif:GPSLatitude"
},
"GPSLONGITUDE": {
"id": "___EXIFGPSLONGITUDE",
"type": "_txt",
"alias": "sesp-exif-gpslongitude",
"label": "Exif:GPSLongitude"
},
"GPSALTITUDE": {
"id": "___EXIFGPSALTITUDE",
"type": "_txt",
"alias": "sesp-exif-gpsaltitude",
"label": "Exif:GPSAltitude"
},
"LINKSTO": {
"id": "___LINKSTO",
"type": "_wpg",
"alias": "sesp-property-links-to",
"label": "Links to"
}
}
}
6 changes: 6 additions & 0 deletions extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@
"path": false,
"description": "Should edits via user accounts in usergroup \"bot\" be ignored when storing data for the special properties?",
"descriptionmsg": "sesp-config-exclude-bot-edits"
},
"LinksToEnabledNamespaces": {
"value": [],
"path": false,
"description": "List of namespaces where the 'Links to' property should be enabled",
"descriptionmsg": "sesp-config-links-to-enabled-namespaces"
}
},
"Hooks": {
Expand Down
5 changes: 4 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
"sesp-property-user-group-desc": "\"$1\" records a list of groups applied to a user. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
"sesp-property-exif-data": "Exif data",
"sesp-property-exif-data-desc": "\"$1\" records the file's EXIF data. It is provided by the [https://www.semantic-mediawiki.org/wiki/Extension:Semantic_Extra_Special_Properties Semantic Extra Special Properties] extension.",
"sesp-property-links-to": "Links to",
"sesp-property-links-to-desc": "\"$1\" records a list of pages the current page links to.",
"sesp-exif-languagecode": "Exif:Language code",
"sesp-exif-gpslatitude": "Exif:Latitude",
"sesp-exif-gpslongitude": "Exif:Longitude",
Expand All @@ -77,5 +79,6 @@
"sesp-config-enabled-property-list": "Specifies the enabled properties",
"sesp-config-label-cache-version": "Specifies an internal cache modifier",
"sesp-config-exclude-bot-edits": "Should edits via user accounts in usergroup \"bot\" be ignored when storing data for the special properties?",
"sesp-config-short-url-prefix": "Used in connection with ShortUrlUtils"
"sesp-config-short-url-prefix": "Used in connection with ShortUrlUtils",
"sesp-config-links-to-enabled-namespaces": "List of namespace ids that are enabled for the 'Links to' property."
}
4 changes: 3 additions & 1 deletion i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"sesp-property-user-group-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
"sesp-property-exif-data": "{{Doc-smw-sp|extension=SESP}}",
"sesp-property-exif-data-desc": "{{Doc-smw-sp-desc|extension=SESP}}",
"sesp-property-links-to": "{{Doc-smw-sp-desc|extension=SESP}}",
"sesp-exif-languagecode": "This is the name of a special property.\n\nRelated to {{msg-mw|Exif-languagecode}}",
"sesp-exif-gpslatitude": "This is the name of a special property.\n\nRelated to {{msg-mw|Exif-gpslatitude}}",
"sesp-exif-gpslongitude": "This is the name of a special property.\n\nRelated to {{msg-mw|Exif-gpslongitude}}",
Expand All @@ -80,5 +81,6 @@
"sesp-config-enabled-property-list": "Explains what a configuration variable does.",
"sesp-config-label-cache-version": "Explains what a configuration variable does.",
"sesp-config-exclude-bot-edits": "Explains what a configuration variable does.",
"sesp-config-short-url-prefix": "Explains what a configuration variable does."
"sesp-config-short-url-prefix": "Explains what a configuration variable does.",
"sesp-config-links-to-enabled-namespaces": "Explains what a configuration variable does."
}
99 changes: 99 additions & 0 deletions src/PropertyAnnotators/LinksToPropertyAnnotator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace SESP\PropertyAnnotators;

use MediaWiki\MediaWikiServices;
use SESP\AppFactory;
use SESP\PropertyAnnotator;
use SMW\DIProperty;
use SMW\DIWikiPage;
use SMW\SemanticData;
use Title;

/**
* @private
* @ingroup SESP
*
* @license GNU GPL v2+
* @since 3.0.4
*/
class LinksToPropertyAnnotator implements PropertyAnnotator {

/**
* Predefined property ID
*/
const PROP_ID = '___LINKSTO';

/**
* @var AppFactory
*/
private $appFactory;

private $enabledNamespaces;

/**
* @param AppFactory $appFactory
*/
public function __construct( AppFactory $appFactory ) {
$this->appFactory = $appFactory;

$this->enabledNamespaces = MediaWikiServices::getInstance()
->getConfigFactory()
->makeConfig( 'sespg' )
->get( 'LinksToEnabledNamespaces' );
}

public function setEnabledNamespaces( array $namespaces ) {
$this->enabledNamespaces = $namespaces;
}

/**
* @since 2.0
*
* {@inheritDoc}
*/
public function isAnnotatorFor( DIProperty $property ) {
return $property->getKey() === self::PROP_ID ;
}

/**
* @since 2.0
*
* {@inheritDoc}
*/
public function addAnnotation( DIProperty $property, SemanticData $semanticData ) {
$page = $semanticData->getSubject()->getTitle();

if ( $page === null || ( !empty( $this->enabledNamespaces ) && !$page->inNamespaces( $this->enabledNamespaces ) ) ) {
return;
}

$con = $this->appFactory->getConnection();

if ( $con === null ) {
return;
}

$where = sprintf(
'pl.pl_from = %s AND pl.pl_title != %s',
$page->getArticleID(),
$con->addQuotes( $page->getDBkey() )
);

$res = $con->select(
[ 'pl' => 'pagelinks', 'page' ],
[ 'sel_title' => 'pl.pl_title', 'sel_ns' => 'pl.pl_namespace' ],
[ $where ],
__METHOD__,
[ 'DISTINCT' ],
[ 'page' => [ 'JOIN', 'page_id=pl_from' ] ]
);

foreach( $res as $row ) {
$title = Title::newFromText( $row->sel_title, $row->sel_ns );
if ( $title !== null && $title->exists() ) {
$semanticData->addPropertyObjectValue( $property, DIWikiPage::newFromTitle( $title ) );
}
}
}
}
124 changes: 124 additions & 0 deletions tests/phpunit/Unit/PropertyAnnotators/LinksToPropertyAnnotatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

namespace SESP\Tests\PropertyAnnotators;

use ConfigFactory;
use HashConfig;
use PHPUnit_Framework_TestCase;
use SESP\AppFactory;
use SESP\PropertyAnnotators\LinksToPropertyAnnotator;
use SMW\DIProperty;
use SMW\DIWikiPage;
use SMW\SemanticData;
use Title;

/**
* @covers \SESP\PropertyAnnotators\LinksToPropertyAnnotator
* @group semantic-extra-special-properties
*
* @license GNU GPL v2+
* @since 2.0
*/
class LinksToPropertyAnnotatorTest extends PHPUnit_Framework_TestCase {

private $property;
private $appFactory;

protected function setUp(): void {
parent::setUp();

$this->appFactory = $this->getMockBuilder( '\SESP\AppFactory' )
->disableOriginalConstructor()
->getMock();

$this->property = new DIProperty( '___LINKSTO' );
}

public function testCanConstruct() {

$this->assertInstanceOf(
LinksToPropertyAnnotator::class,
new LinksToPropertyAnnotator( $this->appFactory )
);
}

public function testIsAnnotatorFor() {

$instance = new LinksToPropertyAnnotator(
$this->appFactory
);

$this->assertTrue(
$instance->isAnnotatorFor( $this->property )
);
}

public function testAddAnnotation() {
$factory = $this->getMockBuilder( AppFactory::class )
->disableOriginalConstructor()
->getMock();

$factory->expects( $this->once() )->method('getConnection');

$subject = $this->getMockBuilder( DIWikiPage::class )
->disableOriginalConstructor()
->getMock();

$subject->expects( $this->once() )
->method( 'getTitle' )
->willReturn( Title::newFromText( 'Foo' ) );

$semanticData = $this->getMockBuilder( SemanticData::class )
->disableOriginalConstructor()
->getMock();

$semanticData->expects( $this->once() )
->method( 'getSubject' )
->willReturn( $subject );

$semanticData->expects( $this->never() )
->method( 'addPropertyObjectValue' );

$annotator = new LinksToPropertyAnnotator(
$factory
);

$annotator->addAnnotation( $this->property, $semanticData );
}

public function testNotAddAnnotation() {
$factory = $this->getMockBuilder( AppFactory::class )
->disableOriginalConstructor()
->getMock();

$factory->expects( $this->never() )
->method('getConnection');

$subject = $this->getMockBuilder( DIWikiPage::class )
->disableOriginalConstructor()
->getMock();

$subject->expects( $this->once() )
->method( 'getTitle' )
->willReturn( Title::newFromText( 'Foo' ) );

$semanticData = $this->getMockBuilder( SemanticData::class )
->disableOriginalConstructor()
->getMock();

$semanticData->expects( $this->once() )
->method( 'getSubject' )
->willReturn( $subject );

$semanticData->expects( $this->never() )
->method( 'addPropertyObjectValue' );

$annotator = new LinksToPropertyAnnotator(
$factory
);

$annotator->setEnabledNamespaces( [ 2 ] );

$annotator->addAnnotation( $this->property, $semanticData );
}
}

0 comments on commit 54b768f

Please sign in to comment.