From 4277034bd54f23d72bc2ad66022a3ed294ff2768 Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sat, 30 Dec 2017 21:59:20 +0000 Subject: [PATCH 01/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Collection/Devices.php | 6 ++++-- src/IKEA/Tradfri/Collection/Groups.php | 6 ++++-- src/IKEA/Tradfri/Collection/Lightbulbs.php | 6 ++++-- src/IKEA/Tradfri/Command/CommandAbstract.php | 5 ++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/IKEA/Tradfri/Collection/Devices.php b/src/IKEA/Tradfri/Collection/Devices.php index 494e8a18..3ae39356 100644 --- a/src/IKEA/Tradfri/Collection/Devices.php +++ b/src/IKEA/Tradfri/Collection/Devices.php @@ -42,11 +42,13 @@ public function getDevices(): array } /** - * Specify data which should be serialized to JSON + * Specify data which should be serialized to JSON. * * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. + * which is a value of any type other than a resource. + * * @since 5.4.0 */ public function jsonSerialize() diff --git a/src/IKEA/Tradfri/Collection/Groups.php b/src/IKEA/Tradfri/Collection/Groups.php index 4c561193..2dd7c213 100644 --- a/src/IKEA/Tradfri/Collection/Groups.php +++ b/src/IKEA/Tradfri/Collection/Groups.php @@ -37,11 +37,13 @@ public function addGroup(Device $group) } /** - * Specify data which should be serialized to JSON + * Specify data which should be serialized to JSON. * * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. + * which is a value of any type other than a resource. + * * @since 5.4.0 */ public function jsonSerialize() diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index 18b7cd71..e2382986 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -56,11 +56,13 @@ public function getActive() } /** - * Specify data which should be serialized to JSON + * Specify data which should be serialized to JSON. * * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. + * which is a value of any type other than a resource. + * * @since 5.4.0 */ public function jsonSerialize() diff --git a/src/IKEA/Tradfri/Command/CommandAbstract.php b/src/IKEA/Tradfri/Command/CommandAbstract.php index 3fab814f..d4950f96 100644 --- a/src/IKEA/Tradfri/Command/CommandAbstract.php +++ b/src/IKEA/Tradfri/Command/CommandAbstract.php @@ -1,12 +1,11 @@ Date: Sat, 30 Dec 2017 23:38:32 +0100 Subject: [PATCH 02/73] - added slack to travis config, and travis lint --- .travis.yml | 73 ++++++++++++++++++++++++++--------------------------- README.md | 2 +- 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/.travis.yml b/.travis.yml index 851de760..74159b12 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,52 +1,51 @@ language: php - sudo: false - cache: directories: - - $HOME/.composer/cache - - $HOME/.local - + - "$HOME/.composer/cache" + - "$HOME/.local" env: - RUN_WITH_COVERAGE=false - + global: + - CC_TEST_REPORTER_ID=ff208c24a9f196d9bfc66a49f6bf8592a07e82c6eed47ea481e299c4c648e393 + - RUN_WITH_COVERAGE=false matrix: fast_finish: true include: - - php: 7.0 - env: EXECUTE_CS_CHECK=true RUN_WITH_COVERAGE=true PATH="$HOME/.local/bin:$PATH" - - php: 7.0 - - php: 7.1 - - php: 7.2 - - php: nightly - - php: hhvm - + - php: 7.0 + env: EXECUTE_CS_CHECK=true RUN_WITH_COVERAGE=true PATH="$HOME/.local/bin:$PATH" + - php: 7.0 + - php: 7.1 + - php: 7.2 + - php: nightly + - php: hhvm allow_failures: - - php: hhvm - - php: nightly - + - php: hhvm + - php: nightly before_install: - - rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini - - travis_retry composer self-update - - git config --global user.name travis-ci - - git config --global user.email travis@webproject.xyz - - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter; fi - - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then chmod +x ./cc-test-reporter; fi - - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then ./cc-test-reporter before-build; fi - +- rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini +- travis_retry composer self-update +- git config --global user.name travis-ci +- git config --global user.email travis@webproject.xyz +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 + > ./cc-test-reporter; fi +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then chmod +x ./cc-test-reporter; fi +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then ./cc-test-reporter before-build; fi install: - - travis_retry composer update --no-interaction --prefer-source - - phpunit --version - +- travis_retry composer update --no-interaction --prefer-source +- phpunit --version script: - - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then composer cs-check; fi - - if [[ $RUN_WITH_COVERAGE != 'true' ]]; then composer run-tests; fi - - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then echo zend_extension=xdebug.so >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini || return 0; fi - - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then composer build-coverage; fi - - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) -Z ; fi - +- if [[ $EXECUTE_CS_CHECK == 'true' ]]; then composer cs-check; fi +- if [[ $RUN_WITH_COVERAGE != 'true' ]]; then composer run-tests; fi +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then echo zend_extension=xdebug.so >> ~/.phpenv/versions/$(phpenv + version-name)/etc/conf.d/xdebug.ini || return 0; fi +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then composer build-coverage; fi +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) + -Z ; fi after_script: - - if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./cc-test-reporter after-build -t=clover tests/_output/coverage.xml --exit-code $TRAVIS_TEST_RESULT ; fi - +- if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then + ./cc-test-reporter after-build -t=clover tests/_output/coverage.xml --exit-code + $TRAVIS_TEST_RESULT ; fi notifications: email: false + slack: + secure: JqH3MeraT5uwvV+Qh+wzjIbo0y7A7ltisIgnJjdT94EVjI94p52HHMB3ABh5/aJ/KMXtcFNov9x5G60+6UztOqHLNYiToOy3PACtz99yEOt5aniAtut9Ne9xaII06KMErCt04cYMl0tTBYiXvzc16GThZ8tEnx+2Hmr5Craj2qn90sWSFMMi2zpyJWAo9UU9cRgYuVy/KGP3Qji3GUe7yXpDMZD4BT5DFr0nr5P/CiJZnnIzseB6LP8A/t9FF2wYnVTyjB9uR+q+A40s7dZ2SSxN/PCi853acJDcozg5uxXaA4RMFVBILzGrWncLl72rxayq8fg4376rEFCFcQBv3lSZN2RwZVbiZIukZ6n3ZDoe+nXJ/9irBH/8drJuDUssIlVVzu8oZ0OzCmpmvpCovy7XToUiTlkEQYc4nvTMgVa9GlmjhevEDLSsS+1qouFmlb8oXsh2rBhRVXUMXTN6VxD3uDFXYvswhcmGNYA5xkH0f1VrgYBqAYjUgKQ1H05Y5zguMSdbcPQsMJd4ZsI8Z/vEZcPoonfCD+nAH0HTVxxD4JVN/4H3lfaF+rNelBMZN/s5JX8DF3+5FQqFqVRyCZ6S+7CMY2M7YZbNx+rnxmm3J+th93p4AWHE1TRJbsiZhStDm9IpUDDoxvng8ebT2bEyLRITVmZ1Hld//AN3/OI= diff --git a/README.md b/README.md index 381f7fec..a0ec797b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ php api to control Ikea smart lights (tradfri) [![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api.svg?branch=master)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api) [![Test Coverage](https://api.codeclimate.com/v1/badges/d736384567fcf3e2b6ed/test_coverage)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/test_coverage) [![StyleCI](https://styleci.io/repos/109524603/shield?branch=master)](https://styleci.io/repos/109524603) - [![Maintainability](https://api.codeclimate.com/v1/badges/d736384567fcf3e2b6ed/maintainability)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/maintainability) [![Code Climate](https://img.shields.io/codeclimate/github/WebProject-xyz/ikea-tradfri-php-api.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/) [![Code Climate](https://img.shields.io/codeclimate/issues//github/WebProject-xyz/ikea-tradfri-php-api.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/) @@ -20,6 +19,7 @@ php api to control Ikea smart lights (tradfri) #### Develop: [![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api.svg?branch=develop)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api) [![StyleCI](https://styleci.io/repos/109524603/shield?branch=develop)](https://styleci.io/repos/109524603) +[![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api/branch/develop/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api) ## Example usage: From e64eac249244892868f4ccab41d5f502863f26c4 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 30 Dec 2017 23:51:24 +0100 Subject: [PATCH 03/73] -fixed coverage report path --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 74159b12..cec955db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ script: -Z ; fi after_script: - if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then - ./cc-test-reporter after-build -t=clover tests/_output/coverage.xml --exit-code + ./cc-test-reporter after-build -t=clover /home/travis/build/WebProject-xyz/ikea-tradfri-php/tests/_output/report.xml --exit-code $TRAVIS_TEST_RESULT ; fi notifications: email: false From e07debcb8b02b1546aedd7fa15ef3e5ee0ed0065 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 30 Dec 2017 23:54:51 +0100 Subject: [PATCH 04/73] - badges --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a0ec797b..a2a0f827 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,17 @@ php api to control Ikea smart lights (tradfri) #### Stable: [![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api.svg?branch=master)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api) -[![Test Coverage](https://api.codeclimate.com/v1/badges/d736384567fcf3e2b6ed/test_coverage)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/test_coverage) -[![StyleCI](https://styleci.io/repos/109524603/shield?branch=master)](https://styleci.io/repos/109524603) -[![Maintainability](https://api.codeclimate.com/v1/badges/d736384567fcf3e2b6ed/maintainability)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/maintainability) [![Code Climate](https://img.shields.io/codeclimate/github/WebProject-xyz/ikea-tradfri-php-api.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/) [![Code Climate](https://img.shields.io/codeclimate/issues//github/WebProject-xyz/ikea-tradfri-php-api.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/) +[![Maintainability](https://api.codeclimate.com/v1/badges/c3a38c872794aa6a83c9/maintainability)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/maintainability) +[![Test Coverage](https://api.codeclimate.com/v1/badges/c3a38c872794aa6a83c9/test_coverage)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/test_coverage) +[![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api/branch/master/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api) +[![StyleCI](https://styleci.io/repos/115823629/shield?branch=master)](https://styleci.io/repos/115823629) #### Develop: -[![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api.svg?branch=develop)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api) -[![StyleCI](https://styleci.io/repos/109524603/shield?branch=develop)](https://styleci.io/repos/109524603) [![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api/branch/develop/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api) +[![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api.svg?branch=develop)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api) +[![StyleCI](https://styleci.io/repos/115823629/shield?branch=develop)](https://styleci.io/repos/115823629) ## Example usage: From ab431c0e2e93d96a3e4f96dea5ecf294cc4d6439 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 30 Dec 2017 23:59:49 +0100 Subject: [PATCH 05/73] - fixed coverage path --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cec955db..2d2dbc82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ script: -Z ; fi after_script: - if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then - ./cc-test-reporter after-build -t=clover /home/travis/build/WebProject-xyz/ikea-tradfri-php/tests/_output/report.xml --exit-code + ./cc-test-reporter after-build -t=clover /home/travis/build/WebProject-xyz/ikea-tradfri-php/tests/_output/coverage.xml --exit-code $TRAVIS_TEST_RESULT ; fi notifications: email: false From ee5bb58a18c7bcde47c7674c0d6c492836104d7f Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 31 Dec 2017 00:07:45 +0100 Subject: [PATCH 06/73] - fixed coverage path --- .travis.yml | 3 ++- build/logs/.gitignore | 2 ++ codeception.yml | 4 ++-- composer.json | 2 +- coverage/.gitkeep | 0 5 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 build/logs/.gitignore delete mode 100644 coverage/.gitkeep diff --git a/.travis.yml b/.travis.yml index 2d2dbc82..e00ac202 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ cache: directories: - "$HOME/.composer/cache" - "$HOME/.local" + - "$HOME/.local" env: global: - CC_TEST_REPORTER_ID=ff208c24a9f196d9bfc66a49f6bf8592a07e82c6eed47ea481e299c4c648e393 @@ -43,7 +44,7 @@ script: -Z ; fi after_script: - if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then - ./cc-test-reporter after-build -t=clover /home/travis/build/WebProject-xyz/ikea-tradfri-php/tests/_output/coverage.xml --exit-code + ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code $TRAVIS_TEST_RESULT ; fi notifications: email: false diff --git a/build/logs/.gitignore b/build/logs/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/build/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/codeception.yml b/codeception.yml index be06358e..1e26023a 100644 --- a/codeception.yml +++ b/codeception.yml @@ -9,7 +9,7 @@ paths: support: tests/_support # directory for output - log: tests/_output + log: build/logs # directory for environment configuration envs: tests/_envs @@ -74,4 +74,4 @@ coverage: include: - src/* exclude: - - vendor/* \ No newline at end of file + - vendor/* diff --git a/composer.json b/composer.json index a1f6a0bb..a8ce8def 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ ], "build-coverage": [ "echo 'Build coverage'", - "./vendor/bin/codecept run --coverage-xml --coverage --xml --colors --steps " + "./vendor/bin/codecept run --coverage-xml=clover.xml --coverage --xml --colors --steps " ] } } diff --git a/coverage/.gitkeep b/coverage/.gitkeep deleted file mode 100644 index e69de29b..00000000 From 993950b45319b2dea90ca3eb19141022ed3b8597 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 31 Dec 2017 00:12:27 +0100 Subject: [PATCH 07/73] - vendor caching --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e00ac202..4742451e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ cache: directories: - "$HOME/.composer/cache" - "$HOME/.local" - - "$HOME/.local" + - "$TRAVIS_BUILD_DIR/vendor" env: global: - CC_TEST_REPORTER_ID=ff208c24a9f196d9bfc66a49f6bf8592a07e82c6eed47ea481e299c4c648e393 From 4b19616a7f533a10cf226752574d863daa161b3e Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 31 Dec 2017 00:17:56 +0100 Subject: [PATCH 08/73] - changed codeception version to 2.* --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a8ce8def..a5420d43 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "doctrine/collections": "^1" }, "require-dev": { - "codeception/codeception": "^2.3", + "codeception/codeception": "^2", "mockery/mockery": "^1", "symfony/phpunit-bridge": "^3.3", "friendsofphp/php-cs-fixer": "^2", From 484e1f4e099e832eea6c660267a9fa65798c3e62 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Tue, 9 Jan 2018 22:23:15 +0100 Subject: [PATCH 09/73] - readme update --- README.md | 12 ++++++------ composer.lock | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a2a0f827..166bd239 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,17 @@ php api to control Ikea smart lights (tradfri) ### Status #### Stable: -[![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api.svg?branch=master)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api) -[![Code Climate](https://img.shields.io/codeclimate/github/WebProject-xyz/ikea-tradfri-php-api.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/) -[![Code Climate](https://img.shields.io/codeclimate/issues//github/WebProject-xyz/ikea-tradfri-php-api.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php-api/) +[![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php.svg?branch=master)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php) +[![Code Climate](https://img.shields.io/codeclimate/github/WebProject-xyz/ikea-tradfri-php.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/) +[![Code Climate](https://img.shields.io/codeclimate/issues//github/WebProject-xyz/ikea-tradfri-php.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/) [![Maintainability](https://api.codeclimate.com/v1/badges/c3a38c872794aa6a83c9/maintainability)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/c3a38c872794aa6a83c9/test_coverage)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/test_coverage) -[![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api/branch/master/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api) +[![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php/branch/master/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php) [![StyleCI](https://styleci.io/repos/115823629/shield?branch=master)](https://styleci.io/repos/115823629) #### Develop: -[![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api/branch/develop/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php-api) -[![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api.svg?branch=develop)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php-api) +[![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php.svg?branch=develop)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php) +[![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php/branch/develop/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php) [![StyleCI](https://styleci.io/repos/115823629/shield?branch=develop)](https://styleci.io/repos/115823629) ## Example usage: diff --git a/composer.lock b/composer.lock index 43253145..a3da252b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "d8e14be57e2e4300a03cedc1bc85b2c9", + "content-hash": "e4eb712364348117761da26bc04daa2c", "packages": [ { "name": "doctrine/collections", From a500a217a6e97c4cfbf40899f71415df2ffa02db Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 13 Jan 2018 01:13:49 +0100 Subject: [PATCH 10/73] - codeclimte config update --- .codeclimate.yml | 62 +++++++++++------ composer.lock | 178 +++++++++++++++++++++++++---------------------- 2 files changed, 136 insertions(+), 104 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 56b04435..14469050 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,26 +1,46 @@ -engines: - duplication: - enabled: true +version: "2" +checks: + argument-count: config: - languages: - - php - fixme: - enabled: true + threshold: 4 + complex-logic: + config: + threshold: 4 + file-lines: + config: + threshold: 250 + method-complexity: + config: + threshold: 5 + method-count: + config: + threshold: 20 + method-lines: + config: + threshold: 25 + nested-control-flow: + config: + threshold: 4 + return-statements: + config: + threshold: 4 + similar-code: + config: + threshold: # language-specific defaults. an override will affect all languages. + identical-code: + config: + threshold: # language-specific defaults. an override will affect all languages. + +plugins: phpmd: enabled: true - config: - file_extensions: - - php - rulesets: "cleancode,codesize,naming,design,unusedcode" phpcodesniffer: enabled: true - config: - file_extensions: "php" - standard: "ZEND" -ratings: - paths: - - src/** - - "**.php" -exclude_paths: - - "vendor/**/*" - - "**Test.php" + SonarPHP: + enabled: true + duplication: + enabled: true + +exclude_patterns: +- "tests/" +- "**/vendor/" diff --git a/composer.lock b/composer.lock index a3da252b..2ef4b08a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "e4eb712364348117761da26bc04daa2c", + "content-hash": "278c3bac95d545c20fa609a40ba42248", "packages": [ { "name": "doctrine/collections", @@ -584,16 +584,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.9.0", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "454ddbe65da6a9297446f442bad244e8a99a9a38" + "reference": "513a3765b56dd029175f9f32995566657ee89dda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/454ddbe65da6a9297446f442bad244e8a99a9a38", - "reference": "454ddbe65da6a9297446f442bad244e8a99a9a38", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/513a3765b56dd029175f9f32995566657ee89dda", + "reference": "513a3765b56dd029175f9f32995566657ee89dda", "shasum": "" }, "require": { @@ -620,10 +620,12 @@ "require-dev": { "johnkary/phpunit-speedtrap": "^1.1 || ^2.0@dev", "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.0", "mikey179/vfsstream": "^1.6", "php-coveralls/php-coveralls": "^2.0", "php-cs-fixer/accessible-object": "^1.0", "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "phpunitgoodpractices/traits": "^1.0", "symfony/phpunit-bridge": "^3.2.2 || ^4.0" }, "suggest": { @@ -634,16 +636,22 @@ "php-cs-fixer" ], "type": "application", + "extra": { + "branch-alias": { + "dev-master": "2.10-dev" + } + }, "autoload": { "psr-4": { "PhpCsFixer\\": "src/" }, "classmap": [ - "tests/Test/Assert/AssertTokensTrait.php", "tests/Test/AbstractFixerTestCase.php", "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", "tests/Test/IntegrationCase.php", - "tests/Test/IntegrationCaseFactory.php" + "tests/Test/IntegrationCaseFactory.php", + "tests/TestCase.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -661,7 +669,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2017-12-08T16:36:20+00:00" + "time": "2018-01-10T17:16:15+00:00" }, { "name": "gecko-packages/gecko-php-unit", @@ -2263,16 +2271,16 @@ }, { "name": "sebastian/comparator", - "version": "2.1.1", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f" + "reference": "11c07feade1d65453e06df3b3b90171d6d982087" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b11c729f95109b56a0fe9650c6a63a0fcd8c439f", - "reference": "b11c729f95109b56a0fe9650c6a63a0fcd8c439f", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/11c07feade1d65453e06df3b3b90171d6d982087", + "reference": "11c07feade1d65453e06df3b3b90171d6d982087", "shasum": "" }, "require": { @@ -2323,7 +2331,7 @@ "compare", "equality" ], - "time": "2017-12-22T14:50:35+00:00" + "time": "2018-01-12T06:34:42+00:00" }, { "name": "sebastian/diff", @@ -2777,16 +2785,16 @@ }, { "name": "symfony/browser-kit", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "f761b4ecdd23a451c2cae6fba704d8b207cbb045" + "reference": "490f27762705c8489bd042fe3e9377a191dba9b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/f761b4ecdd23a451c2cae6fba704d8b207cbb045", - "reference": "f761b4ecdd23a451c2cae6fba704d8b207cbb045", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/490f27762705c8489bd042fe3e9377a191dba9b4", + "reference": "490f27762705c8489bd042fe3e9377a191dba9b4", "shasum": "" }, "require": { @@ -2830,20 +2838,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2017-12-11T22:06:16+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/config", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "e57211b88aa889fefac1cb36866db04100b0f21c" + "reference": "cfd5c972f7b4992a5df41673d25d980ab077aa5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/e57211b88aa889fefac1cb36866db04100b0f21c", - "reference": "e57211b88aa889fefac1cb36866db04100b0f21c", + "url": "https://api.github.com/repos/symfony/config/zipball/cfd5c972f7b4992a5df41673d25d980ab077aa5b", + "reference": "cfd5c972f7b4992a5df41673d25d980ab077aa5b", "shasum": "" }, "require": { @@ -2892,20 +2900,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/console", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e" + "reference": "8394c8ef121949e8f858f13bc1e34f05169e4e7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9f21adfb92a9315b73ae2ed43138988ee4913d4e", - "reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e", + "url": "https://api.github.com/repos/symfony/console/zipball/8394c8ef121949e8f858f13bc1e34f05169e4e7d", + "reference": "8394c8ef121949e8f858f13bc1e34f05169e4e7d", "shasum": "" }, "require": { @@ -2961,20 +2969,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/css-selector", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "eac760b414cf1f64362c3dd047b989e4db121332" + "reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/eac760b414cf1f64362c3dd047b989e4db121332", - "reference": "eac760b414cf1f64362c3dd047b989e4db121332", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/e66394bc7610e69279bfdb3ab11b4fe65403f556", + "reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556", "shasum": "" }, "require": { @@ -3014,20 +3022,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/debug", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "543deab3ffff94402440b326fc94153bae2dfa7a" + "reference": "603b95dda8b00020e4e6e60dc906e7b715b1c245" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/543deab3ffff94402440b326fc94153bae2dfa7a", - "reference": "543deab3ffff94402440b326fc94153bae2dfa7a", + "url": "https://api.github.com/repos/symfony/debug/zipball/603b95dda8b00020e4e6e60dc906e7b715b1c245", + "reference": "603b95dda8b00020e4e6e60dc906e7b715b1c245", "shasum": "" }, "require": { @@ -3070,20 +3078,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-12-12T08:27:14+00:00" + "time": "2018-01-03T17:14:19+00:00" }, { "name": "symfony/dom-crawler", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "dc847845c66fa68ad4522ed27e62b9b9dd12ab3b" + "reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/dc847845c66fa68ad4522ed27e62b9b9dd12ab3b", - "reference": "dc847845c66fa68ad4522ed27e62b9b9dd12ab3b", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/09bd97b844b3151fab82f2fdd62db9c464b3910a", + "reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a", "shasum": "" }, "require": { @@ -3126,20 +3134,20 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b869cbf8a15ca6261689de2c28a7d7f2d0706835" + "reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b869cbf8a15ca6261689de2c28a7d7f2d0706835", - "reference": "b869cbf8a15ca6261689de2c28a7d7f2d0706835", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26b87b6bca8f8f797331a30b76fdae5342dc26ca", + "reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca", "shasum": "" }, "require": { @@ -3189,20 +3197,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/filesystem", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "25b135bea251829e3db6a77d773643408b575ed4" + "reference": "e078773ad6354af38169faf31c21df0f18ace03d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/25b135bea251829e3db6a77d773643408b575ed4", - "reference": "25b135bea251829e3db6a77d773643408b575ed4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", + "reference": "e078773ad6354af38169faf31c21df0f18ace03d", "shasum": "" }, "require": { @@ -3238,20 +3246,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/finder", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a" + "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/dac8d7db537bac7ad8143eb11360a8c2231f251a", - "reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a", + "url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f", + "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f", "shasum": "" }, "require": { @@ -3287,20 +3295,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-11-05T16:10:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/options-resolver", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "4576693efc58c022c3fe9f144aa61d204c86ad2c" + "reference": "f31f4d3ce4eaf7597abc41bd5ba53d634c2fdb0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4576693efc58c022c3fe9f144aa61d204c86ad2c", - "reference": "4576693efc58c022c3fe9f144aa61d204c86ad2c", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/f31f4d3ce4eaf7597abc41bd5ba53d634c2fdb0e", + "reference": "f31f4d3ce4eaf7597abc41bd5ba53d634c2fdb0e", "shasum": "" }, "require": { @@ -3341,20 +3349,20 @@ "configuration", "options" ], - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "074c2e205c849a5fb37b1c24ade03cc975ac8079" + "reference": "24ffb71a115c25f5ee56cbfd38e56ed2cdbeb0a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/074c2e205c849a5fb37b1c24ade03cc975ac8079", - "reference": "074c2e205c849a5fb37b1c24ade03cc975ac8079", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/24ffb71a115c25f5ee56cbfd38e56ed2cdbeb0a9", + "reference": "24ffb71a115c25f5ee56cbfd38e56ed2cdbeb0a9", "shasum": "" }, "require": { @@ -3374,6 +3382,10 @@ "extra": { "branch-alias": { "dev-master": "3.4-dev" + }, + "thanks": { + "name": "phpunit/phpunit", + "url": "https://github.com/sebastianbergmann/phpunit" } }, "autoload": { @@ -3403,7 +3415,7 @@ ], "description": "Symfony PHPUnit Bridge", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-04T17:19:23+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -3580,16 +3592,16 @@ }, { "name": "symfony/process", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "bb3ef65d493a6d57297cad6c560ee04e2a8f5098" + "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/bb3ef65d493a6d57297cad6c560ee04e2a8f5098", - "reference": "bb3ef65d493a6d57297cad6c560ee04e2a8f5098", + "url": "https://api.github.com/repos/symfony/process/zipball/ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", + "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", "shasum": "" }, "require": { @@ -3625,20 +3637,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/stopwatch", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "52510fe1aefdc1c5d2076ac6030421d387e689d1" + "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/52510fe1aefdc1c5d2076ac6030421d387e689d1", - "reference": "52510fe1aefdc1c5d2076ac6030421d387e689d1", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/c865551df7c17e63fc1f09f763db04387f91ae4d", + "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d", "shasum": "" }, "require": { @@ -3674,20 +3686,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2017-11-07T14:28:09+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/yaml", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "afe0cd38486505c9703707707d91450cfc1bd536" + "reference": "25c192f25721a74084272671f658797d9e0e0146" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/afe0cd38486505c9703707707d91450cfc1bd536", - "reference": "afe0cd38486505c9703707707d91450cfc1bd536", + "url": "https://api.github.com/repos/symfony/yaml/zipball/25c192f25721a74084272671f658797d9e0e0146", + "reference": "25c192f25721a74084272671f658797d9e0e0146", "shasum": "" }, "require": { @@ -3732,7 +3744,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-12-11T20:38:23+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "theseer/tokenizer", From 0bcfa07ca31d13abfe43ee30e87c67b80128b77d Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 13 Jan 2018 01:18:41 +0100 Subject: [PATCH 11/73] - change exclude path in .codeclimate.yml --- .codeclimate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 14469050..f6976b7d 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -42,5 +42,5 @@ plugins: enabled: true exclude_patterns: -- "tests/" +- "**/tests/**Test.php" - "**/vendor/" From 93256138f7e76ee9b44ddcecccc6eff8fb26b57b Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 13 Jan 2018 01:27:29 +0100 Subject: [PATCH 12/73] - .codeclimate.yml again: removed nameing check - changed print to echo in examples --- .codeclimate.yml | 4 +++ src/IKEA/Tradfri/Command/CommandAbstract.php | 36 +++++++++++++++++++- wiki/example/example-dim-group.php | 2 +- wiki/example/example-dim-light.php | 2 +- wiki/example/example-group-switch.php | 2 +- wiki/example/example-light-info.php | 2 +- wiki/example/example-light-switch.php | 2 +- wiki/example/example-list-devices.php | 2 +- wiki/example/example-list-groups.php | 2 +- wiki/example/example-list-lights-json.php | 2 +- wiki/example/example-list-lights.php | 2 +- 11 files changed, 48 insertions(+), 10 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index f6976b7d..e0a13c16 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -34,6 +34,10 @@ checks: plugins: phpmd: enabled: true + config: + file_extensions: + - php + rulesets: "design,unusedcode,codesize" phpcodesniffer: enabled: true SonarPHP: diff --git a/src/IKEA/Tradfri/Command/CommandAbstract.php b/src/IKEA/Tradfri/Command/CommandAbstract.php index d4950f96..10f7ad9f 100644 --- a/src/IKEA/Tradfri/Command/CommandAbstract.php +++ b/src/IKEA/Tradfri/Command/CommandAbstract.php @@ -4,6 +4,8 @@ namespace IKEA\Tradfri\Command; +use IKEA\Tradfri\Client\Client; + /** * Class CommandAbstract. */ @@ -13,7 +15,39 @@ abstract class CommandAbstract const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; const COAP_COMMAND_POST = 'coap-client -m post -u "%s" -k "%s"'; + /** + * @var Client + */ protected $_client; - abstract public function __toString(); + /** + * Execute command. + * + * @return $this + */ + abstract public function execute(): self; + + /** + * Get Client + * + * @return mixed + */ + public function getClient() + { + return $this->_client; + } + + /** + * Set Client + * + * @param mixed $client + * + * @return CommandAbstract + */ + public function setClient(mixed $client) + { + $this->_client = $client; + + return $this; + } } diff --git a/wiki/example/example-dim-group.php b/wiki/example/example-dim-group.php index 72847f31..2127ee09 100644 --- a/wiki/example/example-dim-group.php +++ b/wiki/example/example-dim-group.php @@ -54,6 +54,6 @@ } catch (\Exception $e) { echo PHP_EOL.'---------- Error'; echo PHP_EOL. $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-dim-light.php b/wiki/example/example-dim-light.php index abd7b82b..dc27d59d 100644 --- a/wiki/example/example-dim-light.php +++ b/wiki/example/example-dim-light.php @@ -44,6 +44,6 @@ } catch (\Exception $e) { echo PHP_EOL.'---------- Error'; echo PHP_EOL. $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-group-switch.php b/wiki/example/example-group-switch.php index 5850e380..42e6f2a8 100644 --- a/wiki/example/example-group-switch.php +++ b/wiki/example/example-group-switch.php @@ -49,6 +49,6 @@ } catch (\Exception $e) { echo PHP_EOL.'---------- Error'; echo PHP_EOL. $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-light-info.php b/wiki/example/example-light-info.php index 76902cb6..f1d908c7 100644 --- a/wiki/example/example-light-info.php +++ b/wiki/example/example-light-info.php @@ -23,6 +23,6 @@ die('no lights connected to hub'); } catch (\Exception $e) { echo $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-light-switch.php b/wiki/example/example-light-switch.php index 49f4765a..65ecf406 100644 --- a/wiki/example/example-light-switch.php +++ b/wiki/example/example-light-switch.php @@ -37,6 +37,6 @@ } catch (\Exception $e) { echo PHP_EOL.'---------- Error'; echo PHP_EOL. $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-list-devices.php b/wiki/example/example-list-devices.php index 73fc089b..51cba0bd 100644 --- a/wiki/example/example-list-devices.php +++ b/wiki/example/example-list-devices.php @@ -27,6 +27,6 @@ }); } catch (\Exception $e) { echo $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-list-groups.php b/wiki/example/example-list-groups.php index 653c87f1..91ee0b69 100644 --- a/wiki/example/example-list-groups.php +++ b/wiki/example/example-list-groups.php @@ -36,6 +36,6 @@ }); } catch (\Exception $e) { echo $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-list-lights-json.php b/wiki/example/example-list-lights-json.php index 03c7b2dd..13f3e2ba 100755 --- a/wiki/example/example-list-lights-json.php +++ b/wiki/example/example-list-lights-json.php @@ -10,6 +10,6 @@ echo $lights->jsonSerialize(); } catch (\Exception $e) { echo $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } diff --git a/wiki/example/example-list-lights.php b/wiki/example/example-list-lights.php index 952c3ef7..c1348247 100644 --- a/wiki/example/example-list-lights.php +++ b/wiki/example/example-list-lights.php @@ -25,6 +25,6 @@ }); } catch (\Exception $e) { echo $e->getMessage().PHP_EOL.PHP_EOL; - print_r($e->getTraceAsString()); + echo $e->getTraceAsString(); die(); } From 09074324ab57224fefa4b782957223ac635f9dd6 Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sat, 13 Jan 2018 00:28:28 +0000 Subject: [PATCH 13/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Command/CommandAbstract.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IKEA/Tradfri/Command/CommandAbstract.php b/src/IKEA/Tradfri/Command/CommandAbstract.php index 10f7ad9f..7eb3011e 100644 --- a/src/IKEA/Tradfri/Command/CommandAbstract.php +++ b/src/IKEA/Tradfri/Command/CommandAbstract.php @@ -28,7 +28,7 @@ abstract class CommandAbstract abstract public function execute(): self; /** - * Get Client + * Get Client. * * @return mixed */ @@ -38,7 +38,7 @@ public function getClient() } /** - * Set Client + * Set Client. * * @param mixed $client * From 3d048dd1c68b36db7c2b185bb003d4bd0e548c41 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 13 Jan 2018 01:32:40 +0100 Subject: [PATCH 14/73] - .codeclimate.yml changed standard to "Zend,PSR1,PSR2" --- .codeclimate.yml | 3 +++ wiki/example/init-dist.php | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index e0a13c16..776733b3 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -40,6 +40,9 @@ plugins: rulesets: "design,unusedcode,codesize" phpcodesniffer: enabled: true + config: + file_extensions: "php" + standard: "Zend,PSR1,PSR2" SonarPHP: enabled: true duplication: diff --git a/wiki/example/init-dist.php b/wiki/example/init-dist.php index 700d41d0..d8ae1d9b 100644 --- a/wiki/example/init-dist.php +++ b/wiki/example/init-dist.php @@ -1,6 +1,9 @@ Date: Sat, 13 Jan 2018 01:48:19 +0100 Subject: [PATCH 15/73] - .codeclimate.yml changed standard to "Zend,PSR1,PSR2" --- .codeclimate.yml | 9 +- build/configs/ruleset.xml | 27 +++ src/IKEA/Tradfri/Command/Coaps.php | 163 ++++++++++--------- src/IKEA/Tradfri/Command/CommandAbstract.php | 22 +-- 4 files changed, 132 insertions(+), 89 deletions(-) create mode 100644 build/configs/ruleset.xml diff --git a/.codeclimate.yml b/.codeclimate.yml index 776733b3..bb07e41d 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -42,7 +42,14 @@ plugins: enabled: true config: file_extensions: "php" - standard: "Zend,PSR1,PSR2" + standard: "Zend,PSR2,PSR1" + checks: + PSR2 Methods MethodDeclaration Underscore: + enabled: false + PSR2 Classes PropertyDeclaration Underscore: + enabled: false + PSR1 Files SideEffects FoundWithSymbols: + enabled: false SonarPHP: enabled: true duplication: diff --git a/build/configs/ruleset.xml b/build/configs/ruleset.xml new file mode 100644 index 00000000..c46df709 --- /dev/null +++ b/build/configs/ruleset.xml @@ -0,0 +1,27 @@ + + + Custom rules for checking my project + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index f001e84d..cdd466c8 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -20,22 +20,22 @@ class Coaps /** * @var string */ - private $username; + private $_username; /** * @var string */ - private $apiKey; + private $_apiKey; /** * @var string */ - private $ip; + private $_ip; /** * @var string */ - private $secret; + private $_secret; /** * Coaps constructor. @@ -50,7 +50,7 @@ class Coaps public function __construct(string $ip, string $secret, $username = 'wrapper') { $this->setIp($ip); - $this->secret = $secret; + $this->_secret = $secret; if (!\defined('COAP_API_KEY')) { throw new RuntimeException('COAP_API_KEY not set'); } @@ -82,19 +82,27 @@ public function getSharedKeyFromGateway(): string } /** - * Parse result. - * - * @param array $result + * Get Command to get an api key from gateway. * - * @return false|string + * @return string */ - public function parseResult(array $result) + public function getPreSharedKeyCommand(): string { - if (\count($result) === 2 && !empty($result[0])) { - return $result[0]; - } + $command = \sprintf(self::COAP_COMMAND_POST, 'Client_identity', $this->secret) + . ' -e \'{"9090":"' . $this->getUsername() . '"}\'' + . ' "coaps://' . $this->ip . ':5684/' . CoapCommandKeys::KEY_GET_SHARED_KEY . '"'; - return false; + return $command; + } + + /** + * Get Username. + * + * @return string + */ + public function getUsername(): string + { + return $this->_username; } /** @@ -106,58 +114,50 @@ public function parseResult(array $result) */ public function setUsername(string $username): self { - $this->username = $username; + $this->_username = $username; return $this; } /** - * Get Username. - * - * @return string - */ - public function getUsername(): string - { - return $this->username; - } - - /** - * Set ApiKey. + * Parse result. * - * @param string $apiKey + * @param array $result * - * @return Coaps + * @return false|string */ - public function setApiKey(string $apiKey): self + public function parseResult(array $result) { - $this->apiKey = $apiKey; + if (\count($result) === 2 && !empty($result[0])) { + return $result[0]; + } - return $this; + return false; } /** - * Get ApiKey. + * Get Ip. * * @return string */ - public function getApiKey(): string + public function getIp(): string { - return $this->apiKey; + return $this->_ip; } /** * Set and filter ip. * - * @param $ip + * @param $ipAddress * * @throws \InvalidArgumentException * * @return $this */ - public function setIp(string $ip): self + public function setIp(string $ipAddress): self { - if (filter_var($ip, FILTER_VALIDATE_IP)) { - $this->ip = $ip; + if (filter_var($ipAddress, FILTER_VALIDATE_IP)) { + $this->ip = $ipAddress; return $this; } @@ -166,38 +166,39 @@ public function setIp(string $ip): self } /** - * Get Ip. + * Get CoapsCommand GET string. + * + * @param string|int $requestType * * @return string */ - public function getIp(): string + public function getCoapsCommandGet($requestType): string { - return $this->ip; + return \sprintf(self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey()) . ' "coaps://' . $this->ip . ':5684/' . $requestType . '"'; } /** - * Get CoapsCommand GET string. - * - * @param string|int $requestType + * Get ApiKey. * * @return string */ - public function getCoapsCommandGet($requestType): string + public function getApiKey(): string { - return \sprintf(self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey()).' "coaps://'.$this->ip.':5684/'.$requestType.'"'; + return $this->_apiKey; } /** - * Get CoapsCommand PUT string. + * Set ApiKey. * - * @param string|int $requestType - * @param string $inject + * @param string $apiKey * - * @return string + * @return Coaps */ - public function getCoapsCommandPut($requestType, string $inject): string + public function setApiKey(string $apiKey): self { - return \sprintf(self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey()).$inject.' "coaps://'.$this->ip.':5684/'.$requestType.'"'; + $this->_apiKey = $apiKey; + + return $this; } /** @@ -210,37 +211,45 @@ public function getCoapsCommandPut($requestType, string $inject): string */ public function getCoapsCommandPost($requestType, string $inject): string { - return \sprintf(self::COAP_COMMAND_POST, $this->getUsername(), $this->getApiKey()).$inject.' "coaps://'.$this->ip.':5684/'.$requestType.'"'; + return \sprintf( + self::COAP_COMMAND_POST, + $this->getUsername(), + $this->getApiKey() + ) . $inject + . ' "coaps://' . $this->getIp() . ':5684/' . $requestType . '"'; } /** - * Get Command to get an api key from gateway. + * Get Command to switch light on or off. + * + * @param int $deviceId + * @param bool $state * * @return string */ - public function getPreSharedKeyCommand(): string + public function getLightSwitchCommand(int $deviceId, bool $state): string { - $command = \sprintf(self::COAP_COMMAND_POST, 'Client_identity', $this->secret) - .' -e \'{"9090":"'.$this->getUsername().'"}\'' - .' "coaps://'.$this->ip.':5684/'.CoapCommandKeys::KEY_GET_SHARED_KEY.'"'; - - return $command; + return $this->getCoapsCommandPut( + CoapCommandKeys::KEY_GET_DATA . '/' . $deviceId, + ' -e \'{ "' + . CoapCommandKeys::KEY_DEVICE_DATA + . '": [{ "' . + CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' : '0') + . ' }] }\' ' + ); } /** - * Get Command to switch light on or off. + * Get CoapsCommand PUT string. * - * @param int $deviceId - * @param bool $state + * @param string|int $requestType + * @param string $inject * * @return string */ - public function getLightSwitchCommand(int $deviceId, bool $state): string + public function getCoapsCommandPut($requestType, string $inject): string { - return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$deviceId, - ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "'.CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0').' }] }\' ' - ); + return \sprintf(self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey()) . $inject . ' "coaps://' . $this->ip . ':5684/' . $requestType . '"'; } /** @@ -254,8 +263,8 @@ public function getLightSwitchCommand(int $deviceId, bool $state): string public function getGroupSwitchCommand(int $groupId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0').' }\' ' + CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, + ' -e \'{ "' . CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' : '0') . ' }\' ' ); } @@ -270,8 +279,8 @@ public function getGroupSwitchCommand(int $groupId, bool $state): string public function getGroupDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55).' }\' ' + CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, + ' -e \'{ "' . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round($value * 2.55) . ' }\' ' ); } @@ -286,8 +295,8 @@ public function getGroupDimmerCommand(int $groupId, int $value): string public function getLightDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55).' }] }\' ' + CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, + ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round($value * 2.55) . ' }] }\' ' ); } @@ -295,7 +304,7 @@ public function getLightDimmerCommand(int $groupId, int $value): string * Get Command to dim light. * * @param int $groupId - * @param string $color (warm|normal|cold) + * @param string $color (warm|normal|cold) * * @throws \IKEA\Tradfri\Exception\RuntimeException * @@ -303,7 +312,7 @@ public function getLightDimmerCommand(int $groupId, int $value): string */ public function getLightColorCommand(int $groupId, string $color): string { - $payload = ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "'.CoapCommandKeys::KEY_COLOR.'": %s, "'.CoapCommandKeys::KEY_COLOR_2.'": %s }] }\' '; + $payload = ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' . CoapCommandKeys::KEY_COLOR . '": %s, "' . CoapCommandKeys::KEY_COLOR_2 . '": %s }] }\' '; switch ($color) { case 'warm': $payload = \sprintf($payload, '33135', '27211'); @@ -319,7 +328,7 @@ public function getLightColorCommand(int $groupId, string $color): string } return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, + CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, $payload ); } diff --git a/src/IKEA/Tradfri/Command/CommandAbstract.php b/src/IKEA/Tradfri/Command/CommandAbstract.php index 7eb3011e..59e5f7fd 100644 --- a/src/IKEA/Tradfri/Command/CommandAbstract.php +++ b/src/IKEA/Tradfri/Command/CommandAbstract.php @@ -20,19 +20,12 @@ abstract class CommandAbstract */ protected $_client; - /** - * Execute command. - * - * @return $this - */ - abstract public function execute(): self; - /** * Get Client. * - * @return mixed + * @return Client */ - public function getClient() + public function getClient(): Client { return $this->_client; } @@ -40,14 +33,21 @@ public function getClient() /** * Set Client. * - * @param mixed $client + * @param Client $client * * @return CommandAbstract */ - public function setClient(mixed $client) + public function setClient(Client $client): self { $this->_client = $client; return $this; } + + /** + * Execute command. + * + * @return $this + */ + abstract public function execute(): self; } From 423e2ce98460e824ffeec76613ef6ece1f10fd59 Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sat, 13 Jan 2018 00:48:27 +0000 Subject: [PATCH 16/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Command/Coaps.php | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index cdd466c8..f2d5abf3 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -89,8 +89,8 @@ public function getSharedKeyFromGateway(): string public function getPreSharedKeyCommand(): string { $command = \sprintf(self::COAP_COMMAND_POST, 'Client_identity', $this->secret) - . ' -e \'{"9090":"' . $this->getUsername() . '"}\'' - . ' "coaps://' . $this->ip . ':5684/' . CoapCommandKeys::KEY_GET_SHARED_KEY . '"'; + .' -e \'{"9090":"'.$this->getUsername().'"}\'' + .' "coaps://'.$this->ip.':5684/'.CoapCommandKeys::KEY_GET_SHARED_KEY.'"'; return $command; } @@ -174,7 +174,7 @@ public function setIp(string $ipAddress): self */ public function getCoapsCommandGet($requestType): string { - return \sprintf(self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey()) . ' "coaps://' . $this->ip . ':5684/' . $requestType . '"'; + return \sprintf(self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey()).' "coaps://'.$this->ip.':5684/'.$requestType.'"'; } /** @@ -215,8 +215,8 @@ public function getCoapsCommandPost($requestType, string $inject): string self::COAP_COMMAND_POST, $this->getUsername(), $this->getApiKey() - ) . $inject - . ' "coaps://' . $this->getIp() . ':5684/' . $requestType . '"'; + ).$inject + .' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; } /** @@ -230,12 +230,12 @@ public function getCoapsCommandPost($requestType, string $inject): string public function getLightSwitchCommand(int $deviceId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA . '/' . $deviceId, + CoapCommandKeys::KEY_GET_DATA.'/'.$deviceId, ' -e \'{ "' - . CoapCommandKeys::KEY_DEVICE_DATA - . '": [{ "' . - CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' : '0') - . ' }] }\' ' + .CoapCommandKeys::KEY_DEVICE_DATA + .'": [{ "'. + CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0') + .' }] }\' ' ); } @@ -249,7 +249,7 @@ public function getLightSwitchCommand(int $deviceId, bool $state): string */ public function getCoapsCommandPut($requestType, string $inject): string { - return \sprintf(self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey()) . $inject . ' "coaps://' . $this->ip . ':5684/' . $requestType . '"'; + return \sprintf(self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey()).$inject.' "coaps://'.$this->ip.':5684/'.$requestType.'"'; } /** @@ -263,8 +263,8 @@ public function getCoapsCommandPut($requestType, string $inject): string public function getGroupSwitchCommand(int $groupId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, - ' -e \'{ "' . CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' : '0') . ' }\' ' + CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, + ' -e \'{ "'.CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0').' }\' ' ); } @@ -279,8 +279,8 @@ public function getGroupSwitchCommand(int $groupId, bool $state): string public function getGroupDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, - ' -e \'{ "' . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round($value * 2.55) . ' }\' ' + CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, + ' -e \'{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55).' }\' ' ); } @@ -295,8 +295,8 @@ public function getGroupDimmerCommand(int $groupId, int $value): string public function getLightDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, - ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round($value * 2.55) . ' }] }\' ' + CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, + ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55).' }] }\' ' ); } @@ -304,7 +304,7 @@ public function getLightDimmerCommand(int $groupId, int $value): string * Get Command to dim light. * * @param int $groupId - * @param string $color (warm|normal|cold) + * @param string $color (warm|normal|cold) * * @throws \IKEA\Tradfri\Exception\RuntimeException * @@ -312,7 +312,7 @@ public function getLightDimmerCommand(int $groupId, int $value): string */ public function getLightColorCommand(int $groupId, string $color): string { - $payload = ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' . CoapCommandKeys::KEY_COLOR . '": %s, "' . CoapCommandKeys::KEY_COLOR_2 . '": %s }] }\' '; + $payload = ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "'.CoapCommandKeys::KEY_COLOR.'": %s, "'.CoapCommandKeys::KEY_COLOR_2.'": %s }] }\' '; switch ($color) { case 'warm': $payload = \sprintf($payload, '33135', '27211'); @@ -328,7 +328,7 @@ public function getLightColorCommand(int $groupId, string $color): string } return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, + CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, $payload ); } From 3eddb92e7a02eedc2619582e97890ab594ecc7c3 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Mon, 15 Jan 2018 22:19:23 +0100 Subject: [PATCH 17/73] JsonSerializable devices and collections --- src/IKEA/Tradfri/Device/Device.php | 25 +++++++++++++++++++++- wiki/example/example-list-devices-json.php | 18 ++++++++++++++++ wiki/example/example-list-lights-json.php | 2 +- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 wiki/example/example-list-devices-json.php diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index 1e59a7cc..07f32845 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -7,11 +7,12 @@ use IKEA\Tradfri\Exception\TypeException; use IKEA\Tradfri\Service\Api; use IKEA\Tradfri\Service\ServiceInterface; +use JsonSerializable; /** * Class Device. */ -abstract class Device +abstract class Device implements JsonSerializable { const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; const TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; @@ -256,4 +257,26 @@ public function isValidType($type): bool throw new TypeException('unknown type'); } } + + /** + * Specify data which should be serialized to JSON + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * @return mixed data which can be serialized by json_encode, + * which is a value of any type other than a resource. + * @since 5.4.0 + */ + public function jsonSerialize(): array + { + $data = []; + + foreach (get_class_methods(static::class) as $method) { + if ($method !== 'getService' && strpos($method, 'get') === 0) { + $key = strtolower((string)substr($method, 3)); + $data[$key] + = $this->$method(); + } + } + + return $data; + } } diff --git a/wiki/example/example-list-devices-json.php b/wiki/example/example-list-devices-json.php new file mode 100644 index 00000000..c8ebe7dd --- /dev/null +++ b/wiki/example/example-list-devices-json.php @@ -0,0 +1,18 @@ +getDevices(); + $data =$devices->jsonSerialize(); + var_dump($data); + exit; + echo json_encode($data); +} catch (\Exception $e) { + echo $e->getMessage().PHP_EOL.PHP_EOL; + echo $e->getTraceAsString(); + die(); +} diff --git a/wiki/example/example-list-lights-json.php b/wiki/example/example-list-lights-json.php index 13f3e2ba..843cf2df 100755 --- a/wiki/example/example-list-lights-json.php +++ b/wiki/example/example-list-lights-json.php @@ -7,7 +7,7 @@ echo '---------- IKEA Tradfri PHP API Example: '.basename(__FILE__).PHP_EOL; $lights = $api->getLights(); $lights->sortByState(); - echo $lights->jsonSerialize(); + echo json_encode($lights->jsonSerialize()); } catch (\Exception $e) { echo $e->getMessage().PHP_EOL.PHP_EOL; echo $e->getTraceAsString(); From ea733905e9e47c32bbc8e94a2a0f22bdd2dd07b1 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Mon, 15 Jan 2018 22:20:13 +0100 Subject: [PATCH 18/73] JsonSerializable devices and collections #2 --- .../Tradfri/Collection/AbstractCollection.php | 20 +++++++++++++++++++ src/IKEA/Tradfri/Collection/Devices.php | 17 +--------------- src/IKEA/Tradfri/Collection/Groups.php | 15 -------------- src/IKEA/Tradfri/Collection/Lightbulbs.php | 15 -------------- 4 files changed, 21 insertions(+), 46 deletions(-) diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index f8052601..46e1dd4a 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -52,4 +52,24 @@ public function find($closure) return null; } + + /** + * Specify data which should be serialized to JSON. + * + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed data which can be serialized by json_encode, + * which is a value of any type other than a resource. + * + * @since 5.4.0 + */ + public function jsonSerialize() + { + $data = []; + foreach ($this->toArray() as $device) { + /** @var Device $device */ + $data[$device->getId()] = $device->jsonSerialize(); + } + return $data; + } } diff --git a/src/IKEA/Tradfri/Collection/Devices.php b/src/IKEA/Tradfri/Collection/Devices.php index 3ae39356..2cb0cc3b 100644 --- a/src/IKEA/Tradfri/Collection/Devices.php +++ b/src/IKEA/Tradfri/Collection/Devices.php @@ -17,7 +17,7 @@ class Devices extends AbstractCollection /** * Get lightbulbs. * - * @return Lightbulbs + * @return Lightbulbs|Lightbulb[] */ public function getLightbulbs(): Lightbulbs { @@ -40,19 +40,4 @@ public function getDevices(): array { return $this->toArray(); } - - /** - * Specify data which should be serialized to JSON. - * - * @link http://php.net/manual/en/jsonserializable.jsonserialize.php - * - * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. - * - * @since 5.4.0 - */ - public function jsonSerialize() - { - // @TODO: Implement jsonSerialize() method. - } } diff --git a/src/IKEA/Tradfri/Collection/Groups.php b/src/IKEA/Tradfri/Collection/Groups.php index 2dd7c213..85614e79 100644 --- a/src/IKEA/Tradfri/Collection/Groups.php +++ b/src/IKEA/Tradfri/Collection/Groups.php @@ -35,19 +35,4 @@ public function addGroup(Device $group) return $this; } - - /** - * Specify data which should be serialized to JSON. - * - * @link http://php.net/manual/en/jsonserializable.jsonserialize.php - * - * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. - * - * @since 5.4.0 - */ - public function jsonSerialize() - { - // @TODO: Implement jsonSerialize() method. - } } diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index e2382986..e96525ee 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -54,19 +54,4 @@ public function getActive() return $this->createFrom($newItems); } - - /** - * Specify data which should be serialized to JSON. - * - * @link http://php.net/manual/en/jsonserializable.jsonserialize.php - * - * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. - * - * @since 5.4.0 - */ - public function jsonSerialize() - { - // @TODO: Implement jsonSerialize() method. - } } From f785eec24ca61bfbec40e16113b92d624fc19f76 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Mon, 15 Jan 2018 22:20:44 +0100 Subject: [PATCH 19/73] Command helper error handling --- src/IKEA/Tradfri/Helper/Runner.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index 7b0197bb..2255bc78 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -79,7 +79,14 @@ public static function execWithTimeout(string $cmd, int $timeout, $asArray = tru $errors = stream_get_contents($pipes[2]); if (!empty($errors) && empty($buffer)) { - throw new RuntimeException($errors); + $parts = explode("\n", $errors); + if (\count($parts) === 3) { + $errorMessage = $parts[1]; + } else { + $errorMessage = $errors; + } + + throw new RuntimeException($errorMessage); } // Kill the process in case the timeout expired and it's still running. From ce2c12908b324ed752298f2d6073152bdd45c628 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Mon, 15 Jan 2018 22:44:10 +0100 Subject: [PATCH 20/73] code style and change name of service method "on" to "switchOn" --- src/IKEA/Tradfri/Adapter/Coap.php | 55 +++++-- src/IKEA/Tradfri/Client/Client.php | 30 ++-- src/IKEA/Tradfri/Command/Coaps.php | 144 +++++++++++------- src/IKEA/Tradfri/Device/Lightbulb.php | 4 +- src/IKEA/Tradfri/Helper/Runner.php | 36 +++-- src/IKEA/Tradfri/Mapper/DeviceData.php | 2 +- src/IKEA/Tradfri/Service/Api.php | 27 +++- src/IKEA/Tradfri/Service/ServiceInterface.php | 2 +- .../IKEA/Tradfri/Device/LightbulbTest.php | 2 +- tests/unit/IKEA/Tradfri/Service/ApiTest.php | 14 +- wiki/example/example-light-switch.php | 11 +- 11 files changed, 210 insertions(+), 117 deletions(-) diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index 01147f08..d1f2cf8e 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -38,8 +38,11 @@ class Coap extends AdapterAbstract * @param MapperInterface $deviceDataMapper * @param MapperInterface $groupDataMapper */ - public function __construct(Coaps $commands, MapperInterface $deviceDataMapper, MapperInterface $groupDataMapper) - { + public function __construct( + Coaps $commands, + MapperInterface $deviceDataMapper, + MapperInterface $groupDataMapper + ) { $this->commands = $commands; $this->checkOnline($commands->getIp()); @@ -75,7 +78,7 @@ public function getType(int $deviceId): string * * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @return array|\stdClass + * @return array|\stdClass|string */ protected function _getData(string $requestType, int $deviceId = null) { @@ -86,7 +89,9 @@ protected function _getData(string $requestType, int $deviceId = null) $command .= '/'.$deviceId; } - $dataRaw = $this->commands->parseResult(Runner::execWithTimeout($command, 1)); + $dataRaw = $this->commands->parseResult( + Runner::execWithTimeout($command, 1) + ); if ($dataRaw !== false) { $decoded = \json_decode($dataRaw); @@ -172,8 +177,13 @@ public function getGroupsData():array { $groupData = []; foreach ($this->getGroupIds() as $groupId) { - // sometimes the request are to fast, the hub will decline the request (flood security) - $groupData[$groupId] = $this->_getData(CoapCommandKeys::KEY_GET_GROUPS, $groupId); + // sometimes the request are to fast, + // the hub will decline the request (flood security) + $groupData[$groupId] + = $this->_getData( + CoapCommandKeys::KEY_GET_GROUPS, + $groupId + ); //\sleep(1); } @@ -196,7 +206,8 @@ public function getDevicesData(array $deviceIds = null): array } $deviceData = []; foreach ($deviceIds as $deviceId) { - // sometimes the request are to fast, the hub will decline the request (flood security) + // sometimes the request are to fast, + // the hub will decline the request (flood security) $deviceData[$deviceId] = $this->getDeviceData((int) $deviceId); //\sleep(1); } @@ -231,13 +242,13 @@ public function setOnline(bool $isOnline): self /** * Check online state. * - * @param $ip + * @param string $ipAddress * * @return bool */ - public function checkOnline($ip): bool + public function checkOnline(string $ipAddress): bool { - $state = Online::isOnline($ip); + $state = Online::isOnline($ipAddress); $this->setOnline($state); return $state; @@ -256,11 +267,23 @@ public function checkOnline($ip): bool public function changeLightState(int $deviceId, bool $toState): bool { // get command to switch light - $onCommand = $this->commands->getLightSwitchCommand($deviceId, $toState); + $onCommand = $this + ->commands + ->getLightSwitchCommand($deviceId, $toState); + // run command - $data = Runner::execWithTimeout($onCommand, 2); + $data = Runner::execWithTimeout( + $onCommand, + 2, + true, + true + ); // verify result - if (\is_array($data) && count($data) === 4) { + if (\is_array($data) && empty($data[0])) { + /** + * @example data response is now empty since hub update + * so we only check if there is no error message inside + */ return true; } @@ -286,7 +309,7 @@ public function changeGroupState(int $groupId, bool $toState): bool $data = Runner::execWithTimeout($onCommand, 2); // verify result - if (\is_array($data) && count($data) === 4) { + if (\is_array($data) && \count($data) === 4) { return true; } @@ -312,7 +335,7 @@ public function setLightBrightness(int $lightId, int $level): bool $data = Runner::execWithTimeout($onCommand, 2); // verify result - if (\is_array($data) && count($data) === 4) { + if (\is_array($data) && \count($data) === 4) { return true; } @@ -338,7 +361,7 @@ public function setGroupBrightness(int $groupId, int $level): bool $data = Runner::execWithTimeout($onCommand, 2); // verify result - if (\is_array($data) && count($data) === 4) { + if (\is_array($data) && \count($data) === 4) { return true; } diff --git a/src/IKEA/Tradfri/Client/Client.php b/src/IKEA/Tradfri/Client/Client.php index 8b6bd768..fe335439 100644 --- a/src/IKEA/Tradfri/Client/Client.php +++ b/src/IKEA/Tradfri/Client/Client.php @@ -22,16 +22,6 @@ class Client */ protected $adapter; - /** - * Get Adapter. - * - * @return AdapterInterface - */ - private function getAdapter(): AdapterInterface - { - return $this->adapter; - } - /** * Client constructor. * @@ -56,6 +46,16 @@ public function getDevices(ServiceInterface $service): Devices return $this->getAdapter()->getDeviceCollection($service); } + /** + * Get Adapter. + * + * @return AdapterInterface + */ + private function getAdapter(): AdapterInterface + { + return $this->adapter; + } + /** * Get Groups. * @@ -89,7 +89,9 @@ public function lightOn(Lightbulb $lightbulb): bool */ public function lightOff(Lightbulb $lightbulb): bool { - return $this->getAdapter()->changeLightState($lightbulb->getId(), false); + return $this->getAdapter()->changeLightState( + $lightbulb->getId(), false + ); } /** @@ -124,9 +126,11 @@ public function groupOff(Group $group): bool * * @return bool */ - public function dimLight(Lightbulb $lightbulb, int $level):bool + public function dimLight(Lightbulb $lightbulb, int $level): bool { - return $this->getAdapter()->setLightBrightness($lightbulb->getId(), $level); + return $this->getAdapter()->setLightBrightness( + $lightbulb->getId(), $level + ); } /** diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index f2d5abf3..e92817c1 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -4,12 +4,14 @@ namespace IKEA\Tradfri\Command; +use IKEA\Tradfri\Command\Executer\Coap\Get; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Helper\Runner; /** * Class Coaps. + * @deprecated */ class Coaps { @@ -40,22 +42,31 @@ class Coaps /** * Coaps constructor. * - * @param string $ip + * @param string $ipAddress * @param string $secret * @param string $username * * @throws \InvalidArgumentException * @throws \IKEA\Tradfri\Exception\RuntimeException */ - public function __construct(string $ip, string $secret, $username = 'wrapper') + public function __construct( + string $ipAddress, + string $secret, + $username = null) { - $this->setIp($ip); + $this->setIp($ipAddress); $this->_secret = $secret; if (!\defined('COAP_API_KEY')) { throw new RuntimeException('COAP_API_KEY not set'); } + $this->setApiKey(COAP_API_KEY); - $this->setUsername($username); + + if (null !== $username) { + $this->setUsername($username); + } else { + $this->setUsername('wrapper'); + } } /** @@ -88,9 +99,14 @@ public function getSharedKeyFromGateway(): string */ public function getPreSharedKeyCommand(): string { - $command = \sprintf(self::COAP_COMMAND_POST, 'Client_identity', $this->secret) - .' -e \'{"9090":"'.$this->getUsername().'"}\'' - .' "coaps://'.$this->ip.':5684/'.CoapCommandKeys::KEY_GET_SHARED_KEY.'"'; + $command = \sprintf( + self::COAP_COMMAND_POST, + 'Client_identity', + $this->_secret + ) + . ' -e \'{"9090":"' . $this->getUsername() . '"}\'' + . ' "coaps://' . $this->getIp() . ':5684/' + . CoapCommandKeys::KEY_GET_SHARED_KEY . '"'; return $command; } @@ -135,36 +151,6 @@ public function parseResult(array $result) return false; } - /** - * Get Ip. - * - * @return string - */ - public function getIp(): string - { - return $this->_ip; - } - - /** - * Set and filter ip. - * - * @param $ipAddress - * - * @throws \InvalidArgumentException - * - * @return $this - */ - public function setIp(string $ipAddress): self - { - if (filter_var($ipAddress, FILTER_VALIDATE_IP)) { - $this->ip = $ipAddress; - - return $this; - } - - throw new \InvalidArgumentException('Invalid ip'); - } - /** * Get CoapsCommand GET string. * @@ -174,7 +160,9 @@ public function setIp(string $ipAddress): self */ public function getCoapsCommandGet($requestType): string { - return \sprintf(self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey()).' "coaps://'.$this->ip.':5684/'.$requestType.'"'; + return \sprintf( + self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey() + ) . ' "coaps://' . $this->getIp() . ':5684/' . $requestType . '"'; } /** @@ -212,11 +200,41 @@ public function setApiKey(string $apiKey): self public function getCoapsCommandPost($requestType, string $inject): string { return \sprintf( - self::COAP_COMMAND_POST, - $this->getUsername(), - $this->getApiKey() - ).$inject - .' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; + self::COAP_COMMAND_POST, + $this->getUsername(), + $this->getApiKey() + ) . $inject + . ' "coaps://' . $this->getIp() . ':5684/' . $requestType . '"'; + } + + /** + * Get Ip. + * + * @return string + */ + public function getIp(): string + { + return $this->_ip; + } + + /** + * Set and filter ip. + * + * @param $ipAddress + * + * @throws \InvalidArgumentException + * + * @return $this + */ + public function setIp(string $ipAddress): self + { + if (filter_var($ipAddress, FILTER_VALIDATE_IP)) { + $this->_ip = $ipAddress; + + return $this; + } + + throw new \InvalidArgumentException('Invalid ip'); } /** @@ -230,12 +248,12 @@ public function getCoapsCommandPost($requestType, string $inject): string public function getLightSwitchCommand(int $deviceId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$deviceId, + CoapCommandKeys::KEY_GET_DATA . '/' . $deviceId, ' -e \'{ "' - .CoapCommandKeys::KEY_DEVICE_DATA - .'": [{ "'. - CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0') - .' }] }\' ' + . CoapCommandKeys::KEY_DEVICE_DATA + . '": [{ "' . + CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' : '0') + . ' }] }\' ' ); } @@ -249,7 +267,10 @@ public function getLightSwitchCommand(int $deviceId, bool $state): string */ public function getCoapsCommandPut($requestType, string $inject): string { - return \sprintf(self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey()).$inject.' "coaps://'.$this->ip.':5684/'.$requestType.'"'; + return \sprintf( + self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey() + ) . $inject . ' "coaps://' . $this->getIp() . ':5684/' . $requestType + . '"'; } /** @@ -263,8 +284,9 @@ public function getCoapsCommandPut($requestType, string $inject): string public function getGroupSwitchCommand(int $groupId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0').' }\' ' + CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, + ' -e \'{ "' . CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' + : '0') . ' }\' ' ); } @@ -279,8 +301,10 @@ public function getGroupSwitchCommand(int $groupId, bool $state): string public function getGroupDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55).' }\' ' + CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, + ' -e \'{ "' . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round( + $value * 2.55 + ) . ' }\' ' ); } @@ -295,8 +319,10 @@ public function getGroupDimmerCommand(int $groupId, int $value): string public function getLightDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55).' }] }\' ' + CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, + ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' + . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round($value * 2.55) + . ' }] }\' ' ); } @@ -304,7 +330,7 @@ public function getLightDimmerCommand(int $groupId, int $value): string * Get Command to dim light. * * @param int $groupId - * @param string $color (warm|normal|cold) + * @param string $color (warm|normal|cold) * * @throws \IKEA\Tradfri\Exception\RuntimeException * @@ -312,7 +338,9 @@ public function getLightDimmerCommand(int $groupId, int $value): string */ public function getLightColorCommand(int $groupId, string $color): string { - $payload = ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "'.CoapCommandKeys::KEY_COLOR.'": %s, "'.CoapCommandKeys::KEY_COLOR_2.'": %s }] }\' '; + $payload = ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' + . CoapCommandKeys::KEY_COLOR . '": %s, "' + . CoapCommandKeys::KEY_COLOR_2 . '": %s }] }\' '; switch ($color) { case 'warm': $payload = \sprintf($payload, '33135', '27211'); @@ -328,7 +356,7 @@ public function getLightColorCommand(int $groupId, string $color): string } return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, + CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, $payload ); } diff --git a/src/IKEA/Tradfri/Device/Lightbulb.php b/src/IKEA/Tradfri/Device/Lightbulb.php index b4610d31..6b28431a 100644 --- a/src/IKEA/Tradfri/Device/Lightbulb.php +++ b/src/IKEA/Tradfri/Device/Lightbulb.php @@ -26,7 +26,7 @@ class Lightbulb extends Device */ public function getBrightness(): float { - return (float) $this->brightness; + return (float)$this->brightness; } /** @@ -76,7 +76,7 @@ public function off(): bool */ public function on(): bool { - if ($this->getService()->on($this) === true) { + if ($this->getService()->switchOn($this) === true) { $this->setState(true); return true; diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index 2255bc78..d2af3963 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -12,19 +12,25 @@ class Runner { /** - * Execute a command and return it's output. Either wait until the command exits or the timeout has expired. + * Execute a command and return it's output. Either wait + * until the command exits or the timeout has expired. * Found at @link https://stackoverflow.com/a/20992213/3578430. * * @param string $cmd Command to execute. * @param int $timeout Timeout in seconds. * @param bool $asArray + * @param bool $skipEmptyBufferError * * @throws \IKEA\Tradfri\Exception\RuntimeException * * @return array|string */ - public static function execWithTimeout(string $cmd, int $timeout, $asArray = true) - { + public static function execWithTimeout( + string $cmd, + int $timeout, + $asArray = true, + bool $skipEmptyBufferError = false + ) { // File descriptors passed to the process. $descriptors = [ 0 => ['pipe', 'r'], // stdin @@ -35,8 +41,8 @@ public static function execWithTimeout(string $cmd, int $timeout, $asArray = tru // Start the process. $process = proc_open('exec '.$cmd, $descriptors, $pipes); - if (!is_resource($process)) { - throw new \RuntimeException('Could not execute process'); + if (!\is_resource($process)) { + throw new RuntimeException('Could not execute process'); } // Set the stdout stream to none-blocking. @@ -59,15 +65,18 @@ public static function execWithTimeout(string $cmd, int $timeout, $asArray = tru // Get the status of the process. // Do this before we read from the stream, - // this way we can't lose the last bit of output if the process dies between these functions. + // this way we can't lose the last bit + // of output if the process dies between these functions. $status = proc_get_status($process); // Read the contents from the buffer. - // This function will always return immediately as the stream is none-blocking. + // This function will always return immediately + // as the stream is none-blocking. $buffer .= stream_get_contents($pipes[1]); if (!$status['running']) { - // Break from this loop if the process exited before the timeout. + // Break from this loop if the process exited + // before the timeout. break; } @@ -83,10 +92,15 @@ public static function execWithTimeout(string $cmd, int $timeout, $asArray = tru if (\count($parts) === 3) { $errorMessage = $parts[1]; } else { - $errorMessage = $errors; + if (\count($parts) === 2 && !empty($parts[1])) { + $errorMessage = $parts[1]; + } else { + $errorMessage = 'Unknown error'; + } + } + if ($skipEmptyBufferError === false) { + throw new RuntimeException($errorMessage); } - - throw new RuntimeException($errorMessage); } // Kill the process in case the timeout expired and it's still running. diff --git a/src/IKEA/Tradfri/Mapper/DeviceData.php b/src/IKEA/Tradfri/Mapper/DeviceData.php index f1b561ae..2920faf9 100644 --- a/src/IKEA/Tradfri/Mapper/DeviceData.php +++ b/src/IKEA/Tradfri/Mapper/DeviceData.php @@ -33,7 +33,7 @@ class DeviceData extends Mapper */ public function map(ServiceInterface $service, array $devices): AbstractCollection { - if (count($devices) > 0) { + if (\count($devices) > 0) { $collection = new Devices(); foreach ($devices as $device) { if (false === $this->_isValidData($device)) { diff --git a/src/IKEA/Tradfri/Service/Api.php b/src/IKEA/Tradfri/Service/Api.php index e858daee..91f6a949 100644 --- a/src/IKEA/Tradfri/Service/Api.php +++ b/src/IKEA/Tradfri/Service/Api.php @@ -76,10 +76,12 @@ public function getGroups(): Groups public function allLightsOff(Lightbulbs $lightbulbsCollection): bool { $service = $this; - $lightbulbsCollection->forAll(function ($key, $lightbulb) use ($service) { - /* @var Lightbulb $lightbulb */ - $service->off($lightbulb); - }); + $lightbulbsCollection->forAll( + function ($key, $lightbulb) use ($service) { + /* @var Lightbulb $lightbulb */ + $service->off($lightbulb); + } + ); return true; } @@ -93,7 +95,7 @@ public function allLightsOff(Lightbulbs $lightbulbsCollection): bool * * @return bool */ - public function on($device): bool + public function switchOn($device): bool { if ($device instanceof Light) { return $this->client->groupOn($device); @@ -106,6 +108,21 @@ public function on($device): bool throw new RuntimeException('invalid device type: '.$device->getType()); } + /** + * Switch device on. + * + * @param Device|Light $device + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + * @deprecated + * @see Api::switchOn + * @return bool + */ + public function on($device): bool + { + return $this->switchOn($device); + } + /** * Switch device off. * diff --git a/src/IKEA/Tradfri/Service/ServiceInterface.php b/src/IKEA/Tradfri/Service/ServiceInterface.php index d0aee79d..388f87ba 100644 --- a/src/IKEA/Tradfri/Service/ServiceInterface.php +++ b/src/IKEA/Tradfri/Service/ServiceInterface.php @@ -48,7 +48,7 @@ public function allLightsOff(Lightbulbs $lightbulbsCollection): bool; * * @return bool */ - public function on($device): bool; + public function switchOn($device): bool; /** * Switch state of. diff --git a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php index e6ce2be5..d5dc483e 100644 --- a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php +++ b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php @@ -168,7 +168,7 @@ public function testICanSwitchOnFails() /** @var ServiceInterface $service */ $service = \Mockery::mock(Api::class); - $service->shouldReceive('on')->andReturn(false); + $service->shouldReceive('switchOn')->andReturn(false); $lamp->setService($service); $this->assertFalse($lamp->isOn()); diff --git a/tests/unit/IKEA/Tradfri/Service/ApiTest.php b/tests/unit/IKEA/Tradfri/Service/ApiTest.php index eeb1a9ca..285d2a0b 100644 --- a/tests/unit/IKEA/Tradfri/Service/ApiTest.php +++ b/tests/unit/IKEA/Tradfri/Service/ApiTest.php @@ -134,7 +134,7 @@ public function testICanSwitchLightOn() $this->assertFalse($lightbulb->isOn()); // Act - $result = $service->on($lightbulb); + $result = $service->switchOn($lightbulb); // Assert $this->assertTrue($result); @@ -158,7 +158,7 @@ public function testICanNotSwitchLightOn() $this->assertFalse($lightbulb->isOn()); // Act - $result = $service->on($lightbulb); + $result = $service->switchOn($lightbulb); } public function testICanNotSwitchLightOnBecauseItIsOn() @@ -175,7 +175,7 @@ public function testICanNotSwitchLightOnBecauseItIsOn() $this->assertTrue($lightbulb->isOn()); // Act - $result = $service->on($lightbulb); + $result = $service->switchOn($lightbulb); // Assert $this->assertTrue($result); } @@ -218,7 +218,7 @@ public function testICanNotSwitchGroupOnBecauseItIsOn() $this->assertTrue($group->isOn()); // Act - $result = $service->on($group); + $result = $service->switchOn($group); // Assert $this->assertTrue($result); } @@ -237,7 +237,7 @@ public function testICanSwitchGroupOn() $this->assertFalse($group->isOn()); // Act - $result = $service->on($group); + $result = $service->switchOn($group); // Assert $this->assertTrue($result); } @@ -273,7 +273,7 @@ public function testICanSwitchADimmerOn() $client = \Mockery::mock(Client::class); $service = new Api($client); // Act - $result = $service->on($dimmer); + $result = $service->switchOn($dimmer); } public function testICanSwitchADimmerOff() @@ -303,7 +303,7 @@ public function testICanSwitchARemoteOn() $client = \Mockery::mock(Client::class); $service = new Api($client); // Act - $result = $service->on($remote); + $result = $service->switchOn($remote); } public function testICanSwitchARemoteOff() diff --git a/wiki/example/example-light-switch.php b/wiki/example/example-light-switch.php index 65ecf406..45df63bb 100644 --- a/wiki/example/example-light-switch.php +++ b/wiki/example/example-light-switch.php @@ -1,6 +1,8 @@ sortByState(); if (false ===$lights->isEmpty()) { - $light = $lights->first(); - echo '---------- IKEA Tradfri PHP API Example: '.basename(__FILE__).PHP_EOL; + /** @var Lightbulb $light */ + $light = $lights->find( + function ($light) { + /** @var Lightbulb $light */ + return $light->getName() === 'Wohnzimmer - Schreibtisch'; + } + ); echo '---------- Light Information'.PHP_EOL; echo ' '.PHP_EOL; echo '- ID: ' . $light->getId(). PHP_EOL; From f77e0f3ca17a2e6562988ff360e3042983237c0c Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Mon, 15 Jan 2018 22:56:39 +0100 Subject: [PATCH 21/73] code style and more function renaming --- src/IKEA/Tradfri/Device/Lightbulb.php | 12 ++++---- src/IKEA/Tradfri/Group/Light.php | 5 ++-- .../IKEA/Tradfri/Device/LightbulbTest.php | 30 ++++++++++++------- wiki/example/example-dim-group.php | 2 +- wiki/example/example-dim-light.php | 2 +- wiki/example/example-group-switch.php | 2 +- wiki/example/example-light-switch.php | 4 +-- 7 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/IKEA/Tradfri/Device/Lightbulb.php b/src/IKEA/Tradfri/Device/Lightbulb.php index 6b28431a..1334dbdd 100644 --- a/src/IKEA/Tradfri/Device/Lightbulb.php +++ b/src/IKEA/Tradfri/Device/Lightbulb.php @@ -4,6 +4,8 @@ namespace IKEA\Tradfri\Device; +use IKEA\Tradfri\Exception\RuntimeException; + /** * Class Lamp. */ @@ -56,15 +58,14 @@ public function setBrightness(int $brightness): self * * @return bool */ - public function off(): bool + public function switchOff(): bool { if ($this->getService()->off($this) === true) { $this->setState(false); return true; } - - return false; + throw new RuntimeException('switch OFF failed'); } /** @@ -74,15 +75,14 @@ public function off(): bool * * @return bool */ - public function on(): bool + public function switchOn(): bool { if ($this->getService()->switchOn($this) === true) { $this->setState(true); - return true; } - return false; + throw new RuntimeException('switch ON failed'); } /** diff --git a/src/IKEA/Tradfri/Group/Light.php b/src/IKEA/Tradfri/Group/Light.php index 6769cfc5..f12fcdbf 100644 --- a/src/IKEA/Tradfri/Group/Light.php +++ b/src/IKEA/Tradfri/Group/Light.php @@ -38,11 +38,12 @@ public function isOn(): bool /** * Switch group on. * + * @throws \IKEA\Tradfri\Exception\RuntimeException * @return $this */ - public function on(): self + public function switchOn(): self { - if ($this->service->on($this)) { + if ($this->service->switchOn($this)) { $this->setState(true); } diff --git a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php index d5dc483e..6343a6c4 100644 --- a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php +++ b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php @@ -73,7 +73,7 @@ public function testGetBrightness() { // Arrange $lamp = $this->_getModel(); - $lamp->setBrightness((int) round(30*2.54)); + $lamp->setBrightness((int)round(30 * 2.54)); // Act $result = $lamp->getBrightness(); @@ -146,7 +146,7 @@ public function testICanSwitchOn() $this->assertFalse($lamp->isOn()); // Act - $result = $lamp->on(); + $result = $lamp->switchOn(); // Assert $this->assertTrue($result); @@ -154,7 +154,7 @@ public function testICanSwitchOn() $this->assertSame('On', $lamp->getState()); // Act - $result = $lamp->on(); + $result = $lamp->switchOn(); // Assert $this->assertTrue($result); $this->assertTrue($lamp->isOn()); @@ -163,6 +163,8 @@ public function testICanSwitchOn() public function testICanSwitchOnFails() { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('switch ON failed'); // Arrange $lamp = $this->_getModel(); @@ -174,7 +176,7 @@ public function testICanSwitchOnFails() $this->assertFalse($lamp->isOn()); // Act - $result = $lamp->on(); + $result = $lamp->switchOn(); // Assert $this->assertFalse($result); @@ -196,7 +198,7 @@ public function testICanSwitchOff() $this->assertFalse($lamp->isOn()); // Act - $result = $lamp->off(); + $result = $lamp->switchOff(); // Assert $this->assertTrue($result); @@ -204,7 +206,7 @@ public function testICanSwitchOff() $this->assertSame('Off', $lamp->getState()); // Act - $result = $lamp->off(); + $result = $lamp->switchOff(); // Assert $this->assertTrue($result); @@ -223,7 +225,11 @@ public function testICanSwitchOffFails() /** var Client $client */ $client = \Mockery::mock(Client::class); - $client->shouldReceive('lightOff')->andThrow(new RuntimeException('unable to change state of lightbulb: 1')); + $client + ->shouldReceive('lightOff') + ->andThrow( + new RuntimeException('unable to change state of lightbulb: 1') + ); $service = new Api($client); @@ -231,7 +237,7 @@ public function testICanSwitchOffFails() $this->assertTrue($lamp->isOn()); // Act - $result = $lamp->off(); + $result = $lamp->switchOff(); // Assert $this->assertFalse($result); @@ -241,6 +247,10 @@ public function testICanSwitchOffFails() public function testICanSwitchOffReturnedFalse() { + // Assert + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('switch OFF failed'); + // Arrange $lamp = $this->_getModel(); $service = \Mockery::mock(Api::class); @@ -253,7 +263,7 @@ public function testICanSwitchOffReturnedFalse() $this->assertTrue($lamp->isOn()); // Act - $result = $lamp->off(); + $result = $lamp->switchOff(); // Assert $this->assertFalse($result); @@ -261,7 +271,7 @@ public function testICanSwitchOffReturnedFalse() $this->assertSame('On', $lamp->getState()); // Act 2 - $result = $lamp->off(); + $result = $lamp->switchOff(); // Assert 2 $this->assertFalse($result); diff --git a/wiki/example/example-dim-group.php b/wiki/example/example-dim-group.php index 2127ee09..b6457f2e 100644 --- a/wiki/example/example-dim-group.php +++ b/wiki/example/example-dim-group.php @@ -35,7 +35,7 @@ echo '---------- Switch Group'.PHP_EOL; echo 'group is: ' . ($group->isOn() ? 'on' : 'off') . PHP_EOL; echo 'brightness is: ' . $group->getBrightness() . PHP_EOL; - $group->isOn() ? null : $group->on(); + $group->isOn() ? null : $group->switchOn(); if ($group->isOn()) { if ($group->dim(15)) { echo 'dim to 15'. PHP_EOL; diff --git a/wiki/example/example-dim-light.php b/wiki/example/example-dim-light.php index dc27d59d..e35f7505 100644 --- a/wiki/example/example-dim-light.php +++ b/wiki/example/example-dim-light.php @@ -23,7 +23,7 @@ echo ' '.PHP_EOL; echo '---------- Check State'.PHP_EOL; if (!$light->isOn()) { - if ($light->on()) { + if ($light->switchOn()) { echo 'switched on'. PHP_EOL; } } diff --git a/wiki/example/example-group-switch.php b/wiki/example/example-group-switch.php index 42e6f2a8..de28fc58 100644 --- a/wiki/example/example-group-switch.php +++ b/wiki/example/example-group-switch.php @@ -39,7 +39,7 @@ echo 'switched off'. PHP_EOL; } } else { - if ($group->on()) { + if ($group->switchOn()) { echo 'switched on'. PHP_EOL; } } diff --git a/wiki/example/example-light-switch.php b/wiki/example/example-light-switch.php index 45df63bb..a42a34e2 100644 --- a/wiki/example/example-light-switch.php +++ b/wiki/example/example-light-switch.php @@ -30,11 +30,11 @@ function ($light) { echo ' '.PHP_EOL; echo '---------- Change State'.PHP_EOL; if ($light->isOn()) { - if ($light->off()) { + if ($light->switchOff()) { echo 'switched off'. PHP_EOL; } } else { - if ($light->on()) { + if ($light->switchOn()) { echo 'switched on'. PHP_EOL; } } From 099035dd6e4621674ba557e92d993f0015599ecb Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Mon, 15 Jan 2018 21:56:57 +0000 Subject: [PATCH 22/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Adapter/Coap.php | 2 +- .../Tradfri/Collection/AbstractCollection.php | 3 +- src/IKEA/Tradfri/Command/Coaps.php | 57 ++++++++++--------- src/IKEA/Tradfri/Device/Device.php | 9 ++- src/IKEA/Tradfri/Device/Lightbulb.php | 4 +- src/IKEA/Tradfri/Group/Light.php | 1 + src/IKEA/Tradfri/Helper/Runner.php | 4 +- src/IKEA/Tradfri/Service/Api.php | 2 + 8 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index d1f2cf8e..29cbf502 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -280,7 +280,7 @@ public function changeLightState(int $deviceId, bool $toState): bool ); // verify result if (\is_array($data) && empty($data[0])) { - /** + /* * @example data response is now empty since hub update * so we only check if there is no error message inside */ diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index 46e1dd4a..37caa571 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -67,9 +67,10 @@ public function jsonSerialize() { $data = []; foreach ($this->toArray() as $device) { - /** @var Device $device */ + /* @var Device $device */ $data[$device->getId()] = $device->jsonSerialize(); } + return $data; } } diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index e92817c1..39ad51c9 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -11,6 +11,7 @@ /** * Class Coaps. + * * @deprecated */ class Coaps @@ -104,9 +105,9 @@ public function getPreSharedKeyCommand(): string 'Client_identity', $this->_secret ) - . ' -e \'{"9090":"' . $this->getUsername() . '"}\'' - . ' "coaps://' . $this->getIp() . ':5684/' - . CoapCommandKeys::KEY_GET_SHARED_KEY . '"'; + .' -e \'{"9090":"'.$this->getUsername().'"}\'' + .' "coaps://'.$this->getIp().':5684/' + .CoapCommandKeys::KEY_GET_SHARED_KEY.'"'; return $command; } @@ -162,7 +163,7 @@ public function getCoapsCommandGet($requestType): string { return \sprintf( self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey() - ) . ' "coaps://' . $this->getIp() . ':5684/' . $requestType . '"'; + ).' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; } /** @@ -203,8 +204,8 @@ public function getCoapsCommandPost($requestType, string $inject): string self::COAP_COMMAND_POST, $this->getUsername(), $this->getApiKey() - ) . $inject - . ' "coaps://' . $this->getIp() . ':5684/' . $requestType . '"'; + ).$inject + .' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; } /** @@ -248,12 +249,12 @@ public function setIp(string $ipAddress): self public function getLightSwitchCommand(int $deviceId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA . '/' . $deviceId, + CoapCommandKeys::KEY_GET_DATA.'/'.$deviceId, ' -e \'{ "' - . CoapCommandKeys::KEY_DEVICE_DATA - . '": [{ "' . - CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' : '0') - . ' }] }\' ' + .CoapCommandKeys::KEY_DEVICE_DATA + .'": [{ "'. + CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0') + .' }] }\' ' ); } @@ -269,8 +270,8 @@ public function getCoapsCommandPut($requestType, string $inject): string { return \sprintf( self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey() - ) . $inject . ' "coaps://' . $this->getIp() . ':5684/' . $requestType - . '"'; + ).$inject.' "coaps://'.$this->getIp().':5684/'.$requestType + .'"'; } /** @@ -284,9 +285,9 @@ public function getCoapsCommandPut($requestType, string $inject): string public function getGroupSwitchCommand(int $groupId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, - ' -e \'{ "' . CoapCommandKeys::KEY_ONOFF . '": ' . ($state ? '1' - : '0') . ' }\' ' + CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, + ' -e \'{ "'.CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' + : '0').' }\' ' ); } @@ -301,10 +302,10 @@ public function getGroupSwitchCommand(int $groupId, bool $state): string public function getGroupDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS . '/' . $groupId, - ' -e \'{ "' . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round( + CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, + ' -e \'{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round( $value * 2.55 - ) . ' }\' ' + ).' }\' ' ); } @@ -319,10 +320,10 @@ public function getGroupDimmerCommand(int $groupId, int $value): string public function getLightDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, - ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' - . CoapCommandKeys::KEY_DIMMER . '": ' . (int)round($value * 2.55) - . ' }] }\' ' + CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, + ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "' + .CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55) + .' }] }\' ' ); } @@ -330,7 +331,7 @@ public function getLightDimmerCommand(int $groupId, int $value): string * Get Command to dim light. * * @param int $groupId - * @param string $color (warm|normal|cold) + * @param string $color (warm|normal|cold) * * @throws \IKEA\Tradfri\Exception\RuntimeException * @@ -338,9 +339,9 @@ public function getLightDimmerCommand(int $groupId, int $value): string */ public function getLightColorCommand(int $groupId, string $color): string { - $payload = ' -e \'{ "' . CoapCommandKeys::KEY_DEVICE_DATA . '": [{ "' - . CoapCommandKeys::KEY_COLOR . '": %s, "' - . CoapCommandKeys::KEY_COLOR_2 . '": %s }] }\' '; + $payload = ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "' + .CoapCommandKeys::KEY_COLOR.'": %s, "' + .CoapCommandKeys::KEY_COLOR_2.'": %s }] }\' '; switch ($color) { case 'warm': $payload = \sprintf($payload, '33135', '27211'); @@ -356,7 +357,7 @@ public function getLightColorCommand(int $groupId, string $color): string } return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA . '/' . $groupId, + CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, $payload ); } diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index 07f32845..33cd8288 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -259,10 +259,13 @@ public function isValidType($type): bool } /** - * Specify data which should be serialized to JSON + * Specify data which should be serialized to JSON. + * * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * * @return mixed data which can be serialized by json_encode, - * which is a value of any type other than a resource. + * which is a value of any type other than a resource. + * * @since 5.4.0 */ public function jsonSerialize(): array @@ -271,7 +274,7 @@ public function jsonSerialize(): array foreach (get_class_methods(static::class) as $method) { if ($method !== 'getService' && strpos($method, 'get') === 0) { - $key = strtolower((string)substr($method, 3)); + $key = strtolower((string) substr($method, 3)); $data[$key] = $this->$method(); } diff --git a/src/IKEA/Tradfri/Device/Lightbulb.php b/src/IKEA/Tradfri/Device/Lightbulb.php index 1334dbdd..ac9bc23c 100644 --- a/src/IKEA/Tradfri/Device/Lightbulb.php +++ b/src/IKEA/Tradfri/Device/Lightbulb.php @@ -28,7 +28,7 @@ class Lightbulb extends Device */ public function getBrightness(): float { - return (float)$this->brightness; + return (float) $this->brightness; } /** @@ -65,6 +65,7 @@ public function switchOff(): bool return true; } + throw new RuntimeException('switch OFF failed'); } @@ -79,6 +80,7 @@ public function switchOn(): bool { if ($this->getService()->switchOn($this) === true) { $this->setState(true); + return true; } diff --git a/src/IKEA/Tradfri/Group/Light.php b/src/IKEA/Tradfri/Group/Light.php index f12fcdbf..8fa77b00 100644 --- a/src/IKEA/Tradfri/Group/Light.php +++ b/src/IKEA/Tradfri/Group/Light.php @@ -39,6 +39,7 @@ public function isOn(): bool * Switch group on. * * @throws \IKEA\Tradfri\Exception\RuntimeException + * * @return $this */ public function switchOn(): self diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index d2af3963..9319cfa0 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -16,8 +16,8 @@ class Runner * until the command exits or the timeout has expired. * Found at @link https://stackoverflow.com/a/20992213/3578430. * - * @param string $cmd Command to execute. - * @param int $timeout Timeout in seconds. + * @param string $cmd Command to execute. + * @param int $timeout Timeout in seconds. * @param bool $asArray * @param bool $skipEmptyBufferError * diff --git a/src/IKEA/Tradfri/Service/Api.php b/src/IKEA/Tradfri/Service/Api.php index 91f6a949..c1368a19 100644 --- a/src/IKEA/Tradfri/Service/Api.php +++ b/src/IKEA/Tradfri/Service/Api.php @@ -114,8 +114,10 @@ public function switchOn($device): bool * @param Device|Light $device * * @throws \IKEA\Tradfri\Exception\RuntimeException + * * @deprecated * @see Api::switchOn + * * @return bool */ public function on($device): bool From 3b9600fa6358e972deb9434fd6c82544319a5d17 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 20 Jan 2018 03:49:10 +0100 Subject: [PATCH 23/73] new .php_cs and new .codeclimate.yml settings among with a lot of code style fixes --- .codeclimate.yml | 17 +- .php_cs | 126 +++++--- composer.json | 10 +- src/IKEA/Tradfri/Adapter/AdapterAbstract.php | 48 ++- src/IKEA/Tradfri/Adapter/AdapterInterface.php | 2 +- src/IKEA/Tradfri/Adapter/Coap.php | 295 +++++++++--------- src/IKEA/Tradfri/Client/Client.php | 6 +- .../Tradfri/Collection/AbstractCollection.php | 7 +- src/IKEA/Tradfri/Collection/Devices.php | 6 +- src/IKEA/Tradfri/Collection/Groups.php | 2 +- src/IKEA/Tradfri/Collection/Lightbulbs.php | 16 +- src/IKEA/Tradfri/Command/Coaps.php | 127 ++++---- src/IKEA/Tradfri/Command/CommandAbstract.php | 53 ---- src/IKEA/Tradfri/Device/Device.php | 80 ++--- src/IKEA/Tradfri/Device/Dimmer.php | 6 +- src/IKEA/Tradfri/Device/Lightbulb.php | 14 +- src/IKEA/Tradfri/Device/MotionSensor.php | 6 +- src/IKEA/Tradfri/Device/Remote.php | 6 +- src/IKEA/Tradfri/Group/Device.php | 106 +++---- src/IKEA/Tradfri/Group/Light.php | 26 +- src/IKEA/Tradfri/Helper/CoapCommandKeys.php | 28 +- src/IKEA/Tradfri/Helper/Online.php | 52 ++- src/IKEA/Tradfri/Helper/Runner.php | 30 +- src/IKEA/Tradfri/Mapper/DeviceData.php | 118 +++---- src/IKEA/Tradfri/Mapper/GroupData.php | 52 +-- src/IKEA/Tradfri/Mapper/MapperInterface.php | 5 +- src/IKEA/Tradfri/Service/Api.php | 61 ++-- src/IKEA/Tradfri/Validator/Device/Data.php | 140 +++++++++ src/IKEA/Tradfri/Validator/Group/Data.php | 91 ++++++ .../Tradfri/Validator/ValidatorInterface.php | 19 ++ tests/_support/Helper/Unit.php | 8 +- tests/_support/UnitTester.php | 5 +- tests/unit/IKEA/Tradfri/Client/ClientTest.php | 12 +- .../unit/IKEA/Tradfri/Device/DeviceTester.php | 2 +- .../IKEA/Tradfri/Device/LightbulbTest.php | 6 +- tests/unit/IKEA/Tradfri/Group/LightTest.php | 4 +- .../IKEA/Tradfri/Mapper/DeviceDataTest.php | 3 +- .../IKEA/Tradfri/Mapper/GroupDataTest.php | 4 +- tests/unit/IKEA/Tradfri/Service/ApiTest.php | 18 +- wiki/example/example-light-info.php | 2 +- wiki/example/example-list-lights.php | 26 +- 41 files changed, 958 insertions(+), 687 deletions(-) delete mode 100644 src/IKEA/Tradfri/Command/CommandAbstract.php create mode 100644 src/IKEA/Tradfri/Validator/Device/Data.php create mode 100644 src/IKEA/Tradfri/Validator/Group/Data.php create mode 100644 src/IKEA/Tradfri/Validator/ValidatorInterface.php diff --git a/.codeclimate.yml b/.codeclimate.yml index bb07e41d..7d6ffa58 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -37,24 +37,31 @@ plugins: config: file_extensions: - php - rulesets: "design,unusedcode,codesize" + rulesets: "unusedcode,codesize,naming,build/configs/ruleset.xml" phpcodesniffer: enabled: true config: file_extensions: "php" - standard: "Zend,PSR2,PSR1" + standard: "Zend" checks: + Squiz ControlStructures ControlSignature NewlineAfterOpenBrace: + enabled: false PSR2 Methods MethodDeclaration Underscore: enabled: false PSR2 Classes PropertyDeclaration Underscore: enabled: false PSR1 Files SideEffects FoundWithSymbols: enabled: false - SonarPHP: + sonar-php: enabled: true + config: + tests_patterns: + - test/unit/** duplication: enabled: true exclude_patterns: -- "**/tests/**Test.php" -- "**/vendor/" +- .git/**/* +- vendor/**/* +- tests/**/* +- wiki/**/* diff --git a/.php_cs b/.php_cs index 8cc1b230..580a4159 100644 --- a/.php_cs +++ b/.php_cs @@ -1,60 +1,82 @@ setRiskyAllowed(true) - ->setRules([ - '@PHP56Migration' => true, - 'encoding' => true, - 'single_blank_line_at_eof' => true, - 'no_spaces_after_function_name' => true, - 'no_closing_tag' => true, - 'object_operator_without_whitespace' => true, - 'single_import_per_statement' => true, - 'method_argument_space' => true, - 'line_ending' => true, - 'no_alias_functions' => true, - 'no_empty_statement' => true, - 'indentation_type' => true, - 'blank_line_after_namespace' => true, - 'lowercase_keywords' => true, - 'no_spaces_inside_parenthesis' => true, - 'braces' => true, - 'no_trailing_whitespace' => true, - 'no_unused_imports' => true, - 'no_whitespace_in_blank_line' => true, - 'visibility_required' => true, - 'standardize_not_equals' => true, - 'full_opening_tag' => true, - 'array_syntax' => ['syntax' => 'short'], - 'combine_consecutive_unsets' => true, - // one should use PHPUnit methods to set up expected exception instead of annotations - 'general_phpdoc_annotation_remove' => ['expectedException', 'expectedExceptionMessage', 'expectedExceptionMessageRegExp'], - // 'header_comment' => ['header' => $header], - 'heredoc_to_nowdoc' => true, - 'list_syntax' => ['syntax' => 'long'], - 'no_extra_consecutive_blank_lines' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block'], - 'no_short_echo_tag' => true, - 'no_unreachable_default_argument_value' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'ordered_class_elements' => false, - 'ordered_imports' => true, - 'php_unit_strict' => true, - 'php_unit_test_class_requires_covers' => false, - 'phpdoc_add_missing_param_annotation' => true, - 'phpdoc_order' => true, - 'semicolon_after_instruction' => true, - 'strict_comparison' => true, - 'strict_param' => true, - ]) + ->setRules( + [ + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => [ + 'align_double_arrow' => true, + 'align_equals' => true + ], + 'blank_line_after_namespace' => true, + 'blank_line_before_statement' => [ + 'statements' => [ + 'break', + 'continue', + 'return', + 'throw', + 'try', + ], + ], + 'braces' => true, + 'cast_spaces' => true, + 'concat_space' => ['spacing' => 'none'], + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'function_declaration' => true, + /*'header_comment' => ['header' => $header, 'separate' => 'none'],*/ + 'indentation_type' => true, + 'line_ending' => true, + 'lowercase_constants' => true, + 'lowercase_keywords' => true, + 'method_argument_space' => true, + 'native_function_invocation' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_closing_tag' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_consecutive_blank_lines' => true, + 'no_leading_namespace_whitespace' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_whitespace' => true, + 'no_unused_imports' => true, + 'no_whitespace_in_blank_line' => true, + 'phpdoc_align' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_var_without_name' => true, + 'self_accessor' => true, + 'simplified_null_return' => true, + 'single_blank_line_at_eof' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_quote' => true, + 'ternary_operator_spaces' => true, + 'trim_array_spaces' => true, + 'visibility_required' => true, + ] + ) ->setFinder( PhpCsFixer\Finder::create() - ->ignoreDotFiles(true) - ->in(__DIR__.'/src') - ->in(__DIR__.'/tests') - ->exclude(__DIR__.'/vendor') - ) - ; + ->files() + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/tests') + ->name('*.php') + ); diff --git a/composer.json b/composer.json index a5420d43..fd54a037 100644 --- a/composer.json +++ b/composer.json @@ -15,14 +15,14 @@ "homepage": "https://www.webproject.xyz", "require": { "php": "^7", - "doctrine/collections": "^1" + "doctrine/collections": "1.4.*" }, "require-dev": { "codeception/codeception": "^2", - "mockery/mockery": "^1", - "symfony/phpunit-bridge": "^3.3", - "friendsofphp/php-cs-fixer": "^2", - "codeclimate/php-test-reporter": "^0" + "mockery/mockery": "1.*", + "symfony/phpunit-bridge": "3.*", + "friendsofphp/php-cs-fixer": "2.*", + "codeclimate/php-test-reporter": "0.*" }, "autoload": { "psr-4": { diff --git a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php index cd847e64..b9879fd5 100644 --- a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php +++ b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php @@ -19,17 +19,25 @@ abstract class AdapterAbstract implements AdapterInterface /** * @var MapperInterface|DeviceData */ - protected $deviceDataMapper; + protected $_deviceDataMapper; /** * @var MapperInterface|GroupData */ - protected $groupDataMapper; + protected $_groupDataMapper; - public function __construct(MapperInterface $deviceDataMapper, MapperInterface $groupDataMapper) - { - $this->deviceDataMapper = $deviceDataMapper; - $this->groupDataMapper = $groupDataMapper; + /** + * AdapterAbstract constructor. + * + * @param MapperInterface $deviceDataMapper + * @param MapperInterface $groupDataMapper + */ + public function __construct( + MapperInterface $deviceDataMapper, + MapperInterface $groupDataMapper + ) { + $this->_deviceDataMapper = $deviceDataMapper; + $this->_groupDataMapper = $groupDataMapper; } /** @@ -39,7 +47,9 @@ public function __construct(MapperInterface $deviceDataMapper, MapperInterface $ * * @return Devices */ - abstract public function getDeviceCollection(ServiceInterface $service): Devices; + abstract public function getDeviceCollection( + ServiceInterface $service + ): Devices; /** * Get a collection of Groups. @@ -48,5 +58,27 @@ abstract public function getDeviceCollection(ServiceInterface $service): Devices * * @return Groups */ - abstract public function getGroupCollection(ServiceInterface $service): Groups; + abstract public function getGroupCollection( + ServiceInterface $service + ): Groups; + + /** + * Get DeviceDataMapper + * + * @return DeviceData|MapperInterface + */ + public function getDeviceDataMapper() + { + return $this->_deviceDataMapper; + } + + /** + * Get GroupDataMapper + * + * @return GroupData|MapperInterface + */ + public function getGroupDataMapper() + { + return $this->_groupDataMapper; + } } diff --git a/src/IKEA/Tradfri/Adapter/AdapterInterface.php b/src/IKEA/Tradfri/Adapter/AdapterInterface.php index 4df72152..1c499910 100644 --- a/src/IKEA/Tradfri/Adapter/AdapterInterface.php +++ b/src/IKEA/Tradfri/Adapter/AdapterInterface.php @@ -20,7 +20,7 @@ interface AdapterInterface * * @return \stdClass */ - public function getDeviceData(int $deviceId); + public function getDeviceData(int $deviceId): \stdClass; /** * Get device ids as array. diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index 29cbf502..f47dc31c 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -7,7 +7,6 @@ use IKEA\Tradfri\Collection\Devices; use IKEA\Tradfri\Collection\Groups; use IKEA\Tradfri\Command\Coaps; -use IKEA\Tradfri\Device\Group; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Group\Light; use IKEA\Tradfri\Helper\CoapCommandKeys; @@ -21,15 +20,16 @@ */ class Coap extends AdapterAbstract { + const COULD_NOT_SWITCH_STATE = 'Could not switch state'; /** * @var Coaps */ - private $commands; + protected $_commands; /** * @var bool */ - private $isOnline = false; + protected $_isOnline = false; /** * Coap constructor. @@ -43,13 +43,42 @@ public function __construct( MapperInterface $deviceDataMapper, MapperInterface $groupDataMapper ) { - $this->commands = $commands; + $this->_commands = $commands; $this->checkOnline($commands->getIp()); parent::__construct($deviceDataMapper, $groupDataMapper); } + /** + * Check online state. + * + * @param string $ipAddress + * + * @return bool + */ + public function checkOnline(string $ipAddress): bool + { + $state = Online::isOnline($ipAddress); + $this->setOnline($state); + + return $state; + } + + /** + * Set IsOnline. + * + * @param bool $isOnline + * + * @return Coap + */ + public function setOnline(bool $isOnline): self + { + $this->_isOnline = $isOnline; + + return $this; + } + /** * Get device type. * @@ -62,9 +91,13 @@ public function __construct( public function getType(int $deviceId): string { $data = $this->_getData(CoapCommandKeys::KEY_GET_DATA, $deviceId); - - if (isset($data->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_TYPE})) { - return $data->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_TYPE}; + if (\is_object($data) + && \property_exists($data, CoapCommandKeys::KEY_DATA) + && \property_exists($data, CoapCommandKeys::KEY_TYPE) + ) { + return $data + ->{CoapCommandKeys::KEY_DATA} + ->{CoapCommandKeys::KEY_TYPE}; } throw new RuntimeException('invalid coap response'); @@ -83,20 +116,20 @@ public function getType(int $deviceId): string protected function _getData(string $requestType, int $deviceId = null) { if ($this->isOnline()) { - $command = $this->commands->getCoapsCommandGet($requestType); + $command = $this->_commands->getCoapsCommandGet($requestType); if ($deviceId !== null) { $command .= '/'.$deviceId; } - $dataRaw = $this->commands->parseResult( + $dataRaw = $this->_commands->parseResult( Runner::execWithTimeout($command, 1) ); if ($dataRaw !== false) { $decoded = \json_decode($dataRaw); if (null === $decoded) { - return $dataRaw; + $decoded = $dataRaw; } return $decoded; @@ -109,17 +142,13 @@ protected function _getData(string $requestType, int $deviceId = null) } /** - * Get Device data. - * - * @param int $deviceId - * - * @throws \IKEA\Tradfri\Exception\RuntimeException + * Get isOnline. * - * @return \stdClass + * @return bool */ - public function getDeviceData(int $deviceId): \stdClass + public function isOnline(): bool { - return $this->_getData(CoapCommandKeys::KEY_GET_DATA, $deviceId); + return $this->_isOnline; } /** @@ -142,118 +171,6 @@ public function getManufacturer(int $deviceId): string throw new RuntimeException('invalid hub response'); } - /** - * Get an array with lamp ids from soap client. - * - * @throws \IKEA\Tradfri\Exception\RuntimeException - * - * @return array - */ - public function getDeviceIds(): array - { - return $this->_getData(CoapCommandKeys::KEY_GET_DATA); - } - - /** - * Get Group data from hub. - * - * @throws \IKEA\Tradfri\Exception\RuntimeException - * - * @return array - */ - public function getGroupIds(): array - { - return $this->_getData(CoapCommandKeys::KEY_GET_GROUPS); - } - - /** - * Get Groups from hub. - * - * @throws \IKEA\Tradfri\Exception\RuntimeException - * - * @return array - */ - public function getGroupsData():array - { - $groupData = []; - foreach ($this->getGroupIds() as $groupId) { - // sometimes the request are to fast, - // the hub will decline the request (flood security) - $groupData[$groupId] - = $this->_getData( - CoapCommandKeys::KEY_GET_GROUPS, - $groupId - ); - //\sleep(1); - } - - return $groupData; - } - - /** - * Get devices. - * - * @param array|null $deviceIds - * - * @throws \IKEA\Tradfri\Exception\RuntimeException - * - * @return array - */ - public function getDevicesData(array $deviceIds = null): array - { - if ($deviceIds === null) { - $deviceIds = $this->getDeviceIds(); - } - $deviceData = []; - foreach ($deviceIds as $deviceId) { - // sometimes the request are to fast, - // the hub will decline the request (flood security) - $deviceData[$deviceId] = $this->getDeviceData((int) $deviceId); - //\sleep(1); - } - - return $deviceData; - } - - /** - * Get isOnline. - * - * @return bool - */ - public function isOnline(): bool - { - return $this->isOnline; - } - - /** - * Set IsOnline. - * - * @param bool $isOnline - * - * @return Coap - */ - public function setOnline(bool $isOnline): self - { - $this->isOnline = $isOnline; - - return $this; - } - - /** - * Check online state. - * - * @param string $ipAddress - * - * @return bool - */ - public function checkOnline(string $ipAddress): bool - { - $state = Online::isOnline($ipAddress); - $this->setOnline($state); - - return $state; - } - /** * Change State of given device. * @@ -267,8 +184,7 @@ public function checkOnline(string $ipAddress): bool public function changeLightState(int $deviceId, bool $toState): bool { // get command to switch light - $onCommand = $this - ->commands + $onCommand = $this->_commands ->getLightSwitchCommand($deviceId, $toState); // run command @@ -287,7 +203,7 @@ public function changeLightState(int $deviceId, bool $toState): bool return true; } - throw new RuntimeException('Could not switch state'); + throw new RuntimeException(self::COULD_NOT_SWITCH_STATE); } /** @@ -303,7 +219,8 @@ public function changeLightState(int $deviceId, bool $toState): bool public function changeGroupState(int $groupId, bool $toState): bool { // get command to switch light - $onCommand = $this->commands->getGroupSwitchCommand($groupId, $toState); + $onCommand = $this->_commands + ->getGroupSwitchCommand($groupId, $toState); // run command $data = Runner::execWithTimeout($onCommand, 2); @@ -313,7 +230,7 @@ public function changeGroupState(int $groupId, bool $toState): bool return true; } - throw new RuntimeException('Could not switch state'); + throw new RuntimeException(self::COULD_NOT_SWITCH_STATE); } /** @@ -329,7 +246,8 @@ public function changeGroupState(int $groupId, bool $toState): bool public function setLightBrightness(int $lightId, int $level): bool { // get command to dim light - $onCommand = $this->commands->getLightDimmerCommand($lightId, $level); + $onCommand = $this->_commands + ->getLightDimmerCommand($lightId, $level); // run command $data = Runner::execWithTimeout($onCommand, 2); @@ -339,7 +257,7 @@ public function setLightBrightness(int $lightId, int $level): bool return true; } - throw new RuntimeException('Could not switch state'); + throw new RuntimeException(self::COULD_NOT_SWITCH_STATE); } /** @@ -355,7 +273,7 @@ public function setLightBrightness(int $lightId, int $level): bool public function setGroupBrightness(int $groupId, int $level): bool { // get command to switch light - $onCommand = $this->commands->getGroupDimmerCommand($groupId, $level); + $onCommand = $this->_commands->getGroupDimmerCommand($groupId, $level); // run command $data = Runner::execWithTimeout($onCommand, 2); @@ -365,7 +283,7 @@ public function setGroupBrightness(int $groupId, int $level): bool return true; } - throw new RuntimeException('Could not switch state'); + throw new RuntimeException(self::COULD_NOT_SWITCH_STATE); } /** @@ -379,7 +297,59 @@ public function setGroupBrightness(int $groupId, int $level): bool */ public function getDeviceCollection(ServiceInterface $service): Devices { - return $this->deviceDataMapper->map($service, $this->getDevicesData()); + return $this + ->getDeviceDataMapper() + ->map($service, $this->getDevicesData()); + } + + /** + * Get devices. + * + * @param array|null $deviceIds + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + * + * @return array + */ + public function getDevicesData(array $deviceIds = null): array + { + if ($deviceIds === null) { + $deviceIds = $this->getDeviceIds(); + } + $deviceData = []; + foreach ($deviceIds as $deviceId) { + // sometimes the request are to fast, + // the hub will decline the request (flood security) + $deviceData[$deviceId] = $this->getDeviceData((int) $deviceId); + } + + return $deviceData; + } + + /** + * Get an array with lamp ids from soap client. + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + * + * @return array + */ + public function getDeviceIds(): array + { + return $this->_getData(CoapCommandKeys::KEY_GET_DATA); + } + + /** + * Get Device data. + * + * @param int $deviceId + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + * + * @return \stdClass + */ + public function getDeviceData(int $deviceId): \stdClass + { + return $this->_getData(CoapCommandKeys::KEY_GET_DATA, $deviceId); } /** @@ -393,16 +363,57 @@ public function getDeviceCollection(ServiceInterface $service): Devices */ public function getGroupCollection(ServiceInterface $service): Groups { - $groups = $this->groupDataMapper->map($service, $this->getGroupsData()); + $groups = $this + ->getGroupDataMapper() + ->map($service, $this->getGroupsData()); if ($groups->isEmpty() === false) { foreach ($groups->toArray() as $group) { /** @var Light $group */ - $groupDevices = $this->deviceDataMapper->map($service, $this->getDevicesData($group->getDeviceIds())); + $groupDevices = $this + ->_deviceDataMapper + ->map( + $service, + $this->getDevicesData($group->getDeviceIds()) + ); $group->setDevices($groupDevices); } } return $groups; } + + /** + * Get Groups from hub. + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + * + * @return array + */ + public function getGroupsData(): array + { + $groupData = []; + foreach ($this->getGroupIds() as $groupId) { + // sometimes the request are to fast, + // the hub will decline the request (flood security) + $groupData[$groupId] = $this->_getData( + CoapCommandKeys::KEY_GET_GROUPS, + $groupId + ); + } + + return $groupData; + } + + /** + * Get Group data from hub. + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + * + * @return array + */ + public function getGroupIds(): array + { + return $this->_getData(CoapCommandKeys::KEY_GET_GROUPS); + } } diff --git a/src/IKEA/Tradfri/Client/Client.php b/src/IKEA/Tradfri/Client/Client.php index fe335439..07195f74 100644 --- a/src/IKEA/Tradfri/Client/Client.php +++ b/src/IKEA/Tradfri/Client/Client.php @@ -20,7 +20,7 @@ class Client /** * @var AdapterInterface */ - protected $adapter; + protected $_adapter; /** * Client constructor. @@ -31,7 +31,7 @@ class Client */ public function __construct(AdapterInterface $adapter) { - $this->adapter = $adapter; + $this->_adapter = $adapter; } /** @@ -53,7 +53,7 @@ public function getDevices(ServiceInterface $service): Devices */ private function getAdapter(): AdapterInterface { - return $this->adapter; + return $this->_adapter; } /** diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index 37caa571..4bdfacab 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -12,7 +12,8 @@ /** * Class Devices. */ -abstract class AbstractCollection extends ArrayCollection implements JsonSerializable +abstract class AbstractCollection extends ArrayCollection + implements JsonSerializable { /** * Add item to collection. @@ -36,7 +37,7 @@ public function addDevice(Device $newItem) * @throws RuntimeException * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @return mixed + * @return Device|null|void */ public function find($closure) { @@ -50,7 +51,7 @@ public function find($closure) } } - return null; + return; } /** diff --git a/src/IKEA/Tradfri/Collection/Devices.php b/src/IKEA/Tradfri/Collection/Devices.php index 2cb0cc3b..903624ce 100644 --- a/src/IKEA/Tradfri/Collection/Devices.php +++ b/src/IKEA/Tradfri/Collection/Devices.php @@ -21,14 +21,14 @@ class Devices extends AbstractCollection */ public function getLightbulbs(): Lightbulbs { - $lamps = new Lightbulbs(); + $lightbulbs = new Lightbulbs(); foreach ($this->getDevices() as $device) { if ($device->isLightbulb()) { - $lamps->addDevice($device); + $lightbulbs->addDevice($device); } } - return $lamps; + return $lightbulbs; } /** diff --git a/src/IKEA/Tradfri/Collection/Groups.php b/src/IKEA/Tradfri/Collection/Groups.php index 85614e79..57963ce5 100644 --- a/src/IKEA/Tradfri/Collection/Groups.php +++ b/src/IKEA/Tradfri/Collection/Groups.php @@ -29,7 +29,7 @@ public function first(): Light * * @return $this */ - public function addGroup(Device $group) + public function addGroup(Device $group): self { $this->set($group->getId(), $group); diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index e96525ee..ecd55fce 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -26,13 +26,19 @@ public function first() * * @return $this */ - public function sortByState() + public function sortByState(): self { $items = $this->toArray(); - usort($items, function (Lightbulb $a, Lightbulb $b) { - return strcmp($a->getState(), $b->getState()); - }); + \usort( + $items, + function (Lightbulb $lightbulbOne, Lightbulb $lightbulbTwo) { + return \strcmp( + $lightbulbOne->getState(), + $lightbulbTwo->getState() + ); + } + ); return $this->createFrom($items); } @@ -42,7 +48,7 @@ public function sortByState() * * @return static */ - public function getActive() + public function getActive(): self { $newItems = []; foreach ($this->toArray() as $key => $light) { diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 39ad51c9..5a36badd 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -4,7 +4,6 @@ namespace IKEA\Tradfri\Command; -use IKEA\Tradfri\Command\Executer\Coap\Get; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Helper\Runner; @@ -16,29 +15,29 @@ */ class Coaps { - const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; - const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; + const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; + const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; const COAP_COMMAND_POST = 'coap-client -m post -u "%s" -k "%s"'; /** * @var string */ - private $_username; + protected $_username; /** * @var string */ - private $_apiKey; + protected $_apiKey; /** * @var string */ - private $_ip; + protected $_ip; /** * @var string */ - private $_secret; + protected $_secret; /** * Coaps constructor. @@ -53,8 +52,8 @@ class Coaps public function __construct( string $ipAddress, string $secret, - $username = null) - { + $username = null + ) { $this->setIp($ipAddress); $this->_secret = $secret; if (!\defined('COAP_API_KEY')) { @@ -101,13 +100,13 @@ public function getSharedKeyFromGateway(): string public function getPreSharedKeyCommand(): string { $command = \sprintf( - self::COAP_COMMAND_POST, - 'Client_identity', - $this->_secret - ) - .' -e \'{"9090":"'.$this->getUsername().'"}\'' - .' "coaps://'.$this->getIp().':5684/' - .CoapCommandKeys::KEY_GET_SHARED_KEY.'"'; + self::COAP_COMMAND_POST, + 'Client_identity', + $this->_secret + ) + .' -e \'{"9090":"'.$this->getUsername().'"}\'' + .' "coaps://'.$this->getIp().':5684/' + .CoapCommandKeys::KEY_GET_SHARED_KEY.'"'; return $command; } @@ -136,6 +135,36 @@ public function setUsername(string $username): self return $this; } + /** + * Get Ip. + * + * @return string + */ + public function getIp(): string + { + return $this->_ip; + } + + /** + * Set and filter ip. + * + * @param $ipAddress + * + * @throws \InvalidArgumentException + * + * @return $this + */ + public function setIp(string $ipAddress): self + { + if (\filter_var($ipAddress, FILTER_VALIDATE_IP)) { + $this->_ip = $ipAddress; + + return $this; + } + + throw new \InvalidArgumentException('Invalid ip'); + } + /** * Parse result. * @@ -146,7 +175,7 @@ public function setUsername(string $username): self public function parseResult(array $result) { if (\count($result) === 2 && !empty($result[0])) { - return $result[0]; + return (string) $result[0]; } return false; @@ -162,8 +191,10 @@ public function parseResult(array $result) public function getCoapsCommandGet($requestType): string { return \sprintf( - self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey() - ).' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; + self::COAP_COMMAND_GET, + $this->getUsername(), + $this->getApiKey() + ).' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; } /** @@ -201,41 +232,12 @@ public function setApiKey(string $apiKey): self public function getCoapsCommandPost($requestType, string $inject): string { return \sprintf( - self::COAP_COMMAND_POST, - $this->getUsername(), - $this->getApiKey() - ).$inject - .' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; - } - - /** - * Get Ip. - * - * @return string - */ - public function getIp(): string - { - return $this->_ip; - } - - /** - * Set and filter ip. - * - * @param $ipAddress - * - * @throws \InvalidArgumentException - * - * @return $this - */ - public function setIp(string $ipAddress): self - { - if (filter_var($ipAddress, FILTER_VALIDATE_IP)) { - $this->_ip = $ipAddress; - - return $this; - } - - throw new \InvalidArgumentException('Invalid ip'); + self::COAP_COMMAND_POST, + $this->getUsername(), + $this->getApiKey() + ) + .$inject.' "coaps://'.$this->getIp().':5684/' + .$requestType.'"'; } /** @@ -269,9 +271,13 @@ public function getLightSwitchCommand(int $deviceId, bool $state): string public function getCoapsCommandPut($requestType, string $inject): string { return \sprintf( - self::COAP_COMMAND_PUT, $this->getUsername(), $this->getApiKey() - ).$inject.' "coaps://'.$this->getIp().':5684/'.$requestType - .'"'; + self::COAP_COMMAND_PUT, + $this->getUsername(), + $this->getApiKey() + ) + .$inject + .' "coaps://'.$this->getIp().':5684/'.$requestType + .'"'; } /** @@ -303,7 +309,7 @@ public function getGroupDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) round( + ' -e \'{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) \round( $value * 2.55 ).' }\' ' ); @@ -322,7 +328,7 @@ public function getLightDimmerCommand(int $groupId, int $value): string return $this->getCoapsCommandPut( CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "' - .CoapCommandKeys::KEY_DIMMER.'": '.(int) round($value * 2.55) + .CoapCommandKeys::KEY_DIMMER.'": '.(int) \round($value * 2.55) .' }] }\' ' ); } @@ -345,12 +351,15 @@ public function getLightColorCommand(int $groupId, string $color): string switch ($color) { case 'warm': $payload = \sprintf($payload, '33135', '27211'); + break; case 'normal': $payload = \sprintf($payload, '30140', '26909'); + break; case 'cold': $payload = \sprintf($payload, '24930', '24684'); + break; default: throw new RuntimeException('unknown color'); diff --git a/src/IKEA/Tradfri/Command/CommandAbstract.php b/src/IKEA/Tradfri/Command/CommandAbstract.php deleted file mode 100644 index 59e5f7fd..00000000 --- a/src/IKEA/Tradfri/Command/CommandAbstract.php +++ /dev/null @@ -1,53 +0,0 @@ -_client; - } - - /** - * Set Client. - * - * @param Client $client - * - * @return CommandAbstract - */ - public function setClient(Client $client): self - { - $this->_client = $client; - - return $this; - } - - /** - * Execute command. - * - * @return $this - */ - abstract public function execute(): self; -} diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index 33cd8288..985b8c12 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -14,64 +14,65 @@ */ abstract class Device implements JsonSerializable { - const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; + const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; const TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; - const TYPE_DIMMER = 'TRADFRI dimmer'; //todo check this (not added to valid types) - const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; - const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; - const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; + const TYPE_DIMMER = 'TRADFRI dimmer'; + const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; + const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; + const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; /** * @var array */ - protected static $lightblubTypes = [ - self::TYPE_BLUB_GU10, - self::TYPE_BLUB_E27_W, - self::TYPE_BLUB_E27_WS, - ]; + protected static $_lightblubTypes + = [ + self::TYPE_BLUB_GU10, + self::TYPE_BLUB_E27_W, + self::TYPE_BLUB_E27_WS, + ]; /** * @var int */ - private $id; + protected $_id; /** * @var string */ - private $name; + protected $_name; /** * @var string */ - private $manufacturer; + protected $_manufacturer; /** * @var string */ - private $type; + protected $_type; /** * @var string */ - private $version; + protected $_version; /** * @var Api|ServiceInterface */ - private $service; + protected $_service; /** * Lightbulb constructor. * - * @param int $id + * @param int $deviceId * @param string $type * * @throws \IKEA\Tradfri\Exception\RuntimeException */ - public function __construct(int $id, string $type) + public function __construct(int $deviceId, string $type) { $this->setType($type); - $this->id = $id; + $this->_id = $deviceId; } /** @@ -81,7 +82,7 @@ public function __construct(int $id, string $type) */ public function getName(): string { - return $this->name; + return $this->_name; } /** @@ -93,7 +94,7 @@ public function getName(): string */ public function setName($name): self { - $this->name = $name; + $this->_name = $name; return $this; } @@ -105,7 +106,7 @@ public function setName($name): self */ public function getManufacturer(): string { - return $this->manufacturer; + return $this->_manufacturer; } /** @@ -117,7 +118,7 @@ public function getManufacturer(): string */ public function setManufacturer($manufacturer): self { - $this->manufacturer = $manufacturer; + $this->_manufacturer = $manufacturer; return $this; } @@ -129,19 +130,19 @@ public function setManufacturer($manufacturer): self */ public function getId(): int { - return $this->id; + return $this->_id; } /** * Set Id. * - * @param int $id + * @param int $deviceId * * @return Device */ - public function setId(int $id): self + public function setId(int $deviceId): self { - $this->id = $id; + $this->_id = $deviceId; return $this; } @@ -153,7 +154,7 @@ public function setId(int $id): self */ public function getVersion(): string { - return $this->version; + return $this->_version; } /** @@ -165,7 +166,7 @@ public function getVersion(): string */ public function setVersion(string $version): self { - $this->version = $version; + $this->_version = $version; return $this; } @@ -177,7 +178,7 @@ public function setVersion(string $version): self */ public function isLightbulb(): bool { - return \in_array($this->getType(), self::$lightblubTypes, true); + return \in_array($this->getType(), self::$_lightblubTypes, true); } /** @@ -187,7 +188,7 @@ public function isLightbulb(): bool */ public function getType(): string { - return $this->type; + return $this->_type; } /** @@ -202,7 +203,7 @@ public function getType(): string public function setType($type): self { if ($this->isValidType($type)) { - $this->type = $type; + $this->_type = $type; } return $this; @@ -215,7 +216,7 @@ public function setType($type): self */ public function getService(): ServiceInterface { - return $this->service; + return $this->_service; } /** @@ -227,7 +228,7 @@ public function getService(): ServiceInterface */ public function setService(ServiceInterface $service): self { - $this->service = $service; + $this->_service = $service; return $this; } @@ -251,17 +252,18 @@ public function isValidType($type): bool case self::TYPE_REMOTE_CONTROL: case self::TYPE_DIMMER: // todo add more types - return true; break; default: throw new TypeException('unknown type'); } + + return true; } /** * Specify data which should be serialized to JSON. * - * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php * * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. @@ -272,9 +274,9 @@ public function jsonSerialize(): array { $data = []; - foreach (get_class_methods(static::class) as $method) { - if ($method !== 'getService' && strpos($method, 'get') === 0) { - $key = strtolower((string) substr($method, 3)); + foreach (\get_class_methods(static::class) as $method) { + if ($method !== 'getService' && \strpos($method, 'get') === 0) { + $key = \strtolower((string) \substr($method, 3)); $data[$key] = $this->$method(); } diff --git a/src/IKEA/Tradfri/Device/Dimmer.php b/src/IKEA/Tradfri/Device/Dimmer.php index a551ae22..9fbbc22f 100644 --- a/src/IKEA/Tradfri/Device/Dimmer.php +++ b/src/IKEA/Tradfri/Device/Dimmer.php @@ -12,12 +12,12 @@ class Dimmer extends Device /** * Dimmer constructor. * - * @param int $id + * @param int $deviceId * * @throws \IKEA\Tradfri\Exception\RuntimeException */ - public function __construct($id) + public function __construct($deviceId) { - parent::__construct($id, self::TYPE_DIMMER); + parent::__construct($deviceId, self::TYPE_DIMMER); } } diff --git a/src/IKEA/Tradfri/Device/Lightbulb.php b/src/IKEA/Tradfri/Device/Lightbulb.php index ac9bc23c..680c36fe 100644 --- a/src/IKEA/Tradfri/Device/Lightbulb.php +++ b/src/IKEA/Tradfri/Device/Lightbulb.php @@ -14,12 +14,12 @@ class Lightbulb extends Device /** * @var int */ - protected $brightness; + protected $_brightness; /** * @var bool */ - protected $state = false; + protected $_state = false; /** * Get Brightness. @@ -28,7 +28,7 @@ class Lightbulb extends Device */ public function getBrightness(): float { - return (float) $this->brightness; + return (float) $this->_brightness; } /** @@ -43,9 +43,9 @@ public function getBrightness(): float public function setBrightness(int $brightness): self { if ($brightness < 0) { - $this->brightness = 0; + $this->_brightness = 0; } else { - $this->brightness = round($brightness / 2.54); + $this->_brightness = \round($brightness / 2.54); } return $this; @@ -106,7 +106,7 @@ public function getState(): string */ public function setState(bool $state): self { - $this->state = $state; + $this->_state = $state; return $this; } @@ -118,7 +118,7 @@ public function setState(bool $state): self */ public function isOn(): bool { - return $this->state; + return $this->_state; } /** diff --git a/src/IKEA/Tradfri/Device/MotionSensor.php b/src/IKEA/Tradfri/Device/MotionSensor.php index 63f7ddb8..e14e190c 100644 --- a/src/IKEA/Tradfri/Device/MotionSensor.php +++ b/src/IKEA/Tradfri/Device/MotionSensor.php @@ -12,12 +12,12 @@ class MotionSensor extends Device /** * MotionSensor constructor. * - * @param int $id + * @param int $deviceId * * @throws \IKEA\Tradfri\Exception\RuntimeException */ - public function __construct($id) + public function __construct($deviceId) { - parent::__construct($id, self::TYPE_MOTION_SENSOR); + parent::__construct($deviceId, self::TYPE_MOTION_SENSOR); } } diff --git a/src/IKEA/Tradfri/Device/Remote.php b/src/IKEA/Tradfri/Device/Remote.php index 57b1c531..8083212d 100644 --- a/src/IKEA/Tradfri/Device/Remote.php +++ b/src/IKEA/Tradfri/Device/Remote.php @@ -12,12 +12,12 @@ class Remote extends Device /** * Remote constructor. * - * @param int $id + * @param int $deviceId * * @throws \IKEA\Tradfri\Exception\RuntimeException */ - public function __construct($id) + public function __construct($deviceId) { - parent::__construct($id, self::TYPE_REMOTE_CONTROL); + parent::__construct($deviceId, self::TYPE_REMOTE_CONTROL); } } diff --git a/src/IKEA/Tradfri/Group/Device.php b/src/IKEA/Tradfri/Group/Device.php index 1a34a3be..190d06a7 100644 --- a/src/IKEA/Tradfri/Group/Device.php +++ b/src/IKEA/Tradfri/Group/Device.php @@ -16,60 +16,60 @@ class Device /** * @var int */ - protected $id; + protected $_id; /** * @var string */ - protected $name; + protected $_name; /** * @var Api|ServiceInterface */ - protected $service; + protected $_service; /** * @var Devices */ - protected $devices; + protected $_devices; /** * @var array */ - protected $deviceIds = []; + protected $_deviceIds = []; /** * @var int */ - protected $brightness; + protected $_brightness; /** * @var bool */ - protected $state; + protected $_state; /** * Group constructor. * - * @param int $id + * @param int $deviceId * @param ServiceInterface $service */ - public function __construct(int $id, ServiceInterface $service) + public function __construct(int $deviceId, ServiceInterface $service) { - $this->setId($id); + $this->setId($deviceId); $this->setService($service); } /** - * Set device ids. + * Set Service. * - * @param array $ids + * @param Api|ServiceInterface $service * - * @return $this + * @return Device */ - public function setDeviceIds(array $ids) + public function setService(ServiceInterface $service): self { - $this->deviceIds = $ids; + $this->_service = $service; return $this; } @@ -81,7 +81,21 @@ public function setDeviceIds(array $ids) */ public function getDeviceIds(): array { - return $this->deviceIds; + return $this->_deviceIds; + } + + /** + * Set device ids. + * + * @param array $ids + * + * @return $this + */ + public function setDeviceIds(array $ids) + { + $this->_deviceIds = $ids; + + return $this; } /** @@ -91,11 +105,11 @@ public function getDeviceIds(): array */ public function getDevices(): Devices { - if ($this->devices === null) { - $this->devices = new Devices(); + if ($this->_devices === null) { + $this->_devices = new Devices(); } - return $this->devices; + return $this->_devices; } /** @@ -107,7 +121,7 @@ public function getDevices(): Devices */ public function setDevices(Devices $devices): self { - $this->devices = $devices; + $this->_devices = $devices; return $this; } @@ -119,19 +133,19 @@ public function setDevices(Devices $devices): self */ public function getId(): int { - return $this->id; + return $this->_id; } /** * Set Id. * - * @param int $id + * @param int $deviceId * * @return Device */ - public function setId($id): self + public function setId($deviceId): self { - $this->id = $id; + $this->_id = $deviceId; return $this; } @@ -143,7 +157,7 @@ public function setId($id): self */ public function getName(): string { - return $this->name; + return $this->_name; } /** @@ -155,61 +169,47 @@ public function getName(): string */ public function setName(string $name): self { - $this->name = $name; + $this->_name = $name; return $this; } /** - * Set Service. + * Set State of group. * - * @param Api|ServiceInterface $service + * @param bool $state * - * @return Device + * @return $this */ - public function setService(ServiceInterface $service): self + public function setState(bool $state) { - $this->service = $service; + $this->_state = $state; return $this; } /** - * @param int $level + * Get Brightness. * - * @return $this + * @return float */ - public function setBrightness(int $level) + public function getBrightness(): float { - $this->brightness = $level; - - return $this; + return (float) $this->_brightness; } /** - * Set State of group. - * - * @param bool $state + * @param int $level * * @return $this */ - public function setState(bool $state) + public function setBrightness(int $level) { - $this->state = $state; + $this->_brightness = $level; return $this; } - /** - * Get Brightness. - * - * @return float - */ - public function getBrightness(): float - { - return (float) $this->brightness; - } - /** * Get State. * @@ -217,6 +217,6 @@ public function getBrightness(): float */ public function isOn(): bool { - return $this->state; + return $this->_state; } } diff --git a/src/IKEA/Tradfri/Group/Light.php b/src/IKEA/Tradfri/Group/Light.php index 8fa77b00..f8f2118b 100644 --- a/src/IKEA/Tradfri/Group/Light.php +++ b/src/IKEA/Tradfri/Group/Light.php @@ -11,16 +11,6 @@ */ class Light extends Device { - /** - * Get Lights. - * - * @return Lightbulbs - */ - public function getLights(): Lightbulbs - { - return $this->getDevices()->getLightbulbs(); - } - /** * Get State. * @@ -35,6 +25,16 @@ public function isOn(): bool return false; } + /** + * Get Lights. + * + * @return Lightbulbs + */ + public function getLights(): Lightbulbs + { + return $this->getDevices()->getLightbulbs(); + } + /** * Switch group on. * @@ -44,7 +44,7 @@ public function isOn(): bool */ public function switchOn(): self { - if ($this->service->switchOn($this)) { + if ($this->_service->switchOn($this)) { $this->setState(true); } @@ -58,7 +58,7 @@ public function switchOn(): self */ public function off(): self { - if ($this->service->off($this)) { + if ($this->_service->off($this)) { $this->setState(false); } @@ -74,7 +74,7 @@ public function off(): self */ public function dim(int $level): self { - if ($this->service->dim($this, $level)) { + if ($this->_service->dim($this, $level)) { $this->setBrightness($level); } diff --git a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php index 27c00d50..fadc9c8b 100644 --- a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php +++ b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php @@ -10,26 +10,26 @@ class CoapCommandKeys { const KEY_MANUFACTURER = '0'; - const KEY_TYPE = '1'; - const KEY_DATA = '3'; - const KEY_VERSION = '3'; + const KEY_TYPE = '1'; + const KEY_DATA = '3'; + const KEY_VERSION = '3'; const KEY_DEVICE_DATA = '3311'; - const KEY_COLOR = '5709'; + const KEY_COLOR = '5709'; const KEY_COLOR_2 = '5710'; - const KEY_ONOFF = '5850'; - const KEY_DIMMER = '5851'; + const KEY_ONOFF = '5850'; + const KEY_DIMMER = '5851'; - const KEY_NAME = '9001'; - const KEY_TIME = '9002'; - const KEY_ID = '9003'; + const KEY_NAME = '9001'; + const KEY_TIME = '9002'; + const KEY_ID = '9003'; const KEY_GROUPS_DATA = '9018'; - const KEY_X = '9039'; - const KEY_SHARED_KEY = '9091'; + const KEY_X = '9039'; + const KEY_SHARED_KEY = '9091'; - const KEY_GET_DATA = '15001'; - const KEY_GET_LIGHTS = '15002'; - const KEY_GET_GROUPS = '15004'; + const KEY_GET_DATA = '15001'; + const KEY_GET_LIGHTS = '15002'; + const KEY_GET_GROUPS = '15004'; const KEY_GET_SHARED_KEY = '15011/9063'; } diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 0b912cb4..1e653531 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -14,33 +14,51 @@ class Online /** * Check online state. * - * @param string $ip + * @param string $ipAddress * * @return bool */ - public static function isOnline(string $ip): bool + public static function isOnline(string $ipAddress): bool { + $online = true; + $regex = '/(\ \d+% packet loss), (time \d+ms)/'; + try { - $re = '/(\ \d+% packet loss), (time \d+ms)/'; - $data = Runner::execWithTimeout('ping -c1 '.$ip, 1, false); + $data = Runner::execWithTimeout('ping -c1 '.$ipAddress, 1, false); - preg_match_all($re, $data, $matches, PREG_SET_ORDER); + \preg_match_all($regex, $data, $matches, PREG_SET_ORDER); if (isset($matches[0][1])) { - if (\strpos($matches[0][1], ' 0% packet loss') === false) { - throw new RuntimeException('packet loss detected'); - } + self::_validateMatches($matches); + } else { + throw new RuntimeException('unable to ping hub'); + } + } catch (\Exception $exception) { + // todo add log + $online = false; + } - if (\strpos($matches[0][2], 'time 0ms') === false) { - throw new RuntimeException('ping to high'); - } + return $online; + } - return true; - } + /** + * Validate matches + * + * @param array $matches + * + * @return bool + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + */ + protected static function _validateMatches(array $matches): bool + { + if (\strpos($matches[0][1], ' 0% packet loss') === false) { + throw new RuntimeException('packet loss detected'); + } - throw new RuntimeException('unable to ping hub'); - } catch (\Exception $e) { - // todo add log - return false; + if (\strpos($matches[0][2], 'time 0ms') === false) { + throw new RuntimeException('ping to high'); } + + return true; } } diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index 9319cfa0..a2a8e539 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -39,14 +39,14 @@ public static function execWithTimeout( ]; // Start the process. - $process = proc_open('exec '.$cmd, $descriptors, $pipes); + $process = \proc_open('exec '.$cmd, $descriptors, $pipes); if (!\is_resource($process)) { throw new RuntimeException('Could not execute process'); } // Set the stdout stream to none-blocking. - stream_set_blocking($pipes[1], false); + \stream_set_blocking($pipes[1], false); // Turn the timeout into microseconds. $timeout *= 1000000; @@ -56,23 +56,23 @@ public static function execWithTimeout( // While we have time to wait. while ($timeout > 0) { - $start = microtime(true); + $start = \microtime(true); // Wait until we have output or the timer expired. - $read = [$pipes[1]]; + $read = [$pipes[1]]; $other = []; - stream_select($read, $other, $other, 0, (int) $timeout); + \stream_select($read, $other, $other, 0, (int) $timeout); // Get the status of the process. // Do this before we read from the stream, // this way we can't lose the last bit // of output if the process dies between these functions. - $status = proc_get_status($process); + $status = \proc_get_status($process); // Read the contents from the buffer. // This function will always return immediately // as the stream is none-blocking. - $buffer .= stream_get_contents($pipes[1]); + $buffer .= \stream_get_contents($pipes[1]); if (!$status['running']) { // Break from this loop if the process exited @@ -81,14 +81,14 @@ public static function execWithTimeout( } // Subtract the number of microseconds that we waited. - $timeout -= (microtime(true) - $start) * 1000000; + $timeout -= (\microtime(true) - $start) * 1000000; } // Check if there were any errors. - $errors = stream_get_contents($pipes[2]); + $errors = \stream_get_contents($pipes[2]); if (!empty($errors) && empty($buffer)) { - $parts = explode("\n", $errors); + $parts = \explode("\n", $errors); if (\count($parts) === 3) { $errorMessage = $parts[1]; } else { @@ -105,16 +105,16 @@ public static function execWithTimeout( // Kill the process in case the timeout expired and it's still running. // If the process already exited this won't do anything. - if (proc_terminate($process, 9)) { + if (\proc_terminate($process, 9)) { throw new RuntimeException('timeout expired'); } // Close all streams. - fclose($pipes[0]); - fclose($pipes[1]); - fclose($pipes[2]); + \fclose($pipes[0]); + \fclose($pipes[1]); + \fclose($pipes[2]); - proc_close($process); + \proc_close($process); if ($asArray === true) { return \explode("\n", $buffer); diff --git a/src/IKEA/Tradfri/Mapper/DeviceData.php b/src/IKEA/Tradfri/Mapper/DeviceData.php index 2920faf9..5b8369e8 100644 --- a/src/IKEA/Tradfri/Mapper/DeviceData.php +++ b/src/IKEA/Tradfri/Mapper/DeviceData.php @@ -31,8 +31,10 @@ class DeviceData extends Mapper * * @return Devices */ - public function map(ServiceInterface $service, array $devices): AbstractCollection - { + public function map( + ServiceInterface $service, + array $devices + ): AbstractCollection { if (\count($devices) > 0) { $collection = new Devices(); foreach ($devices as $device) { @@ -43,18 +45,34 @@ public function map(ServiceInterface $service, array $devices): AbstractCollecti try { $model = $this->_getModel($id, $device, $service); - } catch (TypeException $e) { + } catch (TypeException $typeException) { // todo add logger continue; } $model->setName($device->{CoapCommandKeys::KEY_NAME}); - $model->setManufacturer($device->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_MANUFACTURER}); - $model->setVersion($device->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_VERSION}); + $model->setManufacturer( + $device + ->{CoapCommandKeys::KEY_DATA} + ->{CoapCommandKeys::KEY_MANUFACTURER} + ); + $model->setVersion( + $device + ->{CoapCommandKeys::KEY_DATA} + ->{CoapCommandKeys::KEY_VERSION} + ); if ($model instanceof Lightbulb) { - $model->setBrightness($device->{CoapCommandKeys::KEY_DEVICE_DATA}[0]->{CoapCommandKeys::KEY_DIMMER}); - $model->setState((bool) $device->{CoapCommandKeys::KEY_DEVICE_DATA}[0]->{CoapCommandKeys::KEY_ONOFF}); + $model->setBrightness( + $device + ->{CoapCommandKeys::KEY_DEVICE_DATA}[0] + ->{CoapCommandKeys::KEY_DIMMER} + ); + $model->setState( + (bool) $device + ->{CoapCommandKeys::KEY_DEVICE_DATA}[0] + ->{CoapCommandKeys::KEY_ONOFF} + ); } $collection->set($model->getId(), $model); @@ -77,39 +95,15 @@ public function map(ServiceInterface $service, array $devices): AbstractCollecti */ protected function _isValidData($device): bool { - try { - switch (false) { - case \is_object($device): - throw new TypeException('device is no object'); - break; - case isset($device->{CoapCommandKeys::KEY_ID}): - throw new RuntimeException('attribute missing ('.CoapCommandKeys::KEY_ID); - break; - case isset($device->{CoapCommandKeys::KEY_DATA}, $device->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_TYPE}): - throw new RuntimeException('attribute missing type key'); - break; - case isset($device->{CoapCommandKeys::KEY_DATA}, $device->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_MANUFACTURER}): - throw new RuntimeException('attribute missing type manufacturer'); - break; - case isset($device->{CoapCommandKeys::KEY_DATA}, $device->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_VERSION}): - throw new RuntimeException('attribute missing type version'); - break; - // only for light bulbs (optional) - case isset($device->{CoapCommandKeys::KEY_DEVICE_DATA}[0]): - case isset($device->{CoapCommandKeys::KEY_DEVICE_DATA}[0]->{CoapCommandKeys::KEY_DIMMER}): - case isset($device->{CoapCommandKeys::KEY_DEVICE_DATA}[0]->{CoapCommandKeys::KEY_ONOFF}): - default: - return true; - } - } catch (\Throwable $e) { - return false; - } + $validator = new \IKEA\Tradfri\Validator\Device\Data(); + + return $validator->isValid($device); } /** * Get model from device object. * - * @param int $id + * @param int $deviceId * @param \stdClass $device * @param ServiceInterface $service * @@ -119,32 +113,38 @@ protected function _isValidData($device): bool * * @return Device|Lightbulb|Remote|MotionSensor */ - protected function _getModel(int $id, \stdClass $device, ServiceInterface $service) - { - if (isset($device->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_TYPE})) { - $type = $device->{CoapCommandKeys::KEY_DATA}->{CoapCommandKeys::KEY_TYPE}; - switch ($type) { - case Device::TYPE_BLUB_E27_W: - case Device::TYPE_BLUB_E27_WS: - case Device::TYPE_BLUB_GU10: - $model = new Lightbulb($id, $type); - break; - case Device::TYPE_MOTION_SENSOR: - $model = new MotionSensor($id, $type); - break; - case Device::TYPE_REMOTE_CONTROL: - $model = new Remote($id, $type); - break; - case Device::TYPE_DIMMER: - $model = new Dimmer($id, $type); - break; - default: - throw new TypeException('invalid type: '.$type); - } + protected function _getModel( + int $deviceId, + \stdClass $device, + ServiceInterface $service + ) { + $type = $device + ->{CoapCommandKeys::KEY_DATA} + ->{CoapCommandKeys::KEY_TYPE}; + + switch ($type) { + case Device::TYPE_BLUB_E27_W: + case Device::TYPE_BLUB_E27_WS: + case Device::TYPE_BLUB_GU10: + $model = new Lightbulb($deviceId, $type); + + break; + case Device::TYPE_MOTION_SENSOR: + $model = new MotionSensor($deviceId); + + break; + case Device::TYPE_REMOTE_CONTROL: + $model = new Remote($deviceId); + + break; + case Device::TYPE_DIMMER: + $model = new Dimmer($deviceId); - return $model->setType($type)->setService($service); + break; + default: + throw new TypeException('invalid type: '.$type); } - throw new TypeException('invalid object'); + return $model->setType($type)->setService($service); } } diff --git a/src/IKEA/Tradfri/Mapper/GroupData.php b/src/IKEA/Tradfri/Mapper/GroupData.php index ed80ae62..b6a4e1df 100644 --- a/src/IKEA/Tradfri/Mapper/GroupData.php +++ b/src/IKEA/Tradfri/Mapper/GroupData.php @@ -6,8 +6,6 @@ use IKEA\Tradfri\Collection\AbstractCollection; use IKEA\Tradfri\Collection\Groups; -use IKEA\Tradfri\Exception\RuntimeException; -use IKEA\Tradfri\Exception\TypeException; use IKEA\Tradfri\Group\Light; use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Service\Api; @@ -26,9 +24,10 @@ class GroupData extends Mapper * * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @return Groups + * @return Groups|AbstractCollection */ - public function map(ServiceInterface $service, array $groupDataItems): AbstractCollection + public function map(ServiceInterface $service, + array $groupDataItems): AbstractCollection { $collection = new Groups(); foreach ($groupDataItems as $device) { @@ -36,9 +35,16 @@ public function map(ServiceInterface $service, array $groupDataItems): AbstractC continue; } - $group = new Light((int) $device->{CoapCommandKeys::KEY_ID}, $service); + $group = new Light( + (int) $device->{CoapCommandKeys::KEY_ID}, $service + ); $group->setName($device->{CoapCommandKeys::KEY_NAME}); - $group->setDeviceIds($device->{CoapCommandKeys::KEY_GROUPS_DATA}->{CoapCommandKeys::KEY_GET_LIGHTS}->{CoapCommandKeys::KEY_ID}); + $group->setDeviceIds( + $device + ->{CoapCommandKeys::KEY_GROUPS_DATA} + ->{CoapCommandKeys::KEY_GET_LIGHTS} + ->{CoapCommandKeys::KEY_ID} + ); $group->setBrightness($device->{CoapCommandKeys::KEY_DIMMER}); $group->setState((bool) $device->{CoapCommandKeys::KEY_ONOFF}); @@ -59,36 +65,8 @@ public function map(ServiceInterface $service, array $groupDataItems): AbstractC */ protected function _isValidData($device): bool { - try { - switch (false) { - case \is_object($device): - throw new TypeException('device is no object'); - break; - case isset($device->{CoapCommandKeys::KEY_ID}): - throw new RuntimeException('attribute missing ID ('.CoapCommandKeys::KEY_ID.')'); - break; - case isset($device->{CoapCommandKeys::KEY_NAME}): - throw new RuntimeException('attribute missing type name ('.CoapCommandKeys::KEY_NAME.')'); - break; - case isset($device->{CoapCommandKeys::KEY_GROUPS_DATA}): - throw new RuntimeException('attribute missing group data ('.CoapCommandKeys::KEY_GROUPS_DATA.')'); - break; - case isset($device->{CoapCommandKeys::KEY_GROUPS_DATA}->{CoapCommandKeys::KEY_GET_LIGHTS}): - throw new RuntimeException('group has no devices ('.CoapCommandKeys::KEY_GROUPS_DATA.'->'.CoapCommandKeys::KEY_GET_LIGHTS.')'); - break; - case \is_array($device->{CoapCommandKeys::KEY_GROUPS_DATA}->{CoapCommandKeys::KEY_GET_LIGHTS}->{CoapCommandKeys::KEY_ID}): - throw new RuntimeException( - 'attribute group data is not an array ('. - CoapCommandKeys::KEY_GROUPS_DATA. - '->'.CoapCommandKeys::KEY_GET_LIGHTS. - '->'.CoapCommandKeys::KEY_ID.')' - ); - break; - default: - return true; - } - } catch (\Throwable $e) { - return false; - } + $validator = new \IKEA\Tradfri\Validator\Group\Data(); + + return $validator->isValid($device); } } diff --git a/src/IKEA/Tradfri/Mapper/MapperInterface.php b/src/IKEA/Tradfri/Mapper/MapperInterface.php index 0e4ff4e9..43af1bd6 100644 --- a/src/IKEA/Tradfri/Mapper/MapperInterface.php +++ b/src/IKEA/Tradfri/Mapper/MapperInterface.php @@ -22,5 +22,8 @@ interface MapperInterface * * @return Devices|AbstractCollection */ - public function map(ServiceInterface $service, array $dataItems): AbstractCollection; + public function map( + ServiceInterface $service, + array $dataItems + ): AbstractCollection; } diff --git a/src/IKEA/Tradfri/Service/Api.php b/src/IKEA/Tradfri/Service/Api.php index c1368a19..436aae51 100644 --- a/src/IKEA/Tradfri/Service/Api.php +++ b/src/IKEA/Tradfri/Service/Api.php @@ -19,10 +19,11 @@ */ class Api implements ServiceInterface { + const INVALID_DEVICE_TYPE = 'invalid device type: '; /** * @var Client */ - private $client; + protected $_client; /** * Api constructor. @@ -31,7 +32,7 @@ class Api implements ServiceInterface */ public function __construct(Client $client) { - $this->client = $client; + $this->_client = $client; } /** @@ -51,7 +52,7 @@ public function getLights(): Lightbulbs */ public function getDevices(): Devices { - return $this->client->getDevices($this); + return $this->_client->getDevices($this); } /** @@ -61,7 +62,7 @@ public function getDevices(): Devices */ public function getGroups(): Groups { - return $this->client->getGroups($this); + return $this->_client->getGroups($this); } /** @@ -77,8 +78,11 @@ public function allLightsOff(Lightbulbs $lightbulbsCollection): bool { $service = $this; $lightbulbsCollection->forAll( - function ($key, $lightbulb) use ($service) { + function ($lightbulbKey, $lightbulb) use ($service) { /* @var Lightbulb $lightbulb */ + if ($lightbulbKey === $lightbulb->getId()) { + // this is ok but who cars can't make var unused + } $service->off($lightbulb); } ); @@ -87,7 +91,7 @@ function ($key, $lightbulb) use ($service) { } /** - * Switch device on. + * Switch device off. * * @param Device|Light $device * @@ -95,17 +99,19 @@ function ($key, $lightbulb) use ($service) { * * @return bool */ - public function switchOn($device): bool + public function off($device): bool { if ($device instanceof Light) { - return $this->client->groupOn($device); + return $this->_client->groupOff($device); } if ($device instanceof Lightbulb) { - return $this->client->lightOn($device); + return $this->_client->lightOff($device); } - throw new RuntimeException('invalid device type: '.$device->getType()); + throw new RuntimeException( + self::INVALID_DEVICE_TYPE.$device->getType() + ); } /** @@ -115,36 +121,21 @@ public function switchOn($device): bool * * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @deprecated - * @see Api::switchOn - * - * @return bool - */ - public function on($device): bool - { - return $this->switchOn($device); - } - - /** - * Switch device off. - * - * @param Device|Light $device - * - * @throws \IKEA\Tradfri\Exception\RuntimeException - * * @return bool */ - public function off($device): bool + public function switchOn($device): bool { if ($device instanceof Light) { - return $this->client->groupOff($device); + return $this->_client->groupOn($device); } if ($device instanceof Lightbulb) { - return $this->client->lightOff($device); + return $this->_client->lightOn($device); } - throw new RuntimeException('invalid device type: '.$device->getType()); + throw new RuntimeException( + self::INVALID_DEVICE_TYPE.$device->getType() + ); } /** @@ -160,13 +151,15 @@ public function off($device): bool public function dim($device, int $level): bool { if ($device instanceof Light) { - return $this->client->dimGroup($device, $level); + return $this->_client->dimGroup($device, $level); } if ($device instanceof Lightbulb) { - return $this->client->dimLight($device, $level); + return $this->_client->dimLight($device, $level); } - throw new RuntimeException('invalid device type: '.$device->getType()); + throw new RuntimeException( + self::INVALID_DEVICE_TYPE.$device->getType() + ); } } diff --git a/src/IKEA/Tradfri/Validator/Device/Data.php b/src/IKEA/Tradfri/Validator/Device/Data.php new file mode 100644 index 00000000..440fa72e --- /dev/null +++ b/src/IKEA/Tradfri/Validator/Device/Data.php @@ -0,0 +1,140 @@ +_hasIdField($device); + + $this->_hasDataField($device); + + $data = $device->{CoapCommandKeys::KEY_DATA}; + $this->_hasDataType($data); + + $this->_hasDataManufacturer($data); + + $this->_hasDataVersion($data); + } catch (RuntimeException $exception) { + $isValid = false; + } catch (\Throwable $exception) { + $isValid = false; + } + + return $isValid; + } + + /** + * @param $device + * + * @return bool + * + * @throws RuntimeException + */ + protected function _hasIdField(\stdClass $device): bool + { + if (!\property_exists($device, CoapCommandKeys::KEY_ID)) { + throw new RuntimeException( + 'attribute missing ('.CoapCommandKeys::KEY_ID + ); + } + + return true; + } + + /** + * @param $device + * + * @return bool + * + * @throws RuntimeException + */ + protected function _hasDataField(\stdClass $device): bool + { + if (!\property_exists($device, CoapCommandKeys::KEY_DATA)) { + throw new RuntimeException( + 'attribute missing ('.CoapCommandKeys::KEY_DATA + ); + } + + return true; + } + + /** + * @param $data + * + * @return bool + * + * @throws RuntimeException + */ + protected function _hasDataType(\stdClass $data): bool + { + if (false === \property_exists($data, CoapCommandKeys::KEY_TYPE)) { + throw new RuntimeException('attribute missing type key'); + } + + return true; + } + + /** + * @param $data + * + * @return bool + * + * @throws RuntimeException + */ + protected function _hasDataManufacturer(\stdClass $data): bool + { + if (!\property_exists($data, CoapCommandKeys::KEY_MANUFACTURER)) { + throw new RuntimeException( + 'attribute missing type manufacturer' + ); + } + + return true; + } + + /** + * @param $data + * + * @return bool + * + * @throws RuntimeException + */ + protected function _hasDataVersion(\stdClass $data): bool + { + if (!\property_exists($data, CoapCommandKeys::KEY_VERSION)) { + throw new RuntimeException( + 'attribute missing type version' + ); + } + + return true; + } +} diff --git a/src/IKEA/Tradfri/Validator/Group/Data.php b/src/IKEA/Tradfri/Validator/Group/Data.php new file mode 100644 index 00000000..d93e6a12 --- /dev/null +++ b/src/IKEA/Tradfri/Validator/Group/Data.php @@ -0,0 +1,91 @@ +_validateDeviceMustHaves($data); + + $isValid = true; + + $groupData = $data->{CoapCommandKeys::KEY_GROUPS_DATA}; + if (!\property_exists( + $groupData, + CoapCommandKeys::KEY_GET_LIGHTS + )) { + throw new RuntimeException( + 'attribute missing ('.CoapCommandKeys::KEY_GET_LIGHTS.')' + ); + } + $lightData = $groupData->{CoapCommandKeys::KEY_GET_LIGHTS}; + + if (!isset($lightData->{CoapCommandKeys::KEY_ID})) { + throw new RuntimeException( + 'attribute group data is not an array ('. + CoapCommandKeys::KEY_GROUPS_DATA. + '->'.CoapCommandKeys::KEY_GET_LIGHTS. + '->'.CoapCommandKeys::KEY_ID.')' + ); + } + } catch (\Throwable $exception) { + $isValid = false; + } + + return $isValid; + } + + /** + * Validate must have properties + * + * @param \stdClass $device + * + * @return bool + * + * @throws \IKEA\Tradfri\Exception\RuntimeException + */ + protected function _validateDeviceMustHaves($device): bool + { + if (\is_object($device) === false) { + throw new TypeException('device is no object'); + } + foreach (self::$_mustHaves as $mustHave) { + if (!\property_exists($device, $mustHave)) { + throw new RuntimeException( + 'attribute missing ('.$mustHave.')' + ); + } + } + + return true; + } +} diff --git a/src/IKEA/Tradfri/Validator/ValidatorInterface.php b/src/IKEA/Tradfri/Validator/ValidatorInterface.php new file mode 100644 index 00000000..65dbfa9e --- /dev/null +++ b/src/IKEA/Tradfri/Validator/ValidatorInterface.php @@ -0,0 +1,19 @@ + json_decode(\json_encode([ + 1000 => \json_decode(\json_encode([ CoapCommandKeys::KEY_NAME => 'Group 1', CoapCommandKeys::KEY_TIME => 1498340208, CoapCommandKeys::KEY_ID => 1000, @@ -122,7 +120,7 @@ public function getGroupDataCoapsResponse(): array ], ], ])), - 2000 => json_decode(\json_encode([ + 2000 => \json_decode(\json_encode([ CoapCommandKeys::KEY_NAME => 'Group 2', CoapCommandKeys::KEY_TIME => 1498339585, CoapCommandKeys::KEY_ID => 2000, @@ -142,7 +140,7 @@ public function getGroupDataCoapsResponse(): array ], ], ])), - 3000 => json_decode(\json_encode([ + 3000 => \json_decode(\json_encode([ CoapCommandKeys::KEY_NAME => 'Group 3', CoapCommandKeys::KEY_TIME => 1498340478, CoapCommandKeys::KEY_ID => 3000, diff --git a/tests/_support/UnitTester.php b/tests/_support/UnitTester.php index f40256e0..a734bc21 100644 --- a/tests/_support/UnitTester.php +++ b/tests/_support/UnitTester.php @@ -5,6 +5,7 @@ /** * Inherited Methods + * * @method void wantToTest($text) * @method void wantTo($text) * @method void execute($callable) @@ -17,12 +18,12 @@ * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL) * * @SuppressWarnings(PHPMD) -*/ + */ class UnitTester extends \Codeception\Actor { use _generated\UnitTesterActions; - /** + /* * Define custom actions here * */ diff --git a/tests/unit/IKEA/Tradfri/Client/ClientTest.php b/tests/unit/IKEA/Tradfri/Client/ClientTest.php index 9b577cf7..b3a60da5 100644 --- a/tests/unit/IKEA/Tradfri/Client/ClientTest.php +++ b/tests/unit/IKEA/Tradfri/Client/ClientTest.php @@ -65,7 +65,7 @@ public function testICanTurnLightOn() $adapter->shouldReceive('changeLightState')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); // Act $result = $client->lightOn($light); // Assert @@ -79,7 +79,7 @@ public function testICanTurnLightOff() $adapter->shouldReceive('changeLightState')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); // Act $result = $client->lightOff($light); // Assert @@ -93,7 +93,7 @@ public function testICanTurnGroupOn() $adapter->shouldReceive('changeGroupState')->andReturn(true); $client = new Client($adapter); - $group = new Light(1, \Mockery::mock(ServiceInterface::class)); + $group = new Light(1, \Mockery::mock(ServiceInterface::class)); // Act $result = $client->groupOn($group); // Assert @@ -107,7 +107,7 @@ public function testICanTurnGroupOff() $adapter->shouldReceive('changeGroupState')->andReturn(true); $client = new Client($adapter); - $group = new Light(1, \Mockery::mock(ServiceInterface::class)); + $group = new Light(1, \Mockery::mock(ServiceInterface::class)); // Act $result = $client->groupOff($group); // Assert @@ -121,7 +121,7 @@ public function testICanDimLight() $adapter->shouldReceive('setLightBrightness')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); // Act $result = $client->dimLight($light, 50); // Assert @@ -135,7 +135,7 @@ public function testICanDimGroup() $adapter->shouldReceive('setGroupBrightness')->andReturn(true); $client = new Client($adapter); - $group = new Light(1, \Mockery::mock(ServiceInterface::class)); + $group = new Light(1, \Mockery::mock(ServiceInterface::class)); // Act $result = $client->dimGroup($group, 50); // Assert diff --git a/tests/unit/IKEA/Tradfri/Device/DeviceTester.php b/tests/unit/IKEA/Tradfri/Device/DeviceTester.php index bbc1574c..60c27e2a 100644 --- a/tests/unit/IKEA/Tradfri/Device/DeviceTester.php +++ b/tests/unit/IKEA/Tradfri/Device/DeviceTester.php @@ -10,8 +10,8 @@ /** * Class DeviceTest + * * @method createMock($originalClassName) - * @package IKEA\Tests\Tradfri\Device */ abstract class DeviceTester extends UnitTest { diff --git a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php index 6343a6c4..598c4864 100644 --- a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php +++ b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php @@ -12,8 +12,6 @@ /** * Class LightbulbTest - * - * @package IKEA\Tests\Tradfri\Device */ class LightbulbTest extends \IKEA\Tests\Tradfri\Device\DeviceTester { @@ -73,7 +71,7 @@ public function testGetBrightness() { // Arrange $lamp = $this->_getModel(); - $lamp->setBrightness((int)round(30 * 2.54)); + $lamp->setBrightness((int) \round(30 * 2.54)); // Act $result = $lamp->getBrightness(); @@ -252,7 +250,7 @@ public function testICanSwitchOffReturnedFalse() $this->expectExceptionMessage('switch OFF failed'); // Arrange - $lamp = $this->_getModel(); + $lamp = $this->_getModel(); $service = \Mockery::mock(Api::class); $service->shouldReceive('off')->andReturn(false); diff --git a/tests/unit/IKEA/Tradfri/Group/LightTest.php b/tests/unit/IKEA/Tradfri/Group/LightTest.php index c0459ac5..009febee 100644 --- a/tests/unit/IKEA/Tradfri/Group/LightTest.php +++ b/tests/unit/IKEA/Tradfri/Group/LightTest.php @@ -11,8 +11,6 @@ /** * Class LightTest - * - * @package IKEA\Tests\Tradfri\Group */ class LightTest extends UnitTest { @@ -51,7 +49,7 @@ public function testICanSetDevicesCollectionToGroup() // Act $group->setDevices(new Devices()); - $result = $group->getDevices(); + $result = $group->getDevices(); $resultLights = $group->getLights(); // Assert $this->assertInstanceOf(Devices::class, $result); diff --git a/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php b/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php index abca1808..807066fe 100644 --- a/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php +++ b/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php @@ -17,7 +17,6 @@ /** * Class DeviceDataTest * - * @package IKEA\Tests\Tradfri\Mapper * @method createMock($originalClassName) */ class DeviceDataTest extends UnitTest @@ -33,7 +32,7 @@ public function testMapDataErrorNoData() $this->expectException(RuntimeException::class); // Arrange $serviceMock = $this->createMock(ServiceInterface::class); - $devices = []; + $devices = []; $mapper = new DeviceData(); // Act diff --git a/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php b/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php index ac329804..21e506d3 100644 --- a/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php +++ b/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php @@ -11,8 +11,6 @@ /** * Class DeviceDataTest - * - * @package IKEA\Tests\Tradfri\Mapper */ class GroupDataTest extends UnitTest { @@ -25,7 +23,7 @@ public function testICanMapEmptyDataWithNoError() { // Arrange $serviceMock = \Mockery::mock(ServiceInterface::class); - $devices = []; + $devices = []; $mapper = new GroupData(); // Act diff --git a/tests/unit/IKEA/Tradfri/Service/ApiTest.php b/tests/unit/IKEA/Tradfri/Service/ApiTest.php index 285d2a0b..5ffc5105 100644 --- a/tests/unit/IKEA/Tradfri/Service/ApiTest.php +++ b/tests/unit/IKEA/Tradfri/Service/ApiTest.php @@ -17,8 +17,6 @@ /** * Class ApiTest - * - * @package IKEA\Tests\Tradfri\Service */ class ApiTest extends UnitTest { @@ -249,7 +247,7 @@ public function testICanSwitchGroupOff() $client = \Mockery::mock(Client::class); $client->shouldReceive('groupOff')->andReturn(true); $service = new Api($client); - $group = new Group(1, $service); + $group = new Group(1, $service); $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W))->setState(true)); @@ -270,7 +268,7 @@ public function testICanSwitchADimmerOn() $dimmer = new Dimmer(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->switchOn($dimmer); @@ -285,7 +283,7 @@ public function testICanSwitchADimmerOff() $dimmer = new Dimmer(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->off($dimmer); @@ -300,7 +298,7 @@ public function testICanSwitchARemoteOn() $remote = new Remote(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->switchOn($remote); @@ -315,7 +313,7 @@ public function testICanSwitchARemoteOff() $remote = new Remote(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->off($remote); @@ -329,7 +327,7 @@ public function testICanDimAGroup() $client->shouldReceive('dimGroup')->andReturn(true); $service = new Api($client); - $group = new Group(1, $service); + $group = new Group(1, $service); // Act $result = $service->dim($group, 20); // Assert @@ -360,7 +358,7 @@ public function testICanNotDimADimmer() $dimmer = new Dimmer(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->dim($dimmer, 20); @@ -375,7 +373,7 @@ public function testICanNotDimARemote() $remote = new Remote(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->dim($remote, 20); diff --git a/wiki/example/example-light-info.php b/wiki/example/example-light-info.php index f1d908c7..493602bd 100644 --- a/wiki/example/example-light-info.php +++ b/wiki/example/example-light-info.php @@ -3,8 +3,8 @@ require __DIR__.'/init.php'; +echo '---------- IKEA Tradfri PHP API Example: '.basename(__FILE__).PHP_EOL; try { - echo '---------- IKEA Tradfri PHP API Example: '.basename(__FILE__).PHP_EOL; $lights = $api->getLights(); diff --git a/wiki/example/example-list-lights.php b/wiki/example/example-list-lights.php index c1348247..52d18647 100644 --- a/wiki/example/example-list-lights.php +++ b/wiki/example/example-list-lights.php @@ -10,19 +10,21 @@ $lights->sortByState(); echo '---------- IKEA Tradfri PHP API Example: '.basename(__FILE__).PHP_EOL; - $lights->forAll(function ($key, $light) { - /** @var \IKEA\Tradfri\Device\Lightbulb $light */ - echo '---------- Light Information'.PHP_EOL; - echo '- ID: ' . $light->getId(). PHP_EOL; - echo '- Name: ' . $light->getName(). PHP_EOL; - echo '- Manufacturer: ' . $light->getManufacturer(). PHP_EOL; - echo '- Version: ' . $light->getVersion(). PHP_EOL; - echo '- State is: ' . $light->getState(). PHP_EOL; - echo '- Brightness ' . $light->getBrightness().'%'. PHP_EOL; - echo ' '.PHP_EOL; + $lights->forAll( + function ($key, $light) { + /** @var \IKEA\Tradfri\Device\Lightbulb $light */ + echo '---------- Light Information'.PHP_EOL; + echo '- ID: ' . $light->getId(). PHP_EOL; + echo '- Name: ' . $light->getName(). PHP_EOL; + echo '- Manufacturer: ' . $light->getManufacturer(). PHP_EOL; + echo '- Version: ' . $light->getVersion(). PHP_EOL; + echo '- State is: ' . $light->getState(). PHP_EOL; + echo '- Brightness ' . $light->getBrightness().'%'. PHP_EOL; + echo ' '.PHP_EOL; - return true; - }); + return true; + } + ); } catch (\Exception $e) { echo $e->getMessage().PHP_EOL.PHP_EOL; echo $e->getTraceAsString(); From b85b54640ceed3d687247748bfbb0e5af22aee7f Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sat, 20 Jan 2018 02:49:22 +0000 Subject: [PATCH 24/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Adapter/AdapterAbstract.php | 6 ++-- .../Tradfri/Collection/AbstractCollection.php | 5 +--- src/IKEA/Tradfri/Command/Coaps.php | 4 +-- src/IKEA/Tradfri/Device/Device.php | 10 +++---- src/IKEA/Tradfri/Helper/CoapCommandKeys.php | 28 +++++++++---------- src/IKEA/Tradfri/Helper/Online.php | 10 +++---- src/IKEA/Tradfri/Helper/Runner.php | 2 +- src/IKEA/Tradfri/Validator/Device/Data.php | 27 +++++++++--------- src/IKEA/Tradfri/Validator/Group/Data.php | 15 +++++----- .../Tradfri/Validator/ValidatorInterface.php | 1 + 10 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php index b9879fd5..99300e6a 100644 --- a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php +++ b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php @@ -37,7 +37,7 @@ public function __construct( MapperInterface $groupDataMapper ) { $this->_deviceDataMapper = $deviceDataMapper; - $this->_groupDataMapper = $groupDataMapper; + $this->_groupDataMapper = $groupDataMapper; } /** @@ -63,7 +63,7 @@ abstract public function getGroupCollection( ): Groups; /** - * Get DeviceDataMapper + * Get DeviceDataMapper. * * @return DeviceData|MapperInterface */ @@ -73,7 +73,7 @@ public function getDeviceDataMapper() } /** - * Get GroupDataMapper + * Get GroupDataMapper. * * @return GroupData|MapperInterface */ diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index 4bdfacab..3b9c8605 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -12,8 +12,7 @@ /** * Class Devices. */ -abstract class AbstractCollection extends ArrayCollection - implements JsonSerializable +abstract class AbstractCollection extends ArrayCollection implements JsonSerializable { /** * Add item to collection. @@ -50,8 +49,6 @@ public function find($closure) throw new RuntimeException('closure function not working'); } } - - return; } /** diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 5a36badd..2c1c48a1 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -15,8 +15,8 @@ */ class Coaps { - const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; - const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; + const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; + const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; const COAP_COMMAND_POST = 'coap-client -m post -u "%s" -k "%s"'; /** diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index 985b8c12..412918ca 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -14,12 +14,12 @@ */ abstract class Device implements JsonSerializable { - const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; + const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; const TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; - const TYPE_DIMMER = 'TRADFRI dimmer'; - const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; - const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; - const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; + const TYPE_DIMMER = 'TRADFRI dimmer'; + const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; + const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; + const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; /** * @var array diff --git a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php index fadc9c8b..27c00d50 100644 --- a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php +++ b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php @@ -10,26 +10,26 @@ class CoapCommandKeys { const KEY_MANUFACTURER = '0'; - const KEY_TYPE = '1'; - const KEY_DATA = '3'; - const KEY_VERSION = '3'; + const KEY_TYPE = '1'; + const KEY_DATA = '3'; + const KEY_VERSION = '3'; const KEY_DEVICE_DATA = '3311'; - const KEY_COLOR = '5709'; + const KEY_COLOR = '5709'; const KEY_COLOR_2 = '5710'; - const KEY_ONOFF = '5850'; - const KEY_DIMMER = '5851'; + const KEY_ONOFF = '5850'; + const KEY_DIMMER = '5851'; - const KEY_NAME = '9001'; - const KEY_TIME = '9002'; - const KEY_ID = '9003'; + const KEY_NAME = '9001'; + const KEY_TIME = '9002'; + const KEY_ID = '9003'; const KEY_GROUPS_DATA = '9018'; - const KEY_X = '9039'; - const KEY_SHARED_KEY = '9091'; + const KEY_X = '9039'; + const KEY_SHARED_KEY = '9091'; - const KEY_GET_DATA = '15001'; - const KEY_GET_LIGHTS = '15002'; - const KEY_GET_GROUPS = '15004'; + const KEY_GET_DATA = '15001'; + const KEY_GET_LIGHTS = '15002'; + const KEY_GET_GROUPS = '15004'; const KEY_GET_SHARED_KEY = '15011/9063'; } diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 1e653531..84d7023d 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -21,7 +21,7 @@ class Online public static function isOnline(string $ipAddress): bool { $online = true; - $regex = '/(\ \d+% packet loss), (time \d+ms)/'; + $regex = '/(\ \d+% packet loss), (time \d+ms)/'; try { $data = Runner::execWithTimeout('ping -c1 '.$ipAddress, 1, false); @@ -41,13 +41,13 @@ public static function isOnline(string $ipAddress): bool } /** - * Validate matches - * - * @param array $matches + * Validate matches. * - * @return bool + * @param array $matches * * @throws \IKEA\Tradfri\Exception\RuntimeException + * + * @return bool */ protected static function _validateMatches(array $matches): bool { diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index a2a8e539..fa4634e8 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -59,7 +59,7 @@ public static function execWithTimeout( $start = \microtime(true); // Wait until we have output or the timer expired. - $read = [$pipes[1]]; + $read = [$pipes[1]]; $other = []; \stream_select($read, $other, $other, 0, (int) $timeout); diff --git a/src/IKEA/Tradfri/Validator/Device/Data.php b/src/IKEA/Tradfri/Validator/Device/Data.php index 440fa72e..b5b772b1 100644 --- a/src/IKEA/Tradfri/Validator/Device/Data.php +++ b/src/IKEA/Tradfri/Validator/Device/Data.php @@ -1,4 +1,5 @@ _validateDeviceMustHaves($data); - $isValid = true; + $isValid = true; $groupData = $data->{CoapCommandKeys::KEY_GROUPS_DATA}; if (!\property_exists( @@ -65,13 +66,13 @@ public function isValid($data): bool } /** - * Validate must have properties + * Validate must have properties. * * @param \stdClass $device * - * @return bool - * * @throws \IKEA\Tradfri\Exception\RuntimeException + * + * @return bool */ protected function _validateDeviceMustHaves($device): bool { diff --git a/src/IKEA/Tradfri/Validator/ValidatorInterface.php b/src/IKEA/Tradfri/Validator/ValidatorInterface.php index 65dbfa9e..d5049e42 100644 --- a/src/IKEA/Tradfri/Validator/ValidatorInterface.php +++ b/src/IKEA/Tradfri/Validator/ValidatorInterface.php @@ -1,4 +1,5 @@ Date: Sat, 20 Jan 2018 03:58:08 +0100 Subject: [PATCH 25/73] some more cleanup --- .codeclimate.yml | 2 +- src/IKEA/Tradfri/Command/Coaps.php | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 7d6ffa58..22a57e78 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -44,7 +44,7 @@ plugins: file_extensions: "php" standard: "Zend" checks: - Squiz ControlStructures ControlSignature NewlineAfterOpenBrace: + Generic Functions OpeningFunctionBraceBsdAllman BraceOnSameLine: enabled: false PSR2 Methods MethodDeclaration Underscore: enabled: false diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 5a36badd..11fe1961 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -105,8 +105,7 @@ public function getPreSharedKeyCommand(): string $this->_secret ) .' -e \'{"9090":"'.$this->getUsername().'"}\'' - .' "coaps://'.$this->getIp().':5684/' - .CoapCommandKeys::KEY_GET_SHARED_KEY.'"'; + .$this->_getRequestTypeCoapsUrl(CoapCommandKeys::KEY_GET_SHARED_KEY); return $command; } @@ -194,7 +193,7 @@ public function getCoapsCommandGet($requestType): string self::COAP_COMMAND_GET, $this->getUsername(), $this->getApiKey() - ).' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; + ).$this->_getRequestTypeCoapsUrl($requestType); } /** @@ -236,8 +235,7 @@ public function getCoapsCommandPost($requestType, string $inject): string $this->getUsername(), $this->getApiKey() ) - .$inject.' "coaps://'.$this->getIp().':5684/' - .$requestType.'"'; + .$inject.$this->_getRequestTypeCoapsUrl($requestType); } /** @@ -276,8 +274,7 @@ public function getCoapsCommandPut($requestType, string $inject): string $this->getApiKey() ) .$inject - .' "coaps://'.$this->getIp().':5684/'.$requestType - .'"'; + .$this->_getRequestTypeCoapsUrl($requestType); } /** @@ -370,4 +367,16 @@ public function getLightColorCommand(int $groupId, string $color): string $payload ); } + + /** + * Get Coap uri + * + * @param $requestType + * + * @return string + */ + protected function _getRequestTypeCoapsUrl($requestType): string + { + return ' "coaps://'.$this->getIp().':5684/'.$requestType.'"'; + } } From 4093950d4286f42042c6dd0f38cc21796b9eef1b Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sat, 20 Jan 2018 02:58:28 +0000 Subject: [PATCH 26/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Command/Coaps.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 5b395c44..fe5939c6 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -369,7 +369,7 @@ public function getLightColorCommand(int $groupId, string $color): string } /** - * Get Coap uri + * Get Coap uri. * * @param $requestType * From 5acc543f9c7d7e859310348acafe5c43b9912e76 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 20 Jan 2018 04:02:57 +0100 Subject: [PATCH 27/73] - csf fix --- src/IKEA/Tradfri/Adapter/AdapterAbstract.php | 2 +- src/IKEA/Tradfri/Command/Coaps.php | 4 +-- src/IKEA/Tradfri/Device/Device.php | 10 +++---- src/IKEA/Tradfri/Helper/CoapCommandKeys.php | 28 ++++++++++---------- src/IKEA/Tradfri/Helper/Online.php | 2 +- src/IKEA/Tradfri/Helper/Runner.php | 2 +- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php index 99300e6a..51bc507e 100644 --- a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php +++ b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php @@ -37,7 +37,7 @@ public function __construct( MapperInterface $groupDataMapper ) { $this->_deviceDataMapper = $deviceDataMapper; - $this->_groupDataMapper = $groupDataMapper; + $this->_groupDataMapper = $groupDataMapper; } /** diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index fe5939c6..67b9a348 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -15,8 +15,8 @@ */ class Coaps { - const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; - const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; + const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; + const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; const COAP_COMMAND_POST = 'coap-client -m post -u "%s" -k "%s"'; /** diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index 412918ca..985b8c12 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -14,12 +14,12 @@ */ abstract class Device implements JsonSerializable { - const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; + const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; const TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; - const TYPE_DIMMER = 'TRADFRI dimmer'; - const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; - const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; - const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; + const TYPE_DIMMER = 'TRADFRI dimmer'; + const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; + const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; + const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; /** * @var array diff --git a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php index 27c00d50..fadc9c8b 100644 --- a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php +++ b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php @@ -10,26 +10,26 @@ class CoapCommandKeys { const KEY_MANUFACTURER = '0'; - const KEY_TYPE = '1'; - const KEY_DATA = '3'; - const KEY_VERSION = '3'; + const KEY_TYPE = '1'; + const KEY_DATA = '3'; + const KEY_VERSION = '3'; const KEY_DEVICE_DATA = '3311'; - const KEY_COLOR = '5709'; + const KEY_COLOR = '5709'; const KEY_COLOR_2 = '5710'; - const KEY_ONOFF = '5850'; - const KEY_DIMMER = '5851'; + const KEY_ONOFF = '5850'; + const KEY_DIMMER = '5851'; - const KEY_NAME = '9001'; - const KEY_TIME = '9002'; - const KEY_ID = '9003'; + const KEY_NAME = '9001'; + const KEY_TIME = '9002'; + const KEY_ID = '9003'; const KEY_GROUPS_DATA = '9018'; - const KEY_X = '9039'; - const KEY_SHARED_KEY = '9091'; + const KEY_X = '9039'; + const KEY_SHARED_KEY = '9091'; - const KEY_GET_DATA = '15001'; - const KEY_GET_LIGHTS = '15002'; - const KEY_GET_GROUPS = '15004'; + const KEY_GET_DATA = '15001'; + const KEY_GET_LIGHTS = '15002'; + const KEY_GET_GROUPS = '15004'; const KEY_GET_SHARED_KEY = '15011/9063'; } diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 84d7023d..71f30699 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -21,7 +21,7 @@ class Online public static function isOnline(string $ipAddress): bool { $online = true; - $regex = '/(\ \d+% packet loss), (time \d+ms)/'; + $regex = '/(\ \d+% packet loss), (time \d+ms)/'; try { $data = Runner::execWithTimeout('ping -c1 '.$ipAddress, 1, false); diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index fa4634e8..a2a8e539 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -59,7 +59,7 @@ public static function execWithTimeout( $start = \microtime(true); // Wait until we have output or the timer expired. - $read = [$pipes[1]]; + $read = [$pipes[1]]; $other = []; \stream_select($read, $other, $other, 0, (int) $timeout); From e82e9e200c3e71500f169f4474c260015ddf2a4e Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sat, 20 Jan 2018 03:03:08 +0000 Subject: [PATCH 28/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Adapter/AdapterAbstract.php | 2 +- src/IKEA/Tradfri/Command/Coaps.php | 4 +-- src/IKEA/Tradfri/Device/Device.php | 10 +++---- src/IKEA/Tradfri/Helper/CoapCommandKeys.php | 28 ++++++++++---------- src/IKEA/Tradfri/Helper/Online.php | 2 +- src/IKEA/Tradfri/Helper/Runner.php | 2 +- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php index 51bc507e..99300e6a 100644 --- a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php +++ b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php @@ -37,7 +37,7 @@ public function __construct( MapperInterface $groupDataMapper ) { $this->_deviceDataMapper = $deviceDataMapper; - $this->_groupDataMapper = $groupDataMapper; + $this->_groupDataMapper = $groupDataMapper; } /** diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 67b9a348..fe5939c6 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -15,8 +15,8 @@ */ class Coaps { - const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; - const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; + const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; + const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; const COAP_COMMAND_POST = 'coap-client -m post -u "%s" -k "%s"'; /** diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index 985b8c12..412918ca 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -14,12 +14,12 @@ */ abstract class Device implements JsonSerializable { - const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; + const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; const TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; - const TYPE_DIMMER = 'TRADFRI dimmer'; - const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; - const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; - const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; + const TYPE_DIMMER = 'TRADFRI dimmer'; + const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; + const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; + const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; /** * @var array diff --git a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php index fadc9c8b..27c00d50 100644 --- a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php +++ b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php @@ -10,26 +10,26 @@ class CoapCommandKeys { const KEY_MANUFACTURER = '0'; - const KEY_TYPE = '1'; - const KEY_DATA = '3'; - const KEY_VERSION = '3'; + const KEY_TYPE = '1'; + const KEY_DATA = '3'; + const KEY_VERSION = '3'; const KEY_DEVICE_DATA = '3311'; - const KEY_COLOR = '5709'; + const KEY_COLOR = '5709'; const KEY_COLOR_2 = '5710'; - const KEY_ONOFF = '5850'; - const KEY_DIMMER = '5851'; + const KEY_ONOFF = '5850'; + const KEY_DIMMER = '5851'; - const KEY_NAME = '9001'; - const KEY_TIME = '9002'; - const KEY_ID = '9003'; + const KEY_NAME = '9001'; + const KEY_TIME = '9002'; + const KEY_ID = '9003'; const KEY_GROUPS_DATA = '9018'; - const KEY_X = '9039'; - const KEY_SHARED_KEY = '9091'; + const KEY_X = '9039'; + const KEY_SHARED_KEY = '9091'; - const KEY_GET_DATA = '15001'; - const KEY_GET_LIGHTS = '15002'; - const KEY_GET_GROUPS = '15004'; + const KEY_GET_DATA = '15001'; + const KEY_GET_LIGHTS = '15002'; + const KEY_GET_GROUPS = '15004'; const KEY_GET_SHARED_KEY = '15011/9063'; } diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 71f30699..84d7023d 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -21,7 +21,7 @@ class Online public static function isOnline(string $ipAddress): bool { $online = true; - $regex = '/(\ \d+% packet loss), (time \d+ms)/'; + $regex = '/(\ \d+% packet loss), (time \d+ms)/'; try { $data = Runner::execWithTimeout('ping -c1 '.$ipAddress, 1, false); diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index a2a8e539..fa4634e8 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -59,7 +59,7 @@ public static function execWithTimeout( $start = \microtime(true); // Wait until we have output or the timer expired. - $read = [$pipes[1]]; + $read = [$pipes[1]]; $other = []; \stream_select($read, $other, $other, 0, (int) $timeout); From af4b857945f6b32c3318fefeaaa75ef42e8dc2ef Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 20 Jan 2018 04:05:02 +0100 Subject: [PATCH 29/73] - cs fix --- .php_cs | 2 +- tests/unit/IKEA/Tradfri/Client/ClientTest.php | 12 ++++++------ tests/unit/IKEA/Tradfri/Device/LightbulbTest.php | 2 +- tests/unit/IKEA/Tradfri/Group/LightTest.php | 2 +- .../unit/IKEA/Tradfri/Mapper/DeviceDataTest.php | 2 +- tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php | 2 +- tests/unit/IKEA/Tradfri/Service/ApiTest.php | 16 ++++++++-------- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.php_cs b/.php_cs index 580a4159..a6f6d985 100644 --- a/.php_cs +++ b/.php_cs @@ -10,7 +10,7 @@ return PhpCsFixer\Config::create() 'array_syntax' => ['syntax' => 'short'], 'binary_operator_spaces' => [ 'align_double_arrow' => true, - 'align_equals' => true + 'align_equals' => false ], 'blank_line_after_namespace' => true, 'blank_line_before_statement' => [ diff --git a/tests/unit/IKEA/Tradfri/Client/ClientTest.php b/tests/unit/IKEA/Tradfri/Client/ClientTest.php index b3a60da5..9b577cf7 100644 --- a/tests/unit/IKEA/Tradfri/Client/ClientTest.php +++ b/tests/unit/IKEA/Tradfri/Client/ClientTest.php @@ -65,7 +65,7 @@ public function testICanTurnLightOn() $adapter->shouldReceive('changeLightState')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); // Act $result = $client->lightOn($light); // Assert @@ -79,7 +79,7 @@ public function testICanTurnLightOff() $adapter->shouldReceive('changeLightState')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); // Act $result = $client->lightOff($light); // Assert @@ -93,7 +93,7 @@ public function testICanTurnGroupOn() $adapter->shouldReceive('changeGroupState')->andReturn(true); $client = new Client($adapter); - $group = new Light(1, \Mockery::mock(ServiceInterface::class)); + $group = new Light(1, \Mockery::mock(ServiceInterface::class)); // Act $result = $client->groupOn($group); // Assert @@ -107,7 +107,7 @@ public function testICanTurnGroupOff() $adapter->shouldReceive('changeGroupState')->andReturn(true); $client = new Client($adapter); - $group = new Light(1, \Mockery::mock(ServiceInterface::class)); + $group = new Light(1, \Mockery::mock(ServiceInterface::class)); // Act $result = $client->groupOff($group); // Assert @@ -121,7 +121,7 @@ public function testICanDimLight() $adapter->shouldReceive('setLightBrightness')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); // Act $result = $client->dimLight($light, 50); // Assert @@ -135,7 +135,7 @@ public function testICanDimGroup() $adapter->shouldReceive('setGroupBrightness')->andReturn(true); $client = new Client($adapter); - $group = new Light(1, \Mockery::mock(ServiceInterface::class)); + $group = new Light(1, \Mockery::mock(ServiceInterface::class)); // Act $result = $client->dimGroup($group, 50); // Assert diff --git a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php index 598c4864..7142a399 100644 --- a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php +++ b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php @@ -250,7 +250,7 @@ public function testICanSwitchOffReturnedFalse() $this->expectExceptionMessage('switch OFF failed'); // Arrange - $lamp = $this->_getModel(); + $lamp = $this->_getModel(); $service = \Mockery::mock(Api::class); $service->shouldReceive('off')->andReturn(false); diff --git a/tests/unit/IKEA/Tradfri/Group/LightTest.php b/tests/unit/IKEA/Tradfri/Group/LightTest.php index 009febee..671d9d3c 100644 --- a/tests/unit/IKEA/Tradfri/Group/LightTest.php +++ b/tests/unit/IKEA/Tradfri/Group/LightTest.php @@ -49,7 +49,7 @@ public function testICanSetDevicesCollectionToGroup() // Act $group->setDevices(new Devices()); - $result = $group->getDevices(); + $result = $group->getDevices(); $resultLights = $group->getLights(); // Assert $this->assertInstanceOf(Devices::class, $result); diff --git a/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php b/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php index 807066fe..d936a97d 100644 --- a/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php +++ b/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php @@ -32,7 +32,7 @@ public function testMapDataErrorNoData() $this->expectException(RuntimeException::class); // Arrange $serviceMock = $this->createMock(ServiceInterface::class); - $devices = []; + $devices = []; $mapper = new DeviceData(); // Act diff --git a/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php b/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php index 21e506d3..de000938 100644 --- a/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php +++ b/tests/unit/IKEA/Tradfri/Mapper/GroupDataTest.php @@ -23,7 +23,7 @@ public function testICanMapEmptyDataWithNoError() { // Arrange $serviceMock = \Mockery::mock(ServiceInterface::class); - $devices = []; + $devices = []; $mapper = new GroupData(); // Act diff --git a/tests/unit/IKEA/Tradfri/Service/ApiTest.php b/tests/unit/IKEA/Tradfri/Service/ApiTest.php index 5ffc5105..0e0f86b0 100644 --- a/tests/unit/IKEA/Tradfri/Service/ApiTest.php +++ b/tests/unit/IKEA/Tradfri/Service/ApiTest.php @@ -247,7 +247,7 @@ public function testICanSwitchGroupOff() $client = \Mockery::mock(Client::class); $client->shouldReceive('groupOff')->andReturn(true); $service = new Api($client); - $group = new Group(1, $service); + $group = new Group(1, $service); $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W))->setState(true)); @@ -268,7 +268,7 @@ public function testICanSwitchADimmerOn() $dimmer = new Dimmer(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->switchOn($dimmer); @@ -283,7 +283,7 @@ public function testICanSwitchADimmerOff() $dimmer = new Dimmer(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->off($dimmer); @@ -298,7 +298,7 @@ public function testICanSwitchARemoteOn() $remote = new Remote(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->switchOn($remote); @@ -313,7 +313,7 @@ public function testICanSwitchARemoteOff() $remote = new Remote(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->off($remote); @@ -327,7 +327,7 @@ public function testICanDimAGroup() $client->shouldReceive('dimGroup')->andReturn(true); $service = new Api($client); - $group = new Group(1, $service); + $group = new Group(1, $service); // Act $result = $service->dim($group, 20); // Assert @@ -358,7 +358,7 @@ public function testICanNotDimADimmer() $dimmer = new Dimmer(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->dim($dimmer, 20); @@ -373,7 +373,7 @@ public function testICanNotDimARemote() $remote = new Remote(1); /** @var Client $client */ - $client = \Mockery::mock(Client::class); + $client = \Mockery::mock(Client::class); $service = new Api($client); // Act $result = $service->dim($remote, 20); From 2f0a9a817f13e4eb1a3cc8521d8a9e70d4f9cf6d Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 4 Feb 2018 22:12:18 +0100 Subject: [PATCH 30/73] - added api as third parameter to client --- src/IKEA/Tradfri/Command/Coaps.php | 8 +++++--- wiki/example/init-dist.php | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index fe5939c6..5d802ff2 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -44,6 +44,7 @@ class Coaps * * @param string $ipAddress * @param string $secret + * @param string $apiKey * @param string $username * * @throws \InvalidArgumentException @@ -52,15 +53,16 @@ class Coaps public function __construct( string $ipAddress, string $secret, + string $apiKey, $username = null ) { $this->setIp($ipAddress); $this->_secret = $secret; - if (!\defined('COAP_API_KEY')) { - throw new RuntimeException('COAP_API_KEY not set'); + if (!empty($apiKey)) { + throw new RuntimeException('$apiKey can not be empty'); } - $this->setApiKey(COAP_API_KEY); + $this->setApiKey($apiKey); if (null !== $username) { $this->setUsername($username); diff --git a/wiki/example/init-dist.php b/wiki/example/init-dist.php index d8ae1d9b..713af0a3 100644 --- a/wiki/example/init-dist.php +++ b/wiki/example/init-dist.php @@ -8,7 +8,7 @@ die('composer up!'); } -require '../../vendor/autoload.php'; +require __DIR__.'/../../vendor/autoload.php'; define('COAP_GATEWAY_IP', 'yourHubIp'); define('COAP_GATEWAY_SECRET', 'secretFromBacksideOfHub'); @@ -22,7 +22,7 @@ $deviceMapper = new IKEA\Tradfri\Mapper\DeviceData(); $groupMapper = new IKEA\Tradfri\Mapper\GroupData(); -$commands = new Coaps(COAP_GATEWAY_IP, COAP_GATEWAY_SECRET); +$commands = new Coaps(COAP_GATEWAY_IP, COAP_GATEWAY_SECRET, COAP_API_KEY); $adapter = new Adapter($commands, $deviceMapper, $groupMapper); $client = new \IKEA\Tradfri\Client\Client($adapter); $api = new \IKEA\Tradfri\Service\Api($client); From fdc3436bae0aa564b1f5851fe2158c8bd7e03911 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 4 Feb 2018 22:21:03 +0100 Subject: [PATCH 31/73] - fixed condition in coaps constructor --- src/IKEA/Tradfri/Command/Coaps.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 5d802ff2..5e417a81 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -58,7 +58,7 @@ public function __construct( ) { $this->setIp($ipAddress); $this->_secret = $secret; - if (!empty($apiKey)) { + if (empty($apiKey)) { throw new RuntimeException('$apiKey can not be empty'); } From 906c04a8ac73cb5ee5c051ac944039fde2ac4a1b Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 4 Feb 2018 23:28:12 +0100 Subject: [PATCH 32/73] - optimized error handling - changed offline detection --- src/IKEA/Tradfri/Helper/Online.php | 6 +----- src/IKEA/Tradfri/Helper/Runner.php | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 84d7023d..374a1214 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -21,7 +21,7 @@ class Online public static function isOnline(string $ipAddress): bool { $online = true; - $regex = '/(\ \d+% packet loss), (time \d+ms)/'; + $regex = '/(\ \d+% packet loss)/'; try { $data = Runner::execWithTimeout('ping -c1 '.$ipAddress, 1, false); @@ -55,10 +55,6 @@ protected static function _validateMatches(array $matches): bool throw new RuntimeException('packet loss detected'); } - if (\strpos($matches[0][2], 'time 0ms') === false) { - throw new RuntimeException('ping to high'); - } - return true; } } diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index fa4634e8..5e3d168b 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -94,6 +94,8 @@ public static function execWithTimeout( } else { if (\count($parts) === 2 && !empty($parts[1])) { $errorMessage = $parts[1]; + } elseif (empty($parts[1])) { + $errorMessage = $parts[0]; } else { $errorMessage = 'Unknown error'; } From 1381633c151da2f0f86990151fad51d816bbc2c7 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 24 Feb 2018 19:29:52 +0100 Subject: [PATCH 33/73] - sort items by name --- src/IKEA/Tradfri/Collection/Devices.php | 2 ++ src/IKEA/Tradfri/Collection/Lightbulbs.php | 28 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/IKEA/Tradfri/Collection/Devices.php b/src/IKEA/Tradfri/Collection/Devices.php index 903624ce..f36e9e83 100644 --- a/src/IKEA/Tradfri/Collection/Devices.php +++ b/src/IKEA/Tradfri/Collection/Devices.php @@ -28,6 +28,8 @@ public function getLightbulbs(): Lightbulbs } } + $lightbulbs = $lightbulbs->sortByName(); + return $lightbulbs; } diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index ecd55fce..b0e857cd 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -4,6 +4,7 @@ namespace IKEA\Tradfri\Collection; +use IKEA\Tradfri\Device\Device; use IKEA\Tradfri\Device\Lightbulb; /** @@ -60,4 +61,31 @@ public function getActive(): self return $this->createFrom($newItems); } + + /** + * Sort items by name + * + * @return static + */ + public function sortByName() + { + return $this->createFrom($this->namesAsKeys()); + } + + /** + * Get an array with names as keys + * + * @return array + */ + protected function namesAsKeys(): array + { + $elements = []; + $this->forAll(function ($key, Device $device) use (&$elements) { + $elements[$device->getName()] = $device; + + return true; + }); + \ksort($elements, \SORT_NATURAL); + return $elements; + } } From 730250907d565398a60b1c5080f9546651c46fa1 Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sat, 24 Feb 2018 18:30:13 +0000 Subject: [PATCH 34/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Collection/Lightbulbs.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index b0e857cd..f26f2677 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -63,7 +63,7 @@ public function getActive(): self } /** - * Sort items by name + * Sort items by name. * * @return static */ @@ -73,7 +73,7 @@ public function sortByName() } /** - * Get an array with names as keys + * Get an array with names as keys. * * @return array */ @@ -86,6 +86,7 @@ protected function namesAsKeys(): array return true; }); \ksort($elements, \SORT_NATURAL); + return $elements; } } From 0b0075df1cd241eb0acaf360ad660a3bfb8527aa Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 7 Apr 2018 23:40:10 +0200 Subject: [PATCH 35/73] - fixed regex to work on mac ping format thx to @synga-nl --- Dockerfile | 33 ++++++++++++++++++++++++++++++ src/IKEA/Tradfri/Helper/Online.php | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..7ba3f279 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +FROM debian as builder +MAINTAINER Benjamin Fahl +ENV DEBIAN_FRONTEND noninteractive +ENV DEBIAN_FRONTEND newt +RUN apt-get update \ + && apt-get install -y \ + make \ + automake \ + libtool \ + clang \ + gcc \ + git \ + libcunit1-dev \ + doxygen \ + libxml2-utils \ + xsltproc \ + docbook-xml \ + asciidoc +ENV DEBIAN_FRONTEND newt +RUN git clone --depth 1 --recursive -b dtls https://github.com/home-assistant/libcoap.git \ + && cd libcoap \ + && ./autogen.sh \ + && ./configure --disable-documentation --disable-shared --without-debug CFLAGS="-D COAP_DEBUG_FD=stderr" \ + && make \ + && make install \ + && cd .. \ + && rm -rf libcoap +FROM debian:stable-slim as runner +COPY --from=builder ./usr/local/bin/coap-client /usr/local/bin/coap-client +COPY --from=builder ./usr/local/bin/coap-server /usr/local/bin/coap-server +COPY --from=builder ./usr/local/bin/coap-rd /usr/local/bin/coap-rd +RUN cd /usr/local/bin/ && ls -l +ENTRYPOINT /usr/local/bin/coap-client diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 374a1214..18a2e310 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -21,7 +21,7 @@ class Online public static function isOnline(string $ipAddress): bool { $online = true; - $regex = '/(\ \d+% packet loss)/'; + $regex = '(\ [\d\.]+% packet loss)'; try { $data = Runner::execWithTimeout('ping -c1 '.$ipAddress, 1, false); From 556eef9dd48b8d98ae02346ffb11a6f6fbe8f100 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 7 Apr 2018 23:54:18 +0200 Subject: [PATCH 36/73] - added gateway flood protection suggested by @synga-nl and default disabled (and added todo to add better solution) --- src/IKEA/Tradfri/Adapter/Coap.php | 4 ++++ wiki/example/init-dist.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index f47dc31c..6c813860 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -321,6 +321,10 @@ public function getDevicesData(array $deviceIds = null): array // sometimes the request are to fast, // the hub will decline the request (flood security) $deviceData[$deviceId] = $this->getDeviceData((int) $deviceId); + // @TODO: add command queue + if ((int) COAP_GATEWAY_FLOOD_PROTECTION > 0) { + \sleep((int) COAP_GATEWAY_FLOOD_PROTECTION); + } } return $deviceData; diff --git a/wiki/example/init-dist.php b/wiki/example/init-dist.php index 713af0a3..5cdd2e03 100644 --- a/wiki/example/init-dist.php +++ b/wiki/example/init-dist.php @@ -18,6 +18,8 @@ defined('COAP_GATEWAY_IP') ? null : die('FOLLOW FIRST RUN HELP IN README'); defined('COAP_GATEWAY_SECRET') ? null : die('FOLLOW FIRST RUN HELP IN README'); +// default: no flood protection +defined('COAP_GATEWAY_FLOOD_PROTECTION') ? null : define('COAP_GATEWAY_FLOOD_PROTECTION', 0); $deviceMapper = new IKEA\Tradfri\Mapper\DeviceData(); From 8fc97681dc1f907e21c7f9900800d10611b523fa Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 8 Apr 2018 00:05:02 +0200 Subject: [PATCH 37/73] - fixed unit tests - readme update --- README.md | 8 ++++++++ tests/unit/IKEA/Tradfri/Service/ApiTest.php | 14 +++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 166bd239..5e46862b 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,11 @@ see `wiki/example` folder - Executor for commands - Json data response - PSR7 ? + +## Docker Coap-Client [WIP] +work in progress +`docker build . -t webproject/coap-client:latest` + +# Run command [WIP] + work in progress +`docker run --rm --name coap-client2 webproject/coap-client` diff --git a/tests/unit/IKEA/Tradfri/Service/ApiTest.php b/tests/unit/IKEA/Tradfri/Service/ApiTest.php index 0e0f86b0..a1937149 100644 --- a/tests/unit/IKEA/Tradfri/Service/ApiTest.php +++ b/tests/unit/IKEA/Tradfri/Service/ApiTest.php @@ -211,7 +211,10 @@ public function testICanNotSwitchGroupOnBecauseItIsOn() $group = new Group(1, $service); $group->setState(true); - $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W))->setState(true)); + $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W)) + ->setState(true) + ->setName('test') + ); $this->assertTrue($group->isOn()); @@ -230,7 +233,9 @@ public function testICanSwitchGroupOn() $service = new Api($client); $group = new Group(1, $service); - $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W))->setState(false)); + $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W)) + ->setState(false) + ->setName('test')); $this->assertFalse($group->isOn()); @@ -249,7 +254,10 @@ public function testICanSwitchGroupOff() $service = new Api($client); $group = new Group(1, $service); - $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W))->setState(true)); + $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W)) + ->setState(true) + ->setName('test') + ); $this->assertTrue($group->isOn()); From be4c341393d6d97fa937723650915a993edc0e47 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Mon, 9 Apr 2018 19:58:06 +0200 Subject: [PATCH 38/73] - chaned flood protection to microseconds --- src/IKEA/Tradfri/Adapter/Coap.php | 2 +- wiki/example/init-dist.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index 6c813860..948b1830 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -323,7 +323,7 @@ public function getDevicesData(array $deviceIds = null): array $deviceData[$deviceId] = $this->getDeviceData((int) $deviceId); // @TODO: add command queue if ((int) COAP_GATEWAY_FLOOD_PROTECTION > 0) { - \sleep((int) COAP_GATEWAY_FLOOD_PROTECTION); + \usleep((int) COAP_GATEWAY_FLOOD_PROTECTION); } } diff --git a/wiki/example/init-dist.php b/wiki/example/init-dist.php index 5cdd2e03..02f69755 100644 --- a/wiki/example/init-dist.php +++ b/wiki/example/init-dist.php @@ -18,8 +18,8 @@ defined('COAP_GATEWAY_IP') ? null : die('FOLLOW FIRST RUN HELP IN README'); defined('COAP_GATEWAY_SECRET') ? null : die('FOLLOW FIRST RUN HELP IN README'); -// default: no flood protection -defined('COAP_GATEWAY_FLOOD_PROTECTION') ? null : define('COAP_GATEWAY_FLOOD_PROTECTION', 0); +// default: no flood protection (time in microseconds) +defined('COAP_GATEWAY_FLOOD_PROTECTION') ? null : define('COAP_GATEWAY_FLOOD_PROTECTION', 100); $deviceMapper = new IKEA\Tradfri\Mapper\DeviceData(); From 6f7669248a17566b460d595e527137273556bb27 Mon Sep 17 00:00:00 2001 From: The Codacy Badger Date: Tue, 5 Jun 2018 21:30:37 +0000 Subject: [PATCH 39/73] Add Codacy badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 166bd239..9869a940 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ php api to control Ikea smart lights (tradfri) ### Status #### Stable: +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b317b3e9521740e59e7dff003a0cbd69)](https://app.codacy.com/app/Fahl-Design/ikea-tradfri-php?utm_source=github.com&utm_medium=referral&utm_content=WebProject-xyz/ikea-tradfri-php&utm_campaign=badger) [![Build Status](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php.svg?branch=master)](https://travis-ci.org/WebProject-xyz/ikea-tradfri-php) [![Code Climate](https://img.shields.io/codeclimate/github/WebProject-xyz/ikea-tradfri-php.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/) [![Code Climate](https://img.shields.io/codeclimate/issues//github/WebProject-xyz/ikea-tradfri-php.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/) From 67b32b6641746609ba8033d7380435f2824cd02b Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Tue, 5 Jun 2018 23:52:12 +0200 Subject: [PATCH 40/73] - added Codacy --- .travis.yml | 1 + composer.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4742451e..e7c1236b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ script: - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) -Z ; fi after_script: +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage clover build/logs/clover.xml ; fi - if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code $TRAVIS_TEST_RESULT ; fi diff --git a/composer.json b/composer.json index fd54a037..6e4b8529 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "mockery/mockery": "1.*", "symfony/phpunit-bridge": "3.*", "friendsofphp/php-cs-fixer": "2.*", - "codeclimate/php-test-reporter": "0.*" + "codeclimate/php-test-reporter": "0.*", + "codacy/coverage": "1.*" }, "autoload": { "psr-4": { From b255622f3394ddcad1ebb256579cde2bc5d934a5 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Tue, 5 Jun 2018 23:52:51 +0200 Subject: [PATCH 41/73] - removed composer lock --- composer.lock | 3849 ------------------------------------------------- 1 file changed, 3849 deletions(-) delete mode 100644 composer.lock diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 2ef4b08a..00000000 --- a/composer.lock +++ /dev/null @@ -1,3849 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "content-hash": "278c3bac95d545c20fa609a40ba42248", - "packages": [ - { - "name": "doctrine/collections", - "version": "v1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", - "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "doctrine/coding-standard": "~0.1@dev", - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "array", - "collections", - "iterator" - ], - "time": "2017-01-03T10:49:41+00:00" - } - ], - "packages-dev": [ - { - "name": "behat/gherkin", - "version": "v4.4.5", - "source": { - "type": "git", - "url": "https://github.com/Behat/Gherkin.git", - "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c14cff4f955b17d20d088dec1bde61c0539ec74", - "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "~4.5|~5", - "symfony/phpunit-bridge": "~2.7|~3", - "symfony/yaml": "~2.3|~3" - }, - "suggest": { - "symfony/yaml": "If you want to parse features, represented in YAML files" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Gherkin": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Gherkin DSL parser for PHP 5.3", - "homepage": "http://behat.org/", - "keywords": [ - "BDD", - "Behat", - "Cucumber", - "DSL", - "gherkin", - "parser" - ], - "time": "2016-10-30T11:50:56+00:00" - }, - { - "name": "codeception/codeception", - "version": "2.3.7", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Codeception.git", - "reference": "151de88277878adc18784ef3eaddd87f4a2fdc14" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/151de88277878adc18784ef3eaddd87f4a2fdc14", - "reference": "151de88277878adc18784ef3eaddd87f4a2fdc14", - "shasum": "" - }, - "require": { - "behat/gherkin": "~4.4.0", - "ext-json": "*", - "ext-mbstring": "*", - "facebook/webdriver": ">=1.1.3 <2.0", - "guzzlehttp/guzzle": ">=4.1.4 <7.0", - "guzzlehttp/psr7": "~1.0", - "php": ">=5.4.0 <8.0", - "phpunit/php-code-coverage": ">=2.2.4 <6.0", - "phpunit/phpunit": ">=4.8.28 <5.0.0 || >=5.6.3 <7.0", - "phpunit/phpunit-mock-objects": ">2.3 <5.0", - "sebastian/comparator": ">1.1 <3.0", - "sebastian/diff": ">=1.4 <3.0", - "symfony/browser-kit": ">=2.7 <5.0", - "symfony/console": ">=2.7 <5.0", - "symfony/css-selector": ">=2.7 <5.0", - "symfony/dom-crawler": ">=2.7 <5.0", - "symfony/event-dispatcher": ">=2.7 <5.0", - "symfony/finder": ">=2.7 <5.0", - "symfony/yaml": ">=2.7 <5.0" - }, - "require-dev": { - "codeception/specify": "~0.3", - "facebook/graph-sdk": "~5.3", - "flow/jsonpath": "~0.2", - "league/factory-muffin": "^3.0", - "league/factory-muffin-faker": "^1.0", - "monolog/monolog": "~1.8", - "pda/pheanstalk": "~3.0", - "php-amqplib/php-amqplib": "~2.4", - "predis/predis": "^1.0", - "squizlabs/php_codesniffer": "~2.0", - "symfony/process": ">=2.7 <5.0", - "vlucas/phpdotenv": "^2.4.0" - }, - "suggest": { - "aws/aws-sdk-php": "For using AWS Auth in REST module and Queue module", - "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests", - "codeception/specify": "BDD-style code blocks", - "codeception/verify": "BDD-style assertions", - "flow/jsonpath": "For using JSONPath in REST module", - "league/factory-muffin": "For DataFactory module", - "league/factory-muffin-faker": "For Faker support in DataFactory module", - "phpseclib/phpseclib": "for SFTP option in FTP Module", - "stecman/symfony-console-completion": "For BASH autocompletion", - "symfony/phpunit-bridge": "For phpunit-bridge support" - }, - "bin": [ - "codecept" - ], - "type": "library", - "extra": { - "branch-alias": [] - }, - "autoload": { - "psr-4": { - "Codeception\\": "src\\Codeception", - "Codeception\\Extension\\": "ext" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" - } - ], - "description": "BDD-style testing framework", - "homepage": "http://codeception.com/", - "keywords": [ - "BDD", - "TDD", - "acceptance testing", - "functional testing", - "unit testing" - ], - "time": "2017-12-12T04:22:17+00:00" - }, - { - "name": "codeclimate/php-test-reporter", - "version": "v0.4.4", - "source": { - "type": "git", - "url": "https://github.com/codeclimate/php-test-reporter.git", - "reference": "eab9ac233f23a4c12a12755793750f22fc46dd3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/codeclimate/php-test-reporter/zipball/eab9ac233f23a4c12a12755793750f22fc46dd3e", - "reference": "eab9ac233f23a4c12a12755793750f22fc46dd3e", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "padraic/phar-updater": "^1.0", - "php": "^5.3 || ^7.0", - "psr/log": "^1.0", - "satooshi/php-coveralls": "^1.0", - "symfony/console": "^2.0 || ^3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.0.0", - "phpunit/phpunit": "^4.8.31" - }, - "bin": [ - "composer/bin/test-reporter" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.3.x-dev" - } - }, - "autoload": { - "psr-4": { - "CodeClimate\\PhpTestReporter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Code Climate", - "email": "hello@codeclimate.com", - "homepage": "https://codeclimate.com" - } - ], - "description": "PHP client for reporting test coverage to Code Climate", - "homepage": "https://github.com/codeclimate/php-test-reporter", - "keywords": [ - "codeclimate", - "coverage" - ], - "time": "2017-02-15T22:25:47+00:00" - }, - { - "name": "composer/semver", - "version": "1.4.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5", - "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "time": "2016-08-30T16:08:34+00:00" - }, - { - "name": "doctrine/annotations", - "version": "v1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "54cacc9b81758b14e3ce750f205a393d52339e97" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97", - "reference": "54cacc9b81758b14e3ce750f205a393d52339e97", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2017-02-24T16:22:25+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14T21:17:01+00:00" - }, - { - "name": "doctrine/lexer", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "lexer", - "parser" - ], - "time": "2014-09-09T13:34:57+00:00" - }, - { - "name": "facebook/webdriver", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/facebook/php-webdriver.git", - "reference": "86b5ca2f67173c9d34340845dd690149c886a605" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/86b5ca2f67173c9d34340845dd690149c886a605", - "reference": "86b5ca2f67173c9d34340845dd690149c886a605", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-zip": "*", - "php": "^5.6 || ~7.0", - "symfony/process": "^2.8 || ^3.1 || ^4.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.0", - "guzzle/guzzle": "^3.4.1", - "php-coveralls/php-coveralls": "^1.0.2", - "php-mock/php-mock-phpunit": "^1.1", - "phpunit/phpunit": "^5.7", - "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0", - "squizlabs/php_codesniffer": "^2.6", - "symfony/var-dumper": "^3.3 || ^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-community": "1.5-dev" - } - }, - "autoload": { - "psr-4": { - "Facebook\\WebDriver\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "A PHP client for Selenium WebDriver", - "homepage": "https://github.com/facebook/php-webdriver", - "keywords": [ - "facebook", - "php", - "selenium", - "webdriver" - ], - "time": "2017-11-15T11:08:09+00:00" - }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.10.0", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "513a3765b56dd029175f9f32995566657ee89dda" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/513a3765b56dd029175f9f32995566657ee89dda", - "reference": "513a3765b56dd029175f9f32995566657ee89dda", - "shasum": "" - }, - "require": { - "composer/semver": "^1.4", - "doctrine/annotations": "^1.2", - "ext-json": "*", - "ext-tokenizer": "*", - "gecko-packages/gecko-php-unit": "^2.0 || ^3.0", - "php": "^5.6 || >=7.0 <7.3", - "php-cs-fixer/diff": "^1.2", - "symfony/console": "^3.2 || ^4.0", - "symfony/event-dispatcher": "^3.0 || ^4.0", - "symfony/filesystem": "^3.0 || ^4.0", - "symfony/finder": "^3.0 || ^4.0", - "symfony/options-resolver": "^3.0 || ^4.0", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0", - "symfony/stopwatch": "^3.0 || ^4.0" - }, - "conflict": { - "hhvm": "*" - }, - "require-dev": { - "johnkary/phpunit-speedtrap": "^1.1 || ^2.0@dev", - "justinrainbow/json-schema": "^5.0", - "keradus/cli-executor": "^1.0", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.0", - "php-cs-fixer/accessible-object": "^1.0", - "phpunit/phpunit": "^5.7.23 || ^6.4.3", - "phpunitgoodpractices/traits": "^1.0", - "symfony/phpunit-bridge": "^3.2.2 || ^4.0" - }, - "suggest": { - "ext-mbstring": "For handling non-UTF8 characters in cache signature.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "extra": { - "branch-alias": { - "dev-master": "2.10-dev" - } - }, - "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" - }, - "classmap": [ - "tests/Test/AbstractFixerTestCase.php", - "tests/Test/AbstractIntegrationTestCase.php", - "tests/Test/Assert/AssertTokensTrait.php", - "tests/Test/IntegrationCase.php", - "tests/Test/IntegrationCaseFactory.php", - "tests/TestCase.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "time": "2018-01-10T17:16:15+00:00" - }, - { - "name": "gecko-packages/gecko-php-unit", - "version": "v3.0", - "source": { - "type": "git", - "url": "https://github.com/GeckoPackages/GeckoPHPUnit.git", - "reference": "6a866551dffc2154c1b091bae3a7877d39c25ca3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GeckoPackages/GeckoPHPUnit/zipball/6a866551dffc2154c1b091bae3a7877d39c25ca3", - "reference": "6a866551dffc2154c1b091bae3a7877d39c25ca3", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-dom": "When testing with xml.", - "ext-libxml": "When testing with xml.", - "phpunit/phpunit": "This is an extension for it so make sure you have it some way." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "GeckoPackages\\PHPUnit\\": "src/PHPUnit" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Additional PHPUnit asserts and constraints.", - "homepage": "https://github.com/GeckoPackages", - "keywords": [ - "extension", - "filesystem", - "phpunit" - ], - "time": "2017-08-23T07:46:41+00:00" - }, - { - "name": "guzzle/guzzle", - "version": "v3.8.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/4de0618a01b34aa1c8c33a3f13f396dcd3882eba", - "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3.3", - "symfony/event-dispatcher": ">=2.1" - }, - "replace": { - "guzzle/batch": "self.version", - "guzzle/cache": "self.version", - "guzzle/common": "self.version", - "guzzle/http": "self.version", - "guzzle/inflection": "self.version", - "guzzle/iterator": "self.version", - "guzzle/log": "self.version", - "guzzle/parser": "self.version", - "guzzle/plugin": "self.version", - "guzzle/plugin-async": "self.version", - "guzzle/plugin-backoff": "self.version", - "guzzle/plugin-cache": "self.version", - "guzzle/plugin-cookie": "self.version", - "guzzle/plugin-curlauth": "self.version", - "guzzle/plugin-error-response": "self.version", - "guzzle/plugin-history": "self.version", - "guzzle/plugin-log": "self.version", - "guzzle/plugin-md5": "self.version", - "guzzle/plugin-mock": "self.version", - "guzzle/plugin-oauth": "self.version", - "guzzle/service": "self.version", - "guzzle/stream": "self.version" - }, - "require-dev": { - "doctrine/cache": "*", - "monolog/monolog": "1.*", - "phpunit/phpunit": "3.7.*", - "psr/log": "1.0.*", - "symfony/class-loader": "*", - "zendframework/zend-cache": "<2.3", - "zendframework/zend-log": "<2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.8-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle": "src/", - "Guzzle\\Tests": "tests/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Guzzle Community", - "homepage": "https://github.com/guzzle/guzzle/contributors" - } - ], - "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "abandoned": "guzzlehttp/guzzle", - "time": "2014-01-28T22:29:15+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "6.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", - "shasum": "" - }, - "require": { - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.5" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.0 || ^5.0", - "psr/log": "^1.0" - }, - "suggest": { - "psr/log": "Required for using the Log middleware" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.2-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2017-06-22T18:50:49+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "v1.3.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "shasum": "" - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "time": "2016-12-20T10:07:11+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.4.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "request", - "response", - "stream", - "uri", - "url" - ], - "time": "2017-03-20T17:10:46+00:00" - }, - { - "name": "hamcrest/hamcrest-php", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", - "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", - "shasum": "" - }, - "require": { - "php": "^5.3|^7.0" - }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" - }, - "require-dev": { - "phpunit/php-file-iterator": "1.3.3", - "phpunit/phpunit": "~4.0", - "satooshi/php-coveralls": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "hamcrest" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD" - ], - "description": "This is the PHP port of Hamcrest Matchers", - "keywords": [ - "test" - ], - "time": "2016-01-20T08:20:44+00:00" - }, - { - "name": "mockery/mockery", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/mockery/mockery.git", - "reference": "1bac8c362b12f522fdd1f1fa3556284c91affa38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/1bac8c362b12f522fdd1f1fa3556284c91affa38", - "reference": "1bac8c362b12f522fdd1f1fa3556284c91affa38", - "shasum": "" - }, - "require": { - "hamcrest/hamcrest-php": "~2.0", - "lib-pcre": ">=7.0", - "php": ">=5.6.0" - }, - "require-dev": { - "phpunit/phpunit": "~5.7|~6.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Mockery": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "http://davedevelopment.co.uk" - } - ], - "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", - "homepage": "http://github.com/mockery/mockery", - "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], - "time": "2017-10-06T16:20:43+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "time": "2017-10-19T19:58:43+00:00" - }, - { - "name": "padraic/humbug_get_contents", - "version": "1.0.4", - "source": { - "type": "git", - "url": "https://github.com/humbug/file_get_contents.git", - "reference": "66797199019d0cb4529cb8d29c6f0b4c5085b53a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/humbug/file_get_contents/zipball/66797199019d0cb4529cb8d29c6f0b4c5085b53a", - "reference": "66797199019d0cb4529cb8d29c6f0b4c5085b53a", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Humbug\\": "src/Humbug/" - }, - "files": [ - "src/function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" - } - ], - "description": "Secure wrapper for accessing HTTPS resources with file_get_contents for PHP 5.3+", - "homepage": "https://github.com/padraic/file_get_contents", - "keywords": [ - "download", - "file_get_contents", - "http", - "https", - "ssl", - "tls" - ], - "time": "2015-04-22T18:45:00+00:00" - }, - { - "name": "padraic/phar-updater", - "version": "1.0.4", - "source": { - "type": "git", - "url": "https://github.com/humbug/phar-updater.git", - "reference": "ac8802df2d1d03b7092b6f044a914f8d21592aae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/humbug/phar-updater/zipball/ac8802df2d1d03b7092b6f044a914f8d21592aae", - "reference": "ac8802df2d1d03b7092b6f044a914f8d21592aae", - "shasum": "" - }, - "require": { - "padraic/humbug_get_contents": "1.0.4", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Humbug\\SelfUpdate\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" - } - ], - "description": "A thing to make PHAR self-updating easy and secure.", - "keywords": [ - "humbug", - "phar", - "self-update", - "update" - ], - "time": "2017-07-12T22:42:45+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v2.0.11", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", - "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", - "shasum": "" - }, - "require": { - "php": ">=5.2.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "autoload": { - "files": [ - "lib/random.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "pseudorandom", - "random" - ], - "time": "2017-09-27T21:40:39+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, - { - "name": "php-cs-fixer/diff", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "f0ef6133d674137e902fdf8a6f2e8e97e14a087b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/f0ef6133d674137e902fdf8a6f2e8e97e14a087b", - "reference": "f0ef6133d674137e902fdf8a6f2e8e97e14a087b", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.4.3", - "symfony/process": "^3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "SpacePossum" - } - ], - "description": "sebastian/diff v2 backport support for PHP5.6", - "homepage": "https://github.com/PHP-CS-Fixer", - "keywords": [ - "diff" - ], - "time": "2017-10-19T09:58:18+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2017-09-11T18:02:19+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "66465776cfc249844bde6d117abff1d22e06c2da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66465776cfc249844bde6d117abff1d22e06c2da", - "reference": "66465776cfc249844bde6d117abff1d22e06c2da", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-27T17:38:31+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "time": "2017-07-14T14:27:02+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.7.3", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2017-11-24T13:59:53+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1", - "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-xdebug": "^2.5.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2017-12-06T09:29:45+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2017-11-27T05:48:46+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "6.4.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/562f7dc75d46510a4ed5d16189ae57fbe45a9932", - "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.2.2", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^4.0.3", - "sebastian/comparator": "^2.0.2", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2017-11-08T11:26:09+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.0" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2017-08-03T14:08:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2016-10-10T12:19:37+00:00" - }, - { - "name": "satooshi/php-coveralls", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-coveralls/php-coveralls.git", - "reference": "37f8f83fe22224eb9d9c6d593cdeb33eedd2a9ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/37f8f83fe22224eb9d9c6d593cdeb33eedd2a9ad", - "reference": "37f8f83fe22224eb9d9c6d593cdeb33eedd2a9ad", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-simplexml": "*", - "guzzle/guzzle": "^2.8 || ^3.0", - "php": "^5.3.3 || ^7.0", - "psr/log": "^1.0", - "symfony/config": "^2.1 || ^3.0 || ^4.0", - "symfony/console": "^2.1 || ^3.0 || ^4.0", - "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0", - "symfony/yaml": "^2.0 || ^3.0 || ^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0" - }, - "suggest": { - "symfony/http-kernel": "Allows Symfony integration" - }, - "bin": [ - "bin/coveralls" - ], - "type": "library", - "autoload": { - "psr-4": { - "Satooshi\\": "src/Satooshi/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kitamura Satoshi", - "email": "with.no.parachute@gmail.com", - "homepage": "https://www.facebook.com/satooshi.jp" - } - ], - "description": "PHP client library for Coveralls API", - "homepage": "https://github.com/php-coveralls/php-coveralls", - "keywords": [ - "ci", - "coverage", - "github", - "test" - ], - "time": "2017-12-06T23:17:56+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" - }, - { - "name": "sebastian/comparator", - "version": "2.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "11c07feade1d65453e06df3b3b90171d6d982087" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/11c07feade1d65453e06df3b3b90171d6d982087", - "reference": "11c07feade1d65453e06df3b3b90171d6d982087", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/diff": "^2.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2018-01-12T06:34:42+00:00" - }, - { - "name": "sebastian/diff", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2017-08-03T08:09:46+00:00" - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2017-07-01T08:51:00+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2017-04-03T13:19:02+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "symfony/browser-kit", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "490f27762705c8489bd042fe3e9377a191dba9b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/490f27762705c8489bd042fe3e9377a191dba9b4", - "reference": "490f27762705c8489bd042fe3e9377a191dba9b4", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/dom-crawler": "~2.8|~3.0|~4.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0|~4.0", - "symfony/process": "~2.8|~3.0|~4.0" - }, - "suggest": { - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\BrowserKit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony BrowserKit Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/config", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "cfd5c972f7b4992a5df41673d25d980ab077aa5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/cfd5c972f7b4992a5df41673d25d980ab077aa5b", - "reference": "cfd5c972f7b4992a5df41673d25d980ab077aa5b", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/filesystem": "~2.8|~3.0|~4.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.3", - "symfony/finder": "<3.3" - }, - "require-dev": { - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/finder": "~3.3|~4.0", - "symfony/yaml": "~3.0|~4.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/console", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "8394c8ef121949e8f858f13bc1e34f05169e4e7d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8394c8ef121949e8f858f13bc1e34f05169e4e7d", - "reference": "8394c8ef121949e8f858f13bc1e34f05169e4e7d", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/debug": "~2.8|~3.0|~4.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/process": "<3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.3|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~2.8|~3.0|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.3|~4.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/e66394bc7610e69279bfdb3ab11b4fe65403f556", - "reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/debug", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "603b95dda8b00020e4e6e60dc906e7b715b1c245" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/603b95dda8b00020e4e6e60dc906e7b715b1c245", - "reference": "603b95dda8b00020e4e6e60dc906e7b715b1c245", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" - }, - "require-dev": { - "symfony/http-kernel": "~2.8|~3.0|~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T17:14:19+00:00" - }, - { - "name": "symfony/dom-crawler", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/09bd97b844b3151fab82f2fdd62db9c464b3910a", - "reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0|~4.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DomCrawler Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26b87b6bca8f8f797331a30b76fdae5342dc26ca", - "reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "conflict": { - "symfony/dependency-injection": "<3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0|~4.0", - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/stopwatch": "~2.8|~3.0|~4.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", - "reference": "e078773ad6354af38169faf31c21df0f18ace03d", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/finder", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f", - "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/options-resolver", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "f31f4d3ce4eaf7597abc41bd5ba53d634c2fdb0e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/f31f4d3ce4eaf7597abc41bd5ba53d634c2fdb0e", - "reference": "f31f4d3ce4eaf7597abc41bd5ba53d634c2fdb0e", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony OptionsResolver Component", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/phpunit-bridge", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "24ffb71a115c25f5ee56cbfd38e56ed2cdbeb0a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/24ffb71a115c25f5ee56cbfd38e56ed2cdbeb0a9", - "reference": "24ffb71a115c25f5ee56cbfd38e56ed2cdbeb0a9", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" - }, - "suggest": { - "ext-zip": "Zip support is required when using bin/simple-phpunit", - "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" - }, - "bin": [ - "bin/simple-phpunit" - ], - "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - }, - "thanks": { - "name": "phpunit/phpunit", - "url": "https://github.com/sebastianbergmann/phpunit" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Bridge\\PhpUnit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony PHPUnit Bridge", - "homepage": "https://symfony.com", - "time": "2018-01-04T17:19:23+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", - "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2017-10-11T12:05:26+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff", - "reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2017-10-11T12:05:26+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "6de4f4884b97abbbed9f0a84a95ff2ff77254254" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/6de4f4884b97abbbed9f0a84a95ff2ff77254254", - "reference": "6de4f4884b97abbbed9f0a84a95ff2ff77254254", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2017-10-11T12:05:26+00:00" - }, - { - "name": "symfony/process", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", - "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Process Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/c865551df7c17e63fc1f09f763db04387f91ae4d", - "reference": "c865551df7c17e63fc1f09f763db04387f91ae4d", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Stopwatch Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "symfony/yaml", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "25c192f25721a74084272671f658797d9e0e0146" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/25c192f25721a74084272671f658797d9e0e0146", - "reference": "25c192f25721a74084272671f658797d9e0e0146", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "conflict": { - "symfony/console": "<3.4" - }, - "require-dev": { - "symfony/console": "~3.4|~4.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2016-11-23T20:04:58+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "^7" - }, - "platform-dev": [] -} From 0575bdaac78074e2841ff147d6a999cda26aba52 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Tue, 5 Jun 2018 23:54:42 +0200 Subject: [PATCH 42/73] - .gitignore : added composer.lock --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a5caa61e..bb0aeda7 100644 --- a/.gitignore +++ b/.gitignore @@ -77,4 +77,4 @@ fabric.properties /tests/_data/example.php coverage/* !coverage/.gitkeep - +composer.lock From c34c9b422962664aee4543ad61713ed11ade4e55 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Wed, 6 Jun 2018 00:13:25 +0200 Subject: [PATCH 43/73] - Codacy settings for travis --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7c1236b..ae2732af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,10 +40,10 @@ script: - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then echo zend_extension=xdebug.so >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini || return 0; fi - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then composer build-coverage; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) - -Z ; fi -after_script: +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) -Z ; fi - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage clover build/logs/clover.xml ; fi +- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage phpunit build/logs/report.xml ; fi +after_script: - if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code $TRAVIS_TEST_RESULT ; fi From 671b18b4c4b0f618e4836f5aa2e7891897633b35 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Wed, 6 Jun 2018 00:18:00 +0200 Subject: [PATCH 44/73] - Codacy settings for travis again --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ae2732af..02f3c3eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,6 @@ script: - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then composer build-coverage; fi - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) -Z ; fi - if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage clover build/logs/clover.xml ; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage phpunit build/logs/report.xml ; fi after_script: - if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code From 98a7c8e22bd2cea02aff9997f5080d4823b41b10 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Wed, 6 Jun 2018 00:23:51 +0200 Subject: [PATCH 45/73] - README.md update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 37afb3df..87c4ffc9 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ php api to control Ikea smart lights (tradfri) [![Code Climate](https://img.shields.io/codeclimate/issues//github/WebProject-xyz/ikea-tradfri-php.svg?style=flat-square)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/) [![Maintainability](https://api.codeclimate.com/v1/badges/c3a38c872794aa6a83c9/maintainability)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/c3a38c872794aa6a83c9/test_coverage)](https://codeclimate.com/github/WebProject-xyz/ikea-tradfri-php/test_coverage) +[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/4706838bc3c245669b351c0920b96b7a)](https://www.codacy.com/app/Fahl-Design/ikea-tradfri-php?utm_source=github.com&utm_medium=referral&utm_content=WebProject-xyz/ikea-tradfri-php&utm_campaign=Badge_Coverage) [![codecov](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php/branch/master/graph/badge.svg)](https://codecov.io/gh/WebProject-xyz/ikea-tradfri-php) [![StyleCI](https://styleci.io/repos/115823629/shield?branch=master)](https://styleci.io/repos/115823629) From 710574f7cc6e853583dae5aa127b2a4eaad34043 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 10 Jun 2018 03:39:16 +0200 Subject: [PATCH 46/73] - disabled ping check --- src/IKEA/Tradfri/Adapter/Coap.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index 948b1830..b05b3363 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -52,15 +52,16 @@ public function __construct( /** * Check online state. - * + * @deprecated no more ping from gateway * @param string $ipAddress * * @return bool */ public function checkOnline(string $ipAddress): bool { - $state = Online::isOnline($ipAddress); - $this->setOnline($state); + // disabled + $state = true; + $this->setOnline(true); return $state; } From 09d8cc9bf7601fbeeabe8645875ab3edf26a8f7c Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 10 Jun 2018 03:39:54 +0200 Subject: [PATCH 47/73] - more dynamic response validation - readme --- README.md | 10 +--------- src/IKEA/Tradfri/Adapter/Coap.php | 2 ++ src/IKEA/Tradfri/Command/Coaps.php | 14 +++++++++++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 87c4ffc9..6cbf43d4 100644 --- a/README.md +++ b/README.md @@ -28,18 +28,10 @@ php api to control Ikea smart lights (tradfri) see `wiki/example` folder - -##### ToDo - -- Single command classes -- Executor for commands -- Json data response -- PSR7 ? - ## Docker Coap-Client [WIP] work in progress `docker build . -t webproject/coap-client:latest` -# Run command [WIP] +### Run command in Docker [WIP] work in progress `docker run --rm --name coap-client2 webproject/coap-client` diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index b05b3363..9cb26442 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -52,7 +52,9 @@ public function __construct( /** * Check online state. + * * @deprecated no more ping from gateway + * * @param string $ipAddress * * @return bool diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 5e417a81..0e881182 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -175,11 +175,19 @@ public function setIp(string $ipAddress): self */ public function parseResult(array $result) { - if (\count($result) === 2 && !empty($result[0])) { - return (string) $result[0]; + // @todo: debug logging + $parsed = false; + if (\count($result) > 0) { + foreach ($result as $part) { + if (!empty($part) + && \strpos($part, 'decrypt') === false + && \strpos($part, 'v:1') === false) { + $parsed = (string) $part; + } + } } - return false; + return $parsed; } /** From 6e96119d7029260760ae27040a5d30d96746eda9 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 10 Jun 2018 03:42:12 +0200 Subject: [PATCH 48/73] - added command keys from @ggravlingen --- src/IKEA/Tradfri/Command/Keys.php | 144 ++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/IKEA/Tradfri/Command/Keys.php diff --git a/src/IKEA/Tradfri/Command/Keys.php b/src/IKEA/Tradfri/Command/Keys.php new file mode 100644 index 00000000..e3e46a08 --- /dev/null +++ b/src/IKEA/Tradfri/Command/Keys.php @@ -0,0 +1,144 @@ + 250, 'max' => 454]; + + // Hue of a RGB bulb + const RANGE_HUE = ['min' => 0, 'max' => 65535]; + // Effective saturation range of a RGB bulb. The bulb will accept + // slightly higher values, but it won't produce any light. + const RANGE_SATURATION = ['min' => 0, 'max' => 65279]; + // Brightness range of all bulbs. 0 will turn off the lamp + const RANGE_BRIGHTNESS = ['min' => 0, 'max' => 254]; + + // XY color + const RANGE_X = ['min' => 0, 'max' => 65535]; + const RANGE_Y = ['min' => 0, 'max' => 65535]; + + // Support info + const SUPPORT_BRIGHTNESS = 1; + const SUPPORT_COLOR_TEMP = 2; + const SUPPORT_HEX_COLOR = 4; + const SUPPORT_RGB_COLOR = 8; + const SUPPORT_XY_COLOR = 16; +} From 99e717c4817529df9059c5b08551cdaa5db2c408 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sun, 10 Jun 2018 04:07:43 +0200 Subject: [PATCH 49/73] - php cs (yoda style and phpdoc order) --- .php_cs | 11 ++ src/IKEA/Tradfri/Adapter/AdapterAbstract.php | 4 +- src/IKEA/Tradfri/Adapter/AdapterInterface.php | 2 +- src/IKEA/Tradfri/Adapter/Coap.php | 18 +- .../Tradfri/Collection/AbstractCollection.php | 6 +- src/IKEA/Tradfri/Collection/Devices.php | 8 +- src/IKEA/Tradfri/Collection/Lightbulbs.php | 2 +- src/IKEA/Tradfri/Command/Coaps.php | 14 +- src/IKEA/Tradfri/Command/CommandInterface.php | 17 ++ src/IKEA/Tradfri/Command/Get.php | 34 ++++ src/IKEA/Tradfri/Command/Keys.php | 1 + .../Tradfri/Command/Light/ChangeState.php | 25 +++ src/IKEA/Tradfri/Command/Post.php | 34 ++++ src/IKEA/Tradfri/Command/Put.php | 161 ++++++++++++++++++ src/IKEA/Tradfri/Device/Device.php | 4 +- src/IKEA/Tradfri/Device/Lightbulb.php | 4 +- src/IKEA/Tradfri/Group/Device.php | 2 +- src/IKEA/Tradfri/Group/Light.php | 2 +- src/IKEA/Tradfri/Helper/Online.php | 2 +- src/IKEA/Tradfri/Helper/Runner.php | 10 +- src/IKEA/Tradfri/Mapper/DeviceData.php | 10 +- src/IKEA/Tradfri/Mapper/GroupData.php | 4 +- src/IKEA/Tradfri/Mapper/MapperInterface.php | 4 +- src/IKEA/Tradfri/Service/Api.php | 2 +- src/IKEA/Tradfri/Validator/Group/Data.php | 2 +- tests/_support/Helper/Unit.php | 8 +- tests/_support/UnitTester.php | 5 +- .../IKEA/Tradfri/Device/LightbulbTest.php | 4 +- 28 files changed, 335 insertions(+), 65 deletions(-) create mode 100644 src/IKEA/Tradfri/Command/CommandInterface.php create mode 100644 src/IKEA/Tradfri/Command/Get.php create mode 100644 src/IKEA/Tradfri/Command/Light/ChangeState.php create mode 100644 src/IKEA/Tradfri/Command/Post.php create mode 100644 src/IKEA/Tradfri/Command/Put.php diff --git a/.php_cs b/.php_cs index a6f6d985..c94b13b0 100644 --- a/.php_cs +++ b/.php_cs @@ -62,6 +62,17 @@ return PhpCsFixer\Config::create() 'phpdoc_trim' => true, 'phpdoc_types' => true, 'phpdoc_var_without_name' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_order' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types_order' => true, + 'return_assignment' => true, + 'semicolon_after_instruction' => true, + 'single_line_comment_style' => true, + 'strict_comparison' => true, + 'strict_param' => true, + 'string_line_ending' => true, + 'yoda_style' => true, 'self_accessor' => true, 'simplified_null_return' => true, 'single_blank_line_at_eof' => true, diff --git a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php index 99300e6a..9f95e678 100644 --- a/src/IKEA/Tradfri/Adapter/AdapterAbstract.php +++ b/src/IKEA/Tradfri/Adapter/AdapterAbstract.php @@ -17,12 +17,12 @@ abstract class AdapterAbstract implements AdapterInterface { /** - * @var MapperInterface|DeviceData + * @var DeviceData|MapperInterface */ protected $_deviceDataMapper; /** - * @var MapperInterface|GroupData + * @var GroupData|MapperInterface */ protected $_groupDataMapper; diff --git a/src/IKEA/Tradfri/Adapter/AdapterInterface.php b/src/IKEA/Tradfri/Adapter/AdapterInterface.php index 1c499910..485c3e13 100644 --- a/src/IKEA/Tradfri/Adapter/AdapterInterface.php +++ b/src/IKEA/Tradfri/Adapter/AdapterInterface.php @@ -46,7 +46,7 @@ public function getGroupsData(): array; /** * Get devices as array. * - * @param array|null $deviceIds + * @param null|array $deviceIds * * @return array */ diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index 9cb26442..f872d86f 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -110,7 +110,7 @@ public function getType(int $deviceId): string * Get data from coaps client. * * @param string $requestType - * @param int|null $deviceId + * @param null|int $deviceId * * @throws \IKEA\Tradfri\Exception\RuntimeException * @@ -121,7 +121,7 @@ protected function _getData(string $requestType, int $deviceId = null) if ($this->isOnline()) { $command = $this->_commands->getCoapsCommandGet($requestType); - if ($deviceId !== null) { + if (null !== $deviceId) { $command .= '/'.$deviceId; } @@ -129,7 +129,7 @@ protected function _getData(string $requestType, int $deviceId = null) Runner::execWithTimeout($command, 1) ); - if ($dataRaw !== false) { + if (false !== $dataRaw) { $decoded = \json_decode($dataRaw); if (null === $decoded) { $decoded = $dataRaw; @@ -229,7 +229,7 @@ public function changeGroupState(int $groupId, bool $toState): bool $data = Runner::execWithTimeout($onCommand, 2); // verify result - if (\is_array($data) && \count($data) === 4) { + if (\is_array($data) && 4 === \count($data)) { return true; } @@ -256,7 +256,7 @@ public function setLightBrightness(int $lightId, int $level): bool $data = Runner::execWithTimeout($onCommand, 2); // verify result - if (\is_array($data) && \count($data) === 4) { + if (\is_array($data) && 4 === \count($data)) { return true; } @@ -282,7 +282,7 @@ public function setGroupBrightness(int $groupId, int $level): bool $data = Runner::execWithTimeout($onCommand, 2); // verify result - if (\is_array($data) && \count($data) === 4) { + if (\is_array($data) && 4 === \count($data)) { return true; } @@ -308,7 +308,7 @@ public function getDeviceCollection(ServiceInterface $service): Devices /** * Get devices. * - * @param array|null $deviceIds + * @param null|array $deviceIds * * @throws \IKEA\Tradfri\Exception\RuntimeException * @@ -316,7 +316,7 @@ public function getDeviceCollection(ServiceInterface $service): Devices */ public function getDevicesData(array $deviceIds = null): array { - if ($deviceIds === null) { + if (null === $deviceIds) { $deviceIds = $this->getDeviceIds(); } $deviceData = []; @@ -374,7 +374,7 @@ public function getGroupCollection(ServiceInterface $service): Groups ->getGroupDataMapper() ->map($service, $this->getGroupsData()); - if ($groups->isEmpty() === false) { + if (false === $groups->isEmpty()) { foreach ($groups->toArray() as $group) { /** @var Light $group */ $groupDevices = $this diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index 3b9c8605..ac588355 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -36,13 +36,13 @@ public function addDevice(Device $newItem) * @throws RuntimeException * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @return Device|null|void + * @return null|Device|void */ public function find($closure) { foreach ($this->toArray() as $item) { if (\is_callable($closure)) { - if ($closure($item) === true) { + if (true === $closure($item)) { return $item; } } else { @@ -65,7 +65,7 @@ public function jsonSerialize() { $data = []; foreach ($this->toArray() as $device) { - /* @var Device $device */ + // @var Device $device $data[$device->getId()] = $device->jsonSerialize(); } diff --git a/src/IKEA/Tradfri/Collection/Devices.php b/src/IKEA/Tradfri/Collection/Devices.php index f36e9e83..8e2bc715 100644 --- a/src/IKEA/Tradfri/Collection/Devices.php +++ b/src/IKEA/Tradfri/Collection/Devices.php @@ -17,7 +17,7 @@ class Devices extends AbstractCollection /** * Get lightbulbs. * - * @return Lightbulbs|Lightbulb[] + * @return Lightbulb[]|Lightbulbs */ public function getLightbulbs(): Lightbulbs { @@ -28,15 +28,13 @@ public function getLightbulbs(): Lightbulbs } } - $lightbulbs = $lightbulbs->sortByName(); - - return $lightbulbs; + return $lightbulbs->sortByName(); } /** * Get items. * - * @return Dimmer[]|MotionSensor[]|Lightbulb[]|Remote[]|array + * @return array|Dimmer[]|Lightbulb[]|MotionSensor[]|Remote[] */ public function getDevices(): array { diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index f26f2677..819aae47 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -15,7 +15,7 @@ class Lightbulbs extends Devices /** * Get first light. * - * @return Lightbulb|null + * @return null|Lightbulb */ public function first() { diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 0e881182..c2273a3a 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -101,15 +101,13 @@ public function getSharedKeyFromGateway(): string */ public function getPreSharedKeyCommand(): string { - $command = \sprintf( + return \sprintf( self::COAP_COMMAND_POST, 'Client_identity', $this->_secret ) .' -e \'{"9090":"'.$this->getUsername().'"}\'' .$this->_getRequestTypeCoapsUrl(CoapCommandKeys::KEY_GET_SHARED_KEY); - - return $command; } /** @@ -180,8 +178,8 @@ public function parseResult(array $result) if (\count($result) > 0) { foreach ($result as $part) { if (!empty($part) - && \strpos($part, 'decrypt') === false - && \strpos($part, 'v:1') === false) { + && false === \strpos($part, 'decrypt') + && false === \strpos($part, 'v:1')) { $parsed = (string) $part; } } @@ -193,7 +191,7 @@ public function parseResult(array $result) /** * Get CoapsCommand GET string. * - * @param string|int $requestType + * @param int|string $requestType * * @return string */ @@ -233,7 +231,7 @@ public function setApiKey(string $apiKey): self /** * Get CoapsCommand POST string. * - * @param string|int $requestType + * @param int|string $requestType * @param string $inject * * @return string @@ -271,7 +269,7 @@ public function getLightSwitchCommand(int $deviceId, bool $state): string /** * Get CoapsCommand PUT string. * - * @param string|int $requestType + * @param int|string $requestType * @param string $inject * * @return string diff --git a/src/IKEA/Tradfri/Command/CommandInterface.php b/src/IKEA/Tradfri/Command/CommandInterface.php new file mode 100644 index 00000000..53aa1f5f --- /dev/null +++ b/src/IKEA/Tradfri/Command/CommandInterface.php @@ -0,0 +1,17 @@ +_ipAddress = $ipAddress; + $this->_username = $username; + $this->_apiKey = $apiKey; + } + + /** + * Get command. + * + * @return string + */ + final public function getCommand(): string + { + return $this->_getUri() + .$this->_getInjectCommand() + .' "' + .$this->_getClientUri() + .'"'; + } + + /** + * Get command uri. + * + * @return string + */ + protected function _getUri(): string + { + return \sprintf( + self::COAP_COMMAND, $this->_getUsername(), $this->_getApiKey() + ); + } + + /** + * Get Username. + * + * @return string + */ + protected function _getUsername(): string + { + return $this->_username; + } + + /** + * Get ApiKey. + * + * @return string + */ + protected function _getApiKey(): string + { + return $this->_apiKey; + } + + /** + * Get InjectCommand. + * + * @return string + */ + protected function _getInjectCommand() + { + return $this->_injectCommand; + } + + /** + * Get coap client uri. + * + * @return string + */ + protected function _getClientUri(): string + { + return 'coaps://'.$this->_getIpAddress().':5684/' + .$this->_getRequestType(); + } + + /** + * Get IpAddress. + * + * @return string + */ + protected function _getIpAddress(): string + { + return $this->_ipAddress; + } + + /** + * Get Request type + * + * @return string + */ + protected function _getRequestType() + { + return $this->_requestType; + } + + /** + * Set RequestType. + * + * @param string $requestType + * + * @return Put + */ + public function setRequestType(string $requestType): self + { + $this->_requestType = $requestType; + + return $this; + } + + /** + * Build command from coap command. + * + * @return string + */ + abstract protected function _buildCommand(): string; +} diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index 412918ca..c23dd427 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -212,7 +212,7 @@ public function setType($type): self /** * Get Service. * - * @return ServiceInterface|Api + * @return Api|ServiceInterface */ public function getService(): ServiceInterface { @@ -275,7 +275,7 @@ public function jsonSerialize(): array $data = []; foreach (\get_class_methods(static::class) as $method) { - if ($method !== 'getService' && \strpos($method, 'get') === 0) { + if ('getService' !== $method && 0 === \strpos($method, 'get')) { $key = \strtolower((string) \substr($method, 3)); $data[$key] = $this->$method(); diff --git a/src/IKEA/Tradfri/Device/Lightbulb.php b/src/IKEA/Tradfri/Device/Lightbulb.php index 680c36fe..56f16b32 100644 --- a/src/IKEA/Tradfri/Device/Lightbulb.php +++ b/src/IKEA/Tradfri/Device/Lightbulb.php @@ -60,7 +60,7 @@ public function setBrightness(int $brightness): self */ public function switchOff(): bool { - if ($this->getService()->off($this) === true) { + if (true === $this->getService()->off($this)) { $this->setState(false); return true; @@ -78,7 +78,7 @@ public function switchOff(): bool */ public function switchOn(): bool { - if ($this->getService()->switchOn($this) === true) { + if (true === $this->getService()->switchOn($this)) { $this->setState(true); return true; diff --git a/src/IKEA/Tradfri/Group/Device.php b/src/IKEA/Tradfri/Group/Device.php index 190d06a7..a7569105 100644 --- a/src/IKEA/Tradfri/Group/Device.php +++ b/src/IKEA/Tradfri/Group/Device.php @@ -105,7 +105,7 @@ public function setDeviceIds(array $ids) */ public function getDevices(): Devices { - if ($this->_devices === null) { + if (null === $this->_devices) { $this->_devices = new Devices(); } diff --git a/src/IKEA/Tradfri/Group/Light.php b/src/IKEA/Tradfri/Group/Light.php index f8f2118b..239ede1f 100644 --- a/src/IKEA/Tradfri/Group/Light.php +++ b/src/IKEA/Tradfri/Group/Light.php @@ -18,7 +18,7 @@ class Light extends Device */ public function isOn(): bool { - if ($this->getLights()->isEmpty() === false) { + if (false === $this->getLights()->isEmpty()) { return $this->getLights()->getActive()->count() > 0; } diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 18a2e310..9bedc5ac 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -51,7 +51,7 @@ public static function isOnline(string $ipAddress): bool */ protected static function _validateMatches(array $matches): bool { - if (\strpos($matches[0][1], ' 0% packet loss') === false) { + if (false === \strpos($matches[0][1], ' 0% packet loss')) { throw new RuntimeException('packet loss detected'); } diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index 5e3d168b..3586d83e 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -28,7 +28,7 @@ class Runner public static function execWithTimeout( string $cmd, int $timeout, - $asArray = true, + bool $asArray = true, bool $skipEmptyBufferError = false ) { // File descriptors passed to the process. @@ -89,10 +89,10 @@ public static function execWithTimeout( if (!empty($errors) && empty($buffer)) { $parts = \explode("\n", $errors); - if (\count($parts) === 3) { + if (3 === \count($parts)) { $errorMessage = $parts[1]; } else { - if (\count($parts) === 2 && !empty($parts[1])) { + if (2 === \count($parts) && !empty($parts[1])) { $errorMessage = $parts[1]; } elseif (empty($parts[1])) { $errorMessage = $parts[0]; @@ -100,7 +100,7 @@ public static function execWithTimeout( $errorMessage = 'Unknown error'; } } - if ($skipEmptyBufferError === false) { + if (false === $skipEmptyBufferError) { throw new RuntimeException($errorMessage); } } @@ -118,7 +118,7 @@ public static function execWithTimeout( \proc_close($process); - if ($asArray === true) { + if (true === $asArray) { return \explode("\n", $buffer); } diff --git a/src/IKEA/Tradfri/Mapper/DeviceData.php b/src/IKEA/Tradfri/Mapper/DeviceData.php index 5b8369e8..5191e3f7 100644 --- a/src/IKEA/Tradfri/Mapper/DeviceData.php +++ b/src/IKEA/Tradfri/Mapper/DeviceData.php @@ -53,12 +53,12 @@ public function map( $model->setName($device->{CoapCommandKeys::KEY_NAME}); $model->setManufacturer( $device - ->{CoapCommandKeys::KEY_DATA} + ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO} ->{CoapCommandKeys::KEY_MANUFACTURER} ); $model->setVersion( $device - ->{CoapCommandKeys::KEY_DATA} + ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO} ->{CoapCommandKeys::KEY_VERSION} ); @@ -111,7 +111,7 @@ protected function _isValidData($device): bool * @throws TypeException * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @return Device|Lightbulb|Remote|MotionSensor + * @return Device|Lightbulb|MotionSensor|Remote */ protected function _getModel( int $deviceId, @@ -119,8 +119,8 @@ protected function _getModel( ServiceInterface $service ) { $type = $device - ->{CoapCommandKeys::KEY_DATA} - ->{CoapCommandKeys::KEY_TYPE}; + ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO} + ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO_TYPE}; switch ($type) { case Device::TYPE_BLUB_E27_W: diff --git a/src/IKEA/Tradfri/Mapper/GroupData.php b/src/IKEA/Tradfri/Mapper/GroupData.php index b6a4e1df..6cc3ed44 100644 --- a/src/IKEA/Tradfri/Mapper/GroupData.php +++ b/src/IKEA/Tradfri/Mapper/GroupData.php @@ -19,12 +19,12 @@ class GroupData extends Mapper /** * Map given data to models. * - * @param ServiceInterface|Api $service + * @param Api|ServiceInterface $service * @param array $groupDataItems * * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @return Groups|AbstractCollection + * @return AbstractCollection|Groups */ public function map(ServiceInterface $service, array $groupDataItems): AbstractCollection diff --git a/src/IKEA/Tradfri/Mapper/MapperInterface.php b/src/IKEA/Tradfri/Mapper/MapperInterface.php index 43af1bd6..dab5d310 100644 --- a/src/IKEA/Tradfri/Mapper/MapperInterface.php +++ b/src/IKEA/Tradfri/Mapper/MapperInterface.php @@ -17,10 +17,10 @@ interface MapperInterface /** * Map given data to models. * - * @param ServiceInterface|Api $service + * @param Api|ServiceInterface $service * @param array $dataItems * - * @return Devices|AbstractCollection + * @return AbstractCollection|Devices */ public function map( ServiceInterface $service, diff --git a/src/IKEA/Tradfri/Service/Api.php b/src/IKEA/Tradfri/Service/Api.php index 436aae51..bac03bc3 100644 --- a/src/IKEA/Tradfri/Service/Api.php +++ b/src/IKEA/Tradfri/Service/Api.php @@ -79,7 +79,7 @@ public function allLightsOff(Lightbulbs $lightbulbsCollection): bool $service = $this; $lightbulbsCollection->forAll( function ($lightbulbKey, $lightbulb) use ($service) { - /* @var Lightbulb $lightbulb */ + // @var Lightbulb $lightbulb if ($lightbulbKey === $lightbulb->getId()) { // this is ok but who cars can't make var unused } diff --git a/src/IKEA/Tradfri/Validator/Group/Data.php b/src/IKEA/Tradfri/Validator/Group/Data.php index 6bce7b4c..69f898d3 100644 --- a/src/IKEA/Tradfri/Validator/Group/Data.php +++ b/src/IKEA/Tradfri/Validator/Group/Data.php @@ -76,7 +76,7 @@ public function isValid($data): bool */ protected function _validateDeviceMustHaves($device): bool { - if (\is_object($device) === false) { + if (false === \is_object($device)) { throw new TypeException('device is no object'); } foreach (self::$_mustHaves as $mustHave) { diff --git a/tests/_support/Helper/Unit.php b/tests/_support/Helper/Unit.php index 5e17a268..e7995c29 100644 --- a/tests/_support/Helper/Unit.php +++ b/tests/_support/Helper/Unit.php @@ -19,7 +19,7 @@ class Unit extends \Codeception\Module */ public function getDevices(): array { - $devices = [ + return [ 'asd invalid', \json_decode(\json_encode([ CoapCommandKeys::KEY_TYPE => 'invalid type error', @@ -91,8 +91,6 @@ public function getDevices(): array ], ])), ]; - - return $devices; } /** @@ -100,7 +98,7 @@ public function getDevices(): array */ public function getGroupDataCoapsResponse(): array { - $groups = [ + return [ 1000 => \json_decode(\json_encode([ CoapCommandKeys::KEY_NAME => 'Group 1', CoapCommandKeys::KEY_TIME => 1498340208, @@ -179,7 +177,5 @@ public function getGroupDataCoapsResponse(): array ], ])), ]; - - return $groups; } } diff --git a/tests/_support/UnitTester.php b/tests/_support/UnitTester.php index a734bc21..2dc3d6d3 100644 --- a/tests/_support/UnitTester.php +++ b/tests/_support/UnitTester.php @@ -23,8 +23,5 @@ class UnitTester extends \Codeception\Actor { use _generated\UnitTesterActions; - /* - * Define custom actions here - * - */ + // Define custom actions here } diff --git a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php index 7142a399..5b826be6 100644 --- a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php +++ b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php @@ -29,9 +29,7 @@ public function testGetAnInstance() */ protected function _getModel(): Lightbulb { - $lamp = new Lightbulb($this->id, Device::TYPE_BLUB_E27_W); - - return $lamp; + return new Lightbulb($this->id, Device::TYPE_BLUB_E27_W); } public function testSetType() From 2c9f34c4ddd040fae4d6165300b33e6f31387965 Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Sun, 10 Jun 2018 02:07:58 +0000 Subject: [PATCH 50/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Command/CommandInterface.php | 1 + src/IKEA/Tradfri/Command/Get.php | 1 + src/IKEA/Tradfri/Command/Keys.php | 3 ++- src/IKEA/Tradfri/Command/Light/ChangeState.php | 3 ++- src/IKEA/Tradfri/Command/Post.php | 1 + src/IKEA/Tradfri/Command/Put.php | 3 ++- 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/IKEA/Tradfri/Command/CommandInterface.php b/src/IKEA/Tradfri/Command/CommandInterface.php index 53aa1f5f..5aace008 100644 --- a/src/IKEA/Tradfri/Command/CommandInterface.php +++ b/src/IKEA/Tradfri/Command/CommandInterface.php @@ -1,4 +1,5 @@ Date: Thu, 14 Jun 2018 23:46:50 +0200 Subject: [PATCH 51/73] - preparing commands and moving classes --- src/IKEA/Tradfri/Command/AbstractCommand.php | 168 ++++++++++++++++++ src/IKEA/Tradfri/Command/{ => Coap}/Keys.php | 2 +- .../Command/{ => Coap}/Light/ChangeState.php | 3 +- src/IKEA/Tradfri/Command/Get.php | 20 +-- src/IKEA/Tradfri/Command/Post.php | 20 +-- src/IKEA/Tradfri/Command/Put.php | 147 +-------------- src/IKEA/Tradfri/Mapper/DeviceData.php | 8 +- 7 files changed, 186 insertions(+), 182 deletions(-) create mode 100644 src/IKEA/Tradfri/Command/AbstractCommand.php rename src/IKEA/Tradfri/Command/{ => Coap}/Keys.php (99%) rename src/IKEA/Tradfri/Command/{ => Coap}/Light/ChangeState.php (81%) diff --git a/src/IKEA/Tradfri/Command/AbstractCommand.php b/src/IKEA/Tradfri/Command/AbstractCommand.php new file mode 100644 index 00000000..cf2a13f4 --- /dev/null +++ b/src/IKEA/Tradfri/Command/AbstractCommand.php @@ -0,0 +1,168 @@ +_ipAddress = $ipAddress; + $this->_username = $username; + $this->_apiKey = $apiKey; + } + + /** + * Get command. + * + * @return string + */ + final public function getCommand(): string + { + return $this->_getUri() + .$this->_getInjectCommand() + .' "' + .$this->_getClientUri() + .'"'; + } + + /** + * Get command uri. + * + * @return string + */ + protected function _getUri(): string + { + return \sprintf( + self::COAP_COMMAND, $this->_getUsername(), $this->_getApiKey() + ); + } + + /** + * Get Username. + * + * @return string + */ + protected function _getUsername(): string + { + return $this->_username; + } + + /** + * Get ApiKey. + * + * @return string + */ + protected function _getApiKey(): string + { + return $this->_apiKey; + } + + /** + * Get InjectCommand. + * + * @return string + */ + protected function _getInjectCommand() + { + return $this->_injectCommand; + } + + /** + * Get coap client uri. + * + * @return string + */ + protected function _getClientUri(): string + { + return 'coaps://'.$this->_getIpAddress().':5684/' + .$this->_getRequestType(); + } + + /** + * Get IpAddress. + * + * @return string + */ + protected function _getIpAddress(): string + { + return $this->_ipAddress; + } + + /** + * Get Request type. + * + * @return string + */ + protected function _getRequestType() + { + return $this->_requestType; + } + + /** + * Set RequestType. + * + * @param string $requestType + * + * @return Put + */ + public function setRequestType(string $requestType): self + { + $this->_requestType = $requestType; + + return $this; + } + + /** + * Build command from coap command. + * + * @return string + */ + abstract protected function _buildCommand(): string; + + /** + * @return string + */ + public function __toString(): string + { + return $this->_buildCommand(); + } +} diff --git a/src/IKEA/Tradfri/Command/Keys.php b/src/IKEA/Tradfri/Command/Coap/Keys.php similarity index 99% rename from src/IKEA/Tradfri/Command/Keys.php rename to src/IKEA/Tradfri/Command/Coap/Keys.php index 508b90fa..af02f94a 100644 --- a/src/IKEA/Tradfri/Command/Keys.php +++ b/src/IKEA/Tradfri/Command/Coap/Keys.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace IKEA\Tradfri\Command; +namespace IKEA\Tradfri\Command\Coap; /** * Class Keys. diff --git a/src/IKEA/Tradfri/Command/Light/ChangeState.php b/src/IKEA/Tradfri/Command/Coap/Light/ChangeState.php similarity index 81% rename from src/IKEA/Tradfri/Command/Light/ChangeState.php rename to src/IKEA/Tradfri/Command/Coap/Light/ChangeState.php index 30dc3f00..3982b512 100644 --- a/src/IKEA/Tradfri/Command/Light/ChangeState.php +++ b/src/IKEA/Tradfri/Command/Coap/Light/ChangeState.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace IKEA\Tradfri\Command\Light; +namespace IKEA\Tradfri\Command\Coap\Light; use IKEA\Tradfri\Command\Put; @@ -13,7 +13,6 @@ class ChangeState extends Put { /** * Build command from coap command - * // todo rethink this. * * @return string */ diff --git a/src/IKEA/Tradfri/Command/Get.php b/src/IKEA/Tradfri/Command/Get.php index 4861f0e5..10d62e45 100644 --- a/src/IKEA/Tradfri/Command/Get.php +++ b/src/IKEA/Tradfri/Command/Get.php @@ -7,29 +7,17 @@ /** * Class Get. */ -class Get implements CommandInterface +class Get extends AbstractCommand { const COAP_COMMAND = 'coap-client -m get -u "%s" -k "%s"'; /** - * Execute command. - * - * @return $this - */ - public function execute(): self - { - // @TODO: Implement execute() method. - return $this; - } - - /** - * Echo command. + * Build command from coap command. * * @return string */ - public function __toString(): string + protected function _buildCommand(): string { - // @TODO: Implement __toString() method. - return ''; + // @TODO: Implement _buildCommand() method. } } diff --git a/src/IKEA/Tradfri/Command/Post.php b/src/IKEA/Tradfri/Command/Post.php index b923ff3e..e85088fc 100644 --- a/src/IKEA/Tradfri/Command/Post.php +++ b/src/IKEA/Tradfri/Command/Post.php @@ -7,29 +7,17 @@ /** * Class Get. */ -class Post implements CommandInterface +class Post extends AbstractCommand { const COAP_COMMAND = 'coap-client -m post -u "%s" -k "%s"'; /** - * Execute command. - * - * @return bool - */ - public function execute(): bool - { - // @TODO: Implement execute() method. - // combine request and coap command and execute it with the client - } - - /** - * Echo command. + * Build command from coap command. * * @return string */ - public function __toString(): string + protected function _buildCommand(): string { - // @TODO: Implement __toString() method. - return ''; + // @TODO: Implement _buildCommand() method. } } diff --git a/src/IKEA/Tradfri/Command/Put.php b/src/IKEA/Tradfri/Command/Put.php index d69a7790..b09a3095 100644 --- a/src/IKEA/Tradfri/Command/Put.php +++ b/src/IKEA/Tradfri/Command/Put.php @@ -7,156 +7,17 @@ /** * Class Put. */ -abstract class Put +class Put extends AbstractCommand { const COAP_COMMAND = 'coap-client -m put -u "%s" -k "%s"'; - /** - * @var - */ - protected $_requestType; - - /** - * @var string - */ - protected $_injectCommand; - - /** - * @var string - */ - protected $_ipAddress; - - /** - * @var string - */ - protected $_username; - - /** - * @var string - */ - protected $_apiKey; - - /** - * Put constructor. - * - * @param string $ipAddress - * @param string $username - * @param string $apiKey - */ - public function __construct( - string $ipAddress, - string $username, - string $apiKey - ) { - $this->_ipAddress = $ipAddress; - $this->_username = $username; - $this->_apiKey = $apiKey; - } - - /** - * Get command. - * - * @return string - */ - final public function getCommand(): string - { - return $this->_getUri() - .$this->_getInjectCommand() - .' "' - .$this->_getClientUri() - .'"'; - } /** - * Get command uri. - * - * @return string - */ - protected function _getUri(): string - { - return \sprintf( - self::COAP_COMMAND, $this->_getUsername(), $this->_getApiKey() - ); - } - - /** - * Get Username. - * - * @return string - */ - protected function _getUsername(): string - { - return $this->_username; - } - - /** - * Get ApiKey. - * - * @return string - */ - protected function _getApiKey(): string - { - return $this->_apiKey; - } - - /** - * Get InjectCommand. - * - * @return string - */ - protected function _getInjectCommand() - { - return $this->_injectCommand; - } - - /** - * Get coap client uri. - * - * @return string - */ - protected function _getClientUri(): string - { - return 'coaps://'.$this->_getIpAddress().':5684/' - .$this->_getRequestType(); - } - - /** - * Get IpAddress. - * - * @return string - */ - protected function _getIpAddress(): string - { - return $this->_ipAddress; - } - - /** - * Get Request type. + * Build command from coap command. * * @return string */ - protected function _getRequestType() - { - return $this->_requestType; - } - - /** - * Set RequestType. - * - * @param string $requestType - * - * @return Put - */ - public function setRequestType(string $requestType): self + protected function _buildCommand(): string { - $this->_requestType = $requestType; - - return $this; + // @TODO: Implement _buildCommand() method. } - - /** - * Build command from coap command. - * - * @return string - */ - abstract protected function _buildCommand(): string; } diff --git a/src/IKEA/Tradfri/Mapper/DeviceData.php b/src/IKEA/Tradfri/Mapper/DeviceData.php index 5191e3f7..a9b4bec4 100644 --- a/src/IKEA/Tradfri/Mapper/DeviceData.php +++ b/src/IKEA/Tradfri/Mapper/DeviceData.php @@ -53,12 +53,12 @@ public function map( $model->setName($device->{CoapCommandKeys::KEY_NAME}); $model->setManufacturer( $device - ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO} + ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO} ->{CoapCommandKeys::KEY_MANUFACTURER} ); $model->setVersion( $device - ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO} + ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO} ->{CoapCommandKeys::KEY_VERSION} ); @@ -119,8 +119,8 @@ protected function _getModel( ServiceInterface $service ) { $type = $device - ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO} - ->{\IKEA\Tradfri\Command\Keys::ATTR_DEVICE_INFO_TYPE}; + ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO} + ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE}; switch ($type) { case Device::TYPE_BLUB_E27_W: From d4ef372275a860d1a9c98913e76184e4891f1b06 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Fri, 15 Jun 2018 00:16:22 +0200 Subject: [PATCH 52/73] - travis magic --- .travis.yml | 48 +++++++++++---------------- build/script/travis_after_success.sh | 8 +++++ build/script/travis_before_install.sh | 19 +++++++++++ build/script/travis_script.sh | 18 ++++++++++ codeception.yml | 3 +- 5 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 build/script/travis_after_success.sh create mode 100644 build/script/travis_before_install.sh create mode 100644 build/script/travis_script.sh diff --git a/.travis.yml b/.travis.yml index 02f3c3eb..226560af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,51 +1,41 @@ language: php +dist: trusty sudo: false + cache: directories: - - "$HOME/.composer/cache" - - "$HOME/.local" - - "$TRAVIS_BUILD_DIR/vendor" + - $TRAVIS_BUILD_DIR/vendor + - $HOME/.composer/cache + - $HOME/.php-cs-fixer + - $HOME/.local env: global: - CC_TEST_REPORTER_ID=ff208c24a9f196d9bfc66a49f6bf8592a07e82c6eed47ea481e299c4c648e393 - RUN_WITH_COVERAGE=false + matrix: fast_finish: true include: - php: 7.0 env: EXECUTE_CS_CHECK=true RUN_WITH_COVERAGE=true PATH="$HOME/.local/bin:$PATH" - - php: 7.0 - php: 7.1 - php: 7.2 + - php: 7.2 + - php: 7.3 - php: nightly - - php: hhvm - allow_failures: - - php: hhvm - - php: nightly + before_install: -- rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini -- travis_retry composer self-update -- git config --global user.name travis-ci -- git config --global user.email travis@webproject.xyz -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 - > ./cc-test-reporter; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then chmod +x ./cc-test-reporter; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then ./cc-test-reporter before-build; fi + - ./build/script/travis_before_install.sh + install: -- travis_retry composer update --no-interaction --prefer-source -- phpunit --version + - travis_retry composer update --no-interaction --prefer-source + script: -- if [[ $EXECUTE_CS_CHECK == 'true' ]]; then composer cs-check; fi -- if [[ $RUN_WITH_COVERAGE != 'true' ]]; then composer run-tests; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then echo zend_extension=xdebug.so >> ~/.phpenv/versions/$(phpenv - version-name)/etc/conf.d/xdebug.ini || return 0; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then composer build-coverage; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) -Z ; fi -- if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage clover build/logs/clover.xml ; fi -after_script: -- if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then - ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code - $TRAVIS_TEST_RESULT ; fi + - ./build/script/travis_script.sh + +after_success: + - ./build/script/travis_after_success.sh + notifications: email: false slack: diff --git a/build/script/travis_after_success.sh b/build/script/travis_after_success.sh new file mode 100644 index 00000000..3552f2b5 --- /dev/null +++ b/build/script/travis_after_success.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e +trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR + +## coverage reports +php vendor/bin/codacycoverage clover tests/_output/coverage.xml +if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code $TRAVIS_TEST_RESULT ; fi diff --git a/build/script/travis_before_install.sh b/build/script/travis_before_install.sh new file mode 100644 index 00000000..36103f9e --- /dev/null +++ b/build/script/travis_before_install.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e +trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR + +## backup and disable xdebug +cp ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini ~/.phpenv/versions/$(phpenv version-name)/xdebug.ini.bak +echo > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini +phpenv rehash + +# create directories for the tests +mkdir -p "$HOME/.php-cs-fixer" + +travis_retry composer self-update +git config --global user.name travis-ci +git config --global user.email travis@webproject.xyz +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter; fi +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then chmod +x ./cc-test-reporter; fi +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then ./cc-test-reporter before-build; fi diff --git a/build/script/travis_script.sh b/build/script/travis_script.sh new file mode 100644 index 00000000..c99ef3cf --- /dev/null +++ b/build/script/travis_script.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e +trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR + +# run static php-cs-fixer code analysis +./vendor/bin/php-cs-fixer fix --dry-run --diff --verbose + +## run the tests with no coverage +if [[ $RUN_WITH_COVERAGE != 'true' ]]; then composer run-tests; fi + +## run the tests with no coverage +## enable xdebug again +./vendor/bin/codecept build +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then mv ~/.phpenv/versions/$(phpenv version-name)/xdebug.ini.bak ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini; fi +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then composer build-coverage; fi +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then bash <(curl -s https://codecov.io/bash) -Z ; fi +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage clover build/logs/clover.xml ; fi diff --git a/codeception.yml b/codeception.yml index 1e26023a..9b85c504 100644 --- a/codeception.yml +++ b/codeception.yml @@ -18,7 +18,8 @@ namespace: IKEA\Tests extensions: enabled: - Codeception\Extension\RunFailed - #- Codeception\Extension\DotReporter + - Codeception\Extension\Logger: # enabled extension + max_files: 5 # logger configuration settings: # name of bootstrap that will be used From 4b3e8c4677461eb431a67d1cd031de225fac07ae Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Thu, 14 Jun 2018 22:16:40 +0000 Subject: [PATCH 53/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Command/AbstractCommand.php | 1 + src/IKEA/Tradfri/Command/Coap/Light/ChangeState.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/IKEA/Tradfri/Command/AbstractCommand.php b/src/IKEA/Tradfri/Command/AbstractCommand.php index cf2a13f4..0cff7032 100644 --- a/src/IKEA/Tradfri/Command/AbstractCommand.php +++ b/src/IKEA/Tradfri/Command/AbstractCommand.php @@ -1,4 +1,5 @@ Date: Fri, 15 Jun 2018 00:30:28 +0200 Subject: [PATCH 54/73] - chmod +x --- build/script/travis_after_success.sh | 1 - build/script/travis_before_install.sh | 1 - build/script/travis_script.sh | 1 - 3 files changed, 3 deletions(-) mode change 100644 => 100755 build/script/travis_after_success.sh mode change 100644 => 100755 build/script/travis_before_install.sh mode change 100644 => 100755 build/script/travis_script.sh diff --git a/build/script/travis_after_success.sh b/build/script/travis_after_success.sh old mode 100644 new mode 100755 index 3552f2b5..ff7fe10c --- a/build/script/travis_after_success.sh +++ b/build/script/travis_after_success.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash - set -e trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR diff --git a/build/script/travis_before_install.sh b/build/script/travis_before_install.sh old mode 100644 new mode 100755 index 36103f9e..2045678e --- a/build/script/travis_before_install.sh +++ b/build/script/travis_before_install.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash - set -e trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR diff --git a/build/script/travis_script.sh b/build/script/travis_script.sh old mode 100644 new mode 100755 index c99ef3cf..a15264ee --- a/build/script/travis_script.sh +++ b/build/script/travis_script.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash - set -e trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR From 115b4a2d90742b92ff6d0376af6a33a2db81d476 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Fri, 15 Jun 2018 00:34:27 +0200 Subject: [PATCH 55/73] - removed travis command from script --- build/script/travis_before_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/script/travis_before_install.sh b/build/script/travis_before_install.sh index 2045678e..627f10d4 100755 --- a/build/script/travis_before_install.sh +++ b/build/script/travis_before_install.sh @@ -10,7 +10,7 @@ phpenv rehash # create directories for the tests mkdir -p "$HOME/.php-cs-fixer" -travis_retry composer self-update +composer self-update --profile git config --global user.name travis-ci git config --global user.email travis@webproject.xyz if [[ $RUN_WITH_COVERAGE == 'true' ]]; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter; fi From e6d4fe3051c2f3fa9278b5382baabe893a464dbc Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Fri, 15 Jun 2018 01:04:02 +0200 Subject: [PATCH 56/73] - refactor command runner and style fixes - added monolog/monolog --- composer.json | 5 +- src/IKEA/Tradfri/Adapter/Coap.php | 14 +-- src/IKEA/Tradfri/Collection/Lightbulbs.php | 2 +- src/IKEA/Tradfri/Command/AbstractCommand.php | 6 +- src/IKEA/Tradfri/Command/Coaps.php | 27 ++-- src/IKEA/Tradfri/Helper/Online.php | 7 +- src/IKEA/Tradfri/Helper/Runner.php | 124 +++++++++++++------ wiki/example/init-dist.php | 2 +- 8 files changed, 114 insertions(+), 73 deletions(-) diff --git a/composer.json b/composer.json index 6e4b8529..5138b1f5 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "symfony/phpunit-bridge": "3.*", "friendsofphp/php-cs-fixer": "2.*", "codeclimate/php-test-reporter": "0.*", - "codacy/coverage": "1.*" + "codacy/coverage": "1.*", + "monolog/monolog": "1.*" }, "autoload": { "psr-4": { @@ -33,7 +34,7 @@ }, "scripts": { "run-tests": [ - "./vendor/bin/codecept run --steps --colors" + "./vendor/bin/codecept run --colors" ], "cs-check": [ "./vendor/bin/php-cs-fixer fix --dry-run -vv" diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index f872d86f..cde9c4ff 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -55,11 +55,11 @@ public function __construct( * * @deprecated no more ping from gateway * - * @param string $ipAddress + * @param string $gatewayAddress * * @return bool */ - public function checkOnline(string $ipAddress): bool + public function checkOnline(string $gatewayAddress): bool { // disabled $state = true; @@ -126,7 +126,7 @@ protected function _getData(string $requestType, int $deviceId = null) } $dataRaw = $this->_commands->parseResult( - Runner::execWithTimeout($command, 1) + (new Runner())->execWithTimeout($command, 1) ); if (false !== $dataRaw) { @@ -191,7 +191,7 @@ public function changeLightState(int $deviceId, bool $toState): bool ->getLightSwitchCommand($deviceId, $toState); // run command - $data = Runner::execWithTimeout( + $data = (new Runner())->execWithTimeout( $onCommand, 2, true, @@ -226,7 +226,7 @@ public function changeGroupState(int $groupId, bool $toState): bool ->getGroupSwitchCommand($groupId, $toState); // run command - $data = Runner::execWithTimeout($onCommand, 2); + $data = (new Runner())->execWithTimeout($onCommand, 2); // verify result if (\is_array($data) && 4 === \count($data)) { @@ -253,7 +253,7 @@ public function setLightBrightness(int $lightId, int $level): bool ->getLightDimmerCommand($lightId, $level); // run command - $data = Runner::execWithTimeout($onCommand, 2); + $data = (new Runner())->execWithTimeout($onCommand, 2); // verify result if (\is_array($data) && 4 === \count($data)) { @@ -279,7 +279,7 @@ public function setGroupBrightness(int $groupId, int $level): bool $onCommand = $this->_commands->getGroupDimmerCommand($groupId, $level); // run command - $data = Runner::execWithTimeout($onCommand, 2); + $data = (new Runner())->execWithTimeout($onCommand, 2); // verify result if (\is_array($data) && 4 === \count($data)) { diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index 819aae47..877733e4 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -80,7 +80,7 @@ public function sortByName() protected function namesAsKeys(): array { $elements = []; - $this->forAll(function ($key, Device $device) use (&$elements) { + $this->forAll(function ($deviceId, Device $device) use (&$elements) { $elements[$device->getName()] = $device; return true; diff --git a/src/IKEA/Tradfri/Command/AbstractCommand.php b/src/IKEA/Tradfri/Command/AbstractCommand.php index 0cff7032..c4f29494 100644 --- a/src/IKEA/Tradfri/Command/AbstractCommand.php +++ b/src/IKEA/Tradfri/Command/AbstractCommand.php @@ -37,16 +37,16 @@ abstract class AbstractCommand implements CommandInterface /** * Put constructor. * - * @param string $ipAddress + * @param string $gatewayAddress * @param string $username * @param string $apiKey */ public function __construct( - string $ipAddress, + string $gatewayAddress, string $username, string $apiKey ) { - $this->_ipAddress = $ipAddress; + $this->_ipAddress = $gatewayAddress; $this->_username = $username; $this->_apiKey = $apiKey; } diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index c2273a3a..37823c30 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -42,7 +42,7 @@ class Coaps /** * Coaps constructor. * - * @param string $ipAddress + * @param string $gatewayAddress * @param string $secret * @param string $apiKey * @param string $username @@ -51,24 +51,19 @@ class Coaps * @throws \IKEA\Tradfri\Exception\RuntimeException */ public function __construct( - string $ipAddress, + string $gatewayAddress, string $secret, string $apiKey, - $username = null + $username ) { - $this->setIp($ipAddress); + $this->setIp($gatewayAddress); $this->_secret = $secret; if (empty($apiKey)) { throw new RuntimeException('$apiKey can not be empty'); } $this->setApiKey($apiKey); - - if (null !== $username) { - $this->setUsername($username); - } else { - $this->setUsername('wrapper'); - } + $this->setUsername($username); } /** @@ -84,7 +79,9 @@ public function getSharedKeyFromGateway(): string $onCommand = $this->getPreSharedKeyCommand(); // run command - $result = $this->parseResult(Runner::execWithTimeout($onCommand, 2)); + $result = $this->parseResult( + (new Runner())->execWithTimeout($onCommand, 2) + ); // verify result if (isset($result->{CoapCommandKeys::KEY_SHARED_KEY})) { @@ -147,16 +144,16 @@ public function getIp(): string /** * Set and filter ip. * - * @param $ipAddress + * @param $gatewayAddress * * @throws \InvalidArgumentException * * @return $this */ - public function setIp(string $ipAddress): self + public function setIp(string $gatewayAddress): self { - if (\filter_var($ipAddress, FILTER_VALIDATE_IP)) { - $this->_ip = $ipAddress; + if (\filter_var($gatewayAddress, FILTER_VALIDATE_IP)) { + $this->_ip = $gatewayAddress; return $this; } diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 9bedc5ac..5a2c0b5d 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -14,17 +14,18 @@ class Online /** * Check online state. * - * @param string $ipAddress + * @param string $gatewayAddress * * @return bool */ - public static function isOnline(string $ipAddress): bool + public static function isOnline(string $gatewayAddress): bool { $online = true; $regex = '(\ [\d\.]+% packet loss)'; try { - $data = Runner::execWithTimeout('ping -c1 '.$ipAddress, 1, false); + $data = (new Runner()) + ->execWithTimeout('ping -c1 '.$gatewayAddress, 1, false); \preg_match_all($regex, $data, $matches, PREG_SET_ORDER); if (isset($matches[0][1])) { diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index 3586d83e..1800ea8b 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -25,11 +25,11 @@ class Runner * * @return array|string */ - public static function execWithTimeout( + public function execWithTimeout( string $cmd, int $timeout, - bool $asArray = true, - bool $skipEmptyBufferError = false + bool $asArray = null, + bool $skipEmptyBufferError = null ) { // File descriptors passed to the process. $descriptors = [ @@ -55,6 +55,86 @@ public static function execWithTimeout( $buffer = ''; // While we have time to wait. + $buffer = $this->_startProcess($timeout, $pipes, $process, $buffer); + + // Check if there were any errors. + $errors = \stream_get_contents($pipes[2]); + + if (!empty($errors) && empty($buffer)) { + $this->_parseErrors($skipEmptyBufferError, $errors); + } + + // Kill the process in case the timeout expired and it's still running. + // If the process already exited this won't do anything. + $this->_killProcess($process); + + // Close all streams. + \fclose($pipes[0]); + \fclose($pipes[1]); + \fclose($pipes[2]); + + \proc_close($process); + + if (true === $asArray) { + return \explode("\n", $buffer); + } + + return $buffer; + } + + /** + * Kill process. + * + * @param $process + */ + private function _killProcess($process) + { + if (\proc_terminate($process, 9)) { + throw new RuntimeException('timeout expired'); + } + } + + /** + * Parse errors. + * + * @param bool $skipEmptyBufferError + * @param $errors + */ + private function _parseErrors(bool $skipEmptyBufferError, $errors) + { + $parts = \explode("\n", $errors); + if (3 === \count($parts)) { + $errorMessage = $parts[1]; + } else { + if (2 === \count($parts) && !empty($parts[1])) { + $errorMessage = $parts[1]; + } elseif (empty($parts[1])) { + $errorMessage = $parts[0]; + } else { + $errorMessage = 'Unknown error'; + } + } + if (false === $skipEmptyBufferError) { + throw new RuntimeException($errorMessage); + } + } + + /** + * Start process. + * + * @param int $timeout + * @param array $pipes + * @param $process + * @param string $buffer + * + * @return string + */ + private function _startProcess( + int $timeout, + array $pipes, + $process, + string $buffer + ): string { while ($timeout > 0) { $start = \microtime(true); @@ -84,44 +164,6 @@ public static function execWithTimeout( $timeout -= (\microtime(true) - $start) * 1000000; } - // Check if there were any errors. - $errors = \stream_get_contents($pipes[2]); - - if (!empty($errors) && empty($buffer)) { - $parts = \explode("\n", $errors); - if (3 === \count($parts)) { - $errorMessage = $parts[1]; - } else { - if (2 === \count($parts) && !empty($parts[1])) { - $errorMessage = $parts[1]; - } elseif (empty($parts[1])) { - $errorMessage = $parts[0]; - } else { - $errorMessage = 'Unknown error'; - } - } - if (false === $skipEmptyBufferError) { - throw new RuntimeException($errorMessage); - } - } - - // Kill the process in case the timeout expired and it's still running. - // If the process already exited this won't do anything. - if (\proc_terminate($process, 9)) { - throw new RuntimeException('timeout expired'); - } - - // Close all streams. - \fclose($pipes[0]); - \fclose($pipes[1]); - \fclose($pipes[2]); - - \proc_close($process); - - if (true === $asArray) { - return \explode("\n", $buffer); - } - return $buffer; } } diff --git a/wiki/example/init-dist.php b/wiki/example/init-dist.php index 02f69755..72b9783e 100644 --- a/wiki/example/init-dist.php +++ b/wiki/example/init-dist.php @@ -24,7 +24,7 @@ $deviceMapper = new IKEA\Tradfri\Mapper\DeviceData(); $groupMapper = new IKEA\Tradfri\Mapper\GroupData(); -$commands = new Coaps(COAP_GATEWAY_IP, COAP_GATEWAY_SECRET, COAP_API_KEY); +$commands = new Coaps(COAP_GATEWAY_IP, COAP_GATEWAY_SECRET, COAP_API_KEY, 'php-api-user'); $adapter = new Adapter($commands, $deviceMapper, $groupMapper); $client = new \IKEA\Tradfri\Client\Client($adapter); $api = new \IKEA\Tradfri\Service\Api($client); From eb11f60e22dcd54ab3818245d8e60ba22201acf1 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Fri, 15 Jun 2018 01:12:43 +0200 Subject: [PATCH 57/73] - fixed coverage paths --- build/script/travis_after_success.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/script/travis_after_success.sh b/build/script/travis_after_success.sh index ff7fe10c..0a3dc6cd 100755 --- a/build/script/travis_after_success.sh +++ b/build/script/travis_after_success.sh @@ -3,5 +3,5 @@ set -e trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR ## coverage reports -php vendor/bin/codacycoverage clover tests/_output/coverage.xml +php vendor/bin/codacycoverage clover build/logs/clover.xml if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code $TRAVIS_TEST_RESULT ; fi From 8de6889f6c9be0ebdb8dde9de09710855d364334 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Fri, 15 Jun 2018 01:14:58 +0200 Subject: [PATCH 58/73] - optimized travis script --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 226560af..9ac6c230 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,9 @@ matrix: env: EXECUTE_CS_CHECK=true RUN_WITH_COVERAGE=true PATH="$HOME/.local/bin:$PATH" - php: 7.1 - php: 7.2 - - php: 7.2 + - php: 7.3 + - php: nightly + allow_failures: - php: 7.3 - php: nightly From 12fed8c913bb5da25c2e3d5cfb01ac7f33b02407 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 00:33:58 +0200 Subject: [PATCH 59/73] - added color as lightblub attribute - code style and refactoring --- .php_cs | 16 +- src/IKEA/Tradfri/Adapter/Coap.php | 166 ++++++++---------- .../Tradfri/Collection/AbstractCollection.php | 25 +-- src/IKEA/Tradfri/Collection/Lightbulbs.php | 10 +- src/IKEA/Tradfri/Command/Coap/Keys.php | 51 ++++-- src/IKEA/Tradfri/Command/Coaps.php | 63 ++++--- src/IKEA/Tradfri/Device/Device.php | 32 ++-- src/IKEA/Tradfri/Device/Dimmer.php | 4 +- src/IKEA/Tradfri/Device/Lightbulb.php | 29 +++ src/IKEA/Tradfri/Device/MotionSensor.php | 7 +- src/IKEA/Tradfri/Device/Remote.php | 7 +- src/IKEA/Tradfri/Helper/CoapCommandKeys.php | 3 + src/IKEA/Tradfri/Helper/Runner.php | 69 ++++---- src/IKEA/Tradfri/Mapper/DeviceData.php | 113 ++++++++---- src/IKEA/Tradfri/Mapper/GroupData.php | 16 +- src/IKEA/Tradfri/Service/Api.php | 2 +- src/IKEA/Tradfri/Validator/Device/Data.php | 31 +++- src/IKEA/Tradfri/Validator/Group/Data.php | 24 +-- tests/_support/Helper/Unit.php | 24 +-- tests/unit/IKEA/Tradfri/Client/ClientTest.php | 7 +- tests/unit/IKEA/Tradfri/Device/DimmerTest.php | 2 +- .../IKEA/Tradfri/Device/LightbulbTest.php | 16 +- .../IKEA/Tradfri/Device/MotionSensorTest.php | 5 +- tests/unit/IKEA/Tradfri/Device/RemoteTest.php | 5 +- .../IKEA/Tradfri/Mapper/DeviceDataTest.php | 92 +++++----- tests/unit/IKEA/Tradfri/Service/ApiTest.php | 28 +-- wiki/example/example-list-devices.php | 1 + 27 files changed, 488 insertions(+), 360 deletions(-) diff --git a/.php_cs b/.php_cs index c94b13b0..21baa789 100644 --- a/.php_cs +++ b/.php_cs @@ -58,7 +58,7 @@ return PhpCsFixer\Config::create() 'phpdoc_no_package' => true, 'phpdoc_scalar' => true, 'phpdoc_separation' => true, - 'phpdoc_to_comment' => true, + 'phpdoc_to_comment' => false, 'phpdoc_trim' => true, 'phpdoc_types' => true, 'phpdoc_var_without_name' => true, @@ -74,7 +74,7 @@ return PhpCsFixer\Config::create() 'string_line_ending' => true, 'yoda_style' => true, 'self_accessor' => true, - 'simplified_null_return' => true, + 'simplified_null_return' => false, 'single_blank_line_at_eof' => true, 'single_import_per_statement' => true, 'single_line_after_imports' => true, @@ -82,6 +82,18 @@ return PhpCsFixer\Config::create() 'ternary_operator_spaces' => true, 'trim_array_spaces' => true, 'visibility_required' => true, + 'ordered_imports' => true, + 'php_unit_strict' => true, + 'php_unit_test_class_requires_covers' => false, + 'ternary_to_null_coalescing' => true, + 'multiline_comment_opening_closing' => false, + 'native_constant_invocation' => true, + 'native_function_casing' => true, + '@PHP71Migration' => false, + 'function_typehint_space' => true, + 'fully_qualified_strict_types' => true, + 'modernize_types_casting' => true, + 'return_type_declaration' => true, ] ) ->setFinder( diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index cde9c4ff..64d458fe 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -10,7 +10,6 @@ use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Group\Light; use IKEA\Tradfri\Helper\CoapCommandKeys; -use IKEA\Tradfri\Helper\Online; use IKEA\Tradfri\Helper\Runner; use IKEA\Tradfri\Mapper\MapperInterface; use IKEA\Tradfri\Service\ServiceInterface; @@ -21,16 +20,12 @@ class Coap extends AdapterAbstract { const COULD_NOT_SWITCH_STATE = 'Could not switch state'; + /** * @var Coaps */ protected $_commands; - /** - * @var bool - */ - protected $_isOnline = false; - /** * Coap constructor. * @@ -44,44 +39,9 @@ public function __construct( MapperInterface $groupDataMapper ) { $this->_commands = $commands; - - $this->checkOnline($commands->getIp()); - parent::__construct($deviceDataMapper, $groupDataMapper); } - /** - * Check online state. - * - * @deprecated no more ping from gateway - * - * @param string $gatewayAddress - * - * @return bool - */ - public function checkOnline(string $gatewayAddress): bool - { - // disabled - $state = true; - $this->setOnline(true); - - return $state; - } - - /** - * Set IsOnline. - * - * @param bool $isOnline - * - * @return Coap - */ - public function setOnline(bool $isOnline): self - { - $this->_isOnline = $isOnline; - - return $this; - } - /** * Get device type. * @@ -118,40 +78,25 @@ public function getType(int $deviceId): string */ protected function _getData(string $requestType, int $deviceId = null) { - if ($this->isOnline()) { - $command = $this->_commands->getCoapsCommandGet($requestType); - - if (null !== $deviceId) { - $command .= '/'.$deviceId; - } + $command = $this->_commands->getCoapsCommandGet($requestType); - $dataRaw = $this->_commands->parseResult( - (new Runner())->execWithTimeout($command, 1) - ); - - if (false !== $dataRaw) { - $decoded = \json_decode($dataRaw); - if (null === $decoded) { - $decoded = $dataRaw; - } + if (null !== $deviceId) { + $command .= '/'.$deviceId; + } - return $decoded; - } + $dataRaw = $this->_commands->parseResult( + (new Runner())->execWithTimeout( + $command, + 1, + true + ) + ); - throw new RuntimeException('invalid hub response'); + if (false !== $dataRaw) { + return $this->_decodeData($dataRaw); } - throw new RuntimeException('api is offline'); - } - - /** - * Get isOnline. - * - * @return bool - */ - public function isOnline(): bool - { - return $this->_isOnline; + throw new RuntimeException('invalid hub response'); } /** @@ -186,17 +131,15 @@ public function getManufacturer(int $deviceId): string */ public function changeLightState(int $deviceId, bool $toState): bool { - // get command to switch light - $onCommand = $this->_commands - ->getLightSwitchCommand($deviceId, $toState); - // run command - $data = (new Runner())->execWithTimeout( - $onCommand, - 2, - true, - true - ); + $data = (new Runner()) + ->execWithTimeout( + $this->_commands->getLightSwitchCommand($deviceId, $toState), + 2, + true, + true + ); + // verify result if (\is_array($data) && empty($data[0])) { /* @@ -221,15 +164,16 @@ public function changeLightState(int $deviceId, bool $toState): bool */ public function changeGroupState(int $groupId, bool $toState): bool { - // get command to switch light - $onCommand = $this->_commands - ->getGroupSwitchCommand($groupId, $toState); - // run command - $data = (new Runner())->execWithTimeout($onCommand, 2); + $data = (new Runner()) + ->execWithTimeout( + $this->_commands->getGroupSwitchCommand($groupId, $toState), + 2 + ); // verify result - if (\is_array($data) && 4 === \count($data)) { + + if ($this->_verifyResult($data)) { return true; } @@ -248,15 +192,14 @@ public function changeGroupState(int $groupId, bool $toState): bool */ public function setLightBrightness(int $lightId, int $level): bool { - // get command to dim light - $onCommand = $this->_commands - ->getLightDimmerCommand($lightId, $level); - // run command - $data = (new Runner())->execWithTimeout($onCommand, 2); + $data = (new Runner())->execWithTimeout( + $this->_commands->getLightDimmerCommand($lightId, $level), + 2 + ); // verify result - if (\is_array($data) && 4 === \count($data)) { + if ($this->_verifyResult($data)) { return true; } @@ -275,14 +218,14 @@ public function setLightBrightness(int $lightId, int $level): bool */ public function setGroupBrightness(int $groupId, int $level): bool { - // get command to switch light - $onCommand = $this->_commands->getGroupDimmerCommand($groupId, $level); - // run command - $data = (new Runner())->execWithTimeout($onCommand, 2); + $data = (new Runner())->execWithTimeout( + $this->_commands->getGroupDimmerCommand($groupId, $level), + 2 + ); // verify result - if (\is_array($data) && 4 === \count($data)) { + if ($this->_verifyResult($data)) { return true; } @@ -423,4 +366,33 @@ public function getGroupIds(): array { return $this->_getData(CoapCommandKeys::KEY_GET_GROUPS); } + + /** + * Decode gateway data. + * + * @param $dataRaw + * + * @return object|string + */ + protected function _decodeData(string $dataRaw) + { + $decoded = \json_decode($dataRaw); + if (null === $decoded) { + $decoded = $dataRaw; + } + + return $decoded; + } + + /** + * Verify result. + * + * @param $data + * + * @return bool + */ + protected function _verifyResult(array $data): bool + { + return \is_array($data) && 4 === \count($data); + } } diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index ac588355..da43946f 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -4,6 +4,7 @@ namespace IKEA\Tradfri\Collection; +use Closure; use Doctrine\Common\Collections\ArrayCollection; use IKEA\Tradfri\Device\Device; use IKEA\Tradfri\Exception\RuntimeException; @@ -12,7 +13,9 @@ /** * Class Devices. */ -abstract class AbstractCollection extends ArrayCollection implements JsonSerializable +abstract class AbstractCollection + extends ArrayCollection + implements JsonSerializable { /** * Add item to collection. @@ -21,7 +24,7 @@ abstract class AbstractCollection extends ArrayCollection implements JsonSeriali * * @return $this */ - public function addDevice(Device $newItem) + public function addDevice(Device $newItem): self { $this->set($newItem->getId(), $newItem); @@ -31,24 +34,22 @@ public function addDevice(Device $newItem) /** * Find item by closure. * - * @param $closure + * @param Closure $closure * * @throws RuntimeException * @throws \IKEA\Tradfri\Exception\RuntimeException * - * @return null|Device|void + * @return null|Device */ - public function find($closure) + public function find(Closure $closure) { foreach ($this->toArray() as $item) { - if (\is_callable($closure)) { - if (true === $closure($item)) { - return $item; - } - } else { - throw new RuntimeException('closure function not working'); + if (true === $closure($item)) { + return $item; } } + + return null; } /** @@ -65,7 +66,7 @@ public function jsonSerialize() { $data = []; foreach ($this->toArray() as $device) { - // @var Device $device + /** @var Device $device */ $data[$device->getId()] = $device->jsonSerialize(); } diff --git a/src/IKEA/Tradfri/Collection/Lightbulbs.php b/src/IKEA/Tradfri/Collection/Lightbulbs.php index 877733e4..33c1de29 100644 --- a/src/IKEA/Tradfri/Collection/Lightbulbs.php +++ b/src/IKEA/Tradfri/Collection/Lightbulbs.php @@ -80,11 +80,13 @@ public function sortByName() protected function namesAsKeys(): array { $elements = []; - $this->forAll(function ($deviceId, Device $device) use (&$elements) { - $elements[$device->getName()] = $device; + $this->forAll( + function ($deviceId, Device $device) use (&$elements) { + $elements[$device->getName().'_'.$deviceId] = $device; - return true; - }); + return true; + } + ); \ksort($elements, \SORT_NATURAL); return $elements; diff --git a/src/IKEA/Tradfri/Command/Coap/Keys.php b/src/IKEA/Tradfri/Command/Coap/Keys.php index af02f94a..b7b817f8 100644 --- a/src/IKEA/Tradfri/Command/Coap/Keys.php +++ b/src/IKEA/Tradfri/Command/Coap/Keys.php @@ -16,9 +16,11 @@ class Keys const ROOT_GATEWAY = '15011'; const ROOT_GROUPS = '15004'; const ROOT_MOODS = '15005'; - const ROOT_NOTIFICATION = '15006'; // speculative name + // speculative name + const ROOT_NOTIFICATION = '15006'; const ROOT_SMART_TASKS = '15010'; - const ROOT_START_ACTION = '15013'; // found under ATTR_START_ACTION + // found under ATTR_START_ACTION + const ROOT_START_ACTION = '15013'; const ROOT_SWITCH = '15009'; const ATTR_ALEXA_PAIR_STATUS = '9093'; @@ -34,8 +36,19 @@ class Keys const ATTR_CURRENT_TIME_UNIX = '9059'; const ATTR_CURRENT_TIME_ISO8601 = '9060'; + const ATTR_GROUP_INFO = '9018'; + const ATTR_GROUP_LIGHTS = '15002'; + const ATTR_DEVICE_INFO = '3'; + const ATTR_DEVICE_INFO_MANUFACTURER = '0'; const ATTR_DEVICE_INFO_TYPE = '1'; + const ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; + const ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; + const ATTR_DEVICE_INFO_TYPE_DIMMER = 'TRADFRI dimmer'; + const ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; + const ATTR_DEVICE_INFO_TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; + const ATTR_DEVICE_INFO_TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; + const ATTR_DEVICE_VERSION = '3'; const ATTR_GATEWAY_TIME_SOURCE = '9071'; const ATTR_GATEWAY_UPDATE_PROGRESS = '9055'; @@ -50,25 +63,32 @@ class Keys const ATTR_KEY_PAIR = '9097'; const ATTR_LAST_SEEN = '9020'; - const ATTR_LIGHT_CONTROL = '3311'; // array + // array + const ATTR_LIGHT_CONTROL = '3311'; const ATTR_MASTER_TOKEN_TAG = '9036'; const ATTR_NAME = '9001'; const ATTR_NTP = '9023'; const ATTR_FIRMWARE_VERSION = '9029'; - const ATTR_FIRST_SETUP = '9069'; // ??? unix epoch value when gateway first setup + // ??? unix epoch value when gateway first setup + const ATTR_FIRST_SETUP = '9069'; const ATTR_GATEWAY_INFO = '15012'; - const ATTR_GATEWAY_ID = '9081'; // ??? id of the gateway - const ATTR_GATEWAY_REBOOT = '9030'; // gw reboot - const ATTR_GATEWAY_FACTORY_DEFAULTS = '9031'; // gw to factory defaults + // ??? id of the gateway + const ATTR_GATEWAY_ID = '9081'; + // gw reboot + const ATTR_GATEWAY_REBOOT = '9030'; + // gw to factory defaults + const ATTR_GATEWAY_FACTORY_DEFAULTS = '9031'; const ATTR_GATEWAY_FACTORY_DEFAULTS_MIN_MAX_MSR = '5605'; const ATTR_GOOGLE_HOME_PAIR_STATUS = '9105'; - - const ATTR_LIGHT_STATE = '5850'; // 0 / 1 - const ATTR_LIGHT_DIMMER = '5851'; // Dimmer, not following spec: 0..255 - const ATTR_LIGHT_COLOR_HEX = '5706'; // string representing a value in hex + // 0 / 1 + const ATTR_LIGHT_STATE = '5850'; + // Dimmer, not following spec: 0..255 + const ATTR_LIGHT_DIMMER = '5851'; + // string representing a value in hex + const ATTR_LIGHT_COLOR_HEX = '5706'; const ATTR_LIGHT_COLOR_X = '5709'; const ATTR_LIGHT_COLOR_Y = '5710'; const ATTR_LIGHT_COLOR_HUE = '5707'; @@ -101,8 +121,10 @@ class Keys const ATTR_SENSOR_TYPE = '5751'; const ATTR_SENSOR_UNIT = '5701'; const ATTR_SENSOR_VALUE = '5700'; - const ATTR_START_ACTION = '9042'; // array - const ATTR_SMART_TASK_TYPE = '9040'; // 4 = transition | 1 = not home | 2 = on/off + // array + const ATTR_START_ACTION = '9042'; + // 4 = transition | 1 = not home | 2 = on/off + const ATTR_SMART_TASK_TYPE = '9040'; const ATTR_SMART_TASK_NOT_AT_HOME = 1; const ATTR_SMART_TASK_LIGHTS_OFF = 2; const ATTR_SMART_TASK_WAKE_UP = 4; @@ -120,7 +142,8 @@ class Keys const ATTR_USE_CURRENT_LIGHT_SETTINGS = '9070'; // URL to json-file containing links to all firmware updates - const URL_OTA_FW = 'https://fw.ota.homesmart.ikea.net/feed/version_info.json'; + const URL_OTA_FW + = 'https://fw.ota.homesmart.ikea.net/feed/version_info.json'; // Mireds range that white-spectrum bulbs can show const RANGE_MIREDS = ['min' => 250, 'max' => 454]; diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 37823c30..80fdce5e 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -4,6 +4,7 @@ namespace IKEA\Tradfri\Command; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Helper\Runner; @@ -15,9 +16,10 @@ */ class Coaps { - const COAP_COMMAND_GET = 'coap-client -m get -u "%s" -k "%s"'; + const PAYLOAD_START = ' -e \'{ "'; + const PAYLOAD_OPEN = '": [{ "'; + const COAP_COMMAND_PUT = 'coap-client -m put -u "%s" -k "%s"'; - const COAP_COMMAND_POST = 'coap-client -m post -u "%s" -k "%s"'; /** * @var string @@ -99,7 +101,7 @@ public function getSharedKeyFromGateway(): string public function getPreSharedKeyCommand(): string { return \sprintf( - self::COAP_COMMAND_POST, + Post::COAP_COMMAND, 'Client_identity', $this->_secret ) @@ -152,7 +154,7 @@ public function getIp(): string */ public function setIp(string $gatewayAddress): self { - if (\filter_var($gatewayAddress, FILTER_VALIDATE_IP)) { + if (\filter_var($gatewayAddress, \FILTER_VALIDATE_IP)) { $this->_ip = $gatewayAddress; return $this; @@ -170,15 +172,14 @@ public function setIp(string $gatewayAddress): self */ public function parseResult(array $result) { - // @todo: debug logging $parsed = false; - if (\count($result) > 0) { - foreach ($result as $part) { - if (!empty($part) - && false === \strpos($part, 'decrypt') - && false === \strpos($part, 'v:1')) { - $parsed = (string) $part; - } + foreach ($result as $part) { + if (!empty($part) + && false === \strpos($part, 'decrypt') + && false === \strpos($part, 'v:1')) { + $parsed = (string) $part; + + break; } } @@ -195,7 +196,7 @@ public function parseResult(array $result) public function getCoapsCommandGet($requestType): string { return \sprintf( - self::COAP_COMMAND_GET, + Get::COAP_COMMAND, $this->getUsername(), $this->getApiKey() ).$this->_getRequestTypeCoapsUrl($requestType); @@ -236,7 +237,7 @@ public function setApiKey(string $apiKey): self public function getCoapsCommandPost($requestType, string $inject): string { return \sprintf( - self::COAP_COMMAND_POST, + Post::COAP_COMMAND, $this->getUsername(), $this->getApiKey() ) @@ -254,11 +255,11 @@ public function getCoapsCommandPost($requestType, string $inject): string public function getLightSwitchCommand(int $deviceId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$deviceId, - ' -e \'{ "' - .CoapCommandKeys::KEY_DEVICE_DATA - .'": [{ "'. - CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' : '0') + Keys::ROOT_DEVICES.'/'.$deviceId, + self::PAYLOAD_START + .Keys::ATTR_LIGHT_CONTROL + .self::PAYLOAD_OPEN + .Keys::ATTR_LIGHT_STATE.'": '.($state ? '1' : '0') .' }] }\' ' ); } @@ -274,7 +275,7 @@ public function getLightSwitchCommand(int $deviceId, bool $state): string public function getCoapsCommandPut($requestType, string $inject): string { return \sprintf( - self::COAP_COMMAND_PUT, + Put::COAP_COMMAND, $this->getUsername(), $this->getApiKey() ) @@ -294,7 +295,7 @@ public function getGroupSwitchCommand(int $groupId, bool $state): string { return $this->getCoapsCommandPut( CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_ONOFF.'": '.($state ? '1' + self::PAYLOAD_START.Keys::ATTR_LIGHT_STATE.'": '.($state ? '1' : '0').' }\' ' ); } @@ -311,7 +312,7 @@ public function getGroupDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_DIMMER.'": '.(int) \round( + self::PAYLOAD_START.CoapCommandKeys::KEY_DIMMER.'": '.(int) \round( $value * 2.55 ).' }\' ' ); @@ -328,8 +329,10 @@ public function getGroupDimmerCommand(int $groupId, int $value): string public function getLightDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, - ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "' + Keys::ROOT_DEVICES.'/'.$groupId, + self::PAYLOAD_START + .CoapCommandKeys::KEY_DEVICE_DATA + .self::PAYLOAD_OPEN .CoapCommandKeys::KEY_DIMMER.'": '.(int) \round($value * 2.55) .' }] }\' ' ); @@ -347,9 +350,13 @@ public function getLightDimmerCommand(int $groupId, int $value): string */ public function getLightColorCommand(int $groupId, string $color): string { - $payload = ' -e \'{ "'.CoapCommandKeys::KEY_DEVICE_DATA.'": [{ "' - .CoapCommandKeys::KEY_COLOR.'": %s, "' - .CoapCommandKeys::KEY_COLOR_2.'": %s }] }\' '; + $payload = self::PAYLOAD_START + .CoapCommandKeys::KEY_DEVICE_DATA + .self::PAYLOAD_OPEN + .CoapCommandKeys::KEY_COLOR + .'": %s, "' + .CoapCommandKeys::KEY_COLOR_2 + .'": %s }] }\' '; switch ($color) { case 'warm': $payload = \sprintf($payload, '33135', '27211'); @@ -368,7 +375,7 @@ public function getLightColorCommand(int $groupId, string $color): string } return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_DATA.'/'.$groupId, + Keys::ROOT_DEVICES.'/'.$groupId, $payload ); } diff --git a/src/IKEA/Tradfri/Device/Device.php b/src/IKEA/Tradfri/Device/Device.php index c23dd427..15a6f8f7 100644 --- a/src/IKEA/Tradfri/Device/Device.php +++ b/src/IKEA/Tradfri/Device/Device.php @@ -4,6 +4,7 @@ namespace IKEA\Tradfri\Device; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Exception\TypeException; use IKEA\Tradfri\Service\Api; use IKEA\Tradfri\Service\ServiceInterface; @@ -14,21 +15,14 @@ */ abstract class Device implements JsonSerializable { - const TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; - const TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; - const TYPE_DIMMER = 'TRADFRI dimmer'; - const TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; - const TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; - const TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; - /** * @var array */ protected static $_lightblubTypes = [ - self::TYPE_BLUB_GU10, - self::TYPE_BLUB_E27_W, - self::TYPE_BLUB_E27_WS, + Keys::ATTR_DEVICE_INFO_TYPE_BLUB_GU10, + Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, + Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, ]; /** @@ -200,7 +194,7 @@ public function getType(): string * * @return Device */ - public function setType($type): self + public function setType(string $type): self { if ($this->isValidType($type)) { $this->_type = $type; @@ -236,21 +230,21 @@ public function setService(ServiceInterface $service): self /** * Validate Type. * - * @param $type + * @param string $type * * @throws \IKEA\Tradfri\Exception\TypeException * * @return bool */ - public function isValidType($type): bool + public function isValidType(string $type): bool { switch ($type) { - case self::TYPE_BLUB_E27_W: - case self::TYPE_BLUB_E27_WS: - case self::TYPE_BLUB_GU10: - case self::TYPE_MOTION_SENSOR: - case self::TYPE_REMOTE_CONTROL: - case self::TYPE_DIMMER: + case Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W: + case Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS: + case Keys::ATTR_DEVICE_INFO_TYPE_BLUB_GU10: + case Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR: + case Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL: + case Keys::ATTR_DEVICE_INFO_TYPE_DIMMER: // todo add more types break; default: diff --git a/src/IKEA/Tradfri/Device/Dimmer.php b/src/IKEA/Tradfri/Device/Dimmer.php index 9fbbc22f..de37d3d6 100644 --- a/src/IKEA/Tradfri/Device/Dimmer.php +++ b/src/IKEA/Tradfri/Device/Dimmer.php @@ -4,6 +4,8 @@ namespace IKEA\Tradfri\Device; +use IKEA\Tradfri\Command\Coap\Keys; + /** * Class Dimmer. */ @@ -18,6 +20,6 @@ class Dimmer extends Device */ public function __construct($deviceId) { - parent::__construct($deviceId, self::TYPE_DIMMER); + parent::__construct($deviceId, Keys::ATTR_DEVICE_INFO_TYPE_DIMMER); } } diff --git a/src/IKEA/Tradfri/Device/Lightbulb.php b/src/IKEA/Tradfri/Device/Lightbulb.php index 56f16b32..02a7fdaa 100644 --- a/src/IKEA/Tradfri/Device/Lightbulb.php +++ b/src/IKEA/Tradfri/Device/Lightbulb.php @@ -16,6 +16,11 @@ class Lightbulb extends Device */ protected $_brightness; + /** + * @var string + */ + protected $_color = ''; + /** * @var bool */ @@ -132,4 +137,28 @@ public function dim(int $level) { $this->getService()->dim($this, $level); } + + /** + * Get Color + * + * @return string + */ + public function getColor(): string + { + return \strtoupper($this->_color); + } + + /** + * Set Color + * + * @param string $color + * + * @return Lightbulb + */ + public function setColor(string $color): self + { + $this->_color = $color; + + return $this; + } } diff --git a/src/IKEA/Tradfri/Device/MotionSensor.php b/src/IKEA/Tradfri/Device/MotionSensor.php index e14e190c..fae94d20 100644 --- a/src/IKEA/Tradfri/Device/MotionSensor.php +++ b/src/IKEA/Tradfri/Device/MotionSensor.php @@ -4,6 +4,8 @@ namespace IKEA\Tradfri\Device; +use IKEA\Tradfri\Command\Coap\Keys; + /** * Class MotionSensor. */ @@ -18,6 +20,9 @@ class MotionSensor extends Device */ public function __construct($deviceId) { - parent::__construct($deviceId, self::TYPE_MOTION_SENSOR); + parent::__construct( + $deviceId, + Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR + ); } } diff --git a/src/IKEA/Tradfri/Device/Remote.php b/src/IKEA/Tradfri/Device/Remote.php index 8083212d..dd2dc5b9 100644 --- a/src/IKEA/Tradfri/Device/Remote.php +++ b/src/IKEA/Tradfri/Device/Remote.php @@ -4,6 +4,8 @@ namespace IKEA\Tradfri\Device; +use IKEA\Tradfri\Command\Coap\Keys; + /** * Class Remote. */ @@ -18,6 +20,9 @@ class Remote extends Device */ public function __construct($deviceId) { - parent::__construct($deviceId, self::TYPE_REMOTE_CONTROL); + parent::__construct( + $deviceId, + Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL + ); } } diff --git a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php index 27c00d50..a5236b8b 100644 --- a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php +++ b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php @@ -6,6 +6,9 @@ /** * Class Keys. + * + * @deprecated use \IKEA\Tradfri\Command\Coap\Keys + * @see \IKEA\Tradfri\Command\Coap\Keys */ class CoapCommandKeys { diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index 1800ea8b..bd5d19ad 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -11,6 +11,15 @@ */ class Runner { + /** + * File descriptors passed to the process. + */ + const DESCRIPTORS + = [ + 0 => ['pipe', 'r'], // stdin + 1 => ['pipe', 'w'], // stdout + 2 => ['pipe', 'w'], // stderr + ]; /** * Execute a command and return it's output. Either wait * until the command exits or the timeout has expired. @@ -31,15 +40,8 @@ public function execWithTimeout( bool $asArray = null, bool $skipEmptyBufferError = null ) { - // File descriptors passed to the process. - $descriptors = [ - 0 => ['pipe', 'r'], // stdin - 1 => ['pipe', 'w'], // stdout - 2 => ['pipe', 'w'], // stderr - ]; - // Start the process. - $process = \proc_open('exec '.$cmd, $descriptors, $pipes); + $process = \proc_open('exec '.$cmd, self::DESCRIPTORS, $pipes); if (!\is_resource($process)) { throw new RuntimeException('Could not execute process'); @@ -48,14 +50,8 @@ public function execWithTimeout( // Set the stdout stream to none-blocking. \stream_set_blocking($pipes[1], false); - // Turn the timeout into microseconds. - $timeout *= 1000000; - // Output buffer. - $buffer = ''; - - // While we have time to wait. - $buffer = $this->_startProcess($timeout, $pipes, $process, $buffer); + $buffer = $this->_startProcess($timeout, $pipes, $process, ''); // Check if there were any errors. $errors = \stream_get_contents($pipes[2]); @@ -69,11 +65,7 @@ public function execWithTimeout( $this->_killProcess($process); // Close all streams. - \fclose($pipes[0]); - \fclose($pipes[1]); - \fclose($pipes[2]); - - \proc_close($process); + $this->_closeStreams($pipes, $process); if (true === $asArray) { return \explode("\n", $buffer); @@ -97,22 +89,20 @@ private function _killProcess($process) /** * Parse errors. * - * @param bool $skipEmptyBufferError - * @param $errors + * @param bool $skipEmptyBufferError + * @param string $errors */ - private function _parseErrors(bool $skipEmptyBufferError, $errors) + private function _parseErrors(bool $skipEmptyBufferError, string $errors) { $parts = \explode("\n", $errors); - if (3 === \count($parts)) { - $errorMessage = $parts[1]; - } else { - if (2 === \count($parts) && !empty($parts[1])) { + switch (\count($parts)) { + case 2 && !empty($parts[1]): + case 3: $errorMessage = $parts[1]; - } elseif (empty($parts[1])) { - $errorMessage = $parts[0]; - } else { + + break; + default: $errorMessage = 'Unknown error'; - } } if (false === $skipEmptyBufferError) { throw new RuntimeException($errorMessage); @@ -135,6 +125,8 @@ private function _startProcess( $process, string $buffer ): string { + // Turn the timeout into microseconds. + $timeout *= 1000000; while ($timeout > 0) { $start = \microtime(true); @@ -166,4 +158,19 @@ private function _startProcess( return $buffer; } + + /** + * Close all streams + * + * @param array $pipes + * @param $process + */ + protected function _closeStreams(array $pipes, $process) + { + \fclose($pipes[0]); + \fclose($pipes[1]); + \fclose($pipes[2]); + + \proc_close($process); + } } diff --git a/src/IKEA/Tradfri/Mapper/DeviceData.php b/src/IKEA/Tradfri/Mapper/DeviceData.php index a9b4bec4..b6188a51 100644 --- a/src/IKEA/Tradfri/Mapper/DeviceData.php +++ b/src/IKEA/Tradfri/Mapper/DeviceData.php @@ -6,6 +6,7 @@ use IKEA\Tradfri\Collection\AbstractCollection; use IKEA\Tradfri\Collection\Devices; +use IKEA\Tradfri\Command\Coap\Keys as AttributeKeys; use IKEA\Tradfri\Device\Device; use IKEA\Tradfri\Device\Dimmer; use IKEA\Tradfri\Device\Lightbulb; @@ -13,7 +14,6 @@ use IKEA\Tradfri\Device\Remote; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Exception\TypeException; -use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Service\ServiceInterface; /** @@ -41,38 +41,23 @@ public function map( if (false === $this->_isValidData($device)) { continue; } - $id = (int) $device->{CoapCommandKeys::KEY_ID}; try { - $model = $this->_getModel($id, $device, $service); + $model = $this->_getModel( + $this->_getDeviceId($device), + $device, + $service + ); } catch (TypeException $typeException) { + // unknown type // todo add logger continue; } - $model->setName($device->{CoapCommandKeys::KEY_NAME}); - $model->setManufacturer( - $device - ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO} - ->{CoapCommandKeys::KEY_MANUFACTURER} - ); - $model->setVersion( - $device - ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO} - ->{CoapCommandKeys::KEY_VERSION} - ); + $this->_setDeviceAttributes($model, $device); if ($model instanceof Lightbulb) { - $model->setBrightness( - $device - ->{CoapCommandKeys::KEY_DEVICE_DATA}[0] - ->{CoapCommandKeys::KEY_DIMMER} - ); - $model->setState( - (bool) $device - ->{CoapCommandKeys::KEY_DEVICE_DATA}[0] - ->{CoapCommandKeys::KEY_ONOFF} - ); + $this->_setLightBlubAttributes($model, $device); } $collection->set($model->getId(), $model); @@ -119,25 +104,25 @@ protected function _getModel( ServiceInterface $service ) { $type = $device - ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO} - ->{\IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE}; + ->{AttributeKeys::ATTR_DEVICE_INFO} + ->{AttributeKeys::ATTR_DEVICE_INFO_TYPE}; switch ($type) { - case Device::TYPE_BLUB_E27_W: - case Device::TYPE_BLUB_E27_WS: - case Device::TYPE_BLUB_GU10: + case AttributeKeys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W: + case AttributeKeys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS: + case AttributeKeys::ATTR_DEVICE_INFO_TYPE_BLUB_GU10: $model = new Lightbulb($deviceId, $type); break; - case Device::TYPE_MOTION_SENSOR: + case AttributeKeys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR: $model = new MotionSensor($deviceId); break; - case Device::TYPE_REMOTE_CONTROL: + case AttributeKeys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL: $model = new Remote($deviceId); break; - case Device::TYPE_DIMMER: + case AttributeKeys::ATTR_DEVICE_INFO_TYPE_DIMMER: $model = new Dimmer($deviceId); break; @@ -147,4 +132,68 @@ protected function _getModel( return $model->setType($type)->setService($service); } + + /** + * Get Device id. + * + * @param $device + * + * @return int + */ + protected function _getDeviceId($device): int + { + return (int) $device->{AttributeKeys::ATTR_ID}; + } + + /** + * Set Lightbulb attributes. + * + * @param $model + * @param $device + */ + protected function _setLightBlubAttributes( + Lightbulb $model, + \stdClass $device + ) { + $model->setBrightness( + $device + ->{AttributeKeys::ATTR_LIGHT_CONTROL}[0] + ->{AttributeKeys::ATTR_LIGHT_DIMMER} + ); + + $model->setColor( + $device + ->{AttributeKeys::ATTR_LIGHT_CONTROL}[0] + ->{AttributeKeys::ATTR_LIGHT_COLOR_HEX} ?? '' + ); + + $model->setState( + (bool) $device + ->{AttributeKeys::ATTR_LIGHT_CONTROL}[0] + ->{AttributeKeys::ATTR_LIGHT_STATE} + ); + } + + /** + * Set Device attributes. + * + * @param $model + * @param $device + */ + protected function _setDeviceAttributes(Device $model, \stdClass $device) + { + $model->setName($device->{AttributeKeys::ATTR_NAME}); + + $model->setManufacturer( + $device + ->{AttributeKeys::ATTR_DEVICE_INFO} + ->{AttributeKeys::ATTR_DEVICE_INFO_MANUFACTURER} + ); + + $model->setVersion( + $device + ->{AttributeKeys::ATTR_DEVICE_INFO} + ->{AttributeKeys::ATTR_DEVICE_VERSION} + ); + } } diff --git a/src/IKEA/Tradfri/Mapper/GroupData.php b/src/IKEA/Tradfri/Mapper/GroupData.php index 6cc3ed44..8491164e 100644 --- a/src/IKEA/Tradfri/Mapper/GroupData.php +++ b/src/IKEA/Tradfri/Mapper/GroupData.php @@ -6,8 +6,8 @@ use IKEA\Tradfri\Collection\AbstractCollection; use IKEA\Tradfri\Collection\Groups; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Group\Light; -use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Service\Api; use IKEA\Tradfri\Service\ServiceInterface; @@ -36,17 +36,17 @@ public function map(ServiceInterface $service, } $group = new Light( - (int) $device->{CoapCommandKeys::KEY_ID}, $service + (int) $device->{Keys::ATTR_ID}, $service ); - $group->setName($device->{CoapCommandKeys::KEY_NAME}); + $group->setName($device->{Keys::ATTR_NAME}); $group->setDeviceIds( $device - ->{CoapCommandKeys::KEY_GROUPS_DATA} - ->{CoapCommandKeys::KEY_GET_LIGHTS} - ->{CoapCommandKeys::KEY_ID} + ->{Keys::ATTR_GROUP_INFO} + ->{Keys::ATTR_GROUP_LIGHTS} + ->{Keys::ATTR_ID} ); - $group->setBrightness($device->{CoapCommandKeys::KEY_DIMMER}); - $group->setState((bool) $device->{CoapCommandKeys::KEY_ONOFF}); + $group->setBrightness($device->{Keys::ATTR_LIGHT_DIMMER}); + $group->setState((bool) $device->{Keys::ATTR_LIGHT_STATE}); $collection->addGroup($group); } diff --git a/src/IKEA/Tradfri/Service/Api.php b/src/IKEA/Tradfri/Service/Api.php index bac03bc3..65beda2c 100644 --- a/src/IKEA/Tradfri/Service/Api.php +++ b/src/IKEA/Tradfri/Service/Api.php @@ -79,7 +79,7 @@ public function allLightsOff(Lightbulbs $lightbulbsCollection): bool $service = $this; $lightbulbsCollection->forAll( function ($lightbulbKey, $lightbulb) use ($service) { - // @var Lightbulb $lightbulb + /** @var Lightbulb $lightbulb */ if ($lightbulbKey === $lightbulb->getId()) { // this is ok but who cars can't make var unused } diff --git a/src/IKEA/Tradfri/Validator/Device/Data.php b/src/IKEA/Tradfri/Validator/Device/Data.php index b5b772b1..c0a9f37f 100644 --- a/src/IKEA/Tradfri/Validator/Device/Data.php +++ b/src/IKEA/Tradfri/Validator/Device/Data.php @@ -4,9 +4,9 @@ namespace IKEA\Tradfri\Validator\Device; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Exception\TypeException; -use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Validator\ValidatorInterface; /** @@ -36,7 +36,8 @@ public function isValid($device): bool $this->_hasDataField($device); - $data = $device->{CoapCommandKeys::KEY_DATA}; + $data = $this->_getData($device); + $this->_hasDataType($data); $this->_hasDataManufacturer($data); @@ -60,9 +61,9 @@ public function isValid($device): bool */ protected function _hasIdField(\stdClass $device): bool { - if (!\property_exists($device, CoapCommandKeys::KEY_ID)) { + if (!\property_exists($device, Keys::ATTR_ID)) { throw new RuntimeException( - 'attribute missing ('.CoapCommandKeys::KEY_ID + 'attribute missing ('.Keys::ATTR_ID.')' ); } @@ -78,9 +79,9 @@ protected function _hasIdField(\stdClass $device): bool */ protected function _hasDataField(\stdClass $device): bool { - if (!\property_exists($device, CoapCommandKeys::KEY_DATA)) { + if (!\property_exists($device, Keys::ATTR_DEVICE_INFO)) { throw new RuntimeException( - 'attribute missing ('.CoapCommandKeys::KEY_DATA + 'attribute missing ('.Keys::ATTR_DEVICE_INFO.')' ); } @@ -96,7 +97,7 @@ protected function _hasDataField(\stdClass $device): bool */ protected function _hasDataType(\stdClass $data): bool { - if (false === \property_exists($data, CoapCommandKeys::KEY_TYPE)) { + if (false === \property_exists($data, Keys::ATTR_DEVICE_INFO_TYPE)) { throw new RuntimeException('attribute missing type key'); } @@ -112,7 +113,7 @@ protected function _hasDataType(\stdClass $data): bool */ protected function _hasDataManufacturer(\stdClass $data): bool { - if (!\property_exists($data, CoapCommandKeys::KEY_MANUFACTURER)) { + if (!\property_exists($data, Keys::ATTR_DEVICE_INFO_MANUFACTURER)) { throw new RuntimeException( 'attribute missing type manufacturer' ); @@ -130,7 +131,7 @@ protected function _hasDataManufacturer(\stdClass $data): bool */ protected function _hasDataVersion(\stdClass $data): bool { - if (!\property_exists($data, CoapCommandKeys::KEY_VERSION)) { + if (!\property_exists($data, Keys::ATTR_DEVICE_VERSION)) { throw new RuntimeException( 'attribute missing type version' ); @@ -138,4 +139,16 @@ protected function _hasDataVersion(\stdClass $data): bool return true; } + + /** + * Get Data. + * + * @param $device + * + * @return mixed + */ + protected function _getData(\stdClass $device) + { + return $device->{Keys::ATTR_DEVICE_INFO}; + } } diff --git a/src/IKEA/Tradfri/Validator/Group/Data.php b/src/IKEA/Tradfri/Validator/Group/Data.php index 69f898d3..f036caac 100644 --- a/src/IKEA/Tradfri/Validator/Group/Data.php +++ b/src/IKEA/Tradfri/Validator/Group/Data.php @@ -4,9 +4,9 @@ namespace IKEA\Tradfri\Validator\Group; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Exception\TypeException; -use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Validator\ValidatorInterface; /** @@ -18,9 +18,9 @@ class Data implements ValidatorInterface * @var array */ protected static $_mustHaves = [ - CoapCommandKeys::KEY_ID, - CoapCommandKeys::KEY_NAME, - CoapCommandKeys::KEY_GROUPS_DATA, + Keys::ATTR_ID, + Keys::ATTR_NAME, + Keys::ATTR_GROUP_INFO, ]; /** @@ -39,23 +39,23 @@ public function isValid($data): bool $isValid = true; - $groupData = $data->{CoapCommandKeys::KEY_GROUPS_DATA}; + $groupData = $data->{Keys::ATTR_GROUP_INFO}; if (!\property_exists( $groupData, - CoapCommandKeys::KEY_GET_LIGHTS + Keys::ATTR_GROUP_LIGHTS )) { throw new RuntimeException( - 'attribute missing ('.CoapCommandKeys::KEY_GET_LIGHTS.')' + 'attribute missing ('.Keys::ATTR_GROUP_LIGHTS.')' ); } - $lightData = $groupData->{CoapCommandKeys::KEY_GET_LIGHTS}; + $lightData = $groupData->{Keys::ATTR_GROUP_LIGHTS}; - if (!isset($lightData->{CoapCommandKeys::KEY_ID})) { + if (!isset($lightData->{Keys::ATTR_ID})) { throw new RuntimeException( 'attribute group data is not an array ('. - CoapCommandKeys::KEY_GROUPS_DATA. - '->'.CoapCommandKeys::KEY_GET_LIGHTS. - '->'.CoapCommandKeys::KEY_ID.')' + Keys::ATTR_GROUP_INFO. + '->'.Keys::ATTR_GROUP_LIGHTS. + '->'.Keys::ATTR_ID.')' ); } } catch (\Throwable $exception) { diff --git a/tests/_support/Helper/Unit.php b/tests/_support/Helper/Unit.php index e7995c29..71626fb5 100644 --- a/tests/_support/Helper/Unit.php +++ b/tests/_support/Helper/Unit.php @@ -35,11 +35,11 @@ public function getDevices(): array ])), \json_decode(\json_encode([ CoapCommandKeys::KEY_ID => 1000, - CoapCommandKeys::KEY_NAME => Device::TYPE_BLUB_E27_W, + CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, CoapCommandKeys::KEY_DATA => [ CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => Device::TYPE_BLUB_E27_W, + CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, ], CoapCommandKeys::KEY_DEVICE_DATA => [ 0 => [ @@ -50,11 +50,11 @@ public function getDevices(): array ])), \json_decode(\json_encode([ CoapCommandKeys::KEY_ID => 2000, - CoapCommandKeys::KEY_NAME => Device::TYPE_BLUB_E27_WS, + CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, CoapCommandKeys::KEY_DATA => [ CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => Device::TYPE_BLUB_E27_WS, + CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, ], CoapCommandKeys::KEY_DEVICE_DATA => [ 0 => [ @@ -65,29 +65,29 @@ public function getDevices(): array ])), \json_decode(\json_encode([ CoapCommandKeys::KEY_ID => 3000, - CoapCommandKeys::KEY_NAME => Device::TYPE_DIMMER, + CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, CoapCommandKeys::KEY_DATA => [ CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => Device::TYPE_DIMMER, + CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, ], ])), \json_decode(\json_encode([ CoapCommandKeys::KEY_ID => 4000, - CoapCommandKeys::KEY_NAME => Device::TYPE_REMOTE_CONTROL, + CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, CoapCommandKeys::KEY_DATA => [ CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => Device::TYPE_REMOTE_CONTROL, + CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, ], ])), \json_decode(\json_encode([ CoapCommandKeys::KEY_ID => 5000, - CoapCommandKeys::KEY_NAME => Device::TYPE_MOTION_SENSOR, + CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, CoapCommandKeys::KEY_DATA => [ CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => Device::TYPE_MOTION_SENSOR, + CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, ], ])), ]; @@ -156,11 +156,11 @@ public function getGroupDataCoapsResponse(): array ])), \json_decode(\json_encode([ CoapCommandKeys::KEY_ID => 5000, - CoapCommandKeys::KEY_NAME => Device::TYPE_MOTION_SENSOR, + CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, CoapCommandKeys::KEY_DATA => [ CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => Device::TYPE_MOTION_SENSOR, + CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, ], ])), 'asd invalid', diff --git a/tests/unit/IKEA/Tradfri/Client/ClientTest.php b/tests/unit/IKEA/Tradfri/Client/ClientTest.php index 9b577cf7..3b8344c7 100644 --- a/tests/unit/IKEA/Tradfri/Client/ClientTest.php +++ b/tests/unit/IKEA/Tradfri/Client/ClientTest.php @@ -7,6 +7,7 @@ use IKEA\Tradfri\Client\Client; use IKEA\Tradfri\Collection\Devices; use IKEA\Tradfri\Collection\Groups; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Device\Lightbulb; use IKEA\Tradfri\Group\Light; use IKEA\Tradfri\Service\ServiceInterface; @@ -65,7 +66,7 @@ public function testICanTurnLightOn() $adapter->shouldReceive('changeLightState')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W); // Act $result = $client->lightOn($light); // Assert @@ -79,7 +80,7 @@ public function testICanTurnLightOff() $adapter->shouldReceive('changeLightState')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W); // Act $result = $client->lightOff($light); // Assert @@ -121,7 +122,7 @@ public function testICanDimLight() $adapter->shouldReceive('setLightBrightness')->andReturn(true); $client = new Client($adapter); - $light = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $light = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W); // Act $result = $client->dimLight($light, 50); // Assert diff --git a/tests/unit/IKEA/Tradfri/Device/DimmerTest.php b/tests/unit/IKEA/Tradfri/Device/DimmerTest.php index 3662dcdf..6465f6a3 100644 --- a/tests/unit/IKEA/Tradfri/Device/DimmerTest.php +++ b/tests/unit/IKEA/Tradfri/Device/DimmerTest.php @@ -31,6 +31,6 @@ public function testIsLightbulb() */ protected function _getModel(): Device { - return new Dimmer($this->id, Device::TYPE_DIMMER); + return new Dimmer($this->id, \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_DIMMER); } } diff --git a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php index 5b826be6..216c3036 100644 --- a/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php +++ b/tests/unit/IKEA/Tradfri/Device/LightbulbTest.php @@ -4,7 +4,7 @@ namespace IKEA\Tests\Tradfri\Device; use IKEA\Tradfri\Client\Client; -use IKEA\Tradfri\Device\Device; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Device\Lightbulb; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Service\Api; @@ -29,19 +29,19 @@ public function testGetAnInstance() */ protected function _getModel(): Lightbulb { - return new Lightbulb($this->id, Device::TYPE_BLUB_E27_W); + return new Lightbulb($this->id, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W); } public function testSetType() { // Arrange $lamp = $this->_getModel(); - $lamp->setType(Device::TYPE_BLUB_E27_W); + $lamp->setType(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W); // Act $result = $lamp->getType(); // Assert - $this->assertSame(Device::TYPE_BLUB_E27_W, $result); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, $result); } public function testIsLightbulb() @@ -93,24 +93,24 @@ public function testSetTypeE27WS() { // Arrange $lamp = $this->_getModel(); - $lamp->setType(Device::TYPE_BLUB_E27_WS); + $lamp->setType(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); // Act $result = $lamp->getType(); // Assert - $this->assertSame(Device::TYPE_BLUB_E27_WS, $result); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, $result); } public function testSetTypeGU10() { // Arrange $lamp = $this->_getModel(); - $lamp->setType(Device::TYPE_BLUB_GU10); + $lamp->setType(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_GU10); // Act $result = $lamp->getType(); // Assert - $this->assertSame(Device::TYPE_BLUB_GU10, $result); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_GU10, $result); } public function testStates() diff --git a/tests/unit/IKEA/Tradfri/Device/MotionSensorTest.php b/tests/unit/IKEA/Tradfri/Device/MotionSensorTest.php index d93b1be6..fcca29d1 100644 --- a/tests/unit/IKEA/Tradfri/Device/MotionSensorTest.php +++ b/tests/unit/IKEA/Tradfri/Device/MotionSensorTest.php @@ -3,7 +3,6 @@ namespace IKEA\Tests\Tradfri\Device; -use IKEA\Tradfri\Device\Device; use IKEA\Tradfri\Device\MotionSensor; class MotionSensorTest extends DeviceTester @@ -29,8 +28,8 @@ public function testIsLightbulb() /** * @return MotionSensor */ - protected function _getModel(): \IKEA\Tradfri\Device\MotionSensor + protected function _getModel(): MotionSensor { - return new MotionSensor($this->id, Device::TYPE_MOTION_SENSOR); + return new MotionSensor($this->id); } } diff --git a/tests/unit/IKEA/Tradfri/Device/RemoteTest.php b/tests/unit/IKEA/Tradfri/Device/RemoteTest.php index 01545245..d927c642 100644 --- a/tests/unit/IKEA/Tradfri/Device/RemoteTest.php +++ b/tests/unit/IKEA/Tradfri/Device/RemoteTest.php @@ -3,7 +3,6 @@ namespace IKEA\Tests\Tradfri\Device; -use IKEA\Tradfri\Device\Device; use IKEA\Tradfri\Device\Remote; class RemoteTest extends DeviceTester @@ -29,8 +28,8 @@ public function testIsLightbulb() /** * @return Remote */ - protected function _getModel(): \IKEA\Tradfri\Device\Remote + protected function _getModel(): Remote { - return new Remote($this->id, Device::TYPE_REMOTE_CONTROL); + return new Remote($this->id); } } diff --git a/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php b/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php index d936a97d..1ebf0209 100644 --- a/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php +++ b/tests/unit/IKEA/Tradfri/Mapper/DeviceDataTest.php @@ -5,7 +5,7 @@ use Codeception\Test\Unit as UnitTest; use IKEA\Tradfri\Collection\Devices; -use IKEA\Tradfri\Device\Device; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Device\Dimmer; use IKEA\Tradfri\Device\Lightbulb; use IKEA\Tradfri\Device\MotionSensor; @@ -49,62 +49,62 @@ public function testICanMapDataToCollectionWithNoError() // Act $result = $mapper->map($serviceMock, $this->tester->getDevices()); // Assert - $this->tester->assertInstanceOf(Devices::class, $result); - $this->tester->assertFalse($result->isEmpty()); - $this->tester->assertSame(5, $result->count()); + $this->assertInstanceOf(Devices::class, $result); + $this->assertFalse($result->isEmpty()); + $this->assertSame(5, $result->count()); $device1 = $result->get(1000); - $this->tester->assertInstanceOf(Lightbulb::class, $device1); - $this->tester->assertTrue($device1->isLightbulb()); - $this->tester->assertSame(1000, $device1->getId()); - $this->tester->assertTrue($device1->isOn()); - $this->tester->assertSame('On', $device1->getState()); - $this->tester->assertSame(Device::TYPE_BLUB_E27_W, $device1->getName()); - $this->tester->assertSame(Device::TYPE_BLUB_E27_W, $device1->getType()); - $this->tester->assertSame('UnitTestFactory', $device1->getManufacturer()); - $this->tester->assertSame('v1.33.7', $device1->getVersion()); - $this->tester->assertSame(9.0, $device1->getBrightness()); + $this->assertInstanceOf(Lightbulb::class, $device1); + $this->assertTrue($device1->isLightbulb()); + $this->assertSame(1000, $device1->getId()); + $this->assertTrue($device1->isOn()); + $this->assertSame('On', $device1->getState()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, $device1->getName()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, $device1->getType()); + $this->assertSame('UnitTestFactory', $device1->getManufacturer()); + $this->assertSame('v1.33.7', $device1->getVersion()); + $this->assertSame(9.0, $device1->getBrightness()); $device2 = $result->get(2000); - $this->tester->assertInstanceOf(Lightbulb::class, $device2); - $this->tester->assertTrue($device2->isLightbulb()); - $this->tester->assertSame(2000, $device2->getId()); - $this->tester->assertFalse($device2->isOn()); - $this->tester->assertSame('Off', $device2->getState()); - $this->tester->assertSame(Device::TYPE_BLUB_E27_WS, $device2->getName()); - $this->tester->assertSame(Device::TYPE_BLUB_E27_WS, $device2->getType()); - $this->tester->assertSame('UnitTestFactory', $device2->getManufacturer()); - $this->tester->assertSame('v1.33.7', $device2->getVersion()); - $this->tester->assertSame(9.0, $device2->getBrightness()); + $this->assertInstanceOf(Lightbulb::class, $device2); + $this->assertTrue($device2->isLightbulb()); + $this->assertSame(2000, $device2->getId()); + $this->assertFalse($device2->isOn()); + $this->assertSame('Off', $device2->getState()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, $device2->getName()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, $device2->getType()); + $this->assertSame('UnitTestFactory', $device2->getManufacturer()); + $this->assertSame('v1.33.7', $device2->getVersion()); + $this->assertSame(9.0, $device2->getBrightness()); $device3 = $result->get(3000); - $this->tester->assertInstanceOf(Dimmer::class, $device3); - $this->tester->assertFalse($device3->isLightbulb()); - $this->tester->assertSame(3000, $device3->getId()); - $this->tester->assertSame(Device::TYPE_DIMMER, $device3->getName()); - $this->tester->assertSame(Device::TYPE_DIMMER, $device3->getType()); - $this->tester->assertSame('UnitTestFactory', $device3->getManufacturer()); - $this->tester->assertSame('v1.33.7', $device3->getVersion()); + $this->assertInstanceOf(Dimmer::class, $device3); + $this->assertFalse($device3->isLightbulb()); + $this->assertSame(3000, $device3->getId()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, $device3->getName()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, $device3->getType()); + $this->assertSame('UnitTestFactory', $device3->getManufacturer()); + $this->assertSame('v1.33.7', $device3->getVersion()); $device4 = $result->get(4000); - $this->tester->assertInstanceOf(Remote::class, $device4); - $this->tester->assertFalse($device4->isLightbulb()); - $this->tester->assertSame(4000, $device4->getId()); - $this->tester->assertSame(Device::TYPE_REMOTE_CONTROL, $device4->getName()); - $this->tester->assertSame(Device::TYPE_REMOTE_CONTROL, $device4->getType()); - $this->tester->assertSame('UnitTestFactory', $device4->getManufacturer()); - $this->tester->assertSame('v1.33.7', $device4->getVersion()); + $this->assertInstanceOf(Remote::class, $device4); + $this->assertFalse($device4->isLightbulb()); + $this->assertSame(4000, $device4->getId()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, $device4->getName()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, $device4->getType()); + $this->assertSame('UnitTestFactory', $device4->getManufacturer()); + $this->assertSame('v1.33.7', $device4->getVersion()); $device5 = $result->get(5000); - $this->tester->assertInstanceOf(MotionSensor::class, $device5); - $this->tester->assertFalse($device5->isLightbulb()); - $this->tester->assertSame(5000, $device5->getId()); - $this->tester->assertSame(Device::TYPE_MOTION_SENSOR, $device5->getName()); - $this->tester->assertSame(Device::TYPE_MOTION_SENSOR, $device5->getType()); - $this->tester->assertSame('UnitTestFactory', $device5->getManufacturer()); - $this->tester->assertSame('v1.33.7', $device5->getVersion()); + $this->assertInstanceOf(MotionSensor::class, $device5); + $this->assertFalse($device5->isLightbulb()); + $this->assertSame(5000, $device5->getId()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, $device5->getName()); + $this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, $device5->getType()); + $this->assertSame('UnitTestFactory', $device5->getManufacturer()); + $this->assertSame('v1.33.7', $device5->getVersion()); $lights = $result->getLightbulbs(); - $this->tester->assertSame(2, $lights->count()); + $this->assertSame(2, $lights->count()); } } diff --git a/tests/unit/IKEA/Tradfri/Service/ApiTest.php b/tests/unit/IKEA/Tradfri/Service/ApiTest.php index a1937149..8ffbaf99 100644 --- a/tests/unit/IKEA/Tradfri/Service/ApiTest.php +++ b/tests/unit/IKEA/Tradfri/Service/ApiTest.php @@ -8,6 +8,7 @@ use IKEA\Tradfri\Collection\Devices; use IKEA\Tradfri\Collection\Groups; use IKEA\Tradfri\Collection\Lightbulbs; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Device\Dimmer; use IKEA\Tradfri\Device\Lightbulb; use IKEA\Tradfri\Device\Remote; @@ -72,7 +73,7 @@ public function testICanSwitchLightOff() $service = new Api($client); - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_WS); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); $lightbulb->setState(true); $this->assertTrue($lightbulb->isOn()); @@ -91,7 +92,7 @@ public function testICanNotSwitchLightOff() $service = new Api($client); - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_WS); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); $lightbulb->setState(true); $this->assertTrue($lightbulb->isOn()); @@ -102,7 +103,7 @@ public function testICanNotSwitchLightOff() public function testICanNotSwitchLightOffBecauseItIsOff() { // Arrange - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_WS); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); $lightbulb->setState(false); /** @var Client $client */ @@ -121,7 +122,7 @@ public function testICanNotSwitchLightOffBecauseItIsOff() public function testICanSwitchLightOn() { // Arrange - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_WS); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); $lightbulb->setState(false); /** @var Client $client */ @@ -145,7 +146,7 @@ public function testICanNotSwitchLightOn() $this->expectExceptionMessage('unable to change state of lightbulb: 1'); // Arrange - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_WS); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); $lightbulb->setState(false); /** @var Client $client */ @@ -162,7 +163,7 @@ public function testICanNotSwitchLightOn() public function testICanNotSwitchLightOnBecauseItIsOn() { // Arrange - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_WS); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); $lightbulb->setState(true); /** @var Client $client */ @@ -181,7 +182,7 @@ public function testICanNotSwitchLightOnBecauseItIsOn() public function testICanSwitchAllLightsOff() { // Arrange - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_WS); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS); $lightbulb->setState(true); $lightbulbs = new Lightbulbs(); @@ -211,7 +212,10 @@ public function testICanNotSwitchGroupOnBecauseItIsOn() $group = new Group(1, $service); $group->setState(true); - $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W)) + $group->getDevices() + ->addDevice( + (new Lightbulb(2, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W) + ) ->setState(true) ->setName('test') ); @@ -233,7 +237,7 @@ public function testICanSwitchGroupOn() $service = new Api($client); $group = new Group(1, $service); - $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W)) + $group->getDevices()->addDevice((new Lightbulb(2, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W)) ->setState(false) ->setName('test')); @@ -254,7 +258,7 @@ public function testICanSwitchGroupOff() $service = new Api($client); $group = new Group(1, $service); - $group->getDevices()->addDevice((new Lightbulb(2, Lightbulb::TYPE_BLUB_E27_W)) + $group->getDevices()->addDevice((new Lightbulb(2, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W)) ->setState(true) ->setName('test') ); @@ -344,9 +348,9 @@ public function testICanDimAGroup() public function testICanDimALight() { // Arrange - $lightbulb = new Lightbulb(1, Lightbulb::TYPE_BLUB_E27_W); + $lightbulb = new Lightbulb(1, Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W); - // @var Client $client */ + /** @var Client $client */ $client = \Mockery::mock(Client::class); $client->shouldReceive('dimLight')->andReturn(true); diff --git a/wiki/example/example-list-devices.php b/wiki/example/example-list-devices.php index 51cba0bd..5f2d4f31 100644 --- a/wiki/example/example-list-devices.php +++ b/wiki/example/example-list-devices.php @@ -20,6 +20,7 @@ if ($device->isLightbulb()) { echo '- State is: ' . $device->getState(). PHP_EOL; echo '- Brightness ' . $device->getBrightness().'%'. PHP_EOL; + echo '- Color HEX #' . $device->getColor().''. PHP_EOL; } echo ' '.PHP_EOL; From 6a5e563349d3331fd2b1007f4e67c21a31b777f4 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 00:47:13 +0200 Subject: [PATCH 60/73] - removed "old" CoapCommandKeys --- src/IKEA/Tradfri/Adapter/Coap.php | 28 ++-- src/IKEA/Tradfri/Command/Coap/Keys.php | 2 +- src/IKEA/Tradfri/Command/Coaps.php | 25 +-- src/IKEA/Tradfri/Helper/CoapCommandKeys.php | 38 ----- tests/_support/Helper/Unit.php | 169 ++++++++++---------- 5 files changed, 112 insertions(+), 150 deletions(-) delete mode 100644 src/IKEA/Tradfri/Helper/CoapCommandKeys.php diff --git a/src/IKEA/Tradfri/Adapter/Coap.php b/src/IKEA/Tradfri/Adapter/Coap.php index 64d458fe..b35209f5 100644 --- a/src/IKEA/Tradfri/Adapter/Coap.php +++ b/src/IKEA/Tradfri/Adapter/Coap.php @@ -6,10 +6,10 @@ use IKEA\Tradfri\Collection\Devices; use IKEA\Tradfri\Collection\Groups; +use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Command\Coaps; use IKEA\Tradfri\Exception\RuntimeException; use IKEA\Tradfri\Group\Light; -use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Helper\Runner; use IKEA\Tradfri\Mapper\MapperInterface; use IKEA\Tradfri\Service\ServiceInterface; @@ -53,14 +53,14 @@ public function __construct( */ public function getType(int $deviceId): string { - $data = $this->_getData(CoapCommandKeys::KEY_GET_DATA, $deviceId); + $data = $this->_getData(Keys::ROOT_DEVICES, $deviceId); if (\is_object($data) - && \property_exists($data, CoapCommandKeys::KEY_DATA) - && \property_exists($data, CoapCommandKeys::KEY_TYPE) + && \property_exists($data, Keys::ATTR_DEVICE_INFO) + && \property_exists($data, Keys::ATTR_DEVICE_INFO_TYPE) ) { return $data - ->{CoapCommandKeys::KEY_DATA} - ->{CoapCommandKeys::KEY_TYPE}; + ->{Keys::ATTR_DEVICE_INFO} + ->{Keys::ATTR_DEVICE_INFO_TYPE}; } throw new RuntimeException('invalid coap response'); @@ -110,10 +110,10 @@ protected function _getData(string $requestType, int $deviceId = null) */ public function getManufacturer(int $deviceId): string { - $data = $this->_getData(CoapCommandKeys::KEY_GET_DATA, $deviceId); + $data = $this->_getData(Keys::ROOT_DEVICES, $deviceId); - if (isset($data->{CoapCommandKeys::KEY_DATA}->{'0'})) { - return $data->{CoapCommandKeys::KEY_DATA}->{'0'}; + if (isset($data->{Keys::ATTR_DEVICE_INFO}->{'0'})) { + return $data->{Keys::ATTR_DEVICE_INFO}->{'0'}; } throw new RuntimeException('invalid hub response'); @@ -267,7 +267,7 @@ public function getDevicesData(array $deviceIds = null): array // sometimes the request are to fast, // the hub will decline the request (flood security) $deviceData[$deviceId] = $this->getDeviceData((int) $deviceId); - // @TODO: add command queue + if ((int) COAP_GATEWAY_FLOOD_PROTECTION > 0) { \usleep((int) COAP_GATEWAY_FLOOD_PROTECTION); } @@ -285,7 +285,7 @@ public function getDevicesData(array $deviceIds = null): array */ public function getDeviceIds(): array { - return $this->_getData(CoapCommandKeys::KEY_GET_DATA); + return $this->_getData(Keys::ROOT_DEVICES); } /** @@ -299,7 +299,7 @@ public function getDeviceIds(): array */ public function getDeviceData(int $deviceId): \stdClass { - return $this->_getData(CoapCommandKeys::KEY_GET_DATA, $deviceId); + return $this->_getData(Keys::ROOT_DEVICES, $deviceId); } /** @@ -347,7 +347,7 @@ public function getGroupsData(): array // sometimes the request are to fast, // the hub will decline the request (flood security) $groupData[$groupId] = $this->_getData( - CoapCommandKeys::KEY_GET_GROUPS, + Keys::ROOT_GROUPS, $groupId ); } @@ -364,7 +364,7 @@ public function getGroupsData(): array */ public function getGroupIds(): array { - return $this->_getData(CoapCommandKeys::KEY_GET_GROUPS); + return $this->_getData(Keys::ROOT_GROUPS); } /** diff --git a/src/IKEA/Tradfri/Command/Coap/Keys.php b/src/IKEA/Tradfri/Command/Coap/Keys.php index b7b817f8..b56f34ae 100644 --- a/src/IKEA/Tradfri/Command/Coap/Keys.php +++ b/src/IKEA/Tradfri/Command/Coap/Keys.php @@ -42,13 +42,13 @@ class Keys const ATTR_DEVICE_INFO = '3'; const ATTR_DEVICE_INFO_MANUFACTURER = '0'; const ATTR_DEVICE_INFO_TYPE = '1'; + const ATTR_DEVICE_VERSION = '3'; const ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR = 'TRADFRI motion sensor'; const ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL = 'TRADFRI remote control'; const ATTR_DEVICE_INFO_TYPE_DIMMER = 'TRADFRI dimmer'; const ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS = 'TRADFRI bulb E27 WS opal 980lm'; const ATTR_DEVICE_INFO_TYPE_BLUB_E27_W = 'TRADFRI bulb E27 W opal 1000lm'; const ATTR_DEVICE_INFO_TYPE_BLUB_GU10 = 'TRADFRI bulb GU10 WS 400lm'; - const ATTR_DEVICE_VERSION = '3'; const ATTR_GATEWAY_TIME_SOURCE = '9071'; const ATTR_GATEWAY_UPDATE_PROGRESS = '9055'; diff --git a/src/IKEA/Tradfri/Command/Coaps.php b/src/IKEA/Tradfri/Command/Coaps.php index 80fdce5e..e4b5061b 100644 --- a/src/IKEA/Tradfri/Command/Coaps.php +++ b/src/IKEA/Tradfri/Command/Coaps.php @@ -6,7 +6,6 @@ use IKEA\Tradfri\Command\Coap\Keys; use IKEA\Tradfri\Exception\RuntimeException; -use IKEA\Tradfri\Helper\CoapCommandKeys; use IKEA\Tradfri\Helper\Runner; /** @@ -86,8 +85,8 @@ public function getSharedKeyFromGateway(): string ); // verify result - if (isset($result->{CoapCommandKeys::KEY_SHARED_KEY})) { - return $result->{CoapCommandKeys::KEY_SHARED_KEY}; + if (isset($result->{Keys::ATTR_PSK})) { + return $result->{Keys::ATTR_PSK}; } throw new RuntimeException('Could not get api key'); @@ -106,7 +105,9 @@ public function getPreSharedKeyCommand(): string $this->_secret ) .' -e \'{"9090":"'.$this->getUsername().'"}\'' - .$this->_getRequestTypeCoapsUrl(CoapCommandKeys::KEY_GET_SHARED_KEY); + .$this->_getRequestTypeCoapsUrl( + Keys::ROOT_GATEWAY.'/'.Keys::ATTR_AUTH + ); } /** @@ -294,7 +295,7 @@ public function getCoapsCommandPut($requestType, string $inject): string public function getGroupSwitchCommand(int $groupId, bool $state): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, + Keys::ROOT_GROUPS.'/'.$groupId, self::PAYLOAD_START.Keys::ATTR_LIGHT_STATE.'": '.($state ? '1' : '0').' }\' ' ); @@ -311,8 +312,8 @@ public function getGroupSwitchCommand(int $groupId, bool $state): string public function getGroupDimmerCommand(int $groupId, int $value): string { return $this->getCoapsCommandPut( - CoapCommandKeys::KEY_GET_GROUPS.'/'.$groupId, - self::PAYLOAD_START.CoapCommandKeys::KEY_DIMMER.'": '.(int) \round( + Keys::ROOT_GROUPS.'/'.$groupId, + self::PAYLOAD_START.Keys::ATTR_LIGHT_DIMMER.'": '.(int) \round( $value * 2.55 ).' }\' ' ); @@ -331,9 +332,9 @@ public function getLightDimmerCommand(int $groupId, int $value): string return $this->getCoapsCommandPut( Keys::ROOT_DEVICES.'/'.$groupId, self::PAYLOAD_START - .CoapCommandKeys::KEY_DEVICE_DATA + .Keys::ATTR_LIGHT_CONTROL .self::PAYLOAD_OPEN - .CoapCommandKeys::KEY_DIMMER.'": '.(int) \round($value * 2.55) + .Keys::ATTR_LIGHT_DIMMER.'": '.(int) \round($value * 2.55) .' }] }\' ' ); } @@ -351,11 +352,11 @@ public function getLightDimmerCommand(int $groupId, int $value): string public function getLightColorCommand(int $groupId, string $color): string { $payload = self::PAYLOAD_START - .CoapCommandKeys::KEY_DEVICE_DATA + .Keys::ATTR_LIGHT_CONTROL .self::PAYLOAD_OPEN - .CoapCommandKeys::KEY_COLOR + .Keys::ATTR_LIGHT_COLOR_X .'": %s, "' - .CoapCommandKeys::KEY_COLOR_2 + .Keys::ATTR_LIGHT_COLOR_Y .'": %s }] }\' '; switch ($color) { case 'warm': diff --git a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php b/src/IKEA/Tradfri/Helper/CoapCommandKeys.php deleted file mode 100644 index a5236b8b..00000000 --- a/src/IKEA/Tradfri/Helper/CoapCommandKeys.php +++ /dev/null @@ -1,38 +0,0 @@ - 'invalid type error', + Keys::ATTR_DEVICE_INFO_TYPE => 'invalid type error', ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 9999, - CoapCommandKeys::KEY_NAME => 'invalid', - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => 'invalid type error', + Keys::ATTR_ID => 9999, + Keys::ATTR_NAME => 'invalid', + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => 'invalid type error', ], ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 1000, - CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, + Keys::ATTR_ID => 1000, + Keys::ATTR_NAME => Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_W, ], - CoapCommandKeys::KEY_DEVICE_DATA => [ + Keys::ATTR_LIGHT_CONTROL => [ 0 => [ - CoapCommandKeys::KEY_DIMMER => 22, - CoapCommandKeys::KEY_ONOFF => 1, + Keys::ATTR_LIGHT_DIMMER => 22, + Keys::ATTR_LIGHT_STATE => 1, ], ], ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 2000, - CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, + Keys::ATTR_ID => 2000, + Keys::ATTR_NAME => Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => Keys::ATTR_DEVICE_INFO_TYPE_BLUB_E27_WS, ], - CoapCommandKeys::KEY_DEVICE_DATA => [ + Keys::ATTR_LIGHT_CONTROL => [ 0 => [ - CoapCommandKeys::KEY_DIMMER => 22, - CoapCommandKeys::KEY_ONOFF => 0, + Keys::ATTR_LIGHT_DIMMER => 22, + Keys::ATTR_LIGHT_STATE => 0, ], ], ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 3000, - CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, + Keys::ATTR_ID => 3000, + Keys::ATTR_NAME => Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => Keys::ATTR_DEVICE_INFO_TYPE_DIMMER, ], ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 4000, - CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, + Keys::ATTR_ID => 4000, + Keys::ATTR_NAME => Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => Keys::ATTR_DEVICE_INFO_TYPE_REMOTE_CONTROL, ], ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 5000, - CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, + Keys::ATTR_ID => 5000, + Keys::ATTR_NAME => Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, ], ])), ]; @@ -100,15 +99,15 @@ public function getGroupDataCoapsResponse(): array { return [ 1000 => \json_decode(\json_encode([ - CoapCommandKeys::KEY_NAME => 'Group 1', - CoapCommandKeys::KEY_TIME => 1498340208, - CoapCommandKeys::KEY_ID => 1000, - CoapCommandKeys::KEY_ONOFF => 1, - CoapCommandKeys::KEY_DIMMER => 38, - CoapCommandKeys::KEY_X => 220273, - CoapCommandKeys::KEY_GROUPS_DATA => (object) [ - CoapCommandKeys::KEY_GET_LIGHTS => (object) [ - CoapCommandKeys::KEY_ID => [ + Keys::ATTR_NAME => 'Group 1', + Keys::ATTR_CREATED_AT => 1498340208, + Keys::ATTR_ID => 1000, + Keys::ATTR_LIGHT_STATE => 1, + Keys::ATTR_LIGHT_DIMMER => 38, + Keys::ATTR_ALEXA_PAIR_STATUS => 220273, + Keys::ATTR_GROUP_INFO => (object) [ + Keys::ATTR_GROUP_LIGHTS => (object) [ + Keys::ATTR_ID => [ 0 => 65540, 1 => 65547, 2 => 65545, @@ -119,15 +118,15 @@ public function getGroupDataCoapsResponse(): array ], ])), 2000 => \json_decode(\json_encode([ - CoapCommandKeys::KEY_NAME => 'Group 2', - CoapCommandKeys::KEY_TIME => 1498339585, - CoapCommandKeys::KEY_ID => 2000, - CoapCommandKeys::KEY_ONOFF => 1, - CoapCommandKeys::KEY_DIMMER => 0, - CoapCommandKeys::KEY_X => 214087, - CoapCommandKeys::KEY_GROUPS_DATA => (object) [ - CoapCommandKeys::KEY_GET_LIGHTS => (object) [ - CoapCommandKeys::KEY_ID => [ + Keys::ATTR_NAME => 'Group 2', + Keys::ATTR_CREATED_AT => 1498339585, + Keys::ATTR_ID => 2000, + Keys::ATTR_LIGHT_STATE => 1, + Keys::ATTR_LIGHT_DIMMER => 0, + Keys::ATTR_ALEXA_PAIR_STATUS => 214087, + Keys::ATTR_GROUP_INFO => (object) [ + Keys::ATTR_GROUP_LIGHTS => (object) [ + Keys::ATTR_ID => [ 0 => 65536, 1 => 65537, 2 => 65538, @@ -139,15 +138,15 @@ public function getGroupDataCoapsResponse(): array ], ])), 3000 => \json_decode(\json_encode([ - CoapCommandKeys::KEY_NAME => 'Group 3', - CoapCommandKeys::KEY_TIME => 1498340478, - CoapCommandKeys::KEY_ID => 3000, - CoapCommandKeys::KEY_ONOFF => 1, - CoapCommandKeys::KEY_DIMMER => 0, - CoapCommandKeys::KEY_X => 222180, - CoapCommandKeys::KEY_GROUPS_DATA => (object) [ - CoapCommandKeys::KEY_GET_LIGHTS => (object) [ - CoapCommandKeys::KEY_ID => [ + Keys::ATTR_NAME => 'Group 3', + Keys::ATTR_CREATED_AT => 1498340478, + Keys::ATTR_ID => 3000, + Keys::ATTR_LIGHT_STATE => 1, + Keys::ATTR_LIGHT_DIMMER => 0, + Keys::ATTR_ALEXA_PAIR_STATUS => 222180, + Keys::ATTR_GROUP_INFO => (object) [ + Keys::ATTR_GROUP_LIGHTS => (object) [ + Keys::ATTR_ID => [ 0 => 65544, 1 => 65546, ], @@ -155,25 +154,25 @@ public function getGroupDataCoapsResponse(): array ], ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 5000, - CoapCommandKeys::KEY_NAME => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => \IKEA\Tradfri\Command\Coap\Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, + Keys::ATTR_ID => 5000, + Keys::ATTR_NAME => Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => Keys::ATTR_DEVICE_INFO_TYPE_MOTION_SENSOR, ], ])), 'asd invalid', \json_decode(\json_encode([ - CoapCommandKeys::KEY_TYPE => 'invalid type error', + Keys::ATTR_DEVICE_INFO_TYPE => 'invalid type error', ])), \json_decode(\json_encode([ - CoapCommandKeys::KEY_ID => 9999, - CoapCommandKeys::KEY_NAME => 'invalid', - CoapCommandKeys::KEY_DATA => [ - CoapCommandKeys::KEY_MANUFACTURER => 'UnitTestFactory', - CoapCommandKeys::KEY_VERSION => 'v1.33.7', - CoapCommandKeys::KEY_TYPE => 'invalid type error', + Keys::ATTR_ID => 9999, + Keys::ATTR_NAME => 'invalid', + Keys::ATTR_DEVICE_INFO => [ + Keys::ATTR_DEVICE_INFO_MANUFACTURER => 'UnitTestFactory', + Keys::ATTR_DEVICE_VERSION => 'v1.33.7', + Keys::ATTR_DEVICE_INFO_TYPE => 'invalid type error', ], ])), ]; From 5afada83f92ccb52890884359339648166b4d1a8 Mon Sep 17 00:00:00 2001 From: Fahl-Design Date: Fri, 15 Jun 2018 22:47:27 +0000 Subject: [PATCH 61/73] Apply fixes from StyleCI --- src/IKEA/Tradfri/Collection/AbstractCollection.php | 6 ++---- src/IKEA/Tradfri/Device/Lightbulb.php | 4 ++-- src/IKEA/Tradfri/Helper/Runner.php | 3 ++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index da43946f..e7390252 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -13,9 +13,7 @@ /** * Class Devices. */ -abstract class AbstractCollection - extends ArrayCollection - implements JsonSerializable +abstract class AbstractCollection extends ArrayCollection implements JsonSerializable { /** * Add item to collection. @@ -66,7 +64,7 @@ public function jsonSerialize() { $data = []; foreach ($this->toArray() as $device) { - /** @var Device $device */ + /* @var Device $device */ $data[$device->getId()] = $device->jsonSerialize(); } diff --git a/src/IKEA/Tradfri/Device/Lightbulb.php b/src/IKEA/Tradfri/Device/Lightbulb.php index 02a7fdaa..3a02e5c5 100644 --- a/src/IKEA/Tradfri/Device/Lightbulb.php +++ b/src/IKEA/Tradfri/Device/Lightbulb.php @@ -139,7 +139,7 @@ public function dim(int $level) } /** - * Get Color + * Get Color. * * @return string */ @@ -149,7 +149,7 @@ public function getColor(): string } /** - * Set Color + * Set Color. * * @param string $color * diff --git a/src/IKEA/Tradfri/Helper/Runner.php b/src/IKEA/Tradfri/Helper/Runner.php index bd5d19ad..b7bb1c02 100644 --- a/src/IKEA/Tradfri/Helper/Runner.php +++ b/src/IKEA/Tradfri/Helper/Runner.php @@ -20,6 +20,7 @@ class Runner 1 => ['pipe', 'w'], // stdout 2 => ['pipe', 'w'], // stderr ]; + /** * Execute a command and return it's output. Either wait * until the command exits or the timeout has expired. @@ -160,7 +161,7 @@ private function _startProcess( } /** - * Close all streams + * Close all streams. * * @param array $pipes * @param $process From f19a0feeeea7c1590dc56ca565d1bf26d34163da Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 00:58:07 +0200 Subject: [PATCH 62/73] - style fix --- src/IKEA/Tradfri/Collection/AbstractCollection.php | 1 - src/IKEA/Tradfri/Helper/Online.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/IKEA/Tradfri/Collection/AbstractCollection.php b/src/IKEA/Tradfri/Collection/AbstractCollection.php index e7390252..6c17173e 100644 --- a/src/IKEA/Tradfri/Collection/AbstractCollection.php +++ b/src/IKEA/Tradfri/Collection/AbstractCollection.php @@ -64,7 +64,6 @@ public function jsonSerialize() { $data = []; foreach ($this->toArray() as $device) { - /* @var Device $device */ $data[$device->getId()] = $device->jsonSerialize(); } diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php index 5a2c0b5d..61dcd4fd 100644 --- a/src/IKEA/Tradfri/Helper/Online.php +++ b/src/IKEA/Tradfri/Helper/Online.php @@ -27,7 +27,7 @@ public static function isOnline(string $gatewayAddress): bool $data = (new Runner()) ->execWithTimeout('ping -c1 '.$gatewayAddress, 1, false); - \preg_match_all($regex, $data, $matches, PREG_SET_ORDER); + \preg_match_all($regex, $data, $matches, \PREG_SET_ORDER); if (isset($matches[0][1])) { self::_validateMatches($matches); } else { From 4bc89bc8d18fa8394bbd1b378893851599abb4ec Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 01:06:44 +0200 Subject: [PATCH 63/73] - removed ping tool because gateway no longer sends ping echo --- src/IKEA/Tradfri/Helper/Online.php | 61 ------------------------------ 1 file changed, 61 deletions(-) delete mode 100644 src/IKEA/Tradfri/Helper/Online.php diff --git a/src/IKEA/Tradfri/Helper/Online.php b/src/IKEA/Tradfri/Helper/Online.php deleted file mode 100644 index 61dcd4fd..00000000 --- a/src/IKEA/Tradfri/Helper/Online.php +++ /dev/null @@ -1,61 +0,0 @@ -execWithTimeout('ping -c1 '.$gatewayAddress, 1, false); - - \preg_match_all($regex, $data, $matches, \PREG_SET_ORDER); - if (isset($matches[0][1])) { - self::_validateMatches($matches); - } else { - throw new RuntimeException('unable to ping hub'); - } - } catch (\Exception $exception) { - // todo add log - $online = false; - } - - return $online; - } - - /** - * Validate matches. - * - * @param array $matches - * - * @throws \IKEA\Tradfri\Exception\RuntimeException - * - * @return bool - */ - protected static function _validateMatches(array $matches): bool - { - if (false === \strpos($matches[0][1], ' 0% packet loss')) { - throw new RuntimeException('packet loss detected'); - } - - return true; - } -} From 2369a7c5252511ba32d72c3fd7463b10bfd7a9d5 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 01:16:16 +0200 Subject: [PATCH 64/73] - codeception output and composer php version --- codeception.yml | 1 + composer.json | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/codeception.yml b/codeception.yml index 9b85c504..935c6e4a 100644 --- a/codeception.yml +++ b/codeception.yml @@ -17,6 +17,7 @@ actor_suffix: Tester namespace: IKEA\Tests extensions: enabled: + - Codeception\Extension\DotReporter - Codeception\Extension\RunFailed - Codeception\Extension\Logger: # enabled extension max_files: 5 # logger configuration diff --git a/composer.json b/composer.json index 5138b1f5..e46205d4 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "webproject-xyz/ikea-tradfri-php-api", "description": "PHP library to control ikea tradfri hub", - "minimum-stability": "stable", + "prefer-stable": true, "license": "MIT", "version": "0.2.0", "authors": [ @@ -14,7 +14,7 @@ "type": "library", "homepage": "https://www.webproject.xyz", "require": { - "php": "^7", + "php": "7.* < 7.3", "doctrine/collections": "1.4.*" }, "require-dev": { From 8018f65665c8c0e65d53417e8d5bd9c0cefa0f16 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 01:33:08 +0200 Subject: [PATCH 65/73] - changed travis caching --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9ac6c230..5fbc4ab5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ sudo: false cache: directories: - - $TRAVIS_BUILD_DIR/vendor + - vendor - $HOME/.composer/cache - $HOME/.php-cs-fixer - $HOME/.local From f0c9a17d320b823d4b122207541ccd997216ca9f Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 01:33:17 +0200 Subject: [PATCH 66/73] - removed distro --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5fbc4ab5..5558549b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: php -dist: trusty sudo: false cache: From 3f5ab7bea02bf8d1bbcc8b4a19e1f2f3eff95fa7 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 01:36:44 +0200 Subject: [PATCH 67/73] - removed php 7.3 check and added php7 without coverage --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5558549b..a5509041 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,11 +15,11 @@ env: matrix: fast_finish: true include: + - php: 7.0 - php: 7.0 env: EXECUTE_CS_CHECK=true RUN_WITH_COVERAGE=true PATH="$HOME/.local/bin:$PATH" - php: 7.1 - php: 7.2 - - php: 7.3 - php: nightly allow_failures: - php: 7.3 From aab1897037e5b666d87b6865335ed4253e3771b3 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 01:41:21 +0200 Subject: [PATCH 68/73] - travis env magic... --- .travis.yml | 3 ++- build/script/travis_after_success.sh | 2 +- build/script/travis_before_install.sh | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a5509041..d8b61fce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,8 @@ before_install: - ./build/script/travis_before_install.sh install: - - travis_retry composer update --no-interaction --prefer-source + - travis_retry composer self-update + - travis_retry composer update --no-interaction --profile script: - ./build/script/travis_script.sh diff --git a/build/script/travis_after_success.sh b/build/script/travis_after_success.sh index 0a3dc6cd..3ad2e736 100755 --- a/build/script/travis_after_success.sh +++ b/build/script/travis_after_success.sh @@ -3,5 +3,5 @@ set -e trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR ## coverage reports -php vendor/bin/codacycoverage clover build/logs/clover.xml +if [[ $RUN_WITH_COVERAGE == 'true' ]]; then php vendor/bin/codacycoverage clover build/logs/clover.xml ; fi if [[ $RUN_WITH_COVERAGE == 'true' && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./cc-test-reporter after-build -t=clover build/logs/clover.xml --exit-code $TRAVIS_TEST_RESULT ; fi diff --git a/build/script/travis_before_install.sh b/build/script/travis_before_install.sh index 627f10d4..26457fb5 100755 --- a/build/script/travis_before_install.sh +++ b/build/script/travis_before_install.sh @@ -10,7 +10,6 @@ phpenv rehash # create directories for the tests mkdir -p "$HOME/.php-cs-fixer" -composer self-update --profile git config --global user.name travis-ci git config --global user.email travis@webproject.xyz if [[ $RUN_WITH_COVERAGE == 'true' ]]; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter; fi From 0a9160febd74b4e2705bf686f92b68daf67d8bd5 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 01:49:12 +0200 Subject: [PATCH 69/73] - lets try install --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d8b61fce..b022da0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ before_install: install: - travis_retry composer self-update - - travis_retry composer update --no-interaction --profile + - travis_retry composer install --prefer-dist --optimize-autoloader --profile --no-interaction script: - ./build/script/travis_script.sh From 2d44b45736e40bf496ecb21f3de9ed9025b9b18d Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 02:06:47 +0200 Subject: [PATCH 70/73] - try to pass missing codeception --- build/script/travis_script.sh | 3 ++- composer.json | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build/script/travis_script.sh b/build/script/travis_script.sh index a15264ee..a793e056 100755 --- a/build/script/travis_script.sh +++ b/build/script/travis_script.sh @@ -4,7 +4,8 @@ trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit # run static php-cs-fixer code analysis ./vendor/bin/php-cs-fixer fix --dry-run --diff --verbose - +## because of Skipped installation of bin codecept for package codeception/codeception: file not found in package in 7.2 +if [[ $(phpenv version-name) == '7.2' ]]; then wget http://codeception.com/codecept.phar | chmod +x codecept.phar | mv codecept.phar vendor/bin/codecept ; fi ## run the tests with no coverage if [[ $RUN_WITH_COVERAGE != 'true' ]]; then composer run-tests; fi diff --git a/composer.json b/composer.json index e46205d4..e2d3dc4f 100644 --- a/composer.json +++ b/composer.json @@ -14,13 +14,13 @@ "type": "library", "homepage": "https://www.webproject.xyz", "require": { - "php": "7.* < 7.3", + "php": "7.*", "doctrine/collections": "1.4.*" }, "require-dev": { - "codeception/codeception": "^2", + "codeception/codeception": "2.4.*", "mockery/mockery": "1.*", - "symfony/phpunit-bridge": "3.*", + "symfony/phpunit-bridge": "4.*", "friendsofphp/php-cs-fixer": "2.*", "codeclimate/php-test-reporter": "0.*", "codacy/coverage": "1.*", From 3c924b0d6ffbbfff861655592444f63717b1e284 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 02:13:27 +0200 Subject: [PATCH 71/73] - travis... again --- build/script/travis_script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/script/travis_script.sh b/build/script/travis_script.sh index a793e056..fb0c9195 100755 --- a/build/script/travis_script.sh +++ b/build/script/travis_script.sh @@ -5,7 +5,7 @@ trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit # run static php-cs-fixer code analysis ./vendor/bin/php-cs-fixer fix --dry-run --diff --verbose ## because of Skipped installation of bin codecept for package codeception/codeception: file not found in package in 7.2 -if [[ $(phpenv version-name) == '7.2' ]]; then wget http://codeception.com/codecept.phar | chmod +x codecept.phar | mv codecept.phar vendor/bin/codecept ; fi +if [[ $(phpenv version-name) == '7.2' ]]; then wget http://codeception.com/codecept.phar | chmod +x codecept.phar | mkdir -p vendor/bin/ | mv ./codecept.phar vendor/bin/codecept ; fi ## run the tests with no coverage if [[ $RUN_WITH_COVERAGE != 'true' ]]; then composer run-tests; fi From e7343ae959a1f7dd4c25a9b69752092b469807c0 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 02:19:13 +0200 Subject: [PATCH 72/73] - travis... again and again --- build/script/travis_script.sh | 5 +++-- composer.json | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build/script/travis_script.sh b/build/script/travis_script.sh index fb0c9195..c098b09c 100755 --- a/build/script/travis_script.sh +++ b/build/script/travis_script.sh @@ -5,9 +5,10 @@ trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit # run static php-cs-fixer code analysis ./vendor/bin/php-cs-fixer fix --dry-run --diff --verbose ## because of Skipped installation of bin codecept for package codeception/codeception: file not found in package in 7.2 -if [[ $(phpenv version-name) == '7.2' ]]; then wget http://codeception.com/codecept.phar | chmod +x codecept.phar | mkdir -p vendor/bin/ | mv ./codecept.phar vendor/bin/codecept ; fi +if [[ $(phpenv version-name) == '7.2' ]]; then wget http://codeception.com/codecept.phar | chmod +x codecept.phar ; fi ## run the tests with no coverage -if [[ $RUN_WITH_COVERAGE != 'true' ]]; then composer run-tests; fi +if [[ $RUN_WITH_COVERAGE != 'true' && $(phpenv version-name) != '7.2' ]]; then composer run-tests; fi +if [[ $RUN_WITH_COVERAGE != 'true' && $(phpenv version-name) == '7.2' ]]; then composer run-tests-72; fi ## run the tests with no coverage ## enable xdebug again diff --git a/composer.json b/composer.json index e2d3dc4f..82ebbfac 100644 --- a/composer.json +++ b/composer.json @@ -36,6 +36,9 @@ "run-tests": [ "./vendor/bin/codecept run --colors" ], + "run-tests-72": [ + "php codecept.phar run --colors" + ], "cs-check": [ "./vendor/bin/php-cs-fixer fix --dry-run -vv" ], From 8cb47582fc1c49fb86b39efa2344cd495eb37135 Mon Sep 17 00:00:00 2001 From: Benjamin Fahl Date: Sat, 16 Jun 2018 02:25:49 +0200 Subject: [PATCH 73/73] - :( --- .travis.yml | 2 +- build/script/travis_script.sh | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b022da0e..9a7c132e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ matrix: - php: 7.2 - php: nightly allow_failures: - - php: 7.3 + - php: 7.2 - php: nightly before_install: diff --git a/build/script/travis_script.sh b/build/script/travis_script.sh index c098b09c..789f767b 100755 --- a/build/script/travis_script.sh +++ b/build/script/travis_script.sh @@ -4,11 +4,9 @@ trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit # run static php-cs-fixer code analysis ./vendor/bin/php-cs-fixer fix --dry-run --diff --verbose -## because of Skipped installation of bin codecept for package codeception/codeception: file not found in package in 7.2 -if [[ $(phpenv version-name) == '7.2' ]]; then wget http://codeception.com/codecept.phar | chmod +x codecept.phar ; fi + ## run the tests with no coverage if [[ $RUN_WITH_COVERAGE != 'true' && $(phpenv version-name) != '7.2' ]]; then composer run-tests; fi -if [[ $RUN_WITH_COVERAGE != 'true' && $(phpenv version-name) == '7.2' ]]; then composer run-tests-72; fi ## run the tests with no coverage ## enable xdebug again