Skip to content

Commit e0c0246

Browse files
committed
Create ByPropertyIdMap
1 parent 1e085d2 commit e0c0246

2 files changed

Lines changed: 463 additions & 0 deletions

File tree

src/ByPropertyIdMap.php

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel;
4+
5+
use InvalidArgumentException;
6+
use OutOfBoundsException;
7+
use Traversable;
8+
use Wikibase\DataModel\Entity\PropertyId;
9+
10+
/**
11+
* Maps property id providers by their property id.
12+
*
13+
* This class allows to reorder elements having the same property id
14+
* as well as changíng the order of the property ids themselves.
15+
*
16+
* @since 3.0
17+
*
18+
* @license GNU GPL v2+
19+
* @author Bene* < benestar.wikimedia@gmail.com >
20+
*/
21+
class ByPropertyIdMap {
22+
23+
/**
24+
* Map of serialized property ids pointing to
25+
* a list of elements with that property id
26+
*
27+
* @var array[]
28+
*/
29+
private $byPropertyId = array();
30+
31+
/**
32+
* @var PropertyId[]
33+
*/
34+
private $propertyIds = array();
35+
36+
/**
37+
* @param PropertyIdProvider[]|Traversable $propertyIdProviders
38+
*
39+
* @throws InvalidArgumentException
40+
*/
41+
public function __construct( $propertyIdProviders ) {
42+
$byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders );
43+
44+
$this->propertyIds = $byPropertyIdGrouper->getPropertyIds();
45+
foreach ( $this->propertyIds as $propertyId ) {
46+
$this->byPropertyId[$propertyId->getSerialization()] = $byPropertyIdGrouper->getByPropertyId( $propertyId );
47+
}
48+
}
49+
50+
/**
51+
* @param PropertyId $propertyId
52+
* @param int|null $index
53+
*
54+
* @throws InvalidArgumentException
55+
* @throws OutOfBoundsException
56+
*/
57+
public function moveGroupToIndex( PropertyId $propertyId, $index ) {
58+
$this->assertIsIndex( $index );
59+
60+
$oldIndex = array_search( $propertyId, $this->propertyIds );
61+
62+
if ( $oldIndex === false ) {
63+
throw new OutOfBoundsException( 'There is no group for property id ' . $propertyId->getSerialization() );
64+
}
65+
66+
if ( $index === null ) {
67+
$index = count( $this->propertyIds );
68+
}
69+
70+
array_splice( $this->propertyIds, $oldIndex, 1 );
71+
array_splice( $this->propertyIds, $index, 0, array( $propertyId ) );
72+
73+
$this->propertyIds = array_values( $this->propertyIds );
74+
}
75+
76+
/**
77+
* @param PropertyIdProvider $propertyIdProvider
78+
* @param int|null $index
79+
*
80+
* @throws InvalidArgumentException
81+
* @throws OutOfBoundsException
82+
*/
83+
public function moveElementToIndex( PropertyIdProvider $propertyIdProvider, $index ) {
84+
$this->assertIsIndex( $index );
85+
86+
$idSerialization = $propertyIdProvider->getPropertyId()->getSerialization();
87+
88+
if ( !isset( $this->byPropertyId[$idSerialization] ) ) {
89+
throw new OutOfBoundsException( 'There is no group for property id ' . $idSerialization );
90+
}
91+
92+
$oldIndex = array_search( $propertyIdProvider, $this->byPropertyId[$idSerialization] );
93+
94+
if ( $oldIndex === false ) {
95+
throw new OutOfBoundsException( 'The property id provider does not exist in this map' );
96+
}
97+
98+
if ( $index === null ) {
99+
$index = count( $this->byPropertyId[$idSerialization] );
100+
}
101+
102+
array_splice( $this->byPropertyId[$idSerialization], $oldIndex, 1 );
103+
array_splice( $this->byPropertyId[$idSerialization], $index, 0, array( $propertyIdProvider ) );
104+
105+
$this->byPropertyId[$idSerialization] = array_values( $this->byPropertyId[$idSerialization] );
106+
}
107+
108+
/**
109+
* @param PropertyIdProvider $propertyIdProvider
110+
* @param int|null $index
111+
*
112+
* @throws InvalidArgumentException
113+
*/
114+
public function addElementAtIndex( PropertyIdProvider $propertyIdProvider, $index ) {
115+
$this->assertIsIndex( $index );
116+
117+
$idSerialization = $propertyIdProvider->getPropertyId()->getSerialization();
118+
119+
if ( !isset( $this->byPropertyId[$idSerialization] ) ) {
120+
$this->byPropertyId[$idSerialization] = array();
121+
$this->propertyIds[] = $propertyIdProvider->getPropertyId();
122+
}
123+
124+
if ( $index === null ) {
125+
$index = count( $this->byPropertyId[$idSerialization] );
126+
}
127+
128+
array_splice( $this->byPropertyId[$idSerialization], $index, 0, array( $propertyIdProvider ) );
129+
130+
$this->byPropertyId[$idSerialization] = array_values( $this->byPropertyId[$idSerialization] );
131+
}
132+
133+
private function assertIsIndex( $index ) {
134+
if ( ( !is_int( $index ) || $index < 0 ) && $index !== null ) {
135+
throw new InvalidArgumentException( '$index must be a non-negative integer or null' );
136+
}
137+
}
138+
139+
/**
140+
* @return PropertyIdProvider[]
141+
*/
142+
public function getFlatArray() {
143+
$propertyIdProviders = array();
144+
145+
foreach ( $this->propertyIds as $propertyId ) {
146+
foreach ( $this->byPropertyId[$propertyId->getSerialization()] as $propertyIdProvider ) {
147+
$propertyIdProviders[] = $propertyIdProvider;
148+
}
149+
}
150+
151+
return $propertyIdProviders;
152+
}
153+
154+
}

0 commit comments

Comments
 (0)