Skip to content

Commit d111f7a

Browse files
author
Paul
committed
Added second parameter (data) to Copy to replace Walk functionality.
Removed Walk strategy. Updated readme.
1 parent fb31788 commit d111f7a

File tree

7 files changed

+96
-156
lines changed

7 files changed

+96
-156
lines changed

README.md

+19-66
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,9 @@ Contents
3939
1. [Merge](#merge)
4040
1. [TakeFirst](#takefirst)
4141
1. [ToList](#tolist)
42-
1. [Translate](#translate)
4342
1. [TryCatch](#trycatch)
4443
1. [Type](#type)
4544
1. [Unique](#unique)
46-
1. [Walk](#walk)
4745
1. [Others](#others)
4846
1. [Debug](#debug)
4947
1. [Requirements](#requirements)
@@ -287,7 +285,7 @@ The following strategies ship with Mapper and provide a suite of commonly used f
287285

288286
#### Fetchers
289287

290-
- [Copy](#copy) – Copies a portion of input data.
288+
- [Copy](#copy) – Copies a portion of input data, or specified data, according to a lookup path.
291289
- [CopyContext](#copycontext) – Copies a portion of context data.
292290
- [CopyKey](#copykey) – Copies the current key.
293291

@@ -305,29 +303,28 @@ The following strategies ship with Mapper and provide a suite of commonly used f
305303
- [Merge](#merge) – Merges two data sets together giving precedence to the latter if keys collide.
306304
- [TakeFirst](#takefirst) – Takes the first value from a collection one or more times.
307305
- [ToList](#tolist) – Converts data to a single-element list unless it is already a list.
308-
- [Translate](#translate) – Translates a value using a mapping.
309306
- [TryCatch](#trycatch) – Tries the primary strategy and falls back to an expression if an exception is thrown.
310307
- [Type](#type) – Casts data to the specified type.
311308
- [Unique](#unique) – Creates a collection of unique values by removing duplicates.
312-
- [Walk](#walk) – Walks a nested structure to the specified element in the same manner as `Copy`.
313309

314310
#### Others
315311

316312
- [Debug](#debug) – Debugs a mapping by breaking the debugger wherever this strategy is inserted.
317313

318314
### Copy
319315

320-
Copies a portion of the input data according to the specified path. Supports traversing nested arrays.
316+
Copies a portion of input data, or specified data, according to a lookup path. Supports traversing nested arrays.
321317

322-
`Copy` is probably the most common strategy whether used by itself or injected into other strategies.
318+
`Copy` is probably the most common strategy whether used by itself or injected into other strategies. Since both its *path* and *data* parameters can be mapped expressions it is highly versatile and can be combined with other strategies, or even itself, to produce powerful expressions.
323319

324320
#### Signature
325321

326322
```php
327-
Copy(Strategy|Mapping|array|mixed $path)
323+
Copy(Strategy|Mapping|array|mixed $path, Strategy|Mapping|array|mixed $data)
328324
```
329325

330326
1. `$path` – Array of path components, string of `->`-delimited path components or a strategy or mapping resolving to such an expression.
327+
2. `$data` – Optional. Array data or an expression that resolves to an array to be copied instead of input data.
331328

332329
#### Example
333330

@@ -351,9 +348,22 @@ $data = [
351348

352349
> 123
353350
351+
#### Specified data example
352+
353+
When data is specified in the second parameter it is used instead of the data sent from `Mapper`.
354+
355+
```php
356+
(new Mapper)->map(
357+
['foo' => 'bar'],
358+
new Copy('foo', ['foo' => 'baz'])
359+
);
360+
```
361+
362+
> 'baz'
363+
354364
#### Path resolver example
355365

356-
Since the path can be derived from other strategies we could nest `Copy` instances to look up values referenced by other keys.
366+
Since the path can be derived from other strategies we can nest `Copy` instances to look up values referenced by other keys.
357367

358368
```php
359369
(new Mapper)->map(
@@ -772,33 +782,6 @@ ToList(Strategy|Mapping|array|mixed $expression)
772782

773783
> ['bar']
774784
775-
### Translate
776-
777-
Translates a value using a mapping. The mapping may derived from any valid expression.
778-
779-
#### Signature
780-
781-
```php
782-
Translate(Strategy $value, Strategy|Mapping|array|mixed $mapping)
783-
```
784-
785-
1. `$value` – Value used to match against an entry in the mapping.
786-
2. `$mapping` – Mapping that specifies what the value may be translated to.
787-
788-
#### Example
789-
790-
```php
791-
(new Mapper)->map(
792-
['foo' => 'foo'],
793-
new Translate(
794-
new Copy('foo'),
795-
['foo' => 'bar']
796-
)
797-
);
798-
```
799-
800-
> 'bar'
801-
802785
### TryCatch
803786

804787
Tries the primary strategy and falls back to an expression if an exception is thrown. The thrown exception is passed to the specified exception handler. The handler should throw an exception if it does not expect the exception type it receives.
@@ -882,36 +865,6 @@ Unique(Strategy|Mapping|array|mixed $collection)
882865

883866
> [1, 2, 3, 4, 5]
884867
885-
### Walk
886-
887-
Walks a nested structure to the specified element in the same manner as [`Copy`](#copy).
888-
889-
#### Signature
890-
891-
```php
892-
Walk(Strategy|Mapping|array|mixed $expression, Strategy|Mapping|array|mixed $path)
893-
```
894-
895-
1. `$expression` – Expression to walk.
896-
2. `$path` – Array of path components, string of `->`-delimited path components or a strategy or mapping resolving to such an expression.
897-
898-
#### Example
899-
900-
```php
901-
(new Mapper)->map(
902-
[
903-
'foo' => [
904-
'bar' => [
905-
'baz' => 123,
906-
],
907-
],
908-
],
909-
new Walk(new Copy('foo'), 'bar->baz')
910-
)
911-
```
912-
913-
> 123
914-
915868
### Debug
916869

917870
Debugs a mapping by breaking the debugger wherever this strategy is inserted. The specified expression will be mapped immediately before triggering the breakpoint. The debugger should see the current data, context and mapped expression.

src/Strategy/Copy.php

+28-1
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,32 @@
22
namespace ScriptFUSION\Mapper\Strategy;
33

44
use ScriptFUSION\ArrayWalker\ArrayWalker;
5+
use ScriptFUSION\Mapper\Mapping;
56

67
/**
7-
* Copies a portion of input data.
8+
* Copies a portion of input data, or specified data, according to a lookup path.
89
*/
910
class Copy extends Delegate
1011
{
1112
const PATH_SEPARATOR = '->';
1213

14+
private $data;
15+
16+
/**
17+
* Initializes this instance with the specified path. If data is specified it is always used instead of input data.
18+
*
19+
* @param Strategy|Mapping|array|mixed $path Array of path components, string of `->`-delimited path components or
20+
* a strategy or mapping resolving to such an expression.
21+
* @param Strategy|Mapping|array|mixed $data Optional. Array data or an expression that resolves to an array to be
22+
* copied instead of input data.
23+
*/
24+
public function __construct($path, $data = null)
25+
{
26+
parent::__construct($path);
27+
28+
$this->data = $data;
29+
}
30+
1331
/**
1432
* @param mixed $record
1533
* @param mixed $context
@@ -18,14 +36,23 @@ class Copy extends Delegate
1836
*/
1937
public function __invoke($record, $context = null)
2038
{
39+
// It is typically an error for record not to be an array but we prefer to avoid throwing exceptions.
2140
if (!is_array($record)) {
2241
return null;
2342
}
2443

44+
// Resolve the path expression. Path will always be an array after this block.
2545
if (!is_array($path = parent::__invoke($record, $context))) {
46+
// If it's not an array treat it as a delimited string; implicitly casts other scalar types.
2647
$path = explode(self::PATH_SEPARATOR, $path);
2748
}
2849

50+
// Overwrite record with resolved data expression if set and ensure it is an array.
51+
if ($this->data !== null && !is_array($record = $this->delegate($this->data, $record, $context))) {
52+
return null;
53+
}
54+
55+
// Walk path unless it is empty.
2956
return $path ? ArrayWalker::walk($record, $path) : null;
3057
}
3158
}

src/Strategy/Walk.php

-31
This file was deleted.

test/Functional/DocumentationTest.php

+11-19
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@
1818
use ScriptFUSION\Mapper\Strategy\Merge;
1919
use ScriptFUSION\Mapper\Strategy\TakeFirst;
2020
use ScriptFUSION\Mapper\Strategy\ToList;
21-
use ScriptFUSION\Mapper\Strategy\Translate;
2221
use ScriptFUSION\Mapper\Strategy\TryCatch;
2322
use ScriptFUSION\Mapper\Strategy\Type;
2423
use ScriptFUSION\Mapper\Strategy\Unique;
25-
use ScriptFUSION\Mapper\Strategy\Walk;
2624
use ScriptFUSIONTest\Fixture\BarBucketAddressToAddresesMapping;
2725
use ScriptFUSIONTest\Fixture\FooBookAddressToAddresesMapping;
2826
use ScriptFUSIONTest\Fixture\FooToBarMapping;
@@ -100,6 +98,17 @@ public function testCopy()
10098
self::assertSame($bar, (new Mapper)->map($data, new Copy(['foo', 'bar'])));
10199
}
102100

101+
public function testSpecifiedDataCopy()
102+
{
103+
self::assertSame(
104+
'baz',
105+
(new Mapper)->map(
106+
['foo' => 'bar'],
107+
new Copy('foo', ['foo' => 'baz'])
108+
)
109+
);
110+
}
111+
103112
public function testNestedCopy()
104113
{
105114
self::assertSame(
@@ -355,21 +364,4 @@ public function testUnique()
355364
)
356365
);
357366
}
358-
359-
public function testWalk()
360-
{
361-
self::assertSame(
362-
$baz = 123,
363-
(new Mapper)->map(
364-
[
365-
'foo' => [
366-
'bar' => [
367-
'baz' => $baz,
368-
],
369-
],
370-
],
371-
new Walk(new Copy('foo'), 'bar->baz')
372-
)
373-
);
374-
}
375367
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
namespace ScriptFUSIONTest\Integration\Mapper\Strategy;
3+
4+
use ScriptFUSION\Mapper\Mapper;
5+
use ScriptFUSION\Mapper\Strategy\Copy;
6+
7+
final class CopyTest extends \PHPUnit_Framework_TestCase
8+
{
9+
public function testWalkFixedPath()
10+
{
11+
$copy = (new Copy('foo->bar', ['foo' => ['bar' => 'baz']]))
12+
->setMapper(new Mapper);
13+
14+
self::assertSame('baz', $copy([]));
15+
}
16+
17+
public function testWalkStrategyPath()
18+
{
19+
$copy = (new Copy(new Copy('foo'), ['bar' => 'baz']))
20+
->setMapper(new Mapper);
21+
22+
self::assertSame('baz', $copy(['foo' => 'bar']));
23+
}
24+
}

test/Integration/Mapper/Strategy/WalkTest.php

-25
This file was deleted.

test/Unit/Mapper/Strategy/CopyTest.php

+14-14
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,6 @@ final class CopyTest extends \PHPUnit_Framework_TestCase
99
{
1010
use MockeryPHPUnitIntegration;
1111

12-
public function testNullRecord()
13-
{
14-
$copy = self::createStrategy(0);
15-
16-
self::assertNull($copy(null));
17-
}
18-
19-
public function testNullPath()
20-
{
21-
$copy = self::createStrategy(null);
22-
23-
self::assertNull($copy([]));
24-
}
25-
2612
public function testFalsyPathComponentString()
2713
{
2814
$copy = self::createStrategy('0');
@@ -41,6 +27,20 @@ public function testFalsyPathComponentArray()
4127
self::assertSame('bar', $copy([['foo', 'bar']]));
4228
}
4329

30+
public function testNullRecord()
31+
{
32+
$copy = self::createStrategy(0);
33+
34+
self::assertNull($copy(null));
35+
}
36+
37+
public function testNullPath()
38+
{
39+
$copy = self::createStrategy(null);
40+
41+
self::assertNull($copy([]));
42+
}
43+
4444
public function testEmptyPathString()
4545
{
4646
$copy = self::createStrategy('');

0 commit comments

Comments
 (0)