Skip to content

Commit

Permalink
Add ::proxy() operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Aug 19, 2019
1 parent a9127d8 commit 4bba092
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
22 changes: 22 additions & 0 deletions spec/drupol/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,28 @@ public function it_can_prepend(): void
->shouldReturn(['A', 'B', 'C', 'D', 'E', 'F']);
}

public function it_can_proxy(): void
{
$input1 = new \ArrayObject(\range('A', 'E'));
$input2 = new \ArrayObject(\range(1, 5));

$this
->beConstructedThrough('with', [[$input1, $input2]]);

$this
->proxy('map', 'count')
->all()
->shouldReturn([5, 5]);

$this
->shouldThrow(\Exception::class)
->during('proxy', ['map', 'foo']);

$this
->shouldThrow(\Exception::class)
->during('proxy', ['foo', 'foo']);
}

public function it_can_rebase(): void
{
$this
Expand Down
9 changes: 9 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use drupol\collection\Operation\Pad;
use drupol\collection\Operation\Pluck;
use drupol\collection\Operation\Prepend;
use drupol\collection\Operation\Proxy;
use drupol\collection\Operation\Range;
use drupol\collection\Operation\Rebase;
use drupol\collection\Operation\Skip;
Expand Down Expand Up @@ -304,6 +305,14 @@ public function prepend(...$items): CollectionInterface
return $this->run(Prepend::with(...$items));
}

/**
* {@inheritdoc}
*/
public function proxy(string $method, string $proxyMethod, ...$parameters): CollectionInterface
{
return $this->run(Proxy::with($method, $proxyMethod, $parameters));
}

/**
* Create a new with a range of number.
*
Expand Down
11 changes: 11 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace drupol\collection\Contract;

use drupol\collection\Contract\Collection as CollectionInterface;

/**
* Interface Collection.
*/
Expand Down Expand Up @@ -220,6 +222,15 @@ public function pluck($pluck, $default = null): self;
*/
public function prepend(...$items): self;

/**
* @param string $method
* @param string $proxyMethod
* @param mixed ...$parameters
*
* @return \drupol\collection\Contract\Collection
*/
public function proxy(string $method, string $proxyMethod, ...$parameters): CollectionInterface;

/**
* @return \drupol\collection\Contract\Collection
*/
Expand Down
44 changes: 44 additions & 0 deletions src/Operation/Proxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace drupol\collection\Operation;

use drupol\collection\Collection;
use drupol\collection\Contract\Collection as CollectionInterface;

/**
* Class Proxy.
*/
final class Proxy extends Operation
{
/**
* {@inheritdoc}
*/
public function run(CollectionInterface $collection): CollectionInterface
{
[$method, $proxyMethod, $parameters] = $this->parameters;

$callback = static function ($value) use ($proxyMethod, $parameters) {
$reflection = new \ReflectionClass($value);

if (false === $reflection->hasMethod($proxyMethod)) {
throw new \InvalidArgumentException(\sprintf('Proxy method %s does not exist.', $proxyMethod));
}

return $reflection
->getMethod($proxyMethod)
->invoke($value, ...$parameters);
};

$reflection = new \ReflectionClass($collection);

if (false === $reflection->hasMethod($method)) {
throw new \InvalidArgumentException(\sprintf('Method %s does not exist.', $method));
}

return Collection::with($reflection
->getMethod($method)
->invoke($collection->rebase(), $callback));
}
}

0 comments on commit 4bba092

Please sign in to comment.