Tobias Gritschacher has submitted this change and it was merged. Change subject: Have HashArray dirive directly from ArrayObject so there is no dependency on MW ......................................................................
Have HashArray dirive directly from ArrayObject so there is no dependency on MW Change-Id: Iee7877fdc04653475a5eaae3e15569f6b5e8a004 --- M DataModel/DataModel/HashArray.php M DataModel/tests/phpunit/hasharray/HashArrayTest.php 2 files changed, 199 insertions(+), 3 deletions(-) Approvals: Tobias Gritschacher: Looks good to me, approved jenkins-bot: Verified diff --git a/DataModel/DataModel/HashArray.php b/DataModel/DataModel/HashArray.php index 326de4d..9b68151 100644 --- a/DataModel/DataModel/HashArray.php +++ b/DataModel/DataModel/HashArray.php @@ -3,6 +3,7 @@ namespace Wikibase; use Hashable; use GenericArrayObject; +use InvalidArgumentException; /** * Generic array object with lookups based on hashes of the elements. @@ -45,7 +46,7 @@ * @licence GNU GPL v2+ * @author Jeroen De Dauw < [email protected] > */ -abstract class HashArray extends GenericArrayObject implements \Hashable, \Comparable { +abstract class HashArray extends \ArrayObject implements \Hashable, \Comparable { /** * Maps element hashes to their offsets. @@ -66,7 +67,64 @@ protected $acceptDuplicates = false; /** - * @see GenericArrayObject::preSetElement + * @var integer + */ + protected $indexOffset = 0; + + /** + * Returns the name of an interface/class that the element should implement/extend. + * + * @since 0.4 + * + * @return string + */ + abstract public function getObjectType(); + + /** + * Constructor. + * @see ArrayObject::__construct + * + * @since 1.20 + * + * @param null|array $input + * @param int $flags + * @param string $iterator_class + */ + public function __construct( $input = null, $flags = 0, $iterator_class = 'ArrayIterator' ) { + parent::__construct( array(), $flags, $iterator_class ); + + if ( !is_null( $input ) ) { + foreach ( $input as $offset => $value ) { + $this->offsetSet( $offset, $value ); + } + } + } + + /** + * Finds a new offset for when appending an element. + * The base class does this, so it would be better to integrate, + * but there does not appear to be any way to do this... + * + * @since 1.20 + * + * @return integer + */ + protected function getNewOffset() { + while ( $this->offsetExists( $this->indexOffset ) ) { + $this->indexOffset++; + } + + return $this->indexOffset; + } + + /** + * Gets called before a new element is added to the ArrayObject. + * + * At this point the index is always set (ie not null) and the + * value is always of the type returned by @see getObjectType. + * + * Should return a boolean. When false is returned the element + * does not get added to the ArrayObject. * * @since 0.1 * @@ -341,4 +399,133 @@ } } + + + + + + + + + + + /** + * @see ArrayObject::append + * + * @since 1.20 + * + * @param mixed $value + */ + public function append( $value ) { + $this->setElement( null, $value ); + } + + /** + * @see ArrayObject::offsetSet() + * + * @since 1.20 + * + * @param mixed $index + * @param mixed $value + */ + public function offsetSet( $index, $value ) { + $this->setElement( $index, $value ); + } + + /** + * Returns if the provided value has the same type as the elements + * that can be added to this ArrayObject. + * + * @since 1.20 + * + * @param mixed $value + * + * @return boolean + */ + protected function hasValidType( $value ) { + $class = $this->getObjectType(); + return $value instanceof $class; + } + + /** + * Method that actually sets the element and holds + * all common code needed for set operations, including + * type checking and offset resolving. + * + * If you want to do additional indexing or have code that + * otherwise needs to be executed whenever an element is added, + * you can overload @see preSetElement. + * + * @since 1.20 + * + * @param mixed $index + * @param mixed $value + * + * @throws InvalidArgumentException + */ + protected function setElement( $index, $value ) { + if ( !$this->hasValidType( $value ) ) { + throw new InvalidArgumentException( + 'Can only add ' . $this->getObjectType() . ' implementing objects to ' . get_called_class() . '.' + ); + } + + if ( is_null( $index ) ) { + $index = $this->getNewOffset(); + } + + if ( $this->preSetElement( $index, $value ) ) { + parent::offsetSet( $index, $value ); + } + } + + /** + * @see Serializable::serialize + * + * @since 1.20 + * + * @return string + */ + public function serialize() { + return serialize( array( + 'data' => $this->getArrayCopy(), + 'index' => $this->indexOffset, + ) ); + } + + /** + * @see Serializable::unserialize + * + * @since 1.20 + * + * @param string $serialization + * + * @return array + */ + public function unserialize( $serialization ) { + $serializationData = unserialize( $serialization ); + + foreach ( $serializationData['data'] as $offset => $value ) { + // Just set the element, bypassing checks and offset resolving, + // as these elements have already gone through this. + parent::offsetSet( $offset, $value ); + } + + $this->indexOffset = $serializationData['index']; + + return $serializationData; + } + + /** + * Returns if the ArrayObject has no elements. + * + * @since 1.20 + * + * @return boolean + */ + public function isEmpty() { + return $this->count() === 0; + } + + } diff --git a/DataModel/tests/phpunit/hasharray/HashArrayTest.php b/DataModel/tests/phpunit/hasharray/HashArrayTest.php index 5ef5983..0a61ebd 100644 --- a/DataModel/tests/phpunit/hasharray/HashArrayTest.php +++ b/DataModel/tests/phpunit/hasharray/HashArrayTest.php @@ -35,10 +35,19 @@ * @licence GNU GPL v2+ * @author Jeroen De Dauw < [email protected] > */ -abstract class HashArrayTest extends \GenericArrayObjectTest { +abstract class HashArrayTest extends \MediaWikiTestCase { public abstract function constructorProvider(); + /** + * Returns the name of the concrete class being tested. + * + * @since 0.4 + * + * @return string + */ + abstract public function getInstanceClass(); + public function instanceProvider() { $class = $this->getInstanceClass(); -- To view, visit https://gerrit.wikimedia.org/r/63218 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iee7877fdc04653475a5eaae3e15569f6b5e8a004 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Jeroen De Dauw <[email protected]> Gerrit-Reviewer: Anja Jentzsch <[email protected]> Gerrit-Reviewer: Ataherivand <[email protected]> Gerrit-Reviewer: Aude <[email protected]> Gerrit-Reviewer: Daniel Kinzler <[email protected]> Gerrit-Reviewer: Daniel Werner <[email protected]> Gerrit-Reviewer: Denny Vrandecic <[email protected]> Gerrit-Reviewer: Henning Snater <[email protected]> Gerrit-Reviewer: Jens Ohlig <[email protected]> Gerrit-Reviewer: Jeroen De Dauw <[email protected]> Gerrit-Reviewer: John Erling Blad <[email protected]> Gerrit-Reviewer: Lydia Pintscher <[email protected]> Gerrit-Reviewer: Markus Kroetzsch <[email protected]> Gerrit-Reviewer: Nikola Smolenski <[email protected]> Gerrit-Reviewer: Silke Meyer <[email protected]> Gerrit-Reviewer: Tobias Gritschacher <[email protected]> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
