diff --git a/src/Objects/CollectionIterator.php b/src/Objects/CollectionIterator.php new file mode 100644 index 0000000..535dd70 --- /dev/null +++ b/src/Objects/CollectionIterator.php @@ -0,0 +1,104 @@ +hasField('type') && + in_array( $collection['type'], array( 'Collection', 'OrderedCollection' ) ) ) ) { + throw new InvalidArgumentException('Must pass a collection'); + } + $itemsField = 'items'; + if ( $collection['type'] == 'OrderedCollection' ) { + $itemsField = 'orderedItems'; + } + $this->items = $collection[$itemsField]; + if ( ! $this->items ) { + throw new InvalidArgumentException('Collection must have an items or orderedItems field!'); + } + $this->collection = $collection; + $this->idx = 0; + } + + public static function iterateCollection( ActivityPubObject $collection ) + { + return new CollectionIterator( $collection ); + } + + /** + * Return the current element + * @link https://php.net/manual/en/iterator.current.php + * @return mixed Can return any type. + * @since 5.0.0 + */ + public function current() + { + return $this->items[$this->idx]; + } + + /** + * Move forward to next element + * @link https://php.net/manual/en/iterator.next.php + * @return void Any returned value is ignored. + * @since 5.0.0 + */ + public function next() + { + $this->idx += 1; + } + + /** + * Return the key of the current element + * @link https://php.net/manual/en/iterator.key.php + * @return mixed scalar on success, or null on failure. + * @since 5.0.0 + */ + public function key() + { + return $this->idx; + } + + /** + * Checks if current position is valid + * @link https://php.net/manual/en/iterator.valid.php + * @return boolean The return value will be casted to boolean and then evaluated. + * Returns true on success or false on failure. + * @since 5.0.0 + */ + public function valid() + { + return $this->items->hasField($this->idx); + } + + /** + * Rewind the Iterator to the first element + * @link https://php.net/manual/en/iterator.rewind.php + * @return void Any returned value is ignored. + * @since 5.0.0 + */ + public function rewind() + { + $this->idx = 0; + } +} \ No newline at end of file diff --git a/test/Objects/CollectionIteratorTest.php b/test/Objects/CollectionIteratorTest.php new file mode 100644 index 0000000..66ed82d --- /dev/null +++ b/test/Objects/CollectionIteratorTest.php @@ -0,0 +1,131 @@ + 'basicIteration', + 'collection' => TestActivityPubObject::fromArray( array( + 'id' => 'mycollection', + 'type' => 'Collection', + 'items' => array( + array( + 'id' => 'item1', + ), + array( + 'id' => 'item2', + ), + array( + 'id' => 'item3', + ), + ) + ) ), + 'expectedItems' => array( + array( + 'id' => 'item1', + ), + array( + 'id' => 'item2', + ), + array( + 'id' => 'item3', + ), + ), + ) ), + array( array( + 'id' => 'orderedCollection', + 'collection' => TestActivityPubObject::fromArray( array( + 'id' => 'mycollection', + 'type' => 'OrderedCollection', + 'orderedItems' => array( + array( + 'id' => 'item1', + ), + array( + 'id' => 'item2', + ), + array( + 'id' => 'item3', + ), + ) + ) ), + 'expectedItems' => array( + array( + 'id' => 'item1', + ), + array( + 'id' => 'item2', + ), + array( + 'id' => 'item3', + ), + ), + ) ), + array( array( + 'id' => 'orderedCollectionWrongItems', + 'collection' => TestActivityPubObject::fromArray( array( + 'id' => 'mycollection', + 'type' => 'OrderedCollection', + 'items' => array( + array( + 'id' => 'item1', + ), + array( + 'id' => 'item2', + ), + array( + 'id' => 'item3', + ), + ) + ) ), + 'expectedException' => \InvalidArgumentException::class, + ) ), + array( array( + 'id' => 'unorderedCollectionWrongItems', + 'collection' => TestActivityPubObject::fromArray( array( + 'id' => 'mycollection', + 'type' => 'Collection', + 'orderedItems' => array( + array( + 'id' => 'item1', + ), + array( + 'id' => 'item2', + ), + array( + 'id' => 'item3', + ), + ) + ) ), + 'expectedException' => \InvalidArgumentException::class, + ) ), + ); + } + + /** + * @dataProvider provideTestCollectionIterator + */ + public function testCollectionIterator( $testCase ) + { + $this->setExpectedException( null ); + if ( array_key_exists( 'expectedException', $testCase ) ) { + $this->setExpectedException( $testCase['expectedException'] ); + } + foreach ( CollectionIterator::iterateCollection( $testCase['collection'] ) as $idx => $item ) { + if ( $item instanceof ActivityPubObject ) { + $item = $item->asArray(); + } + $this->assertEquals( $testCase['expectedItems'][$idx], $item, "Error on test $testCase[id]" ); + } + } +} \ No newline at end of file