Skip to content

Commit 3e01f3b

Browse files
authored
Merge pull request #90 from UseMuffin/endpoint-locator
Make EndpointLocator implement LocatorInterface.
2 parents ef40a9a + f8c8f81 commit 3e01f3b

File tree

7 files changed

+43
-201
lines changed

7 files changed

+43
-201
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
"irc": "irc://irc.freenode.org/muffin"
4040
},
4141
"require": {
42-
"cakephp/orm": "^4.0"
42+
"cakephp/orm": "^4.1@RC"
4343
},
4444
"require-dev": {
45-
"cakephp/cakephp": "^4.0",
45+
"cakephp/cakephp": "^4.0.1@RC",
4646
"cakephp/cakephp-codesniffer": "^4.0",
4747
"phpunit/phpunit": "~8.5.0"
4848
},

config/bootstrap.php

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

src/Model/EndpointLocator.php

Lines changed: 23 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,28 @@
66
use Cake\Core\App;
77
use Cake\Datasource\ConnectionManager;
88
use Cake\Datasource\Exception\MissingDatasourceConfigException;
9+
use Cake\Datasource\Locator\AbstractLocator;
10+
use Cake\Datasource\RepositoryInterface;
911
use Cake\Utility\Inflector;
1012
use Muffin\Webservice\Datasource\Connection;
11-
use RuntimeException;
1213

1314
/**
1415
* Class EndpointLocator
15-
*
16-
* Should implement the LocatorInterface
17-
*
18-
* @see \Cake\ORM\Locator\LocatorInterface
19-
* @see https://github.com/cakephp/cakephp/issues/12014
2016
*/
21-
class EndpointLocator
17+
class EndpointLocator extends AbstractLocator
2218
{
23-
/**
24-
* Configuration for aliases.
25-
*
26-
* @var array
27-
*/
28-
protected $_config = [];
29-
30-
/**
31-
* Instances that belong to the locator.
32-
*
33-
* @var \Muffin\Webservice\Model\Endpoint[]
34-
*/
35-
protected $_instances = [];
36-
37-
/**
38-
* Contains a list of options that were passed to get() method.
39-
*
40-
* @var array
41-
*/
42-
protected $_options = [];
43-
4419
/**
4520
* Set an Endpoint instance to the locator.
4621
*
4722
* @param string $alias The alias to set.
4823
* @param \Muffin\Webservice\Model\Endpoint $object The table to set.
4924
* @return \Muffin\Webservice\Model\Endpoint
25+
* @psalm-suppress MoreSpecificImplementedParamType
26+
* @psalm-suppress MoreSpecificReturnType
5027
*/
51-
public function set(string $alias, Endpoint $object)
28+
public function set(string $alias, RepositoryInterface $object): Endpoint
5229
{
53-
return $this->_instances[$alias] = $object;
30+
return $this->instances[$alias] = $object;
5431
}
5532

5633
/**
@@ -63,17 +40,19 @@ public function set(string $alias, Endpoint $object)
6340
*/
6441
public function get(string $alias, array $options = []): Endpoint
6542
{
66-
if (isset($this->_instances[$alias])) {
67-
if (!empty($options) && $this->_options[$alias] !== $options) {
68-
throw new RuntimeException(sprintf(
69-
'You cannot configure "%s", it already exists in the locator.',
70-
$alias
71-
));
72-
}
73-
74-
return $this->_instances[$alias];
75-
}
43+
/** @var \Muffin\Webservice\Model\Endpoint */
44+
return parent::get($alias, $options);
45+
}
7646

47+
/**
48+
* Wrapper for creating endpoint instances
49+
*
50+
* @param string $alias Endpoint alias.
51+
* @param array $options The alias to check for.
52+
* @return \Muffin\Webservice\Model\Endpoint
53+
*/
54+
protected function createInstance(string $alias, array $options)
55+
{
7756
[, $classAlias] = pluginSplit($alias);
7857
$options = ['alias' => $classAlias] + $options;
7958

@@ -107,10 +86,11 @@ public function get(string $alias, array $options = []): Endpoint
10786
}
10887

10988
$options['registryAlias'] = $alias;
110-
$this->_instances[$alias] = $this->_create($options);
111-
$this->_options[$alias] = $options;
11289

113-
return $this->_instances[$alias];
90+
/** @psalm-var class-string<\Muffin\Webservice\Model\Endpoint> $className */
91+
$className = $options['className'];
92+
93+
return new $className($options);
11494
}
11595

