Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
EditionLookup
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 9
272
0.00% covered (danger)
0.00%
0 / 1
 newFromGlobalState
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 getPropertyIdFromConfig
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getWorks
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEditions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getItemValuesForItem
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 getItemIdValuesForItem
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getMainSnakItemIds
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 getEntity
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3declare( strict_types = 1 );
4
5namespace MediaWiki\Extension\Wikisource;
6
7use RequestContext;
8use Wikibase\Client\Usage\UsageAccumulator;
9use Wikibase\Client\WikibaseClient;
10use Wikibase\DataModel\Entity\EntityDocument;
11use Wikibase\DataModel\Entity\EntityId;
12use Wikibase\DataModel\Entity\EntityIdValue;
13use Wikibase\DataModel\Entity\Item;
14use Wikibase\DataModel\Entity\ItemId;
15use Wikibase\DataModel\Entity\NumericPropertyId;
16use Wikibase\DataModel\Services\Lookup\EntityLookup;
17use Wikibase\DataModel\Services\Lookup\EntityLookupException;
18use Wikibase\DataModel\Snak\PropertyValueSnak;
19use Wikibase\DataModel\Snak\Snak;
20
21/**
22 * Lookup to find editions of a given work and work of a given edition
23 *
24 * @since 0.1
25 *
26 * @license GPL-2.0-or-later
27 * @author  Thomas Pellissier Tanon
28 */
29class EditionLookup {
30
31    /**
32     * @var EntityLookup
33     */
34    private $entityLookup;
35
36    /**
37     * @var NumericPropertyId
38     */
39    private $editionPropertyId;
40
41    /**
42     * @var NumericPropertyId
43     */
44    private $editionOfPropertyId;
45
46    /**
47     * @var UsageAccumulator
48     */
49    private $usageAccumulator;
50
51    /**
52     * @param UsageAccumulator $usageAccumulator
53     * @return self
54     */
55    public static function newFromGlobalState( UsageAccumulator $usageAccumulator ): self {
56        return new self(
57            WikibaseClient::getRestrictedEntityLookup(),
58            self::getPropertyIdFromConfig( 'WikisourceWikibaseEditionProperty' ),
59            self::getPropertyIdFromConfig( 'WikisourceWikibaseEditionOfProperty' ),
60            $usageAccumulator
61        );
62    }
63
64    private static function getPropertyIdFromConfig( string $configParamName ): NumericPropertyId {
65        return new NumericPropertyId( RequestContext::getMain()->getConfig()->get( $configParamName ) );
66    }
67
68    /**
69     * @param EntityLookup $entityLookup
70     * @param NumericPropertyId $editionPropertyId
71     * @param NumericPropertyId $editionOfPropertyId
72     * @param UsageAccumulator $usageAccumulator
73     */
74    public function __construct(
75        EntityLookup $entityLookup,
76        NumericPropertyId $editionPropertyId,
77        NumericPropertyId $editionOfPropertyId,
78        UsageAccumulator $usageAccumulator
79    ) {
80        $this->entityLookup = $entityLookup;
81        $this->editionPropertyId = $editionPropertyId;
82        $this->editionOfPropertyId = $editionOfPropertyId;
83        $this->usageAccumulator = $usageAccumulator;
84    }
85
86    /**
87     * @param Item $item
88     * @return Item[]
89     */
90    public function getWorks( Item $item ): array {
91        return $this->getItemValuesForItem( $item, $this->editionOfPropertyId );
92    }
93
94    /**
95     * @param Item $item
96     * @return Item[]
97     */
98    public function getEditions( Item $item ): array {
99        return $this->getItemValuesForItem( $item, $this->editionPropertyId );
100    }
101
102    /**
103     * @param Item $item
104     * @param NumericPropertyId $propertyId
105     * @return Item[]
106     */
107    private function getItemValuesForItem( Item $item, NumericPropertyId $propertyId ): array {
108        $items = [];
109        foreach ( $this->getItemIdValuesForItem( $item, $propertyId ) as $itemId ) {
110            $item = $this->getEntity( $itemId );
111            if ( $item instanceof Item ) {
112                $items[] = $item;
113            }
114        }
115        return $items;
116    }
117
118    /**
119     * @param Item $item
120     * @param NumericPropertyId $propertyId
121     * @return ItemId[]
122     */
123    private function getItemIdValuesForItem( Item $item, NumericPropertyId $propertyId ): array {
124        $this->usageAccumulator->addStatementUsage( $item->getId(), $propertyId );
125
126        $statements = $item->getStatements()->getByPropertyId( $propertyId );
127        $mainSnaks = $statements->getBestStatements()->getMainSnaks();
128        return $this->getMainSnakItemIds( $mainSnaks );
129    }
130
131    /**
132     * @param Snak[] $mainSnaks
133     * @return ItemId[]
134     */
135    private function getMainSnakItemIds( array $mainSnaks ): array {
136        $values = [];
137        foreach ( $mainSnaks as $snak ) {
138            if ( $snak instanceof PropertyValueSnak ) {
139                $value = $snak->getDataValue();
140                if ( $value instanceof EntityIdValue ) {
141                    $entityId = $value->getEntityId();
142                    if ( $entityId instanceof ItemId ) {
143                        $values[] = $entityId;
144                    }
145                }
146            }
147        }
148        return $values;
149    }
150
151    private function getEntity( EntityId $itemId ): ?EntityDocument {
152        try {
153            return $this->entityLookup->getEntity( $itemId );
154        } catch ( EntityLookupException $e ) {
155            return null;
156        }
157    }
158}