diff --git a/.editorconfig b/.editorconfig
index a84f86c..41e9eef 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -15,4 +15,7 @@ end_of_line = crlf
[*.yml]
indent_style = space
-indent_size = 2
\ No newline at end of file
+indent_size = 2
+
+[*.neon]
+indent_style = tab
diff --git a/.gitattributes b/.gitattributes
index 17493ec..b909522 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2,7 +2,8 @@
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
-.semver export-ignore
-phpunit.xml.dist export-ignore
.travis.yml export-ignore
tests export-ignore
+phpstan.neon export-ignore
+psalm.xml export-ignore
+.github export-ignore
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..6153d71
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,101 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - '*'
+
+jobs:
+ testsuite:
+ runs-on: ubuntu-18.04
+ strategy:
+ fail-fast: false
+ matrix:
+ php-version: ['7.2', '7.4', '8.0']
+ db-type: ['mysql', 'pgsql']
+ prefer-lowest: ['']
+ include:
+ - php-version: '7.2'
+ db-type: 'sqlite'
+ prefer-lowest: 'prefer-lowest'
+
+ services:
+ postgres:
+ image: postgres
+ ports:
+ - 5432:5432
+ env:
+ POSTGRES_PASSWORD: postgres
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Setup Service
+ if: matrix.db-type == 'mysql'
+ run: |
+ sudo service mysql start
+ mysql -h 127.0.0.1 -u root -proot -e 'CREATE DATABASE cakephp;'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+ extensions: mbstring, intl, pdo_${{ matrix.db-type }}
+ coverage: pcov
+
+ - name: Composer install
+ run: |
+ composer --version
+ if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then
+ composer update --prefer-lowest --prefer-stable
+ else
+ composer install
+ fi
+
+ - name: Run PHPUnit
+ run: |
+ if [[ ${{ matrix.db-type }} == 'sqlite' ]]; then export DB_URL='sqlite:///:memory:'; fi
+ if [[ ${{ matrix.db-type }} == 'mysql' ]]; then export DB_URL='mysql://root:root@127.0.0.1/cakephp'; fi
+ if [[ ${{ matrix.db-type }} == 'pgsql' ]]; then export DB_URL='postgres://postgres:postgres@127.0.0.1/postgres'; fi
+
+ if [[ ${{ matrix.php-version }} == '7.4' && ${{ matrix.db-type }} == 'mysql' ]]; then
+ vendor/bin/phpunit --coverage-clover=coverage.xml
+ else
+ vendor/bin/phpunit
+ fi
+
+ - name: Code Coverage Report
+ if: success() && matrix.php-version == '7.4' && matrix.db-type == 'mysql'
+ uses: codecov/codecov-action@v1
+
+ cs-stan:
+ name: Coding Standard & Static Analysis
+ runs-on: ubuntu-18.04
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '7.4'
+ extensions: mbstring, intl
+ coverage: none
+ tools: psalm:4.7, phpstan:0.12
+
+ - name: Composer Install
+ run: composer require cakephp/cakephp-codesniffer:^4.2
+
+ - name: Run phpcs
+ run: vendor/bin/phpcs --standard=CakePHP src/ tests/
+
+ - name: Run psalm
+ if: success() || failure()
+ run: psalm --output-format=github
+
+ - name: Run phpstan
+ if: success() || failure()
+ run: phpstan analyse
diff --git a/.gitignore b/.gitignore
index 364f9bd..654564b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/composer.lock
/plugins
/vendor
+.phpunit.result.cache
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6788a9c..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-language: php
-
-php:
- - 5.6
- - 7.4
-
-services:
- - postgresql
- - mysql
-
-env:
- global:
- - DEFAULT=1
- matrix:
- - DB=mysql DB_DSN='mysql://root@127.0.0.1/cakephp_test?init[]=SET sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"'
- - DB=pgsql DB_DSN='postgres://postgres@127.0.0.1/cakephp_test'
- - DB=sqlite DB_DSN='sqlite:///:memory:'
-
-matrix:
- fast_finish: true
-
- include:
- - php: 7.4
- env: PHPCS=1 DEFAULT=0
-
- - php: 7.1
- env: PHPSTAN=1 DEFAULT=0
-
- - php: 5.6
- env: PREFER_LOWEST=1
-
-before_install:
- - if [[ $DB == 'mysql' ]]; then mysql -u root -e 'CREATE DATABASE cakephp_test;'; fi
- - if [[ $DB == 'pgsql' ]]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi
-
-install:
- - if [[ $TRAVIS_PHP_VERSION != 7.4 ]]; then phpenv config-rm xdebug.ini; fi
-
- - if [[ $PHPSTAN != 1 ]]; then composer install --no-interaction; fi
- - |
- if [[ $PHPSTAN == 1 ]]; then
- composer require phpstan/phpstan:^0.12
- composer install --no-dev
- fi
-
-script:
- - if [[ $TRAVIS_PHP_VERSION == 7.4 ]]; then ./vendor/bin/phpunit --coverage-clover=clover.xml; fi
- - if [[ $DEFAULT == 1 ]]; then ./vendor/bin/phpunit; fi
-
- - if [[ $PHPCS == 1 ]]; then ./vendor/bin/phpcs -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests; fi
-
- - if [[ $PHPSTAN == 1 ]]; then vendor/bin/phpstan analyse src; fi
-
-after_success:
-- if [[ $TRAVIS_PHP_VERSION == 7.4 ]]; then bash <(curl -s https://codecov.io/bash); fi
-
-notifications:
- email: false
diff --git a/README.md b/README.md
index 508182a..43cb8c3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Webservice
-[](https://travis-ci.org/UseMuffin/Webservice)
+[](https://github.com/UseMuffin/Webservice/actions?query=workflow%3ACI+branch%3Amaster)
[](https://codecov.io/github/UseMuffin/Webservice)
[](https://packagist.org/packages/muffin/webservice)
[](LICENSE)
@@ -23,6 +23,24 @@ bin/cake plugin load Muffin/Webservice
## Usage
+### Datasource Configuration
+
+In your `app.php`, add a new `webservice` config under `Datasources`:
+
+```php
+ 'Datasources' => [
+ // Other db config here
+ 'webservice' => [
+ 'className' => \Muffin\Webservice\Connection::class,
+ 'service' => 'Articles',
+ // Any additional keys will be set as Driver's config.
+ ],
+ ],
+```
+
+If you are making a plugin then conventionally the datasource config key name
+should be underscored version of plugin name.
+
### As an ORM
#### Create driver
@@ -31,15 +49,15 @@ bin/cake plugin load Muffin/Webservice
setClient(new Client([
'host' => 'example.com'
@@ -54,8 +72,8 @@ class Articles extends AbstractDriver
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Connection.php b/src/Connection.php
deleted file mode 100644
index 601597b..0000000
--- a/src/Connection.php
+++ /dev/null
@@ -1,78 +0,0 @@
-_normalizeConfig($config);
- $driver = $config['driver'];
- unset($config['driver'], $config['service']);
-
- $this->_driver = new $driver($config);
-
- if (!($this->_driver instanceof AbstractDriver)) {
- throw new UnexpectedDriverException(['driver' => $driver]);
- }
- }
-
- /**
- * Validates certain custom configuration values.
- *
- * @param array $config Raw custom configuration.
- * @return array
- * @throws \Muffin\Webservice\Exception\MissingConnectionException If the connection does not exist.
- * @throws \Muffin\Webservice\Exception\MissingDriverException If the driver does not exist.
- */
- protected function _normalizeConfig($config)
- {
- if (empty($config['driver'])) {
- if (empty($config['service'])) {
- throw new MissingConnectionException(['name' => $config['name']]);
- }
-
- if (!$config['driver'] = App::className($config['service'], 'Webservice/Driver')) {
- throw new MissingDriverException(['driver' => $config['driver']]);
- }
- }
-
- return $config;
- }
-
- /**
- * Proxies the driver's methods.
- *
- * @param string $method Method name.
- * @param array $args Arguments to pass-through
- * @return mixed
- */
- public function __call($method, $args)
- {
- return call_user_func_array([$this->_driver, $method], $args);
- }
-}
diff --git a/src/Datasource/Connection.php b/src/Datasource/Connection.php
new file mode 100644
index 0000000..f31bc3c
--- /dev/null
+++ b/src/Datasource/Connection.php
@@ -0,0 +1,84 @@
+_normalizeConfig($config);
+ /** @psalm-var class-string<\Muffin\Webservice\Webservice\Driver\AbstractDriver> */
+ $driver = $config['driver'];
+ unset($config['driver'], $config['service']);
+
+ $this->_driver = new $driver($config);
+
+ /** @psalm-suppress TypeDoesNotContainType */
+ if (!($this->_driver instanceof AbstractDriver)) {
+ throw new UnexpectedDriverException(['driver' => $driver]);
+ }
+ }
+
+ /**
+ * Validates certain custom configuration values.
+ *
+ * @param array $config Raw custom configuration.
+ * @return array
+ * @throws \Muffin\Webservice\Datasource\Exception\MissingConnectionException If the connection does not exist.
+ * @throws \Muffin\Webservice\Webservice\Exception\MissingDriverException If the driver does not exist.
+ */
+ protected function _normalizeConfig(array $config): array
+ {
+ if (empty($config['driver'])) {
+ if (empty($config['service'])) {
+ throw new MissingConnectionException(['name' => $config['name']]);
+ }
+
+ $config['driver'] = App::className($config['service'], 'Webservice/Driver');
+ if (!$config['driver']) {
+ throw new MissingDriverException(['driver' => $config['driver']]);
+ }
+ }
+
+ return $config;
+ }
+
+ /**
+ * Proxies the driver's methods.
+ *
+ * @param string $method Method name.
+ * @param array $args Arguments to pass-through
+ * @return mixed
+ */
+ public function __call($method, $args)
+ {
+ return call_user_func_array([$this->_driver, $method], $args);
+ }
+}
diff --git a/src/Datasource/Exception/MissingConnectionException.php b/src/Datasource/Exception/MissingConnectionException.php
new file mode 100644
index 0000000..ace3e6e
--- /dev/null
+++ b/src/Datasource/Exception/MissingConnectionException.php
@@ -0,0 +1,16 @@
+_prepareDataAndOptions($data, $options);
+ [$data, $options] = $this->_prepareDataAndOptions($data, $options);
$primaryKey = (array)$this->_endpoint->getPrimaryKey();
+ /** @psalm-var class-string<\Muffin\Webservice\Model\Resource> */
$resourceClass = $this->_endpoint->getResourceClass();
- /* @var \Muffin\Webservice\Model\Resource $entity */
$entity = new $resourceClass();
$entity->setSource($this->_endpoint->getRegistryAlias());
@@ -104,7 +105,7 @@ public function one(array $data, array $options = [])
* @return array The list of validation errors.
* @throws \RuntimeException If no validator can be created.
*/
- protected function _validate($data, $options, $isNew)
+ protected function _validate(array $data, array $options, bool $isNew): array
{
if (!$options['validate']) {
return [];
@@ -116,6 +117,7 @@ protected function _validate($data, $options, $isNew)
} elseif (is_string($options['validate'])) {
$validator = $this->_endpoint->getValidator($options['validate']);
} else {
+ /** @var \Cake\Validation\Validator $validator */
$validator = $options['validator'];
}
@@ -126,7 +128,7 @@ protected function _validate($data, $options, $isNew)
));
}
- return $validator->errors($data, $isNew);
+ return $validator->validate($data, $isNew);
}
/**
@@ -136,7 +138,7 @@ protected function _validate($data, $options, $isNew)
* @param array $options The options passed to this marshaller.
* @return array An array containing prepared data and options.
*/
- protected function _prepareDataAndOptions($data, $options)
+ protected function _prepareDataAndOptions(array $data, array $options): array
{
$options += ['validate' => true];
@@ -163,10 +165,10 @@ protected function _prepareDataAndOptions($data, $options)
*
* @param array $data The data to hydrate.
* @param array $options List of options
- * @return array An array of hydrated records.
+ * @return \Cake\Datasource\EntityInterface[] An array of hydrated records.
* @see \Muffin\Webservice\Model\Endpoint::newEntities()
*/
- public function many(array $data, array $options = [])
+ public function many(array $data, array $options = []): array
{
$output = [];
foreach ($data as $record) {
@@ -196,9 +198,9 @@ public function many(array $data, array $options = [])
* @param array $options List of options.
* @return \Cake\Datasource\EntityInterface
*/
- public function merge(EntityInterface $entity, array $data, array $options = [])
+ public function merge(EntityInterface $entity, array $data, array $options = []): EntityInterface
{
- list($data, $options) = $this->_prepareDataAndOptions($data, $options);
+ [$data, $options] = $this->_prepareDataAndOptions($data, $options);
$isNew = $entity->isNew();
$keys = [];
@@ -262,9 +264,9 @@ public function merge(EntityInterface $entity, array $data, array $options = [])
* data merged in
* @param array $data list of arrays to be merged into the entities
* @param array $options List of options.
- * @return array
+ * @return \Cake\Datasource\EntityInterface[]
*/
- public function mergeMany($entities, array $data, array $options = [])
+ public function mergeMany($entities, array $data, array $options = []): array
{
$primary = (array)$this->_endpoint->getPrimaryKey();
@@ -272,7 +274,7 @@ public function mergeMany($entities, array $data, array $options = [])
->groupBy(function ($el) use ($primary) {
$keys = [];
foreach ($primary as $key) {
- $keys[] = isset($el[$key]) ? $el[$key] : '';
+ $keys[] = $el[$key] ?? '';
}
return implode(';', $keys);
@@ -282,7 +284,9 @@ public function mergeMany($entities, array $data, array $options = [])
})
->toArray();
- $new = isset($indexed[null]) ? $indexed[null] : [];
+ /** @psalm-suppress NullArrayOffset, InvalidArrayOffset */
+ $new = $indexed[null] ?? [];
+ /** @psalm-suppress PossiblyNullArrayOffset, InvalidArrayOffset */
unset($indexed[null]);
$output = [];
@@ -292,7 +296,7 @@ public function mergeMany($entities, array $data, array $options = [])
}
$key = implode(';', $entity->extract($primary));
- if ($key === null || !isset($indexed[$key])) {
+ if ($key === '' || !isset($indexed[$key])) {
continue;
}
diff --git a/src/Query.php b/src/Datasource/Query.php
similarity index 71%
rename from src/Query.php
rename to src/Datasource/Query.php
index 3d00505..d8a8814 100644
--- a/src/Query.php
+++ b/src/Datasource/Query.php
@@ -1,12 +1,15 @@
webservice($webservice);
- $this->endpoint($endpoint);
+ $this->setWebservice($webservice);
+ $this->setEndpoint($endpoint);
}
/**
@@ -155,7 +158,7 @@ public function delete()
* @param string $name name of the clause to be returned
* @return mixed
*/
- public function clause($name)
+ public function clause(string $name)
{
if (isset($this->_parts[$name])) {
return $this->_parts[$name];
@@ -167,37 +170,52 @@ public function clause($name)
/**
* Set the endpoint to be used
*
- * @param \Muffin\Webservice\Model\Endpoint|null $endpoint The endpoint to use
- * @return \Muffin\Webservice\Model\Endpoint|$this
+ * @param \Muffin\Webservice\Model\Endpoint $endpoint The endpoint to use
+ * @return $this
+ * @psalm-suppress LessSpecificReturnStatement
*/
- public function endpoint(Endpoint $endpoint = null)
+ public function setEndpoint(Endpoint $endpoint)
{
- if ($endpoint === null) {
- return $this->getRepository();
- }
-
$this->repository($endpoint);
return $this;
}
/**
- * Set the webservice to be used
+ * Set the endpoint to be used
*
- * @param null|\Muffin\Webservice\Webservice\WebserviceInterface $webservice The webservice to use
- * @return \Muffin\Webservice\Webservice\WebserviceInterface|self
+ * @return \Muffin\Webservice\Model\Endpoint
+ * @psalm-suppress MoreSpecificReturnType
*/
- public function webservice(WebserviceInterface $webservice = null)
+ public function getEndpoint(): Endpoint
{
- if ($webservice === null) {
- return $this->_webservice;
- }
+ /** @var \Muffin\Webservice\Model\Endpoint */
+ return $this->getRepository();
+ }
+ /**
+ * Set the webservice to be used
+ *
+ * @param \Muffin\Webservice\Webservice\WebserviceInterface $webservice The webservice to use
+ * @return $this
+ */
+ public function setWebservice(WebserviceInterface $webservice)
+ {
$this->_webservice = $webservice;
return $this;
}
+ /**
+ * Get the webservice used
+ *
+ * @return \Muffin\Webservice\Webservice\WebserviceInterface
+ */
+ public function getWebservice()
+ {
+ return $this->_webservice;
+ }
+
/**
* Apply custom finds to against an existing query object.
*
@@ -216,6 +234,7 @@ public function webservice(WebserviceInterface $webservice = null)
*/
public function find($finder, array $options = [])
{
+ /** @psalm-suppress UndefinedInterfaceMethod */
return $this->getRepository()->callFinder($finder, $this, $options);
}
@@ -231,6 +250,7 @@ public function firstOrFail()
if ($entity) {
return $entity;
}
+ /** @psalm-suppress UndefinedInterfaceMethod */
throw new RecordNotFoundException(sprintf(
'Record not found in endpoint "%s"',
$this->getRepository()->getName()
@@ -241,10 +261,10 @@ public function firstOrFail()
* Alias a field with the endpoint's current alias.
*
* @param string $field The field to alias.
- * @param null $alias Not being used
+ * @param string|null $alias Not being used
* @return array The field prefixed with the endpoint alias.
*/
- public function aliasField($field, $alias = null)
+ public function aliasField(string $field, ?string $alias = null): array
{
return [$field => $field];
}
@@ -253,17 +273,18 @@ public function aliasField($field, $alias = null)
* Apply conditions to the query
*
* @param array|null $conditions The conditions to apply
- * @param array|null $types Not used
+ * @param array $types Not used
* @param bool $overwrite Whether to overwrite the current conditions
- * @return $this|array
+ * @return $this
+ * @psalm-suppress MoreSpecificImplementedParamType
*/
- public function where($conditions = null, $types = [], $overwrite = false)
+ public function where($conditions = null, array $types = [], bool $overwrite = false)
{
if ($conditions === null) {
return $this->clause('where');
}
- $this->_parts['where'] = (!$overwrite) ? Hash::merge($this->clause('where'), $conditions) : $conditions;
+ $this->_parts['where'] = !$overwrite ? Hash::merge($this->clause('where'), $conditions) : $conditions;
return $this;
}
@@ -271,13 +292,14 @@ public function where($conditions = null, $types = [], $overwrite = false)
/**
* Add AND conditions to the query
*
- * @param string|array|\Cake\Database\ExpressionInterface|callable $conditions The conditions to add with AND.
+ * @param string|array $conditions The conditions to add with AND.
* @param array $types associative array of type names used to bind values to query
+ * @return $this
* @see \Cake\Database\Query::where()
* @see \Cake\Database\Type
- * @return $this
+ * @psalm-suppress PossiblyInvalidArgument
*/
- public function andWhere($conditions, $types = [])
+ public function andWhere($conditions, array $types = [])
{
$this->where($conditions, $types);
@@ -287,15 +309,11 @@ public function andWhere($conditions, $types = [])
/**
* Charge this query's action
*
- * @param int|null $action Action to use
- * @return $this|int
+ * @param int $action Action to use
+ * @return $this
*/
- public function action($action = null)
+ public function action(int $action)
{
- if ($action === null) {
- return $this->clause('action');
- }
-
$this->_parts['action'] = $action;
return $this;
@@ -310,21 +328,22 @@ public function action($action = null)
*
* Pages should start at 1.
*
- * @param int $page The page number you want.
+ * @param int $num The page number you want.
* @param int $limit The number of rows you want in the page. If null
* the current limit clause will be used.
* @return $this
*/
- public function page($page = null, $limit = null)
+ public function page(int $num, ?int $limit = null)
{
- if ($page === null) {
- return $this->clause('page');
+ if ($num < 1) {
+ throw new InvalidArgumentException('Pages must start at 1.');
}
+
if ($limit !== null) {
$this->limit($limit);
}
- $this->_parts['page'] = $page;
+ $this->_parts['page'] = $num;
return $this;
}
@@ -343,13 +362,11 @@ public function page($page = null, $limit = null)
*
* @param int $limit number of records to be returned
* @return $this
+ * @psalm-suppress MoreSpecificImplementedParamType
+ * @psalm-suppress ParamNameMismatch
*/
- public function limit($limit = null)
+ public function limit($limit)
{
- if ($limit === null) {
- return $this->clause('limit');
- }
-
$this->_parts['limit'] = $limit;
return $this;
@@ -367,7 +384,7 @@ public function set($fields = null)
return $this->clause('set');
}
- if (!in_array($this->action(), [self::ACTION_CREATE, self::ACTION_UPDATE])) {
+ if (!in_array($this->clause('action'), [self::ACTION_CREATE, self::ACTION_UPDATE])) {
throw new \UnexpectedValueException(__('The action of this query needs to be either create update'));
}
@@ -377,7 +394,7 @@ public function set($fields = null)
}
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
public function offset($num)
{
@@ -399,13 +416,13 @@ public function offset($num)
* By default this function will append any passed argument to the list of fields
* to be selected, unless the second argument is set to true.
*
- * @param array|string $fields fields to be added to the list
+ * @param array|\Cake\Database\ExpressionInterface|\Closure|string $fields fields to be added to the list
* @param bool $overwrite whether to reset order with field list or not
* @return $this
*/
public function order($fields, $overwrite = false)
{
- $this->_parts['order'] = (!$overwrite) ? Hash::merge($this->clause('order'), $fields) : $fields;
+ $this->_parts['order'] = !$overwrite ? Hash::merge($this->clause('order'), $fields) : $fields;
return $this;
}
@@ -450,18 +467,19 @@ public function applyOptions(array $options)
*
* @return int
*/
- public function count()
+ public function count(): int
{
- if ($this->action() !== self::ACTION_READ) {
+ if ($this->clause('action') !== self::ACTION_READ) {
return 0;
}
- if (!$this->__resultSet) {
+ if (!$this->_result) {
$this->_execute();
}
- if ($this->__resultSet) {
- return $this->__resultSet->total();
+ if ($this->_result) {
+ /** @psalm-suppress PossiblyInvalidMethodCall, PossiblyUndefinedMethod */
+ return (int)$this->_result->total();
}
return 0;
@@ -477,11 +495,11 @@ public function count()
* $singleUser = $query->first();
* ```
*
- * @return mixed the first result from the ResultSet
+ * @return \Cake\Datasource\EntityInterface|array|null the first result from the ResultSet
*/
public function first()
{
- if (!$this->__resultSet) {
+ if (!$this->_result) {
$this->limit(1);
}
@@ -497,7 +515,8 @@ public function first()
*/
public function triggerBeforeFind()
{
- if (!$this->_beforeFindFired && $this->action() === self::ACTION_READ) {
+ if (!$this->_beforeFindFired && $this->clause('action') === self::ACTION_READ) {
+ /** @var \Muffin\Webservice\Model\Endpoint $endpoint */
$endpoint = $this->getRepository();
$this->_beforeFindFired = true;
$endpoint->dispatchEvent('Model.beforeFind', [
@@ -511,28 +530,36 @@ public function triggerBeforeFind()
/**
* Execute the query
*
- * @return \Traversable
+ * @return bool|int|\Muffin\Webservice\Model\Resource|\Muffin\Webservice\Datasource\ResultSet
+ * @psalm-suppress MoreSpecificReturnType
*/
public function execute()
{
- return $this->_execute();
+ if ($this->clause('action') === self::ACTION_READ) {
+ /** @psalm-suppress LessSpecificReturnStatement */
+ return $this->_execute();
+ }
+
+ return $this->_result = $this->_webservice->execute($this);
}
/**
* Executes this query and returns a traversable object containing the results
*
- * @return \Traversable
+ * @return \Cake\Datasource\ResultSetInterface
*/
- protected function _execute()
+ protected function _execute(): ResultSetInterface
{
$this->triggerBeforeFind();
- if ($this->__resultSet) {
+ if ($this->_result) {
+ /** @psalm-var class-string<\Cake\Datasource\ResultSetInterface> $decorator */
$decorator = $this->_decoratorClass();
- return new $decorator($this->__resultSet);
+ return new $decorator($this->_result);
}
- return $this->__resultSet = $this->_webservice->execute($this);
+ /** @var \Cake\Datasource\ResultSetInterface */
+ return $this->_result = $this->_webservice->execute($this);
}
/**
@@ -544,17 +571,17 @@ public function __debugInfo()
{
return [
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
- 'action' => $this->action(),
+ 'action' => $this->clause('action'),
'formatters' => $this->_formatters,
'offset' => $this->clause('offset'),
- 'page' => $this->page(),
- 'limit' => $this->limit(),
+ 'page' => $this->clause('page'),
+ 'limit' => $this->clause('limit'),
'set' => $this->set(),
'sort' => $this->clause('order'),
'extraOptions' => $this->getOptions(),
'conditions' => $this->where(),
- 'repository' => $this->endpoint(),
- 'webservice' => $this->webservice(),
+ 'repository' => $this->getEndpoint(),
+ 'webservice' => $this->getWebservice(),
];
}
@@ -577,8 +604,9 @@ public function jsonSerialize()
* @param bool $overwrite whether to reset fields with passed list or not
* @return $this
* @see \Cake\Database\Query::select
+ * @psalm-suppress MoreSpecificImplementedParamType
*/
- public function select($fields = [], $overwrite = false)
+ public function select($fields = [], bool $overwrite = false)
{
if (!is_string($fields) && is_callable($fields)) {
$fields = $fields($this);
diff --git a/src/ResultSet.php b/src/Datasource/ResultSet.php
similarity index 93%
rename from src/ResultSet.php
rename to src/Datasource/ResultSet.php
index 021bc5d..124cf1b 100644
--- a/src/ResultSet.php
+++ b/src/Datasource/ResultSet.php
@@ -1,6 +1,7 @@
_results = array_values($resources);
$this->_total = $total;
@@ -152,7 +153,7 @@ public function unserialize($serialized)
*
* @return int
*/
- public function count()
+ public function count(): int
{
return count($this->_results);
}
@@ -162,7 +163,7 @@ public function count()
*
* @return int|null
*/
- public function total()
+ public function total(): ?int
{
return $this->_total;
}
diff --git a/src/Schema.php b/src/Datasource/Schema.php
similarity index 80%
rename from src/Schema.php
rename to src/Datasource/Schema.php
index 8499d47..062f928 100644
--- a/src/Schema.php
+++ b/src/Datasource/Schema.php
@@ -1,8 +1,10 @@
_repository = $endpoint;
foreach ($columns as $field => $definition) {
@@ -124,7 +125,7 @@ public function __construct($endpoint, array $columns = [])
*
* @return string
*/
- public function name()
+ public function name(): string
{
return $this->_repository;
}
@@ -158,7 +159,7 @@ public function name()
* @param array|string $attrs The attributes for the column.
* @return $this
*/
- public function addColumn($name, $attrs)
+ public function addColumn(string $name, $attrs)
{
if (is_string($attrs)) {
$attrs = ['type' => $attrs];
@@ -177,9 +178,9 @@ public function addColumn($name, $attrs)
/**
* Get the column names in the endpoint.
*
- * @return array
+ * @return string[]
*/
- public function columns()
+ public function columns(): array
{
return array_keys($this->_columns);
}
@@ -190,7 +191,7 @@ public function columns()
* @param string $name The column name.
* @return array|null Column data or null.
*/
- public function column($name)
+ public function getColumn(string $name): ?array
{
if (!isset($this->_columns[$name])) {
return null;
@@ -202,24 +203,29 @@ public function column($name)
}
/**
- * Sets the type of a column, or returns its current type
- * if none is passed.
+ * Check if schema has column
*
- * @param string $name The column to get the type of.
- * @param string $type The type to set the column to.
- * @return string|null Either the column type or null.
- * @deprecated 2.0.0 Please use setColumnType or getColumnType instead.
+ * @param string $name The column name.
+ * @return bool
*/
- public function columnType($name, $type = null)
+ public function hasColumn(string $name): bool
{
- if (!isset($this->_columns[$name])) {
- return null;
- }
- if ($type !== null) {
- $this->setColumnType($name, $type);
- }
+ return isset($this->_columns[$name]);
+ }
- return $this->getColumnType($name);
+ /**
+ * Remove a column from the table schema.
+ *
+ * If the column is not defined in the table, no error will be raised.
+ *
+ * @param string $name The name of the column
+ * @return $this
+ */
+ public function removeColumn(string $name)
+ {
+ unset($this->_columns[$name], $this->_typeMap[$name]);
+
+ return $this;
}
/**
@@ -229,7 +235,7 @@ public function columnType($name, $type = null)
* @param string $type Type to set for the column
* @return $this
*/
- public function setColumnType($name, $type)
+ public function setColumnType(string $name, string $type)
{
$this->_columns[$name]['type'] = $type;
$this->_typeMap[$name] = $type;
@@ -243,7 +249,7 @@ public function setColumnType($name, $type)
* @param string $name Column name
* @return null|string
*/
- public function getColumnType($name)
+ public function getColumnType(string $name): ?string
{
if (!isset($this->_columns[$name])) {
return null;
@@ -260,7 +266,7 @@ public function getColumnType($name)
* @param string $column The column name to get the base type from
* @return string|null The base type name
*/
- public function baseColumnType($column)
+ public function baseColumnType(string $column): ?string
{
if (isset($this->_columns[$column]['baseType'])) {
return $this->_columns[$column]['baseType'];
@@ -272,8 +278,8 @@ public function baseColumnType($column)
return null;
}
- if (Type::getMap($type)) {
- $type = Type::build($type)->getBaseType();
+ if (TypeFactory::getMap($type)) {
+ $type = TypeFactory::build($type)->getBaseType();
}
return $this->_columns[$column]['baseType'] = $type;
@@ -285,7 +291,7 @@ public function baseColumnType($column)
*
* @return array
*/
- public function typeMap()
+ public function typeMap(): array
{
return $this->_typeMap;
}
@@ -298,13 +304,13 @@ public function typeMap()
* @param string $name The column to get the type of.
* @return bool Whether or not the field is nullable.
*/
- public function isNullable($name)
+ public function isNullable(string $name): bool
{
if (!isset($this->_columns[$name])) {
return true;
}
- return ($this->_columns[$name]['null'] === true);
+ return $this->_columns[$name]['null'] === true;
}
/**
@@ -312,7 +318,7 @@ public function isNullable($name)
*
* @return array
*/
- public function defaultValues()
+ public function defaultValues(): array
{
$defaults = [];
foreach ($this->_columns as $name => $data) {
@@ -334,7 +340,7 @@ public function defaultValues()
* @return array Column name(s) for the primary key. An
* empty list will be returned when the endpoint has no primary key.
*/
- public function primaryKey()
+ public function getPrimaryKey(): array
{
$primaryKeys = [];
foreach ($this->_columns as $name => $data) {
@@ -348,26 +354,6 @@ public function primaryKey()
return $primaryKeys;
}
- /**
- * Get/set the options for a endpoint.
- *
- * Endpoint options allow you to set platform specific endpoint level options.
- *
- * @param array|null $options The options to set, or null to read options.
- * @return $this|array Either the endpoint instance, or an array of options when reading.
- * @deprecated 2.0.0 Please use setOptions and getOptions instead.
- */
- public function options($options = null)
- {
- if ($options === null) {
- return $this->getOptions();
- }
-
- $this->setOptions($options);
-
- return $this;
- }
-
/**
* Set the schema options for an endpoint
*
@@ -386,7 +372,7 @@ public function setOptions(array $options)
*
* @return array
*/
- public function getOptions()
+ public function getOptions(): array
{
return $this->_options;
}
diff --git a/src/Driver/empty b/src/Driver/empty
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Exception/MissingConnectionException.php b/src/Exception/MissingConnectionException.php
deleted file mode 100644
index 2a3bd32..0000000
--- a/src/Exception/MissingConnectionException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-
*/
protected $_resourceClass;
@@ -84,14 +88,14 @@ class Endpoint implements RepositoryInterface, EventListenerInterface, EventDisp
/**
* The name of the field that represents the primary key in the endpoint
*
- * @var string|array
+ * @var string|array|null
*/
protected $_primaryKey;
/**
* The name of the field that represents a human readable representation of a row
*
- * @var string
+ * @var string|string[]
*/
protected $_displayField;
@@ -181,15 +185,18 @@ public function __construct(array $config = [])
* instance is created through the EndpointRegistry without a connection.
*
* @return string
- *
* @see \Muffin\Webservice\Model\EndpointRegistry::get()
*/
- public static function defaultConnectionName()
+ public static function defaultConnectionName(): string
{
- $namespaceParts = explode('\\', get_called_class());
- $plugin = array_slice(array_reverse($namespaceParts), 3, 2);
+ $namespaceParts = explode('\\', static::class);
+ $plugin = current(array_slice(array_reverse($namespaceParts), 3, 2));
- return Inflector::underscore(current($plugin));
+ if ($plugin === 'App') {
+ return 'webservice';
+ }
+
+ return Inflector::underscore($plugin);
}
/**
@@ -207,36 +214,20 @@ public static function defaultConnectionName()
* @param array $config Configuration options passed to the constructor
* @return void
*/
- public function initialize(array $config)
+ public function initialize(array $config): void
{
}
- /**
- * Returns the endpoint name or sets a new one
- *
- * @param string|null $endpoint the new endpoint name
- * @return string
- * @deprecated 2.0.0 use setName() and getName() instead.
- */
- public function endpoint($endpoint = null)
- {
- if ($endpoint !== null) {
- $this->setName($endpoint);
- }
-
- return $this->getName();
- }
-
/**
* Set the name of this endpoint
*
* @param string $name The name for this endpoint instance
* @return $this
*/
- public function setName($name)
+ public function setName(string $name)
{
$inflectMethod = $this->getInflectionMethod();
- $this->_name = Inflector::$inflectMethod($name);
+ $this->_name = Inflector::{$inflectMethod}($name);
return $this;
}
@@ -246,69 +237,37 @@ public function setName($name)
*
* @return string
*/
- public function getName()
+ public function getName(): string
{
if ($this->_name === null) {
- $endpoint = namespaceSplit(get_class($this));
+ $endpoint = namespaceSplit(static::class);
$endpoint = substr(end($endpoint), 0, -8);
$inflectMethod = $this->getInflectionMethod();
- $this->_name = Inflector::$inflectMethod($endpoint);
+ $this->_name = Inflector::{$inflectMethod}($endpoint);
}
return $this->_name;
}
- /**
- * Returns the endpoint alias or sets a new one
- *
- * @param string|null $alias the new endpoint alias
- * @return string
- * @deprecated 2.0.0 Use getAlias and setAlias instead
- */
- public function alias($alias = null)
- {
- if ($alias !== null) {
- $this->setAlias($alias);
- }
-
- return $this->getAlias();
- }
-
/**
* Alias a field with the endpoint's current alias.
*
* @param string $field The field to alias.
* @return string The field prefixed with the endpoint alias.
*/
- public function aliasField($field)
+ public function aliasField(string $field): string
{
return $this->getAlias() . '.' . $field;
}
- /**
- * Returns the endpoint registry key used to create this endpoint instance
- *
- * @param string|null $registryAlias the key used to access this object
- * @return string
- * @deprecated 2.0.0 Use setRegistryAlias()/getRegistryAlias() instead.
- */
- public function registryAlias($registryAlias = null)
- {
- if ($registryAlias !== null) {
- $this->setRegistryAlias($registryAlias);
- }
-
- return $this->getRegistryAlias();
- }
-
/**
* Sets the table registry key used to create this table instance.
*
* @param string $registryAlias The key used to access this object.
* @return $this
*/
- public function setRegistryAlias($registryAlias)
+ public function setRegistryAlias(string $registryAlias)
{
$this->_registryAlias = $registryAlias;
@@ -320,7 +279,7 @@ public function setRegistryAlias($registryAlias)
*
* @return string
*/
- public function getRegistryAlias()
+ public function getRegistryAlias(): string
{
if ($this->_registryAlias === null) {
$this->_registryAlias = $this->getAlias();
@@ -329,29 +288,13 @@ public function getRegistryAlias()
return $this->_registryAlias;
}
- /**
- * Set the driver to use
- *
- * @param \Muffin\Webservice\AbstractDriver|null $connection The driver to use
- * @return \Muffin\Webservice\AbstractDriver|\Muffin\Webservice\Connection
- * @deprecated 2.0.0 Use setConnection() and getConnection() instead.
- */
- public function connection($connection = null)
- {
- if ($connection !== null) {
- $this->setConnection($connection);
- }
-
- return $this->getConnection();
- }
-
/**
* Sets the connection driver.
*
- * @param \Muffin\Webservice\Connection $connection Connection instance
+ * @param \Muffin\Webservice\Datasource\Connection $connection Connection instance
* @return $this
*/
- public function setConnection($connection)
+ public function setConnection(Connection $connection)
{
$this->_connection = $connection;
@@ -361,37 +304,13 @@ public function setConnection($connection)
/**
* Returns the connection driver.
*
- * @return \Muffin\Webservice\Connection|null
+ * @return \Muffin\Webservice\Datasource\Connection
*/
- public function getConnection()
+ public function getConnection(): Connection
{
return $this->_connection;
}
- /**
- * Returns the schema endpoint object describing this endpoint's properties.
- *
- * If an \Muffin\Webservice\Schema is passed, it will be used for this endpoint
- * instead of the default one.
- *
- * If an array is passed, a new \Muffin\Webservice\Schema will be constructed
- * out of it and used as the schema for this endpoint.
- *
- * @param array|\Muffin\Webservice\Schema|null $schema New schema to be used for this endpoint
- * @return \Muffin\Webservice\Schema
- * @deprecated 2.0.0 Use setSchema() and getSchema() instead
- */
- public function schema($schema = null)
- {
- if ($schema === null) {
- return $this->getSchema();
- }
-
- $this->setSchema($schema);
-
- return $this->getSchema();
- }
-
/**
* Set the endpoints schema
*
@@ -401,7 +320,7 @@ public function schema($schema = null)
* If an array is passed, a new \Muffin\Webservice\Schema will be constructed
* out of it and used as the schema for this endpoint.
*
- * @param \Muffin\Webservice\Schema|array $schema Either an array of fields and config, or a schema object
+ * @param \Muffin\Webservice\Datasource\Schema|array $schema Either an array of fields and config, or a schema object
* @return $this
*/
public function setSchema($schema)
@@ -418,9 +337,9 @@ public function setSchema($schema)
/**
* Returns the schema endpoint object describing this endpoint's properties.
*
- * @return \Muffin\Webservice\Schema
+ * @return \Muffin\Webservice\Datasource\Schema
*/
- public function getSchema()
+ public function getSchema(): Schema
{
if ($this->_schema === null) {
$this->_schema = $this->_initializeSchema($this->getWebservice()->describe($this->getName()));
@@ -447,11 +366,11 @@ public function getSchema()
* }
* ```
*
- * @param \Muffin\Webservice\Schema $schema The schema definition fetched from webservice.
- * @return \Muffin\Webservice\Schema the altered schema
+ * @param \Muffin\Webservice\Datasource\Schema $schema The schema definition fetched from webservice.
+ * @return \Muffin\Webservice\Datasource\Schema the altered schema
* @api
*/
- protected function _initializeSchema(Schema $schema)
+ protected function _initializeSchema(Schema $schema): Schema
{
return $schema;
}
@@ -465,27 +384,11 @@ protected function _initializeSchema(Schema $schema)
* @param string $field The field to check for.
* @return bool True if the field exists, false if it does not.
*/
- public function hasField($field)
+ public function hasField(string $field): bool
{
$schema = $this->getSchema();
- return $schema->column($field) !== null;
- }
-
- /**
- * Returns the primary key field name or sets a new one
- *
- * @param string|array|null $key sets a new name to be used as primary key
- * @return string|array
- * @deprecated 2.0.0 Use getPrimaryKey() and setPrimaryKey() instead
- */
- public function primaryKey($key = null)
- {
- if ($key !== null) {
- $this->setPrimaryKey($key);
- }
-
- return $this->getPrimaryKey();
+ return $schema->getColumn($field) !== null;
}
/**
@@ -505,16 +408,13 @@ public function setPrimaryKey($key)
* Get the endpoints primary key, if one is not set, fetch it from the schema
*
* @return array|string
- * @throws \Muffin\Webservice\Exception\UnexpectedDriverException When no schema exists to fetch the key from
+ * @throws \Muffin\Webservice\Webservice\Exception\UnexpectedDriverException When no schema exists to fetch the key from
*/
public function getPrimaryKey()
{
if ($this->_primaryKey === null) {
$schema = $this->getSchema();
- if (!$schema) {
- throw new UnexpectedDriverException(__('No schema has been defined for this endpoint'));
- }
- $key = (array)$schema->primaryKey();
+ $key = $schema->getPrimaryKey();
if (count($key) === 1) {
$key = $key[0];
}
@@ -524,26 +424,10 @@ public function getPrimaryKey()
return $this->_primaryKey;
}
- /**
- * Returns the display field or sets a new one
- *
- * @param string|null $key sets a new name to be used as display field
- * @return string
- * @deprecated 2.0.0 Use setDisplayField and getDisplayField instead.
- */
- public function displayField($key = null)
- {
- if ($key !== null) {
- $this->setDisplayField($key);
- }
-
- return $this->getDisplayField();
- }
-
/**
* Sets the endpoint display field
*
- * @param string $field The new field to use as the display field
+ * @param string|string[] $field The new field to use as the display field
* @return $this
*/
public function setDisplayField($field)
@@ -556,8 +440,8 @@ public function setDisplayField($field)
/**
* Get the endpoints current display field
*
- * @return string
- * @throws \Muffin\Webservice\Exception\UnexpectedDriverException When no schema exists to fetch the key from
+ * @return string|string[]
+ * @throws \Muffin\Webservice\Webservice\Exception\UnexpectedDriverException When no schema exists to fetch the key from
*/
public function getDisplayField()
{
@@ -566,13 +450,10 @@ public function getDisplayField()
$this->_displayField = array_shift($primary);
$schema = $this->getSchema();
- if (!$schema) {
- throw new UnexpectedDriverException(__('No schema has been defined for this endpoint'));
- }
- if ($schema->column('title')) {
+ if ($schema->getColumn('title')) {
$this->_displayField = 'title';
}
- if ($schema->column('name')) {
+ if ($schema->getColumn('name')) {
$this->_displayField = 'name';
}
}
@@ -580,38 +461,23 @@ public function getDisplayField()
return $this->_displayField;
}
- /**
- * Returns the class used to hydrate resources for this endpoint or sets a new one
- *
- * @param string|null $name the name of the class to use
- * @throws \Muffin\Webservice\Exception\MissingResourceClassException when the entity class cannot be found
- * @return string
- * @deprecated 2.0.0 Use setResourceClassName() and getResourceClassName() instead.
- */
- public function resourceClass($name = null)
- {
- if ($name !== null) {
- $this->setResourceClass($name);
- }
-
- return $this->getResourceClass();
- }
-
/**
* Set the resource class name used to hydrate resources for this endpoint
*
* @param string $name Name of the class to use
* @return $this
- * @throws \Muffin\Webservice\Exception\MissingResourceClassException If the resource class specified does not exist
+ * @throws \Muffin\Webservice\Model\Exception\MissingResourceClassException If the resource class specified does not exist
*/
- public function setResourceClass($name)
+ public function setResourceClass(string $name)
{
- $this->_resourceClass = App::className($name, 'Model/Resource');
-
- if (!$this->_resourceClass) {
+ /** @psalm-var class-string<\Muffin\Webservice\Model\Resource>|null */
+ $className = App::className($name, 'Model/Resource');
+ if (!$className) {
throw new MissingResourceClassException([$name]);
}
+ $this->_resourceClass = $className;
+
return $this;
}
@@ -619,19 +485,21 @@ public function setResourceClass($name)
* Get the resource class name used to hydrate resources for this endpoint
*
* @return string
+ * @psalm-return class-string<\Muffin\Webservice\Model\Resource>
*/
- public function getResourceClass()
+ public function getResourceClass(): string
{
if (!$this->_resourceClass) {
- $default = \Muffin\Webservice\Model\Resource::class;
- $self = get_called_class();
+ $default = Resource::class;
+ $self = static::class;
$parts = explode('\\', $self);
- if ($self === __CLASS__ || count($parts) < 3) {
+ if ($self === self::class || count($parts) < 3) {
return $this->_resourceClass = $default;
}
$alias = Inflector::singularize(substr(array_pop($parts), 0, -8));
+ /** @psalm-var class-string<\Muffin\Webservice\Model\Resource> */
$name = implode('\\', array_slice($parts, 0, -1)) . '\Resource\\' . $alias;
if (!class_exists($name)) {
return $this->_resourceClass = $default;
@@ -643,29 +511,13 @@ public function getResourceClass()
return $this->_resourceClass;
}
- /**
- * Returns the inflect method or sets a new one
- *
- * @param null|string $method The inflection method to use
- * @return null|string
- * @deprecated 2.0.0 Use setInflectionMethod() and getInflectionMethod() instead.
- */
- public function inflectionMethod($method = null)
- {
- if ($method !== null) {
- $this->setInflectionMethod($method);
- }
-
- return $this->getInflectionMethod();
- }
-
/**
* Set a new inflection method
*
* @param string $method The name of the inflection method
* @return $this
*/
- public function setInflectionMethod($method)
+ public function setInflectionMethod(string $method)
{
$this->_inflectionMethod = $method;
@@ -675,44 +527,24 @@ public function setInflectionMethod($method)
/**
* Get the inflection method
*
- * @return string|null
+ * @return string
*/
- public function getInflectionMethod()
+ public function getInflectionMethod(): string
{
return $this->_inflectionMethod;
}
- /**
- * Returns an instance of the Webservice used
- *
- * @param \Muffin\Webservice\Webservice\WebserviceInterface|string|null $webservice The webservice to use
- * @return $this|\Muffin\Webservice\Webservice\WebserviceInterface
- * @deprecated 2.0.0 Use setWebservice() and getWebservice() instead.
- */
- public function webservice($webservice = null)
- {
- if ($webservice !== null) {
- return $this->setWebservice($this->getName(), $webservice);
- }
-
- return $this->getWebservice();
- }
-
/**
* Set the webservice instance to be used for this endpoint
*
* @param string $alias Alias for the webservice
* @param \Muffin\Webservice\Webservice\WebserviceInterface $webservice The webservice instance
* @return $this
- * @throws \Muffin\Webservice\Exception\UnexpectedDriverException When no driver exists for the endpoint
+ * @throws \Muffin\Webservice\Webservice\Exception\UnexpectedDriverException When no driver exists for the endpoint
*/
- public function setWebservice($alias, $webservice)
+ public function setWebservice(string $alias, WebserviceInterface $webservice)
{
$connection = $this->getConnection();
- if (!$connection) {
- throw new UnexpectedDriverException(__('No driver has been defined for this endpoint'));
- }
-
$connection->setWebservice($alias, $webservice);
$this->_webservice = $connection->getWebservice($alias);
@@ -724,7 +556,7 @@ public function setWebservice($alias, $webservice)
*
* @return \Muffin\Webservice\Webservice\WebserviceInterface
*/
- public function getWebservice()
+ public function getWebservice(): WebserviceInterface
{
if ($this->_webservice === null) {
$this->_webservice = $this->getConnection()->getWebservice($this->getName());
@@ -743,10 +575,10 @@ public function getWebservice()
* listeners. Any listener can set a valid result set using $query
*
* @param string $type the type of query to perform
- * @param array|\ArrayAccess $options An array that will be passed to Query::applyOptions()
- * @return \Muffin\Webservice\Query
+ * @param array $options An array that will be passed to Query::applyOptions()
+ * @return \Muffin\Webservice\Datasource\Query
*/
- public function find($type = 'all', $options = [])
+ public function find(string $type = 'all', array $options = []): Query
{
$query = $this->query()->read();
@@ -759,11 +591,11 @@ public function find($type = 'all', $options = [])
* By default findAll() applies no conditions, you
* can override this method in subclasses to modify how `find('all')` works.
*
- * @param \Muffin\Webservice\Query $query The query to find with
+ * @param \Muffin\Webservice\Datasource\Query $query The query to find with
* @param array $options The options to use for the find
- * @return \Muffin\Webservice\Query The query builder
+ * @return \Muffin\Webservice\Datasource\Query The query builder
*/
- public function findAll(Query $query, array $options)
+ public function findAll(Query $query, array $options): Query
{
return $query;
}
@@ -821,11 +653,11 @@ public function findAll(Query $query, array $options)
* ]
* ```
*
- * @param \Muffin\Webservice\Query $query The query to find with
+ * @param \Muffin\Webservice\Datasource\Query $query The query to find with
* @param array $options The options for the find
- * @return \Muffin\Webservice\Query The query builder
+ * @return \Muffin\Webservice\Datasource\Query The query builder
*/
- public function findList(Query $query, array $options)
+ public function findList(Query $query, array $options): Query
{
$options += [
'keyField' => $this->getPrimaryKey(),
@@ -860,7 +692,7 @@ public function findList(Query $query, array $options)
* the associated value
* @return array
*/
- protected function _setFieldMatchers($options, $keys)
+ protected function _setFieldMatchers(array $options, array $keys): array
{
foreach ($keys as $field) {
if (!is_array($options[$field])) {
@@ -900,12 +732,12 @@ protected function _setFieldMatchers($options, $keys)
* ```
*
* @param mixed $primaryKey primary key value to find
- * @param array|\ArrayAccess $options options accepted by `Endpoint::find()`
+ * @param array $options Options.
* @throws \Cake\Datasource\Exception\RecordNotFoundException if the record with such id could not be found
* @return \Cake\Datasource\EntityInterface
* @see \Cake\Datasource\RepositoryInterface::find()
*/
- public function get($primaryKey, $options = [])
+ public function get($primaryKey, array $options = []): EntityInterface
{
$key = (array)$this->getPrimaryKey();
$alias = $this->getAlias();
@@ -922,14 +754,14 @@ public function get($primaryKey, $options = [])
throw new InvalidPrimaryKeyException(sprintf(
'Record not found in endpoint "%s" with primary key [%s]',
$this->getName(),
- implode($primaryKey, ', ')
+ implode(', ', $primaryKey)
));
}
$conditions = array_combine($key, $primaryKey);
- $cacheConfig = isset($options['cache']) ? $options['cache'] : false;
- $cacheKey = isset($options['key']) ? $options['key'] : false;
- $finder = isset($options['finder']) ? $options['finder'] : 'all';
+ $cacheConfig = $options['cache'] ?? false;
+ $cacheKey = $options['key'] ?? false;
+ $finder = $options['finder'] ?? 'all';
unset($options['key'], $options['cache'], $options['finder']);
$query = $this->find($finder, $options)->where($conditions);
@@ -937,7 +769,7 @@ public function get($primaryKey, $options = [])
if ($cacheConfig) {
if (!$cacheKey) {
$cacheKey = sprintf(
- "get:%s.%s%s",
+ 'get:%s.%s%s',
$this->getConnection()->configName(),
$this->getName(),
json_encode($primaryKey)
@@ -961,34 +793,41 @@ public function get($primaryKey, $options = [])
* called allowing you to define additional default values. The new
* entity will be saved and returned.
*
- * @param array $search The criteria to find existing records by.
+ * @param mixed $search The criteria to find existing records by.
* @param callable|null $callback A callback that will be invoked for newly
* created entities. This callback will be called *before* the entity
* is persisted.
- * @return \Cake\Datasource\EntityInterface An entity.
+ * @return \Cake\Datasource\EntityInterface|array An entity.
+ * @throws \Cake\ORM\Exception\PersistenceFailedException When the entity couldn't be saved
*/
- public function findOrCreate($search, callable $callback = null)
+ public function findOrCreate($search, ?callable $callback = null)
{
$query = $this->find()->where($search);
$row = $query->first();
if ($row) {
return $row;
}
+
$entity = $this->newEntity();
$entity->set($search, ['guard' => false]);
if ($callback) {
$callback($entity);
}
- return $this->save($entity) ?: $entity;
+ $result = $this->save($entity);
+ if ($result === false) {
+ throw new PersistenceFailedException($entity, ['findOrCreate']);
+ }
+
+ return $entity;
}
/**
* Creates a new Query instance for this repository
*
- * @return \Muffin\Webservice\Query
+ * @return \Muffin\Webservice\Datasource\Query
*/
- public function query()
+ public function query(): Query
{
return new Query($this->getWebservice(), $this);
}
@@ -1003,9 +842,11 @@ public function query()
* @param array $fields A hash of field => new value.
* @param mixed $conditions Conditions to be used, accepts anything Query::where() can take.
* @return int Count Returns the affected rows.
+ * @psalm-suppress MoreSpecificImplementedParamType
*/
- public function updateAll($fields, $conditions)
+ public function updateAll($fields, $conditions): int
{
+ /** @psalm-suppress PossiblyInvalidMethodCall, PossiblyUndefinedMethod */
return $this->query()->update()->where($conditions)->set($fields)->execute()->count();
}
@@ -1018,11 +859,12 @@ public function updateAll($fields, $conditions)
* need those first load a collection of records and delete them.
*
* @param mixed $conditions Conditions to be used, accepts anything Query::where() can take.
- * @return \Traversable|int Count Returns the affected rows.
- *
+ * @return int Count of affected rows.
* @see \Muffin\Webservice\Endpoint::delete()
+ * @psalm-suppress InvalidReturnStatement
+ * @psalm-suppress InvalidReturnType
*/
- public function deleteAll($conditions)
+ public function deleteAll($conditions): int
{
return $this->query()->delete()->where($conditions)->execute();
}
@@ -1031,12 +873,12 @@ public function deleteAll($conditions)
* Returns true if there is any record in this repository matching the specified
* conditions.
*
- * @param array|\ArrayAccess $conditions list of conditions to pass to the query
+ * @param mixed $conditions list of conditions to pass to the query
* @return bool
*/
- public function exists($conditions)
+ public function exists($conditions): bool
{
- return ($this->find()->where($conditions)->count() > 0);
+ return $this->find()->where($conditions)->count() > 0;
}
/**
@@ -1044,53 +886,53 @@ public function exists($conditions)
* returns the same resource after a successful save or false in case
* of any error.
*
- * @param \Cake\Datasource\EntityInterface $resource the resource to be saved
+ * @param \Cake\Datasource\EntityInterface $entity the resource to be saved
* @param array|\ArrayAccess $options The options to use when saving.
- * @return \Cake\Datasource\EntityInterface|bool
+ * @return \Cake\Datasource\EntityInterface|false
*/
- public function save(EntityInterface $resource, $options = [])
+ public function save(EntityInterface $entity, $options = [])
{
$options = new ArrayObject((array)$options + [
'checkRules' => true,
'checkExisting' => false,
]);
- if ($resource->getErrors()) {
+ if ($entity->getErrors()) {
return false;
}
- if ($resource->isNew() === false && !$resource->isDirty()) {
- return $resource;
+ if ($entity->isNew() === false && !$entity->isDirty()) {
+ return $entity;
}
$primaryColumns = (array)$this->getPrimaryKey();
- if ($options['checkExisting'] && $primaryColumns && $resource->isNew() && $resource->has($primaryColumns)) {
+ if ($options['checkExisting'] && $primaryColumns && $entity->isNew() && $entity->has($primaryColumns)) {
$alias = $this->getAlias();
$conditions = [];
- foreach ($resource->extract($primaryColumns) as $k => $v) {
+ foreach ($entity->extract($primaryColumns) as $k => $v) {
$conditions["$alias.$k"] = $v;
}
- $resource->isNew(!$this->exists($conditions));
+ $entity->setNew(!$this->exists($conditions));
}
- $mode = $resource->isNew() ? RulesChecker::CREATE : RulesChecker::UPDATE;
- if ($options['checkRules'] && !$this->checkRules($resource, $mode, $options)) {
+ $mode = $entity->isNew() ? RulesChecker::CREATE : RulesChecker::UPDATE;
+ if ($options['checkRules'] && !$this->checkRules($entity, $mode, $options)) {
return false;
}
- $event = $this->dispatchEvent('Model.beforeSave', compact('resource', 'options'));
+ $event = $this->dispatchEvent('Model.beforeSave', compact('entity', 'options'));
if ($event->isStopped()) {
- return $event->result;
+ return $event->getResult();
}
- $data = $resource->extract($this->getSchema()->columns(), true);
+ $data = $entity->extract($this->getSchema()->columns(), true);
- if ($resource->isNew()) {
+ if ($entity->isNew()) {
$query = $this->query()->create();
} else {
- $query = $this->query()->update()->where($resource->extract($primaryColumns));
+ $query = $this->query()->update()->where($entity->extract($primaryColumns));
}
$query->set($data);
@@ -1099,13 +941,14 @@ public function save(EntityInterface $resource, $options = [])
return false;
}
- if (($resource->isNew()) && ($result instanceof EntityInterface)) {
+ if ($entity->isNew() && ($result instanceof EntityInterface)) {
return $result;
}
- $className = get_class($resource);
+ /** @psalm-var class-string<\Cake\Datasource\EntityInterface> $className */
+ $className = get_class($entity);
- return new $className($resource->toArray(), [
+ return new $className($entity->toArray(), [
'markNew' => false,
'markClean' => true,
]);
@@ -1114,15 +957,16 @@ public function save(EntityInterface $resource, $options = [])
/**
* Delete a single resource.
*
- * @param \Cake\Datasource\EntityInterface $resource The resource to remove.
+ * @param \Cake\Datasource\EntityInterface $entity The resource to remove.
* @param array|\ArrayAccess $options The options for the delete.
* @return bool
*/
- public function delete(EntityInterface $resource, $options = [])
+ public function delete(EntityInterface $entity, $options = []): bool
{
- return (bool)$this->query()->delete()->where([
- $this->getPrimaryKey() => $resource->get($this->getPrimaryKey()),
- ])->execute();
+ $primaryKeys = (array)$this->getPrimaryKey();
+ $values = $entity->extract($primaryKeys);
+
+ return (bool)$this->query()->delete()->where(array_combine($primaryKeys, $values))->execute();
}
/**
@@ -1131,7 +975,7 @@ public function delete(EntityInterface $resource, $options = [])
* @param string $type name of finder to check
* @return bool
*/
- public function hasFinder($type)
+ public function hasFinder(string $type): bool
{
$finder = 'find' . $type;
@@ -1143,12 +987,12 @@ public function hasFinder($type)
* if no query is passed a new one will be created and returned
*
* @param string $type name of the finder to be called
- * @param \Muffin\Webservice\Query $query The query object to apply the finder options to
+ * @param \Muffin\Webservice\Datasource\Query $query The query object to apply the finder options to
* @param array $options List of options to pass to the finder
- * @return \Muffin\Webservice\Query
+ * @return \Muffin\Webservice\Datasource\Query
* @throws \BadMethodCallException If the requested finder cannot be found
*/
- public function callFinder($type, Query $query, array $options = [])
+ public function callFinder(string $type, Query $query, array $options = []): Query
{
$query->applyOptions($options);
$options = $query->getOptions();
@@ -1170,7 +1014,7 @@ public function callFinder($type, Query $query, array $options = [])
* @return mixed
* @throws \BadMethodCallException when there are missing arguments, or when and & or are combined.
*/
- protected function _dynamicFinder($method, $args)
+ protected function _dynamicFinder(string $method, array $args)
{
$method = Inflector::underscore($method);
preg_match('/^find_([\w]+)_by_/', $method, $matches);
@@ -1215,7 +1059,7 @@ protected function _dynamicFinder($method, $args)
$conditions = [
'OR' => $makeConditions($fields, $args),
];
- } elseif ($hasAnd !== false) {
+ } else {
$fields = explode('_and_', $fields);
$conditions = $makeConditions($fields, $args);
}
@@ -1250,11 +1094,9 @@ public function __call($method, $args)
* Override this method if you want a endpoint object to use custom
* marshalling logic.
*
- * @return \Muffin\Webservice\Marshaller
- *
- * @see \Muffin\Webservice\Marshaller
+ * @return \Muffin\Webservice\Datasource\Marshaller
*/
- public function marshaller()
+ public function marshaller(): Marshaller
{
return new Marshaller($this);
}
@@ -1268,18 +1110,12 @@ public function marshaller()
* on the primary key data existing in the database when the entity
* is saved. Until the entity is saved, it will be a detached record.
*
- * @param array|null $data The data to build an entity with.
+ * @param array $data The data to build an entity with.
* @param array $options A list of options for the object hydration.
- * @return \Muffin\Webservice\Model\Resource
+ * @return \Cake\Datasource\EntityInterface
*/
- public function newEntity($data = null, array $options = [])
+ public function newEntity(array $data = [], array $options = []): EntityInterface
{
- if ($data === null) {
- $class = $this->getResourceClass();
- $entity = new $class([], ['source' => $this->getRegistryAlias()]);
-
- return $entity;
- }
$marshaller = $this->marshaller();
return $marshaller->one($data, $options);
@@ -1287,8 +1123,23 @@ public function newEntity($data = null, array $options = [])
/**
* {@inheritDoc}
+ *
+ * @return \Cake\Datasource\EntityInterface
+ * @psalm-suppress InvalidReturnStatement
+ * @psalm-suppress InvalidReturnType
+ */
+ public function newEmptyEntity(): EntityInterface
+ {
+ $class = $this->getResourceClass();
+ $entity = new $class([], ['source' => $this->getRegistryAlias()]);
+
+ return $entity;
+ }
+
+ /**
+ * @inheritDoc
*/
- public function newEntities(array $data, array $options = [])
+ public function newEntities(array $data, array $options = []): array
{
$marshaller = $this->marshaller();
@@ -1310,10 +1161,9 @@ public function newEntities(array $data, array $options = [])
* data merged in
* @param array $data key value list of fields to be merged into the resource
* @param array $options A list of options for the object hydration.
- *
* @return \Cake\Datasource\EntityInterface
*/
- public function patchEntity(EntityInterface $entity, array $data, array $options = [])
+ public function patchEntity(EntityInterface $entity, array $data, array $options = []): EntityInterface
{
$marshaller = $this->marshaller();
@@ -1336,10 +1186,10 @@ public function patchEntity(EntityInterface $entity, array $data, array $options
* data merged in
* @param array $data list of arrays to be merged into the entities
* @param array $options A list of options for the objects hydration.
- *
* @return array
+ * @psalm-return array
*/
- public function patchEntities($entities, array $data, array $options = [])
+ public function patchEntities(iterable $entities, array $data, array $options = []): array
{
$marshaller = $this->marshaller();
@@ -1370,7 +1220,7 @@ public function patchEntities($entities, array $data, array $options = [])
*
* @return array
*/
- public function implementedEvents()
+ public function implementedEvents(): array
{
$eventMap = [
'Model.beforeMarshal' => 'beforeMarshal',
@@ -1405,7 +1255,7 @@ public function implementedEvents()
* @param \Cake\Datasource\RulesChecker $rules The rules object to be modified.
* @return \Cake\Datasource\RulesChecker
*/
- public function buildRules(RulesChecker $rules)
+ public function buildRules(RulesChecker $rules): RulesChecker
{
return $rules;
}
@@ -1417,15 +1267,13 @@ public function buildRules(RulesChecker $rules)
*/
public function __debugInfo()
{
- $conn = $this->getConnection();
-
return [
'registryAlias' => $this->getRegistryAlias(),
'alias' => $this->getAlias(),
'endpoint' => $this->getName(),
'resourceClass' => $this->getResourceClass(),
'defaultConnection' => $this->defaultConnectionName(),
- 'connectionName' => $conn ? $conn->configName() : null,
+ 'connectionName' => $this->getConnection()->configName(),
'inflector' => $this->getInflectionMethod(),
];
}
@@ -1448,8 +1296,12 @@ public function setAlias($alias)
*
* @return string
*/
- public function getAlias()
+ public function getAlias(): string
{
+ if ($this->_alias === null) {
+ $this->_alias = $this->getName();
+ }
+
return $this->_alias;
}
}
diff --git a/src/Model/EndpointLocator.php b/src/Model/EndpointLocator.php
index d2831b4..7e8081f 100644
--- a/src/Model/EndpointLocator.php
+++ b/src/Model/EndpointLocator.php
@@ -1,52 +1,33 @@
_instances[$alias] = $object;
+ return $this->instances[$alias] = $repository;
}
/**
@@ -57,20 +38,22 @@ public function set($alias, Endpoint $object)
* @return \Muffin\Webservice\Model\Endpoint
* @throws \RuntimeException If the registry alias is already in use.
*/
- public function get($alias, array $options = [])
+ public function get(string $alias, array $options = []): Endpoint
{
- if (isset($this->_instances[$alias])) {
- if (!empty($options) && $this->_options[$alias] !== $options) {
- throw new RuntimeException(sprintf(
- 'You cannot configure "%s", it already exists in the locator.',
- $alias
- ));
- }
-
- return $this->_instances[$alias];
- }
+ /** @var \Muffin\Webservice\Model\Endpoint */
+ return parent::get($alias, $options);
+ }
- list(, $classAlias) = pluginSplit($alias);
+ /**
+ * Wrapper for creating endpoint instances
+ *
+ * @param string $alias Endpoint alias.
+ * @param array $options The alias to check for.
+ * @return \Muffin\Webservice\Model\Endpoint
+ */
+ protected function createInstance(string $alias, array $options)
+ {
+ [, $classAlias] = pluginSplit($alias);
$options = ['alias' => $classAlias] + $options;
if (empty($options['className'])) {
@@ -81,129 +64,55 @@ public function get($alias, array $options = [])
$options['className'] = $className;
} else {
if (!isset($options['endpoint']) && strpos($options['className'], '\\') === false) {
- list(, $endpoint) = pluginSplit($options['className']);
+ [, $endpoint] = pluginSplit($options['className']);
$options['endpoint'] = Inflector::underscore($endpoint);
}
- $options['className'] = 'Muffin\Webservice\Model\Endpoint';
+ $options['className'] = Endpoint::class;
}
if (empty($options['connection'])) {
- if ($options['className'] !== 'Muffin\Webservice\Model\Endpoint') {
+ if ($options['className'] !== Endpoint::class) {
$connectionName = $options['className']::defaultConnectionName();
} else {
- $pluginParts = explode('/', pluginSplit($alias)[0]);
-
- $connectionName = Inflector::underscore(end($pluginParts));
+ if (strpos($alias, '.') === false) {
+ $connectionName = 'webservice';
+ } else {
+ /** @psalm-suppress PossiblyNullArgument */
+ $pluginParts = explode('/', pluginSplit($alias)[0]);
+ $connectionName = Inflector::underscore(end($pluginParts));
+ }
}
- $options['connection'] = ConnectionManager::get($connectionName);
+ $options['connection'] = $this->getConnection($connectionName);
+ } elseif (is_string($options['connection'])) {
+ $options['connection'] = $this->getConnection($options['connection']);
}
$options['registryAlias'] = $alias;
- $this->_instances[$alias] = $this->_create($options);
- $this->_options[$alias] = $options;
- return $this->_instances[$alias];
- }
+ /** @psalm-var class-string<\Muffin\Webservice\Model\Endpoint> $className */
+ $className = $options['className'];
- /**
- * Check to see if an instance exists in the locator.
- *
- * @param string $alias The alias to check for.
- * @return bool
- */
- public function exists($alias)
- {
- return isset($this->_instances[$alias]);
+ return new $className($options);
}
/**
- * Returns configuration for an alias or the full configuration array for all aliases.
+ * Get connection instance.
*
- * @param string|null $alias Endpoint alias
- * @return array
+ * @param string $connectionName Connection name.
+ * @return \Muffin\Webservice\Datasource\Connection
*/
- public function getConfig($alias = null)
+ protected function getConnection(string $connectionName): Connection
{
- if ($alias === null) {
- return $this->_config;
+ try {
+ /** @var \Muffin\Webservice\Datasource\Connection */
+ return ConnectionManager::get($connectionName);
+ } catch (MissingDatasourceConfigException $e) {
+ $message = $e->getMessage()
+ . ' You can override Endpoint::defaultConnectionName() to return the connection name you want.';
+
+ /** @psalm-suppress PossiblyInvalidArgument */
+ throw new MissingDatasourceConfigException($message, $e->getCode(), $e->getPrevious());
}
-
- return isset($this->_config[$alias]) ? $this->_config[$alias] : [];
- }
-
- /**
- * Stores a list of options to be used when instantiating an object with a matching alias.
- *
- * If configuring many aliases, use an array keyed by the alias.
- *
- * ```
- * $locator->setConfig([
- * 'Example' => ['registryAlias' => 'example'],
- * 'Posts' => ['registryAlias' => 'posts'],
- * ]);
- * ```
- *
- * @param string|array $alias The alias to set configuration for, or an array of configuration keyed by alias
- * @param null|array $config Array of configuration options
- * @return $this
- * @throws \RuntimeException
- */
- public function setConfig($alias, $config = null)
- {
- if (!is_string($alias)) {
- $this->_config = $alias;
-
- return $this;
- }
-
- if (isset($this->_instances[$alias])) {
- throw new RuntimeException(sprintf(
- 'You cannot configure "%s", it has already been constructed.',
- $alias
- ));
- }
-
- $this->_config[$alias] = $config;
-
- return $this;
- }
-
- /**
- * Clear the endpoint locator of all instances
- *
- * @return void
- */
- public function clear()
- {
- $this->_instances = [];
- $this->_options = [];
- $this->_config = [];
- }
-
- /**
- * Remove a specific endpoint instance from the locator by alias
- *
- * @param string $alias String alias of the endpoint
- * @return void
- */
- public function remove($alias)
- {
- unset(
- $this->_instances[$alias],
- $this->_options[$alias],
- $this->_config[$alias]
- );
- }
-
- /**
- * Wrapper for creating endpoint instances
- *
- * @param array $options The alias to check for.
- * @return \Muffin\Webservice\Model\Endpoint
- */
- protected function _create(array $options)
- {
- return new $options['className']($options);
}
}
diff --git a/src/Model/EndpointRegistry.php b/src/Model/EndpointRegistry.php
deleted file mode 100644
index ff70b99..0000000
--- a/src/Model/EndpointRegistry.php
+++ /dev/null
@@ -1,123 +0,0 @@
- $classAlias] + $options;
-
- if (empty($options['className'])) {
- $options['className'] = Inflector::camelize($alias);
- }
- $className = App::className($options['className'], 'Model/Endpoint', 'Endpoint');
- if ($className) {
- $options['className'] = $className;
- } else {
- if (!isset($options['endpoint']) && strpos($options['className'], '\\') === false) {
- list(, $endpoint) = pluginSplit($options['className']);
- $options['endpoint'] = Inflector::underscore($endpoint);
- }
- $options['className'] = 'Muffin\Webservice\Model\Endpoint';
- }
-
- if (empty($options['connection'])) {
- if ($options['className'] !== 'Muffin\Webservice\Model\Endpoint') {
- $connectionName = $options['className']::defaultConnectionName();
- } else {
- $pluginParts = explode('/', pluginSplit($alias)[0]);
-
- $connectionName = Inflector::underscore(end($pluginParts));
- }
-
- $options['connection'] = ConnectionManager::get($connectionName);
- }
-
- $options['registryAlias'] = $alias;
- self::$_instances[$alias] = self::_create($options);
- self::$_options[$alias] = $options;
-
- return self::$_instances[$alias];
- }
-
- /**
- * Wrapper for creating endpoint instances
- *
- * @param array $options The alias to check for.
- *
- * @return \Muffin\Webservice\Model\Endpoint
- */
- protected static function _create(array $options)
- {
- return new $options['className']($options);
- }
-}
diff --git a/src/Exception/MissingEndpointSchemaException.php b/src/Model/Exception/MissingEndpointSchemaException.php
similarity index 56%
rename from src/Exception/MissingEndpointSchemaException.php
rename to src/Model/Exception/MissingEndpointSchemaException.php
index 9341997..a1a4891 100644
--- a/src/Exception/MissingEndpointSchemaException.php
+++ b/src/Model/Exception/MissingEndpointSchemaException.php
@@ -1,12 +1,12 @@
isNew($options['markNew']);
+ $this->setNew($options['markNew']);
}
if (!empty($properties) && $options['markClean'] && !$options['useSetters']) {
- $this->_properties = $properties;
+ $this->_fields = $properties;
return;
}
diff --git a/src/Model/ResourceBasedEntityInterface.php b/src/Model/ResourceBasedEntityInterface.php
index 06ef4fe..66b1d37 100644
--- a/src/Model/ResourceBasedEntityInterface.php
+++ b/src/Model/ResourceBasedEntityInterface.php
@@ -1,17 +1,17 @@
set($resource->toArray());
}
diff --git a/src/Model/Schema.php b/src/Model/Schema.php
index 74a2d0d..89639b7 100644
--- a/src/Model/Schema.php
+++ b/src/Model/Schema.php
@@ -1,17 +1,19 @@
stopPropagation()` to achieve the same result.
- *
- * @param \Cake\Event\Event $event container object having the `request`, `response` and `additionalParams`
- * keys in the data property.
- * @return void
- */
- public function beforeDispatch(Event $event)
- {
- $controller = false;
- if (isset($event->data['controller'])) {
- $controller = $event->data['controller'];
- }
- if ($controller) {
- $callback = ['Muffin\Webservice\Model\EndpointRegistry', 'get'];
- $controller->modelFactory('Endpoint', $callback);
- }
- }
-}
diff --git a/src/AbstractDriver.php b/src/Webservice/Driver/AbstractDriver.php
similarity index 62%
rename from src/AbstractDriver.php
rename to src/Webservice/Driver/AbstractDriver.php
index d375ea1..1662168 100644
--- a/src/AbstractDriver.php
+++ b/src/Webservice/Driver/AbstractDriver.php
@@ -1,15 +1,17 @@
setConfig($config);
@@ -63,23 +65,7 @@ public function __construct($config = [])
*
* @return void
*/
- abstract public function initialize();
-
- /**
- * Set or return an instance of the client used for communication
- *
- * @param object $client The client to use
- * @return object
- * @deprecated 2.0.0 Use setClient() and getClient() instead.
- */
- public function client($client = null)
- {
- if ($client === null) {
- return $this->getClient();
- }
-
- return $this->setClient($client);
- }
+ abstract public function initialize(): void;
/**
* Set the client instance this driver will use to make requests
@@ -87,7 +73,7 @@ public function client($client = null)
* @param object $client Client instance
* @return $this
*/
- public function setClient($client)
+ public function setClient(object $client)
{
$this->_client = $client;
@@ -99,28 +85,11 @@ public function setClient($client)
*
* @return object
*/
- public function getClient()
+ public function getClient(): object
{
return $this->_client;
}
- /**
- * Set or get a instance of a webservice
- *
- * @param string $name The name of the webservice
- * @param \Muffin\Webservice\Webservice\WebserviceInterface|null $webservice The instance of the webservice you'd like to set
- * @return $this|\Muffin\Webservice\Webservice\WebserviceInterface
- * @deprecated 2.0.0 Use setWebservice() or getWebservice() instead.
- */
- public function webservice($name, WebserviceInterface $webservice = null)
- {
- if ($webservice !== null) {
- $this->setWebservice($name, $webservice);
- }
-
- return $this->getWebservice($name);
- }
-
/**
* Set the webservice instance used by the driver
*
@@ -128,7 +97,7 @@ public function webservice($name, WebserviceInterface $webservice = null)
* @param \Muffin\Webservice\Webservice\WebserviceInterface $webservice Instance of the webservice
* @return $this
*/
- public function setWebservice($name, WebserviceInterface $webservice)
+ public function setWebservice(string $name, WebserviceInterface $webservice)
{
$this->_webservices[$name] = $webservice;
@@ -139,12 +108,12 @@ public function setWebservice($name, WebserviceInterface $webservice)
* Fetch a webservice instance from the driver registry
*
* @param string $name Registry alias to fetch
- * @return \Muffin\Webservice\Webservice\WebserviceInterface|null
+ * @return \Muffin\Webservice\Webservice\WebserviceInterface
*/
- public function getWebservice($name)
+ public function getWebservice(string $name): WebserviceInterface
{
if (!isset($this->_webservices[$name])) {
- list($pluginName) = pluginSplit(App::shortName(get_class($this), 'Webservice/Driver'));
+ [$pluginName] = pluginSplit(App::shortName(static::class, 'Webservice/Driver'));
$webserviceClass = implode('.', array_filter([$pluginName, Inflector::camelize($name)]));
@@ -160,15 +129,17 @@ public function getWebservice($name)
}
/**
- * Returns a logger instance
- *
- * @return \Psr\Log\LoggerInterface
+ * Sets a logger
*
- * @deprecated 1.4.0 Use getLogger() instead.
+ * @param \Psr\Log\LoggerInterface $logger Logger object
+ * @return $this
+ * @psalm-suppress ImplementedReturnTypeMismatch
*/
- public function logger()
+ public function setLogger(LoggerInterface $logger)
{
- return $this->logger;
+ $this->logger = $logger;
+
+ return $this;
}
/**
@@ -176,7 +147,7 @@ public function logger()
*
* @return \Psr\Log\LoggerInterface|null
*/
- public function getLogger()
+ public function getLogger(): ?LoggerInterface
{
return $this->logger;
}
@@ -186,28 +157,11 @@ public function getLogger()
*
* @return string
*/
- public function configName()
+ public function configName(): string
{
return (string)$this->_config['name'];
}
- /**
- * Enables or disables query logging for this driver
- *
- * @param bool|null $enable whether to turn logging on or disable it. Use null to read current value.
- * @return bool
- *
- * @deprecated 1.4.0 Use enableQueryLogging()/disableQueryLogging()/isQueryLoggingEnabled() instead.
- */
- public function logQueries($enable = null)
- {
- if ($enable === null) {
- return $this->_logQueries;
- }
-
- return $this->_logQueries = $enable;
- }
-
/**
* Enable query logging for the driver
*
@@ -237,7 +191,7 @@ public function disableQueryLogging()
*
* @return bool
*/
- public function isQueryLoggingEnabled()
+ public function isQueryLoggingEnabled(): bool
{
return $this->_logQueries;
}
@@ -249,17 +203,10 @@ public function isQueryLoggingEnabled()
* @param array $args Arguments to pass-through.
* @return mixed
* @throws \RuntimeException If the client object has not been initialized.
- * @throws \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException If the method does not exist in the client.
+ * @throws \Muffin\Webservice\Webservice\Exception\UnimplementedWebserviceMethodException If the method does not exist in the client.
*/
public function __call($method, $args)
{
- if (!is_object($this->getClient())) {
- throw new RuntimeException(sprintf(
- 'The `%s` client has not been initialized',
- $this->getConfig('name')
- ));
- }
-
if (!method_exists($this->getClient(), $method)) {
throw new UnimplementedWebserviceMethodException([
'name' => $this->getConfig('name'),
@@ -279,7 +226,7 @@ public function __debugInfo()
{
return [
'client' => $this->getClient(),
- 'logger' => $this->logger(),
+ 'logger' => $this->getLogger(),
'query_logging' => $this->isQueryLoggingEnabled(),
'webservices' => array_keys($this->_webservices),
];
@@ -292,26 +239,28 @@ public function __debugInfo()
*
* @param string $className Class name of the webservice to initialize
* @param array $options Set of options to pass to the constructor
- * @return WebserviceInterface
- * @throws \Muffin\Webservice\Exception\MissingWebserviceClassException If no webservice class can be found
+ * @return \Muffin\Webservice\Webservice\WebserviceInterface
+ * @throws \Muffin\Webservice\Webservice\Exception\MissingWebserviceClassException If no webservice class can be found
*/
- protected function _createWebservice($className, array $options = [])
+ protected function _createWebservice(string $className, array $options = []): WebserviceInterface
{
$webservice = App::className($className, 'Webservice', 'Webservice');
if ($webservice) {
+ /** @psalm-var \Muffin\Webservice\Webservice\WebserviceInterface */
return new $webservice($options);
}
- $namespaceParts = explode('\\', get_class($this));
+ $namespaceParts = explode('\\', static::class);
$fallbackWebserviceClass = end($namespaceParts);
- list($pluginName) = pluginSplit($className);
+ [$pluginName] = pluginSplit($className);
if ($pluginName) {
$fallbackWebserviceClass = $pluginName . '.' . $fallbackWebserviceClass;
}
$fallbackWebservice = App::className($fallbackWebserviceClass, 'Webservice', 'Webservice');
if ($fallbackWebservice) {
+ /** @psalm-var \Muffin\Webservice\Webservice\WebserviceInterface */
return new $fallbackWebservice($options);
}
diff --git a/src/Exception/MissingDriverException.php b/src/Webservice/Exception/MissingDriverException.php
similarity index 54%
rename from src/Exception/MissingDriverException.php
rename to src/Webservice/Exception/MissingDriverException.php
index 07de5dc..be71b8d 100644
--- a/src/Exception/MissingDriverException.php
+++ b/src/Webservice/Exception/MissingDriverException.php
@@ -1,11 +1,12 @@
getDriver();
- }
-
- return $this->setDriver($driver);
- }
-
/**
* Set the webservice driver and return the instance for chaining
*
- * @param \Muffin\Webservice\AbstractDriver $driver Instance of the driver
+ * @param \Muffin\Webservice\Webservice\Driver\AbstractDriver $driver Instance of the driver
* @return $this
*/
public function setDriver(AbstractDriver $driver)
@@ -99,27 +86,15 @@ public function setDriver(AbstractDriver $driver)
/**
* Get this webservices driver
*
- * @return \Muffin\Webservice\AbstractDriver|null
+ * @return \Muffin\Webservice\Webservice\Driver\AbstractDriver
*/
- public function getDriver()
+ public function getDriver(): AbstractDriver
{
- return $this->_driver;
- }
-
- /**
- * Set the endpoint path to use
- *
- * @param string|null $endpoint The endpoint
- * @return string|$this
- * @deprecated 2.0.0 Use setEndpoint() and getEndpoint() instead.
- */
- public function endpoint($endpoint = null)
- {
- if ($endpoint === null) {
- return $this->getEndpoint();
+ if ($this->_driver === null) {
+ throw new RuntimeException('No driver has been defined');
}
- return $this->setEndpoint($endpoint);
+ return $this->_driver;
}
/**
@@ -128,7 +103,7 @@ public function endpoint($endpoint = null)
* @param string $endpoint Endpoint path
* @return $this
*/
- public function setEndpoint($endpoint)
+ public function setEndpoint(string $endpoint)
{
$this->_endpoint = $endpoint;
@@ -140,7 +115,7 @@ public function setEndpoint($endpoint)
*
* @return string
*/
- public function getEndpoint()
+ public function getEndpoint(): string
{
return $this->_endpoint;
}
@@ -152,7 +127,7 @@ public function getEndpoint()
* @param array $requiredFields The required fields
* @return void
*/
- public function addNestedResource($url, array $requiredFields)
+ public function addNestedResource(string $url, array $requiredFields): void
{
$this->_nestedResources[$url] = [
'requiredFields' => $requiredFields,
@@ -163,40 +138,39 @@ public function addNestedResource($url, array $requiredFields)
* Checks if a set of conditions match a nested resource
*
* @param array $conditions The conditions in a query
- * @return bool|string Either a URL or false in case no nested resource matched
+ * @return string|null Either a URL or false in case no nested resource matched
*/
- public function nestedResource(array $conditions)
+ public function nestedResource(array $conditions): ?string
{
foreach ($this->_nestedResources as $url => $options) {
- if (count(array_intersect_key(array_flip($options['requiredFields']), $conditions)) !== count($options['requiredFields'])) {
+ $fieldsInConditionsCount = count(array_intersect_key(array_flip($options['requiredFields']), $conditions));
+ $requiredFieldsCount = count($options['requiredFields']);
+
+ if ($fieldsInConditionsCount !== $requiredFieldsCount) {
continue;
}
return Text::insert($url, $conditions);
}
- return false;
+ return null;
}
/**
* Executes a query
*
- * @param Query $query The query to execute
+ * @param \Muffin\Webservice\Datasource\Query $query The query to execute
* @param array $options The options to use
- *
- * @return \Muffin\Webservice\ResultSet|int|bool
+ * @return bool|int|\Muffin\Webservice\Model\Resource|\Muffin\Webservice\Datasource\ResultSet
*/
public function execute(Query $query, array $options = [])
{
$result = $this->_executeQuery($query, $options);
- if ($this->getDriver() === null) {
- throw new \UnexpectedValueException(__('No driver has been defined'));
- }
+ $logger = $this->getDriver()->getLogger();
- // Write to the logger when one has been defined
- if ($this->getDriver()->getLogger()) {
- $this->_logQuery($query, $this->getDriver()->getLogger());
+ if ($logger !== null) {
+ $this->_logQuery($query, $logger);
}
return $result;
@@ -206,17 +180,18 @@ public function execute(Query $query, array $options = [])
* Returns a schema for the provided endpoint
*
* @param string $endpoint The endpoint to get the schema for
- * @return \Muffin\Webservice\Schema The schema to use
+ * @return \Muffin\Webservice\Datasource\Schema The schema to use
*/
- public function describe($endpoint)
+ public function describe(string $endpoint): Schema
{
- $shortName = App::shortName(get_class($this), 'Webservice', 'Webservice');
- list($plugin, $name) = pluginSplit($shortName);
+ $shortName = App::shortName(static::class, 'Webservice', 'Webservice');
+ [$plugin, $name] = pluginSplit($shortName);
$endpoint = Inflector::classify(str_replace('-', '_', $endpoint));
$schemaShortName = implode('.', array_filter([$plugin, $endpoint]));
$schemaClassName = App::className($schemaShortName, 'Model/Endpoint/Schema', 'Schema');
if ($schemaClassName) {
+ /** @var \Muffin\Webservice\Datasource\Schema */
return new $schemaClassName($endpoint);
}
@@ -229,13 +204,15 @@ public function describe($endpoint)
/**
* Execute the appropriate method for a query
*
- * @param \Muffin\Webservice\Query $query The query to execute
+ * @param \Muffin\Webservice\Datasource\Query $query The query to execute
* @param array $options The options to use
- * @return bool|int|\Muffin\Webservice\ResultSet
+ * @return bool|int|\Muffin\Webservice\Model\Resource|\Muffin\Webservice\Datasource\ResultSet
+ * @psalm-suppress NullableReturnStatement
+ * @psalm-suppress InvalidNullableReturnType
*/
protected function _executeQuery(Query $query, array $options = [])
{
- switch ($query->action()) {
+ switch ($query->clause('action')) {
case Query::ACTION_CREATE:
return $this->_executeCreateQuery($query, $options);
case Query::ACTION_READ:
@@ -252,16 +229,16 @@ protected function _executeQuery(Query $query, array $options = [])
/**
* Executes a query with the create action
*
- * @param \Muffin\Webservice\Query $query The query to execute
+ * @param \Muffin\Webservice\Datasource\Query $query The query to execute
* @param array $options The options to use
- * @return bool|void
- * @throws \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
+ * @return bool|\Muffin\Webservice\Model\Resource
+ * @throws \Muffin\Webservice\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
* implemented into userland classes
*/
protected function _executeCreateQuery(Query $query, array $options = [])
{
throw new UnimplementedWebserviceMethodException([
- 'name' => get_class($this),
+ 'name' => static::class,
'method' => '_executeCreateQuery',
]);
}
@@ -269,16 +246,16 @@ protected function _executeCreateQuery(Query $query, array $options = [])
/**
* Executes a query with the read action
*
- * @param \Muffin\Webservice\Query $query The query to execute
+ * @param \Muffin\Webservice\Datasource\Query $query The query to execute
* @param array $options The options to use
- * @return \Muffin\Webservice\ResultSet|bool|void
- * @throws \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
+ * @return bool|\Muffin\Webservice\Datasource\ResultSet
+ * @throws \Muffin\Webservice\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
* implemented into userland classes
*/
protected function _executeReadQuery(Query $query, array $options = [])
{
throw new UnimplementedWebserviceMethodException([
- 'name' => get_class($this),
+ 'name' => static::class,
'method' => '_executeReadQuery',
]);
}
@@ -286,16 +263,16 @@ protected function _executeReadQuery(Query $query, array $options = [])
/**
* Executes a query with the update action
*
- * @param \Muffin\Webservice\Query $query The query to execute
+ * @param \Muffin\Webservice\Datasource\Query $query The query to execute
* @param array $options The options to use
- * @return int|bool|void
- * @throws \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
+ * @return int|bool|\Muffin\Webservice\Model\Resource
+ * @throws \Muffin\Webservice\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
* implemented into userland classes
*/
protected function _executeUpdateQuery(Query $query, array $options = [])
{
throw new UnimplementedWebserviceMethodException([
- 'name' => get_class($this),
+ 'name' => static::class,
'method' => '_executeUpdateQuery',
]);
}
@@ -303,16 +280,16 @@ protected function _executeUpdateQuery(Query $query, array $options = [])
/**
* Executes a query with the delete action
*
- * @param \Muffin\Webservice\Query $query The query to execute
+ * @param \Muffin\Webservice\Datasource\Query $query The query to execute
* @param array $options The options to use
- * @return int|bool|void
- * @throws \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
+ * @return int|bool
+ * @throws \Muffin\Webservice\Webservice\Exception\UnimplementedWebserviceMethodException When this method has not been
* implemented into userland classes
*/
protected function _executeDeleteQuery(Query $query, array $options = [])
{
throw new UnimplementedWebserviceMethodException([
- 'name' => get_class($this),
+ 'name' => static::class,
'method' => '_executeDeleteQuery',
]);
}
@@ -323,8 +300,11 @@ protected function _executeDeleteQuery(Query $query, array $options = [])
* @param string $resourceClass The class to use to create the resource
* @param array $properties The properties to apply
* @return \Muffin\Webservice\Model\Resource
+ * @psalm-suppress LessSpecificReturnStatement
+ * @psalm-suppress MoreSpecificReturnType
+ * @psalm-suppress InvalidStringClass
*/
- protected function _createResource($resourceClass, array $properties = [])
+ protected function _createResource(string $resourceClass, array $properties = []): Resource
{
return new $resourceClass($properties, [
'markClean' => true,
@@ -335,17 +315,17 @@ protected function _createResource($resourceClass, array $properties = [])
/**
* Logs a query to the specified logger
*
- * @param \Muffin\Webservice\Query $query The query to log
+ * @param \Muffin\Webservice\Datasource\Query $query The query to log
* @param \Psr\Log\LoggerInterface $logger The logger instance to use
* @return void
*/
- protected function _logQuery(Query $query, LoggerInterface $logger)
+ protected function _logQuery(Query $query, LoggerInterface $logger): void
{
if (!$this->getDriver()->isQueryLoggingEnabled()) {
return;
}
- $logger->debug($query->endpoint()->getName(), [
+ $logger->debug($query->getEndpoint()->getName(), [
'params' => $query->where(),
]);
}
@@ -357,7 +337,7 @@ protected function _logQuery(Query $query, LoggerInterface $logger)
* @param array $results Array of results from the API
* @return \Muffin\Webservice\Model\Resource[] Array of resource objects
*/
- protected function _transformResults(Endpoint $endpoint, array $results)
+ protected function _transformResults(Endpoint $endpoint, array $results): array
{
$resources = [];
foreach ($results as $result) {
@@ -374,7 +354,7 @@ protected function _transformResults(Endpoint $endpoint, array $results)
* @param array $result The API result
* @return \Muffin\Webservice\Model\Resource
*/
- protected function _transformResource(Endpoint $endpoint, array $result)
+ protected function _transformResource(Endpoint $endpoint, array $result): Resource
{
$properties = [];
@@ -393,8 +373,8 @@ protected function _transformResource(Endpoint $endpoint, array $result)
public function __debugInfo()
{
return [
- 'driver' => $this->getDriver(),
- 'endpoint' => $this->getEndpoint(),
+ 'driver' => $this->_driver,
+ 'endpoint' => $this->_endpoint,
];
}
}
diff --git a/src/Webservice/WebserviceInterface.php b/src/Webservice/WebserviceInterface.php
index 496d45f..6c41616 100644
--- a/src/Webservice/WebserviceInterface.php
+++ b/src/Webservice/WebserviceInterface.php
@@ -1,8 +1,10 @@
loadPlugins(['Muffin/Webservice']);
+ }
+
/**
* Test that the plugins bootstrap is correctly registering the Endpoint
* repository type with the factory locator
@@ -38,7 +43,6 @@ public function testFactoryLocatorAddition()
{
$result = FactoryLocator::get('Endpoint');
- $this->assertInstanceOf(EndpointLocator::class, $result[0]);
- $this->assertSame('get', $result[1]);
+ $this->assertInstanceOf(EndpointLocator::class, $result);
}
}
diff --git a/tests/TestCase/ConnectionTest.php b/tests/TestCase/ConnectionTest.php
index 740e819..7347738 100644
--- a/tests/TestCase/ConnectionTest.php
+++ b/tests/TestCase/ConnectionTest.php
@@ -1,18 +1,21 @@
expectException(MissingDriverException::class);
+
new Connection([
'name' => 'test',
'service' => 'MissingDriver',
]);
}
- /**
- * @expectedException \Muffin\Webservice\Exception\MissingConnectionException
- */
public function testConstructorNoDriver()
{
+ $this->expectException(MissingConnectionException::class);
+
new Connection([
'name' => 'test',
]);
diff --git a/tests/TestCase/MarshallerTest.php b/tests/TestCase/MarshallerTest.php
index 5337308..fbad5d6 100644
--- a/tests/TestCase/MarshallerTest.php
+++ b/tests/TestCase/MarshallerTest.php
@@ -1,17 +1,18 @@
'test',
@@ -32,6 +33,7 @@ public function setUp()
'connection' => $connection,
'primaryKey' => 'id',
'displayField' => 'title',
+ 'alias' => 'TestEndpoint',
]);
$this->marshaller = new Marshaller($endpoint);
@@ -221,7 +223,7 @@ public function testMergeWithValidationErrors()
'title' => 'Testing',
'body' => 'Longer body',
]);
- $entity->isNew(false);
+ $entity->setNew(false);
$data = [
'title' => 'Changed the title',
diff --git a/tests/TestCase/Model/Endpoint/Schema/SchemaTest.php b/tests/TestCase/Model/Endpoint/Schema/SchemaTest.php
index dc8454d..b040ce4 100644
--- a/tests/TestCase/Model/Endpoint/Schema/SchemaTest.php
+++ b/tests/TestCase/Model/Endpoint/Schema/SchemaTest.php
@@ -1,8 +1,10 @@
schema = new TestSchema('test');
}
@@ -38,7 +40,7 @@ public function testColumns()
$this->assertEquals(['id', 'title', 'body'], $this->schema->columns());
}
- public function testColumn()
+ public function testGetColumn()
{
$this->assertEquals(
[
@@ -50,7 +52,7 @@ public function testColumn()
'comment' => null,
'primaryKey' => null,
],
- $this->schema->column('id')
+ $this->schema->getColumn('id')
);
}
@@ -124,7 +126,7 @@ public function testDefaultValues()
public function testPrimaryKey()
{
$this->schema->addColumn('id', ['type' => 'integer', 'primaryKey' => true]);
- $this->assertEquals(['id'], $this->schema->primaryKey());
+ $this->assertEquals(['id'], $this->schema->getPrimaryKey());
}
public function testOptions()
diff --git a/tests/TestCase/Model/EndpointLocatorTest.php b/tests/TestCase/Model/EndpointLocatorTest.php
index 7621528..e64e524 100644
--- a/tests/TestCase/Model/EndpointLocatorTest.php
+++ b/tests/TestCase/Model/EndpointLocatorTest.php
@@ -1,7 +1,12 @@
Locator = new EndpointLocator();
}
- public function tearDown()
+ public function tearDown(): void
{
parent::tearDown();
unset($this->Locator);
}
- public function testConfig()
- {
- $this->assertSame([], $this->Locator->getConfig());
-
- $configTest = ['foo' => 'bar'];
- $this->Locator->setConfig('test', $configTest);
- $this->assertSame($configTest, $this->Locator->getConfig('test'));
-
- $configExample = ['example' => true];
- $this->Locator->setConfig('example', $configExample);
- $this->assertSame($configExample, $this->Locator->getConfig('example'));
- }
-
- /**
- * @expectedException \RuntimeException
- * @expectedExceptionMessage You cannot configure "Test", it has already been constructed.
- */
- public function testSetConfigForExistingObject()
- {
- $this->Locator->get('Test', [
- 'registryAlias' => 'Test',
- 'connection' => 'test',
- ]);
-
- $this->Locator->setConfig('Test', ['foo' => 'bar']);
- }
-
- public function testSetConfigUsingAliasArray()
- {
- $multiAliasConfig = [
- 'Test' => ['foo' => 'bar'],
- 'Example' => ['foo' => 'bar'],
- ];
-
- $result = $this->Locator->setConfig($multiAliasConfig);
- $this->assertInstanceOf(EndpointLocator::class, $result);
-
- $this->assertSame($multiAliasConfig, $this->Locator->getConfig());
- }
-
public function testRemoveUsingExists()
{
/** @var \PHPUnit\Framework\MockObject\MockObject|\Muffin\Webservice\Model\Endpoint $first */
$first = $this->getMockBuilder(Endpoint::class)
->setConstructorArgs([['alias' => 'First']])
- ->setMethods(['getAlias'])
+ ->onlyMethods(['getAlias'])
->getMock();
$first->expects($this->any())
->method('getAlias')
->willReturn('First');
- /** @var \PHPUnit\Framework\MockObject\MockObject|\Muffin\Webservice\Model\Endpoint $first */
+ /** @var \PHPUnit\Framework\MockObject\MockObject|\Muffin\Webservice\Model\Endpoint $second */
$second = $this->getMockBuilder(Endpoint::class)
->setConstructorArgs([['alias' => 'Second']])
- ->setMethods(['getAlias'])
+ ->onlyMethods(['getAlias'])
->getMock();
$second->expects($this->any())
->method('getAlias')
@@ -101,7 +66,7 @@ public function testGet()
/** @var \Muffin\Webservice\Model\Endpoint $first */
$first = $this->getMockBuilder(Endpoint::class)
->setConstructorArgs([['alias' => 'First']])
- ->setMethods(['getAlias'])
+ ->onlyMethods(['getAlias'])
->getMock();
$first->expects($this->any())
->method('getAlias')
@@ -113,12 +78,23 @@ public function testGet()
$this->assertSame($first, $result);
}
- /**
- * @expectedException \RuntimeException
- * @expectedExceptionMessage You cannot configure "First", it already exists in the locator.
- */
+ public function testGetException()
+ {
+ $this->expectException(MissingDatasourceConfigException::class);
+ $this->expectExceptionMessage(
+ 'The datasource configuration "non-existent" was not found.'
+ . ' You can override Endpoint::defaultConnectionName() to return the connection name you want.'
+ );
+
+ $locator = new EndpointLocator();
+ $locator->get('Foo', ['className' => TestEndpoint::class, 'connection' => 'non-existent']);
+ }
+
public function testGetWithExistingObject()
{
+ $this->expectException(RuntimeException::class);
+ $this->expectExceptionMessage('You cannot configure "First", it already exists in the registry.');
+
$result = $this->Locator->get('First', [
'className' => Endpoint::class,
'registryAlias' => 'First',
@@ -155,7 +131,7 @@ public function testClear()
/** @var \Muffin\Webservice\Model\Endpoint $first */
$first = $this->getMockBuilder(Endpoint::class)
->setConstructorArgs([['alias' => 'First']])
- ->setMethods(['getAlias'])
+ ->onlyMethods(['getAlias'])
->getMock();
$first->expects($this->any())
->method('getAlias')
diff --git a/tests/TestCase/Model/EndpointRegistryTest.php b/tests/TestCase/Model/EndpointRegistryTest.php
deleted file mode 100644
index 24ceb02..0000000
--- a/tests/TestCase/Model/EndpointRegistryTest.php
+++ /dev/null
@@ -1,127 +0,0 @@
- new Connection([
- 'name' => 'test',
- 'service' => 'test',
- ]),
- ]);
-
- $this->assertInstanceOf(Endpoint::class, $result);
- $this->assertEquals('test', $result->endpoint());
- }
-
- /**
- * Ensure that if you try and set the options for an already configured Endpoint instance an
- * exception is thrown
- *
- * @expectedException \RuntimeException
- * @expectedExceptionMessage You cannot configure "Test", it already exists in the registry.
- */
- public function testReconfiguringExistingInstance()
- {
- $result = EndpointRegistry::get('Test', [
- 'connection' => new Connection([
- 'name' => 'test',
- 'service' => 'test',
- ]),
- 'displayField' => 'foo',
- ]);
-
- $this->assertInstanceOf(Endpoint::class, $result);
- $this->assertEquals('test', $result->endpoint());
-
- $result = EndpointRegistry::get('Test', [
- 'displayField' => 'foo',
- ]);
- }
-
- public function testGettingSameInstance()
- {
- $result = EndpointRegistry::get('Test', [
- 'connection' => new Connection([
- 'name' => 'test',
- 'service' => 'test',
- ]),
- ]);
-
- $this->assertInstanceOf(Endpoint::class, $result);
- $this->assertEquals('test', $result->endpoint());
-
- $result = EndpointRegistry::get('Test');
-
- $this->assertInstanceOf(Endpoint::class, $result);
- $this->assertEquals('test', $result->endpoint());
- }
-
- public function testGetInstanceWithNoEndpointName()
- {
- $result = EndpointRegistry::get('Test', [
- 'connection' => new Connection([
- 'name' => 'test',
- 'service' => 'test',
- ]),
- 'className' => 'UnfindableClass',
- ]);
-
- $this->assertInstanceOf(Endpoint::class, $result);
- $this->assertEquals('unfindable_class', $result->endpoint());
- }
-
- public function testRemovingInstance()
- {
- $result = EndpointRegistry::get('Test', [
- 'connection' => new Connection([
- 'name' => 'test',
- 'service' => 'test',
- ]),
- ]);
-
- $this->assertInstanceOf(Endpoint::class, $result);
-
- EndpointRegistry::remove('Test');
-
- $ref = new \ReflectionClass(EndpointRegistry::class);
- $this->assertEmpty($ref->getStaticProperties()['_instances']);
- $this->assertEmpty($ref->getStaticProperties()['_options']);
- }
-
- public function testClearing()
- {
- $result = EndpointRegistry::get('Test', [
- 'connection' => new Connection([
- 'name' => 'test',
- 'service' => 'test',
- ]),
- ]);
-
- $this->assertInstanceOf(Endpoint::class, $result);
-
- EndpointRegistry::clear();
-
- $ref = new \ReflectionClass(EndpointRegistry::class);
- $this->assertEmpty($ref->getStaticProperties()['_instances']);
- $this->assertEmpty($ref->getStaticProperties()['_options']);
- }
-}
diff --git a/tests/TestCase/Model/EndpointTest.php b/tests/TestCase/Model/EndpointTest.php
index b19fe8c..8d26ce9 100644
--- a/tests/TestCase/Model/EndpointTest.php
+++ b/tests/TestCase/Model/EndpointTest.php
@@ -1,36 +1,41 @@
endpoint->find();
- $this->assertInstanceOf('\Muffin\Webservice\Query', $query);
+ $this->assertInstanceOf(Query::class, $query);
}
public function testFindByTitle()
@@ -123,11 +128,10 @@ public function testExists()
$this->assertFalse($this->endpoint->exists(['id' => 10]));
}
- /**
- * @expectedException \Cake\Datasource\Exception\RecordNotFoundException
- */
public function testGetNonExisting()
{
+ $this->expectException(RecordNotFoundException::class);
+
$this->endpoint->get(10);
}
@@ -175,11 +179,10 @@ public function testUpdatingSave()
$this->assertEquals($newResource->title, 'New ORM for webservices');
}
- /**
- * @expectedException \Cake\Datasource\Exception\RecordNotFoundException
- */
public function testDelete()
{
+ $this->expectException(RecordNotFoundException::class);
+
$resource = $this->endpoint->get(2);
$this->assertTrue($this->endpoint->delete($resource));
@@ -200,10 +203,13 @@ public function testDeleteAll()
public function testNewEntity()
{
- $this->assertEquals(new Resource([
+ $resource = new Resource([
'title' => 'New entity',
'body' => 'New entity body',
- ]), $this->endpoint->newEntity([
+ ]);
+ $resource->setSource('test');
+
+ $this->assertEquals($resource, $this->endpoint->newEntity([
'title' => 'New entity',
'body' => 'New entity body',
]));
@@ -211,15 +217,21 @@ public function testNewEntity()
public function testNewEntities()
{
+ $resource1 = new Resource([
+ 'title' => 'New entity',
+ 'body' => 'New entity body',
+ ]);
+ $resource1->setSource('test');
+
+ $resource2 = new Resource([
+ 'title' => 'Second new entity',
+ 'body' => 'Second new entity body',
+ ]);
+ $resource2->setSource('test');
+
$this->assertEquals([
- new Resource([
- 'title' => 'New entity',
- 'body' => 'New entity body',
- ]),
- new Resource([
- 'title' => 'Second new entity',
- 'body' => 'Second new entity body',
- ]),
+ $resource1,
+ $resource2,
], $this->endpoint->newEntities([
[
'title' => 'New entity',
@@ -257,7 +269,6 @@ public function testAliasField()
public function testConnection()
{
$endpoint = new Endpoint(['endpoint' => 'users']);
- $this->assertNull($endpoint->getConnection());
$endpoint->setConnection($this->connection);
$this->assertSame($this->connection, $endpoint->getConnection());
}
@@ -377,7 +388,7 @@ public function testSchema()
$schema = ['id' => ['type' => 'integer']];
$endpoint->setSchema($schema);
$this->assertEquals(
- new \Muffin\Webservice\Schema('another', $schema),
+ new Schema('another', $schema),
$endpoint->getSchema()
);
}
@@ -391,7 +402,7 @@ public function testFindWithSelectAndWhere()
->select($fields)
->where($conditions);
- $this->assertInstanceOf('\Muffin\Webservice\Query', $query);
+ $this->assertInstanceOf(Query::class, $query);
$this->assertSame($fields, $query->clause('select'));
$this->assertSame($conditions, $query->clause('where'));
}
@@ -414,14 +425,13 @@ public function testConstructorResourceClass()
'resourceClass' => 'Example',
]);
- $this->assertSame('Muffin\Webservice\Test\test_app\Model\Resource\Example', $endpoint->getResourceClass());
+ $this->assertSame('TestApp\Model\Resource\Example', $endpoint->getResourceClass());
}
- /**
- * @expectedException \Muffin\Webservice\Exception\MissingResourceClassException
- */
public function testSetResourceMissingClass()
{
+ $this->expectException(MissingResourceClassException::class);
+
new Endpoint([
'name' => 'example',
'resourceClass' => 'Missing',
@@ -433,24 +443,6 @@ public function testHasField()
$this->assertTrue($this->endpoint->hasField('title'));
}
- /**
- * Fake an incorrect return of the schema to check the exception
- *
- * @expectedException \Muffin\Webservice\Exception\UnexpectedDriverException
- */
- public function testGetPrimaryKeyException()
- {
- $endpoint = $this->getMockBuilder(Endpoint::class)
- ->setMethods(['getSchema'])
- ->getMock();
-
- $endpoint->expects($this->once())
- ->method('getSchema')
- ->willReturn(false);
-
- $endpoint->getPrimaryKey();
- }
-
public function testSetWebservice()
{
$testWebservice = new TestWebservice();
@@ -460,34 +452,16 @@ public function testSetWebservice()
$this->assertInstanceOf(WebserviceInterface::class, $this->endpoint->getWebservice());
}
- /**
- * @expectedException \Muffin\Webservice\Exception\UnexpectedDriverException
- */
- public function testSetWebserviceException()
- {
- $endpoint = $this->getMockBuilder(Endpoint::class)
- ->setMethods(['getConnection'])
- ->getMock();
-
- $endpoint->expects($this->once())
- ->method('getConnection')
- ->willReturn(false);
-
- $testWebservice = new TestWebservice();
- $endpoint->setWebservice('test', $testWebservice);
- }
-
public function testHasFinder()
{
$this->assertTrue($this->endpoint->hasFinder('Examples'));
$this->assertFalse($this->endpoint->hasFinder('Missing'));
}
- /**
- * @expectedException \BadMethodCallException
- */
public function testCallMissingFinder()
{
+ $this->expectException(BadMethodCallException::class);
+
$query = $this->getMockBuilder(Query::class)
->setConstructorArgs([new TestWebservice(), $this->endpoint])
->getMock();
@@ -498,8 +472,8 @@ public function testCallMissingFinder()
public function testDebugInfo()
{
$expected = [
- 'registryAlias' => null,
- 'alias' => null,
+ 'registryAlias' => 'test',
+ 'alias' => 'test',
'endpoint' => 'test',
'resourceClass' => 'Muffin\\Webservice\\Model\\Resource',
'defaultConnection' => 'test_app',
@@ -515,6 +489,6 @@ public function testGetResourceWithCustomResource()
{
$endpoint = new ExampleEndpoint();
- $this->assertEquals('Muffin\Webservice\Test\test_app\Model\Resource\Example', $endpoint->getResourceClass());
+ $this->assertEquals('TestApp\Model\Resource\Example', $endpoint->getResourceClass());
}
}
diff --git a/tests/TestCase/Model/ResourceTest.php b/tests/TestCase/Model/ResourceTest.php
index e3e4264..7a9e888 100644
--- a/tests/TestCase/Model/ResourceTest.php
+++ b/tests/TestCase/Model/ResourceTest.php
@@ -1,14 +1,13 @@
$endpoint,
+ 'source' => 'TestEndPoint',
]);
- $this->assertEquals($endpoint, $resource->getSource());
+ $this->assertEquals('TestEndPoint', $resource->getSource());
}
public function testConstructUseSettersOff()
diff --git a/tests/TestCase/QueryTest.php b/tests/TestCase/QueryTest.php
index 0372239..6fa31cc 100644
--- a/tests/TestCase/QueryTest.php
+++ b/tests/TestCase/QueryTest.php
@@ -1,18 +1,19 @@
assertNull($this->query->action());
+ $this->assertNull($this->query->clause('action'));
$this->assertEquals($this->query, $this->query->action(Query::ACTION_READ));
- $this->assertEquals(Query::ACTION_READ, $this->query->action());
+ $this->assertEquals(Query::ACTION_READ, $this->query->clause('action'));
}
public function testActionMethods()
{
$this->assertEquals($this->query, $this->query->create());
- $this->assertEquals(Query::ACTION_CREATE, $this->query->action());
+ $this->assertEquals(Query::ACTION_CREATE, $this->query->clause('action'));
$this->assertEquals($this->query, $this->query->read());
- $this->assertEquals(Query::ACTION_READ, $this->query->action());
+ $this->assertEquals(Query::ACTION_READ, $this->query->clause('action'));
$this->assertEquals($this->query, $this->query->update());
- $this->assertEquals(Query::ACTION_UPDATE, $this->query->action());
+ $this->assertEquals(Query::ACTION_UPDATE, $this->query->clause('action'));
$this->assertEquals($this->query, $this->query->delete());
- $this->assertEquals(Query::ACTION_DELETE, $this->query->action());
+ $this->assertEquals(Query::ACTION_DELETE, $this->query->clause('action'));
}
public function testAliasField()
@@ -86,8 +87,8 @@ public function testApplyOptions()
],
'customOption' => 'value',
]));
- $this->assertEquals(1, $this->query->page());
- $this->assertEquals(2, $this->query->limit());
+ $this->assertEquals(1, $this->query->clause('page'));
+ $this->assertEquals(2, $this->query->clause('limit'));
$this->assertEquals([
'field' => 'ASC',
], $this->query->clause('order'));
@@ -98,21 +99,20 @@ public function testApplyOptions()
public function testFind()
{
- $this->query->endpoint()->setPrimaryKey('id');
- $this->query->endpoint()->setDisplayField('title');
+ $this->query->getEndpoint()->setPrimaryKey('id');
+ $this->query->getEndpoint()->setDisplayField('title');
$this->assertEquals($this->query, $this->query->find('list'));
$debugInfo = $this->query->__debugInfo();
- $this->assertInternalType('callable', $debugInfo['formatters'][0]);
+ $this->assertIsCallable($debugInfo['formatters'][0]);
}
- /**
- * @expectedException \UnexpectedValueException
- */
public function testSetInvalidAction()
{
+ $this->expectException(UnexpectedValueException::class);
+
$this->query->read();
$this->query->set([]);
@@ -166,11 +166,12 @@ public function testOrder()
public function testExecuteTwice()
{
$mockWebservice = $this
- ->getMockBuilder('\Muffin\Webservice\Test\test_app\Webservice\StaticWebservice')
- ->setMethods([
+ ->getMockBuilder('\TestApp\Webservice\StaticWebservice')
+ ->onlyMethods([
'execute',
])
->getMock();
+
$mockWebservice->expects($this->once())
->method('execute')
->will($this->returnValue(new ResultSet([
@@ -187,7 +188,10 @@ public function testExecuteTwice()
'title' => 'Webservices',
]),
], 3)));
- $this->query->webservice($mockWebservice);
+
+ $this->query
+ ->setWebservice($mockWebservice)
+ ->action(Query::ACTION_READ);
$this->query->execute();
@@ -265,13 +269,13 @@ public function testSelectWithString()
public function testSelectWithExpression()
{
- $exp = new Comparison('upvotes', 50, 'integer', '>=');
+ $exp = new ComparisonExpression('upvotes', 50, 'integer', '>=');
$this->query->select($exp);
- /** @var Comparison $comparisonClause */
+ /** @var ComparisonExpression $comparisonClause */
$comparisonClause = $this->query->clause('select')[0];
- $this->assertInstanceOf(Comparison::class, $comparisonClause);
+ $this->assertInstanceOf(ComparisonExpression::class, $comparisonClause);
$this->assertEquals(50, $comparisonClause->getValue());
$this->assertEquals('>=', $comparisonClause->getOperator());
}
@@ -291,7 +295,7 @@ public function testSelectWithCallable()
/**
* @inheritDoc
*/
- public function tearDown()
+ public function tearDown(): void
{
parent::tearDown();
diff --git a/tests/TestCase/ResultSetTest.php b/tests/TestCase/ResultSetTest.php
index aaa46ee..eb72e53 100644
--- a/tests/TestCase/ResultSetTest.php
+++ b/tests/TestCase/ResultSetTest.php
@@ -1,14 +1,14 @@
assertInternalType('string', serialize($this->resultSet));
+ $this->assertIsString(serialize($this->resultSet));
}
public function testUnserialize()
{
$unserialized = unserialize(serialize($this->resultSet));
- $this->assertInstanceOf('\Muffin\Webservice\ResultSet', $unserialized);
+ $this->assertInstanceOf(ResultSet::class, $unserialized);
}
/**
* @inheritDoc
*/
- public function tearDown()
+ public function tearDown(): void
{
parent::tearDown();
diff --git a/tests/TestCase/Webservice/WebserviceTest.php b/tests/TestCase/Webservice/WebserviceTest.php
index d81ee1b..8dca7d7 100644
--- a/tests/TestCase/Webservice/WebserviceTest.php
+++ b/tests/TestCase/Webservice/WebserviceTest.php
@@ -1,16 +1,18 @@
assertEquals('/articles/16-10-2015', $this->webservice->nestedResource([
'date' => '16-10-2015',
]));
- $this->assertFalse($this->webservice->nestedResource([
+ $this->assertNull($this->webservice->nestedResource([
'title' => 'hello',
]));
}
- /**
- * @expectedException \UnexpectedValueException
- * @expectedExceptionMessage No driver has been defined
- */
- public function testExecuteWithoutDriver()
- {
- $webservice = new TestWebservice();
-
- $query = new Query($webservice, new Endpoint());
-
- $webservice->execute($query);
- }
-
public function testExecuteLoggingWithLogger()
{
$logger = $this->getMockBuilder('Cake\Log\Engine\ConsoleLog')
- ->setMethods([
+ ->onlyMethods([
'debug',
])
->getMock();
@@ -105,7 +94,7 @@ public function testExecuteLoggingWithLogger()
public function testExecuteLoggingWithLoggerEnabled()
{
$logger = $this->getMockBuilder('Cake\Log\Engine\ConsoleLog')
- ->setMethods([
+ ->onlyMethods([
'debug',
])
->getMock();
@@ -121,48 +110,44 @@ public function testExecuteLoggingWithLoggerEnabled()
$this->webservice->execute($query);
}
- /**
- * @expectedException \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException
- * @expectedExceptionMessage Webservice Muffin\Webservice\Test\test_app\Webservice\TestWebservice does not implement _executeCreateQuery
- */
public function testExecuteWithoutCreate()
{
+ $this->expectException(UnimplementedWebserviceMethodException::class);
+ $this->expectExceptionMessage('Webservice TestApp\Webservice\TestWebservice does not implement _executeCreateQuery');
+
$query = new Query($this->webservice, new Endpoint());
$query->create();
$this->webservice->execute($query);
}
- /**
- * @expectedException \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException
- * @expectedExceptionMessage Webservice Muffin\Webservice\Test\test_app\Webservice\TestWebservice does not implement _executeReadQuery
- */
public function testExecuteWithoutRead()
{
+ $this->expectException(UnimplementedWebserviceMethodException::class);
+ $this->expectExceptionMessage('Webservice TestApp\Webservice\TestWebservice does not implement _executeReadQuery');
+
$query = new Query($this->webservice, new Endpoint());
$query->read();
$this->webservice->execute($query);
}
- /**
- * @expectedException \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException
- * @expectedExceptionMessage Webservice Muffin\Webservice\Test\test_app\Webservice\TestWebservice does not implement _executeUpdateQuery
- */
public function testExecuteWithoutUpdate()
{
+ $this->expectException(UnimplementedWebserviceMethodException::class);
+ $this->expectExceptionMessage('Webservice TestApp\Webservice\TestWebservice does not implement _executeUpdateQuery');
+
$query = new Query($this->webservice, new Endpoint());
$query->update();
$this->webservice->execute($query);
}
- /**
- * @expectedException \Muffin\Webservice\Exception\UnimplementedWebserviceMethodException
- * @expectedExceptionMessage Webservice Muffin\Webservice\Test\test_app\Webservice\TestWebservice does not implement _executeDeleteQuery
- */
public function testExecuteWithoutDelete()
{
+ $this->expectException(UnimplementedWebserviceMethodException::class);
+ $this->expectExceptionMessage('Webservice TestApp\Webservice\TestWebservice does not implement _executeDeleteQuery');
+
$query = new Query($this->webservice, new Endpoint());
$query->delete();
@@ -171,7 +156,7 @@ public function testExecuteWithoutDelete()
public function testCreateResource()
{
- /* @var \Muffin\Webservice\Model\Resource $resource */
+ /** @var \Muffin\Webservice\Model\Resource $resource */
$resource = $this->webservice->createResource('\Muffin\Webservice\Model\Resource', []);
$this->assertInstanceOf('\Muffin\Webservice\Model\Resource', $resource);
@@ -199,7 +184,7 @@ public function testTransformResults()
],
]);
- $this->assertInternalType('array', $resources);
+ $this->assertIsArray($resources);
$this->assertInstanceOf('\Muffin\Webservice\Model\Resource', $resources[0]);
}
@@ -214,17 +199,18 @@ public function testDescribe()
public function testDebugInfo()
{
- $this->assertEquals([
+ $expected = [
'driver' => $this->webservice->getDriver(),
- 'endpoint' => $this->webservice->getEndpoint(),
- ], $this->webservice->__debugInfo());
+ 'endpoint' => null,
+ ];
+
+ $this->assertEquals($expected, $this->webservice->__debugInfo());
}
- /**
- * @expectedException \Muffin\Webservice\Exception\MissingEndpointSchemaException
- */
public function testDescribeException()
{
+ $this->expectException(MissingEndpointSchemaException::class);
+
$this->webservice->describe('example');
}
}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 7affa7d..76891ea 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -1,4 +1,6 @@
register();
-
-$loader->addNamespace('TestApp', APP);
-$loader->addNamespace('SomeVendor\SomePlugin', APP . 'plugins' . DS . 'SomeVendor' . DS . 'SomePlugin' . DS . 'src');
-$loader->addNamespace('TestPlugin', APP . 'plugins' . DS . 'TestPlugin' . DS . 'src');
-
require_once CORE_PATH . 'config/bootstrap.php';
date_default_timezone_set('UTC');
@@ -47,7 +44,7 @@
Configure::write('debug', true);
Configure::write('App', [
- 'namespace' => 'Muffin\\Webservice\\Test\\test_app',
+ 'namespace' => 'TestApp',
'encoding' => 'UTF-8',
'base' => false,
'baseUrl' => false,
@@ -89,8 +86,10 @@
putenv('DB_DSN=sqlite:///:memory:');
}
-ConnectionManager::setConfig('test', ['url' => getenv('DB_DSN')]);
-ConnectionManager::setConfig('test_webservice', ['url' => getenv('DB_DSN')]);
+ConnectionManager::setConfig('test', [
+ 'className' => Connection::class,
+ 'driver' => TestDriver::class,
+] + ConnectionManager::parseDsn(env('DB_DSN')));
Log::setConfig([
'debug' => [
@@ -104,8 +103,3 @@
'file' => 'error',
],
]);
-
-Plugin::getCollection()->add(new \Muffin\Webservice\Plugin());
-require Plugin::getCollection()->get('Muffin/Webservice')->getConfigPath() . 'bootstrap.php';
-
-loadPHPUnitAliases();
diff --git a/tests/test_app/Webservice/Driver/Test.php b/tests/test_app/Webservice/Driver/Test.php
deleted file mode 100644
index ce35fa7..0000000
--- a/tests/test_app/Webservice/Driver/Test.php
+++ /dev/null
@@ -1,27 +0,0 @@
-_createResource($resourceClass, $properties);
diff --git a/tests/test_app/plugins/TestPlugin/src/Webservice/Driver/TestPlugin.php b/tests/test_app/plugins/TestPlugin/src/Webservice/Driver/TestPlugin.php
index d5350ca..6d3fb1b 100644
--- a/tests/test_app/plugins/TestPlugin/src/Webservice/Driver/TestPlugin.php
+++ b/tests/test_app/plugins/TestPlugin/src/Webservice/Driver/TestPlugin.php
@@ -1,18 +1,18 @@
_createResource($resourceClass, $properties);
diff --git a/tests/test_app/Model/Endpoint/AppEndpoint.php b/tests/test_app/src/Model/Endpoint/AppEndpoint.php
similarity index 59%
rename from tests/test_app/Model/Endpoint/AppEndpoint.php
rename to tests/test_app/src/Model/Endpoint/AppEndpoint.php
index e7e0581..601d1d5 100644
--- a/tests/test_app/Model/Endpoint/AppEndpoint.php
+++ b/tests/test_app/src/Model/Endpoint/AppEndpoint.php
@@ -1,10 +1,10 @@
addColumn('id', [
'type' => 'int',
diff --git a/tests/test_app/Model/Endpoint/TestEndpoint.php b/tests/test_app/src/Model/Endpoint/TestEndpoint.php
similarity index 79%
rename from tests/test_app/Model/Endpoint/TestEndpoint.php
rename to tests/test_app/src/Model/Endpoint/TestEndpoint.php
index 86f03fd..f48fbcd 100644
--- a/tests/test_app/Model/Endpoint/TestEndpoint.php
+++ b/tests/test_app/src/Model/Endpoint/TestEndpoint.php
@@ -1,28 +1,27 @@
requirePresence('title')
- ->notEmpty('title')
+ ->notEmptyString('title')
->requirePresence('body')
- ->notEmpty('body')
+ ->notEmptyString('body')
->minLength('body', 5, 'Must be 5 characters or longer');
return $validator;
diff --git a/tests/test_app/Model/Resource/Example.php b/tests/test_app/src/Model/Resource/Example.php
similarity index 58%
rename from tests/test_app/Model/Resource/Example.php
rename to tests/test_app/src/Model/Resource/Example.php
index 3bd4b82..1dd5b6e 100644
--- a/tests/test_app/Model/Resource/Example.php
+++ b/tests/test_app/src/Model/Resource/Example.php
@@ -1,10 +1,10 @@
resources[$index],
], 1);
}
- if (isset($query->where()[$query->endpoint()->aliasField('title')])) {
+ if (isset($query->where()[$query->getEndpoint()->aliasField('title')])) {
$resources = [];
foreach ($this->resources as $resource) {
- if ($resource->title !== $query->where()[$query->endpoint()->aliasField('title')]) {
+ if ($resource->title !== $query->where()[$query->getEndpoint()->aliasField('title')]) {
continue;
}
@@ -109,7 +108,7 @@ protected function _executeDeleteQuery(Query $query, array $options = [])
unset($this->resources[$this->conditionsToIndex($conditions)]);
- return ($exists) ? 1 : 0;
+ return $exists ? 1 : 0;
} elseif (is_array($conditions['id'])) {
$deleted = 0;
diff --git a/tests/test_app/Webservice/Logger.php b/tests/test_app/src/Webservice/Logger.php
similarity index 95%
rename from tests/test_app/Webservice/Logger.php
rename to tests/test_app/src/Webservice/Logger.php
index 5b4dedd..36e0c55 100644
--- a/tests/test_app/Webservice/Logger.php
+++ b/tests/test_app/src/Webservice/Logger.php
@@ -1,6 +1,7 @@
[
diff --git a/tests/test_app/Webservice/TestWebservice.php b/tests/test_app/src/Webservice/TestWebservice.php
similarity index 88%
rename from tests/test_app/Webservice/TestWebservice.php
rename to tests/test_app/src/Webservice/TestWebservice.php
index 331ad64..c4e8e59 100644
--- a/tests/test_app/Webservice/TestWebservice.php
+++ b/tests/test_app/src/Webservice/TestWebservice.php
@@ -1,13 +1,13 @@
_createResource($resourceClass, $properties);