Skip to content

Commit 9b11e54

Browse files
committed
Merge branch '4.0'
2 parents 02706f0 + 40c2815 commit 9b11e54

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1474
-1164
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ php:
1010
- 5.6
1111
- 7.0
1212
- 7.1
13+
- 7.2
1314

1415
env:
1516
matrix:
@@ -21,7 +22,7 @@ matrix:
2122

2223
cache:
2324
directories:
24-
- .composer/cache
25+
- vendor
2526

2627
install:
2728
- alias composer=composer\ -n && composer selfupdate

README.md

Lines changed: 193 additions & 123 deletions
Large diffs are not rendered by default.

composer.json

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@
1010
"license": "LGPL-3.0",
1111
"require": {
1212
"php": "^5.5|^7",
13-
"connectors/http": "^1",
14-
"connectors/soap": "^1",
1513
"scriptfusion/static-class": "^1",
1614
"scriptfusion/retry": "^1.1",
17-
"scriptfusion/retry-exception-handlers": "^1",
18-
"eloquent/enumeration": "^5",
15+
"scriptfusion/retry-exception-handlers": "^1.1",
16+
"psr/container": "^1",
1917
"psr/cache": "^1"
2018
},
2119
"require-dev": {
2220
"phpunit/phpunit": "^4.8",
2321
"mockery/mockery": "^0.9.4"
2422
},
2523
"suggest" : {
26-
"transformers/mapping": "Transforms array collections using Mappings."
24+
"connectors/http": "Provides an HTTP connector for Porter providers.",
25+
"transformers/mapping-transformer": "Transforms records using Mappings."
2726
},
2827
"autoload": {
2928
"psr-4": {
@@ -37,10 +36,5 @@
3736
},
3837
"scripts": {
3938
"test": "phpunit -c test"
40-
},
41-
"extra": {
42-
"branch-alias": {
43-
"dev-master": "3-dev"
44-
}
4539
}
4640
}