11696
/**
@@ -132,108 +112,4 @@ protected function getConnection(string $connectionName): Connection
132112
throw new MissingDatasourceConfigException($message, $e->getCode(), $e->getPrevious());
133113
}
134114
}
135-
136-
/**
137-
* Check to see if an instance exists in the locator.
138-
*
139-
* @param string $alias The alias to check for.
140-
* @return bool
141-
*/
142-
public function exists(string $alias): bool
143-
{
144-
return isset($this->_instances[$alias]);
145-
}
146-
147-
/**
148-
* Returns configuration for an alias or the full configuration array for all aliases.
149-
*
150-
* @param string|null $alias Endpoint alias
151-
* @return array
152-
*/
153-
public function getConfig(?string $alias = null): array
154-
{
155-
if ($alias === null) {
156-
return $this->_config;
157-
}
158-
159-
return $this->_config[$alias] ?? [];
160-
}
161-
162-
/**
163-
* Stores a list of options to be used when instantiating an object with a matching alias.
164-
*
165-
* If configuring many aliases, use an array keyed by the alias.
166-
*
167-
* ```
168-
* $locator->setConfig([
169-
* 'Example' => ['registryAlias' => 'example'],
170-
* 'Posts' => ['registryAlias' => 'posts'],
171-
* ]);
172-
* ```
173-
*
174-
* @param string|array $alias The alias to set configuration for, or an array of configuration keyed by alias
175-
* @param null|array $config Array of configuration options
176-
* @return $this
177-
* @throws \RuntimeException
178-
*/
179-
public function setConfig($alias, $config = null)
180-
{
181-
if (!is_string($alias)) {
182-
$this->_config = $alias;
183-
184-
return $this;
185-
}
186-
187-
if (isset($this->_instances[$alias])) {
188-
throw new RuntimeException(sprintf(
189-
'You cannot configure "%s", it has already been constructed.',
190-
$alias
191-
));
192-
}
193-
194-
$this->_config[$alias] = $config;
195-
196-
return $this;
197-
}
198-
199-
/**
200-
* Clear the endpoint locator of all instances
201-
*
202-
* @return void
203-
*/
204-
public function clear(): void
205-
{
206-
$this->_instances = [];
207-
$this->_options = [];
208-
$this->_config = [];
209-
}
210-
211-
/**
212-
* Remove a specific endpoint instance from the locator by alias
213-
*
214-
* @param string $alias String alias of the endpoint
215-
* @return void
216-
*/
217-
public function remove($alias): void
218-
{
219-
unset(
220-
$this->_instances[$alias],
221-
$this->_options[$alias],
222-
$this->_config[$alias]
223-
);
224-
}
225-
226-
/**
227-
* Wrapper for creating endpoint instances
228-
*
229-
* @param array $options The alias to check for.
230-
* @return \Muffin\Webservice\Model\Endpoint
231-
*/
232-
protected function _create(array $options): Endpoint
233-
{
234-
/** @psalm-var class-string<\Muffin\Webservice\Model\Endpoint> $className */
235-
$className = $options['className'];
236-
237-
return new $className($options);
238-
}
239115
}

src/Plugin.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
namespace Muffin\Webservice;
55

66
use Cake\Core\BasePlugin;
7+
use Cake\Core\PluginApplicationInterface;
8+
use Cake\Datasource\FactoryLocator;
9+
use Muffin\Webservice\Model\EndpointLocator;
710