src/Cache/CacheAdvice.php

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/Cache/CacheKeyGenerator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
interface CacheKeyGenerator
55
{
6+
const RESERVED_CHARACTERS = '{}()/\@:';
7+
68
/**
79
* @param string $source
810
* @param array $sortedOptions Options sorted by key.

src/Cache/CacheToggle.php

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/Cache/CacheUnavailableException.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
/**
77
* The exception that is thrown when cache is unavailable.
88
*/
9-
class CacheUnavailableException extends \RuntimeException implements CacheException
9+
final class CacheUnavailableException extends \RuntimeException implements CacheException
1010
{
11-
public static function modify()
11+
public static function createUnsupported()
1212
{
13-
return new self('Cannot modify cache: cache unavailable.');
13+
return new self('Cannot cache: connector does not support caching.');
1414
}
1515
}

src/Cache/JsonCacheKeyGenerator.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
<?php
22
namespace ScriptFUSION\Porter\Cache;
33

4-
use ScriptFUSION\Porter\Connector\CachingConnector;
5-
64
class JsonCacheKeyGenerator implements CacheKeyGenerator
75
{
86
public function generateCacheKey($source, array $sortedOptions)
97
{
108
return str_replace(
11-
str_split(CachingConnector::RESERVED_CHARACTERS),
9+
str_split(self::RESERVED_CHARACTERS),
1210
'.',
1311
json_encode([$source, $sortedOptions], JSON_UNESCAPED_SLASHES)
1412
);

src/Collection/RecordCollection.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,54 @@ abstract class RecordCollection implements \Iterator
1010

1111
private $previousCollection;
1212

13-
public function __construct(\Iterator $records, RecordCollection $previousCollection = null)
13+
public function __construct(\Iterator $records, self $previousCollection = null)
1414
{
1515
$this->records = $records;
1616
$this->previousCollection = $previousCollection;
1717
}
1818

19+
/**
20+
* @return array
21+
*/
1922
public function current()
2023
{
21-
return $this->records->current();
24+
$current = $this->records->current();
25+
26+
// TODO: Consider removing when dropping PHP 5 support (replace with type hint).
27+
if (!is_array($current)) {
28+
throw new \RuntimeException('Record collection did not return an array.');
29+
}
30+
31+
return $current;
2232
}
2333

34+
/**
35+
* @return void
36+
*/
2437
public function next()
2538
{
2639
$this->records->next();
2740
}
2841

42+
/**
43+
* @return mixed
44+
*/
2945
public function key()
3046
{
3147
return $this->records->key();
3248
}
3349

50+
/**
51+
* @return bool
52+
*/
3453
public function valid()
3554
{
3655
return $this->records->valid();
3756
}
3857

58+
/**
59+
* @return void
60+
*/
3961
public function rewind()
4062
{
4163
$this->records->rewind();

src/Connector/CachingConnector.php

Lines changed: 35 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,127 +3,101 @@
33

44
use Psr\Cache\CacheItemPoolInterface;
55
use ScriptFUSION\Porter\Cache\CacheKeyGenerator;
6-
use ScriptFUSION\Porter\Cache\CacheToggle;
76
use ScriptFUSION\Porter\Cache\InvalidCacheKeyException;
87
use ScriptFUSION\Porter\Cache\JsonCacheKeyGenerator;
98
use ScriptFUSION\Porter\Cache\MemoryCache;
10-
use ScriptFUSION\Porter\Options\EncapsulatedOptions;
119

1210
/**
13-
* Caches remote data using PSR-6-compliant objects.
11+
* Wraps a connector to cache fetched data using PSR-6-compliant objects.
1412
*/
15-
abstract class CachingConnector implements Connector, CacheToggle
13+
class CachingConnector implements Connector, ConnectorWrapper
1614
{
17-
const RESERVED_CHARACTERS = '{}()/\@:';
18-
1915
/**
20-
* @var CacheItemPoolInterface
16+
* @var Connector
2117
*/
22-
private $cache;
18+
private $connector;
2319

2420
/**
25-
* @var bool
21+
* @var CacheItemPoolInterface
2622
*/
27-
private $cacheEnabled = true;
23+
private $cache;
2824

2925
/**
3026
* @var CacheKeyGenerator
3127
*/
3228
private $cacheKeyGenerator;
3329

34-
public function __construct(CacheItemPoolInterface $cache = null, CacheKeyGenerator $cacheKeyGenerator = null)
35-
{
30+
public function __construct(
31+
Connector $connector,
32+
CacheItemPoolInterface $cache = null,
33+
CacheKeyGenerator $cacheKeyGenerator = null
34+
) {
35+
$this->connector = $connector;
3636
$this->cache = $cache ?: new MemoryCache;
3737
$this->cacheKeyGenerator = $cacheKeyGenerator ?: new JsonCacheKeyGenerator;
3838
}
3939

40+
public function __clone()
41+
{
42+
$this->connector = clone $this->connector;
43+
44+
/* It doesn't make sense to clone the cache because we want cache state to be shared between imports.
45+
We're also not cloning the CacheKeyGenerator because they're expected to be stateless algorithms. */
46+
}
47+
4048
/**
49+
* @param ConnectionContext $context
4150
* @param string $source
42-
* @param EncapsulatedOptions|null $options
4351
*
4452
* @return mixed
4553
*
4654
* @throws InvalidCacheKeyException
4755
*/
48-
public function fetch($source, EncapsulatedOptions $options = null)
56+
public function fetch(ConnectionContext $context, $source)
4957
{
50-
if ($this->isCacheEnabled()) {
51-
$optionsCopy = $options ? $options->copy() : [];
52-
53-
ksort($optionsCopy);
58+
if ($context->mustCache()) {
59+
$options = $this->connector instanceof ConnectorOptions ? $this->connector->getOptions()->copy() : [];
60+
ksort($options);
5461

55-
$key = $this->validateCacheKey($this->getCacheKeyGenerator()->generateCacheKey($source, $optionsCopy));
62+
$this->validateCacheKey($key = $this->cacheKeyGenerator->generateCacheKey($source, $options));
5663

5764
if ($this->cache->hasItem($key)) {
5865
return $this->cache->getItem($key)->get();
5966
}
6067
}
6168

62-
$data = $this->fetchFreshData($source, $options);
69+
$data = $this->connector->fetch($context, $source);
6370

6471
isset($key) && $this->cache->save($this->cache->getItem($key)->set($data));
6572

6673
return $data;
6774
}
6875

69-
abstract public function fetchFreshData($source, EncapsulatedOptions $options = null);
70-
71-
public function getCache()
72-
{
73-
return $this->cache;
74-
}
75-
76-
public function setCache(CacheItemPoolInterface $cache)
77-
{
78-
$this->cache = $cache;
79-
}
80-
81-
public function enableCache()
82-
{
83-
$this->cacheEnabled = true;
84-
}
85-
86-
public function disableCache()
87-
{
88-
$this->cacheEnabled = false;
89-
}
90-
91-
public function isCacheEnabled()
92-
{
93-
return $this->cacheEnabled;
94-
}
95-
96-
public function getCacheKeyGenerator()
97-
{
98-
return $this->cacheKeyGenerator;
99-
}
100-
101-
public function setCacheKeyGenerator(CacheKeyGenerator $cacheKeyGenerator)
102-
{
103-
$this->cacheKeyGenerator = $cacheKeyGenerator;
104-
}
105-
10676
/**
10777
* @param mixed $key
10878
*
109-
* @return string
79+
* @return void
11080
*
11181
* @throws InvalidCacheKeyException Cache key contains invalid data.
11282
*/
11383
private function validateCacheKey($key)
11484
{
85+
// TODO: Remove when PHP 5 support dropped and replace with string hint.
11586
if (!is_string($key)) {
11687
throw new InvalidCacheKeyException('Cache key must be a string.');
11788
}
11889

119-
if (strpbrk($key, self::RESERVED_CHARACTERS) !== false) {
90+
if (strpbrk($key, CacheKeyGenerator::RESERVED_CHARACTERS) !== false) {
12091
throw new InvalidCacheKeyException(sprintf(
12192
'Cache key "%s" contains one or more reserved characters: "%s".',
12293
$key,
123-
self::RESERVED_CHARACTERS
94+
CacheKeyGenerator::RESERVED_CHARACTERS
12495
));
12596
}
97+
}
12698

127-
return $key;
99+
public function getWrappedConnector()
100+
{
101+
return $this->connector;
128102
}
129103
}

0 commit comments

Comments
 (0)