811
class Plugin extends BasePlugin
912
{
@@ -27,4 +30,12 @@ class Plugin extends BasePlugin
2730
* @var bool
2831
*/
2932
protected $consoleEnabled = false;
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
public function bootstrap(PluginApplicationInterface $app): void
38+
{
39+
FactoryLocator::add('Endpoint', new EndpointLocator());
40+
}
3041
}

tests/TestCase/BootstrapTest.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313

1414
class BootstrapTest extends TestCase
1515
{
16+
public function setUp(): void
17+
{
18+
$this->loadPlugins(['Muffin/Webservice']);
19+
}
20+
1621
/**
1722
* Test that the plugins bootstrap is correctly registering the Endpoint
1823
* repository type with the factory locator
@@ -38,7 +43,6 @@ public function testFactoryLocatorAddition()
3843
{
3944
$result = FactoryLocator::get('Endpoint');
4045

41-
$this->assertInstanceOf(EndpointLocator::class, $result[0]);
42-
$this->assertSame('get', $result[1]);
46+
$this->assertInstanceOf(EndpointLocator::class, $result);
4347
}
4448
}

tests/TestCase/Model/EndpointLocatorTest.php

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,45 +29,6 @@ public function tearDown(): void
2929
unset($this->Locator);
3030
}
3131

32-
public function testConfig()
33-
{
34-
$this->assertSame([], $this->Locator->getConfig());
35-
36-
$configTest = ['foo' => 'bar'];
37-
$this->Locator->setConfig('test', $configTest);
38-
$this->assertSame($configTest, $this->Locator->getConfig('test'));
39-
40-
$configExample = ['example' => true];
41-
$this->Locator->setConfig('example', $configExample);
42-
$this->assertSame($configExample, $this->Locator->getConfig('example'));
43-
}
44-
45-
public function testSetConfigForExistingObject()
46-
{
47-
$this->expectException(RuntimeException::class);
48-
$this->expectExceptionMessage('You cannot configure "Test", it has already been constructed.');
49-
50-
$this->Locator->get('Test', [
51-
'registryAlias' => 'Test',
52-
'connection' => 'test',
53-
]);
54-
55-
$this->Locator->setConfig('Test', ['foo' => 'bar']);
56-
}
57-
58-
public function testSetConfigUsingAliasArray()
59-
{
60-
$multiAliasConfig = [
61-
'Test' => ['foo' => 'bar'],
62-
'Example' => ['foo' => 'bar'],
63-
];
64-
65-
$result = $this->Locator->setConfig($multiAliasConfig);
66-
$this->assertInstanceOf(EndpointLocator::class, $result);
67-
68-
$this->assertSame($multiAliasConfig, $this->Locator->getConfig());
69-
}
70-
7132
public function testRemoveUsingExists()
7233
{
7334
/** @var \PHPUnit\Framework\MockObject\MockObject|\Muffin\Webservice\Model\Endpoint $first */
@@ -132,7 +93,7 @@ public function testGetException()
13293
public function testGetWithExistingObject()
13394
{
13495
$this->expectException(RuntimeException::class);
135-
$this->expectExceptionMessage('You cannot configure "First", it already exists in the locator.');
96+
$this->expectExceptionMessage('You cannot configure "First", it already exists in the registry.');
13697

13798
$result = $this->Locator->get('First', [
13899
'className' => Endpoint::class,

tests/bootstrap.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
use Cake\Cache\Cache;
1717
use Cake\Core\Configure;
18-
use Cake\Core\Plugin;
1918
use Cake\Datasource\ConnectionManager;
2019
use Cake\Log\Log;
2120
use Muffin\Webservice\Datasource\Connection;
@@ -104,6 +103,3 @@
104103
'file' => 'error',
105104
],
106105
]);
107-
108-
Plugin::getCollection()->add(new \Muffin\Webservice\Plugin());
109-
require Plugin::getCollection()->get('Muffin/Webservice')->getConfigPath() . 'bootstrap.php';

0 commit comments

Comments
 (0)